summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergio Ahumada <sergio.ahumada@digia.com>2013-04-10 15:41:47 +0200
committerSergio Ahumada <sergio.ahumada@digia.com>2013-04-10 15:42:22 +0200
commit90297a64f203959f90041887ea31f4bd04bc059a (patch)
tree86f8ad6a5af26fd618cdb2e20601e6df89ac94d6
parent537a4bc4011d32de193dc31caf09a44c1810ab33 (diff)
parentf273d6fbc02055ff3999adc0df76360ca0670435 (diff)
Merge branch 'stable' into dev
-rwxr-xr-xconfigure35
-rw-r--r--dist/changes-5.0.249
-rw-r--r--doc/global/qt-cpp-ignore.qdocconf1
-rw-r--r--examples/network/torrent/main.cpp1
-rw-r--r--examples/network/torrent/peerwireclient.cpp8
-rw-r--r--examples/network/torrent/peerwireclient.h9
-rw-r--r--examples/network/torrent/trackerclient.cpp49
-rw-r--r--examples/widgets/graphicsview/boxes/boxes.pro6
-rw-r--r--mkspecs/common/clang-mac.conf3
-rw-r--r--mkspecs/common/mac.conf3
-rw-r--r--mkspecs/common/xcode.conf8
-rw-r--r--mkspecs/features/c++11.prf7
-rw-r--r--mkspecs/features/create_cmake.prf8
-rw-r--r--mkspecs/features/ctest_testcase.prf20
-rw-r--r--mkspecs/features/data/android/dx.bat2
-rw-r--r--mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in6
-rw-r--r--mkspecs/features/exclusive_builds.prf2
-rw-r--r--mkspecs/features/mac/default_post.prf4
-rw-r--r--mkspecs/features/mac/sdk.prf9
-rw-r--r--mkspecs/features/qt_parts.prf3
-rwxr-xr-xmkspecs/unsupported/macx-ios-clang/Info.plist.app8
-rw-r--r--mkspecs/unsupported/macx-ios-clang/qmake.conf5
-rw-r--r--qmake/generators/makefile.cpp6
-rw-r--r--qmake/generators/unix/unixmake2.cpp8
-rw-r--r--qmake/generators/win32/msvc_nmake.cpp1
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp6
-rw-r--r--src/3rdparty/angle/.gitignore21
-rw-r--r--src/3rdparty/angle/include/GLES2/gl2ext.h46
-rw-r--r--src/3rdparty/angle/include/GLSLANG/ShaderLang.h103
-rw-r--r--src/3rdparty/angle/src/common/angleutils.h28
-rw-r--r--src/3rdparty/angle/src/common/debug.cpp15
-rw-r--r--src/3rdparty/angle/src/common/debug.h7
-rw-r--r--src/3rdparty/angle/src/common/system.h26
-rw-r--r--src/3rdparty/angle/src/common/version.h6
-rw-r--r--src/3rdparty/angle/src/compiler/BaseTypes.h6
-rw-r--r--src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp10
-rw-r--r--src/3rdparty/angle/src/compiler/Compiler.cpp43
-rw-r--r--src/3rdparty/angle/src/compiler/ConstantUnion.h3
-rw-r--r--src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp22
-rw-r--r--src/3rdparty/angle/src/compiler/DetectDiscontinuity.h2
-rw-r--r--src/3rdparty/angle/src/compiler/Diagnostics.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/Diagnostics.h2
-rw-r--r--src/3rdparty/angle/src/compiler/DirectiveHandler.h2
-rw-r--r--src/3rdparty/angle/src/compiler/ExtensionBehavior.h2
-rw-r--r--src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp4
-rw-r--r--src/3rdparty/angle/src/compiler/HashNames.h19
-rw-r--r--src/3rdparty/angle/src/compiler/Initialize.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/Intermediate.cpp40
-rw-r--r--src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp6
-rw-r--r--src/3rdparty/angle/src/compiler/MapLongVariableNames.h2
-rw-r--r--src/3rdparty/angle/src/compiler/OutputESSL.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/OutputESSL.h6
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSL.cpp8
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSL.h6
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp168
-rw-r--r--src/3rdparty/angle/src/compiler/OutputGLSLBase.h25
-rw-r--r--src/3rdparty/angle/src/compiler/OutputHLSL.cpp1304
-rw-r--r--src/3rdparty/angle/src/compiler/OutputHLSL.h35
-rw-r--r--src/3rdparty/angle/src/compiler/ParseHelper.cpp17
-rw-r--r--src/3rdparty/angle/src/compiler/ParseHelper.h5
-rw-r--r--src/3rdparty/angle/src/compiler/ShHandle.h23
-rw-r--r--src/3rdparty/angle/src/compiler/ShaderLang.cpp113
-rw-r--r--src/3rdparty/angle/src/compiler/SymbolTable.h16
-rw-r--r--src/3rdparty/angle/src/compiler/TranslatorESSL.cpp5
-rw-r--r--src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp5
-rw-r--r--src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp9
-rw-r--r--src/3rdparty/angle/src/compiler/TranslatorHLSL.h11
-rw-r--r--src/3rdparty/angle/src/compiler/Types.h37
-rw-r--r--src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp10
-rw-r--r--src/3rdparty/angle/src/compiler/Uniform.cpp21
-rw-r--r--src/3rdparty/angle/src/compiler/Uniform.h35
-rw-r--r--src/3rdparty/angle/src/compiler/ValidateLimitations.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/VariableInfo.cpp34
-rw-r--r--src/3rdparty/angle/src/compiler/VariableInfo.h5
-rw-r--r--src/3rdparty/angle/src/compiler/VariablePacker.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/glslang.h2
-rw-r--r--src/3rdparty/angle/src/compiler/glslang.l170
-rw-r--r--src/3rdparty/angle/src/compiler/glslang.y41
-rw-r--r--src/3rdparty/angle/src/compiler/intermOut.cpp2
-rw-r--r--src/3rdparty/angle/src/compiler/intermediate.h29
-rw-r--r--src/3rdparty/angle/src/compiler/osinclude.h21
-rw-r--r--src/3rdparty/angle/src/compiler/ossource_nspr.cpp43
-rw-r--r--src/3rdparty/angle/src/compiler/parseConst.cpp7
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.cpp)2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.cpp)2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.cpp)4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.y)8
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Input.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Input.cpp)15
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Input.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Input.h)19
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.cpp)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Lexer.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Macro.cpp)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Macro.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Macro.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.cpp)14
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.h)2
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.cpp)4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.h)4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/SourceLocation.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Token.cpp (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Token.cpp)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Token.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Token.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.h)4
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.l)16
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/atom.c737
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/atom.h63
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/compile.h100
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/cpp.c1118
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/cpp.h86
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/cppstruct.c152
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/memory.c158
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/memory.h58
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/numeric_lex.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/parser.h93
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h (renamed from src/3rdparty/angle/src/compiler/preprocessor/new/pp_utils.h)0
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/preprocess.h50
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/scanner.c698
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/scanner.h81
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/slglobals.h82
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/symbols.c288
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/symbols.h111
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/tokens.c467
-rw-r--r--src/3rdparty/angle/src/compiler/preprocessor/tokens.h90
-rw-r--r--src/3rdparty/angle/src/libEGL/Config.cpp117
-rw-r--r--src/3rdparty/angle/src/libEGL/Config.h15
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.cpp874
-rw-r--r--src/3rdparty/angle/src/libEGL/Display.h94
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.cpp433
-rw-r--r--src/3rdparty/angle/src/libEGL/Surface.h34
-rw-r--r--src/3rdparty/angle/src/libEGL/libEGL.cpp258
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp3
-rw-r--r--src/3rdparty/angle/src/libEGL/main.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/BinaryStream.h3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.cpp72
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Buffer.h42
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp2769
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.h248
-rw-r--r--src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp231
-rw-r--r--src/3rdparty/angle/src/libGLESv2/D3DConstantTable.h117
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.cpp104
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Fence.h18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py8
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp361
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Framebuffer.h69
-rw-r--r--src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/IndexDataManager.cpp473
-rw-r--r--src/3rdparty/angle/src/libGLESv2/IndexDataManager.h149
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.cpp27
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Program.h15
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp1774
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ProgramBinary.h145
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Query.cpp98
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Query.h17
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp230
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Renderbuffer.h64
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/ResourceManager.h24
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp79
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.h26
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.cpp2301
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Texture.h242
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Uniform.cpp43
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Uniform.h48
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexDataManager.cpp783
-rw-r--r--src/3rdparty/angle/src/libGLESv2/VertexDataManager.h169
-rw-r--r--src/3rdparty/angle/src/libGLESv2/angletypes.h128
-rw-r--r--src/3rdparty/angle/src/libGLESv2/constants.h34
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp1390
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2.def3
-rw-r--r--src/3rdparty/angle/src/libGLESv2/libGLESv2d.def2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp35
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/mathutil.h22
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.cpp9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/precompiled.h45
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp (renamed from src/3rdparty/angle/src/libGLESv2/Blit.cpp)163
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Blit.h (renamed from src/3rdparty/angle/src/libGLESv2/Blit.h)28
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.cpp40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h44
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp352
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h56
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp76
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h42
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp134
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp135
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h45
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp548
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image.h131
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp457
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image11.h76
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp736
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Image9.h79
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ImageSSE2.cpp (renamed from src/3rdparty/angle/src/libGLESv2/TextureSSE2.cpp)18
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp202
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h137
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp182
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h53
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp207
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h53
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp316
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.h66
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp166
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h74
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp122
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Query11.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp125
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Query9.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h42
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp406
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h101
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h56
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp378
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h58
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp113
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h40
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp201
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h238
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp3531
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h348
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp3211
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h347
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderCache.h (renamed from src/3rdparty/angle/src/libEGL/ShaderCache.h)20
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h51
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp109
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h47
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp60
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h39
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h44
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp770
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h78
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp449
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h55
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.cpp122
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.h110
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp676
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h120
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp328
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h109
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp229
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h138
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp418
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h73
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp486
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h90
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp258
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h65
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp217
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h58
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h203
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp688
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h95
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp500
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h74
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps (renamed from src/3rdparty/angle/src/libGLESv2/shaders/Blit.ps)0
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs (renamed from src/3rdparty/angle/src/libGLESv2/shaders/Blit.vs)0
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl33
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl29
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h (renamed from src/3rdparty/angle/src/libGLESv2/vertexconversion.h)7
-rw-r--r--src/3rdparty/angle/src/libGLESv2/utilities.cpp674
-rw-r--r--src/3rdparty/angle/src/libGLESv2/utilities.h75
-rw-r--r--src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp106
-rw-r--r--src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h62
-rw-r--r--src/3rdparty/angle/src/third_party/compiler/LICENSE22
-rw-r--r--src/3rdparty/angle/src/third_party/compiler/README.angle12
-rw-r--r--src/3rdparty/angle/src/third_party/murmurhash/LICENSE2
-rw-r--r--src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp334
-rw-r--r--src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h37
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java124
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtNative.java14
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java5
-rw-r--r--src/android/java/AndroidManifest.xml2
-rw-r--r--src/android/java/res/values/libs.xml7
-rw-r--r--src/android/java/src/org/kde/necessitas/ministro/IMinistro.aidl11
-rw-r--r--src/android/java/src/org/kde/necessitas/ministro/IMinistroCallback.aidl6
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java74
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java2
-rw-r--r--src/android/java/version.xml2
-rw-r--r--src/angle/patches/0001-Dynamically-resolve-functions-of-dwmapi.dll.patch22
-rw-r--r--src/angle/patches/0003-Fix-Float16ToFloat32.py.patch54
-rw-r--r--src/angle/patches/0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch30
-rw-r--r--src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch40
-rw-r--r--src/angle/patches/0006-ANGLE-Do-not-reset-the-share-handle-when-resetting-t.patch32
-rw-r--r--src/angle/patches/0006-Make-DX9-DX11-mutually-exclusive.patch140
-rw-r--r--src/angle/patches/0007-ANGLE-Fix-typedefs-for-Win64.patch14
-rw-r--r--src/angle/patches/0008-ANGLE-DX11-Prevent-assert-when-view-is-minimized-or-.patch58
-rw-r--r--src/angle/patches/0009-ANGLE-Avoid-memory-copies-on-buffers-when-data-is-nu.patch72
-rw-r--r--src/angle/src/compiler/preprocessor/preprocessor.pro52
-rw-r--r--src/angle/src/compiler/translator_common.pro24
-rw-r--r--src/angle/src/compiler/translator_hlsl.pro6
-rw-r--r--src/angle/src/config.pri5
-rw-r--r--src/angle/src/libEGL/libEGL.pro9
-rw-r--r--src/angle/src/libGLESv2/libGLESv2.pro186
-rw-r--r--src/corelib/Qt5CTestMacros.cmake29
-rw-r--r--src/corelib/Qt5CoreConfigExtras.cmake.in6
-rw-r--r--src/corelib/doc/src/objectmodel/properties.qdoc2
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/io/qdatastream.cpp1
-rw-r--r--src/corelib/io/qlockfile.h4
-rw-r--r--src/corelib/io/qsavefile.cpp101
-rw-r--r--src/corelib/io/qsavefile.h3
-rw-r--r--src/corelib/io/qsavefile_p.h3
-rw-r--r--src/corelib/itemmodels/qabstractproxymodel.cpp7
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp3
-rw-r--r--src/corelib/kernel/qmetatype.h2
-rw-r--r--src/corelib/kernel/qvariant.cpp2
-rw-r--r--src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp2
-rw-r--r--src/gui/accessible/qaccessible.cpp73
-rw-r--r--src/gui/accessible/qaccessible.h12
-rw-r--r--src/gui/accessible/qaccessible2.cpp35
-rw-r--r--src/gui/accessible/qaccessible2_p.h18
-rw-r--r--src/gui/doc/qtgui.qdocconf2
-rw-r--r--src/gui/doc/src/qtgui.qdoc4
-rw-r--r--src/gui/opengl/qopenglfunctions_1_2.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_1_3.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_1_4.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_1_5.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_2_0.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_2_1.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_3_0.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_3_1.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_3_2_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_3_2_core.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_3_3_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_3_3_core.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_4_0_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_4_0_core.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_4_1_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_4_1_core.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_4_2_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_4_2_core.h6
-rw-r--r--src/gui/opengl/qopenglfunctions_4_3_compatibility.h12
-rw-r--r--src/gui/opengl/qopenglfunctions_4_3_core.h6
-rw-r--r--src/gui/opengl/qopenglversionfunctions.cpp2
-rw-r--r--src/gui/opengl/qopenglversionfunctions.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp15
-rw-r--r--src/network/bearer/qnetworkconfigmanager.cpp6
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor.cpp14
-rw-r--r--src/platformsupport/linuxaccessibility/atspiadaptor_p.h2
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.cpp94
-rw-r--r--src/plugins/accessible/widgets/qaccessiblewidgets.h8
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.cpp7
-rw-r--r--src/plugins/accessible/widgets/simplewidgets.h6
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp3
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.cpp11
-rw-r--r--src/plugins/platforms/android/src/androidjnimain.h1
-rw-r--r--src/plugins/platforms/android/src/androidjnimenu.cpp29
-rw-r--r--src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp7
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp6
-rw-r--r--src/plugins/platforms/android/src/raster/qandroidplatformscreen.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm10
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm2
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks.h2
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp9
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp6
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h1
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm2
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm2
-rw-r--r--src/plugins/platforms/ios/qiostheme.h4
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm14
-rw-r--r--src/plugins/platforms/ios/qiosviewcontroller.mm2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm2
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h4
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp6
-rw-r--r--src/printsupport/doc/src/qtprintsupport-module.qdoc3
-rw-r--r--src/sql/drivers/db2/qsql_db2.cpp17
-rw-r--r--src/sql/drivers/db2/qsql_db2_p.h2
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp30
-rw-r--r--src/sql/drivers/ibase/qsql_ibase_p.h7
-rw-r--r--src/sql/drivers/mysql/qsql_mysql.cpp69
-rw-r--r--src/sql/drivers/mysql/qsql_mysql_p.h4
-rw-r--r--src/sql/drivers/oci/qsql_oci.cpp21
-rw-r--r--src/sql/drivers/oci/qsql_oci_p.h3
-rw-r--r--src/sql/drivers/odbc/qsql_odbc.cpp44
-rw-r--r--src/sql/drivers/odbc/qsql_odbc_p.h3
-rw-r--r--src/sql/drivers/psql/qsql_psql.cpp48
-rw-r--r--src/sql/drivers/psql/qsql_psql_p.h5
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite.cpp16
-rw-r--r--src/sql/drivers/sqlite/qsql_sqlite_p.h4
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2.cpp20
-rw-r--r--src/sql/drivers/sqlite2/qsql_sqlite2_p.h6
-rw-r--r--src/sql/drivers/tds/qsql_tds.cpp18
-rw-r--r--src/sql/drivers/tds/qsql_tds_p.h2
-rw-r--r--src/sql/kernel/qsqldriver.cpp7
-rw-r--r--src/sql/kernel/qsqldriver.h1
-rw-r--r--src/sql/kernel/qsqldriver_p.h29
-rw-r--r--src/tools/qdoc/doc/config/qdoc.qdocconf2
-rw-r--r--src/tools/qdoc/node.cpp1
-rw-r--r--src/tools/qdoc/node.h4
-rw-r--r--src/tools/qdoc/qdocdatabase.cpp22
-rw-r--r--src/tools/uic/qclass_lib_map.h2
-rw-r--r--src/widgets/dialogs/qwizard.cpp12
-rw-r--r--src/widgets/dialogs/qwizard_win.cpp18
-rw-r--r--src/widgets/kernel/qwidget.cpp3
-rw-r--r--src/widgets/styles/qgtkstyle_p.cpp50
-rw-r--r--src/xml/doc/src/qtxml-index.qdoc2
-rw-r--r--tests/auto/cmake/cmake.pro10
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp85
-rw-r--r--tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp26
-rw-r--r--tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp35
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp50
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_databases.h22
-rw-r--r--tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp193
-rw-r--r--tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp8
-rw-r--r--tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp236
-rw-r--r--tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp14
-rw-r--r--tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp70
-rw-r--r--tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp86
-rw-r--r--tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp62
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp95
-rw-r--r--tests/benchmarks/sql/kernel/qsqlquery/main.cpp80
-rw-r--r--tools/configure/configureapp.cpp17
-rw-r--r--util/glgen/qopenglextensions.h.footer60
-rw-r--r--util/glgen/qopenglextensions.h.header116
-rw-r--r--util/glgen/qopenglversionfunctions.h.header7
-rw-r--r--util/glgen/qopenglversionfunctions__VERSION__.h.footer2
-rw-r--r--util/glgen/qopenglversionfunctions__VERSION__.h.header4
-rw-r--r--util/glgen/specparser.cpp7
-rw-r--r--util/glgen/specparser.h1
432 files changed, 29728 insertions, 17873 deletions
diff --git a/configure b/configure
index a7d1790969..0c58ab21c3 100755
--- a/configure
+++ b/configure
@@ -233,7 +233,7 @@ macSDKify()
sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1")
if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi
- sysroot=$(xcodebuild -sdk $sdk -version Path 2>/dev/null)
+ sysroot=$(/usr/bin/xcodebuild -sdk $sdk -version Path 2>/dev/null)
if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi
case "$sdk" in
@@ -256,7 +256,7 @@ macSDKify()
# Prefix tool with toolchain path
var=$(echo "$line" | cut -d '=' -f 1)
val=$(echo "$line" | cut -d '=' -f 2-)
- sdk_val=$(xcrun -sdk $sdk -find $(echo $val | cut -d ' ' -f 1))
+ sdk_val=$(/usr/bin/xcrun -sdk $sdk -find $(echo $val | cut -d ' ' -f 1))
val=$(echo $sdk_val $(echo $val | cut -s -d ' ' -f 2-))
echo "$var=$val"
;;
@@ -445,6 +445,28 @@ if [ "$OSTYPE" = "msys" ]; then
BUILD_ON_MSYS=yes
fi
+#-------------------------------------------------------------------------------
+# Verify Xcode installation on Mac OS
+#-------------------------------------------------------------------------------
+
+if [ "$BUILD_ON_MAC" = "yes" ]; then
+ if ! /usr/bin/xcode-select --print-path >/dev/null 2>&1; then
+ echo >&2
+ echo " No Xcode is selected. Use xcode-select -switch to choose an Xcode" >&2
+ echo " version. See the xcode-select man page for more information." >&2
+ echo >&2
+ exit 2
+ fi
+
+ if ! /usr/bin/xcrun -find xcrun >/dev/null 2>&1; then
+ echo >&2
+ echo " Xcode not set up properly. You may need to confirm the license" >&2
+ echo " agreement by running /usr/bin/xcodebuild without arguments." >&2
+ echo >&2
+ exit 2
+ fi
+fi
+
#-----------------------------------------------------------------------------
# Qt version detection
#-----------------------------------------------------------------------------
@@ -2459,7 +2481,7 @@ if [ -z "$PLATFORM" ]; then
# about the OS version, since we're not using the clang version that comes
# with the system. We use 'xcrun' to check the clang version that's part of
# the Xcode installation.
- if [ "$(xcrun -sdk macosx clang -v 2>&1 | sed -n 's/.*version \([0-9]\).*/\1/p')" -ge 3 ]; then
+ if [ "$(/usr/bin/xcrun -sdk macosx clang -v 2>&1 | sed -n 's/.*version \([0-9]\).*/\1/p')" -ge 3 ]; then
PLATFORM=macx-clang
# Advertise g++ as an alternative on Lion and below
@@ -2814,9 +2836,10 @@ if [ "$CFG_FORCEDEBUGINFO" = "yes" ]; then
QMAKE_CONFIG="$QMAKE_CONFIG force_debug_info"
fi
-# iOS builds should be static to be able to submit to the App Store
if [ "$XPLATFORM_IOS" = "yes" ]; then
- CFG_SHARED="no"
+ CFG_SHARED="no" # iOS builds should be static to be able to submit to the App Store
+ CFG_CXX11="no" # C++11 support disabled for now
+ CFG_SKIP_MODULES="$CFG_SKIP_MODULES qtdeclarative qtquickcontrols qtwebkit qtgraphicaleffects qtdoc qtmultimedia qtwebkit-examples-and-demos qttools"
fi
# disable GTK style support auto-detection on Mac
@@ -3040,7 +3063,7 @@ fi
QT_INSTALL_BINS=`"$relpath/config.tests/unix/makeabs" "$QT_INSTALL_BINS"`
if [ "$XPLATFORM_MINGW" = "yes" ]; then
- QT_INSTALL_LIBEXECS_DIRNAME="lib"
+ QT_INSTALL_LIBEXECS_DIRNAME="bin"
else
QT_INSTALL_LIBEXECS_DIRNAME="libexec"
fi
diff --git a/dist/changes-5.0.2 b/dist/changes-5.0.2
index 108512a98a..a9d715d1e6 100644
--- a/dist/changes-5.0.2
+++ b/dist/changes-5.0.2
@@ -22,9 +22,6 @@ information about a particular change.
General Improvements
--------------------
- - [QTBUG-26697] The -skip option was added to configure, which enables not
- building particular modules. Typical use case: -skip webkit.
-
Third party components
----------------------
@@ -50,6 +47,8 @@ QtGui
QtWidgets
---------
+- [QTBUG-28817] Fixed QColorDialog::setOption(), QFontDialog::setOption().
+
QtNetwork
---------
@@ -88,6 +87,10 @@ Qt for Linux/X11
Qt for Windows
--------------
+ - [QTBUG-30185] Fixed adding of suffixes in Window native file save dialog.
+ - [QTBUG-29010, QTBUG-28531] Fixed handling of layered windows required for
+ translucent or non-opaque windows.
+
Qt for Mac OS X
---------------
@@ -110,12 +113,52 @@ Qt for Windows CE
* Tools *
****************************************************************************
+Build System & configure
+------------------------
+
+ - [QTBUG-26697] The -skip option was added to configure, which enables not
+ building particular modules. Typical use case: -skip webkit.
+ - [QTBUG-28769, ...] Assorted build fixes
+ - [QTBUG-28902] Fixed contents of installed .prl files
+ - [QTBUG-29110, QTBUG-29186, ...] Assorted fixes to CMake config files
+ - [QTBUG-29174] Fixed numerous configure options which start with -l
+ - [QTBUG-29400] Fixed configure -fully-process not creating .vcproj files
+ - [QTBUG-29453, ...] Fixed generation of pkg-config .pc files
+ - [QTBUG-29478] Fixed static builds with ICU
+ - [QTBUG-29661] Fixed QtWebProcess.exe not finding Qt DLLs. -libexec
+ now defaults to bin/ on Windows.
+ - [QTBUG-29838] Fixed module versioning when mixing releases
+ - [QTBUG-30102] Fixed passing of values with spaces to -device-option
+ - Production builds do not build examples any more. 'make install' will
+ copy only the example sources.
+ - pkg-config: qt_config is now contained only in Qt5Core.pc, and it reflects
+ QT_CONFIG, not the module build's CONFIG.
+
qmake
-----
+ - [QTBUG-28132] Fixed parallelized 'jom install'
+ - [QTBUG-29143] MSVC: Fixed parsing of /openmp
+ - [QTBUG-29286] MSVC: Fixed use of VERSION breaking MSVC2010 projects
+ - [QTBUG-29329] MSVC: Fixed misparsing of /Gs as /GS
+ - [QTBUG-29329] MSVC: Stopped disabling buffer security check by default
+ - [QTBUG-29371] Fixed generation of XCode projects for XCode 4.6
+ - [QTBUG-29698] MSVC: Fixed incremental linking with non-standard shells
+ - [QTBUG-29700] Fixed pkg-config file generation when cross-compiling
+ - Qt modules are now enumerated in QT_MODULES, not QT_CONFIG. For portability,
+ use qtHaveModule() (since 5.0.1) or !isEmpty(QT.<module>.name) instead.
- $$(VAR) style environment variable expansions will not split on
whitespace any more. Use $$split() if necessary.
+ - Fixed qmake -tp vc (and configure without -no-vcproj)
+ - MSVC: Fixed an empty VERSION causing a garbled version in .rc files
+ - Windows: Added support for specifying application icon (via RC_ICONS)
+ - Added spec for BlackBerry Playbook
+
+moc
+---
+ - [QTBUG-29759] Fixed infinite recursion in macro substitution which
+ prevented some headers to compile.
****************************************************************************
* Plugins *
diff --git a/doc/global/qt-cpp-ignore.qdocconf b/doc/global/qt-cpp-ignore.qdocconf
index 6c71263bff..1f34f366cb 100644
--- a/doc/global/qt-cpp-ignore.qdocconf
+++ b/doc/global/qt-cpp-ignore.qdocconf
@@ -41,6 +41,7 @@ Cpp.ignoretokens += \
Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_PRINTSUPPORT_EXPORT \
+ Q_QML_EXPORT \
Q_SCRIPT_EXPORT \
Q_SCRIPTTOOLS_EXPORT \
Q_SQL_EXPORT \
diff --git a/examples/network/torrent/main.cpp b/examples/network/torrent/main.cpp
index 13b40d28cc..9cdca69122 100644
--- a/examples/network/torrent/main.cpp
+++ b/examples/network/torrent/main.cpp
@@ -45,7 +45,6 @@
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
- qWarning("The usage of QHttp is not recommended anymore, please use QNetworkAccessManager.");
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
Q_INIT_RESOURCE(icons);
diff --git a/examples/network/torrent/peerwireclient.cpp b/examples/network/torrent/peerwireclient.cpp
index ade465ab47..0f77ba10d3 100644
--- a/examples/network/torrent/peerwireclient.cpp
+++ b/examples/network/torrent/peerwireclient.cpp
@@ -386,15 +386,15 @@ bool PeerWireClient::canTransferMore() const
|| !outgoingBuffer.isEmpty() || !pendingBlocks.isEmpty();
}
-void PeerWireClient::connectToHostImplementation(const QString &hostName,
- quint16 port, OpenMode openMode)
+void PeerWireClient::connectToHost(const QHostAddress &address,
+ quint16 port, OpenMode openMode)
{
setOpenMode(openMode);
- socket.connectToHost(hostName, port, openMode);
+ socket.connectToHost(address, port, openMode);
}
-void PeerWireClient::diconnectFromHostImplementation()
+void PeerWireClient::diconnectFromHost()
{
socket.disconnectFromHost();
}
diff --git a/examples/network/torrent/peerwireclient.h b/examples/network/torrent/peerwireclient.h
index 7cd08d90cb..35e4cc6ffb 100644
--- a/examples/network/torrent/peerwireclient.h
+++ b/examples/network/torrent/peerwireclient.h
@@ -118,6 +118,10 @@ public:
void setReadBufferSize(qint64 size);
+ void connectToHost(const QHostAddress &address,
+ quint16 port, OpenMode openMode = ReadWrite);
+ void diconnectFromHost();
+
signals:
void infoHashReceived(const QByteArray &infoHash);
void readyToTransfer();
@@ -133,11 +137,6 @@ signals:
void bytesReceived(qint64 size);
-protected slots:
- void connectToHostImplementation(const QString &hostName,
- quint16 port, OpenMode openMode = ReadWrite);
- void diconnectFromHostImplementation();
-
protected:
void timerEvent(QTimerEvent *event);
diff --git a/examples/network/torrent/trackerclient.cpp b/examples/network/torrent/trackerclient.cpp
index d714050fa7..fef3c7d596 100644
--- a/examples/network/torrent/trackerclient.cpp
+++ b/examples/network/torrent/trackerclient.cpp
@@ -97,14 +97,10 @@ void TrackerClient::timerEvent(QTimerEvent *event)
void TrackerClient::fetchPeerList()
{
- // Prepare connection details
- QString fullUrl = metaInfo.announceUrl();
- QUrl url(fullUrl);
- QString passkey = "?";
- if (fullUrl.contains("?passkey")) {
- passkey = metaInfo.announceUrl().mid(fullUrl.indexOf("?passkey"), -1);
- passkey += '&';
- }
+ QUrl url(metaInfo.announceUrl());
+
+ // Base the query on announce url to include a passkey (if any)
+ QUrlQuery query(url);
// Percent encode the hash
QByteArray infoHash = torrentDownloader->infoHash();
@@ -115,43 +111,44 @@ void TrackerClient::fetchPeerList()
}
bool seeding = (torrentDownloader->state() == TorrentClient::Seeding);
- QByteArray query;
- query += url.path().toLatin1();
- query += passkey;
- query += "info_hash=" + encodedSum;
- query += "&peer_id=" + ConnectionManager::instance()->clientId();
- query += "&port=" + QByteArray::number(TorrentServer::instance()->serverPort());
- query += "&compact=1";
- query += "&uploaded=" + QByteArray::number(torrentDownloader->uploadedBytes());
+
+ query.addQueryItem("info_hash", encodedSum);
+ query.addQueryItem("peer_id", ConnectionManager::instance()->clientId());
+ query.addQueryItem("port", QByteArray::number(TorrentServer::instance()->serverPort()));
+ query.addQueryItem("compact", "1");
+ query.addQueryItem("uploaded", QByteArray::number(torrentDownloader->uploadedBytes()));
if (!firstSeeding) {
- query += "&downloaded=0";
- query += "&left=0";
+ query.addQueryItem("downloaded", "0");
+ query.addQueryItem("left", "0");
} else {
- query += "&downloaded=" + QByteArray::number(
- torrentDownloader->downloadedBytes());
+ query.addQueryItem("downloaded",
+ QByteArray::number(torrentDownloader->downloadedBytes()));
int left = qMax<int>(0, metaInfo.totalSize() - torrentDownloader->downloadedBytes());
- query += "&left=" + QByteArray::number(seeding ? 0 : left);
+ query.addQueryItem("left", QByteArray::number(seeding ? 0 : left));
}
if (seeding && firstSeeding) {
- query += "&event=completed";
+ query.addQueryItem("event", "completed");
firstSeeding = false;
} else if (firstTrackerRequest) {
firstTrackerRequest = false;
- query += "&event=started";
+ query.addQueryItem("event", "started");
} else if(lastTrackerRequest) {
- query += "&event=stopped";
+ query.addQueryItem("event", "stopped");
}
if (!trackerId.isEmpty())
- query += "&trackerid=" + trackerId;
+ query.addQueryItem("trackerid", trackerId);
+
+ url.setQuery(query);
QNetworkRequest req(url);
if (!url.userName().isEmpty()) {
uname = url.userName();
pwd = url.password();
- connect(&http, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*)));
+ connect(&http, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
+ this, SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*)));
}
http.get(req);
}
diff --git a/examples/widgets/graphicsview/boxes/boxes.pro b/examples/widgets/graphicsview/boxes/boxes.pro
index a4b253c580..93621878f1 100644
--- a/examples/widgets/graphicsview/boxes/boxes.pro
+++ b/examples/widgets/graphicsview/boxes/boxes.pro
@@ -1,5 +1,11 @@
QT += opengl widgets
+contains(QT_CONFIG, opengles.) {
+ contains(QT_CONFIG, angle): \
+ warning("Qt was built with ANGLE, which provides only OpenGL ES 2.0 on top of DirectX 9.0c")
+ error("This example requires Qt to be configured with -opengl desktop")
+}
+
HEADERS += 3rdparty/fbm.h \
glbuffers.h \
glextensions.h \
diff --git a/mkspecs/common/clang-mac.conf b/mkspecs/common/clang-mac.conf
index efe771d24d..3280274f36 100644
--- a/mkspecs/common/clang-mac.conf
+++ b/mkspecs/common/clang-mac.conf
@@ -5,3 +5,6 @@ QMAKE_OBJCXXFLAGS_PRECOMPILE = -x objective-c++-header -c ${QMAKE_PCH_INPUT}
QMAKE_OBJCXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
QMAKE_XCODE_GCC_VERSION = com.apple.compilers.llvm.clang.1_0
+
+QMAKE_CXXFLAGS_CXX11 += -stdlib=libc++
+QMAKE_LFLAGS_CXX11 += -stdlib=libc++
diff --git a/mkspecs/common/mac.conf b/mkspecs/common/mac.conf
index cf54f3f580..f31db3bb4b 100644
--- a/mkspecs/common/mac.conf
+++ b/mkspecs/common/mac.conf
@@ -26,4 +26,7 @@ QMAKE_LIBS_THREAD =
QMAKE_AR = ar cq
QMAKE_RANLIB = ranlib -s
+# We rely on Xcode to build
+include(xcode.conf)
+
include(unix.conf)
diff --git a/mkspecs/common/xcode.conf b/mkspecs/common/xcode.conf
index 9da6406f7f..b15266b678 100644
--- a/mkspecs/common/xcode.conf
+++ b/mkspecs/common/xcode.conf
@@ -3,7 +3,7 @@
#
# Get path of Xcode's Developer directory
-QMAKE_XCODE_DEVELOPER_PATH = $$system("xcode-select --print-path")
+QMAKE_XCODE_DEVELOPER_PATH = $$system("/usr/bin/xcode-select --print-path 2>/dev/null")
isEmpty(QMAKE_XCODE_DEVELOPER_PATH): \
error("Xcode path is not set. Please use xcode-select to choose Xcode installation path.")
@@ -11,7 +11,11 @@ isEmpty(QMAKE_XCODE_DEVELOPER_PATH): \
!exists($$QMAKE_XCODE_DEVELOPER_PATH): \
error("Xcode is not installed in $${QMAKE_XCODE_DEVELOPER_PATH}. Please use xcode-select to choose Xcode installation path.")
+# Make sure Xcode is set up properly
+isEmpty($$list($$system("/usr/bin/xcrun -find xcrun 2>/dev/null"))): \
+ error("Xcode not set up properly. You may need to confirm the license agreement by running /usr/bin/xcodebuild.")
+
# Extract Xcode version using xcodebuild
-xcode_version = $$system("xcodebuild -version")
+xcode_version = $$system("/usr/bin/xcodebuild -version")
QMAKE_XCODE_VERSION = $$member(xcode_version, 1)
unset(xcode_version)
diff --git a/mkspecs/features/c++11.prf b/mkspecs/features/c++11.prf
index 4b56fa9fd2..32eaca4a9b 100644
--- a/mkspecs/features/c++11.prf
+++ b/mkspecs/features/c++11.prf
@@ -1,3 +1,10 @@
QMAKE_CXXFLAGS += $$QMAKE_CXXFLAGS_CXX11
QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CXXFLAGS_CXX11
QMAKE_LFLAGS += $$QMAKE_LFLAGS_CXX11
+
+contains(QMAKE_LFLAGS, -stdlib=libc++) {
+ equals(QMAKE_MACOSX_DEPLOYMENT_TARGET, 10.6): \
+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
+ contains(QMAKE_IOS_DEPLOYMENT_TARGET, ^4.*): \
+ QMAKE_IOS_DEPLOYMENT_TARGET = 5.0
+}
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index 9aef37472f..cf0acaf4b7 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -55,10 +55,10 @@ CMAKE_BIN_DIR = $$cmakeRelativePath($$[QT_HOST_BINS], $$[QT_INSTALL_PREFIX])
CMAKE_BIN_DIR_IS_ABSOLUTE = True
}
-CMAKE_ARCHDATA_DIR = $$cmakeRelativePath($$[QT_INSTALL_ARCHDATA], $$[QT_INSTALL_PREFIX])
-!isEmpty(CMAKE_FORCE_ABSOLUTE_PATHS)|contains(CMAKE_ARCHDATA_DIR, "^\\.\\./.*") { # For the mkspecs
- CMAKE_ARCHDATA_DIR = $$[QT_INSTALL_ARCHDATA]/
- CMAKE_ARCHDATA_DIR_IS_ABSOLUTE = True
+CMAKE_HOST_DATA_DIR = $$cmakeRelativePath($$[QT_HOST_DATA], $$[QT_INSTALL_PREFIX])
+!isEmpty(CMAKE_FORCE_ABSOLUTE_PATHS)|contains(CMAKE_HOST_DATA_DIR, "^\\.\\./.*") {
+ CMAKE_HOST_DATA_DIR = $$[QT_HOST_DATA]/
+ CMAKE_HOST_DATA_DIR_IS_ABSOLUTE = True
}
static|staticlib:CMAKE_STATIC_TYPE = true
diff --git a/mkspecs/features/ctest_testcase.prf b/mkspecs/features/ctest_testcase.prf
index 79adde3446..7faf738d6e 100644
--- a/mkspecs/features/ctest_testcase.prf
+++ b/mkspecs/features/ctest_testcase.prf
@@ -56,9 +56,27 @@ isEmpty(CMAKE_VERSION) {
SET = set
equals(QMAKE_DIR_SEP, "/"):SET = export
+ CMAKE_MODULE_VERSIONS =
+ CMAKE_MODULES_UNDER_TEST =
+ for (MODULE_UNDER_TEST, CMAKE_QT_MODULES_UNDER_TEST) {
+ CMAKE_NAME = $$cmakeModuleName($$MODULE_UNDER_TEST)
+ CMAKE_MODULE_VERSIONS += \
+ -DCMAKE_$${CMAKE_NAME}_MODULE_MAJOR_VERSION=$$eval(QT.$${MODULE_UNDER_TEST}.MAJOR_VERSION) \
+ -DCMAKE_$${CMAKE_NAME}_MODULE_MINOR_VERSION=$$eval(QT.$${MODULE_UNDER_TEST}.MINOR_VERSION) \
+ -DCMAKE_$${CMAKE_NAME}_MODULE_PATCH_VERSION=$$eval(QT.$${MODULE_UNDER_TEST}.PATCH_VERSION)
+ CMAKE_MODULES_UNDER_TEST += $$CMAKE_NAME
+ }
+ CMAKE_MODULES_UNDER_TEST = $$join(CMAKE_MODULES_UNDER_TEST, ;)
+
check.commands = \
$(MKDIR) $$BUILD_DIR && cd $$BUILD_DIR && $$SET VERBOSE=1 && \
- cmake $$_PRO_FILE_PWD_ $$CMAKE_GENERATOR $$CMAKE_MODULE_DEFINES -DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} -DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH -DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" && \
+ cmake $$_PRO_FILE_PWD_ $$CMAKE_GENERATOR \
+ $$CMAKE_MODULE_DEFINES \
+ -DCMAKE_BUILD_TYPE=$${CMAKE_BUILD_TYPE} \
+ -DCMAKE_PREFIX_PATH=$$CMAKE_PREFIX_PATH \
+ -DQt5_MODULE_TEST_DEPENDS=\"$${dependentmodules}\" \
+ $${CMAKE_MODULE_VERSIONS} \
+ -DCMAKE_MODULES_UNDER_TEST=\"$$CMAKE_MODULES_UNDER_TEST\" && \
$(TESTRUNNER) ctest --output-on-failure
}
diff --git a/mkspecs/features/data/android/dx.bat b/mkspecs/features/data/android/dx.bat
index a60a1b4cbe..af143c52b5 100644
--- a/mkspecs/features/data/android/dx.bat
+++ b/mkspecs/features/data/android/dx.bat
@@ -41,7 +41,7 @@ set jarfile=dx.jar
set "frameworkdir=%androidsdk%\platform-tools"
if exist "%frameworkdir%\%jarfile%" goto JarFileOk
- set "frameworkdir=%androidsdk%\lib"
+ set "frameworkdir=%frameworkdir%\lib"
if exist "%frameworkdir%\%jarfile%" goto JarFileOk
set "frameworkdir=%androidsdk%\framework"
diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
index e5bbc97161..65ba03d44c 100644
--- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
+++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
@@ -9,9 +9,7 @@ get_filename_component(_qt5$${CMAKE_MODULE_NAME}_install_prefix \"${CMAKE_CURREN
set(_qt5$${CMAKE_MODULE_NAME}_install_prefix \"$$[QT_INSTALL_PREFIX]\")
!!ENDIF
-set(Qt5$${CMAKE_MODULE_NAME}_VERSION_MAJOR "$$eval(QT.$${MODULE}.MAJOR_VERSION)")
-set(Qt5$${CMAKE_MODULE_NAME}_VERSION_MINOR "$$eval(QT.$${MODULE}.MINOR_VERSION)")
-set(Qt5$${CMAKE_MODULE_NAME}_VERSION_PATCH "$$eval(QT.$${MODULE}.PATCH_VERSION)")
+# For backwards compatibility only. Use Qt5$${CMAKE_MODULE_NAME}_VERSION instead.
set(Qt5$${CMAKE_MODULE_NAME}_VERSION_STRING "$$eval(QT.$${MODULE}.MAJOR_VERSION).$$eval(QT.$${MODULE}.MINOR_VERSION).$$eval(QT.$${MODULE}.PATCH_VERSION)")
set(Qt5$${CMAKE_MODULE_NAME}_LIBRARIES Qt5::$${CMAKE_MODULE_NAME})
@@ -88,7 +86,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
${Qt5$${CMAKE_MODULE_NAME}_VERSION_STRING} ${_Qt5$${CMAKE_MODULE_NAME}_FIND_VERSION_EXACT}
${_Qt5$${CMAKE_MODULE_NAME}_DEPENDENCIES_FIND_QUIET}
${_Qt5$${CMAKE_MODULE_NAME}_FIND_DEPENDENCIES_REQUIRED}
- PATHS \"${_qt5$${CMAKE_MODULE_NAME}_install_prefix}\" NO_DEFAULT_PATH
+ PATHS \"${CMAKE_CURRENT_LIST_DIR}/..\" NO_DEFAULT_PATH
)
endif()
diff --git a/mkspecs/features/exclusive_builds.prf b/mkspecs/features/exclusive_builds.prf
index adcad79fe1..c45ff22c06 100644
--- a/mkspecs/features/exclusive_builds.prf
+++ b/mkspecs/features/exclusive_builds.prf
@@ -6,7 +6,7 @@ defineTest(fixExclusiveOutputDirs) {
count(ARGS, 2, greaterThan):isEqual($$list($$lower($$3)), false):appendFirstBuild = false
else:appendFirstBuild = true
- isEmpty(QMAKE_DIR_REPLACE):QMAKE_DIR_REPLACE += OBJECTS_DIR MOC_DIR RCC_DIR
+ isEmpty(QMAKE_DIR_REPLACE):QMAKE_DIR_REPLACE += OBJECTS_DIR MOC_DIR RCC_DIR PRECOMPILED_DIR
lessThan(firstBuild, $$secondBuild):eval($${firstBuild}_and_$${secondBuild}_target:QMAKE_DIR_REPLACE += DESTDIR)
else:eval($${secondBuild}_and_$${firstBuild}_target:QMAKE_DIR_REPLACE += DESTDIR)
for(fix, QMAKE_DIR_REPLACE) {
diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf
index 714b4c7d06..437e3d93e4 100644
--- a/mkspecs/features/mac/default_post.prf
+++ b/mkspecs/features/mac/default_post.prf
@@ -15,3 +15,7 @@ qt:!isEmpty(QT_CONFIG) {
contains(QT_CONFIG, x86_64):!contains(QT_CONFIG, x86):CONFIG += x86_64
}
}
+
+# Ensure that we process sdk.prf first, as it will update QMAKE_CXX
+# and friends that other features/extra compilers may depend on.
+sdk: load(sdk)
diff --git a/mkspecs/features/mac/sdk.prf b/mkspecs/features/mac/sdk.prf
index eaa3108a8b..ece0e27536 100644
--- a/mkspecs/features/mac/sdk.prf
+++ b/mkspecs/features/mac/sdk.prf
@@ -5,7 +5,7 @@ isEmpty(QMAKE_MAC_SDK): \
contains(QMAKE_MAC_SDK, .*/.*): \
error("QMAKE_MAC_SDK can only contain short-form SDK names (eg. macosx, iphoneos)")
-QMAKE_MAC_SDK_PATH = $$system("xcodebuild -sdk $$QMAKE_MAC_SDK -version Path 2>/dev/null")
+QMAKE_MAC_SDK_PATH = $$system("/usr/bin/xcodebuild -sdk $$QMAKE_MAC_SDK -version Path 2>/dev/null")
isEmpty(QMAKE_MAC_SDK_PATH): error("Could not resolve SDK path for \'$$QMAKE_MAC_SDK\'")
!equals(MAKEFILE_GENERATOR, XCODE) {
@@ -24,7 +24,9 @@ for(tool, $$list(QMAKE_CC QMAKE_CXX QMAKE_FIX_RPATH QMAKE_AR QMAKE_RANLIB QMAKE_
value = $$eval($$tool)
isEmpty(value): next()
- sysrooted = $$system("xcrun -sdk $$QMAKE_MAC_SDK -find $$first(value)")
+ sysrooted = $$system("/usr/bin/xcrun -sdk $$QMAKE_MAC_SDK -find $$first(value) 2>/dev/null")
+ isEmpty(sysrooted): next()
+
$$tool = $$sysrooted $$member(value, 1, -1)
}
@@ -40,6 +42,9 @@ isEmpty(QMAKE_MAC_PLATFORM_NAME): error("Could not resolve platform name for SDK
# FIXME: Get the version_min_flag out of the platform's 'Native Build System.xcspec'
version_identifier = $$replace(QMAKE_MAC_PLATFORM_NAME, iphonesimulator, ios-simulator)
+ # C++11 support may affect the deployment target
+ c++11: load(c++11)
+
ios:!host_build: \
deployment_target = $$QMAKE_IOS_DEPLOYMENT_TARGET
else: \
diff --git a/mkspecs/features/qt_parts.prf b/mkspecs/features/qt_parts.prf
index 12ba312bcd..37dc849f83 100644
--- a/mkspecs/features/qt_parts.prf
+++ b/mkspecs/features/qt_parts.prf
@@ -9,6 +9,9 @@
# We mean it.
#
+# Ensure that each module has a .qmake.cache when properly qmake'd.
+cache()
+
load(qt_build_config)
TEMPLATE = subdirs
diff --git a/mkspecs/unsupported/macx-ios-clang/Info.plist.app b/mkspecs/unsupported/macx-ios-clang/Info.plist.app
index bcf7f41f27..c7d660b8d1 100755
--- a/mkspecs/unsupported/macx-ios-clang/Info.plist.app
+++ b/mkspecs/unsupported/macx-ios-clang/Info.plist.app
@@ -14,6 +14,14 @@
<string>@EXECUTABLE@</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.@BUNDLEIDENTIFIER@</string>
+ <key>CFBundleDisplayName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
</dict>
diff --git a/mkspecs/unsupported/macx-ios-clang/qmake.conf b/mkspecs/unsupported/macx-ios-clang/qmake.conf
index 32d10a06ed..833e22e3bd 100644
--- a/mkspecs/unsupported/macx-ios-clang/qmake.conf
+++ b/mkspecs/unsupported/macx-ios-clang/qmake.conf
@@ -15,9 +15,6 @@ DEFINES += DARWIN_NO_CARBON QT_NO_CORESERVICES QT_NO_PRINTER QT_N
# Universal target (iPhone and iPad)
QMAKE_IOS_TARGETED_DEVICE_FAMILY = 1,2
-include(../../common/xcode.conf)
-lessThan(QMAKE_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later")
-
include(../../common/ios.conf)
include(../../common/gcc-base-mac.conf)
include(../../common/clang.conf)
@@ -25,4 +22,6 @@ include(../../common/clang-mac.conf)
include(../../common/ios/clang.conf)
include(../../common/ios/qmake.conf)
+lessThan(QMAKE_XCODE_VERSION, "4.3"): error("This mkspec requires Xcode 4.3 or later")
+
load(qt_config)
diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp
index 69a8c809ac..d095bdf83d 100644
--- a/qmake/generators/makefile.cpp
+++ b/qmake/generators/makefile.cpp
@@ -3271,10 +3271,10 @@ MakefileGenerator::writePkgConfigFile()
t << "Cflags: "
// << var("QMAKE_CXXFLAGS") << " "
<< varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
- << project->values("PRL_EXPORT_CXXFLAGS").join(' ')
- << project->values("QMAKE_PKGCONFIG_CFLAGS").join(' ')
+ << varGlue("PRL_EXPORT_CXXFLAGS", "", " ", " ")
+ << varGlue("QMAKE_PKGCONFIG_CFLAGS", "", " ", " ")
// << varGlue("DEFINES","-D"," -D"," ")
- << " -I${includedir}" << endl;
+ << "-I${includedir}" << endl;
// requires
const QString requires = project->values("QMAKE_PKGCONFIG_REQUIRES").join(' ');
diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp
index 400908bc91..9cb63ce539 100644
--- a/qmake/generators/unix/unixmake2.cpp
+++ b/qmake/generators/unix/unixmake2.cpp
@@ -579,7 +579,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t"
- << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << destdir;
+ << "-$(MOVE) $(TARGET) " << destdir << "\n\t"
+ << "-$(MOVE) $(TARGET0) " << destdir << "\n\t"
+ << "-$(MOVE) $(TARGET1) " << destdir << "\n\t"
+ << "-$(MOVE) $(TARGET2) " << destdir << "\n\t";
if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl;
@@ -592,7 +595,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t)
t << "\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
<< "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
- << "-$(MOVE) $(TARGET) $(TARGET0) " << destdir;
+ << "-$(MOVE) $(TARGET) " << destdir << "\n\t"
+ << "-$(MOVE) $(TARGET0) " << destdir << "\n\t";
if(!project->isEmpty("QMAKE_POST_LINK"))
t << "\n\t" << var("QMAKE_POST_LINK");
t << endl << endl;
diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp
index ee53f94d90..e2c9fdbf37 100644
--- a/qmake/generators/win32/msvc_nmake.cpp
+++ b/qmake/generators/win32/msvc_nmake.cpp
@@ -307,7 +307,6 @@ void NmakeMakefileGenerator::init()
project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk");
project->values("QMAKE_CLEAN").append("vc*.pdb");
project->values("QMAKE_CLEAN").append("vc*.idb");
- project->values("DEFINES").removeAll("NDEBUG");
} else {
ProStringList &defines = project->values("DEFINES");
if (!defines.contains("NDEBUG"))
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 793c2ad1ad..d3187bacb5 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -981,12 +981,8 @@ void VcprojGenerator::initConfiguration()
initDeploymentTool();
initPreLinkEventTools();
- // Set definite values in both configurations
- if (isDebug) {
- conf.compiler.PreprocessorDefinitions.removeAll("NDEBUG");
- } else {
+ if (!isDebug)
conf.compiler.PreprocessorDefinitions += "NDEBUG";
- }
}
void VcprojGenerator::initCompilerTool()
diff --git a/src/3rdparty/angle/.gitignore b/src/3rdparty/angle/.gitignore
index cfa07de1ee..c53d356b04 100644
--- a/src/3rdparty/angle/.gitignore
+++ b/src/3rdparty/angle/.gitignore
@@ -19,17 +19,24 @@ DEPS
codereview.settings
# Generated by flex/bison
-src/compiler/preprocessor/new/Tokenizer.cpp
-src/compiler/preprocessor/new/ExpressionParser.cpp
+src/compiler/preprocessor/Tokenizer.cpp
+src/compiler/preprocessor/ExpressionParser.cpp
src/compiler/glslang_lex.cpp
src/compiler/glslang_tab.cpp
src/compiler/glslang_tab.h
# Generated by FXC
-src/libGLESv2/shaders/standardvs.h
-src/libGLESv2/shaders/flipyvs.h
-src/libGLESv2/shaders/luminanceps.h
-src/libGLESv2/shaders/componentmaskps.h
-src/libGLESv2/shaders/passthroughps.h
+src/libGLESv2/renderer/shaders/compiled/standardvs.h
+src/libGLESv2/renderer/shaders/compiled/flipyvs.h
+src/libGLESv2/renderer/shaders/compiled/luminanceps.h
+src/libGLESv2/renderer/shaders/compiled/componentmaskps.h
+src/libGLESv2/renderer/shaders/compiled/passthroughps.h
+src/libGLESv2/renderer/shaders/compiled/PassthroughRGBA11ps.h
+src/libGLESv2/renderer/shaders/compiled/PassthroughRGB11ps.h
+src/libGLESv2/renderer/shaders/compiled/PassthroughLumAlpha11ps.h
+src/libGLESv2/renderer/shaders/compiled/PassthroughLum11ps.h
+src/libGLESv2/renderer/shaders/compiled/Passthrough11vs.h
+src/libGLESv2/renderer/shaders/compiled/Clear11ps.h
+src/libGLESv2/renderer/shaders/compiled/Clear11vs.h
diff --git a/src/3rdparty/angle/include/GLES2/gl2ext.h b/src/3rdparty/angle/include/GLES2/gl2ext.h
index e297fbfe87..bad50f9ccb 100644
--- a/src/3rdparty/angle/include/GLES2/gl2ext.h
+++ b/src/3rdparty/angle/include/GLES2/gl2ext.h
@@ -556,6 +556,44 @@ typedef void* GLeglImageOES;
#define GL_COLOR_ATTACHMENT15_NV 0x8CEF
#endif
+/* GL_EXT_draw_buffers */
+#ifndef GL_EXT_draw_buffers
+#define GL_MAX_DRAW_BUFFERS_EXT 0x8824
+#define GL_DRAW_BUFFER0_EXT 0x8825
+#define GL_DRAW_BUFFER1_EXT 0x8826
+#define GL_DRAW_BUFFER2_EXT 0x8827
+#define GL_DRAW_BUFFER3_EXT 0x8828
+#define GL_DRAW_BUFFER4_EXT 0x8829
+#define GL_DRAW_BUFFER5_EXT 0x882A
+#define GL_DRAW_BUFFER6_EXT 0x882B
+#define GL_DRAW_BUFFER7_EXT 0x882C
+#define GL_DRAW_BUFFER8_EXT 0x882D
+#define GL_DRAW_BUFFER9_EXT 0x882E
+#define GL_DRAW_BUFFER10_EXT 0x882F
+#define GL_DRAW_BUFFER11_EXT 0x8830
+#define GL_DRAW_BUFFER12_EXT 0x8831
+#define GL_DRAW_BUFFER13_EXT 0x8832
+#define GL_DRAW_BUFFER14_EXT 0x8833
+#define GL_DRAW_BUFFER15_EXT 0x8834
+#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
+#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1
+#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2
+#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3
+#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4
+#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5
+#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6
+#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7
+#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8
+#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9
+#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA
+#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB
+#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC
+#define GL_COLOR_ATTACHMENT13_EXT 0x8CED
+#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE
+#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF
+#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF
+#endif
+
/* GL_NV_fbo_color_attachments */
#ifndef GL_NV_fbo_color_attachments
#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF
@@ -1331,6 +1369,14 @@ GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs);
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs);
#endif
+#ifndef GL_EXT_draw_buffers
+#define GL_EXT_draw_buffers 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDrawBuffersEXT (GLsizei n, const GLenum *bufs);
+#endif
+typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSEXTPROC) (GLsizei n, const GLenum *bufs);
+#endif
+
/* GL_NV_fbo_color_attachments */
#ifndef GL_NV_fbo_color_attachments
#define GL_NV_fbo_color_attachments 1
diff --git a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
index d925029a2c..da0f87aed9 100644
--- a/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
+++ b/src/3rdparty/angle/include/GLSLANG/ShaderLang.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -23,6 +23,9 @@
#define COMPILER_EXPORT
#endif
+#include "KHR/khrplatform.h"
+#include <stddef.h>
+
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -34,7 +37,7 @@ extern "C" {
// Version number for shader translation API.
// It is incremented everytime the API changes.
-#define SH_VERSION 107
+#define ANGLE_SH_VERSION 110
//
// The names of the following enums have been derived by replacing GL prefix
@@ -75,9 +78,11 @@ typedef enum {
} ShShaderSpec;
typedef enum {
- SH_ESSL_OUTPUT = 0x8B45,
- SH_GLSL_OUTPUT = 0x8B46,
- SH_HLSL_OUTPUT = 0x8B47
+ SH_ESSL_OUTPUT = 0x8B45,
+ SH_GLSL_OUTPUT = 0x8B46,
+ SH_HLSL_OUTPUT = 0x8B47,
+ SH_HLSL9_OUTPUT = 0x8B47,
+ SH_HLSL11_OUTPUT = 0x8B48
} ShShaderOutput;
typedef enum {
@@ -110,7 +115,11 @@ typedef enum {
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
- SH_MAPPED_NAME_MAX_LENGTH = 0x8B8B
+ SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
+ SH_NAME_MAX_LENGTH = 0x6001,
+ SH_HASHED_NAME_MAX_LENGTH = 0x6002,
+ SH_HASHED_NAMES_COUNT = 0x6003,
+ SH_ACTIVE_UNIFORMS_ARRAY = 0x6004
} ShShaderInfo;
// Compile options.
@@ -146,8 +155,25 @@ typedef enum {
// Enforce the GLSL 1.017 Appendix A section 7 packing restrictions.
SH_ENFORCE_PACKING_RESTRICTIONS = 0x0800,
+
+ // This flag ensures all indirect (expression-based) array indexing
+ // is clamped to the bounds of the array. This ensures, for example,
+ // that you cannot read off the end of a uniform, whether an array
+ // vec234, or mat234 type. The ShArrayIndexClampingStrategy enum,
+ // specified in the ShBuiltInResources when constructing the
+ // compiler, selects the strategy for the clamping implementation.
+ SH_CLAMP_INDIRECT_ARRAY_BOUNDS = 0x1000
} ShCompileOptions;
+// Defines alternate strategies for implementing array index clamping.
+typedef enum {
+ // Use the clamp intrinsic for array index clamping.
+ SH_CLAMP_WITH_CLAMP_INTRINSIC = 1,
+
+ // Use a user-defined function for array index clamping.
+ SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION
+} ShArrayIndexClampingStrategy;
+
//
// Driver must call this first, once, before doing any other
// compiler operations.
@@ -160,6 +186,10 @@ COMPILER_EXPORT int ShInitialize();
//
COMPILER_EXPORT int ShFinalize();
+// The 64 bits hash function. The first parameter is the input string; the
+// second parameter is the string length.
+typedef khronos_uint64_t (*ShHashFunction64)(const char*, size_t);
+
//
// Implementation dependent built-in resources (constants and extensions).
// The names for these resources has been obtained by stripping gl_/GL_.
@@ -181,6 +211,20 @@ typedef struct
int OES_standard_derivatives;
int OES_EGL_image_external;
int ARB_texture_rectangle;
+ int EXT_draw_buffers;
+
+ // Set to 1 if highp precision is supported in the fragment language.
+ // Default is 0.
+ int FragmentPrecisionHigh;
+
+ // Name Hashing.
+ // Set a 64 bit hash function to enable user-defined name hashing.
+ // Default is NULL.
+ ShHashFunction64 HashFunction;
+
+ // Selects a strategy to use when implementing array index clamping.
+ // Default is SH_CLAMP_WITH_CLAMP_INTRINSIC.
+ ShArrayIndexClampingStrategy ArrayIndexClampingStrategy;
} ShBuiltInResources;
//
@@ -207,7 +251,7 @@ typedef void* ShHandle;
// spec: Specifies the language spec the compiler must conform to -
// SH_GLES2_SPEC or SH_WEBGL_SPEC.
// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT,
-// or SH_HLSL_OUTPUT.
+// SH_HLSL9_OUTPUT or SH_HLSL11_OUTPUT.
// resources: Specifies the built-in resources.
COMPILER_EXPORT ShHandle ShConstructCompiler(
ShShaderType type,
@@ -244,7 +288,7 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
COMPILER_EXPORT int ShCompile(
const ShHandle handle,
const char* const shaderStrings[],
- const int numStrings,
+ size_t numStrings,
int compileOptions
);
@@ -267,11 +311,16 @@ COMPILER_EXPORT int ShCompile(
// 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.
+//
// params: Requested parameter
COMPILER_EXPORT void ShGetInfo(const ShHandle handle,
ShShaderInfo pname,
- int* params);
+ size_t* params);
// Returns nul-terminated information log for a compiled shader.
// Parameters:
@@ -314,7 +363,7 @@ COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
// mappedName are the same.
COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle,
int index,
- int* length,
+ size_t* length,
int* size,
ShDataType* type,
char* name,
@@ -341,12 +390,42 @@ COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle,
// mappedName are the same.
COMPILER_EXPORT void ShGetActiveUniform(const ShHandle handle,
int index,
- int* length,
+ size_t* length,
int* size,
ShDataType* type,
char* name,
char* mappedName);
+// Returns information about a name hashing entry from the latest compile.
+// 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);
+
+// Returns a parameter from a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// pname: Specifies the parameter to query.
+// The following parameters are defined:
+// SH_ACTIVE_UNIFORMS_ARRAY: an STL vector of active uniforms. Valid only for
+// HLSL output.
+// params: Requested parameter
+COMPILER_EXPORT void ShGetInfoPointer(const ShHandle handle,
+ ShShaderInfo pname,
+ void** params);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/3rdparty/angle/src/common/angleutils.h b/src/3rdparty/angle/src/common/angleutils.h
index ff9730c4da..31ac559279 100644
--- a/src/3rdparty/angle/src/common/angleutils.h
+++ b/src/3rdparty/angle/src/common/angleutils.h
@@ -15,6 +15,31 @@
TypeName(const TypeName&); \
void operator=(const TypeName&)
+template <typename T, unsigned int N>
+inline unsigned int ArraySize(T(&)[N])
+{
+ return N;
+}
+
+template <typename T, unsigned int N>
+void SafeRelease(T (&resourceBlock)[N])
+{
+ for (unsigned int i = 0; i < N; i++)
+ {
+ SafeRelease(resourceBlock[i]);
+ }
+}
+
+template <typename T>
+void SafeRelease(T& resource)
+{
+ if (resource)
+ {
+ resource->Release();
+ resource = NULL;
+ }
+}
+
#if defined(_MSC_VER)
#define snprintf _snprintf
#endif
@@ -23,4 +48,7 @@
#define VENDOR_ID_INTEL 0x8086
#define VENDOR_ID_NVIDIA 0x10DE
+#define GL_BGRA4_ANGLEX 0x6ABC
+#define GL_BGR5_A1_ANGLEX 0x6ABD
+
#endif // COMMON_ANGLEUTILS_H_
diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp
index b2238f9708..438d3975e8 100644
--- a/src/3rdparty/angle/src/common/debug.cpp
+++ b/src/3rdparty/angle/src/common/debug.cpp
@@ -7,11 +7,12 @@
// debug.cpp: Debugging utilities.
#include "common/debug.h"
-
-#include <stdio.h>
-#include <stdarg.h>
+#include "common/system.h"
+#ifdef ANGLE_ENABLE_D3D11
+typedef DWORD D3DCOLOR;
+#else
#include <d3d9.h>
-#include <windows.h>
+#endif
namespace gl
{
@@ -84,6 +85,12 @@ bool perfActive()
ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
{
#if !defined(ANGLE_DISABLE_PERF)
+#if defined(ANGLE_DISABLE_TRACE)
+ if (!perfActive())
+ {
+ return;
+ }
+#endif
va_list vararg;
va_start(vararg, format);
output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
diff --git a/src/3rdparty/angle/src/common/debug.h b/src/3rdparty/angle/src/common/debug.h
index 5f8f60fe61..23ee26d23b 100644
--- a/src/3rdparty/angle/src/common/debug.h
+++ b/src/3rdparty/angle/src/common/debug.h
@@ -99,6 +99,13 @@ namespace gl
#define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__)
#endif
+// A macro that determines whether an object has a given runtime type.
+#if !defined(NDEBUG) && (!defined(_MSC_VER) || defined(_CPPRTTI))
+#define HAS_DYNAMIC_TYPE(type, obj) (dynamic_cast<type >(obj) != NULL)
+#else
+#define HAS_DYNAMIC_TYPE(type, obj) true
+#endif
+
// A macro functioning as a compile-time assert to validate constant conditions
#define META_ASSERT(condition) typedef int COMPILE_TIME_ASSERT_##__LINE__[static_cast<bool>(condition)?1:-1]
diff --git a/src/3rdparty/angle/src/common/system.h b/src/3rdparty/angle/src/common/system.h
new file mode 100644
index 0000000000..5eb140bccd
--- /dev/null
+++ b/src/3rdparty/angle/src/common/system.h
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// system.h: Includes Windows system headers and undefines macros that conflict.
+
+#ifndef COMMON_SYSTEM_H
+#define COMMON_SYSTEM_H
+
+#if !defined(WIN32_LEAN_AND_MEAN)
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#if defined(min)
+#undef min
+#endif
+
+#if defined(max)
+#undef max
+#endif
+
+#endif // COMMON_SYSTEM_H
diff --git a/src/3rdparty/angle/src/common/version.h b/src/3rdparty/angle/src/common/version.h
index fec98a15c9..7913851e6a 100644
--- a/src/3rdparty/angle/src/common/version.h
+++ b/src/3rdparty/angle/src/common/version.h
@@ -1,10 +1,12 @@
#define MAJOR_VERSION 1
-#define MINOR_VERSION 0
+#define MINOR_VERSION 1
#define BUILD_VERSION 0
-#define BUILD_REVISION 1318
+#define BUILD_REVISION 2037
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
#define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION)
#define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION)
+
+#define VERSION_DWORD ((MAJOR_VERSION << 24) | (MINOR_VERSION << 16) | BUILD_REVISION)
diff --git a/src/3rdparty/angle/src/compiler/BaseTypes.h b/src/3rdparty/angle/src/compiler/BaseTypes.h
index 5f83185304..af4c7e3ed9 100644
--- a/src/3rdparty/angle/src/compiler/BaseTypes.h
+++ b/src/3rdparty/angle/src/compiler/BaseTypes.h
@@ -16,7 +16,7 @@ enum TPrecision
EbpUndefined,
EbpLow,
EbpMedium,
- EbpHigh,
+ EbpHigh
};
inline const char* getPrecisionString(TPrecision p)
@@ -47,7 +47,7 @@ enum TBasicType
EbtGuardSamplerEnd, // non type: see implementation of IsSampler()
EbtStruct,
EbtAddress, // should be deprecated??
- EbtInvariant, // used as a type when qualifying a previously declared variable as being invariant
+ EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
};
inline const char* getBasicString(TBasicType t)
@@ -114,7 +114,7 @@ enum TQualifier
EvqFragData,
// end of list
- EvqLast,
+ EvqLast
};
//
diff --git a/src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp b/src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp
index f46ff66d40..637ccc5e37 100644
--- a/src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/CodeGenHLSL.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -14,9 +14,11 @@
TCompiler* ConstructCompiler(
ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
{
- switch (output) {
- case SH_HLSL_OUTPUT:
- return new TranslatorHLSL(type, spec);
+ switch (output)
+ {
+ case SH_HLSL9_OUTPUT:
+ case SH_HLSL11_OUTPUT:
+ return new TranslatorHLSL(type, spec, output);
default:
return NULL;
}
diff --git a/src/3rdparty/angle/src/compiler/Compiler.cpp b/src/3rdparty/angle/src/compiler/Compiler.cpp
index 9e7f75c33a..c8c79e7147 100644
--- a/src/3rdparty/angle/src/compiler/Compiler.cpp
+++ b/src/3rdparty/angle/src/compiler/Compiler.cpp
@@ -19,6 +19,7 @@
#include "compiler/depgraph/DependencyGraphOutput.h"
#include "compiler/timing/RestrictFragmentShaderTiming.h"
#include "compiler/timing/RestrictVertexShaderTiming.h"
+#include "third_party/compiler/ArrayBoundsClamper.h"
bool isWebGLBasedSpec(ShShaderSpec spec)
{
@@ -37,6 +38,7 @@ bool InitializeSymbolTable(
// The builtins deliberately don't specify precisions for the function
// arguments and return types. For that reason we don't try to check them.
TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
+ parseContext.fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
GlobalParseContext = &parseContext;
@@ -101,6 +103,8 @@ TShHandleBase::~TShHandleBase() {
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
shaderSpec(spec),
+ fragmentPrecisionHigh(false),
+ clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
builtInFunctionEmulator(type)
{
longNameMap = LongNameMap::GetInstance();
@@ -123,12 +127,18 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
if (!InitBuiltInSymbolTable(resources))
return false;
InitExtensionBehavior(resources, extensionBehavior);
+ fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
+
+ arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
+ clampingStrategy = resources.ArrayIndexClampingStrategy;
+
+ hashFunction = resources.HashFunction;
return true;
}
bool TCompiler::compile(const char* const shaderStrings[],
- const int numStrings,
+ size_t numStrings,
int compileOptions)
{
TScopedPoolAllocator scopedAlloc(&allocator, true);
@@ -143,7 +153,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
// First string is path of source file if flag is set. The actual source follows.
const char* sourcePath = NULL;
- int firstSource = 0;
+ size_t firstSource = 0;
if (compileOptions & SH_SOURCE_PATH)
{
sourcePath = shaderStrings[0];
@@ -154,6 +164,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, compileOptions, true,
sourcePath, infoSink);
+ parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
GlobalParseContext = &parseContext;
// We preserve symbols at the built-in level from compile-to-compile.
@@ -190,10 +201,15 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
+ // Clamping uniform array bounds needs to happen after validateLimitations pass.
+ if (success && (compileOptions & SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
+ arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
+
// Call mapLongVariableNames() before collectAttribsUniforms() so in
// collectAttribsUniforms() we already have the mapped symbol names and
// we could composite mapped and original variable names.
- if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
+ // Also, if we hash all the names, then no need to do this for long names.
+ if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
mapLongVariableNames(root);
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
@@ -227,6 +243,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
{
TBuiltIns builtIns;
+ compileResources = resources;
builtIns.initialize(shaderType, shaderSpec, resources);
return InitializeSymbolTable(builtIns.getBuiltInStrings(),
shaderType, shaderSpec, resources, infoSink, symbolTable);
@@ -234,6 +251,7 @@ bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
void TCompiler::clearResults()
{
+ arrayBoundsClamper.Cleanup();
infoSink.info.erase();
infoSink.obj.erase();
infoSink.debug.erase();
@@ -242,6 +260,8 @@ void TCompiler::clearResults()
uniforms.clear();
builtInFunctionEmulator.Cleanup();
+
+ nameMap.clear();
}
bool TCompiler::detectRecursion(TIntermNode* root)
@@ -317,7 +337,7 @@ bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
void TCompiler::collectAttribsUniforms(TIntermNode* root)
{
- CollectAttribsUniforms collect(attribs, uniforms);
+ CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
root->traverse(&collect);
}
@@ -344,6 +364,21 @@ const TExtensionBehavior& TCompiler::getExtensionBehavior() const
return extensionBehavior;
}
+const ShBuiltInResources& TCompiler::getResources() const
+{
+ return compileResources;
+}
+
+const ArrayBoundsClamper& TCompiler::getArrayBoundsClamper() const
+{
+ return arrayBoundsClamper;
+}
+
+ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
+{
+ return clampingStrategy;
+}
+
const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
{
return builtInFunctionEmulator;
diff --git a/src/3rdparty/angle/src/compiler/ConstantUnion.h b/src/3rdparty/angle/src/compiler/ConstantUnion.h
index fd9d94dc5a..32af4d38b0 100644
--- a/src/3rdparty/angle/src/compiler/ConstantUnion.h
+++ b/src/3rdparty/angle/src/compiler/ConstantUnion.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -14,6 +14,7 @@ public:
ConstantUnion()
{
iConst = 0;
+ type = EbtVoid;
}
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
diff --git a/src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp b/src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp
index 472232a75d..7c3b68a0b3 100644
--- a/src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp
+++ b/src/3rdparty/angle/src/compiler/DetectDiscontinuity.cpp
@@ -16,11 +16,26 @@ namespace sh
{
bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
{
+ mLoopDepth = 0;
mLoopDiscontinuity = false;
node->traverse(this);
return mLoopDiscontinuity;
}
+bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop)
+{
+ if (visit == PreVisit)
+ {
+ ++mLoopDepth;
+ }
+ else if (visit == PostVisit)
+ {
+ --mLoopDepth;
+ }
+
+ return true;
+}
+
bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
{
if (mLoopDiscontinuity)
@@ -28,14 +43,19 @@ bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
return false;
}
+ if (!mLoopDepth)
+ {
+ return true;
+ }
+
switch (node->getFlowOp())
{
case EOpKill:
break;
case EOpBreak:
case EOpContinue:
- mLoopDiscontinuity = true;
case EOpReturn:
+ mLoopDiscontinuity = true;
break;
default: UNREACHABLE();
}
diff --git a/src/3rdparty/angle/src/compiler/DetectDiscontinuity.h b/src/3rdparty/angle/src/compiler/DetectDiscontinuity.h
index 8bda4c3dea..e5520bd5b0 100644
--- a/src/3rdparty/angle/src/compiler/DetectDiscontinuity.h
+++ b/src/3rdparty/angle/src/compiler/DetectDiscontinuity.h
@@ -23,8 +23,10 @@ class DetectLoopDiscontinuity : public TIntermTraverser
protected:
bool visitBranch(Visit visit, TIntermBranch *node);
+ bool visitLoop(Visit visit, TIntermLoop *loop);
bool visitAggregate(Visit visit, TIntermAggregate *node);
+ int mLoopDepth;
bool mLoopDiscontinuity;
};
diff --git a/src/3rdparty/angle/src/compiler/Diagnostics.cpp b/src/3rdparty/angle/src/compiler/Diagnostics.cpp
index 8aa1cb6b24..06f370dbe5 100644
--- a/src/3rdparty/angle/src/compiler/Diagnostics.cpp
+++ b/src/3rdparty/angle/src/compiler/Diagnostics.cpp
@@ -8,7 +8,7 @@
#include "compiler/debug.h"
#include "compiler/InfoSink.h"
-#include "compiler/preprocessor/new/SourceLocation.h"
+#include "compiler/preprocessor/SourceLocation.h"
TDiagnostics::TDiagnostics(TInfoSink& infoSink) :
mInfoSink(infoSink),
diff --git a/src/3rdparty/angle/src/compiler/Diagnostics.h b/src/3rdparty/angle/src/compiler/Diagnostics.h
index 3670414b03..cb71bb1204 100644
--- a/src/3rdparty/angle/src/compiler/Diagnostics.h
+++ b/src/3rdparty/angle/src/compiler/Diagnostics.h
@@ -7,7 +7,7 @@
#ifndef COMPILER_DIAGNOSTICS_H_
#define COMPILER_DIAGNOSTICS_H_
-#include "compiler/preprocessor/new/Diagnostics.h"
+#include "compiler/preprocessor/DiagnosticsBase.h"
class TInfoSink;
diff --git a/src/3rdparty/angle/src/compiler/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/DirectiveHandler.h
index 21d3dfc315..95ca59d6fe 100644
--- a/src/3rdparty/angle/src/compiler/DirectiveHandler.h
+++ b/src/3rdparty/angle/src/compiler/DirectiveHandler.h
@@ -9,7 +9,7 @@
#include "compiler/ExtensionBehavior.h"
#include "compiler/Pragma.h"
-#include "compiler/preprocessor/new/DirectiveHandler.h"
+#include "compiler/preprocessor/DirectiveHandlerBase.h"
class TDiagnostics;
diff --git a/src/3rdparty/angle/src/compiler/ExtensionBehavior.h b/src/3rdparty/angle/src/compiler/ExtensionBehavior.h
index 6040980837..5c1595fb21 100644
--- a/src/3rdparty/angle/src/compiler/ExtensionBehavior.h
+++ b/src/3rdparty/angle/src/compiler/ExtensionBehavior.h
@@ -16,7 +16,7 @@ typedef enum
EBhEnable,
EBhWarn,
EBhDisable,
- EBhUndefined,
+ EBhUndefined
} TBehavior;
inline const char* getBehaviorString(TBehavior b)
diff --git a/src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp b/src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp
index fdc3f44431..27a13eabab 100644
--- a/src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp
+++ b/src/3rdparty/angle/src/compiler/ForLoopUnroll.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -210,6 +210,6 @@ int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
{
ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL));
- return node->getUnionArrayPointer()->getIConst();
+ return node->getIConst(0);
}
diff --git a/src/3rdparty/angle/src/compiler/HashNames.h b/src/3rdparty/angle/src/compiler/HashNames.h
new file mode 100644
index 0000000000..d2141e2d85
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/HashNames.h
@@ -0,0 +1,19 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_HASH_NAMES_H_
+#define COMPILER_HASH_NAMES_H_
+
+#include <map>
+
+#include "compiler/intermediate.h"
+#include "GLSLANG/ShaderLang.h"
+
+#define HASHED_NAME_PREFIX "webgl_"
+
+typedef std::map<TPersistString, TPersistString> NameMap;
+
+#endif // COMPILER_HASH_NAMES_H_
diff --git a/src/3rdparty/angle/src/compiler/Initialize.cpp b/src/3rdparty/angle/src/compiler/Initialize.cpp
index 3e94ce7ba8..97b46f898e 100644
--- a/src/3rdparty/angle/src/compiler/Initialize.cpp
+++ b/src/3rdparty/angle/src/compiler/Initialize.cpp
@@ -654,4 +654,6 @@ void InitExtensionBehavior(const ShBuiltInResources& resources,
extBehavior["GL_OES_EGL_image_external"] = EBhUndefined;
if (resources.ARB_texture_rectangle)
extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
+ if (resources.EXT_draw_buffers)
+ extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
}
diff --git a/src/3rdparty/angle/src/compiler/Intermediate.cpp b/src/3rdparty/angle/src/compiler/Intermediate.cpp
index 92c450530e..edf279ef67 100644
--- a/src/3rdparty/angle/src/compiler/Intermediate.cpp
+++ b/src/3rdparty/angle/src/compiler/Intermediate.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -12,6 +12,7 @@
#include <limits.h>
#include <algorithm>
+#include "compiler/HashNames.h"
#include "compiler/localintermediate.h"
#include "compiler/QualifierAlive.h"
#include "compiler/RemoveTree.h"
@@ -592,7 +593,7 @@ TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nod
//
if (cond->getAsTyped() && cond->getAsTyped()->getAsConstantUnion()) {
- if (cond->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getBConst() == true)
+ if (cond->getAsConstantUnion()->getBConst(0) == true)
return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1->getLine()) : NULL;
else
return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2->getLine()) : NULL;
@@ -646,7 +647,7 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* true
//
if (cond->getAsConstantUnion() && trueBlock->getAsConstantUnion() && falseBlock->getAsConstantUnion()) {
- if (cond->getAsConstantUnion()->getUnionArrayPointer()->getBConst())
+ if (cond->getAsConstantUnion()->getBConst(0))
return trueBlock;
else
return falseBlock;
@@ -845,6 +846,7 @@ bool TIntermUnary::promote(TInfoSink&)
}
setType(operand->getType());
+ type.setQualifier(EvqTemporary);
return true;
}
@@ -1161,7 +1163,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
case EbtFloat:
if (rightUnionArray[i] == 0.0f) {
infoSink.info.message(EPrefixWarning, "Divide by zero error during constant folding", getLine());
- tempConstArray[i].setFConst(FLT_MAX);
+ tempConstArray[i].setFConst(unionArray[i].getFConst() < 0 ? -FLT_MAX : FLT_MAX);
} else
tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
break;
@@ -1376,7 +1378,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod
TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
{
- ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
int size = node->getType().getObjectSize();
ConstantUnion *leftUnionArray = new ConstantUnion[size];
@@ -1387,13 +1388,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtFloat:
switch (node->getType().getBasicType()) {
case EbtInt:
- leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getIConst()));
+ leftUnionArray[i].setFConst(static_cast<float>(node->getIConst(i)));
break;
case EbtBool:
- leftUnionArray[i].setFConst(static_cast<float>(rightUnionArray[i].getBConst()));
+ leftUnionArray[i].setFConst(static_cast<float>(node->getBConst(i)));
break;
case EbtFloat:
- leftUnionArray[i] = rightUnionArray[i];
+ leftUnionArray[i].setFConst(static_cast<float>(node->getFConst(i)));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
@@ -1403,13 +1404,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtInt:
switch (node->getType().getBasicType()) {
case EbtInt:
- leftUnionArray[i] = rightUnionArray[i];
+ leftUnionArray[i].setIConst(static_cast<int>(node->getIConst(i)));
break;
case EbtBool:
- leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getBConst()));
+ leftUnionArray[i].setIConst(static_cast<int>(node->getBConst(i)));
break;
case EbtFloat:
- leftUnionArray[i].setIConst(static_cast<int>(rightUnionArray[i].getFConst()));
+ leftUnionArray[i].setIConst(static_cast<int>(node->getFConst(i)));
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
@@ -1419,13 +1420,13 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtBool:
switch (node->getType().getBasicType()) {
case EbtInt:
- leftUnionArray[i].setBConst(rightUnionArray[i].getIConst() != 0);
+ leftUnionArray[i].setBConst(node->getIConst(i) != 0);
break;
case EbtBool:
- leftUnionArray[i] = rightUnionArray[i];
+ leftUnionArray[i].setBConst(node->getBConst(i));
break;
case EbtFloat:
- leftUnionArray[i].setBConst(rightUnionArray[i].getFConst() != 0.0f);
+ leftUnionArray[i].setBConst(node->getFConst(i) != 0.0f);
break;
default:
infoSink.info.message(EPrefixInternalError, "Cannot promote", node->getLine());
@@ -1445,3 +1446,14 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node->getLine());
}
+// static
+TString TIntermTraverser::hash(const TString& name, ShHashFunction64 hashFunction)
+{
+ if (hashFunction == NULL || name.empty())
+ return name;
+ khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
+ TStringStream stream;
+ stream << HASHED_NAME_PREFIX << std::hex << number;
+ TString hashedName = stream.str();
+ return hashedName;
+}
diff --git a/src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp b/src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp
index a50310154d..a41d20f4e8 100644
--- a/src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp
+++ b/src/3rdparty/angle/src/compiler/MapLongVariableNames.cpp
@@ -8,7 +8,7 @@
namespace {
-TString mapLongName(int id, const TString& name, bool isGlobal)
+TString mapLongName(size_t id, const TString& name, bool isGlobal)
{
ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE);
TStringStream stream;
@@ -70,7 +70,7 @@ void LongNameMap::Insert(const char* originalName, const char* mappedName)
originalName, mappedName));
}
-int LongNameMap::Size() const
+size_t LongNameMap::Size() const
{
return mLongNameMap.size();
}
@@ -115,7 +115,7 @@ TString MapLongVariableNames::mapGlobalLongName(const TString& name)
const char* mappedName = mGlobalMap->Find(name.c_str());
if (mappedName != NULL)
return mappedName;
- int id = mGlobalMap->Size();
+ size_t id = mGlobalMap->Size();
TString rt = mapLongName(id, name, true);
mGlobalMap->Insert(name.c_str(), rt.c_str());
return rt;
diff --git a/src/3rdparty/angle/src/compiler/MapLongVariableNames.h b/src/3rdparty/angle/src/compiler/MapLongVariableNames.h
index fb2c7e81cb..d6352acb4b 100644
--- a/src/3rdparty/angle/src/compiler/MapLongVariableNames.h
+++ b/src/3rdparty/angle/src/compiler/MapLongVariableNames.h
@@ -31,7 +31,7 @@ public:
void Insert(const char* originalName, const char* mappedName);
// Return the number of entries in the map.
- int Size() const;
+ size_t Size() const;
private:
LongNameMap();
diff --git a/src/3rdparty/angle/src/compiler/OutputESSL.cpp b/src/3rdparty/angle/src/compiler/OutputESSL.cpp
index 64ee92d44e..c2048f1cec 100644
--- a/src/3rdparty/angle/src/compiler/OutputESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputESSL.cpp
@@ -6,8 +6,12 @@
#include "compiler/OutputESSL.h"
-TOutputESSL::TOutputESSL(TInfoSinkBase& objSink)
- : TOutputGLSLBase(objSink)
+TOutputESSL::TOutputESSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
+ : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/3rdparty/angle/src/compiler/OutputESSL.h b/src/3rdparty/angle/src/compiler/OutputESSL.h
index 4fa73c8047..05db96e497 100644
--- a/src/3rdparty/angle/src/compiler/OutputESSL.h
+++ b/src/3rdparty/angle/src/compiler/OutputESSL.h
@@ -12,7 +12,11 @@
class TOutputESSL : public TOutputGLSLBase
{
public:
- TOutputESSL(TInfoSinkBase& objSink);
+ TOutputESSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision precision);
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSL.cpp b/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
index dd31b4b58b..206f403408 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputGLSL.cpp
@@ -6,8 +6,12 @@
#include "compiler/OutputGLSL.h"
-TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
- : TOutputGLSLBase(objSink)
+TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
+ : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
{
}
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSL.h b/src/3rdparty/angle/src/compiler/OutputGLSL.h
index 0fe2356eb7..199b6f3e46 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSL.h
+++ b/src/3rdparty/angle/src/compiler/OutputGLSL.h
@@ -12,7 +12,11 @@
class TOutputGLSL : public TOutputGLSLBase
{
public:
- TOutputGLSL(TInfoSinkBase& objSink);
+ TOutputGLSL(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
virtual bool writeVariablePrecision(TPrecision);
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp b/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
index 552fa5066d..1b9a10deaa 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputGLSLBase.cpp
@@ -7,37 +7,10 @@
#include "compiler/OutputGLSLBase.h"
#include "compiler/debug.h"
+#include <cfloat>
+
namespace
{
-TString getTypeName(const TType& type)
-{
- TInfoSinkBase out;
- if (type.isMatrix())
- {
- out << "mat";
- out << type.getNominalSize();
- }
- else if (type.isVector())
- {
- switch (type.getBasicType())
- {
- case EbtFloat: out << "vec"; break;
- case EbtInt: out << "ivec"; break;
- case EbtBool: out << "bvec"; break;
- default: UNREACHABLE(); break;
- }
- out << type.getNominalSize();
- }
- else
- {
- if (type.getBasicType() == EbtStruct)
- out << type.getTypeName();
- else
- out << type.getBasicString();
- }
- return TString(out.c_str());
-}
-
TString arrayBrackets(const TType& type)
{
ASSERT(type.isArray());
@@ -66,10 +39,18 @@ bool isSingleStatement(TIntermNode* node) {
}
} // namespace
-TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink)
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
- mDeclaringVariables(false)
+ mDeclaringVariables(false),
+ mClampingStrategy(clampingStrategy),
+ mHashFunction(hashFunction),
+ mNameMap(nameMap),
+ mSymbolTable(symbolTable)
{
}
@@ -101,7 +82,7 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
if ((type.getBasicType() == EbtStruct) &&
(mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end()))
{
- out << "struct " << type.getTypeName() << "{\n";
+ out << "struct " << hashName(type.getTypeName()) << "{\n";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -110,7 +91,7 @@ void TOutputGLSLBase::writeVariableType(const TType& type)
ASSERT(fieldType != NULL);
if (writeVariablePrecision(fieldType->getPrecision()))
out << " ";
- out << getTypeName(*fieldType) << " " << fieldType->getFieldName();
+ out << getTypeName(*fieldType) << " " << hashName(fieldType->getFieldName());
if (fieldType->isArray())
out << arrayBrackets(*fieldType);
out << ";\n";
@@ -140,7 +121,7 @@ void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args)
const TString& name = arg->getSymbol();
if (!name.empty())
- out << " " << name;
+ out << " " << hashName(name);
if (type.isArray())
out << arrayBrackets(type);
@@ -157,7 +138,7 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
if (type.getBasicType() == EbtStruct)
{
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
const TTypeList* structure = type.getStruct();
ASSERT(structure != NULL);
for (size_t i = 0; i < structure->size(); ++i)
@@ -178,7 +159,7 @@ const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type,
{
switch (pConstUnion->getType())
{
- case EbtFloat: out << pConstUnion->getFConst(); break;
+ case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion->getFConst())); break;
case EbtInt: out << pConstUnion->getIConst(); break;
case EbtBool: out << pConstUnion->getBConst(); break;
default: UNREACHABLE();
@@ -196,7 +177,7 @@ void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
out << mLoopUnroll.GetLoopIndexValue(node);
else
- out << node->getSymbol();
+ out << hashVariableName(node->getSymbol());
if (mDeclaringVariables && node->getType().isArray())
out << arrayBrackets(node->getType());
@@ -235,15 +216,59 @@ bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
break;
case EOpIndexDirect:
- case EOpIndexIndirect:
writeTriplet(visit, NULL, "[", "]");
break;
+ case EOpIndexIndirect:
+ if (node->getAddIndexClamp())
+ {
+ if (visit == InVisit)
+ {
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+ out << "[int(clamp(float(";
+ } else {
+ out << "[webgl_int_clamp(";
+ }
+ }
+ else if (visit == PostVisit)
+ {
+ int maxSize;
+ TIntermTyped *left = node->getLeft();
+ TType leftType = left->getType();
+
+ if (left->isArray())
+ {
+ // The shader will fail validation if the array length is not > 0.
+ maxSize = leftType.getArraySize() - 1;
+ }
+ else
+ {
+ maxSize = leftType.getNominalSize() - 1;
+ }
+
+ if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+ out << "), 0.0, float(" << maxSize << ")))]";
+ } else {
+ out << ", 0, " << maxSize << ")]";
+ }
+ }
+ }
+ else
+ {
+ writeTriplet(visit, NULL, "[", "]");
+ }
+ break;
case EOpIndexDirectStruct:
if (visit == InVisit)
{
out << ".";
// TODO(alokp): ASSERT
- out << node->getType().getFieldName();
+ TString fieldName = node->getType().getFieldName();
+
+ const TType& structType = node->getLeft()->getType();
+ if (!mSymbolTable.findBuiltIn(structType.getTypeName()))
+ fieldName = hashName(fieldName);
+
+ out << fieldName;
visitChildren = false;
}
break;
@@ -467,7 +492,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function declaration.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << node->getName();
+ out << " " << hashName(node->getName());
out << "(";
writeFunctionParameters(node->getSequence());
@@ -480,7 +505,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function definition.
ASSERT(visit == PreVisit);
writeVariableType(node->getType());
- out << " " << TFunction::unmangleName(node->getName());
+ out << " " << hashFunctionName(node->getName());
incrementDepth();
// Function definition node contains one or two children nodes
@@ -510,8 +535,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
// Function call.
if (visit == PreVisit)
{
- TString functionName = TFunction::unmangleName(node->getName());
- out << functionName << "(";
+ out << hashFunctionName(node->getName()) << "(";
}
else if (visit == InVisit)
{
@@ -572,7 +596,7 @@ bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
{
const TType& type = node->getType();
ASSERT(type.getBasicType() == EbtStruct);
- out << type.getTypeName() << "(";
+ out << hashName(type.getTypeName()) << "(";
}
else if (visit == InVisit)
{
@@ -718,3 +742,59 @@ void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
out << "{\n}\n"; // Empty code block.
}
}
+
+TString TOutputGLSLBase::getTypeName(const TType& type)
+{
+ TInfoSinkBase out;
+ if (type.isMatrix())
+ {
+ out << "mat";
+ out << type.getNominalSize();
+ }
+ else if (type.isVector())
+ {
+ switch (type.getBasicType())
+ {
+ case EbtFloat: out << "vec"; break;
+ case EbtInt: out << "ivec"; break;
+ case EbtBool: out << "bvec"; break;
+ default: UNREACHABLE(); break;
+ }
+ out << type.getNominalSize();
+ }
+ else
+ {
+ if (type.getBasicType() == EbtStruct)
+ out << hashName(type.getTypeName());
+ else
+ out << type.getBasicString();
+ }
+ return TString(out.c_str());
+}
+
+TString TOutputGLSLBase::hashName(const TString& name)
+{
+ if (mHashFunction == NULL || name.empty())
+ return name;
+ NameMap::const_iterator it = mNameMap.find(name.c_str());
+ if (it != mNameMap.end())
+ return it->second.c_str();
+ TString hashedName = TIntermTraverser::hash(name, mHashFunction);
+ mNameMap[name.c_str()] = hashedName.c_str();
+ return hashedName;
+}
+
+TString TOutputGLSLBase::hashVariableName(const TString& name)
+{
+ if (mSymbolTable.findBuiltIn(name) != NULL)
+ return name;
+ return hashName(name);
+}
+
+TString TOutputGLSLBase::hashFunctionName(const TString& mangled_name)
+{
+ TString name = TFunction::unmangleName(mangled_name);
+ if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == "main")
+ return name;
+ return hashName(name);
+}
diff --git a/src/3rdparty/angle/src/compiler/OutputGLSLBase.h b/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
index efd0b5fc2d..c9f72d5631 100644
--- a/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
+++ b/src/3rdparty/angle/src/compiler/OutputGLSLBase.h
@@ -16,7 +16,11 @@
class TOutputGLSLBase : public TIntermTraverser
{
public:
- TOutputGLSLBase(TInfoSinkBase& objSink);
+ TOutputGLSLBase(TInfoSinkBase& objSink,
+ ShArrayIndexClampingStrategy clampingStrategy,
+ ShHashFunction64 hashFunction,
+ NameMap& nameMap,
+ TSymbolTable& symbolTable);
protected:
TInfoSinkBase& objSink() { return mObjSink; }
@@ -25,6 +29,7 @@ protected:
virtual bool writeVariablePrecision(TPrecision precision) = 0;
void writeFunctionParameters(const TIntermSequence& args);
const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion);
+ TString getTypeName(const TType& type);
virtual void visitSymbol(TIntermSymbol* node);
virtual void visitConstantUnion(TIntermConstantUnion* node);
@@ -37,6 +42,15 @@ protected:
void visitCodeBlock(TIntermNode* node);
+
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name.
+ TString hashName(const TString& name);
+ // Same as hashName(), but without hashing built-in variables.
+ TString hashVariableName(const TString& name);
+ // Same as hashName(), but without hashing built-in functions.
+ TString hashFunctionName(const TString& mangled_name);
+
private:
TInfoSinkBase& mObjSink;
bool mDeclaringVariables;
@@ -48,6 +62,15 @@ private:
DeclaredStructs mDeclaredStructs;
ForLoopUnroll mLoopUnroll;
+
+ ShArrayIndexClampingStrategy mClampingStrategy;
+
+ // name hashing.
+ ShHashFunction64 mHashFunction;
+
+ NameMap& mNameMap;
+
+ TSymbolTable& mSymbolTable;
};
#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
diff --git a/src/3rdparty/angle/src/compiler/OutputHLSL.cpp b/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
index a430695744..f6a984148b 100644
--- a/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/OutputHLSL.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,13 +8,14 @@
#include "common/angleutils.h"
#include "compiler/debug.h"
+#include "compiler/DetectDiscontinuity.h"
#include "compiler/InfoSink.h"
-#include "compiler/UnfoldShortCircuit.h"
#include "compiler/SearchSymbol.h"
-#include "compiler/DetectDiscontinuity.h"
+#include "compiler/UnfoldShortCircuit.h"
-#include <stdio.h>
#include <algorithm>
+#include <cfloat>
+#include <stdio.h>
namespace sh
{
@@ -26,7 +27,8 @@ TString str(int i)
return buffer;
}
-OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, true), mContext(context)
+OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType)
+ : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
{
mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
mInsideFunction = false;
@@ -46,6 +48,8 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesTexture2DProjLod0_bias = false;
mUsesTextureCubeLod0 = false;
mUsesTextureCubeLod0_bias = false;
+ mUsesFragColor = false;
+ mUsesFragData = false;
mUsesDepthRange = false;
mUsesFragCoord = false;
mUsesPointCoord = false;
@@ -80,6 +84,8 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mUsesAtan2_3 = false;
mUsesAtan2_4 = false;
+ mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
+
mScopeDepth = 0;
mUniqueIndex = 0;
@@ -89,6 +95,24 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mInsideDiscontinuousLoop = false;
mExcessiveLoopIndex = NULL;
+
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ if (mContext.shaderType == SH_FRAGMENT_SHADER)
+ {
+ mUniformRegister = 3; // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
+ }
+ else
+ {
+ mUniformRegister = 2; // Reserve registers for dx_DepthRange and dx_ViewAdjust
+ }
+ }
+ else
+ {
+ mUniformRegister = 0;
+ }
+
+ mSamplerRegister = 0;
}
OutputHLSL::~OutputHLSL()
@@ -98,7 +122,7 @@ OutputHLSL::~OutputHLSL()
void OutputHLSL::output()
{
- mContainsLoopDiscontinuity = containsLoopDiscontinuity(mContext.treeRoot);
+ mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER && containsLoopDiscontinuity(mContext.treeRoot);
mContext.treeRoot->traverse(this); // Output the body first to determine what has to go in the header
header();
@@ -112,6 +136,11 @@ TInfoSinkBase &OutputHLSL::getBodyStream()
return mBody;
}
+const ActiveUniforms &OutputHLSL::getUniforms()
+{
+ return mActiveUniforms;
+}
+
int OutputHLSL::vectorSize(const TType &type) const
{
int elementSize = type.isMatrix() ? type.getNominalSize() : 1;
@@ -135,58 +164,71 @@ void OutputHLSL::header()
out << *constructor;
}
- if (shaderType == SH_FRAGMENT_SHADER)
+ TString uniforms;
+ TString varyings;
+ TString attributes;
+
+ for (ReferencedSymbols::const_iterator uniform = mReferencedUniforms.begin(); uniform != mReferencedUniforms.end(); uniform++)
{
- TString uniforms;
- TString varyings;
+ const TType &type = uniform->second->getType();
+ const TString &name = uniform->second->getSymbol();
- TSymbolTableLevel *symbols = mContext.symbolTable.getGlobalLevel();
- int semanticIndex = 0;
+ if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType())) // Also declare the texture
+ {
+ int index = samplerRegister(mReferencedUniforms[name]);
+
+ uniforms += "uniform SamplerState sampler_" + decorateUniform(name, type) + arrayString(type) +
+ " : register(s" + str(index) + ");\n";
- for (TSymbolTableLevel::const_iterator namedSymbol = symbols->begin(); namedSymbol != symbols->end(); namedSymbol++)
+ uniforms += "uniform " + textureString(type) + " texture_" + decorateUniform(name, type) + arrayString(type) +
+ " : register(t" + str(index) + ");\n";
+ }
+ else
{
- const TSymbol *symbol = (*namedSymbol).second;
- const TString &name = symbol->getName();
+ uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) +
+ " : register(" + registerString(mReferencedUniforms[name]) + ");\n";
+ }
+ }
- if (symbol->isVariable())
- {
- const TVariable *variable = static_cast<const TVariable*>(symbol);
- const TType &type = variable->getType();
- TQualifier qualifier = type.getQualifier();
+ for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
+ {
+ const TType &type = varying->second->getType();
+ const TString &name = varying->second->getSymbol();
- if (qualifier == EvqUniform)
- {
- if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end())
- {
- uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) + ";\n";
- }
- }
- else if (qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
- {
- if (mReferencedVaryings.find(name.c_str()) != mReferencedVaryings.end())
- {
- // Program linking depends on this exact format
- varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
+ // Program linking depends on this exact format
+ varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
+ }
- semanticIndex += type.isArray() ? type.getArraySize() : 1;
- }
- }
- else if (qualifier == EvqGlobal || qualifier == EvqTemporary)
- {
- // Globals are declared and intialized as an aggregate node
- }
- else if (qualifier == EvqConst)
- {
- // Constants are repeated as literals where used
- }
- else UNREACHABLE();
- }
- }
+ for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
+ {
+ const TType &type = attribute->second->getType();
+ const TString &name = attribute->second->getSymbol();
+
+ attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
+ }
+
+ if (shaderType == SH_FRAGMENT_SHADER)
+ {
+ TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find("GL_EXT_draw_buffers");
+ bool usingMRTExtension = iter != mContext.extensionBehavior().end() && iter->second == EBhEnable;
+
+ unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
out << "// Varyings\n";
out << varyings;
out << "\n"
- "static float4 gl_Color[1] = {float4(0, 0, 0, 0)};\n";
+ "static float4 gl_Color[" << numColorValues << "] =\n"
+ "{\n";
+ for (unsigned int i = 0; i < numColorValues; i++)
+ {
+ out << " float4(0, 0, 0, 0)";
+ if (i + 1 != numColorValues)
+ {
+ out << ",";
+ }
+ out << "\n";
+ }
+ out << "};\n";
if (mUsesFragCoord)
{
@@ -205,205 +247,379 @@ void OutputHLSL::header()
out << "\n";
- if (mUsesFragCoord)
+ if (mUsesDepthRange)
+ {
+ out << "struct gl_DepthRangeParameters\n"
+ "{\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
+ "\n";
+ }
+
+ if (mOutputType == SH_HLSL11_OUTPUT)
{
- out << "uniform float4 dx_Coord;\n"
- "uniform float2 dx_Depth;\n";
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n";
+
+ if (mUsesDepthRange)
+ {
+ out << " float3 dx_DepthRange : packoffset(c0);\n";
+ }
+
+ if (mUsesFragCoord)
+ {
+ out << " float4 dx_ViewCoords : packoffset(c1);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << " float3 dx_DepthFront : packoffset(c2);\n";
+ }
+
+ out << "};\n";
}
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);";
+ }
- if (mUsesFrontFacing)
+ if (mUsesFragCoord)
+ {
+ out << "uniform float4 dx_ViewCoords : register(c1);\n";
+ }
+
+ if (mUsesFragCoord || mUsesFrontFacing)
+ {
+ out << "uniform float3 dx_DepthFront : register(c2);\n";
+ }
+ }
+
+ out << "\n";
+
+ if (mUsesDepthRange)
{
- out << "uniform bool dx_PointsOrLines;\n"
- "uniform bool dx_FrontCCW;\n";
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
+ "\n";
}
- out << "\n";
out << uniforms;
out << "\n";
if (mUsesTexture2D)
{
- out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
- "{\n"
- " return tex2D(s, t);\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
+ "{\n"
+ " return tex2D(s, t);\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n"
+ "{\n"
+ " return t.Sample(s, uv);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2D_bias)
{
- out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n"
- "{\n"
- " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n"
+ "{\n"
+ " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv, float bias)\n"
+ "{\n"
+ " return t.SampleBias(s, uv, bias);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2DProj)
{
- out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
- "{\n"
- " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
- "{\n"
- " return tex2Dproj(s, t);\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
+ "{\n"
+ " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
+ "{\n"
+ " return tex2Dproj(s, t);\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.Sample(s, float2(uvw.x / uvw.z, uvw.y / uvw.z));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
+ "{\n"
+ " return t.Sample(s, float2(uvw.x / uvw.w, uvw.y / uvw.w));\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2DProj_bias)
{
- out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n"
- "{\n"
- " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n"
- "{\n"
- " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n"
+ "{\n"
+ " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n"
+ "{\n"
+ " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleBias(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), bias);\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleBias(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), bias);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCube)
{
- out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
- "{\n"
- " return texCUBE(s, t);\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
+ "{\n"
+ " return texCUBE(s, t);\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.Sample(s, uvw);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCube_bias)
{
- out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n"
- "{\n"
- " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n"
+ "{\n"
+ " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleBias(s, uvw, bias);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
// These *Lod0 intrinsics are not available in GL fragment shaders.
// They are used to sample using discontinuous texture coordinates.
if (mUsesTexture2DLod0)
{
- out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod0(sampler2D s, float2 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv)\n"
+ "{\n"
+ " return t.SampleLevel(s, uv, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2DLod0_bias)
{
- out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv, float bias)\n"
+ "{\n"
+ " return t.SampleLevel(s, uv, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2DProjLod0)
{
- out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProjLod(sampler2D s, float4 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float4 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTexture2DProjLod0_bias)
{
- out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float3 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float4 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCubeLod0)
{
- out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n"
- "{\n"
- " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n"
+ "{\n"
+ " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, uvw, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCubeLod0_bias)
{
- out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n"
- "{\n"
- " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n"
+ "{\n"
+ " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw, float bias)\n"
+ "{\n"
+ " return t.SampleLevel(s, uvw, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
- }
- else // Vertex shader
- {
- TString uniforms;
- TString attributes;
- TString varyings;
- TSymbolTableLevel *symbols = mContext.symbolTable.getGlobalLevel();
-
- for (TSymbolTableLevel::const_iterator namedSymbol = symbols->begin(); namedSymbol != symbols->end(); namedSymbol++)
+ if (usingMRTExtension && mNumRenderTargets > 1)
{
- const TSymbol *symbol = (*namedSymbol).second;
- const TString &name = symbol->getName();
-
- if (symbol->isVariable())
- {
- const TVariable *variable = static_cast<const TVariable*>(symbol);
- const TType &type = variable->getType();
- TQualifier qualifier = type.getQualifier();
+ out << "#define GL_USES_MRT\n";
+ }
- if (qualifier == EvqUniform)
- {
- if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end())
- {
- uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) + ";\n";
- }
- }
- else if (qualifier == EvqAttribute)
- {
- if (mReferencedAttributes.find(name.c_str()) != mReferencedAttributes.end())
- {
- attributes += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
- }
- }
- else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut)
- {
- if (mReferencedVaryings.find(name.c_str()) != mReferencedVaryings.end())
- {
- // Program linking depends on this exact format
- varyings += "static " + typeString(type) + " " + decorate(name) + arrayString(type) + " = " + initializer(type) + ";\n";
- }
- }
- else if (qualifier == EvqGlobal || qualifier == EvqTemporary)
- {
- // Globals are declared and intialized as an aggregate node
- }
- else if (qualifier == EvqConst)
- {
- // Constants are repeated as literals where used
- }
- else UNREACHABLE();
- }
+ if (mUsesFragColor)
+ {
+ out << "#define GL_USES_FRAG_COLOR\n";
}
+ if (mUsesFragData)
+ {
+ out << "#define GL_USES_FRAG_DATA\n";
+ }
+ }
+ else // Vertex shader
+ {
out << "// Attributes\n";
out << attributes;
out << "\n"
@@ -417,74 +633,194 @@ void OutputHLSL::header()
out << "\n"
"// Varyings\n";
out << varyings;
- out << "\n"
- "uniform float2 dx_HalfPixelSize;\n"
- "\n";
- out << uniforms;
out << "\n";
-
- if (mUsesTexture2D)
+
+ if (mUsesDepthRange)
{
- out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
+ out << "struct gl_DepthRangeParameters\n"
"{\n"
- " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
- "}\n"
+ " float near;\n"
+ " float far;\n"
+ " float diff;\n"
+ "};\n"
"\n";
}
- if (mUsesTexture2DLod)
+ if (mOutputType == SH_HLSL11_OUTPUT)
{
- out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x, t.y, 0, lod));\n"
- "}\n"
+ if (mUsesDepthRange)
+ {
+ out << "cbuffer DriverConstants : register(b1)\n"
+ "{\n"
+ " float3 dx_DepthRange : packoffset(c0);\n"
+ "};\n"
+ "\n";
+ }
+ }
+ else
+ {
+ if (mUsesDepthRange)
+ {
+ out << "uniform float3 dx_DepthRange : register(c0);\n";
+ }
+
+ out << "uniform float4 dx_ViewAdjust : register(c1);\n"
"\n";
}
- if (mUsesTexture2DProj)
+ if (mUsesDepthRange)
{
- out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
- "}\n"
+ out << "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
"\n";
}
+ out << uniforms;
+ out << "\n";
+
+ if (mUsesTexture2D)
+ {
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2D(sampler2D s, float2 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n"
+ "{\n"
+ " return t.SampleLevel(s, uv, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
+ }
+
+ if (mUsesTexture2DLod)
+ {
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x, t.y, 0, lod));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DLod(Texture2D t, SamplerState s, float2 uv, float lod)\n"
+ "{\n"
+ " return t.SampleLevel(s, uv, lod);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
+ }
+
+ if (mUsesTexture2DProj)
+ {
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(sampler2D s, float4 t)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
+ }
+
if (mUsesTexture2DProjLod)
{
- out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, lod));\n"
- "}\n"
- "\n"
- "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n"
- "{\n"
- " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, lod));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, lod));\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n"
+ "{\n"
+ " return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, lod));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float lod)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), lod);\n"
+ "}\n"
+ "\n"
+ "float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), lod);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCube)
{
- out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
- "{\n"
- " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n"
+ "{\n"
+ " return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n"
+ "{\n"
+ " return t.SampleLevel(s, uvw, 0);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
if (mUsesTextureCubeLod)
{
- out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n"
- "{\n"
- " return texCUBElod(s, float4(t.x, t.y, t.z, lod));\n"
- "}\n"
- "\n";
+ if (mOutputType == SH_HLSL9_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n"
+ "{\n"
+ " return texCUBElod(s, float4(t.x, t.y, t.z, lod));\n"
+ "}\n"
+ "\n";
+ }
+ else if (mOutputType == SH_HLSL11_OUTPUT)
+ {
+ out << "float4 gl_textureCubeLod(TextureCube t, SamplerState s, float3 uvw, float lod)\n"
+ "{\n"
+ " return t.SampleLevel(s, uvw, lod);\n"
+ "}\n"
+ "\n";
+ }
+ else UNREACHABLE();
}
}
@@ -508,20 +844,6 @@ void OutputHLSL::header()
out << "#define GL_USES_POINT_SIZE\n";
}
- if (mUsesDepthRange)
- {
- out << "struct gl_DepthRangeParameters\n"
- "{\n"
- " float near;\n"
- " float far;\n"
- " float diff;\n"
- "};\n"
- "\n"
- "uniform float3 dx_DepthRange;"
- "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
- "\n";
- }
-
if (mUsesXor)
{
out << "bool xor(bool p, bool q)\n"
@@ -812,10 +1134,12 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
if (name == "gl_FragColor")
{
out << "gl_Color[0]";
+ mUsesFragColor = true;
}
else if (name == "gl_FragData")
{
out << "gl_Color";
+ mUsesFragData = true;
}
else if (name == "gl_DepthRange")
{
@@ -848,17 +1172,17 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node)
if (qualifier == EvqUniform)
{
- mReferencedUniforms.insert(name.c_str());
+ mReferencedUniforms[name] = node;
out << decorateUniform(name, node->getType());
}
else if (qualifier == EvqAttribute)
{
- mReferencedAttributes.insert(name.c_str());
+ mReferencedAttributes[name] = node;
out << decorate(name);
}
else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
{
- mReferencedVaryings.insert(name.c_str());
+ mReferencedVaryings[name] = node;
out << decorate(name);
}
else
@@ -973,7 +1297,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
if (element)
{
- int i = element->getUnionArrayPointer()[0].getIConst();
+ int i = element->getIConst(0);
switch (i)
{
@@ -1276,7 +1600,6 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
TIntermSequence &sequence = node->getSequence();
TIntermTyped *variable = sequence[0]->getAsTyped();
- bool visit = true;
if (variable && (variable->getQualifier() == EvqTemporary || variable->getQualifier() == EvqGlobal))
{
@@ -1309,19 +1632,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
(*sit)->traverse(this);
}
- if (visit && this->inVisit)
+ if (*sit != sequence.back())
{
- if (*sit != sequence.back())
- {
- visit = this->visitAggregate(InVisit, node);
- }
+ out << ", ";
}
}
-
- if (visit && this->postVisit)
- {
- this->visitAggregate(PostVisit, node);
- }
}
else if (variable->getAsSymbolNode() && variable->getAsSymbolNode()->getSymbol() == "") // Type (struct) declaration
{
@@ -1329,7 +1644,24 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
}
else UNREACHABLE();
}
-
+ else if (variable && (variable->getQualifier() == EvqVaryingOut || variable->getQualifier() == EvqInvariantVaryingOut))
+ {
+ for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+ {
+ TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
+
+ if (symbol)
+ {
+ // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking
+ mReferencedVaryings[symbol->getSymbol()] = symbol;
+ }
+ else
+ {
+ (*sit)->traverse(this);
+ }
+ }
+ }
+
return false;
}
else if (visit == InVisit)
@@ -1440,151 +1772,163 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
break;
case EOpFunctionCall:
{
- if (visit == PreVisit)
- {
- TString name = TFunction::unmangleName(node->getName());
- bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
+ TString name = TFunction::unmangleName(node->getName());
+ bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
- if (node->isUserDefined())
- {
- out << decorate(name) << (lod0 ? "Lod0(" : "(");
- }
- else
+ if (node->isUserDefined())
+ {
+ out << decorate(name) << (lod0 ? "Lod0(" : "(");
+ }
+ else
+ {
+ if (name == "texture2D")
{
- if (name == "texture2D")
+ if (!lod0)
{
- if (!lod0)
+ if (node->getSequence().size() == 2)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTexture2D = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTexture2D_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_texture2D(";
+ mUsesTexture2D = true;
}
- else
+ else if (node->getSequence().size() == 3)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTexture2DLod0 = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTexture2DLod0_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_texture2DLod0(";
+ mUsesTexture2D_bias = true;
}
+ else UNREACHABLE();
+
+ out << "gl_texture2D(";
}
- else if (name == "texture2DProj")
+ else
{
- if (!lod0)
+ if (node->getSequence().size() == 2)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTexture2DProj = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTexture2DProj_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_texture2DProj(";
+ mUsesTexture2DLod0 = true;
}
- else
+ else if (node->getSequence().size() == 3)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTexture2DProjLod0 = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTexture2DProjLod0_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_texture2DProjLod0(";
+ mUsesTexture2DLod0_bias = true;
}
+ else UNREACHABLE();
+
+ out << "gl_texture2DLod0(";
}
- else if (name == "textureCube")
+ }
+ else if (name == "texture2DProj")
+ {
+ if (!lod0)
{
- if (!lod0)
+ if (node->getSequence().size() == 2)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTextureCube = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTextureCube_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_textureCube(";
+ mUsesTexture2DProj = true;
}
- else
+ else if (node->getSequence().size() == 3)
{
- if (node->getSequence().size() == 2)
- {
- mUsesTextureCubeLod0 = true;
- }
- else if (node->getSequence().size() == 3)
- {
- mUsesTextureCubeLod0_bias = true;
- }
- else UNREACHABLE();
-
- out << "gl_textureCubeLod0(";
+ mUsesTexture2DProj_bias = true;
}
+ else UNREACHABLE();
+
+ out << "gl_texture2DProj(";
}
- else if (name == "texture2DLod")
+ else
{
- if (node->getSequence().size() == 3)
+ if (node->getSequence().size() == 2)
+ {
+ mUsesTexture2DProjLod0 = true;
+ }
+ else if (node->getSequence().size() == 3)
{
- mUsesTexture2DLod = true;
+ mUsesTexture2DProjLod0_bias = true;
}
else UNREACHABLE();
- out << "gl_texture2DLod(";
+ out << "gl_texture2DProjLod0(";
}
- else if (name == "texture2DProjLod")
+ }
+ else if (name == "textureCube")
+ {
+ if (!lod0)
{
- if (node->getSequence().size() == 3)
+ if (node->getSequence().size() == 2)
+ {
+ mUsesTextureCube = true;
+ }
+ else if (node->getSequence().size() == 3)
{
- mUsesTexture2DProjLod = true;
+ mUsesTextureCube_bias = true;
}
else UNREACHABLE();
- out << "gl_texture2DProjLod(";
+ out << "gl_textureCube(";
}
- else if (name == "textureCubeLod")
+ else
{
- if (node->getSequence().size() == 3)
+ if (node->getSequence().size() == 2)
{
- mUsesTextureCubeLod = true;
+ mUsesTextureCubeLod0 = true;
+ }
+ else if (node->getSequence().size() == 3)
+ {
+ mUsesTextureCubeLod0_bias = true;
}
else UNREACHABLE();
- out << "gl_textureCubeLod(";
+ out << "gl_textureCubeLod0(";
+ }
+ }
+ else if (name == "texture2DLod")
+ {
+ if (node->getSequence().size() == 3)
+ {
+ mUsesTexture2DLod = true;
+ }
+ else UNREACHABLE();
+
+ out << "gl_texture2DLod(";
+ }
+ else if (name == "texture2DProjLod")
+ {
+ if (node->getSequence().size() == 3)
+ {
+ mUsesTexture2DProjLod = true;
}
else UNREACHABLE();
+
+ out << "gl_texture2DProjLod(";
}
+ else if (name == "textureCubeLod")
+ {
+ if (node->getSequence().size() == 3)
+ {
+ mUsesTextureCubeLod = true;
+ }
+ else UNREACHABLE();
+
+ out << "gl_textureCubeLod(";
+ }
+ else UNREACHABLE();
}
- else if (visit == InVisit)
- {
- out << ", ";
- }
- else
+
+ TIntermSequence &arguments = node->getSequence();
+
+ for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++)
{
- out << ")";
+ if (mOutputType == SH_HLSL11_OUTPUT && IsSampler((*arg)->getAsTyped()->getBasicType()))
+ {
+ out << "texture_";
+ (*arg)->traverse(this);
+ out << ", sampler_";
+ }
+
+ (*arg)->traverse(this);
+
+ if (arg < arguments.end() - 1)
+ {
+ out << ", ";
+ }
}
+
+ out << ")";
+
+ return false;
}
break;
case EOpParameters: outputTriplet(visit, "(", ", ", ")\n{\n"); break;
@@ -1778,14 +2122,17 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
{
bool wasDiscontinuous = mInsideDiscontinuousLoop;
- if (!mInsideDiscontinuousLoop)
+ if (mContainsLoopDiscontinuity && !mInsideDiscontinuousLoop)
{
mInsideDiscontinuousLoop = containsLoopDiscontinuity(node);
}
- if (handleExcessiveLoop(node))
+ if (mOutputType == SH_HLSL9_OUTPUT)
{
- return false;
+ if (handleExcessiveLoop(node))
+ {
+ return false;
+ }
}
TInfoSinkBase &out = mBody;
@@ -1976,7 +2323,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
index = symbol;
- initial = constant->getUnionArrayPointer()[0].getIConst();
+ initial = constant->getIConst(0);
}
}
}
@@ -1998,7 +2345,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
comparator = test->getOp();
- limit = constant->getUnionArrayPointer()[0].getIConst();
+ limit = constant->getIConst(0);
}
}
}
@@ -2019,7 +2366,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
{
if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
- int value = constant->getUnionArrayPointer()[0].getIConst();
+ int value = constant->getIConst(0);
switch (op)
{
@@ -2191,6 +2538,12 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
name = decorate(name);
}
+ if (mOutputType == SH_HLSL11_OUTPUT && IsSampler(type.getBasicType()))
+ {
+ return qualifierString(qualifier) + " " + textureString(type) + " texture_" + name + arrayString(type) + ", " +
+ qualifierString(qualifier) + " SamplerState sampler_" + name + arrayString(type);
+ }
+
return qualifierString(qualifier) + " " + typeString(type) + " " + name + arrayString(type);
}
@@ -2285,10 +2638,28 @@ TString OutputHLSL::typeString(const TType &type)
}
}
- UNIMPLEMENTED(); // FIXME
+ UNREACHABLE();
return "<unknown type>";
}
+TString OutputHLSL::textureString(const TType &type)
+{
+ switch (type.getBasicType())
+ {
+ case EbtSampler2D:
+ return "Texture2D";
+ case EbtSamplerCube:
+ return "TextureCube";
+ case EbtSamplerExternalOES:
+ return "Texture2D";
+ default:
+ break;
+ }
+
+ UNREACHABLE();
+ return "<unknown texture type>";
+}
+
TString OutputHLSL::arrayString(const TType &type)
{
if (!type.isArray())
@@ -2565,7 +2936,7 @@ const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &type, const Con
{
switch (constUnion->getType())
{
- case EbtFloat: out << constUnion->getFConst(); break;
+ case EbtFloat: out << std::min(FLT_MAX, std::max(-FLT_MAX, constUnion->getFConst())); break;
case EbtInt: out << constUnion->getIConst(); break;
case EbtBool: out << constUnion->getBConst(); break;
default: UNREACHABLE();
@@ -2640,11 +3011,7 @@ TString OutputHLSL::decorate(const TString &string)
TString OutputHLSL::decorateUniform(const TString &string, const TType &type)
{
- if (type.isArray())
- {
- return "ar_" + string; // Allows identifying arrays of size 1
- }
- else if (type.getBasicType() == EbtSamplerExternalOES)
+ if (type.getBasicType() == EbtSamplerExternalOES)
{
return "ex_" + string;
}
@@ -2661,4 +3028,197 @@ TString OutputHLSL::decorateField(const TString &string, const TType &structure)
return string;
}
+
+TString OutputHLSL::registerString(TIntermSymbol *operand)
+{
+ ASSERT(operand->getQualifier() == EvqUniform);
+
+ if (IsSampler(operand->getBasicType()))
+ {
+ return "s" + str(samplerRegister(operand));
+ }
+
+ return "c" + str(uniformRegister(operand));
+}
+
+int OutputHLSL::samplerRegister(TIntermSymbol *sampler)
+{
+ const TType &type = sampler->getType();
+ ASSERT(IsSampler(type.getBasicType()));
+
+ int index = mSamplerRegister;
+ mSamplerRegister += sampler->totalRegisterCount();
+
+ declareUniform(type, sampler->getSymbol(), index);
+
+ return index;
+}
+
+int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
+{
+ const TType &type = uniform->getType();
+ ASSERT(!IsSampler(type.getBasicType()));
+
+ int index = mUniformRegister;
+ mUniformRegister += uniform->totalRegisterCount();
+
+ declareUniform(type, uniform->getSymbol(), index);
+
+ return index;
+}
+
+void OutputHLSL::declareUniform(const TType &type, const TString &name, int index)
+{
+ const TTypeList *structure = type.getStruct();
+
+ if (!structure)
+ {
+ mActiveUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index));
+ }
+ else
+ {
+ if (type.isArray())
+ {
+ int elementIndex = index;
+
+ for (int i = 0; i < type.getArraySize(); i++)
+ {
+ for (size_t j = 0; j < structure->size(); j++)
+ {
+ const TType &fieldType = *(*structure)[j].type;
+ const TString &fieldName = fieldType.getFieldName();
+
+ const TString uniformName = name + "[" + str(i) + "]." + fieldName;
+ declareUniform(fieldType, uniformName, elementIndex);
+ elementIndex += fieldType.totalRegisterCount();
+ }
+ }
+ }
+ else
+ {
+ int fieldIndex = index;
+
+ for (size_t i = 0; i < structure->size(); i++)
+ {
+ const TType &fieldType = *(*structure)[i].type;
+ const TString &fieldName = fieldType.getFieldName();
+
+ const TString uniformName = name + "." + fieldName;
+ declareUniform(fieldType, uniformName, fieldIndex);
+ fieldIndex += fieldType.totalRegisterCount();
+ }
+ }
+ }
+}
+
+GLenum OutputHLSL::glVariableType(const TType &type)
+{
+ if (type.getBasicType() == EbtFloat)
+ {
+ if (type.isScalar())
+ {
+ return GL_FLOAT;
+ }
+ else if (type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_FLOAT_VEC2;
+ case 3: return GL_FLOAT_VEC3;
+ case 4: return GL_FLOAT_VEC4;
+ default: UNREACHABLE();
+ }
+ }
+ else if (type.isMatrix())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_FLOAT_MAT2;
+ case 3: return GL_FLOAT_MAT3;
+ case 4: return GL_FLOAT_MAT4;
+ default: UNREACHABLE();
+ }
+ }
+ else UNREACHABLE();
+ }
+ else if (type.getBasicType() == EbtInt)
+ {
+ if (type.isScalar())
+ {
+ return GL_INT;
+ }
+ else if (type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_INT_VEC2;
+ case 3: return GL_INT_VEC3;
+ case 4: return GL_INT_VEC4;
+ default: UNREACHABLE();
+ }
+ }
+ else UNREACHABLE();
+ }
+ else if (type.getBasicType() == EbtBool)
+ {
+ if (type.isScalar())
+ {
+ return GL_BOOL;
+ }
+ else if (type.isVector())
+ {
+ switch(type.getNominalSize())
+ {
+ case 2: return GL_BOOL_VEC2;
+ case 3: return GL_BOOL_VEC3;
+ case 4: return GL_BOOL_VEC4;
+ default: UNREACHABLE();
+ }
+ }
+ else UNREACHABLE();
+ }
+ else if (type.getBasicType() == EbtSampler2D)
+ {
+ return GL_SAMPLER_2D;
+ }
+ else if (type.getBasicType() == EbtSamplerCube)
+ {
+ return GL_SAMPLER_CUBE;
+ }
+ else UNREACHABLE();
+
+ return GL_NONE;
+}
+
+GLenum OutputHLSL::glVariablePrecision(const TType &type)
+{
+ if (type.getBasicType() == EbtFloat)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh: return GL_HIGH_FLOAT;
+ case EbpMedium: return GL_MEDIUM_FLOAT;
+ case EbpLow: return GL_LOW_FLOAT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default: UNREACHABLE();
+ }
+ }
+ else if (type.getBasicType() == EbtInt)
+ {
+ switch (type.getPrecision())
+ {
+ case EbpHigh: return GL_HIGH_INT;
+ case EbpMedium: return GL_MEDIUM_INT;
+ case EbpLow: return GL_LOW_INT;
+ case EbpUndefined:
+ // Should be defined as the default precision by the parser
+ default: UNREACHABLE();
+ }
+ }
+
+ // Other types (boolean, sampler) don't have a precision
+ return GL_NONE;
+}
+
}
diff --git a/src/3rdparty/angle/src/compiler/OutputHLSL.h b/src/3rdparty/angle/src/compiler/OutputHLSL.h
index dc843fb366..749a3461b3 100644
--- a/src/3rdparty/angle/src/compiler/OutputHLSL.h
+++ b/src/3rdparty/angle/src/compiler/OutputHLSL.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,9 +9,14 @@
#include <list>
#include <set>
+#include <map>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
#include "compiler/intermediate.h"
#include "compiler/ParseHelper.h"
+#include "compiler/Uniform.h"
namespace sh
{
@@ -20,14 +25,16 @@ class UnfoldShortCircuit;
class OutputHLSL : public TIntermTraverser
{
public:
- explicit OutputHLSL(TParseContext &context);
+ OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
~OutputHLSL();
void output();
TInfoSinkBase &getBodyStream();
+ const ActiveUniforms &getUniforms();
TString typeString(const TType &type);
+ TString textureString(const TType &type);
static TString qualifierString(TQualifier qualifier);
static TString arrayString(const TType &type);
static TString initializer(const TType &type);
@@ -64,6 +71,7 @@ class OutputHLSL : public TIntermTraverser
TString structLookup(const TString &typeName);
TParseContext &mContext;
+ const ShShaderOutput mOutputType;
UnfoldShortCircuit *mUnfoldShortCircuit;
bool mInsideFunction;
@@ -72,9 +80,10 @@ class OutputHLSL : public TIntermTraverser
TInfoSinkBase mBody;
TInfoSinkBase mFooter;
- std::set<std::string> mReferencedUniforms;
- std::set<std::string> mReferencedAttributes;
- std::set<std::string> mReferencedVaryings;
+ typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
+ ReferencedSymbols mReferencedUniforms;
+ ReferencedSymbols mReferencedAttributes;
+ ReferencedSymbols mReferencedVaryings;
// Parameters determining what goes in the header output
bool mUsesTexture2D;
@@ -92,6 +101,8 @@ class OutputHLSL : public TIntermTraverser
bool mUsesTexture2DProjLod0_bias;
bool mUsesTextureCubeLod0;
bool mUsesTextureCubeLod0_bias;
+ bool mUsesFragColor;
+ bool mUsesFragData;
bool mUsesDepthRange;
bool mUsesFragCoord;
bool mUsesPointCoord;
@@ -126,6 +137,8 @@ class OutputHLSL : public TIntermTraverser
bool mUsesAtan2_3;
bool mUsesAtan2_4;
+ int mNumRenderTargets;
+
typedef std::set<TString> Constructors;
Constructors mConstructors;
@@ -146,6 +159,18 @@ class OutputHLSL : public TIntermTraverser
bool mInsideDiscontinuousLoop;
TIntermSymbol *mExcessiveLoopIndex;
+
+ int mUniformRegister;
+ int mSamplerRegister;
+
+ TString registerString(TIntermSymbol *operand);
+ int samplerRegister(TIntermSymbol *sampler);
+ int uniformRegister(TIntermSymbol *uniform);
+ void declareUniform(const TType &type, const TString &name, int index);
+ static GLenum glVariableType(const TType &type);
+ static GLenum glVariablePrecision(const TType &type);
+
+ ActiveUniforms mActiveUniforms;
};
}
diff --git a/src/3rdparty/angle/src/compiler/ParseHelper.cpp b/src/3rdparty/angle/src/compiler/ParseHelper.cpp
index 508f1726a7..441ff35e00 100644
--- a/src/3rdparty/angle/src/compiler/ParseHelper.cpp
+++ b/src/3rdparty/angle/src/compiler/ParseHelper.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,7 +10,7 @@
#include <stdio.h>
#include "compiler/glslang.h"
-#include "compiler/preprocessor/new/SourceLocation.h"
+#include "compiler/preprocessor/SourceLocation.h"
///////////////////////////////////////////////////////////////////////
//
@@ -33,7 +33,7 @@ bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TV
enum {
exyzw,
ergba,
- estpq,
+ estpq
} fieldSet[4];
for (int i = 0; i < fields.num; ++i) {
@@ -286,7 +286,7 @@ bool TParseContext::lValueErrorCheck(int line, const char* op, TIntermTyped* nod
for (TIntermSequence::iterator p = aggrNode->getSequence().begin();
p != aggrNode->getSequence().end(); p++) {
- int value = (*p)->getAsTyped()->getAsConstantUnion()->getUnionArrayPointer()->getIConst();
+ int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
offset[value]++;
if (offset[value] > 1) {
error(line, " l-value of swizzle cannot have duplicate components", op);
@@ -493,7 +493,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
bool overFull = false;
bool matrixInMatrix = false;
bool arrayArg = false;
- for (int i = 0; i < function.getParamCount(); ++i) {
+ for (size_t i = 0; i < function.getParamCount(); ++i) {
const TParameter& param = function.getParam(i);
size += param.type->getObjectSize();
@@ -512,7 +512,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
if (constType)
type->setQualifier(EvqConst);
- if (type->isArray() && type->getArraySize() != function.getParamCount()) {
+ if (type->isArray() && static_cast<size_t>(type->getArraySize()) != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor");
return true;
}
@@ -680,7 +680,7 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
return true;
}
- size = constant->getUnionArrayPointer()->getIConst();
+ size = constant->getIConst(0);
if (size <= 0) {
error(line, "array size must be a positive integer", "");
@@ -1313,7 +1313,6 @@ TIntermTyped* TParseContext::addConstVectorNode(TVectorFields& fields, TIntermTy
ConstantUnion *unionArray;
if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer();
- ASSERT(unionArray);
if (!unionArray) {
return node;
@@ -1507,7 +1506,7 @@ bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldT
//
// Returns 0 for success.
//
-int PaParseStrings(int count, const char* const string[], const int length[],
+int PaParseStrings(size_t count, const char* const string[], const int length[],
TParseContext* context) {
if ((count == 0) || (string == NULL))
return 1;
diff --git a/src/3rdparty/angle/src/compiler/ParseHelper.h b/src/3rdparty/angle/src/compiler/ParseHelper.h
index 824ee00f39..26a3ea1308 100644
--- a/src/3rdparty/angle/src/compiler/ParseHelper.h
+++ b/src/3rdparty/angle/src/compiler/ParseHelper.h
@@ -9,7 +9,7 @@
#include "compiler/Diagnostics.h"
#include "compiler/DirectiveHandler.h"
#include "compiler/localintermediate.h"
-#include "compiler/preprocessor/new/Preprocessor.h"
+#include "compiler/preprocessor/Preprocessor.h"
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
@@ -58,6 +58,7 @@ struct TParseContext {
const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return
bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit.
+ bool fragmentPrecisionHigh; // true if highp precision is supported in the fragment language.
TString HashErrMsg;
bool AfterEOF;
TDiagnostics diagnostics;
@@ -134,7 +135,7 @@ struct TParseContext {
bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType);
};
-int PaParseStrings(int count, const char* const string[], const int length[],
+int PaParseStrings(size_t count, const char* const string[], const int length[],
TParseContext* context);
#endif // _PARSER_HELPER_INCLUDED_
diff --git a/src/3rdparty/angle/src/compiler/ShHandle.h b/src/3rdparty/angle/src/compiler/ShHandle.h
index 6ba302ad04..28049305e0 100644
--- a/src/3rdparty/angle/src/compiler/ShHandle.h
+++ b/src/3rdparty/angle/src/compiler/ShHandle.h
@@ -18,13 +18,16 @@
#include "compiler/BuiltInFunctionEmulator.h"
#include "compiler/ExtensionBehavior.h"
+#include "compiler/HashNames.h"
#include "compiler/InfoSink.h"
#include "compiler/SymbolTable.h"
#include "compiler/VariableInfo.h"
+#include "third_party/compiler/ArrayBoundsClamper.h"
class LongNameMap;
class TCompiler;
class TDependencyGraph;
+class TranslatorHLSL;
//
// Helper function to identify specs that are based on the WebGL spec,
@@ -40,6 +43,7 @@ public:
TShHandleBase();
virtual ~TShHandleBase();
virtual TCompiler* getAsCompiler() { return 0; }
+ virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
protected:
// Memory allocator. Allocates and tracks memory required by the compiler.
@@ -59,7 +63,7 @@ public:
bool Init(const ShBuiltInResources& resources);
bool compile(const char* const shaderStrings[],
- const int numStrings,
+ size_t numStrings,
int compileOptions);
// Get results of the last compilation.
@@ -68,6 +72,10 @@ public:
const TVariableInfoList& getUniforms() const { return uniforms; }
int getMappedNameMaxLength() const;
+ ShHashFunction64 getHashFunction() const { return hashFunction; }
+ NameMap& getNameMap() { return nameMap; }
+ TSymbolTable& getSymbolTable() { return symbolTable; }
+
protected:
ShShaderType getShaderType() const { return shaderType; }
ShShaderSpec getShaderSpec() const { return shaderSpec; }
@@ -100,7 +108,11 @@ protected:
bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph& graph);
// Get built-in extensions with default behavior.
const TExtensionBehavior& getExtensionBehavior() const;
+ // Get the resources set by InitBuiltInSymbolTable
+ const ShBuiltInResources& getResources() const;
+ const ArrayBoundsClamper& getArrayBoundsClamper() const;
+ ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const;
private:
@@ -109,12 +121,17 @@ private:
int maxUniformVectors;
+ ShBuiltInResources compileResources;
+
// Built-in symbol table for the given language, spec, and resources.
// It is preserved from compile-to-compile.
TSymbolTable symbolTable;
// Built-in extensions with default behavior.
TExtensionBehavior extensionBehavior;
+ bool fragmentPrecisionHigh;
+ ArrayBoundsClamper arrayBoundsClamper;
+ ShArrayIndexClampingStrategy clampingStrategy;
BuiltInFunctionEmulator builtInFunctionEmulator;
// Results of compilation.
@@ -124,6 +141,10 @@ private:
// Cached copy of the ref-counted singleton.
LongNameMap* longNameMap;
+
+ // name hashing.
+ ShHashFunction64 hashFunction;
+ NameMap nameMap;
};
//
diff --git a/src/3rdparty/angle/src/compiler/ShaderLang.cpp b/src/3rdparty/angle/src/compiler/ShaderLang.cpp
index 56f5c7f2ec..92f39311c2 100644
--- a/src/3rdparty/angle/src/compiler/ShaderLang.cpp
+++ b/src/3rdparty/angle/src/compiler/ShaderLang.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -14,6 +14,7 @@
#include "compiler/InitializeDll.h"
#include "compiler/preprocessor/length_limits.h"
#include "compiler/ShHandle.h"
+#include "compiler/TranslatorHLSL.h"
//
// This is the platform independent interface between an OGL driver
@@ -21,18 +22,18 @@
//
static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
- int expectedValue)
+ size_t expectedValue)
{
- int activeUniformLimit = 0;
+ size_t activeUniformLimit = 0;
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
- int activeAttribLimit = 0;
+ size_t activeAttribLimit = 0;
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
}
-static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
+static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
{
- int mappedNameMaxLength = 0;
+ size_t mappedNameMaxLength = 0;
ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength);
return (expectedValue == mappedNameMaxLength);
}
@@ -40,7 +41,7 @@ static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue)
static void getVariableInfo(ShShaderInfo varType,
const ShHandle handle,
int index,
- int* length,
+ size_t* length,
int* size,
ShDataType* type,
char* name,
@@ -69,14 +70,14 @@ static void getVariableInfo(ShShaderInfo varType,
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
// in ShGetInfo, below.
- int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
+ size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
name[activeUniformAndAttribLength - 1] = 0;
if (mappedName) {
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
- int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
+ size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
@@ -125,6 +126,15 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->OES_standard_derivatives = 0;
resources->OES_EGL_image_external = 0;
resources->ARB_texture_rectangle = 0;
+ resources->EXT_draw_buffers = 0;
+
+ // Disable highp precision in fragment shader by default.
+ resources->FragmentPrecisionHigh = 0;
+
+ // Disable name hashing by default.
+ resources->HashFunction = NULL;
+
+ resources->ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
}
//
@@ -172,7 +182,7 @@ void ShDestruct(ShHandle handle)
int ShCompile(
const ShHandle handle,
const char* const shaderStrings[],
- const int numStrings,
+ size_t numStrings,
int compileOptions)
{
if (!InitThread())
@@ -190,7 +200,7 @@ int ShCompile(
return success ? 1 : 0;
}
-void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
{
if (!handle || !params)
return;
@@ -224,6 +234,22 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
// handle array and struct dereferences.
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
+ case SH_NAME_MAX_LENGTH:
+ *params = 1 + MAX_SYMBOL_NAME_LEN;
+ 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;
+ *params = 16 + sizeof(HashedNamePrefix);
+ }
+ break;
+ case SH_HASHED_NAMES_COUNT:
+ *params = compiler->getNameMap().size();
+ break;
default: UNREACHABLE();
}
}
@@ -262,7 +288,7 @@ void ShGetObjectCode(const ShHandle handle, char* objCode)
void ShGetActiveAttrib(const ShHandle handle,
int index,
- int* length,
+ size_t* length,
int* size,
ShDataType* type,
char* name,
@@ -274,7 +300,7 @@ void ShGetActiveAttrib(const ShHandle handle,
void ShGetActiveUniform(const ShHandle handle,
int index,
- int* length,
+ size_t* length,
int* size,
ShDataType* type,
char* name,
@@ -283,3 +309,64 @@ void ShGetActiveUniform(const ShHandle handle,
getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name, mappedName);
}
+
+void ShGetNameHashingEntry(const ShHandle handle,
+ int index,
+ char* name,
+ char* hashedName)
+{
+ 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';
+}
+
+void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
+{
+ if (!handle || !params)
+ return;
+
+ TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+ TranslatorHLSL* translator = base->getAsTranslatorHLSL();
+ if (!translator) return;
+
+ switch(pname)
+ {
+ case SH_ACTIVE_UNIFORMS_ARRAY:
+ *params = (void*)&translator->getUniforms();
+ break;
+ default: UNREACHABLE();
+ }
+}
diff --git a/src/3rdparty/angle/src/compiler/SymbolTable.h b/src/3rdparty/angle/src/compiler/SymbolTable.h
index a89499e4f4..d27aa332b7 100644
--- a/src/3rdparty/angle/src/compiler/SymbolTable.h
+++ b/src/3rdparty/angle/src/compiler/SymbolTable.h
@@ -169,8 +169,8 @@ public:
void setDefined() { defined = true; }
bool isDefined() { return defined; }
- int getParamCount() const { return static_cast<int>(parameters.size()); }
- const TParameter& getParam(int i) const { return parameters[i]; }
+ size_t getParamCount() const { return parameters.size(); }
+ const TParameter& getParam(size_t i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const;
TFunction(const TFunction&, TStructureMap& remapper);
@@ -323,10 +323,16 @@ public:
void dump(TInfoSink &infoSink) const;
void copyTable(const TSymbolTable& copyOf);
- void setDefaultPrecision( TBasicType type, TPrecision prec ){
- if( type != EbtFloat && type != EbtInt ) return; // Only set default precision for int/float
+ bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){
+ if (IsSampler(type.type))
+ return true; // Skip sampler types for the time being
+ if (type.type != EbtFloat && type.type != EbtInt)
+ return false; // Only set default precision for int/float
+ if (type.size != 1 || type.matrix || type.array)
+ return false; // Not allowed to set for aggregate types
int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
- precisionStack[indexOfLastElement][type] = prec; // Uses map operator [], overwrites the current value
+ precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value
+ return true;
}
// Searches down the precisionStack for a precision qualifier for the specified TBasicType
diff --git a/src/3rdparty/angle/src/compiler/TranslatorESSL.cpp b/src/3rdparty/angle/src/compiler/TranslatorESSL.cpp
index e3a2c2a802..2900f8a8ed 100644
--- a/src/3rdparty/angle/src/compiler/TranslatorESSL.cpp
+++ b/src/3rdparty/angle/src/compiler/TranslatorESSL.cpp
@@ -22,8 +22,11 @@ void TranslatorESSL::translate(TIntermNode* root) {
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
sink, getShaderType() == SH_FRAGMENT_SHADER);
+ // Write array bounds clamping emulation if needed.
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
// Write translated shader.
- TOutputESSL outputESSL(sink);
+ TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputESSL);
}
diff --git a/src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp b/src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp
index bb07a1eb4e..7ca4341dcd 100644
--- a/src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/TranslatorGLSL.cpp
@@ -35,7 +35,10 @@ void TranslatorGLSL::translate(TIntermNode* root) {
getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
sink, false);
+ // Write array bounds clamping emulation if needed.
+ getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
// Write translated shader.
- TOutputGLSL outputGLSL(sink);
+ TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
root->traverse(&outputGLSL);
}
diff --git a/src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp b/src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp
index f41decd48c..37408a07c4 100644
--- a/src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp
+++ b/src/3rdparty/angle/src/compiler/TranslatorHLSL.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,15 +9,16 @@
#include "compiler/InitializeParseContext.h"
#include "compiler/OutputHLSL.h"
-TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
- : TCompiler(type, spec)
+TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
+ : TCompiler(type, spec), mOutputType(output)
{
}
void TranslatorHLSL::translate(TIntermNode *root)
{
TParseContext& parseContext = *GetGlobalParseContext();
- sh::OutputHLSL outputHLSL(parseContext);
+ sh::OutputHLSL outputHLSL(parseContext, getResources(), mOutputType);
outputHLSL.output();
+ mActiveUniforms = outputHLSL.getUniforms();
}
diff --git a/src/3rdparty/angle/src/compiler/TranslatorHLSL.h b/src/3rdparty/angle/src/compiler/TranslatorHLSL.h
index c3f672ba91..9550e15e8e 100644
--- a/src/3rdparty/angle/src/compiler/TranslatorHLSL.h
+++ b/src/3rdparty/angle/src/compiler/TranslatorHLSL.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,13 +8,20 @@
#define COMPILER_TRANSLATORHLSL_H_
#include "compiler/ShHandle.h"
+#include "compiler/Uniform.h"
class TranslatorHLSL : public TCompiler {
public:
- TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
+ TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
+
+ virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
+ const sh::ActiveUniforms &getUniforms() { return mActiveUniforms; }
protected:
virtual void translate(TIntermNode* root);
+
+ sh::ActiveUniforms mActiveUniforms;
+ ShShaderOutput mOutputType;
};
#endif // COMPILER_TRANSLATORHLSL_H_
diff --git a/src/3rdparty/angle/src/compiler/Types.h b/src/3rdparty/angle/src/compiler/Types.h
index d4576673b1..854bb44c07 100644
--- a/src/3rdparty/angle/src/compiler/Types.h
+++ b/src/3rdparty/angle/src/compiler/Types.h
@@ -136,6 +136,43 @@ public:
return totalSize;
}
+ int elementRegisterCount() const
+ {
+ TTypeList *structure = getStruct();
+
+ if (structure)
+ {
+ int registerCount = 0;
+
+ for (size_t i = 0; i < structure->size(); i++)
+ {
+ registerCount += (*structure)[i].type->totalRegisterCount();
+ }
+
+ return registerCount;
+ }
+ else if (isMatrix())
+ {
+ return getNominalSize();
+ }
+ else
+ {
+ return 1;
+ }
+ }
+
+ int totalRegisterCount() const
+ {
+ if (array)
+ {
+ return arraySize * elementRegisterCount();
+ }
+ else
+ {
+ return elementRegisterCount();
+ }
+ }
+
bool isMatrix() const { return matrix ? true : false; }
void setMatrix(bool m) { matrix = m; }
diff --git a/src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp b/src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp
index 1782ebc90c..47f0afca6a 100644
--- a/src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp
+++ b/src/3rdparty/angle/src/compiler/UnfoldShortCircuit.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -95,9 +95,9 @@ bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
mTemporaryIndex = i + 1;
}
return false;
+ default:
+ return true;
}
-
- return true;
}
bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
@@ -111,6 +111,8 @@ bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n";
+ out << "{\n";
+
mTemporaryIndex = i + 1;
node->getCondition()->traverse(this);
out << "if(";
@@ -135,6 +137,8 @@ bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
out << ";\n"
"}\n";
+ out << "}\n";
+
mTemporaryIndex = i + 1;
}
diff --git a/src/3rdparty/angle/src/compiler/Uniform.cpp b/src/3rdparty/angle/src/compiler/Uniform.cpp
new file mode 100644
index 0000000000..f367db2be8
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/Uniform.cpp
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/Uniform.h"
+
+namespace sh
+{
+
+Uniform::Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex)
+{
+ this->type = type;
+ this->precision = precision;
+ this->name = name;
+ this->arraySize = arraySize;
+ this->registerIndex = registerIndex;
+}
+
+}
diff --git a/src/3rdparty/angle/src/compiler/Uniform.h b/src/3rdparty/angle/src/compiler/Uniform.h
new file mode 100644
index 0000000000..4c53ffa7d2
--- /dev/null
+++ b/src/3rdparty/angle/src/compiler/Uniform.h
@@ -0,0 +1,35 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_UNIFORM_H_
+#define COMPILER_UNIFORM_H_
+
+#include <string>
+#include <vector>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+namespace sh
+{
+
+struct Uniform
+{
+ Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex);
+
+ GLenum type;
+ GLenum precision;
+ std::string name;
+ unsigned int arraySize;
+
+ int registerIndex;
+};
+
+typedef std::vector<Uniform> ActiveUniforms;
+
+}
+
+#endif // COMPILER_UNIFORM_H_
diff --git a/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp b/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
index d69ec6bbaa..a5562d09a4 100644
--- a/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
+++ b/src/3rdparty/angle/src/compiler/ValidateLimitations.cpp
@@ -421,7 +421,7 @@ bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
return true;
// List of param indices for which loop indices are used as argument.
- typedef std::vector<int> ParamIndex;
+ typedef std::vector<size_t> ParamIndex;
ParamIndex pIndex;
TIntermSequence& params = node->getSequence();
for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
diff --git a/src/3rdparty/angle/src/compiler/VariableInfo.cpp b/src/3rdparty/angle/src/compiler/VariableInfo.cpp
index 3ff283627b..eb6bea9b0f 100644
--- a/src/3rdparty/angle/src/compiler/VariableInfo.cpp
+++ b/src/3rdparty/angle/src/compiler/VariableInfo.cpp
@@ -77,23 +77,25 @@ static void getBuiltInVariableInfo(const TType& type,
static void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList);
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction);
// Returns info for an attribute or uniform.
static void getVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList)
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
for (int i = 0; i < type.getArraySize(); ++i) {
TString lname = name + arrayBrackets(i);
TString lmappedName = mappedName + arrayBrackets(i);
- getUserDefinedVariableInfo(type, lname, lmappedName, infoList);
+ getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
}
} else {
- getUserDefinedVariableInfo(type, name, mappedName, infoList);
+ getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
}
} else {
getBuiltInVariableInfo(type, name, mappedName, infoList);
@@ -124,7 +126,8 @@ void getBuiltInVariableInfo(const TType& type,
void getUserDefinedVariableInfo(const TType& type,
const TString& name,
const TString& mappedName,
- TVariableInfoList& infoList)
+ TVariableInfoList& infoList,
+ ShHashFunction64 hashFunction)
{
ASSERT(type.getBasicType() == EbtStruct);
@@ -133,8 +136,9 @@ void getUserDefinedVariableInfo(const TType& type,
const TType* fieldType = (*structure)[i].type;
getVariableInfo(*fieldType,
name + "." + fieldType->getFieldName(),
- mappedName + "." + fieldType->getFieldName(),
- infoList);
+ mappedName + "." + TIntermTraverser::hash(fieldType->getFieldName(), hashFunction),
+ infoList,
+ hashFunction);
}
}
@@ -149,9 +153,11 @@ TVariableInfo::TVariableInfo(ShDataType type, int size)
}
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms)
+ TVariableInfoList& uniforms,
+ ShHashFunction64 hashFunction)
: mAttribs(attribs),
- mUniforms(uniforms)
+ mUniforms(uniforms),
+ mHashFunction(hashFunction)
{
}
@@ -206,10 +212,16 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
// cannot be initialized in a shader, we must have only
// TIntermSymbol nodes in the sequence.
ASSERT(variable != NULL);
+ TString processedSymbol;
+ if (mHashFunction == NULL)
+ processedSymbol = variable->getSymbol();
+ else
+ processedSymbol = TIntermTraverser::hash(variable->getOriginalSymbol(), mHashFunction);
getVariableInfo(variable->getType(),
variable->getOriginalSymbol(),
- variable->getSymbol(),
- infoList);
+ processedSymbol,
+ infoList,
+ mHashFunction);
}
}
break;
diff --git a/src/3rdparty/angle/src/compiler/VariableInfo.h b/src/3rdparty/angle/src/compiler/VariableInfo.h
index fdcc08f5b5..4130a589f5 100644
--- a/src/3rdparty/angle/src/compiler/VariableInfo.h
+++ b/src/3rdparty/angle/src/compiler/VariableInfo.h
@@ -27,7 +27,8 @@ typedef std::vector<TVariableInfo> TVariableInfoList;
class CollectAttribsUniforms : public TIntermTraverser {
public:
CollectAttribsUniforms(TVariableInfoList& attribs,
- TVariableInfoList& uniforms);
+ TVariableInfoList& uniforms,
+ ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
virtual void visitConstantUnion(TIntermConstantUnion*);
@@ -41,6 +42,8 @@ public:
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
+
+ ShHashFunction64 mHashFunction;
};
#endif // COMPILER_VARIABLE_INFO_H_
diff --git a/src/3rdparty/angle/src/compiler/VariablePacker.cpp b/src/3rdparty/angle/src/compiler/VariablePacker.cpp
index 2f0c4bc2a2..8957287763 100644
--- a/src/3rdparty/angle/src/compiler/VariablePacker.cpp
+++ b/src/3rdparty/angle/src/compiler/VariablePacker.cpp
@@ -85,7 +85,7 @@ int VariablePacker::GetNumRows(ShDataType type)
case SH_FLOAT_MAT3:
return 3;
case SH_FLOAT_MAT2:
- return 1;
+ return 2;
case SH_FLOAT_VEC4:
case SH_INT_VEC4:
case SH_BOOL_VEC4:
diff --git a/src/3rdparty/angle/src/compiler/glslang.h b/src/3rdparty/angle/src/compiler/glslang.h
index 3a45daf3a4..f221199093 100644
--- a/src/3rdparty/angle/src/compiler/glslang.h
+++ b/src/3rdparty/angle/src/compiler/glslang.h
@@ -8,7 +8,7 @@ struct TParseContext;
extern int glslang_initialize(TParseContext* context);
extern int glslang_finalize(TParseContext* context);
-extern int glslang_scan(int count,
+extern int glslang_scan(size_t count,
const char* const string[],
const int length[],
TParseContext* context);
diff --git a/src/3rdparty/angle/src/compiler/glslang.l b/src/3rdparty/angle/src/compiler/glslang.l
index e0483e2ea9..140a9aeb2d 100644
--- a/src/3rdparty/angle/src/compiler/glslang.l
+++ b/src/3rdparty/angle/src/compiler/glslang.l
@@ -38,7 +38,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
%{
#include "compiler/glslang.h"
#include "compiler/ParseHelper.h"
-#include "compiler/preprocessor/new/Token.h"
+#include "compiler/preprocessor/Token.h"
#include "compiler/util.h"
#include "glslang_tab.h"
@@ -51,7 +51,7 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
#define YY_INPUT(buf, result, max_size) \
result = string_input(buf, max_size, yyscanner);
-static int string_input(char* buf, int max_size, yyscan_t yyscanner);
+static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
static int check_type(yyscan_t yyscanner);
static int reserved_word(yyscan_t yyscanner);
%}
@@ -203,10 +203,10 @@ O [0-7]
return check_type(yyscanner);
}
-0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{O}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0[xX]{H}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
+0{O}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
0{D}+ { context->error(yylineno, "Invalid Octal number.", yytext); context->recover(); return 0;}
-{D}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+{D}+ { yylval->lex.i = static_cast<int>(strtol(yytext, 0, 0)); return(INTCONSTANT); }
{D}+{E} { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
{D}+"."{D}*({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
@@ -272,146 +272,13 @@ O [0-7]
%%
-// Old preprocessor interface.
-extern "C" {
-#include "compiler/preprocessor/preprocess.h"
-
-extern int InitPreprocessor();
-extern int FinalizePreprocessor();
-extern void PredefineIntMacro(const char *name, int value);
-
-#define SETUP_CONTEXT(pp) \
- TParseContext* context = (TParseContext*) pp->pC; \
- struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
-
-// Preprocessor callbacks.
-void CPPDebugLogMsg(const char *msg)
-{
- SETUP_CONTEXT(cpp);
- context->trace(msg);
-}
-
-void CPPWarningToInfoLog(const char *msg)
-{
- SETUP_CONTEXT(cpp);
- context->warning(yylineno, msg, "");
-}
-
-void CPPShInfoLogMsg(const char *msg)
-{
- SETUP_CONTEXT(cpp);
- context->error(yylineno, msg, "");
- context->recover();
-}
-
-void CPPErrorToInfoLog(const char *msg)
-{
- SETUP_CONTEXT(cpp);
- context->error(yylineno, msg, "");
- context->recover();
-}
-
-void SetLineNumber(int line)
-{
- SETUP_CONTEXT(cpp);
- int string = 0;
- DecodeSourceLoc(yylineno, &string, NULL);
- yylineno = EncodeSourceLoc(string, line);
-}
-
-void SetStringNumber(int string)
-{
- SETUP_CONTEXT(cpp);
- int line = 0;
- DecodeSourceLoc(yylineno, NULL, &line);
- yylineno = EncodeSourceLoc(string, line);
-}
-
-int GetStringNumber()
-{
- SETUP_CONTEXT(cpp);
- int string = 0;
- DecodeSourceLoc(yylineno, &string, NULL);
- return string;
-}
-
-int GetLineNumber()
-{
- SETUP_CONTEXT(cpp);
- int line = 0;
- DecodeSourceLoc(yylineno, NULL, &line);
- return line;
-}
-
-void IncLineNumber()
-{
- SETUP_CONTEXT(cpp);
- int string = 0, line = 0;
- DecodeSourceLoc(yylineno, &string, &line);
- yylineno = EncodeSourceLoc(string, ++line);
-}
-
-void DecLineNumber()
-{
- SETUP_CONTEXT(cpp);
- int string = 0, line = 0;
- DecodeSourceLoc(yylineno, &string, &line);
- yylineno = EncodeSourceLoc(string, --line);
-}
-
-void HandlePragma(const char **tokens, int numTokens)
-{
- SETUP_CONTEXT(cpp);
-
- if (numTokens != 4) return;
- if (strcmp(tokens[1], "(") != 0) return;
- if (strcmp(tokens[3], ")") != 0) return;
-
- context->handlePragmaDirective(yylineno, tokens[0], tokens[2]);
-}
-
-void StoreStr(const char *string)
-{
- SETUP_CONTEXT(cpp);
- TString strSrc;
- strSrc = TString(string);
-
- context->HashErrMsg = context->HashErrMsg + " " + strSrc;
-}
-
-const char* GetStrfromTStr(void)
-{
- SETUP_CONTEXT(cpp);
- cpp->ErrMsg = context->HashErrMsg.c_str();
- return cpp->ErrMsg;
-}
-
-void ResetTString(void)
-{
- SETUP_CONTEXT(cpp);
- context->HashErrMsg = "";
-}
-
-void updateExtensionBehavior(const char* extName, const char* behavior)
-{
- SETUP_CONTEXT(cpp);
- context->handleExtensionDirective(yylineno, extName, behavior);
-}
-} // extern "C"
-
-int string_input(char* buf, int max_size, yyscan_t yyscanner) {
- int len = 0;
-
-#if ANGLE_USE_NEW_PREPROCESSOR
+yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
pp::Token token;
yyget_extra(yyscanner)->preprocessor.lex(&token);
- len = token.type == pp::Token::LAST ? 0 : token.text.size();
- if ((len > 0) && (len < max_size))
+ yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
+ if (len < max_size)
memcpy(buf, token.text.c_str(), len);
yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner);
-#else
- len = yylex_CPP(buf, max_size);
-#endif // ANGLE_USE_NEW_PREPROCESSOR
if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow");
@@ -471,41 +338,28 @@ int glslang_finalize(TParseContext* context) {
context->scanner = NULL;
yylex_destroy(scanner);
-#if !ANGLE_USE_NEW_PREPROCESSOR
- FinalizePreprocessor();
-#endif
return 0;
}
-int glslang_scan(int count, const char* const string[], const int length[],
+int glslang_scan(size_t count, const char* const string[], const int length[],
TParseContext* context) {
yyrestart(NULL, context->scanner);
yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
context->AfterEOF = false;
// Initialize preprocessor.
-#if ANGLE_USE_NEW_PREPROCESSOR
if (!context->preprocessor.init(count, string, length))
return 1;
-#else
- if (InitPreprocessor())
- return 1;
- cpp->pC = context;
- cpp->pastFirstStatement = 0;
- if (InitScannerInput(cpp, count, string, length))
- return 1;
-#endif // ANGLE_USE_NEW_PREPROCESSOR
// Define extension macros.
const TExtensionBehavior& extBehavior = context->extensionBehavior();
for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
iter != extBehavior.end(); ++iter) {
-#if ANGLE_USE_NEW_PREPROCESSOR
context->preprocessor.predefineMacro(iter->first.c_str(), 1);
-#else
- PredefineIntMacro(iter->first.c_str(), 1);
-#endif
}
+ if (context->fragmentPrecisionHigh)
+ context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
+
return 0;
}
diff --git a/src/3rdparty/angle/src/compiler/glslang.y b/src/3rdparty/angle/src/compiler/glslang.y
index 39c9cee26e..8dbcee32ef 100644
--- a/src/3rdparty/angle/src/compiler/glslang.y
+++ b/src/3rdparty/angle/src/compiler/glslang.y
@@ -1,6 +1,6 @@
/*
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -38,6 +38,9 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
#include "compiler/ParseHelper.h"
#include "GLSLANG/ShaderLang.h"
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
+
#define YYLEX_PARAM context->scanner
%}
@@ -242,36 +245,36 @@ postfix_expression
}
if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
if ($1->isArray()) { // constant folding for arrays
- $$ = context->addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+ $$ = context->addConstArrayNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
} else if ($1->isVector()) { // constant folding for vectors
TVectorFields fields;
fields.num = 1;
- fields.offsets[0] = $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
+ fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // need to do it this way because v.xy sends fields integer array
$$ = context->addConstVectorNode(fields, $1, $2.line);
} else if ($1->isMatrix()) { // constant folding for matrices
- $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+ $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIConst(0), $1, $2.line);
}
} else {
if ($3->getQualifier() == EvqConst) {
- if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
+ if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getIConst(0) && !$1->isArray() ) {
std::stringstream extraInfoStream;
- extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
+ extraInfoStream << "field selection out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover();
} else {
if ($1->isArray()) {
if ($1->getType().getArraySize() == 0) {
- if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
- if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
+ if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getIConst(0)) {
+ if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, $2.line))
context->recover();
} else {
if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
context->recover();
}
- } else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
+ } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1->getType().getArraySize()) {
std::stringstream extraInfoStream;
- extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() << "'";
+ extraInfoStream << "array index out of range '" << $3->getAsConstantUnion()->getIConst(0) << "'";
std::string extraInfo = extraInfoStream.str();
context->error($2.line, "", "[", extraInfo.c_str());
context->recover();
@@ -521,7 +524,7 @@ function_call
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
TQualifier qual;
- for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
+ for (size_t i = 0; i < fnCandidate->getParamCount(); ++i) {
qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) {
if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
@@ -962,7 +965,7 @@ declaration
prototype->setType(function.getReturnType());
prototype->setName(function.getName());
- for (int i = 0; i < function.getParamCount(); i++)
+ for (size_t i = 0; i < function.getParamCount(); i++)
{
const TParameter &param = function.getParam(i);
if (param.name != 0)
@@ -988,7 +991,14 @@ declaration
$$ = $1.intermAggregate;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
- context->symbolTable.setDefaultPrecision( $3.type, $2 );
+ if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
+ context->error($1.line, "precision is not supported in fragment shader", "highp");
+ context->recover();
+ }
+ if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
+ context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type));
+ context->recover();
+ }
$$ = 0;
}
;
@@ -1009,7 +1019,7 @@ function_prototype
context->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString());
context->recover();
}
- for (int i = 0; i < prevDec->getParamCount(); ++i) {
+ for (size_t i = 0; i < prevDec->getParamCount(); ++i) {
if (prevDec->getParam(i).type->getQualifier() != $1->getParam(i).type->getQualifier()) {
context->error($2.line, "overloaded functions must have the same parameter qualifiers", $1->getParam(i).type->getQualifierString());
context->recover();
@@ -2079,7 +2089,7 @@ function_definition
// knows where to find parameters.
//
TIntermAggregate* paramNodes = new TIntermAggregate;
- for (int i = 0; i < function->getParamCount(); i++) {
+ for (size_t i = 0; i < function->getParamCount(); i++) {
const TParameter& param = function->getParam(i);
if (param.name != 0) {
TVariable *variable = new TVariable(param.name, *param.type);
@@ -2139,4 +2149,3 @@ function_definition
int glslang_parse(TParseContext* context) {
return yyparse(context);
}
-
diff --git a/src/3rdparty/angle/src/compiler/intermOut.cpp b/src/3rdparty/angle/src/compiler/intermOut.cpp
index e83c7b72f2..f48a049c63 100644
--- a/src/3rdparty/angle/src/compiler/intermOut.cpp
+++ b/src/3rdparty/angle/src/compiler/intermOut.cpp
@@ -42,7 +42,7 @@ TString TType::getCompleteString() const
if (qualifier != EvqTemporary && qualifier != EvqGlobal)
stream << getQualifierString() << " " << getPrecisionString() << " ";
if (array)
- stream << "array of ";
+ stream << "array[" << getArraySize() << "] of ";
if (matrix)
stream << size << "X" << size << " matrix of ";
else if (size > 1)
diff --git a/src/3rdparty/angle/src/compiler/intermediate.h b/src/3rdparty/angle/src/compiler/intermediate.h
index af78fa00ef..8e76ef921f 100644
--- a/src/3rdparty/angle/src/compiler/intermediate.h
+++ b/src/3rdparty/angle/src/compiler/intermediate.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -16,6 +16,8 @@
#ifndef __INTERMEDIATE_H
#define __INTERMEDIATE_H
+#include "GLSLANG/ShaderLang.h"
+
#include "compiler/Common.h"
#include "compiler/Types.h"
#include "compiler/ConstantUnion.h"
@@ -181,7 +183,7 @@ enum TOperator {
EOpVectorTimesScalarAssign,
EOpMatrixTimesScalarAssign,
EOpMatrixTimesMatrixAssign,
- EOpDivAssign,
+ EOpDivAssign
};
extern const char* getOperatorString(TOperator op);
@@ -257,6 +259,10 @@ public:
const char* getQualifierString() const { return type.getQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); }
+ int totalRegisterCount() const { return type.totalRegisterCount(); }
+ int elementRegisterCount() const { return type.elementRegisterCount(); }
+ int getArraySize() const { return type.getArraySize(); }
+
protected:
TType type;
};
@@ -267,7 +273,7 @@ protected:
enum TLoopType {
ELoopFor,
ELoopWhile,
- ELoopDoWhile,
+ ELoopDoWhile
};
class TIntermLoop : public TIntermNode {
@@ -356,7 +362,10 @@ public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
- void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
+
+ int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
+ float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
+ bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
virtual void traverse(TIntermTraverser*);
@@ -389,7 +398,7 @@ protected:
//
class TIntermBinary : public TIntermOperator {
public:
- TIntermBinary(TOperator o) : TIntermOperator(o) {}
+ TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
virtual TIntermBinary* getAsBinaryNode() { return this; }
virtual void traverse(TIntermTraverser*);
@@ -400,9 +409,15 @@ public:
TIntermTyped* getRight() const { return right; }
bool promote(TInfoSink&);
+ void setAddIndexClamp() { addIndexClamp = true; }
+ bool getAddIndexClamp() { return addIndexClamp; }
+
protected:
TIntermTyped* left;
TIntermTyped* right;
+
+ // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
+ bool addIndexClamp;
};
//
@@ -545,6 +560,10 @@ public:
void incrementDepth() {depth++;}
void decrementDepth() {depth--;}
+ // Return the original name if hash function pointer is NULL;
+ // otherwise return the hashed name.
+ static TString hash(const TString& name, ShHashFunction64 hashFunction);
+
const bool preVisit;
const bool inVisit;
const bool postVisit;
diff --git a/src/3rdparty/angle/src/compiler/osinclude.h b/src/3rdparty/angle/src/compiler/osinclude.h
index 1d95907b79..d8bb1a797c 100644
--- a/src/3rdparty/angle/src/compiler/osinclude.h
+++ b/src/3rdparty/angle/src/compiler/osinclude.h
@@ -24,9 +24,7 @@
#error Unsupported platform.
#endif
-#if defined(ANGLE_USE_NSPR)
-#include "prthread.h"
-#elif defined(ANGLE_OS_WIN)
+#if defined(ANGLE_OS_WIN)
#define STRICT
#define VC_EXTRALEAN 1
#include <windows.h>
@@ -34,7 +32,7 @@
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
-#endif // ANGLE_USE_NSPR
+#endif // ANGLE_OS_WIN
#include "compiler/debug.h"
@@ -42,16 +40,13 @@
//
// Thread Local Storage Operations
//
-#if defined(ANGLE_USE_NSPR)
-typedef PRUintn OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
-#elif defined(ANGLE_OS_WIN)
+#if defined(ANGLE_OS_WIN)
typedef DWORD OS_TLSIndex;
#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
#elif defined(ANGLE_OS_POSIX)
-typedef unsigned int OS_TLSIndex;
-#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
-#endif // ANGLE_USE_NSPR
+typedef pthread_key_t OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1))
+#endif // ANGLE_OS_WIN
OS_TLSIndex OS_AllocTLSIndex();
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
@@ -60,9 +55,7 @@ bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
{
ASSERT(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_USE_NSPR)
- return PR_GetThreadPrivate(nIndex);
-#elif defined(ANGLE_OS_WIN)
+#if defined(ANGLE_OS_WIN)
return TlsGetValue(nIndex);
#elif defined(ANGLE_OS_POSIX)
return pthread_getspecific(nIndex);
diff --git a/src/3rdparty/angle/src/compiler/ossource_nspr.cpp b/src/3rdparty/angle/src/compiler/ossource_nspr.cpp
deleted file mode 100644
index f63d81e5d5..0000000000
--- a/src/3rdparty/angle/src/compiler/ossource_nspr.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-//
-// This file contains the nspr specific functions
-//
-#include "compiler/osinclude.h"
-
-//
-// Thread Local Storage Operations
-//
-OS_TLSIndex OS_AllocTLSIndex()
-{
- PRUintn index;
- PRStatus status = PR_NewThreadPrivateIndex(&index, NULL);
-
- if (status) {
- assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage");
- return OS_INVALID_TLS_INDEX;
- }
-
- return index;
-}
-
-bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
-{
- if (nIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "OS_SetTLSValue(): Invalid TLS Index");
- return false;
- }
-
- return PR_SetThreadPrivate(nIndex, lpvValue) == 0;
-}
-
-bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
-{
- // Can't delete TLS keys with nspr
- return true;
-}
-
diff --git a/src/3rdparty/angle/src/compiler/parseConst.cpp b/src/3rdparty/angle/src/compiler/parseConst.cpp
index 9a8a50c31c..421d31f586 100644
--- a/src/3rdparty/angle/src/compiler/parseConst.cpp
+++ b/src/3rdparty/angle/src/compiler/parseConst.cpp
@@ -151,6 +151,13 @@ bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
{
+ if (!node->getUnionArrayPointer())
+ {
+ // The constant was not initialized, this should already have been logged
+ assert(infoSink.info.size() != 0);
+ return;
+ }
+
ConstantUnion* leftUnionArray = unionArray;
int instanceSize = type.getObjectSize();
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
index 3f50dfc98a..3e22e1f1c5 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include <cassert>
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.h b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h
index 07bc411846..07bc411846 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Diagnostics.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DiagnosticsBase.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp
index ca91e1c71b..ef35c6ed50 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.cpp
@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
-#include "DirectiveHandler.h"
+#include "DirectiveHandlerBase.h"
namespace pp
{
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
index 2aaeec2818..2aaeec2818 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveHandler.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveHandlerBase.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.cpp b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
index f2e42d06bf..94dfdf513d 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.cpp
@@ -10,8 +10,8 @@
#include <cstdlib>
#include <sstream>
-#include "Diagnostics.h"
-#include "DirectiveHandler.h"
+#include "DiagnosticsBase.h"
+#include "DirectiveHandlerBase.h"
#include "ExpressionParser.h"
#include "MacroExpander.h"
#include "Token.h"
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.h b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h
index 8a7f0072ba..8a7f0072ba 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/DirectiveParser.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/DirectiveParser.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.h b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h
index 092d059413..092d059413 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.y b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y
index 832ad4001e..b6d3143e60 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/ExpressionParser.y
+++ b/src/3rdparty/angle/src/compiler/preprocessor/ExpressionParser.y
@@ -22,7 +22,11 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
#if defined(__GNUC__)
// Triggered by the auto-generated pplval variable.
+#if !defined(__clang__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#else
#pragma GCC diagnostic ignored "-Wuninitialized"
+#endif
#elif defined(_MSC_VER)
#pragma warning(disable: 4065 4701)
#endif
@@ -32,7 +36,7 @@ WHICH GENERATES THE GLSL ES preprocessor expression parser.
#include <cassert>
#include <sstream>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Lexer.h"
#include "Token.h"
@@ -42,6 +46,8 @@ typedef __int64 YYSTYPE;
#include <stdint.h>
typedef intmax_t YYSTYPE;
#endif // _MSC_VER
+#define YYENABLE_NLS 0
+#define YYLTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_TRIVIAL 1
#define YYSTYPE_IS_DECLARED 1
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Input.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp
index c3de95f313..b4d970a97d 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Input.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Input.cpp
@@ -17,27 +17,26 @@ Input::Input() : mCount(0), mString(0)
{
}
-Input::Input(int count, const char* const string[], const int length[]) :
+Input::Input(size_t count, const char* const string[], const int length[]) :
mCount(count),
mString(string)
{
- assert(mCount >= 0);
mLength.reserve(mCount);
- for (int i = 0; i < mCount; ++i)
+ for (size_t i = 0; i < mCount; ++i)
{
int len = length ? length[i] : -1;
- mLength.push_back(len < 0 ? strlen(mString[i]) : len);
+ mLength.push_back(len < 0 ? std::strlen(mString[i]) : len);
}
}
-int Input::read(char* buf, int maxSize)
+size_t Input::read(char* buf, size_t maxSize)
{
- int nRead = 0;
+ size_t nRead = 0;
while ((nRead < maxSize) && (mReadLoc.sIndex < mCount))
{
- int size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
+ size_t size = mLength[mReadLoc.sIndex] - mReadLoc.cIndex;
size = std::min(size, maxSize);
- memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
+ std::memcpy(buf + nRead, mString[mReadLoc.sIndex] + mReadLoc.cIndex, size);
nRead += size;
mReadLoc.cIndex += size;
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Input.h b/src/3rdparty/angle/src/compiler/preprocessor/Input.h
index dac734b68d..14b7597cb4 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Input.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Input.h
@@ -7,6 +7,7 @@
#ifndef COMPILER_PREPROCESSOR_INPUT_H_
#define COMPILER_PREPROCESSOR_INPUT_H_
+#include <stddef.h>
#include <vector>
namespace pp
@@ -17,18 +18,18 @@ class Input
{
public:
Input();
- Input(int count, const char* const string[], const int length[]);
+ Input(size_t count, const char* const string[], const int length[]);
- int count() const { return mCount; }
- const char* string(int index) const { return mString[index]; }
- int length(int index) const { return mLength[index]; }
+ size_t count() const { return mCount; }
+ const char* string(size_t index) const { return mString[index]; }
+ size_t length(size_t index) const { return mLength[index]; }
- int read(char* buf, int maxSize);
+ size_t read(char* buf, size_t maxSize);
struct Location
{
- int sIndex; // String index;
- int cIndex; // Char index.
+ size_t sIndex; // String index;
+ size_t cIndex; // Char index.
Location() : sIndex(0), cIndex(0) { }
};
@@ -36,9 +37,9 @@ class Input
private:
// Input.
- int mCount;
+ size_t mCount;
const char* const* mString;
- std::vector<int> mLength;
+ std::vector<size_t> mLength;
Location mReadLoc;
};
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp
index 7c663ee761..7c663ee761 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.cpp
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.h b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h
index eb85cea873..eb85cea873 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Lexer.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Lexer.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Macro.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp
index b2e3088e32..b2e3088e32 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Macro.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Macro.cpp
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Macro.h b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h
index 7ec0149116..7ec0149116 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Macro.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Macro.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.cpp b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
index 701cec9a4b..1116c516ff 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.cpp
@@ -9,7 +9,7 @@
#include <algorithm>
#include <sstream>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Token.h"
namespace pp
@@ -57,7 +57,7 @@ MacroExpander::MacroExpander(Lexer* lexer,
MacroExpander::~MacroExpander()
{
- for (size_t i = 0; i < mContextStack.size(); ++i)
+ for (std::size_t i = 0; i < mContextStack.size(); ++i)
{
delete mContextStack[i];
}
@@ -224,7 +224,7 @@ bool MacroExpander::expandMacro(const Macro& macro,
replaceMacroParams(macro, args, replacements);
}
- for (size_t i = 0; i < replacements->size(); ++i)
+ for (std::size_t i = 0; i < replacements->size(); ++i)
{
Token& repl = replacements->at(i);
if (i == 0)
@@ -311,7 +311,7 @@ bool MacroExpander::collectMacroArgs(const Macro& macro,
// Pre-expand each argument before substitution.
// This step expands each argument individually before they are
// inserted into the macro body.
- for (size_t i = 0; i < args->size(); ++i)
+ for (std::size_t i = 0; i < args->size(); ++i)
{
MacroArg& arg = args->at(i);
TokenLexer lexer(&arg);
@@ -332,7 +332,7 @@ void MacroExpander::replaceMacroParams(const Macro& macro,
const std::vector<MacroArg>& args,
std::vector<Token>* replacements)
{
- for (size_t i = 0; i < macro.replacements.size(); ++i)
+ for (std::size_t i = 0; i < macro.replacements.size(); ++i)
{
const Token& repl = macro.replacements[i];
if (repl.type != Token::IDENTIFIER)
@@ -352,13 +352,13 @@ void MacroExpander::replaceMacroParams(const Macro& macro,
continue;
}
- size_t iArg = std::distance(macro.parameters.begin(), iter);
+ std::size_t iArg = std::distance(macro.parameters.begin(), iter);
const MacroArg& arg = args[iArg];
if (arg.empty())
{
continue;
}
- size_t iRepl = replacements->size();
+ std::size_t iRepl = replacements->size();
replacements->insert(replacements->end(), arg.begin(), arg.end());
// The replacement token inherits padding properties from
// macro replacement token.
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.h b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h
index 7c5c543871..21b67571f1 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/MacroExpander.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/MacroExpander.h
@@ -53,7 +53,7 @@ class MacroExpander : public Lexer
struct MacroContext
{
const Macro* macro;
- size_t index;
+ std::size_t index;
std::vector<Token> replacements;
MacroContext() : macro(0), index(0) { }
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp
index ffa7225a8f..5ffc6420bc 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.cpp
@@ -9,7 +9,7 @@
#include <cassert>
#include <sstream>
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "DirectiveParser.h"
#include "Macro.h"
#include "MacroExpander.h"
@@ -48,7 +48,7 @@ Preprocessor::~Preprocessor()
delete mImpl;
}
-bool Preprocessor::init(int count,
+bool Preprocessor::init(size_t count,
const char* const string[],
const int length[])
{
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.h b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
index 5fe35b27bd..7b70180fc8 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Preprocessor.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Preprocessor.h
@@ -7,6 +7,8 @@
#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_
#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_
+#include <stddef.h>
+
#include "pp_utils.h"
namespace pp
@@ -32,7 +34,7 @@ class Preprocessor
// Each element in the length array may contain the length of the
// corresponding string or a value less than 0 to indicate that the string
// is null terminated.
- bool init(int count, const char* const string[], const int length[]);
+ bool init(size_t count, const char* const string[], const int length[]);
// Adds a pre-defined macro.
void predefineMacro(const char* name, int value);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/SourceLocation.h b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h
index 6982613ac7..6982613ac7 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/SourceLocation.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/SourceLocation.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Token.cpp b/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp
index 67f50aa32c..67f50aa32c 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Token.cpp
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Token.cpp
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Token.h b/src/3rdparty/angle/src/compiler/preprocessor/Token.h
index 8b553aecb6..8b553aecb6 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Token.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Token.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.h b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
index a594d2d865..7a6fa87b04 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.h
@@ -32,12 +32,12 @@ class Tokenizer : public Lexer
bool leadingSpace;
bool lineStart;
};
- static const size_t kMaxTokenLength;
+ static const std::size_t kMaxTokenLength;
Tokenizer(Diagnostics* diagnostics);
~Tokenizer();
- bool init(int count, const char* const string[], const int length[]);
+ bool init(size_t count, const char* const string[], const int length[]);
void setFileNumber(int file);
void setLineNumber(int line);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.l b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
index 9762988350..fc81d84f37 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/Tokenizer.l
+++ b/src/3rdparty/angle/src/compiler/preprocessor/Tokenizer.l
@@ -1,6 +1,6 @@
/*
//
-// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -14,7 +14,7 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
%top{
//
-// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2011-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -25,7 +25,7 @@ IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh.
%{
#include "Tokenizer.h"
-#include "Diagnostics.h"
+#include "DiagnosticsBase.h"
#include "Token.h"
#if defined(__GNUC__)
@@ -229,6 +229,8 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
return '\n';
}
+\\{NEWLINE} { ++yylineno; }
+
. {
yylval->assign(1, yytext[0]);
return pp::Token::PP_OTHER;
@@ -239,13 +241,14 @@ FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".")
// Set the location for EOF token manually.
pp::Input* input = &yyextra->input;
pp::Input::Location* scanLoc = &yyextra->scanLoc;
- int sIndexMax = std::max(0, input->count() - 1);
+ yy_size_t sIndexMax = input->count() ? input->count() - 1 : 0;
if (scanLoc->sIndex != sIndexMax)
{
// We can only reach here if there are empty strings at the
// end of the input.
scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0;
- yyfileno = sIndexMax; yylineno = 1;
+ // FIXME: this is not 64-bit clean.
+ yyfileno = static_cast<int>(sIndexMax); yylineno = 1;
}
yylloc->file = yyfileno;
yylloc->line = yylineno;
@@ -278,9 +281,8 @@ Tokenizer::~Tokenizer()
destroyScanner();
}
-bool Tokenizer::init(int count, const char* const string[], const int length[])
+bool Tokenizer::init(size_t count, const char* const string[], const int length[])
{
- if (count < 0) return false;
if ((count > 0) && (string == 0)) return false;
mContext.input = Input(count, string, length);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/atom.c b/src/3rdparty/angle/src/compiler/preprocessor/atom.c
deleted file mode 100644
index 39158d2fa1..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/atom.c
+++ /dev/null
@@ -1,737 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-//
-// atom.c
-//
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "common/angleutils.h"
-#include "compiler/debug.h"
-#include "compiler/preprocessor/slglobals.h"
-
-#undef malloc
-#undef realloc
-#undef free
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////// String table: //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-static const struct {
- int val;
- const char *str;
-} tokens[] = {
- { CPP_AND_OP, "&&" },
- { CPP_AND_ASSIGN, "&=" },
- { CPP_SUB_ASSIGN, "-=" },
- { CPP_MOD_ASSIGN, "%=" },
- { CPP_ADD_ASSIGN, "+=" },
- { CPP_DIV_ASSIGN, "/=" },
- { CPP_MUL_ASSIGN, "*=" },
- { CPP_RIGHT_BRACKET, ":>" },
- { CPP_EQ_OP, "==" },
- { CPP_XOR_OP, "^^" },
- { CPP_XOR_ASSIGN, "^=" },
- { CPP_FLOATCONSTANT, "<float-const>" },
- { CPP_GE_OP, ">=" },
- { CPP_RIGHT_OP, ">>" },
- { CPP_RIGHT_ASSIGN, ">>=" },
- { CPP_IDENTIFIER, "<ident>" },
- { CPP_INTCONSTANT, "<int-const>" },
- { CPP_LE_OP, "<=" },
- { CPP_LEFT_OP, "<<" },
- { CPP_LEFT_ASSIGN, "<<=" },
- { CPP_LEFT_BRACKET, "<:" },
- { CPP_LEFT_BRACE, "<%" },
- { CPP_DEC_OP, "--" },
- { CPP_RIGHT_BRACE, "%>" },
- { CPP_NE_OP, "!=" },
- { CPP_OR_OP, "||" },
- { CPP_OR_ASSIGN, "|=" },
- { CPP_INC_OP, "++" },
- { CPP_STRCONSTANT, "<string-const>" },
- { CPP_TYPEIDENTIFIER, "<type-ident>" },
-};
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////// String table: //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#define INIT_STRING_TABLE_SIZE 16384
-
-typedef struct StringTable_Rec {
- char *strings;
- int nextFree;
- int size;
-} StringTable;
-
-/*
- * InitStringTable() - Initialize the string table.
- *
- */
-
-static int InitStringTable(StringTable *stable)
-{
- stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
- if (!stable->strings)
- return 0;
- // Zero-th offset means "empty" so don't use it.
- stable->nextFree = 1;
- stable->size = INIT_STRING_TABLE_SIZE;
- return 1;
-} // InitStringTable
-
-/*
- * FreeStringTable() - Free the string table.
- *
- */
-
-static void FreeStringTable(StringTable *stable)
-{
- if (stable->strings)
- free(stable->strings);
- stable->strings = NULL;
- stable->nextFree = 0;
- stable->size = 0;
-} // FreeStringTable
-
-/*
- * HashString() - Hash a string with the base hash function.
- *
- */
-
-static int HashString(const char *s)
-{
- int hval = 0;
-
- while (*s) {
- hval = (hval*13507 + *s*197) ^ (hval >> 2);
- s++;
- }
- return hval & 0x7fffffff;
-} // HashString
-
-/*
- * HashString2() - Hash a string with the incrimenting hash function.
- *
- */
-
-static int HashString2(const char *s)
-{
- int hval = 0;
-
- while (*s) {
- hval = (hval*729 + *s*37) ^ (hval >> 1);
- s++;
- }
- return hval;
-} // HashString2
-
-/*
- * AddString() - Add a string to a string table. Return it's offset.
- *
- */
-
-static int AddString(StringTable *stable, const char *s)
-{
- int len, loc;
- char *str;
-
- len = (int) strlen(s);
- while (stable->nextFree + len + 1 >= stable->size) {
- assert(stable->size < 1000000);
- str = (char *) malloc(stable->size*2);
- memcpy(str, stable->strings, stable->size);
- free(stable->strings);
- stable->strings = str;
- stable->size = stable->size*2;
- }
- loc = stable->nextFree;
- strcpy(&stable->strings[loc], s);
- stable->nextFree += len + 1;
- return loc;
-} // AddString
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////// Hash table: ///////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#define INIT_HASH_TABLE_SIZE 2047
-#define HASH_TABLE_MAX_COLLISIONS 3
-
-typedef struct HashEntry_Rec {
- int index; // String table offset of string representation
- int value; // Atom (symbol) value
-} HashEntry;
-
-typedef struct HashTable_Rec {
- HashEntry *entry;
- int size;
- int entries;
- int counts[HASH_TABLE_MAX_COLLISIONS + 1];
-} HashTable;
-
-/*
- * InitHashTable() - Initialize the hash table.
- *
- */
-
-static int InitHashTable(HashTable *htable, int fsize)
-{
- int ii;
-
- htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
- if (!htable->entry)
- return 0;
- htable->size = fsize;
- for (ii = 0; ii < fsize; ii++) {
- htable->entry[ii].index = 0;
- htable->entry[ii].value = 0;
- }
- htable->entries = 0;
- for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
- htable->counts[ii] = 0;
- return 1;
-} // InitHashTable
-
-/*
- * FreeHashTable() - Free the hash table.
- *
- */
-
-static void FreeHashTable(HashTable *htable)
-{
- if (htable->entry)
- free(htable->entry);
- htable->entry = NULL;
- htable->size = 0;
- htable->entries = 0;
-} // FreeHashTable
-
-/*
- * Empty() - See if a hash table entry is empty.
- *
- */
-
-static int Empty(HashTable *htable, int hashloc)
-{
- assert(hashloc >= 0 && hashloc < htable->size);
- if (htable->entry[hashloc].index == 0) {
- return 1;
- } else {
- return 0;
- }
-} // Empty
-
-/*
- * Match() - See if a hash table entry is matches a string.
- *
- */
-
-static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
-{
- int strloc;
-
- strloc = htable->entry[hashloc].index;
- if (!strcmp(s, &stable->strings[strloc])) {
- return 1;
- } else {
- return 0;
- }
-} // Match
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////// Atom table: ///////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#define INIT_ATOM_TABLE_SIZE 1024
-
-
-struct AtomTable_Rec {
- StringTable stable; // String table.
- HashTable htable; // Hashes string to atom number and token value. Multiple strings can
- // have the same token value but each unique string is a unique atom.
- int *amap; // Maps atom value to offset in string table. Atoms all map to unique
- // strings except for some undefined values in the lower, fixed part
- // of the atom table that map to "<undefined>". The lowest 256 atoms
- // correspond to single character ASCII values except for alphanumeric
- // characters and '_', which can be other tokens. Next come the
- // language tokens with their atom values equal to the token value.
- // Then come predefined atoms, followed by user specified identifiers.
- int *arev; // Reversed atom for symbol table use.
- int nextFree;
- int size;
-};
-
-static AtomTable latable = { { NULL, 0, 0 }, { NULL, 0, 0, {0} }, NULL, NULL, 0, 0 };
-AtomTable *atable = &latable;
-
-static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
-
-/*
- * GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
- *
- */
-
-static int GrowAtomTable(AtomTable *atable, int size)
-{
- int *newmap, *newrev;
-
- if (atable->size < size) {
- if (atable->amap) {
- newmap = realloc(atable->amap, sizeof(int)*size);
- newrev = realloc(atable->arev, sizeof(int)*size);
- } else {
- newmap = malloc(sizeof(int)*size);
- newrev = malloc(sizeof(int)*size);
- atable->size = 0;
- }
- if (!newmap || !newrev) {
- /* failed to grow -- error */
- if (newmap)
- atable->amap = newmap;
- if (newrev)
- atable->arev = newrev;
- return -1;
- }
- memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
- memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
- atable->amap = newmap;
- atable->arev = newrev;
- atable->size = size;
- }
- return 0;
-} // GrowAtomTable
-
-/*
- * lReverse() - Reverse the bottom 20 bits of a 32 bit int.
- *
- */
-
-static int lReverse(int fval)
-{
- unsigned int in = fval;
- int result = 0, cnt = 0;
-
- while(in) {
- result <<= 1;
- result |= in&1;
- in >>= 1;
- cnt++;
- }
-
- // Don't use all 31 bits. One million atoms is plenty and sometimes the
- // upper bits are used for other things.
-
- if (cnt < 20)
- result <<= 20 - cnt;
- return result;
-} // lReverse
-
-/*
- * AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
- *
- */
-
-static int AllocateAtom(AtomTable *atable)
-{
- if (atable->nextFree >= atable->size)
- GrowAtomTable(atable, atable->nextFree*2);
- atable->amap[atable->nextFree] = -1;
- atable->arev[atable->nextFree] = lReverse(atable->nextFree);
- atable->nextFree++;
- return atable->nextFree - 1;
-} // AllocateAtom
-
-/*
- * SetAtomValue() - Allocate a new atom associated with "hashindex".
- *
- */
-
-static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
-{
- atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
- atable->htable.entry[hashindex].value = atomnumber;
-} // SetAtomValue
-
-/*
- * FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
- *
- */
-
-static int FindHashLoc(AtomTable *atable, const char *s)
-{
- int hashloc, hashdelta, count;
- int FoundEmptySlot = 0;
- int collision[HASH_TABLE_MAX_COLLISIONS + 1];
-
- hashloc = HashString(s) % atable->htable.size;
- if (!Empty(&atable->htable, hashloc)) {
- if (Match(&atable->htable, &atable->stable, s, hashloc))
- return hashloc;
- collision[0] = hashloc;
- hashdelta = HashString2(s);
- count = 0;
- while (count < HASH_TABLE_MAX_COLLISIONS) {
- hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
- if (!Empty(&atable->htable, hashloc)) {
- if (Match(&atable->htable, &atable->stable, s, hashloc)) {
- return hashloc;
- }
- } else {
- FoundEmptySlot = 1;
- break;
- }
- count++;
- collision[count] = hashloc;
- }
-
- if (!FoundEmptySlot) {
- if (cpp->options.DumpAtomTable) {
- int ii;
- char str[200];
- snprintf(str, sizeof(str), "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
- HASH_TABLE_MAX_COLLISIONS);
- CPPShInfoLogMsg(str);
-
- snprintf(str, sizeof(str), "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
- CPPShInfoLogMsg(str);
- for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
- snprintf(str, sizeof(str), "*** Collides on try %d at hash entry %04x with \"%s\"",
- ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
- CPPShInfoLogMsg(str);
- }
- }
- return -1;
- } else {
- atable->htable.counts[count]++;
- }
- }
- return hashloc;
-} // FindHashLoc
-
-/*
- * IncreaseHashTableSize()
- *
- */
-
-static int IncreaseHashTableSize(AtomTable *atable)
-{
- int ii, strloc, oldhashloc, value, size;
- AtomTable oldtable;
- char *s;
-
- // Save the old atom table and create a new one:
-
- oldtable = *atable;
- size = oldtable.htable.size*2 + 1;
- if (!InitAtomTable(atable, size))
- return 0;
-
- // Add all the existing values to the new atom table preserving their atom values:
-
- for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
- strloc = oldtable.amap[ii];
- s = &oldtable.stable.strings[strloc];
- oldhashloc = FindHashLoc(&oldtable, s);
- assert(oldhashloc >= 0);
- value = oldtable.htable.entry[oldhashloc].value;
- AddAtomFixed(atable, s, value);
- }
- FreeAtomTable(&oldtable);
- return 1;
-} // IncreaseHashTableSize
-
-/*
- * LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
- * initialize the atom value in the hash table to 0. Return the hash table index.
- */
-
-static int LookUpAddStringHash(AtomTable *atable, const char *s)
-{
- int hashloc, strloc;
-
- while(1) {
- hashloc = FindHashLoc(atable, s);
- if (hashloc >= 0)
- break;
- IncreaseHashTableSize(atable);
- }
-
- if (Empty(&atable->htable, hashloc)) {
- atable->htable.entries++;
- strloc = AddString(&atable->stable, s);
- atable->htable.entry[hashloc].index = strloc;
- atable->htable.entry[hashloc].value = 0;
- }
- return hashloc;
-} // LookUpAddStringHash
-
-/*
- * LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
- * initialize the atom value in the hash table to the next atom number.
- * Return the atom value of string.
- */
-
-int LookUpAddString(AtomTable *atable, const char *s)
-{
- int hashindex, atom;
-
- hashindex = LookUpAddStringHash(atable, s);
- atom = atable->htable.entry[hashindex].value;
- if (atom == 0) {
- atom = AllocateAtom(atable);
- SetAtomValue(atable, atom, hashindex);
- }
- return atom;
-} // LookUpAddString
-
-/*
- * GetAtomString()
- *
- */
-
-const char *GetAtomString(AtomTable *atable, int atom)
-{
- int soffset;
-
- if (atom > 0 && atom < atable->nextFree) {
- soffset = atable->amap[atom];
- if (soffset > 0 && soffset < atable->stable.nextFree) {
- return &atable->stable.strings[soffset];
- } else {
- return "<internal error: bad soffset>";
- }
- } else {
- if (atom == 0) {
- return "<null atom>";
- } else {
- if (atom == EOF) {
- return "<EOF>";
- } else {
- return "<invalid atom>";
- }
- }
- }
-} // GetAtomString
-
-/*
- * GetReversedAtom()
- *
- */
-
-int GetReversedAtom(AtomTable *atable, int atom)
-{
- if (atom > 0 && atom < atable->nextFree) {
- return atable->arev[atom];
- } else {
- return 0;
- }
-} // GetReversedAtom
-
-/*
- * AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
- * Return it's atom index.
- */
-
-int AddAtom(AtomTable *atable, const char *s)
-{
- int atom;
-
- atom = LookUpAddString(atable, s);
- return atom;
-} // AddAtom
-
-/*
- * AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
- * Assign it the atom value of "atom".
- */
-
-static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
-{
- int hashindex, lsize;
-
- hashindex = LookUpAddStringHash(atable, s);
- if (atable->nextFree >= atable->size || atom >= atable->size) {
- lsize = atable->size*2;
- if (lsize <= atom)
- lsize = atom + 1;
- GrowAtomTable(atable, lsize);
- }
- atable->amap[atom] = atable->htable.entry[hashindex].index;
- atable->htable.entry[hashindex].value = atom;
- //if (atom >= atable->nextFree)
- // atable->nextFree = atom + 1;
- while (atom >= atable->nextFree) {
- atable->arev[atable->nextFree] = lReverse(atable->nextFree);
- atable->nextFree++;
- }
- return atom;
-} // AddAtomFixed
-
-/*
- * InitAtomTable() - Initialize the atom table.
- *
- */
-
-int InitAtomTable(AtomTable *atable, int htsize)
-{
- unsigned int ii;
-
- htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
- if (!InitStringTable(&atable->stable))
- return 0;
- if (!InitHashTable(&atable->htable, htsize))
- return 0;
-
- atable->nextFree = 0;
- atable->amap = NULL;
- atable->size = 0;
- GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
- if (!atable->amap)
- return 0;
-
- // Initialize lower part of atom table to "<undefined>" atom:
-
- AddAtomFixed(atable, "<undefined>", 0);
- for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
- atable->amap[ii] = atable->amap[0];
-
- // Add single character tokens to the atom table:
-
- {
- const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
- char t[2];
-
- t[1] = '\0';
- while (*s) {
- t[0] = *s;
- AddAtomFixed(atable, t, s[0]);
- s++;
- }
- }
-
- // Add multiple character scanner tokens :
-
- for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
- AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
-
- // Add error symbol if running in error mode:
-
- if (cpp->options.ErrorMode)
- AddAtomFixed(atable, "error", ERROR_SY);
-
- AddAtom(atable, "<*** end fixed atoms ***>");
-
- return 1;
-} // InitAtomTable
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////// Debug Printing Functions: //////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
- * PrintAtomTable()
- *
- */
-
-void PrintAtomTable(AtomTable *atable)
-{
- int ii;
- char str[200];
-
- for (ii = 0; ii < atable->nextFree; ii++) {
- snprintf(str, sizeof(str), "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
- CPPDebugLogMsg(str);
- }
- snprintf(str, sizeof(str), "Hash table: size=%d, entries=%d, collisions=",
- atable->htable.size, atable->htable.entries);
- CPPDebugLogMsg(str);
- for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
- snprintf(str, sizeof(str), " %d", atable->htable.counts[ii]);
- CPPDebugLogMsg(str);
- }
-
-} // PrintAtomTable
-
-
-/*
- * GetStringOfAtom()
- *
- */
-
-char* GetStringOfAtom(AtomTable *atable, int atom)
-{
- char* chr_str;
- chr_str=&atable->stable.strings[atable->amap[atom]];
- return chr_str;
-} // GetStringOfAtom
-
-/*
- * FreeAtomTable() - Free the atom table and associated memory
- *
- */
-
-void FreeAtomTable(AtomTable *atable)
-{
- FreeStringTable(&atable->stable);
- FreeHashTable(&atable->htable);
- if (atable->amap)
- free(atable->amap);
- if (atable->arev)
- free(atable->arev);
- atable->amap = NULL;
- atable->arev = NULL;
- atable->nextFree = 0;
- atable->size = 0;
-} // FreeAtomTable
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////// End of atom.c ///////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/atom.h b/src/3rdparty/angle/src/compiler/preprocessor/atom.h
deleted file mode 100644
index 1d84c32515..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/atom.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// atom.h
-//
-
-#if !defined(__ATOM_H)
-#define __ATOM_H 1
-
-typedef struct AtomTable_Rec AtomTable;
-
-extern AtomTable *atable;
-
-int InitAtomTable(AtomTable *atable, int htsize);
-void FreeAtomTable(AtomTable *atable);
-int AddAtom(AtomTable *atable, const char *s);
-void PrintAtomTable(AtomTable *atable);
-int LookUpAddString(AtomTable *atable, const char *s);
-const char *GetAtomString(AtomTable *atable, int atom);
-int GetReversedAtom(AtomTable *atable, int atom);
-char* GetStringOfAtom(AtomTable *atable, int atom);
-#endif // !defined(__ATOM_H)
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/compile.h b/src/3rdparty/angle/src/compiler/preprocessor/compile.h
deleted file mode 100644
index 11808531cc..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/compile.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// compile.h
-//
-
-#if !defined(__COMPILE_H)
-#define __COMPILE_H 1
-
-int InitCPPStruct(void);
-
-typedef struct Options_Rec{
- const char *profileString;
- int ErrorMode;
- int Quiet;
-
- // Debug The Compiler options:
- int DumpAtomTable;
-} Options;
-
-#define MAX_IF_NESTING 64
-struct CPPStruct_Rec {
- // Public members
- SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers
- Options options; // Compile options and parameters
-
- // Private members
- SourceLoc lastSourceLoc;
-
- // Scanner data:
-
- SourceLoc *tokenLoc; // Source location of most recent token seen by the scanner
- int mostRecentToken; // Most recent token seen by the scanner
- InputSrc *currentInput;
- int previous_token;
- int pastFirstStatement; // used to make sure that #version is the first statement seen in the file, if present
-
- void *pC; // storing the parseContext of the compile object in cpp.
-
- // Private members:
- SourceLoc ltokenLoc;
- int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor)
- int elsedepth[MAX_IF_NESTING];//Keep a track of #if depth..Max allowed is 64.
- int elsetracker; //#if-#else and #endif constructs...Counter.
- const char *ErrMsg;
- int CompileError; //Indicate compile error when #error, #else,#elif mismatch.
-
- //
- // Globals used to communicate between PaParseStrings() and yy_input()and
- // also across the files.(gen_glslang.cpp and scanner.c)
- //
- int PaWhichStr; // which string we're parsing
- const int* PaStrLen; // array of lengths of the PaArgv strings
- int PaArgc; // count of strings in the array
- const char* const* PaArgv; // our array of strings to parse
- unsigned int tokensBeforeEOF : 1;
-};
-
-#endif // !defined(__COMPILE_H)
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/cpp.c b/src/3rdparty/angle/src/compiler/preprocessor/cpp.c
deleted file mode 100644
index 8a1076b9df..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/cpp.c
+++ /dev/null
@@ -1,1118 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// cpp.c
-//
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "common/angleutils.h"
-#include "compiler/preprocessor/slglobals.h"
-
-#if defined(_MSC_VER)
-#pragma warning(disable: 4054)
-#pragma warning(disable: 4152)
-#pragma warning(disable: 4706)
-#endif
-
-static int CPPif(yystypepp * yylvalpp);
-
-/* Don't use memory.c's replacements, as we clean up properly here */
-#undef malloc
-#undef free
-
-static int bindAtom = 0;
-static int constAtom = 0;
-static int defaultAtom = 0;
-static int defineAtom = 0;
-static int definedAtom = 0;
-static int elseAtom = 0;
-static int elifAtom = 0;
-static int endifAtom = 0;
-static int ifAtom = 0;
-static int ifdefAtom = 0;
-static int ifndefAtom = 0;
-static int includeAtom = 0;
-static int lineAtom = 0;
-static int pragmaAtom = 0;
-static int texunitAtom = 0;
-static int undefAtom = 0;
-static int errorAtom = 0;
-static int __LINE__Atom = 0;
-static int __FILE__Atom = 0;
-static int __VERSION__Atom = 0;
-static int versionAtom = 0;
-static int extensionAtom = 0;
-
-static Scope *macros = 0;
-#define MAX_MACRO_ARGS 64
-
-static SourceLoc ifloc; /* outermost #if */
-
-int InitCPP(void)
-{
- char buffer[64], *t;
- const char *f;
-
- // Add various atoms needed by the CPP line scanner:
- bindAtom = LookUpAddString(atable, "bind");
- constAtom = LookUpAddString(atable, "const");
- defaultAtom = LookUpAddString(atable, "default");
- defineAtom = LookUpAddString(atable, "define");
- definedAtom = LookUpAddString(atable, "defined");
- elifAtom = LookUpAddString(atable, "elif");
- elseAtom = LookUpAddString(atable, "else");
- endifAtom = LookUpAddString(atable, "endif");
- ifAtom = LookUpAddString(atable, "if");
- ifdefAtom = LookUpAddString(atable, "ifdef");
- ifndefAtom = LookUpAddString(atable, "ifndef");
- includeAtom = LookUpAddString(atable, "include");
- lineAtom = LookUpAddString(atable, "line");
- pragmaAtom = LookUpAddString(atable, "pragma");
- texunitAtom = LookUpAddString(atable, "texunit");
- undefAtom = LookUpAddString(atable, "undef");
- errorAtom = LookUpAddString(atable, "error");
- __LINE__Atom = LookUpAddString(atable, "__LINE__");
- __FILE__Atom = LookUpAddString(atable, "__FILE__");
- __VERSION__Atom = LookUpAddString(atable, "__VERSION__");
- versionAtom = LookUpAddString(atable, "version");
- extensionAtom = LookUpAddString(atable, "extension");
- macros = NewScopeInPool(mem_CreatePool(0, 0));
- strcpy(buffer, "PROFILE_");
- t = buffer + strlen(buffer);
- f = cpp->options.profileString;
- while ((isalnum(*f) || *f == '_') && t < buffer + sizeof(buffer) - 1)
- *t++ = toupper(*f++);
- *t = 0;
-
- PredefineIntMacro("GL_ES", 1);
- PredefineIntMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
-
- return 1;
-} // InitCPP
-
-int FreeCPP(void)
-{
- if (macros)
- {
- mem_FreePool(macros->pool);
- macros = 0;
- }
-
- return 1;
-}
-
-int FinalCPP(void)
-{
- if (cpp->ifdepth)
- CPPErrorToInfoLog("#if mismatch");
- return 1;
-}
-
-static int CPPdefine(yystypepp * yylvalpp)
-{
- int token, name, args[MAX_MACRO_ARGS], argc;
- const char *message;
- MacroSymbol mac;
- Symbol *symb;
- SourceLoc dummyLoc;
- memset(&mac, 0, sizeof(mac));
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != CPP_IDENTIFIER) {
- CPPErrorToInfoLog("#define");
- return token;
- }
- name = yylvalpp->sc_ident;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(' && !yylvalpp->sc_int) {
- // gather arguments
- argc = 0;
- do {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (argc == 0 && token == ')') break;
- if (token != CPP_IDENTIFIER) {
- CPPErrorToInfoLog("#define");
- return token;
- }
- if (argc < MAX_MACRO_ARGS)
- args[argc++] = yylvalpp->sc_ident;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- } while (token == ',');
- if (token != ')') {
- CPPErrorToInfoLog("#define");
- return token;
- }
- mac.argc = argc;
- mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
- memcpy(mac.args, args, argc * sizeof(int));
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- mac.body = NewTokenStream(GetAtomString(atable, name), macros->pool);
- while (token != '\n') {
- if (token == '\\') {
- CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
- return token;
- } else if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input in #define preprocessor directive - expected a newline");
- return 0;
- }
- RecordToken(mac.body, token, yylvalpp);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- };
-
- symb = LookUpSymbol(macros, name);
- if (symb) {
- if (!symb->details.mac.undef) {
- // already defined -- need to make sure they are identical
- if (symb->details.mac.argc != mac.argc) goto error;
- for (argc=0; argc < mac.argc; argc++)
- if (symb->details.mac.args[argc] != mac.args[argc])
- goto error;
- RewindTokenStream(symb->details.mac.body);
- RewindTokenStream(mac.body);
- do {
- int old_lval, old_token;
- old_token = ReadToken(symb->details.mac.body, yylvalpp);
- old_lval = yylvalpp->sc_int;
- token = ReadToken(mac.body, yylvalpp);
- if (token != old_token || yylvalpp->sc_int != old_lval) {
- error:
- StoreStr("Macro Redefined");
- StoreStr(GetStringOfAtom(atable,name));
- message=GetStrfromTStr();
- DecLineNumber();
- CPPShInfoLogMsg(message);
- IncLineNumber();
- ResetTString();
- break; }
- } while (token > 0);
- }
- //FreeMacro(&symb->details.mac);
- } else {
- dummyLoc.file = 0;
- dummyLoc.line = 0;
- symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
- }
- symb->details.mac = mac;
- return '\n';
-} // CPPdefine
-
-static int CPPundef(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- Symbol *symb;
- if(token == '\n'){
- CPPErrorToInfoLog("#undef");
- return token;
- }
- if (token != CPP_IDENTIFIER)
- goto error;
- symb = LookUpSymbol(macros, yylvalpp->sc_ident);
- if (symb) {
- symb->details.mac.undef = 1;
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- error:
- CPPErrorToInfoLog("#undef");
- }
- return token;
-} // CPPundef
-
-/* CPPelse -- skip forward to appropriate spot. This is actually used
-** to skip to and #endif after seeing an #else, AND to skip to a #else,
-** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
-*/
-
-static int CPPelse(int matchelse, yystypepp * yylvalpp)
-{
- int atom,depth=0;
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- while (token > 0) {
- if (token != '#') {
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input in #else preprocessor directive - expected a newline");
- return 0;
- }
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- continue;
- }
- if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
- continue;
- atom = yylvalpp->sc_ident;
- if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
- depth++; cpp->ifdepth++; cpp->elsetracker++;
- if (cpp->ifdepth > MAX_IF_NESTING) {
- CPPErrorToInfoLog("max #if nesting depth exceeded");
- cpp->CompileError = 1;
- return 0;
- }
- // sanity check elsetracker
- if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
- CPPErrorToInfoLog("mismatched #if/#endif statements");
- cpp->CompileError = 1;
- return 0;
- }
- cpp->elsedepth[cpp->elsetracker] = 0;
- }
- else if (atom == endifAtom) {
- if(--depth<0){
- if (cpp->elsetracker)
- --cpp->elsetracker;
- if (cpp->ifdepth)
- --cpp->ifdepth;
- break;
- }
- --cpp->elsetracker;
- --cpp->ifdepth;
- }
- else if (((int)(matchelse) != 0)&& depth==0) {
- if (atom == elseAtom ) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input following #else preprocessor directive - expected a newline");
- return 0;
- }
- }
- }
- break;
- }
- else if (atom == elifAtom) {
- /* we decrement cpp->ifdepth here, because CPPif will increment
- * it and we really want to leave it alone */
- if (cpp->ifdepth){
- --cpp->ifdepth;
- --cpp->elsetracker;
- }
- return CPPif(yylvalpp);
- }
- }
- else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
- CPPErrorToInfoLog("#else after a #else");
- cpp->CompileError=1;
- return 0;
- }
- };
- return token;
-}
-
-enum eval_prec {
- MIN_PREC,
- COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
- MAX_PREC
-};
-
-static int op_logor(int a, int b) { return a || b; }
-static int op_logand(int a, int b) { return a && b; }
-static int op_or(int a, int b) { return a | b; }
-static int op_xor(int a, int b) { return a ^ b; }
-static int op_and(int a, int b) { return a & b; }
-static int op_eq(int a, int b) { return a == b; }
-static int op_ne(int a, int b) { return a != b; }
-static int op_ge(int a, int b) { return a >= b; }
-static int op_le(int a, int b) { return a <= b; }
-static int op_gt(int a, int b) { return a > b; }
-static int op_lt(int a, int b) { return a < b; }
-static int op_shl(int a, int b) { return a << b; }
-static int op_shr(int a, int b) { return a >> b; }
-static int op_add(int a, int b) { return a + b; }
-static int op_sub(int a, int b) { return a - b; }
-static int op_mul(int a, int b) { return a * b; }
-static int op_div(int a, int b) { return a / b; }
-static int op_mod(int a, int b) { return a % b; }
-static int op_pos(int a) { return a; }
-static int op_neg(int a) { return -a; }
-static int op_cmpl(int a) { return ~a; }
-static int op_not(int a) { return !a; }
-
-struct {
- int token, prec, (*op)(int, int);
-} binop[] = {
- { CPP_OR_OP, LOGOR, op_logor },
- { CPP_AND_OP, LOGAND, op_logand },
- { '|', OR, op_or },
- { '^', XOR, op_xor },
- { '&', AND, op_and },
- { CPP_EQ_OP, EQUAL, op_eq },
- { CPP_NE_OP, EQUAL, op_ne },
- { '>', RELATION, op_gt },
- { CPP_GE_OP, RELATION, op_ge },
- { '<', RELATION, op_lt },
- { CPP_LE_OP, RELATION, op_le },
- { CPP_LEFT_OP, SHIFT, op_shl },
- { CPP_RIGHT_OP, SHIFT, op_shr },
- { '+', ADD, op_add },
- { '-', ADD, op_sub },
- { '*', MUL, op_mul },
- { '/', MUL, op_div },
- { '%', MUL, op_mod },
-};
-
-struct {
- int token, (*op)(int);
-} unop[] = {
- { '+', op_pos },
- { '-', op_neg },
- { '~', op_cmpl },
- { '!', op_not },
-};
-
-#define ALEN(A) (sizeof(A)/sizeof(A[0]))
-
-static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
-{
- int i, val;
- Symbol *s;
- if (token == CPP_IDENTIFIER) {
- if (yylvalpp->sc_ident == definedAtom) {
- int needclose = 0;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(') {
- needclose = 1;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- if (token != CPP_IDENTIFIER)
- goto error;
- *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
- ? !s->details.mac.undef : 0;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (needclose) {
- if (token != ')')
- goto error;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- } else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- return eval(token, prec, res, err, yylvalpp);
- } else {
- goto error;
- }
- } else if (token == CPP_INTCONSTANT) {
- *res = yylvalpp->sc_int;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- } else if (token == '(') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, MIN_PREC, res, err, yylvalpp);
- if (!*err) {
- if (token != ')')
- goto error;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- } else {
- for (i = ALEN(unop) - 1; i >= 0; i--) {
- if (unop[i].token == token)
- break;
- }
- if (i >= 0) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, UNARY, res, err, yylvalpp);
- *res = unop[i].op(*res);
- } else {
- goto error;
- }
- }
- while (!*err) {
- if (token == ')' || token == '\n') break;
- for (i = ALEN(binop) - 1; i >= 0; i--) {
- if (binop[i].token == token)
- break;
- }
- if (i < 0 || binop[i].prec <= prec)
- break;
- val = *res;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- token = eval(token, binop[i].prec, res, err, yylvalpp);
-
- if (binop[i].op == op_div || binop[i].op == op_mod)
- {
- if (*res == 0)
- {
- CPPErrorToInfoLog("preprocessor divide or modulo by zero");
- *err = 1;
- return token;
- }
- }
-
- *res = binop[i].op(val, *res);
- }
- return token;
-error:
- CPPErrorToInfoLog("incorrect preprocessor directive");
- *err = 1;
- *res = 0;
- return token;
-} // eval
-
-static int CPPif(yystypepp * yylvalpp) {
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- int res = 0, err = 0;
-
- if (!cpp->ifdepth++)
- ifloc = *cpp->tokenLoc;
- if(cpp->ifdepth > MAX_IF_NESTING){
- CPPErrorToInfoLog("max #if nesting depth exceeded");
- cpp->CompileError = 1;
- return 0;
- }
- cpp->elsetracker++;
- // sanity check elsetracker
- if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
- CPPErrorToInfoLog("mismatched #if/#endif statements");
- cpp->CompileError = 1;
- return 0;
- }
- cpp->elsedepth[cpp->elsetracker] = 0;
-
- token = eval(token, MIN_PREC, &res, &err, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #if preprocessor directive - expected a newline");
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input in #if preprocessor directive - expected a newline");
- return 0;
- }
- }
- }
- if (!res && !err) {
- token = CPPelse(1, yylvalpp);
- }
-
- return token;
-} // CPPif
-
-static int CPPifdef(int defined, yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- int name = yylvalpp->sc_ident;
- if(++cpp->ifdepth > MAX_IF_NESTING){
- CPPErrorToInfoLog("max #if nesting depth exceeded");
- cpp->CompileError = 1;
- return 0;
- }
- cpp->elsetracker++;
- // sanity check elsetracker
- if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
- CPPErrorToInfoLog("mismatched #if/#endif statements");
- cpp->CompileError = 1;
- return 0;
- }
- cpp->elsedepth[cpp->elsetracker] = 0;
-
- if (token != CPP_IDENTIFIER) {
- defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
- } else {
- Symbol *s = LookUpSymbol(macros, name);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
- return 0;
- }
- }
- }
- if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
- token = CPPelse(1, yylvalpp);
- }
- return token;
-} // CPPifdef
-
-static int CPPline(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if(token=='\n'){
- DecLineNumber();
- CPPErrorToInfoLog("#line");
- IncLineNumber();
- return token;
- }
- else if (token == CPP_INTCONSTANT) {
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- SetLineNumber(yylvalpp->sc_int);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token == CPP_INTCONSTANT) {
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- SetStringNumber(yylvalpp->sc_int);
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if(token!='\n')
- CPPErrorToInfoLog("#line");
- }
- else if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#line");
- }
- }
- else{
- CPPErrorToInfoLog("#line");
- }
- return token;
-}
-
-static int CPPerror(yystypepp * yylvalpp) {
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- const char *message;
-
- while (token != '\n') {
- if (token <= 0){
- CPPErrorToInfoLog("unexpected end of input in #error preprocessor directive - expected a newline");
- return 0;
- }else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
- StoreStr(yylvalpp->symbol_name);
- }else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
- StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
- }else {
- StoreStr(GetStringOfAtom(atable,token));
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- DecLineNumber();
- //store this msg into the shader's information log..set the Compile Error flag!!!!
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- cpp->CompileError=1;
- IncLineNumber();
- return '\n';
-}//CPPerror
-
-static int CPPpragma(yystypepp * yylvalpp)
-{
- char SrcStrName[2];
- char** allTokens;
- int tokenCount = 0;
- int maxTokenCount = 10;
- const char* SrcStr;
- int i;
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token=='\n') {
- DecLineNumber();
- CPPErrorToInfoLog("#pragma");
- IncLineNumber();
- return token;
- }
-
- allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);
-
- while (token != '\n') {
- if (tokenCount >= maxTokenCount) {
- maxTokenCount *= 2;
- allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
- }
- switch (token) {
- case CPP_IDENTIFIER:
- SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case CPP_INTCONSTANT:
- SrcStr = yylvalpp->symbol_name;
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case CPP_FLOATCONSTANT:
- SrcStr = yylvalpp->symbol_name;
- allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
- strcpy(allTokens[tokenCount++], SrcStr);
- break;
- case -1:
- // EOF
- CPPShInfoLogMsg("#pragma directive must end with a newline");
- goto freeMemoryAndReturnToken;
- default:
- SrcStrName[0] = token;
- SrcStrName[1] = '\0';
- allTokens[tokenCount] = (char*)malloc(2);
- strcpy(allTokens[tokenCount++], SrcStrName);
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
-
- HandlePragma((const char**)allTokens, tokenCount);
-
-freeMemoryAndReturnToken:
- for (i = 0; i < tokenCount; ++i) {
- free (allTokens[i]);
- }
- free (allTokens);
-
- return token;
-} // CPPpragma
-
-#define ESSL_VERSION_NUMBER 100
-#define ESSL_VERSION_STRING "100"
-
-static int CPPversion(yystypepp * yylvalpp)
-{
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (cpp->pastFirstStatement == 1)
- CPPShInfoLogMsg("#version must occur before any other statement in the program");
-
- if(token=='\n'){
- DecLineNumber();
- CPPErrorToInfoLog("#version");
- IncLineNumber();
- return token;
- }
- if (token != CPP_INTCONSTANT)
- CPPErrorToInfoLog("#version");
-
- yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
- //SetVersionNumber(yylvalpp->sc_int);
-
- if (yylvalpp->sc_int != ESSL_VERSION_NUMBER)
- CPPShInfoLogMsg("Version number not supported by ESSL");
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-
- if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#version");
- }
- return token;
-} // CPPversion
-
-static int CPPextension(yystypepp * yylvalpp)
-{
-
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- char extensionName[MAX_SYMBOL_NAME_LEN + 1];
-
- if(token=='\n'){
- DecLineNumber();
- CPPShInfoLogMsg("extension name not specified");
- IncLineNumber();
- return token;
- }
-
- if (token != CPP_IDENTIFIER)
- CPPErrorToInfoLog("#extension");
-
- strncpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident), MAX_SYMBOL_NAME_LEN);
- extensionName[MAX_SYMBOL_NAME_LEN] = '\0';
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != ':') {
- CPPShInfoLogMsg("':' missing after extension name");
- return token;
- }
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != CPP_IDENTIFIER) {
- CPPShInfoLogMsg("behavior for extension not specified");
- return token;
- }
-
- updateExtensionBehavior(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
-
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '\n'){
- return token;
- }
- else{
- CPPErrorToInfoLog("#extension");
- }
- return token;
-} // CPPextension
-
-int readCPPline(yystypepp * yylvalpp)
-{
- int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- const char *message;
-
- if (token == CPP_IDENTIFIER) {
- if (yylvalpp->sc_ident == defineAtom) {
- token = CPPdefine(yylvalpp);
- } else if (yylvalpp->sc_ident == elseAtom) {
- if(ChkCorrectElseNesting()){
- if (!cpp->ifdepth ){
- CPPErrorToInfoLog("#else mismatch");
- cpp->CompileError=1;
- return 0;
- }
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpected end of input in #ifdef preprocessor directive - expected a newline");
- return 0;
- }
- }
- }
- token = CPPelse(0, yylvalpp);
- }else{
- CPPErrorToInfoLog("#else after a #else");
- cpp->ifdepth = 0;
- cpp->elsetracker = 0;
- cpp->pastFirstStatement = 1;
- cpp->CompileError = 1;
- return 0;
- }
- } else if (yylvalpp->sc_ident == elifAtom) {
- if (!cpp->ifdepth){
- CPPErrorToInfoLog("#elif mismatch");
- cpp->CompileError=1;
- return 0;
- }
- // this token is really a dont care, but we still need to eat the tokens
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- while (token != '\n') {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) { // EOF or error
- CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline");
- cpp->CompileError = 1;
- return 0;
- }
- }
- token = CPPelse(0, yylvalpp);
- } else if (yylvalpp->sc_ident == endifAtom) {
- if (!cpp->ifdepth){
- CPPErrorToInfoLog("#endif mismatch");
- cpp->CompileError=1;
- return 0;
- }
- else
- --cpp->ifdepth;
-
- if (cpp->elsetracker)
- --cpp->elsetracker;
-
- } else if (yylvalpp->sc_ident == ifAtom) {
- token = CPPif(yylvalpp);
- } else if (yylvalpp->sc_ident == ifdefAtom) {
- token = CPPifdef(1, yylvalpp);
- } else if (yylvalpp->sc_ident == ifndefAtom) {
- token = CPPifdef(0, yylvalpp);
- } else if (yylvalpp->sc_ident == lineAtom) {
- token = CPPline(yylvalpp);
- } else if (yylvalpp->sc_ident == pragmaAtom) {
- token = CPPpragma(yylvalpp);
- } else if (yylvalpp->sc_ident == undefAtom) {
- token = CPPundef(yylvalpp);
- } else if (yylvalpp->sc_ident == errorAtom) {
- token = CPPerror(yylvalpp);
- } else if (yylvalpp->sc_ident == versionAtom) {
- token = CPPversion(yylvalpp);
- } else if (yylvalpp->sc_ident == extensionAtom) {
- token = CPPextension(yylvalpp);
- } else {
- StoreStr("Invalid Directive");
- StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- }
- }
- while (token != '\n' && token != 0 && token != EOF) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
-
- cpp->pastFirstStatement = 1;
-
- return token;
-} // readCPPline
-
-void FreeMacro(MacroSymbol *s) {
- DeleteTokenStream(s->body);
-}
-
-void PredefineIntMacro(const char *name, int value) {
- SourceLoc location = {0, 0};
- Symbol *symbol = NULL;
- MacroSymbol macro = {0, NULL, NULL, 0, 0};
- yystypepp val = {0, 0.0, 0, {0}};
- int atom = 0;
-
- macro.body = NewTokenStream(name, macros->pool);
- val.sc_int = value;
- snprintf(val.symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", value);
- RecordToken(macro.body, CPP_INTCONSTANT, &val);
- atom = LookUpAddString(atable, name);
- symbol = AddSymbol(&location, macros, atom, MACRO_S);
- symbol->details.mac = macro;
-}
-
-static int eof_scan(InputSrc *in, yystypepp * yylvalpp) { return -1; }
-static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) { }
-
-static void PushEofSrc() {
- InputSrc *in = malloc(sizeof(InputSrc));
- memset(in, 0, sizeof(InputSrc));
- in->scan = eof_scan;
- in->getch = eof_scan;
- in->ungetch = noop;
- in->prev = cpp->currentInput;
- cpp->currentInput = in;
-}
-
-static void PopEofSrc() {
- if (cpp->currentInput->scan == eof_scan) {
- InputSrc *in = cpp->currentInput;
- cpp->currentInput = in->prev;
- free(in);
- }
-}
-
-static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
- int token;
- TokenStream *n;
- RewindTokenStream(a);
- do {
- token = ReadToken(a, yylvalpp);
- if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
- break;
- } while (token > 0);
- if (token <= 0) return a;
- n = NewTokenStream("macro arg", 0);
- PushEofSrc();
- ReadFromTokenStream(a, 0, 0);
- while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
- if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
- continue;
- RecordToken(n, token, yylvalpp);
- }
- PopEofSrc();
- DeleteTokenStream(a);
- return n;
-} // PrescanMacroArg
-
-typedef struct MacroInputSrc {
- InputSrc base;
- MacroSymbol *mac;
- TokenStream **args;
-} MacroInputSrc;
-
-/* macro_scan ---
-** return the next token for a macro expanion, handling macro args
-*/
-static int macro_scan(MacroInputSrc *in, yystypepp * yylvalpp) {
- int i;
- int token = ReadToken(in->mac->body, yylvalpp);
- if (token == CPP_IDENTIFIER) {
- for (i = in->mac->argc-1; i>=0; i--)
- if (in->mac->args[i] == yylvalpp->sc_ident) break;
- if (i >= 0) {
- ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0);
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- }
- }
- if (token > 0) return token;
- in->mac->busy = 0;
- cpp->currentInput = in->base.prev;
- if (in->args) {
- for (i=in->mac->argc-1; i>=0; i--)
- DeleteTokenStream(in->args[i]);
- free(in->args);
- }
- free(in);
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-} // macro_scan
-
-/* MacroExpand
-** check an identifier (atom) to see if it a macro that should be expanded.
-** If it is, push an InputSrc that will produce the appropriate expansion
-** and return TRUE. If not, return FALSE.
-*/
-
-int MacroExpand(int atom, yystypepp * yylvalpp)
-{
- Symbol *sym = LookUpSymbol(macros, atom);
- MacroInputSrc *in;
- int i,j, token, depth=0;
- const char *message;
- if (atom == __LINE__Atom) {
- yylvalpp->sc_int = GetLineNumber();
- snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (atom == __FILE__Atom) {
- yylvalpp->sc_int = GetStringNumber();
- snprintf(yylvalpp->symbol_name, MAX_SYMBOL_NAME_LEN+1, "%d", yylvalpp->sc_int);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (atom == __VERSION__Atom) {
- strcpy(yylvalpp->symbol_name,ESSL_VERSION_STRING);
- yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
- UngetToken(CPP_INTCONSTANT, yylvalpp);
- return 1;
- }
- if (!sym || sym->details.mac.undef) return 0;
- if (sym->details.mac.busy) return 0; // no recursive expansions
- in = malloc(sizeof(*in));
- memset(in, 0, sizeof(*in));
- in->base.scan = (void *)macro_scan;
- in->base.line = cpp->currentInput->line;
- in->base.name = cpp->currentInput->name;
- in->mac = &sym->details.mac;
- if (sym->details.mac.args) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token != '(') {
- UngetToken(token, yylvalpp);
- yylvalpp->sc_ident = atom;
- return 0;
- }
- in->args = malloc(in->mac->argc * sizeof(TokenStream *));
- for (i=0; i<in->mac->argc; i++)
- in->args[i] = NewTokenStream("macro arg", 0);
- i=0;j=0;
- do{
- depth = 0;
- while(1) {
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token <= 0) {
- StoreStr("EOF in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- return 1;
- }
- if((in->mac->argc==0) && (token!=')')) break;
- if (depth == 0 && (token == ',' || token == ')')) break;
- if (token == '(') depth++;
- if (token == ')') depth--;
- RecordToken(in->args[i], token, yylvalpp);
- j=1;
- }
- if (token == ')') {
- if((in->mac->argc==1) &&j==0)
- break;
- i++;
- break;
- }
- i++;
- }while(i < in->mac->argc);
-
- if (i < in->mac->argc) {
- StoreStr("Too few args in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- } else if (token != ')') {
- depth=0;
- while (token >= 0 && (depth > 0 || token != ')')) {
- if (token == ')') depth--;
- token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- if (token == '(') depth++;
- }
-
- if (token <= 0) {
- StoreStr("EOF in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- return 1;
- }
- StoreStr("Too many args in Macro ");
- StoreStr(GetStringOfAtom(atable,atom));
- message=GetStrfromTStr();
- CPPShInfoLogMsg(message);
- ResetTString();
- }
- for (i=0; i<in->mac->argc; i++) {
- in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
- }
- }
-#if 0
- printf(" <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
- loc.line, GetAtomString(atable, atom));
- for (i=0; i<in->mac->argc; i++) {
- printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
- DumpTokenStream(stdout, in->args[i]);
- printf("'\n");
- }
-#endif
- /*retain the input source*/
- in->base.prev = cpp->currentInput;
- sym->details.mac.busy = 1;
- RewindTokenStream(sym->details.mac.body);
- cpp->currentInput = &in->base;
- return 1;
-} // MacroExpand
-
-int ChkCorrectElseNesting(void)
-{
- // sanity check to make sure elsetracker is in a valid range
- if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) {
- return 0;
- }
-
- if (cpp->elsedepth[cpp->elsetracker] == 0) {
- cpp->elsedepth[cpp->elsetracker] = 1;
- return 1;
- }
- return 0;
-}
-
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/cpp.h b/src/3rdparty/angle/src/compiler/preprocessor/cpp.h
deleted file mode 100644
index 802e23ef07..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/cpp.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// cpp.h
-//
-
-#if !defined(__CPP_H)
-#define __CPP_H 1
-
-#include "compiler/preprocessor/parser.h"
-#include "compiler/preprocessor/tokens.h"
-
-int InitCPP(void);
-int FinalCPP(void);
-int readCPPline(yystypepp * yylvalpp);
-int MacroExpand(int atom, yystypepp * yylvalpp);
-int ChkCorrectElseNesting(void);
-
-typedef struct MacroSymbol {
- int argc;
- int *args;
- TokenStream *body;
- unsigned busy:1;
- unsigned undef:1;
-} MacroSymbol;
-
-void FreeMacro(MacroSymbol *);
-void PredefineIntMacro(const char *name, int value);
-
-void CPPDebugLogMsg(const char *msg); // Prints information into debug log
-void CPPShInfoLogMsg(const char*); // Store cpp Err Msg into Sh.Info.Log
-void CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
-void HandlePragma(const char**, int numTokens); // #pragma directive container.
-void ResetTString(void); // #error Message as TString.
-void CPPErrorToInfoLog(const char*); // Stick all cpp errors into Sh.Info.log.
-void StoreStr(const char*); // Store the TString in Parse Context.
-void SetLineNumber(int); // Set line number.
-void SetStringNumber(int); // Set string number.
-int GetLineNumber(void); // Get the current String Number.
-int GetStringNumber(void); // Get the current String Number.
-const char* GetStrfromTStr(void); // Convert TString to String.
-void updateExtensionBehavior(const char* extName, const char* behavior);
-int FreeCPP(void);
-
-#endif // !(defined(__CPP_H)
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/cppstruct.c b/src/3rdparty/angle/src/compiler/preprocessor/cppstruct.c
deleted file mode 100644
index 58cff31091..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/cppstruct.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// cppstruct.c
-//
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "compiler/preprocessor/slglobals.h"
-
-CPPStruct *cpp = NULL;
-static int refCount = 0;
-
-int InitPreprocessor(void);
-int ResetPreprocessor(void);
-int FreeCPPStruct(void);
-int FinalizePreprocessor(void);
-
-/*
- * InitCPPStruct() - Initilaize the CPP structure.
- *
- */
-
-int InitCPPStruct(void)
-{
- int len;
- char *p;
-
- cpp = (CPPStruct *) malloc(sizeof(CPPStruct));
- if (cpp == NULL)
- return 0;
-
- refCount++;
-
- // Initialize public members:
- cpp->pLastSourceLoc = &cpp->lastSourceLoc;
-
- p = (char *) &cpp->options;
- len = sizeof(cpp->options);
- while (--len >= 0)
- p[len] = 0;
-
- ResetPreprocessor();
- return 1;
-} // InitCPPStruct
-
-int ResetPreprocessor(void)
-{
- // Initialize private members:
-
- cpp->lastSourceLoc.file = 0;
- cpp->lastSourceLoc.line = 0;
- cpp->pC = 0;
- cpp->CompileError = 0;
- cpp->ifdepth = 0;
- for(cpp->elsetracker = 0; cpp->elsetracker < MAX_IF_NESTING; cpp->elsetracker++)
- cpp->elsedepth[cpp->elsetracker] = 0;
- cpp->elsetracker = 0;
- cpp->tokensBeforeEOF = 0;
- return 1;
-}
-
-//Intializing the Preprocessor.
-
-int InitPreprocessor(void)
-{
- # define CPP_STUFF true
- # ifdef CPP_STUFF
- FreeCPPStruct();
- InitCPPStruct();
- cpp->options.Quiet = 1;
- cpp->options.profileString = "generic";
- if (!InitAtomTable(atable, 0))
- return 1;
- if (!InitScanner(cpp))
- return 1;
- # endif
- return 0;
-}
-
-//FreeCPPStruct() - Free the CPP structure.
-
-int FreeCPPStruct(void)
-{
- if (refCount)
- {
- free(cpp);
- refCount--;
- }
-
- return 1;
-}
-
-//Finalizing the Preprocessor.
-
-int FinalizePreprocessor(void)
-{
- # define CPP_STUFF true
- # ifdef CPP_STUFF
- FreeAtomTable(atable);
- FreeCPPStruct();
- FreeScanner();
- # endif
- return 0;
-}
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////// End of cppstruct.c //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/memory.c b/src/3rdparty/angle/src/compiler/preprocessor/memory.c
deleted file mode 100644
index 029521a559..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/memory.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-
-#ifndef _MSC_VER
-#include <stdint.h>
-#endif
-
-#include "compiler/preprocessor/memory.h"
-
-#if defined(_MSC_VER)
-#pragma warning(disable: 4706)
-#endif
-
-// default alignment and chunksize, if called with 0 arguments
-#define CHUNKSIZE (64*1024)
-#define ALIGN 8
-
-// we need to call the `real' malloc and free, not our replacements
-#undef malloc
-#undef free
-
-struct chunk {
- struct chunk *next;
-};
-
-struct cleanup {
- struct cleanup *next;
- void (*fn)(void *);
- void *arg;
-};
-
-struct MemoryPool_rec {
- struct chunk *next;
- uintptr_t free, end;
- size_t chunksize;
- uintptr_t alignmask;
- struct cleanup *cleanup;
-};
-
-MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
-{
- MemoryPool *pool;
-
- if (align == 0) align = ALIGN;
- if (chunksize == 0) chunksize = CHUNKSIZE;
- if (align & (align-1)) return 0;
- if (chunksize < sizeof(MemoryPool)) return 0;
- if (chunksize & (align-1)) return 0;
- if (!(pool = malloc(chunksize))) return 0;
- pool->next = 0;
- pool->chunksize = chunksize;
- pool->alignmask = (uintptr_t)(align)-1;
- pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
- pool->end = (uintptr_t)pool + chunksize;
- pool->cleanup = 0;
- return pool;
-}
-
-void mem_FreePool(MemoryPool *pool)
-{
- struct cleanup *cleanup;
- struct chunk *p, *next;
-
- for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
- cleanup->fn(cleanup->arg);
- }
- for (p = (struct chunk *)pool; p; p = next) {
- next = p->next;
- free(p);
- }
-}
-
-void *mem_Alloc(MemoryPool *pool, size_t size)
-{
- struct chunk *ch;
- void *rv = (void *)pool->free;
- size = (size + pool->alignmask) & ~pool->alignmask;
- if (size <= 0) size = pool->alignmask;
- pool->free += size;
- if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
- size_t minreq = (size + sizeof(struct chunk) + pool->alignmask)
- & ~pool->alignmask;
- pool->free = (uintptr_t)rv;
- if (minreq >= pool->chunksize) {
- // request size is too big for the chunksize, so allocate it as
- // a single chunk of the right size
- ch = malloc(minreq);
- if (!ch) return 0;
- } else {
- ch = malloc(pool->chunksize);
- if (!ch) return 0;
- pool->free = (uintptr_t)ch + minreq;
- pool->end = (uintptr_t)ch + pool->chunksize;
- }
- ch->next = pool->next;
- pool->next = ch;
- rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
- }
- return rv;
-}
-
-int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
- struct cleanup *cleanup;
-
- pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
- cleanup = mem_Alloc(pool, sizeof(struct cleanup));
- if (!cleanup) return -1;
- cleanup->next = pool->cleanup;
- cleanup->fn = fn;
- cleanup->arg = arg;
- pool->cleanup = cleanup;
- return 0;
-}
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/memory.h b/src/3rdparty/angle/src/compiler/preprocessor/memory.h
deleted file mode 100644
index 5fcadb32f6..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/memory.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-#ifndef __MEMORY_H
-#define __MEMORY_H
-
-#include <stddef.h>
-
-typedef struct MemoryPool_rec MemoryPool;
-
-extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align);
-extern void mem_FreePool(MemoryPool *);
-extern void *mem_Alloc(MemoryPool *p, size_t size);
-extern void *mem_Realloc(MemoryPool *p, void *old, size_t oldsize, size_t newsize);
-extern int mem_AddCleanup(MemoryPool *p, void (*fn)(void *), void *arg);
-
-#endif /* __MEMORY_H */
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/numeric_lex.h b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h
index b04125d230..b04125d230 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/numeric_lex.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/numeric_lex.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/parser.h b/src/3rdparty/angle/src/compiler/preprocessor/parser.h
deleted file mode 100644
index f67342b670..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/parser.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-#ifndef BISON_PARSER_H
-# define BISON_PARSER_H
-
-#ifndef yystypepp
-typedef struct {
- int sc_int;
- float sc_fval;
- int sc_ident;
- char symbol_name[MAX_SYMBOL_NAME_LEN+1];
-} yystypepp;
-
-# define YYSTYPE_IS_TRIVIAL 1
-#endif
-# define CPP_AND_OP 257
-# define CPP_SUB_ASSIGN 259
-# define CPP_MOD_ASSIGN 260
-# define CPP_ADD_ASSIGN 261
-# define CPP_DIV_ASSIGN 262
-# define CPP_MUL_ASSIGN 263
-# define CPP_EQ_OP 264
-# define CPP_XOR_OP 265
-# define ERROR_SY 266
-# define CPP_FLOATCONSTANT 267
-# define CPP_GE_OP 268
-# define CPP_RIGHT_OP 269
-# define CPP_IDENTIFIER 270
-# define CPP_INTCONSTANT 271
-# define CPP_LE_OP 272
-# define CPP_LEFT_OP 273
-# define CPP_DEC_OP 274
-# define CPP_NE_OP 275
-# define CPP_OR_OP 276
-# define CPP_INC_OP 277
-# define CPP_STRCONSTANT 278
-# define CPP_TYPEIDENTIFIER 279
-
-# define FIRST_USER_TOKEN_SY 289
-
-# define CPP_RIGHT_ASSIGN 280
-# define CPP_LEFT_ASSIGN 281
-# define CPP_AND_ASSIGN 282
-# define CPP_OR_ASSIGN 283
-# define CPP_XOR_ASSIGN 284
-# define CPP_LEFT_BRACKET 285
-# define CPP_RIGHT_BRACKET 286
-# define CPP_LEFT_BRACE 287
-# define CPP_RIGHT_BRACE 288
-
-#endif /* not BISON_PARSER_H */
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/new/pp_utils.h b/src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h
index 17164ea8b0..17164ea8b0 100644
--- a/src/3rdparty/angle/src/compiler/preprocessor/new/pp_utils.h
+++ b/src/3rdparty/angle/src/compiler/preprocessor/pp_utils.h
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/preprocess.h b/src/3rdparty/angle/src/compiler/preprocessor/preprocess.h
deleted file mode 100644
index 15056da2c9..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/preprocess.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-
-#include "compiler/preprocessor/slglobals.h"
-extern CPPStruct *cpp;
-int InitCPPStruct(void);
-int InitScanner(CPPStruct *cpp);
-int InitAtomTable(AtomTable *atable, int htsize);
-char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/scanner.c b/src/3rdparty/angle/src/compiler/preprocessor/scanner.c
deleted file mode 100644
index fde853c1e0..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/scanner.c
+++ /dev/null
@@ -1,698 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// scanner.c
-//
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if 0
- #include <ieeefp.h>
-#else
- #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
- ((*(int *)&(x) & 0x007fffffL)==0000000000L))
-#endif
-
-#include "compiler/preprocessor/slglobals.h"
-#include "compiler/util.h"
-
-typedef struct StringInputSrc {
- InputSrc base;
- char *p;
-} StringInputSrc;
-
-static int ScanFromString(const char *s);
-
-static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
-{
- return EOF;
-} // eof_scan
-
-static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
-
-static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop, 0, 0 };
-
-static int byte_scan(InputSrc *, yystypepp * yylvalpp);
-
-#define EOL_SY '\n'
-
-#if defined(_MSC_VER)
- #define DBG_BREAKPOINT() __asm int 3
-#elif defined(_M_AMD64)
- #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
-#else
- #define DBG_BREAKPOINT()
-#endif
-
-#if defined(_MSC_VER) && !defined(_M_AMD64)
- __int64 RDTSC ( void ) {
-
- __int64 v;
-
- __asm __emit 0x0f
- __asm __emit 0x31
- __asm mov dword ptr v, eax
- __asm mov dword ptr v+4, edx
-
- return v;
- }
-#endif
-
-
-int InitScanner(CPPStruct *cpp)
-{
- // Add various atoms needed by the CPP line scanner:
- if (!InitCPP())
- return 0;
-
- cpp->mostRecentToken = 0;
- cpp->tokenLoc = &cpp->ltokenLoc;
-
- cpp->ltokenLoc.file = 0;
- cpp->ltokenLoc.line = 0;
-
- cpp->currentInput = &eof_inputsrc;
- cpp->previous_token = '\n';
- cpp->pastFirstStatement = 0;
-
- return 1;
-} // InitScanner
-
-int FreeScanner(void)
-{
- return (FreeCPP());
-}
-
-int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[])
-{
- cpp->PaWhichStr = 0;
- cpp->PaArgv = string;
- cpp->PaArgc = count;
- cpp->PaStrLen = length;
- ScanFromString(string[0]);
- return 0;
-}
-
-/*
- * str_getch()
- * takes care of reading from multiple strings.
- * returns the next-char from the input stream.
- * returns EOF when the complete shader is parsed.
- */
-static int str_getch(StringInputSrc *in)
-{
- for(;;){
- if (*in->p){
- if (*in->p == '\n') {
- in->base.line++;
- IncLineNumber();
- }
- return *in->p++;
- }
- if(++(cpp->PaWhichStr) < cpp->PaArgc){
- free(in);
- SetStringNumber(cpp->PaWhichStr);
- SetLineNumber(1);
- ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
- in=(StringInputSrc*)cpp->currentInput;
- continue;
- }
- else{
- cpp->currentInput = in->base.prev;
- cpp->PaWhichStr=0;
- free(in);
- return EOF;
- }
- }
-} // str_getch
-
-static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
- if (in->p[-1] == ch)in->p--;
- else {
- *(in->p)='\0'; //this would take care of shifting to the previous string.
- cpp->PaWhichStr--;
- }
- if (ch == '\n') {
- in->base.line--;
- DecLineNumber();
- }
-} // str_ungetch
-
-int ScanFromString(const char *s)
-{
-
- StringInputSrc *in = malloc(sizeof(StringInputSrc));
- memset(in, 0, sizeof(StringInputSrc));
- in->p = (char*) s;
- in->base.line = 1;
- in->base.scan = byte_scan;
- in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
- in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
- in->base.prev = cpp->currentInput;
- cpp->currentInput = &in->base;
-
- return 1;
-} // ScanFromString;
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////// Floating point constants: /////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-#define APPEND_CHAR_S(ch, str, len, max_len) \
- if (len < max_len) { \
- str[len++] = ch; \
- } else if (!alreadyComplained) { \
- CPPErrorToInfoLog("BUFFER OVERFLOW"); \
- alreadyComplained = 1; \
- }
-
-/*
- * lFloatConst() - Scan a floating point constant. Assumes that the scanner
- * has seen at least one digit, followed by either a decimal '.' or the
- * letter 'e'.
- * ch - '.' or 'e'
- * len - length of string already copied into yylvalpp->symbol_name.
- */
-
-static int lFloatConst(int ch, int len, yystypepp * yylvalpp)
-{
- int alreadyComplained = 0;
- assert((ch == '.') || (ch == 'e') || (ch == 'E'));
-
- if (ch == '.') {
- do {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch >= '0' && ch <= '9');
- }
-
- // Exponent:
- if (ch == 'e' || ch == 'E') {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '+') {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else if (ch == '-') {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- if (ch >= '0' && ch <= '9') {
- while (ch >= '0' && ch <= '9') {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- } else {
- CPPErrorToInfoLog("EXPONENT INVALID");
- }
- }
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
-
- assert(len <= MAX_SYMBOL_NAME_LEN);
- yylvalpp->symbol_name[len] = '\0';
- yylvalpp->sc_fval = (float) atof_dot(yylvalpp->symbol_name);
- if (isinff(yylvalpp->sc_fval)) {
- CPPErrorToInfoLog("FLOAT CONSTANT OVERFLOW");
- }
- return CPP_FLOATCONSTANT;
-} // lFloatConst
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////// Normal Scanner //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
-{
- char string_val[MAX_STRING_LEN + 1];
- int alreadyComplained = 0;
- int len, ch, ii, ival = 0;
-
- for (;;) {
- yylvalpp->sc_int = 0;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
-
- while (ch == ' ' || ch == '\t' || ch == '\r') {
- yylvalpp->sc_int = 1;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
-
- cpp->ltokenLoc.file = cpp->currentInput->name;
- cpp->ltokenLoc.line = cpp->currentInput->line;
- alreadyComplained = 0;
- len = 0;
- switch (ch) {
- default:
- return ch; // Single character token
- case EOF:
- return -1;
- case 'A': case 'B': case 'C': case 'D': case 'E':
- case 'F': case 'G': case 'H': case 'I': case 'J':
- case 'K': case 'L': case 'M': case 'N': case 'O':
- case 'P': case 'Q': case 'R': case 'S': case 'T':
- case 'U': case 'V': case 'W': case 'X': case 'Y':
- case 'Z': case '_':
- case 'a': case 'b': case 'c': case 'd': case 'e':
- case 'f': case 'g': case 'h': case 'i': case 'j':
- case 'k': case 'l': case 'm': case 'n': case 'o':
- case 'p': case 'q': case 'r': case 's': case 't':
- case 'u': case 'v': case 'w': case 'x': case 'y':
- case 'z':
- do {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '_');
- assert(len <= MAX_SYMBOL_NAME_LEN);
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_ident = LookUpAddString(atable, yylvalpp->symbol_name);
- return CPP_IDENTIFIER;
- break;
- case '0':
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == 'x' || ch == 'X') { // hexadecimal integer constants
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if ((ch >= '0' && ch <= '9') ||
- (ch >= 'A' && ch <= 'F') ||
- (ch >= 'a' && ch <= 'f'))
- {
- ival = 0;
- do {
- if ((ival <= 0x0fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
- yylvalpp->symbol_name[len++] = ch;
- if (ch >= '0' && ch <= '9') {
- ii = ch - '0';
- } else if (ch >= 'A' && ch <= 'F') {
- ii = ch - 'A' + 10;
- } else {
- ii = ch - 'a' + 10;
- }
- ival = (ival << 4) | ii;
- } else if (!alreadyComplained) {
- CPPErrorToInfoLog("HEX CONSTANT OVERFLOW");
- alreadyComplained = 1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while ((ch >= '0' && ch <= '9') ||
- (ch >= 'A' && ch <= 'F') ||
- (ch >= 'a' && ch <= 'f'));
- } else {
- CPPErrorToInfoLog("HEX CONSTANT INVALID");
- }
- assert(len <= MAX_SYMBOL_NAME_LEN);
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_int = ival;
- return CPP_INTCONSTANT;
- } else if (ch >= '0' && ch <= '7') { // octal integer constants
- ival = 0;
- do {
- if ((ival <= 0x1fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
- yylvalpp->symbol_name[len++] = ch;
- ii = ch - '0';
- ival = (ival << 3) | ii;
- } else if (!alreadyComplained) {
- CPPErrorToInfoLog("OCT CONSTANT OVERFLOW");
- alreadyComplained = 1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch >= '0' && ch <= '7');
- if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E')
- return lFloatConst(ch, len, yylvalpp);
- assert(len <= MAX_SYMBOL_NAME_LEN);
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_int = ival;
- return CPP_INTCONSTANT;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- ch = '0';
- }
- // Fall through...
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- do {
- APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch >= '0' && ch <= '9');
- if (ch == '.' || ch == 'e' || ch == 'E') {
- return lFloatConst(ch, len, yylvalpp);
- } else {
- assert(len <= MAX_SYMBOL_NAME_LEN);
- yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- ival = 0;
- for (ii = 0; ii < len; ii++) {
- ch = yylvalpp->symbol_name[ii] - '0';
- ival = ival*10 + ch;
- if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
- CPPErrorToInfoLog("INTEGER CONSTANT OVERFLOW");
- break;
- }
- }
- yylvalpp->sc_int = ival;
- if(ival==0)
- strcpy(yylvalpp->symbol_name,"0");
- return CPP_INTCONSTANT;
- }
- break;
- case '-':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '-') {
- return CPP_DEC_OP;
- } else if (ch == '=') {
- return CPP_SUB_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '-';
- }
- case '+':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '+') {
- return CPP_INC_OP;
- } else if (ch == '=') {
- return CPP_ADD_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '+';
- }
- case '*':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_MUL_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '*';
- }
- case '%':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_MOD_ASSIGN;
- } else if (ch == '>'){
- return CPP_RIGHT_BRACE;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '%';
- }
- case ':':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '>') {
- return CPP_RIGHT_BRACKET;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return ':';
- }
- case '^':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '^') {
- return CPP_XOR_OP;
- } else {
- if (ch == '=')
- return CPP_XOR_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '^';
- }
- }
-
- case '=':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_EQ_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '=';
- }
- case '!':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '=') {
- return CPP_NE_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '!';
- }
- case '|':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '|') {
- return CPP_OR_OP;
- } else {
- if (ch == '=')
- return CPP_OR_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '|';
- }
- }
- case '&':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '&') {
- return CPP_AND_OP;
- } else {
- if (ch == '=')
- return CPP_AND_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '&';
- }
- }
- case '<':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '<') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if(ch == '=')
- return CPP_LEFT_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return CPP_LEFT_OP;
- }
- } else {
- if (ch == '=') {
- return CPP_LE_OP;
- } else {
- if (ch == '%')
- return CPP_LEFT_BRACE;
- else if (ch == ':')
- return CPP_LEFT_BRACKET;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '<';
- }
- }
- }
- case '>':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '>') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if(ch == '=')
- return CPP_RIGHT_ASSIGN;
- else{
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return CPP_RIGHT_OP;
- }
- } else {
- if (ch == '=') {
- return CPP_GE_OP;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '>';
- }
- }
- case '.':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch >= '0' && ch <= '9') {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return lFloatConst('.', 0, yylvalpp);
- } else {
- if (ch == '.') {
- return -1; // Special EOF hack
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '.';
- }
- }
- case '/':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == '/') {
- do {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } while (ch != '\n' && ch != EOF);
- if (ch == EOF)
- return -1;
- return '\n';
- } else if (ch == '*') {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- do {
- while (ch != '*') {
- if (ch == EOF) {
- CPPErrorToInfoLog("EOF IN COMMENT");
- return -1;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == EOF) {
- CPPErrorToInfoLog("EOF IN COMMENT");
- return -1;
- }
- } while (ch != '/');
- // Go try it again...
- } else if (ch == '=') {
- return CPP_DIV_ASSIGN;
- } else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return '/';
- }
- break;
- case '"':
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- while (ch != '"' && ch != '\n' && ch != EOF) {
- if (ch == '\\') {
- CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
- return -1;
- }
- APPEND_CHAR_S(ch, string_val, len, MAX_STRING_LEN);
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- };
- assert(len <= MAX_STRING_LEN);
- string_val[len] = '\0';
- if (ch == '"') {
- yylvalpp->sc_ident = LookUpAddString(atable, string_val);
- return CPP_STRCONSTANT;
- } else {
- CPPErrorToInfoLog("EOL IN STRING");
- return ERROR_SY;
- }
- break;
- }
- }
-} // byte_scan
-
-int yylex_CPP(char* buf, int maxSize)
-{
- yystypepp yylvalpp;
- int token = '\n';
-
- for(;;) {
-
- char* tokenString = 0;
- token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
- if(check_EOF(token))
- return 0;
- if (token < 0) {
- // This check may need to be improved to support UTF-8
- // characters in comments.
- CPPErrorToInfoLog("preprocessor encountered non-ASCII character in shader source");
- return 0;
- }
- if (token == '#') {
- if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
- token = readCPPline(&yylvalpp);
- if(check_EOF(token))
- return 0;
- continue;
- } else {
- CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
- return 0;
- }
- }
- cpp->previous_token = token;
- // expand macros
- if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
- cpp->pastFirstStatement = 1;
- continue;
- }
-
- if (token == '\n')
- continue;
- cpp->pastFirstStatement = 1;
-
- if (token == CPP_IDENTIFIER) {
- tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
- } else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
- tokenString = yylvalpp.symbol_name;
- } else {
- tokenString = GetStringOfAtom(atable,token);
- }
-
- if (tokenString) {
- int len = strlen(tokenString);
- cpp->tokensBeforeEOF = 1;
- if (len >= maxSize) {
- return maxSize;
- } else if (len > 0) {
- strcpy(buf, tokenString);
- return len;
- }
-
- return 0;
- }
- }
-} // yylex
-
-//Checks if the token just read is EOF or not.
-int check_EOF(int token)
-{
- if(token==-1){
- if(cpp->ifdepth >0){
- CPPErrorToInfoLog("#endif missing!! Compilation stopped");
- cpp->CompileError=1;
- }
- return 1;
- }
- return 0;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////// End of scanner.c //////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/scanner.h b/src/3rdparty/angle/src/compiler/preprocessor/scanner.h
deleted file mode 100644
index b67c1d644e..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/scanner.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// scanner.h
-//
-
-#if !defined(__SCANNER_H)
-#define __SCANNER_H 1
-
-#include "compiler/preprocessor/length_limits.h"
-#include "compiler/preprocessor/parser.h"
-
-// Not really atom table stuff but needed first...
-
-typedef struct SourceLoc_Rec {
- unsigned short file, line;
-} SourceLoc;
-
-int yylex_CPP(char* buf, int maxSize);
-
-typedef struct InputSrc {
- struct InputSrc *prev;
- int (*scan)(struct InputSrc *, yystypepp *);
- int (*getch)(struct InputSrc *, yystypepp *);
- void (*ungetch)(struct InputSrc *, int, yystypepp *);
- int name; /* atom */
- int line;
-} InputSrc;
-
-int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
-int InitScannerInput(CPPStruct *cpp, int count, const char* const string[], const int length[]);
-int check_EOF(int); // check if we hit a EOF abruptly
-void CPPErrorToInfoLog(const char *); // sticking the msg,line into the Shader's.Info.log
-void SetLineNumber(int);
-void SetStringNumber(int);
-void IncLineNumber(void);
-void DecLineNumber(void);
-int FreeScanner(void); // Free the cpp scanner
-#endif // !(defined(__SCANNER_H)
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/slglobals.h b/src/3rdparty/angle/src/compiler/preprocessor/slglobals.h
deleted file mode 100644
index 4634626643..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/slglobals.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// slglobals.h
-//
-
-#if !defined(__SLGLOBALS_H)
-#define __SLGLOBALS_H 1
-
-typedef struct CPPStruct_Rec CPPStruct;
-
-extern CPPStruct *cpp;
-
-#undef CPPC_DEBUG_THE_COMPILER
-#if defined(_DEBUG)
-#define CPPC_DEBUG_THE_COMPILER 1
-#endif
-
-#undef CPPC_ENABLE_TOOLS
-#define CPPC_ENABLE_TOOLS 1
-
-#include "compiler/preprocessor/memory.h"
-#include "compiler/preprocessor/atom.h"
-#include "compiler/preprocessor/scanner.h"
-#include "compiler/preprocessor/cpp.h"
-#include "compiler/preprocessor/tokens.h"
-#include "compiler/preprocessor/symbols.h"
-#include "compiler/preprocessor/compile.h"
-#if !defined(NO_PARSER)
-#include "compiler/preprocessor/parser.h"
-#endif
-
-#if !defined(NULL)
-#define NULL 0
-#endif
-
-#endif // !(defined(__SLGLOBALS_H)
-
-
-
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/symbols.c b/src/3rdparty/angle/src/compiler/preprocessor/symbols.c
deleted file mode 100644
index f18b2569b3..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/symbols.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// symbols.c
-//
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "compiler/preprocessor/slglobals.h"
-
-#if defined(_MSC_VER)
-#pragma warning(disable: 4706)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-Scope *ScopeList = NULL;
-Scope *CurrentScope = NULL;
-Scope *GlobalScope = NULL;
-
-static void unlinkScope(void *_scope) {
- Scope *scope = _scope;
-
- if (scope->next)
- scope->next->prev = scope->prev;
- if (scope->prev)
- scope->prev->next = scope->next;
- else
- ScopeList = scope->next;
-}
-
-/*
- * NewScope()
- *
- */
-Scope *NewScopeInPool(MemoryPool *pool)
-{
- Scope *lScope;
-
- lScope = mem_Alloc(pool, sizeof(Scope));
- lScope->pool = pool;
- lScope->parent = NULL;
- lScope->funScope = NULL;
- lScope->symbols = NULL;
-
- lScope->level = 0;
-
- lScope->programs = NULL;
- if ((lScope->next = ScopeList))
- ScopeList->prev = lScope;
- lScope->prev = 0;
- ScopeList = lScope;
- mem_AddCleanup(pool, unlinkScope, lScope);
- return lScope;
-} // NewScope
-
-/*
- * PushScope()
- *
- */
-
-void PushScope(Scope *fScope)
-{
- Scope *lScope;
-
- if (CurrentScope) {
- fScope->level = CurrentScope->level + 1;
- if (fScope->level == 1) {
- if (!GlobalScope) {
- /* HACK - CTD -- if GlobalScope==NULL and level==1, we're
- * defining a function in the superglobal scope. Things
- * will break if we leave the level as 1, so we arbitrarily
- * set it to 2 */
- fScope->level = 2;
- }
- }
- if (fScope->level >= 2) {
- lScope = fScope;
- while (lScope->level > 2)
- lScope = lScope->next;
- fScope->funScope = lScope;
- }
- } else {
- fScope->level = 0;
- }
- fScope->parent = CurrentScope;
- CurrentScope = fScope;
-} // PushScope
-
-/*
- * PopScope()
- *
- */
-
-Scope *PopScope(void)
-{
- Scope *lScope;
-
- lScope = CurrentScope;
- if (CurrentScope)
- CurrentScope = CurrentScope->parent;
- return lScope;
-} // PopScope
-
-/*
- * NewSymbol() - Allocate a new symbol node;
- *
- */
-
-Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
-{
- Symbol *lSymb;
- char *pch;
- unsigned int ii;
-
- lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
- lSymb->left = NULL;
- lSymb->right = NULL;
- lSymb->next = NULL;
- lSymb->name = name;
- lSymb->loc = *loc;
- lSymb->kind = kind;
-
- // Clear union area:
-
- pch = (char *) &lSymb->details;
- for (ii = 0; ii < sizeof(lSymb->details); ii++)
- *pch++ = 0;
- return lSymb;
-} // NewSymbol
-
-/*
- * lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
- * are generated in order. We'll fix this later (by reversing the bit pattern).
- */
-
-static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
-{
- Symbol *lSymb;
- int lrev, frev;
-
- lSymb = *fSymbols;
- if (lSymb) {
- frev = GetReversedAtom(atable, fSymb->name);
- while (lSymb) {
- lrev = GetReversedAtom(atable, lSymb->name);
- if (lrev == frev) {
- CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)");
- break;
- } else {
- if (lrev > frev) {
- if (lSymb->left) {
- lSymb = lSymb->left;
- } else {
- lSymb->left = fSymb;
- break;
- }
- } else {
- if (lSymb->right) {
- lSymb = lSymb->right;
- } else {
- lSymb->right = fSymb;
- break;
- }
- }
- }
- }
- } else {
- *fSymbols = fSymb;
- }
-} // lAddToTree
-
-
-/*
- * AddSymbol() - Add a variable, type, or function name to a scope.
- *
- */
-
-Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
-{
- Symbol *lSymb;
-
- if (!fScope)
- fScope = CurrentScope;
- lSymb = NewSymbol(loc, fScope, atom, kind);
- lAddToTree(&fScope->symbols, lSymb);
- return lSymb;
-} // AddSymbol
-
-
-/*********************************************************************************************/
-/************************************ Symbol Semantic Functions ******************************/
-/*********************************************************************************************/
-
-/*
- * LookUpLocalSymbol()
- *
- */
-
-Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
-{
- Symbol *lSymb;
- int rname, ratom;
-
- ratom = GetReversedAtom(atable, atom);
- if (!fScope)
- fScope = CurrentScope;
- lSymb = fScope->symbols;
- while (lSymb) {
- rname = GetReversedAtom(atable, lSymb->name);
- if (rname == ratom) {
- return lSymb;
- } else {
- if (rname > ratom) {
- lSymb = lSymb->left;
- } else {
- lSymb = lSymb->right;
- }
- }
- }
- return NULL;
-} // LookUpLocalSymbol
-
-/*
- * LookUpSymbol()
- *
- */
-
-Symbol *LookUpSymbol(Scope *fScope, int atom)
-{
- Symbol *lSymb;
-
- if (!fScope)
- fScope = CurrentScope;
- while (fScope) {
- lSymb = LookUpLocalSymbol(fScope, atom);
- if (lSymb)
- return lSymb;
- fScope = fScope->parent;
- }
- return NULL;
-} // LookUpSymbol
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/symbols.h b/src/3rdparty/angle/src/compiler/preprocessor/symbols.h
deleted file mode 100644
index e7d0b075fa..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/symbols.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// symbols.h
-//
-
-#if !defined(__SYMBOLS_H)
-#define __SYMBOLS_H 1
-
-#include "compiler/preprocessor/memory.h"
-
-typedef enum symbolkind {
- MACRO_S
-} symbolkind;
-
-// Typedefs for things defined here in "symbols.h":
-
-typedef struct Scope_Rec Scope;
-typedef struct Symbol_Rec Symbol;
-
-typedef struct SymbolList_Rec {
- struct SymbolList_Rec *next;
- Symbol *symb;
-} SymbolList;
-
-struct Scope_Rec {
- Scope *next, *prev; // doubly-linked list of all scopes
- Scope *parent;
- Scope *funScope; // Points to base scope of enclosing function
- MemoryPool *pool; // pool used for allocation in this scope
- Symbol *symbols;
-
- int level; // 0 = super globals, 1 = globals, etc.
-
- // Only used at global scope (level 1):
- SymbolList *programs; // List of programs for this compilation.
-};
-
-
-// Symbol table is a simple binary tree.
-
-#include "compiler/preprocessor/cpp.h" // to get MacroSymbol def
-
-struct Symbol_Rec {
- Symbol *left, *right;
- Symbol *next;
- int name; // Name atom
- SourceLoc loc;
- symbolkind kind;
- union {
- MacroSymbol mac;
- } details;
-};
-
-extern Scope *CurrentScope;
-extern Scope *GlobalScope;
-extern Scope *ScopeList;
-
-Scope *NewScopeInPool(MemoryPool *);
-#define NewScope() NewScopeInPool(CurrentScope->pool)
-void PushScope(Scope *fScope);
-Scope *PopScope(void);
-Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
-Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
-Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
-Symbol *LookUpSymbol(Scope *fScope, int atom);
-
-
-#endif // !defined(__SYMBOLS_H)
-
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/tokens.c b/src/3rdparty/angle/src/compiler/preprocessor/tokens.c
deleted file mode 100644
index b94c05ebd4..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/tokens.c
+++ /dev/null
@@ -1,467 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// tokens.c
-//
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "common/angleutils.h"
-#include "compiler/debug.h"
-#include "compiler/preprocessor/slglobals.h"
-#include "compiler/util.h"
-
-#if defined(_MSC_VER)
-#pragma warning(disable: 4054)
-#pragma warning(disable: 4152)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
-
-/*
- * idstr()
- * Copy a string to a malloc'ed block and convert it into something suitable
- * for an ID
- *
- */
-
-static char *idstr(const char *fstr, MemoryPool *pool)
-{
- size_t len;
- char *str, *t;
- const char *f;
-
- len = strlen(fstr);
- if (!pool)
- str = (char *) malloc(len + 1);
- else
- str = (char *) mem_Alloc(pool, len + 1);
-
- for (f=fstr, t=str; *f; f++) {
- if (isalnum(*f)) *t++ = *f;
- else if (*f == '.' || *f == '/') *t++ = '_';
- }
- *t = 0;
- return str;
-} // idstr
-
-
-/*
- * lNewBlock()
- *
- */
-
-static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
-{
- TokenBlock *lBlock;
-
- if (!pool)
- lBlock = (TokenBlock *) malloc(sizeof(TokenBlock) + 256);
- else
- lBlock = (TokenBlock *) mem_Alloc(pool, sizeof(TokenBlock) + 256);
- lBlock->count = 0;
- lBlock->current = 0;
- lBlock->data = (unsigned char *) lBlock + sizeof(TokenBlock);
- lBlock->max = 256;
- lBlock->next = NULL;
- if (fTok->head) {
- fTok->current->next = lBlock;
- } else {
- fTok->head = lBlock;
- }
- fTok->current = lBlock;
- return lBlock;
-} // lNewBlock
-
-/*
- * lAddByte()
- *
- */
-
-static void lAddByte(TokenStream *fTok, unsigned char fVal)
-{
- TokenBlock *lBlock;
- lBlock = fTok->current;
- if (lBlock->count >= lBlock->max)
- lBlock = lNewBlock(fTok, 0);
- lBlock->data[lBlock->count++] = fVal;
-} // lAddByte
-
-
-
-/*
- * lReadByte() - Get the next byte from a stream.
- *
- */
-
-static int lReadByte(TokenStream *pTok)
-{
- TokenBlock *lBlock;
- int lval = -1;
-
- lBlock = pTok->current;
- if (lBlock) {
- if (lBlock->current >= lBlock->count) {
- lBlock = lBlock->next;
- if (lBlock)
- lBlock->current = 0;
- pTok->current = lBlock;
- }
- if (lBlock)
- lval = lBlock->data[lBlock->current++];
- }
- return lval;
-} // lReadByte
-
-/////////////////////////////////////// Global Functions://////////////////////////////////////
-
-/*
- * NewTokenStream()
- *
- */
-
-TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
-{
- TokenStream *pTok;
-
- if (!pool)
- pTok = (TokenStream *) malloc(sizeof(TokenStream));
- else
- pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
- pTok->next = NULL;
- pTok->name = idstr(name, pool);
- pTok->head = NULL;
- pTok->current = NULL;
- lNewBlock(pTok, pool);
- return pTok;
-} // NewTokenStream
-
-/*
- * DeleteTokenStream()
- *
- */
-
-void DeleteTokenStream(TokenStream *pTok)
-{
- TokenBlock *pBlock, *nBlock;
-
- if (pTok) {
- pBlock = pTok->head;
- while (pBlock) {
- nBlock = pBlock->next;
- free(pBlock);
- pBlock = nBlock;
- }
- if (pTok->name)
- free(pTok->name);
- free(pTok);
- }
-} // DeleteTokenStream
-
-/*
- * RecordToken() - Add a token to the end of a list for later playback or printout.
- *
- */
-
-void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
-{
- const char *s;
- char *str=NULL;
-
- if (token > 256)
- lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
- else
- lAddByte(pTok, (unsigned char)(token & 0x7f));
- switch (token) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- case CPP_STRCONSTANT:
- s = GetAtomString(atable, yylvalpp->sc_ident);
- while (*s)
- lAddByte(pTok, (unsigned char) *s++);
- lAddByte(pTok, 0);
- break;
- case CPP_FLOATCONSTANT:
- case CPP_INTCONSTANT:
- str=yylvalpp->symbol_name;
- while (*str){
- lAddByte(pTok, (unsigned char) *str++);
- }
- lAddByte(pTok, 0);
- break;
- case '(':
- lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
- default:
- break;
- }
-} // RecordToken
-
-/*
- * RewindTokenStream() - Reset a token stream in preperation for reading.
- *
- */
-
-void RewindTokenStream(TokenStream *pTok)
-{
- if (pTok->head) {
- pTok->current = pTok->head;
- pTok->current->current = 0;
- }
-} // RewindTokenStream
-
-/*
- * ReadToken() - Read the next token from a stream.
- *
- */
-
-int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
-{
- char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
- char string_val[MAX_STRING_LEN + 1];
- int ltoken, len;
- char ch;
- int base, accum;
- char ch_val;
-
- ltoken = lReadByte(pTok);
- if (ltoken >= 0) {
- if (ltoken > 127)
- ltoken += 128;
- switch (ltoken) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- len = 0;
- ch = lReadByte(pTok);
- while ((ch >= 'a' && ch <= 'z') ||
- (ch >= 'A' && ch <= 'Z') ||
- (ch >= '0' && ch <= '9') ||
- ch == '_')
- {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len++] = ch;
- ch = lReadByte(pTok);
- }
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
- return CPP_IDENTIFIER;
- break;
- case CPP_STRCONSTANT:
- len = 0;
- while ((ch = lReadByte(pTok)) != 0)
- if (len < MAX_STRING_LEN)
- string_val[len++] = ch;
- string_val[len] = '\0';
- yylvalpp->sc_ident = LookUpAddString(atable, string_val);
- break;
- case CPP_FLOATCONSTANT:
- len = 0;
- ch = lReadByte(pTok);
- while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
- {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len++] = ch;
- ch = lReadByte(pTok);
- }
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- strcpy(yylvalpp->symbol_name,symbol_name);
- yylvalpp->sc_fval=(float)atof_dot(yylvalpp->symbol_name);
- break;
- case CPP_INTCONSTANT:
- len = 0;
- accum = 0;
- ch = lReadByte(pTok);
- if (ch == '0') {
- symbol_name[len++] = ch;
- ch = lReadByte(pTok);
- if (ch == 'x' || ch == 'X') {
- symbol_name[len++] = ch;
- base = 16;
- ch = lReadByte(pTok);
- } else {
- base = 8;
- }
- } else {
- base = 10;
- }
-
- while (len < MAX_SYMBOL_NAME_LEN)
- {
- ch_val = -1;
- if (isdigit(ch))
- ch_val = ch - '0';
- else if (isxdigit(ch))
- ch_val = tolower(ch) - 'a' + 10;
-
- if (ch_val < 0 || ch_val >= base)
- break;
-
- symbol_name[len++] = ch;
- accum = accum * base + ch_val;
- ch = lReadByte(pTok);
- }
- symbol_name[len] = '\0';
- assert(ch == '\0');
- strcpy(yylvalpp->symbol_name, symbol_name);
- yylvalpp->sc_int = accum;
- break;
- case '(':
- yylvalpp->sc_int = lReadByte(pTok);
- break;
- }
- return ltoken;
- }
- return EOF_SY;
-} // ReadToken
-
-typedef struct TokenInputSrc {
- InputSrc base;
- TokenStream *tokens;
- int (*final)(CPPStruct *);
-} TokenInputSrc;
-
-static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
-{
- int token = ReadToken(in->tokens, yylvalpp);
- int (*final)(CPPStruct *);
- cpp->tokenLoc->file = cpp->currentInput->name;
- cpp->tokenLoc->line = cpp->currentInput->line;
- if (token == '\n') {
- in->base.line++;
- return token;
- }
- if (token > 0) return token;
- cpp->currentInput = in->base.prev;
- final = in->final;
- free(in);
- if (final && !final(cpp)) return -1;
- return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
-}
-
-int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
-{
- TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
- memset(in, 0, sizeof(TokenInputSrc));
- in->base.name = name;
- in->base.prev = cpp->currentInput;
- in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
- in->base.line = 1;
- in->tokens = ts;
- in->final = final;
- RewindTokenStream(ts);
- cpp->currentInput = &in->base;
- return 1;
-}
-
-typedef struct UngotToken {
- InputSrc base;
- int token;
- yystypepp lval;
-} UngotToken;
-
-static int reget_token(UngotToken *t, yystypepp * yylvalpp)
-{
- int token = t->token;
- *yylvalpp = t->lval;
- cpp->currentInput = t->base.prev;
- free(t);
- return token;
-}
-
-void UngetToken(int token, yystypepp * yylvalpp) {
- UngotToken *t = malloc(sizeof(UngotToken));
- memset(t, 0, sizeof(UngotToken));
- t->token = token;
- t->lval = *yylvalpp;
- t->base.scan = (void *)reget_token;
- t->base.prev = cpp->currentInput;
- t->base.name = cpp->currentInput->name;
- t->base.line = cpp->currentInput->line;
- cpp->currentInput = &t->base;
-}
-
-
-void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
- int token;
- char str[100];
-
- if (fp == 0) fp = stdout;
- RewindTokenStream(s);
- while ((token = ReadToken(s, yylvalpp)) > 0) {
- switch (token) {
- case CPP_IDENTIFIER:
- case CPP_TYPEIDENTIFIER:
- snprintf(str, sizeof(str), "%s ", GetAtomString(atable, yylvalpp->sc_ident));
- break;
- case CPP_STRCONSTANT:
- snprintf(str, sizeof(str), "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
- break;
- case CPP_FLOATCONSTANT:
- //printf("%g9.6 ", yylvalpp->sc_fval);
- break;
- case CPP_INTCONSTANT:
- //printf("%d ", yylvalpp->sc_int);
- break;
- default:
- if (token >= 127)
- snprintf(str, sizeof(str), "%s ", GetAtomString(atable, token));
- else
- snprintf(str, sizeof(str), "%c", token);
- break;
- }
- CPPDebugLogMsg(str);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/3rdparty/angle/src/compiler/preprocessor/tokens.h b/src/3rdparty/angle/src/compiler/preprocessor/tokens.h
deleted file mode 100644
index dbf4a2ccfe..0000000000
--- a/src/3rdparty/angle/src/compiler/preprocessor/tokens.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/****************************************************************************\
-Copyright (c) 2002, NVIDIA Corporation.
-
-NVIDIA Corporation("NVIDIA") supplies this software to you in
-consideration of your agreement to the following terms, and your use,
-installation, modification or redistribution of this NVIDIA software
-constitutes acceptance of these terms. If you do not agree with these
-terms, please do not use, install, modify or redistribute this NVIDIA
-software.
-
-In consideration of your agreement to abide by the following terms, and
-subject to these terms, NVIDIA grants you a personal, non-exclusive
-license, under NVIDIA's copyrights in this original NVIDIA software (the
-"NVIDIA Software"), to use, reproduce, modify and redistribute the
-NVIDIA Software, with or without modifications, in source and/or binary
-forms; provided that if you redistribute the NVIDIA Software, you must
-retain the copyright notice of NVIDIA, this notice and the following
-text and disclaimers in all such redistributions of the NVIDIA Software.
-Neither the name, trademarks, service marks nor logos of NVIDIA
-Corporation may be used to endorse or promote products derived from the
-NVIDIA Software without specific prior written permission from NVIDIA.
-Except as expressly stated in this notice, no other rights or licenses
-express or implied, are granted by NVIDIA herein, including but not
-limited to any patent rights that may be infringed by your derivative
-works or by other works in which the NVIDIA Software may be
-incorporated. No hardware is licensed hereunder.
-
-THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
-WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
-INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
-NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
-PRODUCTS.
-
-IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
-INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
-OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
-NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
-TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
-NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-\****************************************************************************/
-//
-// tokens.h
-//
-
-#if !defined(__TOKENS_H)
-#define __TOKENS_H 1
-
-#include <stdio.h>
-#include "compiler/preprocessor/parser.h"
-
-#define EOF_SY (-1)
-
-typedef struct TokenBlock_Rec TokenBlock;
-
-typedef struct TokenStream_Rec {
- struct TokenStream_Rec *next;
- char *name;
- TokenBlock *head;
- TokenBlock *current;
-} TokenStream;
-
-struct TokenBlock_Rec {
- TokenBlock *next;
- int current;
- int count;
- int max;
- unsigned char *data;
-};
-
-extern TokenStream stdlib_cpp_stream;
-
-
-TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
-void DeleteTokenStream(TokenStream *pTok);
-void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp);
-void RewindTokenStream(TokenStream *pTok);
-int ReadToken(TokenStream *pTok, yystypepp * yylvalpp);
-int ReadFromTokenStream(TokenStream *pTok, int name, int (*final)(CPPStruct *));
-void UngetToken(int, yystypepp * yylvalpp);
-
-#if defined(CPPC_ENABLE_TOOLS)
-
-void DumpTokenStream(FILE *, TokenStream *, yystypepp * yylvalpp);
-
-#endif // defined(CPPC_ENABLE_TOOLS)
-
-#endif // !defined(__TOKENS_H)
diff --git a/src/3rdparty/angle/src/libEGL/Config.cpp b/src/3rdparty/angle/src/libEGL/Config.cpp
index 89bc8d89f4..5488cb6f4f 100644
--- a/src/3rdparty/angle/src/libEGL/Config.cpp
+++ b/src/3rdparty/angle/src/libEGL/Config.cpp
@@ -13,76 +13,30 @@
#include <algorithm>
#include <vector>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
#include "common/debug.h"
using namespace std;
namespace egl
{
-Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
- : mDisplayMode(displayMode), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample)
-{
- set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight);
-}
-
-void Config::setDefaults()
-{
- mBufferSize = 0;
- mRedSize = 0;
- mGreenSize = 0;
- mBlueSize = 0;
- mLuminanceSize = 0;
- mAlphaSize = 0;
- mAlphaMaskSize = 0;
- mBindToTextureRGB = EGL_DONT_CARE;
- mBindToTextureRGBA = EGL_DONT_CARE;
- mColorBufferType = EGL_RGB_BUFFER;
- mConfigCaveat = EGL_DONT_CARE;
- mConfigID = EGL_DONT_CARE;
- mConformant = 0;
- mDepthSize = 0;
- mLevel = 0;
- mMatchNativePixmap = EGL_NONE;
- mMaxPBufferWidth = 0;
- mMaxPBufferHeight = 0;
- mMaxPBufferPixels = 0;
- mMaxSwapInterval = EGL_DONT_CARE;
- mMinSwapInterval = EGL_DONT_CARE;
- mNativeRenderable = EGL_DONT_CARE;
- mNativeVisualID = 0;
- mNativeVisualType = EGL_DONT_CARE;
- mRenderableType = EGL_OPENGL_ES_BIT;
- mSampleBuffers = 0;
- mSamples = 0;
- mStencilSize = 0;
- mSurfaceType = EGL_WINDOW_BIT;
- mTransparentType = EGL_NONE;
- mTransparentRedValue = EGL_DONT_CARE;
- mTransparentGreenValue = EGL_DONT_CARE;
- mTransparentBlueValue = EGL_DONT_CARE;
-}
-
-void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
+Config::Config(rx::ConfigDesc desc, EGLint minInterval, EGLint maxInterval, EGLint texWidth, EGLint texHeight)
+ : mRenderTargetFormat(desc.renderTargetFormat), mDepthStencilFormat(desc.depthStencilFormat), mMultiSample(desc.multiSample)
{
mBindToTextureRGB = EGL_FALSE;
mBindToTextureRGBA = EGL_FALSE;
- switch (renderTargetFormat)
+ switch (desc.renderTargetFormat)
{
- case D3DFMT_A1R5G5B5:
+ case GL_RGB5_A1:
mBufferSize = 16;
mRedSize = 5;
mGreenSize = 5;
mBlueSize = 5;
mAlphaSize = 1;
break;
- case D3DFMT_A2R10G10B10:
- mBufferSize = 32;
- mRedSize = 10;
- mGreenSize = 10;
- mBlueSize = 10;
- mAlphaSize = 2;
- break;
- case D3DFMT_A8R8G8B8:
+ case GL_RGBA8_OES:
mBufferSize = 32;
mRedSize = 8;
mGreenSize = 8;
@@ -90,14 +44,14 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mAlphaSize = 8;
mBindToTextureRGBA = true;
break;
- case D3DFMT_R5G6B5:
+ case GL_RGB565:
mBufferSize = 16;
mRedSize = 5;
mGreenSize = 6;
mBlueSize = 5;
mAlphaSize = 0;
break;
- case D3DFMT_X8R8G8B8:
+ case GL_RGB8_OES:
mBufferSize = 32;
mRedSize = 8;
mGreenSize = 8;
@@ -105,6 +59,14 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mAlphaSize = 0;
mBindToTextureRGB = true;
break;
+ case GL_BGRA8_EXT:
+ mBufferSize = 32;
+ mRedSize = 8;
+ mGreenSize = 8;
+ mBlueSize = 8;
+ mAlphaSize = 8;
+ mBindToTextureRGBA = true;
+ break;
default:
UNREACHABLE(); // Other formats should not be valid
}
@@ -112,52 +74,32 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mLuminanceSize = 0;
mAlphaMaskSize = 0;
mColorBufferType = EGL_RGB_BUFFER;
- mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG;
+ mConfigCaveat = (desc.fastConfig) ? EGL_NONE : EGL_SLOW_CONFIG;
mConfigID = 0;
mConformant = EGL_OPENGL_ES2_BIT;
- switch (depthStencilFormat)
+ switch (desc.depthStencilFormat)
{
- case D3DFMT_UNKNOWN:
+ case GL_NONE:
mDepthSize = 0;
mStencilSize = 0;
break;
-// case D3DFMT_D16_LOCKABLE:
-// mDepthSize = 16;
-// mStencilSize = 0;
-// break;
- case D3DFMT_D32:
+ case GL_DEPTH_COMPONENT32_OES:
mDepthSize = 32;
mStencilSize = 0;
break;
- case D3DFMT_D15S1:
- mDepthSize = 15;
- mStencilSize = 1;
- break;
- case D3DFMT_D24S8:
+ case GL_DEPTH24_STENCIL8_OES:
mDepthSize = 24;
mStencilSize = 8;
break;
- case D3DFMT_D24X8:
+ case GL_DEPTH_COMPONENT24_OES:
mDepthSize = 24;
mStencilSize = 0;
break;
- case D3DFMT_D24X4S4:
- mDepthSize = 24;
- mStencilSize = 4;
- break;
- case D3DFMT_D16:
+ case GL_DEPTH_COMPONENT16:
mDepthSize = 16;
mStencilSize = 0;
break;
-// case D3DFMT_D32F_LOCKABLE:
-// mDepthSize = 32;
-// mStencilSize = 0;
-// break;
-// case D3DFMT_D24FS8:
-// mDepthSize = 24;
-// mStencilSize = 8;
-// break;
default:
UNREACHABLE();
}
@@ -173,8 +115,8 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mNativeVisualID = 0;
mNativeVisualType = 0;
mRenderableType = EGL_OPENGL_ES2_BIT;
- mSampleBuffers = multiSample ? 1 : 0;
- mSamples = multiSample;
+ mSampleBuffers = desc.multiSample ? 1 : 0;
+ mSamples = desc.multiSample;
mSurfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
mTransparentType = EGL_NONE;
mTransparentRedValue = 0;
@@ -288,10 +230,9 @@ ConfigSet::ConfigSet()
{
}
-void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight)
+void ConfigSet::add(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight)
{
- Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight);
-
+ Config config(desc, minSwapInterval, maxSwapInterval, texWidth, texHeight);
mSet.insert(config);
}
diff --git a/src/3rdparty/angle/src/libEGL/Config.h b/src/3rdparty/angle/src/libEGL/Config.h
index 95626ed1ad..680337b700 100644
--- a/src/3rdparty/angle/src/libEGL/Config.h
+++ b/src/3rdparty/angle/src/libEGL/Config.h
@@ -13,10 +13,10 @@
#define EGLAPI
#include <EGL/egl.h>
-#include <d3d9.h>
#include <set>
+#include "libGLESv2/renderer/Renderer.h"
#include "common/angleutils.h"
namespace egl
@@ -26,16 +26,13 @@ class Display;
class Config
{
public:
- Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
+ Config(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight);
- void setDefaults();
- void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
EGLConfig getHandle() const;
- const D3DDISPLAYMODE mDisplayMode;
- const D3DFORMAT mRenderTargetFormat;
- const D3DFORMAT mDepthStencilFormat;
- const EGLint mMultiSample;
+ const GLenum mRenderTargetFormat;
+ const GLenum mDepthStencilFormat;
+ const GLint mMultiSample;
EGLint mBufferSize; // Depth of the color buffer
EGLint mRedSize; // Bits of Red in the color buffer
@@ -99,7 +96,7 @@ class ConfigSet
public:
ConfigSet();
- void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight);
+ void add(rx::ConfigDesc desc, EGLint minSwapInterval, EGLint maxSwapInterval, EGLint texWidth, EGLint texHeight);
size_t size() const;
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
const egl::Config *get(EGLConfig configHandle);
diff --git a/src/3rdparty/angle/src/libEGL/Display.cpp b/src/3rdparty/angle/src/libEGL/Display.cpp
index a2dee6d964..d5d0f0f831 100644
--- a/src/3rdparty/angle/src/libEGL/Display.cpp
+++ b/src/3rdparty/angle/src/libEGL/Display.cpp
@@ -16,20 +16,12 @@
#include "common/debug.h"
#include "libGLESv2/mathutil.h"
-#include "libGLESv2/utilities.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/SwapChain.h"
#include "libEGL/main.h"
-
-// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
-#define REF_RAST 0
-
-// 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_ENABLE_D3D9EX=0" in your project file.
-#if !defined(ANGLE_ENABLE_D3D9EX)
-// Enables use of the IDirect3D9Ex interface, when available
-#define ANGLE_ENABLE_D3D9EX 1
-#endif // !defined(ANGLE_ENABLE_D3D9EX)
+#include "libEGL/Surface.h"
namespace egl
{
@@ -69,27 +61,10 @@ egl::Display *Display::getDisplay(EGLNativeDisplayType displayId)
Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software) : mDc(deviceContext)
{
- mD3d9Module = NULL;
-
- mD3d9 = NULL;
- mD3d9Ex = NULL;
- mDevice = NULL;
- mDeviceEx = NULL;
- mDeviceWindow = NULL;
-
- mAdapter = D3DADAPTER_DEFAULT;
-
- #if REF_RAST == 1 || defined(FORCE_REF_RAST)
- mDeviceType = D3DDEVTYPE_REF;
- #else
- mDeviceType = D3DDEVTYPE_HAL;
- #endif
-
- mMinSwapInterval = 1;
- mMaxSwapInterval = 1;
+
mSoftwareDevice = software;
mDisplayId = displayId;
- mDeviceLost = false;
+ mRenderer = NULL;
}
Display::~Display()
@@ -100,7 +75,7 @@ Display::~Display()
if (thisDisplay != displays.end())
{
- displays.erase(thisDisplay);
+ displays.erase(thisDisplay);
}
}
@@ -111,197 +86,48 @@ bool Display::initialize()
return true;
}
- if (mSoftwareDevice)
- {
- mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
- }
- else
- {
- mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
- }
- if (mD3d9Module == NULL)
+ mRenderer = glCreateRenderer(this, mDc, mSoftwareDevice);
+
+ if (!mRenderer)
{
terminate();
- return false;
- }
-
- typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
- Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
-
- // Use Direct3D9Ex if available. Among other things, this version is less
- // inclined to report a lost context, for example when the user switches
- // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
- if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
- {
- ASSERT(mD3d9Ex);
- mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
- ASSERT(mD3d9);
- }
- else
- {
- mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ return error(EGL_NOT_INITIALIZED, false);
}
- if (mD3d9)
- {
- if (mDc != NULL)
- {
- // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
- }
-
- HRESULT result;
-
- // Give up on getting device caps after about one second.
- for (int i = 0; i < 10; ++i)
- {
- result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
-
- if (SUCCEEDED(result))
- {
- break;
- }
- else if (result == D3DERR_NOTAVAILABLE)
- {
- Sleep(100); // Give the driver some time to initialize/recover
- }
- else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
- {
- terminate();
- return error(EGL_BAD_ALLOC, false);
- }
- }
-
- if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
- {
- terminate();
- return error(EGL_NOT_INITIALIZED, false);
- }
-
- // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
- // This is required by Texture2D::convertToRenderTarget.
- if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
- {
- terminate();
- return error(EGL_NOT_INITIALIZED, false);
- }
-
- mMinSwapInterval = 4;
- mMaxSwapInterval = 0;
-
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
-
- mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
+ EGLint minSwapInterval = mRenderer->getMinSwapInterval();
+ EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
+ EGLint maxTextureWidth = mRenderer->getMaxTextureWidth();
+ EGLint maxTextureHeight = mRenderer->getMaxTextureHeight();
- // ATI cards on XP have problems with non-power-of-two textures.
- mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
- !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
- !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
- !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD);
-
- const D3DFORMAT renderTargetFormats[] =
- {
- D3DFMT_A1R5G5B5,
- // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
- D3DFMT_A8R8G8B8,
- D3DFMT_R5G6B5,
- // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
- D3DFMT_X8R8G8B8
- };
-
- const D3DFORMAT depthStencilFormats[] =
- {
- D3DFMT_UNKNOWN,
- // D3DFMT_D16_LOCKABLE,
- D3DFMT_D32,
- // D3DFMT_D15S1,
- D3DFMT_D24S8,
- D3DFMT_D24X8,
- // D3DFMT_D24X4S4,
- D3DFMT_D16,
- // D3DFMT_D32F_LOCKABLE,
- // D3DFMT_D24FS8
- };
-
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- ConfigSet configSet;
-
- for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
- {
- D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
+ rx::ConfigDesc *descList;
+ int numConfigs = mRenderer->generateConfigs(&descList);
+ ConfigSet configSet;
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+ for (int i = 0; i < numConfigs; ++i)
+ configSet.add(descList[i], minSwapInterval, maxSwapInterval,
+ maxTextureWidth, maxTextureHeight);
- if (SUCCEEDED(result))
- {
- for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
- {
- D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
- HRESULT result = D3D_OK;
-
- if(depthStencilFormat != D3DFMT_UNKNOWN)
- {
- result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
- }
-
- if (SUCCEEDED(result))
- {
- if(depthStencilFormat != D3DFMT_UNKNOWN)
- {
- result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
- }
-
- if (SUCCEEDED(result))
- {
- // FIXME: enumerate multi-sampling
-
- configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0,
- mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight);
- }
- }
- }
- }
- }
-
- // Give the sorted configs a unique ID and store them internally
- EGLint index = 1;
- for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
- {
- Config configuration = *config;
- configuration.mConfigID = index;
- index++;
-
- mConfigSet.mSet.insert(configuration);
- }
- }
-
- if (!isInitialized())
+ // Give the sorted configs a unique ID and store them internally
+ EGLint index = 1;
+ for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
{
- terminate();
+ Config configuration = *config;
+ configuration.mConfigID = index;
+ index++;
- return false;
+ mConfigSet.mSet.insert(configuration);
}
- initExtensionString();
-
- static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
- static const TCHAR className[] = TEXT("STATIC");
-
- mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
+ mRenderer->deleteConfigs(descList);
+ descList = NULL;
- if (!createDevice())
+ if (!isInitialized())
{
terminate();
return false;
}
- mVertexShaderCache.initialize(mDevice);
- mPixelShaderCache.initialize(mDevice);
+ initExtensionString();
return true;
}
@@ -318,79 +144,8 @@ void Display::terminate()
destroyContext(*mContextSet.begin());
}
- while (!mEventQueryPool.empty())
- {
- mEventQueryPool.back()->Release();
- mEventQueryPool.pop_back();
- }
-
- mVertexShaderCache.clear();
- mPixelShaderCache.clear();
-
- if (mDevice)
- {
- // If the device is lost, reset it first to prevent leaving the driver in an unstable state
- if (testDeviceLost())
- {
- resetDevice();
- }
-
- mDevice->Release();
- mDevice = NULL;
- }
-
- if (mDeviceEx)
- {
- mDeviceEx->Release();
- mDeviceEx = NULL;
- }
-
- if (mD3d9)
- {
- mD3d9->Release();
- mD3d9 = NULL;
- }
-
- if (mDeviceWindow)
- {
- DestroyWindow(mDeviceWindow);
- mDeviceWindow = NULL;
- }
-
- if (mD3d9Ex)
- {
- mD3d9Ex->Release();
- mD3d9Ex = NULL;
- }
-
- if (mD3d9Module)
- {
- mD3d9Module = NULL;
- }
-}
-
-void Display::startScene()
-{
- if (!mSceneStarted)
- {
- long result = mDevice->BeginScene();
- if (SUCCEEDED(result)) {
- // This is defensive checking against the device being
- // lost at unexpected times.
- mSceneStarted = true;
- }
- }
-}
-
-void Display::endScene()
-{
- if (mSceneStarted)
- {
- // EndScene can fail if the device was lost, for example due
- // to a TDR during a draw call.
- mDevice->EndScene();
- mSceneStarted = false;
- }
+ glDestroyRenderer(mRenderer);
+ mRenderer = NULL;
}
bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
@@ -443,107 +198,7 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
return true;
}
-bool Display::createDevice()
-{
- D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
-
- HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
- {
- return error(EGL_BAD_ALLOC, false);
- }
-
- if (FAILED(result))
- {
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
- return error(EGL_BAD_ALLOC, false);
- }
- }
-
- if (mD3d9Ex)
- {
- result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
- ASSERT(SUCCEEDED(result));
- }
-
- initializeDevice();
-
- return true;
-}
-
-// do any one-time device initialization
-// NOTE: this is also needed after a device lost/reset
-// to reset the scene status and ensure the default states are reset.
-void Display::initializeDevice()
-{
- // Permanent non-default states
- mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
- mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
-
- if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
- {
- mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize);
- }
- else
- {
- mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f
- }
-
- mSceneStarted = false;
-}
-
-bool Display::resetDevice()
-{
- D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
-
- HRESULT result = D3D_OK;
- bool lost = testDeviceLost();
- int attempts = 3;
-
- while (lost && attempts > 0)
- {
- if (mDeviceEx)
- {
- Sleep(500); // Give the graphics driver some CPU time
- result = mDeviceEx->ResetEx(&presentParameters, NULL);
- }
- else
- {
- result = mDevice->TestCooperativeLevel();
-
- while (result == D3DERR_DEVICELOST)
- {
- Sleep(100); // Give the graphics driver some CPU time
- result = mDevice->TestCooperativeLevel();
- }
-
- if (result == D3DERR_DEVICENOTRESET)
- {
- result = mDevice->Reset(&presentParameters);
- }
- }
-
- lost = testDeviceLost();
- attempts --;
- }
-
- if (FAILED(result))
- {
- ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
- return error(EGL_BAD_ALLOC, false);
- }
-
- // reset device defaults
- initializeDevice();
- return true;
-}
EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
{
@@ -587,7 +242,7 @@ EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGL
return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
- if (testDeviceLost())
+ if (mRenderer->testDeviceLost(false))
{
if (!restoreLostDevice())
return EGL_NO_SURFACE;
@@ -678,7 +333,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
- if (textureFormat != EGL_NO_TEXTURE && !getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
+ if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
{
return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
}
@@ -700,7 +355,7 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
- if (testDeviceLost())
+ if (mRenderer->testDeviceLost(false))
{
if (!restoreLostDevice())
return EGL_NO_SURFACE;
@@ -721,24 +376,18 @@ EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle,
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
{
- if (!mDevice)
+ if (!mRenderer)
{
- if (!createDevice())
- {
- return NULL;
- }
+ return NULL;
}
- else if (testDeviceLost()) // Lost device
+ else if (mRenderer->testDeviceLost(false)) // Lost device
{
if (!restoreLostDevice())
return NULL;
}
- const egl::Config *config = mConfigSet.get(configHandle);
-
- gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess);
+ gl::Context *context = glCreateContext(shareContext, mRenderer, notifyResets, robustAccess);
mContextSet.insert(context);
- mDeviceLost = false;
return context;
}
@@ -757,18 +406,9 @@ bool Display::restoreLostDevice()
(*surface)->release();
}
- while (!mEventQueryPool.empty())
- {
- mEventQueryPool.back()->Release();
- mEventQueryPool.pop_back();
- }
-
- mVertexShaderCache.clear();
- mPixelShaderCache.clear();
-
- if (!resetDevice())
+ if (!mRenderer->resetDevice())
{
- return false;
+ return error(EGL_BAD_ALLOC, false);
}
// Restore any surfaces that may have been lost
@@ -799,18 +439,20 @@ void Display::notifyDeviceLost()
{
(*context)->markContextLost();
}
- mDeviceLost = true;
- error(EGL_CONTEXT_LOST);
+ egl::error(EGL_CONTEXT_LOST);
}
-bool Display::isDeviceLost()
+void Display::recreateSwapChains()
{
- return mDeviceLost;
+ for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ {
+ (*surface)->getSwapChain()->recreate();
+ }
}
bool Display::isInitialized() const
{
- return mD3d9 != NULL && mConfigSet.size() > 0;
+ return mRenderer != NULL && mConfigSet.size() > 0;
}
bool Display::isValidConfig(EGLConfig config)
@@ -841,352 +483,10 @@ bool Display::hasExistingWindowSurface(HWND window)
return false;
}
-EGLint Display::getMinSwapInterval()
-{
- return mMinSwapInterval;
-}
-
-EGLint Display::getMaxSwapInterval()
-{
- return mMaxSwapInterval;
-}
-
-IDirect3DDevice9 *Display::getDevice()
-{
- if (!mDevice)
- {
- if (!createDevice())
- {
- return NULL;
- }
- }
-
- return mDevice;
-}
-
-D3DCAPS9 Display::getDeviceCaps()
-{
- return mDeviceCaps;
-}
-
-D3DADAPTER_IDENTIFIER9 *Display::getAdapterIdentifier()
-{
- return &mAdapterIdentifier;
-}
-
-bool Display::testDeviceLost()
-{
- if (mDeviceEx)
- {
- return FAILED(mDeviceEx->CheckDeviceState(NULL));
- }
- else if (mDevice)
- {
- return FAILED(mDevice->TestCooperativeLevel());
- }
-
- return false; // No device yet, so no reset required
-}
-
-bool Display::testDeviceResettable()
-{
- HRESULT status = D3D_OK;
-
- if (mDeviceEx)
- {
- status = mDeviceEx->CheckDeviceState(NULL);
- }
- else if (mDevice)
- {
- status = mDevice->TestCooperativeLevel();
- }
-
- switch (status)
- {
- case D3DERR_DEVICENOTRESET:
- case D3DERR_DEVICEHUNG:
- return true;
- default:
- return false;
- }
-}
-
-void Display::sync(bool block)
-{
- HRESULT result;
-
- IDirect3DQuery9* query = allocateEventQuery();
- if (!query)
- {
- return;
- }
-
- result = query->Issue(D3DISSUE_END);
- ASSERT(SUCCEEDED(result));
-
- do
- {
- result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
-
- if(block && result == S_FALSE)
- {
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
- // explicitly check for device loss
- // some drivers seem to return S_FALSE even if the device is lost
- // instead of D3DERR_DEVICELOST like they should
- if (testDeviceLost())
- {
- result = D3DERR_DEVICELOST;
- }
- }
- }
- while(block && result == S_FALSE);
-
- freeEventQuery(query);
-
- if (isDeviceLostError(result))
- {
- notifyDeviceLost();
- }
-}
-
-IDirect3DQuery9* Display::allocateEventQuery()
-{
- IDirect3DQuery9 *query = NULL;
-
- if (mEventQueryPool.empty())
- {
- HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
- ASSERT(SUCCEEDED(result));
- }
- else
- {
- query = mEventQueryPool.back();
- mEventQueryPool.pop_back();
- }
-
- return query;
-}
-
-void Display::freeEventQuery(IDirect3DQuery9* query)
-{
- if (mEventQueryPool.size() > 1000)
- {
- query->Release();
- }
- else
- {
- mEventQueryPool.push_back(query);
- }
-}
-
-void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
-{
- for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
- {
- HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
- TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
-
- multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
- }
-}
-
-bool Display::getDXT1TextureSupport()
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
-}
-
-bool Display::getDXT3TextureSupport()
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
-}
-
-bool Display::getDXT5TextureSupport()
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
-}
-
-// we use INTZ for depth textures in Direct3D9
-// we also want NULL texture support to ensure the we can make depth-only FBOs
-// see http://aras-p.info/texts/D3D9GPUHacks.html
-bool Display::getDepthTextureSupport() const
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- bool intz = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
- D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ));
- bool null = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
- D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
-
- return intz && null;
-}
-
-bool Display::getFloat32TextureSupport(bool *filtering, bool *renderable)
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
- D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
-
- *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
- D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F))&&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
-
- if (!*filtering && !*renderable)
- {
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
- D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
- }
- else
- {
- return true;
- }
-}
-
-bool Display::getFloat16TextureSupport(bool *filtering, bool *renderable)
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- *filtering = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
- D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
-
- *renderable = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
- D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
-
- if (!*filtering && !*renderable)
- {
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
- D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
- SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
- D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
- }
- else
- {
- return true;
- }
-}
-
-bool Display::getLuminanceTextureSupport()
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
-}
-
-bool Display::getLuminanceAlphaTextureSupport()
-{
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
-}
-
-float Display::getTextureFilterAnisotropySupport() const
-{
- // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
- if ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2))
- {
- return mDeviceCaps.MaxAnisotropy;
- }
- return 1.0f;
-}
-
-D3DPOOL Display::getBufferPool(DWORD usage) const
-{
- if (mD3d9Ex != NULL)
- {
- return D3DPOOL_DEFAULT;
- }
- else
- {
- if (!(usage & D3DUSAGE_DYNAMIC))
- {
- return D3DPOOL_MANAGED;
- }
- }
-
- return D3DPOOL_DEFAULT;
-}
-
-D3DPOOL Display::getTexturePool(DWORD usage) const
-{
- if (mD3d9Ex != NULL)
- {
- return D3DPOOL_DEFAULT;
- }
- else
- {
- if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
- {
- return D3DPOOL_MANAGED;
- }
- }
-
- return D3DPOOL_DEFAULT;
-}
-
-bool Display::getEventQuerySupport()
-{
- IDirect3DQuery9 *query = allocateEventQuery();
- if (query)
- {
- freeEventQuery(query);
- return true;
- }
- else
- {
- return false;
- }
-}
-
-D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters()
-{
- D3DPRESENT_PARAMETERS presentParameters = {0};
-
- // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
- presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
- presentParameters.BackBufferCount = 1;
- presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
- presentParameters.BackBufferWidth = 1;
- presentParameters.BackBufferHeight = 1;
- presentParameters.EnableAutoDepthStencil = FALSE;
- presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = mDeviceWindow;
- presentParameters.MultiSampleQuality = 0;
- presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
- presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
- presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
- presentParameters.Windowed = TRUE;
-
- return presentParameters;
-}
-
void Display::initExtensionString()
{
HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ bool shareHandleSupported = mRenderer->getShareHandleSupport();
mExtensionString = "";
@@ -1194,7 +494,7 @@ void Display::initExtensionString()
mExtensionString += "EGL_EXT_create_context_robustness ";
// ANGLE-specific extensions
- if (shareHandleSupported())
+ if (shareHandleSupported)
{
mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
}
@@ -1206,12 +506,15 @@ void Display::initExtensionString()
mExtensionString += "EGL_ANGLE_software_display ";
}
- if (shareHandleSupported())
+ if (shareHandleSupported)
{
mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
}
- mExtensionString += "EGL_NV_post_sub_buffer";
+ if (mRenderer->getPostSubBufferSupport())
+ {
+ mExtensionString += "EGL_NV_post_sub_buffer";
+ }
std::string::size_type end = mExtensionString.find_last_not_of(' ');
if (end != std::string::npos)
@@ -1225,68 +528,5 @@ const char *Display::getExtensionString() const
return mExtensionString.c_str();
}
-bool Display::shareHandleSupported() const
-{
- // PIX doesn't seem to support using share handles, so disable them.
- return isD3d9ExDevice() && !gl::perfActive();
-}
-
-IDirect3DVertexShader9 *Display::createVertexShader(const DWORD *function, size_t length)
-{
- return mVertexShaderCache.create(function, length);
-}
-
-IDirect3DPixelShader9 *Display::createPixelShader(const DWORD *function, size_t length)
-{
- return mPixelShaderCache.create(function, length);
-}
-
-// Only Direct3D 10 ready devices support all the necessary vertex texture formats.
-// We test this using D3D9 by checking support for the R16F format.
-bool Display::getVertexTextureSupport() const
-{
- if (!isInitialized() || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0))
- {
- return false;
- }
-
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F);
-
- return SUCCEEDED(result);
-}
-
-bool Display::getNonPower2TextureSupport() const
-{
- return mSupportsNonPower2Textures;
-}
-
-bool Display::getOcclusionQuerySupport() const
-{
- if (!isInitialized())
- {
- return false;
- }
-
- IDirect3DQuery9 *query = NULL;
- HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query);
-
- if (SUCCEEDED(result) && query)
- {
- query->Release();
- return true;
- }
- else
- {
- return false;
- }
-}
-
-bool Display::getInstancingSupport() const
-{
- return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
-}
}
diff --git a/src/3rdparty/angle/src/libEGL/Display.h b/src/3rdparty/angle/src/libEGL/Display.h
index 23b57b74c6..8c71e51b7a 100644
--- a/src/3rdparty/angle/src/libEGL/Display.h
+++ b/src/3rdparty/angle/src/libEGL/Display.h
@@ -11,36 +11,22 @@
#ifndef LIBEGL_DISPLAY_H_
#define LIBEGL_DISPLAY_H_
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-#include <d3d9.h>
+#include "common/system.h"
#include <set>
#include <vector>
-#include "libGLESv2/Context.h"
-
#include "libEGL/Config.h"
-#include "libEGL/ShaderCache.h"
-#include "libEGL/Surface.h"
-
-const int versionWindowsVista = MAKEWORD(0x00, 0x06);
-const int versionWindows7 = MAKEWORD(0x01, 0x06);
-// Return the version of the operating system in a format suitable for ordering
-// comparison.
-inline int getComparableOSVersion()
+namespace gl
{
- DWORD version = GetVersion();
- int majorVersion = LOBYTE(LOWORD(version));
- int minorVersion = HIBYTE(LOWORD(version));
- return MAKEWORD(minorVersion, majorVersion);
+class Context;
}
namespace egl
{
+class Surface;
+
class Display
{
public:
@@ -49,9 +35,6 @@ class Display
bool initialize();
void terminate();
- virtual void startScene();
- virtual void endScene();
-
static egl::Display *getDisplay(EGLNativeDisplayType displayId);
bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig);
@@ -70,81 +53,25 @@ class Display
bool isValidSurface(egl::Surface *surface);
bool hasExistingWindowSurface(HWND window);
- EGLint getMinSwapInterval();
- EGLint getMaxSwapInterval();
-
- virtual IDirect3DDevice9 *getDevice();
- virtual D3DCAPS9 getDeviceCaps();
- virtual D3DADAPTER_IDENTIFIER9 *getAdapterIdentifier();
- virtual bool testDeviceLost();
- virtual bool testDeviceResettable();
- virtual void sync(bool block);
- virtual IDirect3DQuery9* allocateEventQuery();
- virtual void freeEventQuery(IDirect3DQuery9* query);
- virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
- virtual bool getDXT1TextureSupport();
- virtual bool getDXT3TextureSupport();
- virtual bool getDXT5TextureSupport();
- virtual bool getEventQuerySupport();
- virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
- virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
- virtual bool getLuminanceTextureSupport();
- virtual bool getLuminanceAlphaTextureSupport();
- virtual bool getVertexTextureSupport() const;
- virtual bool getNonPower2TextureSupport() const;
- virtual bool getDepthTextureSupport() const;
- virtual bool getOcclusionQuerySupport() const;
- virtual bool getInstancingSupport() const;
- virtual float getTextureFilterAnisotropySupport() const;
- virtual D3DPOOL getBufferPool(DWORD usage) const;
- virtual D3DPOOL getTexturePool(DWORD usage) const;
+ rx::Renderer *getRenderer() { return mRenderer; };
+ // exported methods must be virtual
virtual void notifyDeviceLost();
- bool isDeviceLost();
+ virtual void recreateSwapChains();
- bool isD3d9ExDevice() const { return mD3d9Ex != NULL; }
const char *getExtensionString() const;
- bool shareHandleSupported() const;
-
- virtual IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length);
- virtual IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
private:
DISALLOW_COPY_AND_ASSIGN(Display);
Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software);
- D3DPRESENT_PARAMETERS getDefaultPresentParameters();
-
bool restoreLostDevice();
EGLNativeDisplayType mDisplayId;
const HDC mDc;
- HMODULE mD3d9Module;
-
- UINT mAdapter;
- D3DDEVTYPE mDeviceType;
- IDirect3D9 *mD3d9; // Always valid after successful initialization.
- IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported.
- IDirect3DDevice9 *mDevice;
- IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
-
- // A pool of event queries that are currently unused.
- std::vector<IDirect3DQuery9*> mEventQueryPool;
-
- VertexShaderCache mVertexShaderCache;
- PixelShaderCache mPixelShaderCache;
-
- D3DCAPS9 mDeviceCaps;
- D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
- HWND mDeviceWindow;
-
- bool mSceneStarted;
- EGLint mMaxSwapInterval;
- EGLint mMinSwapInterval;
bool mSoftwareDevice;
- bool mSupportsNonPower2Textures;
typedef std::set<Surface*> SurfaceSet;
SurfaceSet mSurfaceSet;
@@ -153,11 +80,8 @@ class Display
typedef std::set<gl::Context*> ContextSet;
ContextSet mContextSet;
- bool mDeviceLost;
- bool createDevice();
- void initializeDevice();
- bool resetDevice();
+ rx::Renderer *mRenderer;
void initExtensionString();
std::string mExtensionString;
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
index d9e1887e85..a430a3530f 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -14,6 +14,8 @@
#include "common/debug.h"
#include "libGLESv2/Texture.h"
+#include "libGLESv2/renderer/SwapChain.h"
+#include "libGLESv2/main.h"
#include "libEGL/main.h"
#include "libEGL/Display.h"
@@ -23,14 +25,11 @@
namespace egl
{
-Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
+Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported)
: mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported)
{
+ mRenderer = mDisplay->getRenderer();
mSwapChain = NULL;
- mBackBuffer = NULL;
- mDepthStencil = NULL;
- mRenderTarget = NULL;
- mOffscreenTexture = NULL;
mShareHandle = NULL;
mTexture = NULL;
mTextureFormat = EGL_NO_TEXTURE;
@@ -40,6 +39,8 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
mSwapInterval = -1;
+ mWidth = -1;
+ mHeight = -1;
setSwapInterval(1);
subclassWindow();
@@ -48,11 +49,8 @@ Surface::Surface(Display *display, const Config *config, HWND window, EGLint pos
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)
{
+ mRenderer = mDisplay->getRenderer();
mSwapChain = NULL;
- mBackBuffer = NULL;
- mDepthStencil = NULL;
- mRenderTarget = NULL;
- mOffscreenTexture = NULL;
mWindowSubclassed = false;
mTexture = NULL;
mTextureFormat = textureFormat;
@@ -76,8 +74,6 @@ bool Surface::initialize()
typedef HRESULT (STDAPICALLTYPE *PtrDwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (STDAPICALLTYPE *PtrDwmSetPresentParameters)(HWND, DWM_PRESENT_PARAMETERS *);
- ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
-
if (!resetSwapChain())
return false;
@@ -118,260 +114,113 @@ bool Surface::initialize()
void Surface::release()
{
- if (mSwapChain)
- {
- mSwapChain->Release();
- mSwapChain = NULL;
- }
-
- if (mBackBuffer)
- {
- mBackBuffer->Release();
- mBackBuffer = NULL;
- }
-
- if (mDepthStencil)
- {
- mDepthStencil->Release();
- mDepthStencil = NULL;
- }
-
- if (mRenderTarget)
- {
- mRenderTarget->Release();
- mRenderTarget = NULL;
- }
-
- if (mOffscreenTexture)
- {
- mOffscreenTexture->Release();
- mOffscreenTexture = NULL;
- }
+ delete mSwapChain;
+ mSwapChain = NULL;
if (mTexture)
{
mTexture->releaseTexImage();
mTexture = NULL;
}
-
- mShareHandle = NULL;
}
bool Surface::resetSwapChain()
{
- if (!mWindow)
- {
- return resetSwapChain(mWidth, mHeight);
- }
-
- RECT windowRect;
- if (!GetClientRect(getWindowHandle(), &windowRect))
- {
- ASSERT(false);
+ ASSERT(!mSwapChain);
- ERR("Could not retrieve the window dimensions");
- return false;
- }
-
- return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
-}
+ int width;
+ int height;
-bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
-{
- IDirect3DDevice9 *device = mDisplay->getDevice();
-
- if (device == NULL)
+ if (mWindow)
{
- return false;
- }
-
- // Evict all non-render target textures to system memory and release all resources
- // before reallocating them to free up as much video memory as possible.
- device->EvictManagedResources();
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(false);
- HRESULT result;
+ ERR("Could not retrieve the window dimensions");
+ return error(EGL_BAD_SURFACE, false);
+ }
- // Release specific resources to free up memory for the new render target, while the
- // old render target still exists for the purpose of preserving its contents.
- if (mSwapChain)
- {
- mSwapChain->Release();
- mSwapChain = NULL;
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
}
-
- if (mBackBuffer)
+ else
{
- mBackBuffer->Release();
- mBackBuffer = NULL;
+ // non-window surface - size is determined at creation
+ width = mWidth;
+ height = mHeight;
}
- if (mOffscreenTexture)
+ mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
+ mConfig->mRenderTargetFormat,
+ mConfig->mDepthStencilFormat);
+ if (!mSwapChain)
{
- mOffscreenTexture->Release();
- mOffscreenTexture = NULL;
+ return error(EGL_BAD_ALLOC, false);
}
- if (mDepthStencil)
+ if (!resetSwapChain(width, height))
{
- mDepthStencil->Release();
- mDepthStencil = NULL;
+ delete mSwapChain;
+ mSwapChain = NULL;
+ return false;
}
- HANDLE *pShareHandle = NULL;
- if (!mWindow && mDisplay->shareHandleSupported())
- {
- pShareHandle = &mShareHandle;
- }
+ return true;
+}
- // CreateTexture will fail on zero dimensions, so just release old target
- if (!backbufferWidth || !backbufferHeight)
- {
- if (mRenderTarget)
- {
- mRenderTarget->Release();
- mRenderTarget = NULL;
- }
+bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(mSwapChain);
+ // Prevent bad swap chain resize by calling reset if size is invalid
+ if (backbufferWidth < 1 || backbufferHeight < 1)
+ {
mWidth = backbufferWidth;
mHeight = backbufferHeight;
- mPresentIntervalDirty = false;
-
- return true;
+ return mSwapChain->reset(0, 0, mSwapInterval) == EGL_SUCCESS;
}
- result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
- mConfig->mRenderTargetFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
- if (FAILED(result))
- {
- ERR("Could not create offscreen texture: %08lX", result);
- release();
+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
+ if (status == EGL_CONTEXT_LOST)
+ {
+ mDisplay->notifyDeviceLost();
+ return false;
}
-
- IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
-
- result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
- ASSERT(SUCCEEDED(result));
-
- if (oldRenderTarget)
+ else if (status != EGL_SUCCESS)
{
- RECT rect =
- {
- 0, 0,
- mWidth, mHeight
- };
-
- if (rect.right > static_cast<LONG>(backbufferWidth))
- {
- rect.right = backbufferWidth;
- }
+ return error(status, false);
+ }
- if (rect.bottom > static_cast<LONG>(backbufferHeight))
- {
- rect.bottom = backbufferHeight;
- }
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
- mDisplay->endScene();
+ return true;
+}
- result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
- ASSERT(SUCCEEDED(result));
+bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
- oldRenderTarget->Release();
- }
+ EGLint status = mSwapChain->reset(backbufferWidth, backbufferHeight, mSwapInterval);
- if (mWindow)
+ if (status == EGL_CONTEXT_LOST)
{
- D3DPRESENT_PARAMETERS presentParameters = {0};
- presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
- presentParameters.BackBufferCount = 1;
- presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
- presentParameters.EnableAutoDepthStencil = FALSE;
- presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = getWindowHandle();
- presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
- presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
- presentParameters.PresentationInterval = mPresentInterval;
- presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
- presentParameters.Windowed = TRUE;
- presentParameters.BackBufferWidth = backbufferWidth;
- presentParameters.BackBufferHeight = backbufferHeight;
-
- // http://crbug.com/140239
- // http://crbug.com/143434
- //
- // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
- // when using the integrated Intel. This rounds the width up rather than down.
- //
- // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
- // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
- D3DADAPTER_IDENTIFIER9* adapterIdentifier = mDisplay->getAdapterIdentifier();
- if (adapterIdentifier->VendorId == VENDOR_ID_INTEL)
- {
- presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
- }
-
- result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
-
- ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
- }
-
- result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
- ASSERT(SUCCEEDED(result));
- InvalidateRect(mWindow, NULL, FALSE);
+ mRenderer->notifyDeviceLost();
+ return false;
}
-
- if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN)
+ else if (status != EGL_SUCCESS)
{
- result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, mConfig->mDepthStencilFormat, D3DMULTISAMPLE_NONE,
- 0, FALSE, &mDepthStencil, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
-
- ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
- }
+ return error(status, false);
}
mWidth = backbufferWidth;
mHeight = backbufferHeight;
+ mSwapIntervalDirty = false;
- mPresentIntervalDirty = false;
return true;
}
@@ -397,86 +246,18 @@ bool Surface::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
return true;
}
- IDirect3DDevice9 *device = mDisplay->getDevice();
-
- // Disable all pipeline operations
- device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
- device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
- device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
- device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
- device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
- device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
- device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
- device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
- device->SetPixelShader(NULL);
- device->SetVertexShader(NULL);
-
- device->SetRenderTarget(0, mBackBuffer);
- device->SetDepthStencilSurface(NULL);
-
- device->SetTexture(0, mOffscreenTexture);
- device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
- device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
- device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
- device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
- device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
-
- D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
- device->SetViewport(&viewport);
-
- float x1 = x - 0.5f;
- float y1 = (mHeight - y - height) - 0.5f;
- float x2 = (x + width) - 0.5f;
- float y2 = (mHeight - y) - 0.5f;
-
- float u1 = x / float(mWidth);
- float v1 = y / float(mHeight);
- float u2 = (x + width) / float(mWidth);
- float v2 = (y + height) / float(mHeight);
-
- float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
- {x2, y1, 0.0f, 1.0f, u2, v2},
- {x2, y2, 0.0f, 1.0f, u2, v1},
- {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
-
- mDisplay->startScene();
- device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
- mDisplay->endScene();
-
- device->SetTexture(0, NULL);
-
- RECT rect =
- {
- x, mHeight - y - height,
- x + width, mHeight - y
- };
-
- HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
- gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
- if (context)
+ if (status == EGL_CONTEXT_LOST)
{
- context->markAllStateDirty();
- }
-
- if (isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
+ mRenderer->notifyDeviceLost();
return false;
}
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
+ else if (status != EGL_SUCCESS)
{
- return error(EGL_BAD_ALLOC, false);
+ return error(status, false);
}
- ASSERT(SUCCEEDED(result));
-
checkForOutOfDateSwapChain();
return true;
@@ -572,9 +353,17 @@ bool Surface::checkForOutOfDateSwapChain()
int clientHeight = client.bottom - client.top;
bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
- if (sizeDirty || mPresentIntervalDirty)
+ if (mSwapIntervalDirty)
{
resetSwapChain(clientWidth, clientHeight);
+ }
+ else if (sizeDirty)
+ {
+ resizeSwapChain(clientWidth, clientHeight);
+ }
+
+ if (mSwapIntervalDirty || sizeDirty)
+ {
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
@@ -582,22 +371,8 @@ bool Surface::checkForOutOfDateSwapChain()
return true;
}
- return false;
-}
-
-DWORD Surface::convertInterval(EGLint interval)
-{
- switch(interval)
- {
- case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
- case 1: return D3DPRESENT_INTERVAL_ONE;
- case 2: return D3DPRESENT_INTERVAL_TWO;
- case 3: return D3DPRESENT_INTERVAL_THREE;
- case 4: return D3DPRESENT_INTERVAL_FOUR;
- default: UNREACHABLE();
- }
- return D3DPRESENT_INTERVAL_DEFAULT;
+ return false;
}
bool Surface::swap()
@@ -631,38 +406,9 @@ EGLint Surface::isPostSubBufferSupported() const
return mPostSubBufferSupported;
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Surface::getRenderTarget()
-{
- if (mRenderTarget)
- {
- mRenderTarget->AddRef();
- }
-
- return mRenderTarget;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Surface::getDepthStencil()
-{
- if (mDepthStencil)
- {
- mDepthStencil->AddRef();
- }
-
- return mDepthStencil;
-}
-
-IDirect3DTexture9 *Surface::getOffscreenTexture()
+rx::SwapChain *Surface::getSwapChain() const
{
- if (mOffscreenTexture)
- {
- mOffscreenTexture->AddRef();
- }
-
- return mOffscreenTexture;
+ return mSwapChain;
}
void Surface::setSwapInterval(EGLint interval)
@@ -673,11 +419,10 @@ void Surface::setSwapInterval(EGLint interval)
}
mSwapInterval = interval;
- mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
- mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
+ mSwapInterval = std::max(mSwapInterval, mRenderer->getMinSwapInterval());
+ mSwapInterval = std::min(mSwapInterval, mRenderer->getMaxSwapInterval());
- mPresentInterval = convertInterval(mSwapInterval);
- mPresentIntervalDirty = true;
+ mSwapIntervalDirty = true;
}
EGLenum Surface::getTextureFormat() const
@@ -700,7 +445,7 @@ gl::Texture2D *Surface::getBoundTexture() const
return mTexture;
}
-D3DFORMAT Surface::getFormat() const
+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 40bd7028ab..938b800cdd 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.h
+++ b/src/3rdparty/angle/src/libEGL/Surface.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,12 +8,11 @@
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
-#ifndef INCLUDE_SURFACE_H_
-#define INCLUDE_SURFACE_H_
+#ifndef LIBEGL_SURFACE_H_
+#define LIBEGL_SURFACE_H_
#define EGLAPI
#include <EGL/egl.h>
-#include <d3d9.h>
#include "common/angleutils.h"
@@ -21,6 +20,11 @@ namespace gl
{
class Texture2D;
}
+namespace rx
+{
+class Renderer;
+class SwapChain;
+}
namespace egl
{
@@ -48,18 +52,14 @@ class Surface
virtual EGLint isPostSubBufferSupported() const;
- virtual IDirect3DSurface9 *getRenderTarget();
- virtual IDirect3DSurface9 *getDepthStencil();
- virtual IDirect3DTexture9 *getOffscreenTexture();
-
- HANDLE getShareHandle() { return mShareHandle; }
+ virtual rx::SwapChain *getSwapChain() const;
void setSwapInterval(EGLint interval);
bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update
virtual EGLenum getTextureFormat() const;
virtual EGLenum getTextureTarget() const;
- virtual D3DFORMAT getFormat() const;
+ virtual EGLenum getFormat() const;
virtual void setBoundTexture(gl::Texture2D *texture);
virtual gl::Texture2D *getBoundTexture() const;
@@ -68,19 +68,16 @@ private:
DISALLOW_COPY_AND_ASSIGN(Surface);
Display *const mDisplay;
- IDirect3DSwapChain9 *mSwapChain;
- IDirect3DSurface9 *mBackBuffer;
- IDirect3DSurface9 *mDepthStencil;
- IDirect3DSurface9* mRenderTarget;
- IDirect3DTexture9* mOffscreenTexture;
+ rx::Renderer *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);
- static DWORD convertInterval(EGLint interval);
const HWND mWindow; // Window that the surface is created for.
bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
@@ -103,10 +100,9 @@ private:
EGLint mSwapInterval;
EGLint mPostSubBufferSupported;
- DWORD mPresentInterval;
- bool mPresentIntervalDirty;
+ bool mSwapIntervalDirty;
gl::Texture2D *mTexture;
};
}
-#endif // INCLUDE_SURFACE_H_
+#endif // LIBEGL_SURFACE_H_
diff --git a/src/3rdparty/angle/src/libEGL/libEGL.cpp b/src/3rdparty/angle/src/libEGL/libEGL.cpp
index 25df1c8c24..7fca456cf5 100644
--- a/src/3rdparty/angle/src/libEGL/libEGL.cpp
+++ b/src/3rdparty/angle/src/libEGL/libEGL.cpp
@@ -12,21 +12,23 @@
#include "common/version.h"
#include "libGLESv2/Context.h"
#include "libGLESv2/Texture.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/SwapChain.h"
#include "libEGL/main.h"
#include "libEGL/Display.h"
-
+#include "libEGL/Surface.h"
bool validateDisplay(egl::Display *display)
{
if (display == EGL_NO_DISPLAY)
{
- return error(EGL_BAD_DISPLAY, false);
+ return egl::error(EGL_BAD_DISPLAY, false);
}
if (!display->isInitialized())
{
- return error(EGL_NOT_INITIALIZED, false);
+ return egl::error(EGL_NOT_INITIALIZED, false);
}
return true;
@@ -41,7 +43,7 @@ bool validateConfig(egl::Display *display, EGLConfig config)
if (!display->isValidConfig(config))
{
- return error(EGL_BAD_CONFIG, false);
+ return egl::error(EGL_BAD_CONFIG, false);
}
return true;
@@ -56,7 +58,7 @@ bool validateContext(egl::Display *display, gl::Context *context)
if (!display->isValidContext(context))
{
- return error(EGL_BAD_CONTEXT, false);
+ return egl::error(EGL_BAD_CONTEXT, false);
}
return true;
@@ -71,7 +73,7 @@ bool validateSurface(egl::Display *display, egl::Surface *surface)
if (!display->isValidSurface(surface))
{
- return error(EGL_BAD_SURFACE, false);
+ return egl::error(EGL_BAD_SURFACE, false);
}
return true;
@@ -103,7 +105,7 @@ EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id)
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
}
}
@@ -116,24 +118,24 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
if (dpy == EGL_NO_DISPLAY)
{
- return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
if (!display->initialize())
{
- return error(EGL_NOT_INITIALIZED, EGL_FALSE);
+ return egl::error(EGL_NOT_INITIALIZED, EGL_FALSE);
}
if (major) *major = 1;
if (minor) *minor = 4;
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -145,18 +147,18 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy)
{
if (dpy == EGL_NO_DISPLAY)
{
- return error(EGL_BAD_DISPLAY, EGL_FALSE);
+ return egl::error(EGL_BAD_DISPLAY, EGL_FALSE);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
display->terminate();
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -176,20 +178,20 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name)
switch (name)
{
case EGL_CLIENT_APIS:
- return success("OpenGL_ES");
+ return egl::success("OpenGL_ES");
case EGL_EXTENSIONS:
return display->getExtensionString();
case EGL_VENDOR:
- return success("Google Inc.");
+ return egl::success("Google Inc.");
case EGL_VERSION:
- return success("1.4 (ANGLE " VERSION_STRING ")");
+ return egl::success("1.4 (ANGLE " VERSION_STRING ")");
}
- return error(EGL_BAD_PARAMETER, (const char*)NULL);
+ return egl::error(EGL_BAD_PARAMETER, (const char*)NULL);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, (const char*)NULL);
+ return egl::error(EGL_BAD_ALLOC, (const char*)NULL);
}
}
@@ -210,21 +212,21 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co
if (!num_config)
{
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
const EGLint attribList[] = {EGL_NONE};
if (!display->getConfigs(configs, attribList, config_size, num_config))
{
- return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -245,7 +247,7 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
if (!num_config)
{
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
const EGLint attribList[] = {EGL_NONE};
@@ -257,11 +259,11 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
display->getConfigs(configs, attrib_list, config_size, num_config);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -281,14 +283,14 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint
if (!display->getConfigAttrib(config, attribute, value))
{
- return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -310,14 +312,14 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
if (!IsWindow(window))
{
- return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
}
return display->createWindowSurface(window, config, attrib_list);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
}
@@ -339,7 +341,7 @@ EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, c
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
}
@@ -359,11 +361,11 @@ EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EG
UNIMPLEMENTED(); // FIXME
- return success(EGL_NO_SURFACE);
+ return egl::success(EGL_NO_SURFACE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
}
@@ -383,16 +385,16 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
if (surface == EGL_NO_SURFACE)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
display->destroySurface((egl::Surface*)surface);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -413,7 +415,7 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
if (surface == EGL_NO_SURFACE)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
switch (attribute)
@@ -470,14 +472,14 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint
*value = eglSurface->isPostSubBufferSupported();
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -498,23 +500,26 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
if (surface == EGL_NO_SURFACE)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
switch (attribute)
{
case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
- *value = (void*) eglSurface->getShareHandle();
+ {
+ rx::SwapChain *swapchain = eglSurface->getSwapChain();
+ *value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
+ }
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -528,20 +533,20 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api)
{
case EGL_OPENGL_API:
case EGL_OPENVG_API:
- return error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE); // Not supported by this implementation
case EGL_OPENGL_ES_API:
break;
default:
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
egl::setCurrentAPI(api);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -553,11 +558,11 @@ EGLenum __stdcall eglQueryAPI(void)
{
EGLenum API = egl::getCurrentAPI();
- return success(API);
+ return egl::success(API);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -569,11 +574,11 @@ EGLBoolean __stdcall eglWaitClient(void)
{
UNIMPLEMENTED(); // FIXME
- return success(0);
+ return egl::success(0);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -585,11 +590,11 @@ EGLBoolean __stdcall eglReleaseThread(void)
{
eglMakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -610,14 +615,14 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu
if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
}
return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
}
@@ -638,11 +643,11 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint
UNIMPLEMENTED(); // FIXME
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -662,34 +667,34 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint
if (buffer != EGL_BACK_BUFFER)
{
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (eglSurface->getBoundTexture())
{
- return error(EGL_BAD_ACCESS, EGL_FALSE);
+ return egl::error(EGL_BAD_ACCESS, EGL_FALSE);
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return error(EGL_BAD_MATCH, EGL_FALSE);
+ return egl::error(EGL_BAD_MATCH, EGL_FALSE);
}
if (!glBindTexImage(eglSurface))
{
- return error(EGL_BAD_MATCH, EGL_FALSE);
+ return egl::error(EGL_BAD_MATCH, EGL_FALSE);
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -709,17 +714,17 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
if (buffer != EGL_BACK_BUFFER)
{
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
{
- return error(EGL_BAD_MATCH, EGL_FALSE);
+ return egl::error(EGL_BAD_MATCH, EGL_FALSE);
}
gl::Texture2D *texture = eglSurface->getBoundTexture();
@@ -729,11 +734,11 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi
texture->releaseTexImage();
}
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -754,16 +759,16 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
if (draw_surface == NULL)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
draw_surface->setSwapInterval(interval);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -791,32 +796,32 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
if (attribute[1] == EGL_TRUE)
{
- return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
+ return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented
// robust_access = true;
}
else if (attribute[1] != EGL_FALSE)
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_ATTRIBUTE, 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 error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
break;
default:
- return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
}
}
}
if (client_version != 2)
{
- return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
}
if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification)
{
- return error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_MATCH, EGL_NO_CONTEXT);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -829,13 +834,13 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access);
if (context)
- return success(context);
+ return egl::success(context);
else
- return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
+ return egl::error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
}
}
@@ -855,16 +860,16 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
if (ctx == EGL_NO_CONTEXT)
{
- return error(EGL_BAD_CONTEXT, EGL_FALSE);
+ return egl::error(EGL_BAD_CONTEXT, EGL_FALSE);
}
display->destroyContext(context);
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -877,22 +882,21 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
{
egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx);
- IDirect3DDevice9 *device = display->getDevice();
- if (!device || display->testDeviceLost())
+ if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
{
- display->notifyDeviceLost();
return EGL_FALSE;
}
- if (display->isDeviceLost())
+ rx::Renderer *renderer = display->getRenderer();
+ if (renderer->testDeviceLost(true))
{
- return error(EGL_CONTEXT_LOST, EGL_FALSE);
+ return EGL_FALSE;
}
- if (ctx != EGL_NO_CONTEXT && !validateContext(display, context))
+ if (renderer->isDeviceLost())
{
- return EGL_FALSE;
+ return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
}
if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) ||
@@ -912,11 +916,11 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
glMakeCurrent(context, display, static_cast<egl::Surface*>(draw));
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -928,11 +932,11 @@ EGLContext __stdcall eglGetCurrentContext(void)
{
EGLContext context = glGetCurrentContext();
- return success(context);
+ return egl::success(context);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_CONTEXT);
}
}
@@ -945,21 +949,21 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw)
if (readdraw == EGL_READ)
{
EGLSurface read = egl::getCurrentReadSurface();
- return success(read);
+ return egl::success(read);
}
else if (readdraw == EGL_DRAW)
{
EGLSurface draw = egl::getCurrentDrawSurface();
- return success(draw);
+ return egl::success(draw);
}
else
{
- return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
}
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
}
}
@@ -971,11 +975,11 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void)
{
EGLDisplay dpy = egl::getCurrentDisplay();
- return success(dpy);
+ return egl::success(dpy);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
+ return egl::error(EGL_BAD_ALLOC, EGL_NO_DISPLAY);
}
}
@@ -996,11 +1000,11 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr
UNIMPLEMENTED(); // FIXME
- return success(0);
+ return egl::success(0);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -1012,11 +1016,11 @@ EGLBoolean __stdcall eglWaitGL(void)
{
UNIMPLEMENTED(); // FIXME
- return success(0);
+ return egl::success(0);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -1028,11 +1032,11 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine)
{
UNIMPLEMENTED(); // FIXME
- return success(0);
+ return egl::success(0);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -1050,24 +1054,24 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
return EGL_FALSE;
}
- if (display->isDeviceLost())
+ if (display->getRenderer()->isDeviceLost())
{
- return error(EGL_CONTEXT_LOST, EGL_FALSE);
+ return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (eglSurface->swap())
{
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
@@ -1087,18 +1091,18 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ
return EGL_FALSE;
}
- if (display->isDeviceLost())
+ if (display->getRenderer()->isDeviceLost())
{
- return error(EGL_CONTEXT_LOST, EGL_FALSE);
+ return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
}
UNIMPLEMENTED(); // FIXME
- return success(0);
+ return egl::success(0);
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
}
@@ -1110,7 +1114,7 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
{
if (x < 0 || y < 0 || width < 0 || height < 0)
{
- return error(EGL_BAD_PARAMETER, EGL_FALSE);
+ return egl::error(EGL_BAD_PARAMETER, EGL_FALSE);
}
egl::Display *display = static_cast<egl::Display*>(dpy);
@@ -1121,24 +1125,24 @@ EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLi
return EGL_FALSE;
}
- if (display->isDeviceLost())
+ if (display->getRenderer()->isDeviceLost())
{
- return error(EGL_CONTEXT_LOST, EGL_FALSE);
+ return egl::error(EGL_CONTEXT_LOST, EGL_FALSE);
}
if (surface == EGL_NO_SURFACE)
{
- return error(EGL_BAD_SURFACE, EGL_FALSE);
+ return egl::error(EGL_BAD_SURFACE, EGL_FALSE);
}
if (eglSurface->postSubBuffer(x, y, width, height))
{
- return success(EGL_TRUE);
+ return egl::success(EGL_TRUE);
}
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, EGL_FALSE);
+ return egl::error(EGL_BAD_ALLOC, EGL_FALSE);
}
return EGL_FALSE;
@@ -1163,7 +1167,7 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char
{"", NULL},
};
- for (int ext = 0; ext < sizeof(eglExtensions) / sizeof(Extension); ext++)
+ for (unsigned int ext = 0; ext < ArraySize(eglExtensions); ext++)
{
if (strcmp(procname, eglExtensions[ext].name) == 0)
{
@@ -1175,7 +1179,7 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char
}
catch(std::bad_alloc&)
{
- return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
+ return egl::error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL);
}
}
}
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index 614bcf67ad..7ba77f08d1 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -155,9 +155,10 @@ 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 d09d9e6bc3..77da8f0f8e 100644
--- a/src/3rdparty/angle/src/libEGL/main.h
+++ b/src/3rdparty/angle/src/libEGL/main.h
@@ -38,7 +38,6 @@ EGLSurface getCurrentDrawSurface();
void setCurrentReadSurface(EGLSurface surface);
EGLSurface getCurrentReadSurface();
-}
void error(EGLint errorCode);
@@ -58,4 +57,6 @@ const T &success(const T &returnValue)
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 5f7213b8da..21c2f86ce8 100644
--- a/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
+++ b/src/3rdparty/angle/src/libGLESv2/BinaryStream.h
@@ -9,9 +9,6 @@
#ifndef LIBGLESV2_BINARYSTREAM_H_
#define LIBGLESV2_BINARYSTREAM_H_
-#include <string>
-#include <vector>
-
#include "common/angleutils.h"
namespace gl
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
index dd12e3c077..8d5b4ef2a1 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,19 +11,20 @@
#include "libGLESv2/Buffer.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/VertexDataManager.h"
-#include "libGLESv2/IndexDataManager.h"
+#include "libGLESv2/renderer/VertexBuffer.h"
+#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
-Buffer::Buffer(GLuint id) : RefCountObject(id)
+Buffer::Buffer(rx::Renderer *renderer, GLuint id) : RefCountObject(id)
{
- mContents = NULL;
- mSize = 0;
+ mRenderer = renderer;
mUsage = GL_DYNAMIC_DRAW;
+ mBufferStorage = renderer->createBufferStorage();
mStaticVertexBuffer = NULL;
mStaticIndexBuffer = NULL;
mUnmodifiedDataUse = 0;
@@ -30,47 +32,32 @@ Buffer::Buffer(GLuint id) : RefCountObject(id)
Buffer::~Buffer()
{
- delete[] mContents;
+ delete mBufferStorage;
delete mStaticVertexBuffer;
delete mStaticIndexBuffer;
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
{
- if (size == 0)
- {
- delete[] mContents;
- mContents = NULL;
- }
- else if (size != mSize)
- {
- delete[] mContents;
- mContents = new GLubyte[size];
- memset(mContents, 0, size);
- }
+ mBufferStorage->clear();
+ mBufferStorage->setData(data, size, 0);
- if (data != NULL && size > 0)
- {
- memcpy(mContents, data, size);
- }
-
- mSize = size;
mUsage = usage;
invalidateStaticData();
if (usage == GL_STATIC_DRAW)
{
- mStaticVertexBuffer = new StaticVertexBuffer(getDevice());
- mStaticIndexBuffer = new StaticIndexBuffer(getDevice());
+ mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
+ mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
}
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
- memcpy(mContents + offset, data, size);
-
- if ((mStaticVertexBuffer && mStaticVertexBuffer->size() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->size() != 0))
+ mBufferStorage->setData(data, size, offset);
+
+ if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0))
{
invalidateStaticData();
}
@@ -78,12 +65,27 @@ void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
mUnmodifiedDataUse = 0;
}
-StaticVertexBuffer *Buffer::getStaticVertexBuffer()
+rx::BufferStorage *Buffer::getStorage() const
+{
+ return mBufferStorage;
+}
+
+unsigned int Buffer::size()
+{
+ return mBufferStorage->getSize();
+}
+
+GLenum Buffer::usage() const
+{
+ return mUsage;
+}
+
+rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer()
{
return mStaticVertexBuffer;
}
-StaticIndexBuffer *Buffer::getStaticIndexBuffer()
+rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer()
{
return mStaticIndexBuffer;
}
@@ -106,10 +108,10 @@ void Buffer::promoteStaticUsage(int dataSize)
{
mUnmodifiedDataUse += dataSize;
- if (mUnmodifiedDataUse > 3 * mSize)
+ if (mUnmodifiedDataUse > 3 * mBufferStorage->getSize())
{
- mStaticVertexBuffer = new StaticVertexBuffer(getDevice());
- mStaticIndexBuffer = new StaticIndexBuffer(getDevice());
+ mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer);
+ mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer);
}
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h
index 7019c4e160..4376ada5c0 100644
--- a/src/3rdparty/angle/src/libGLESv2/Buffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -11,49 +11,51 @@
#ifndef LIBGLESV2_BUFFER_H_
#define LIBGLESV2_BUFFER_H_
-#include <cstddef>
-#include <vector>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+namespace rx
+{
+class Renderer;
+class BufferStorage;
+class StaticIndexBufferInterface;
+class StaticVertexBufferInterface;
+};
+
namespace gl
{
-class StaticVertexBuffer;
-class StaticIndexBuffer;
class Buffer : public RefCountObject
{
public:
- explicit Buffer(GLuint id);
+ Buffer(rx::Renderer *renderer, GLuint id);
virtual ~Buffer();
void bufferData(const void *data, GLsizeiptr size, GLenum usage);
void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset);
- void *data() { return mContents; }
- size_t size() const { return mSize; }
- GLenum usage() const { return mUsage; }
+ GLenum usage() const;
+
+ rx::BufferStorage *getStorage() const;
+ unsigned int size();
- StaticVertexBuffer *getStaticVertexBuffer();
- StaticIndexBuffer *getStaticIndexBuffer();
+ rx::StaticVertexBufferInterface *getStaticVertexBuffer();
+ rx::StaticIndexBufferInterface *getStaticIndexBuffer();
void invalidateStaticData();
void promoteStaticUsage(int dataSize);
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
- GLubyte *mContents;
- GLsizeiptr mSize;
+ rx::Renderer *mRenderer;
GLenum mUsage;
- StaticVertexBuffer *mStaticVertexBuffer;
- StaticIndexBuffer *mStaticIndexBuffer;
- GLsizeiptr mUnmodifiedDataUse;
+ rx::BufferStorage *mBufferStorage;
+
+ rx::StaticVertexBufferInterface *mStaticVertexBuffer;
+ rx::StaticIndexBufferInterface *mStaticIndexBuffer;
+ unsigned int mUnmodifiedDataUse;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index 414bfa968d..90ba2539d8 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,38 +10,41 @@
#include "libGLESv2/Context.h"
-#include <algorithm>
-
-#include "libEGL/Display.h"
-
#include "libGLESv2/main.h"
-#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
-#include "libGLESv2/Blit.h"
-#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Fence.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/Query.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
-#include "libGLESv2/VertexDataManager.h"
-#include "libGLESv2/IndexDataManager.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/renderer/IndexDataManager.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+#include "libGLESv2/renderer/Renderer.h"
+
+#include "libEGL/Surface.h"
#undef near
#undef far
namespace gl
{
-Context::Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) : mConfig(config)
+static const char* makeStaticString(const std::string& str)
{
- ASSERT(robustAccess == false); // Unimplemented
+ static std::set<std::string> strings;
+ std::set<std::string>::iterator it = strings.find(str);
+ if (it != strings.end())
+ return it->c_str();
+
+ return strings.insert(str).first->c_str();
+}
- mDisplay = NULL;
- mDevice = NULL;
+Context::Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
+{
+ ASSERT(robustAccess == false); // Unimplemented
mFenceHandleAllocator.setBaseHandle(0);
@@ -49,68 +53,73 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
mState.depthClearValue = 1.0f;
mState.stencilClearValue = 0;
- mState.cullFace = false;
- mState.cullMode = GL_BACK;
- mState.frontFace = GL_CCW;
- mState.depthTest = false;
- mState.depthFunc = GL_LESS;
- mState.blend = false;
- mState.sourceBlendRGB = GL_ONE;
- mState.sourceBlendAlpha = GL_ONE;
- mState.destBlendRGB = GL_ZERO;
- mState.destBlendAlpha = GL_ZERO;
- mState.blendEquationRGB = GL_FUNC_ADD;
- mState.blendEquationAlpha = GL_FUNC_ADD;
+ mState.rasterizer.cullFace = false;
+ mState.rasterizer.cullMode = GL_BACK;
+ mState.rasterizer.frontFace = GL_CCW;
+ mState.rasterizer.polygonOffsetFill = false;
+ mState.rasterizer.polygonOffsetFactor = 0.0f;
+ mState.rasterizer.polygonOffsetUnits = 0.0f;
+ mState.rasterizer.pointDrawMode = false;
+ mState.scissorTest = false;
+ mState.scissor.x = 0;
+ mState.scissor.y = 0;
+ mState.scissor.width = 0;
+ mState.scissor.height = 0;
+
+ mState.blend.blend = false;
+ mState.blend.sourceBlendRGB = GL_ONE;
+ mState.blend.sourceBlendAlpha = GL_ONE;
+ mState.blend.destBlendRGB = GL_ZERO;
+ mState.blend.destBlendAlpha = GL_ZERO;
+ mState.blend.blendEquationRGB = GL_FUNC_ADD;
+ mState.blend.blendEquationAlpha = GL_FUNC_ADD;
+ mState.blend.sampleAlphaToCoverage = false;
+ mState.blend.dither = true;
+
mState.blendColor.red = 0;
mState.blendColor.green = 0;
mState.blendColor.blue = 0;
mState.blendColor.alpha = 0;
- mState.stencilTest = false;
- mState.stencilFunc = GL_ALWAYS;
+
+ mState.depthStencil.depthTest = false;
+ mState.depthStencil.depthFunc = GL_LESS;
+ mState.depthStencil.depthMask = true;
+ mState.depthStencil.stencilTest = false;
+ mState.depthStencil.stencilFunc = GL_ALWAYS;
+ mState.depthStencil.stencilMask = -1;
+ mState.depthStencil.stencilWritemask = -1;
+ mState.depthStencil.stencilBackFunc = GL_ALWAYS;
+ mState.depthStencil.stencilBackMask = - 1;
+ mState.depthStencil.stencilBackWritemask = -1;
+ mState.depthStencil.stencilFail = GL_KEEP;
+ mState.depthStencil.stencilPassDepthFail = GL_KEEP;
+ mState.depthStencil.stencilPassDepthPass = GL_KEEP;
+ mState.depthStencil.stencilBackFail = GL_KEEP;
+ mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
+ mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
+
mState.stencilRef = 0;
- mState.stencilMask = -1;
- mState.stencilWritemask = -1;
- mState.stencilBackFunc = GL_ALWAYS;
mState.stencilBackRef = 0;
- mState.stencilBackMask = - 1;
- mState.stencilBackWritemask = -1;
- mState.stencilFail = GL_KEEP;
- mState.stencilPassDepthFail = GL_KEEP;
- mState.stencilPassDepthPass = GL_KEEP;
- mState.stencilBackFail = GL_KEEP;
- mState.stencilBackPassDepthFail = GL_KEEP;
- mState.stencilBackPassDepthPass = GL_KEEP;
- mState.polygonOffsetFill = false;
- mState.polygonOffsetFactor = 0.0f;
- mState.polygonOffsetUnits = 0.0f;
- mState.sampleAlphaToCoverage = false;
+
mState.sampleCoverage = false;
mState.sampleCoverageValue = 1.0f;
mState.sampleCoverageInvert = false;
- mState.scissorTest = false;
- mState.dither = true;
mState.generateMipmapHint = GL_DONT_CARE;
mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
mState.lineWidth = 1.0f;
- mState.viewportX = 0;
- mState.viewportY = 0;
- mState.viewportWidth = config->mDisplayMode.Width;
- mState.viewportHeight = config->mDisplayMode.Height;
+ mState.viewport.x = 0;
+ mState.viewport.y = 0;
+ mState.viewport.width = 0;
+ mState.viewport.height = 0;
mState.zNear = 0.0f;
mState.zFar = 1.0f;
- mState.scissorX = 0;
- mState.scissorY = 0;
- mState.scissorWidth = config->mDisplayMode.Width;
- mState.scissorHeight = config->mDisplayMode.Height;
-
- mState.colorMaskRed = true;
- mState.colorMaskGreen = true;
- mState.colorMaskBlue = true;
- mState.colorMaskAlpha = true;
- mState.depthMask = true;
+ mState.blend.colorMaskRed = true;
+ mState.blend.colorMaskGreen = true;
+ mState.blend.colorMaskBlue = true;
+ mState.blend.colorMaskAlpha = true;
if (shareContext != NULL)
{
@@ -119,7 +128,7 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
}
else
{
- mResourceManager = new ResourceManager();
+ mResourceManager = new ResourceManager(mRenderer);
}
// [OpenGL ES 2.0.24] section 3.7 page 83:
@@ -128,8 +137,8 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero.set(new Texture2D(0));
- mTextureCubeMapZero.set(new TextureCubeMap(0));
+ mTexture2DZero.set(new Texture2D(mRenderer, 0));
+ mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
mState.activeSampler = 0;
bindArrayBuffer(0);
@@ -147,10 +156,8 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
mState.unpackAlignment = 4;
mState.packReverseRowOrder = false;
- mVertexDataManager = NULL;
- mIndexDataManager = NULL;
- mBlit = NULL;
- mLineLoopIB = NULL;
+ mExtensionString = NULL;
+ mRendererString = NULL;
mInvalidEnum = false;
mInvalidValue = false;
@@ -164,15 +171,13 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext, boo
mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
mRobustAccess = robustAccess;
+ mSupportsBGRATextures = false;
mSupportsDXT1Textures = false;
mSupportsDXT3Textures = false;
mSupportsDXT5Textures = false;
mSupportsEventQueries = false;
mSupportsOcclusionQueries = false;
mNumCompressedTextureFormats = 0;
- mMaxSupportedSamples = 0;
- mMaskedClearSavedState = NULL;
- markAllStateDirty();
}
Context::~Context()
@@ -203,15 +208,9 @@ Context::~Context()
deleteQuery(mQueryMap.begin()->first);
}
- while (!mMultiSampleSupport.empty())
- {
- delete [] mMultiSampleSupport.begin()->second;
- mMultiSampleSupport.erase(mMultiSampleSupport.begin());
- }
-
for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
{
- for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++)
+ for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
{
mState.samplerTexture[type][sampler].set(NULL);
}
@@ -239,86 +238,42 @@ Context::~Context()
mTexture2DZero.set(NULL);
mTextureCubeMapZero.set(NULL);
- delete mVertexDataManager;
- delete mIndexDataManager;
- delete mBlit;
- delete mLineLoopIB;
-
- if (mMaskedClearSavedState)
- {
- mMaskedClearSavedState->Release();
- }
-
mResourceManager->release();
}
-void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
+void Context::makeCurrent(egl::Surface *surface)
{
- mDisplay = display;
- mDevice = mDisplay->getDevice();
-
if (!mHasBeenCurrent)
{
- mDeviceCaps = mDisplay->getDeviceCaps();
-
- mVertexDataManager = new VertexDataManager(this, mDevice);
- mIndexDataManager = new IndexDataManager(this, mDevice);
- mBlit = new Blit(this);
+ mMajorShaderModel = mRenderer->getMajorShaderModel();
+ mMaximumPointSize = mRenderer->getMaxPointSize();
+ mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
+ mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
+ mSupportsInstancing = mRenderer->getInstancingSupport();
- mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
- mMaximumPointSize = mDeviceCaps.MaxPointSize;
- mSupportsVertexTexture = mDisplay->getVertexTextureSupport();
- mSupportsNonPower2Texture = mDisplay->getNonPower2TextureSupport();
- mSupportsInstancing = mDisplay->getInstancingSupport();
-
- mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
+ mMaxViewportDimension = mRenderer->getMaxViewportDimension();
+ mMaxTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
(int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
mMaxRenderbufferDimension = mMaxTextureDimension;
mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
- mMaxTextureAnisotropy = mDisplay->getTextureFilterAnisotropySupport();
+ mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d, MaxTextureAnisotropy=%f",
mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel, mMaxTextureAnisotropy);
- const D3DFORMAT renderBufferFormats[] =
- {
- D3DFMT_A8R8G8B8,
- D3DFMT_X8R8G8B8,
- D3DFMT_R5G6B5,
- D3DFMT_D24S8
- };
-
- int max = 0;
- for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
- {
- bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
- mDisplay->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
- mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
-
- for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
- {
- if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
- {
- max = j;
- }
- }
- }
-
- mMaxSupportedSamples = max;
-
- mSupportsEventQueries = mDisplay->getEventQuerySupport();
- mSupportsOcclusionQueries = mDisplay->getOcclusionQuerySupport();
- mSupportsDXT1Textures = mDisplay->getDXT1TextureSupport();
- mSupportsDXT3Textures = mDisplay->getDXT3TextureSupport();
- mSupportsDXT5Textures = mDisplay->getDXT5TextureSupport();
- mSupportsFloat32Textures = mDisplay->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
- mSupportsFloat16Textures = mDisplay->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
- mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport();
- mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport();
- mSupportsDepthTextures = mDisplay->getDepthTextureSupport();
- mSupportsTextureFilterAnisotropy = mMaxTextureAnisotropy >= 2.0f;
-
- mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
+ mSupportsEventQueries = mRenderer->getEventQuerySupport();
+ mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
+ mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
+ mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
+ mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
+ mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
+ mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures);
+ mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures);
+ mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
+ mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
+ mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
+ mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
+ mSupports32bitIndices = mRenderer->get32BitIndexSupport();
mNumCompressedTextureFormats = 0;
if (supportsDXT1Textures())
@@ -337,89 +292,30 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
initExtensionString();
initRendererString();
- mState.viewportX = 0;
- mState.viewportY = 0;
- mState.viewportWidth = surface->getWidth();
- mState.viewportHeight = surface->getHeight();
+ mState.viewport.x = 0;
+ mState.viewport.y = 0;
+ mState.viewport.width = surface->getWidth();
+ mState.viewport.height = surface->getHeight();
- mState.scissorX = 0;
- mState.scissorY = 0;
- mState.scissorWidth = surface->getWidth();
- mState.scissorHeight = surface->getHeight();
+ mState.scissor.x = 0;
+ mState.scissor.y = 0;
+ mState.scissor.width = surface->getWidth();
+ mState.scissor.height = surface->getHeight();
mHasBeenCurrent = true;
}
- // Wrap the existing Direct3D 9 resources into GL objects and assign them to the '0' names
- IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
- IDirect3DSurface9 *depthStencil = surface->getDepthStencil();
+ // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
+ rx::SwapChain *swapchain = surface->getSwapChain();
- Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
- DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
- Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
+ Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
+ DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
+ Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
-
- if (defaultRenderTarget)
- {
- defaultRenderTarget->Release();
- }
-
- if (depthStencil)
- {
- depthStencil->Release();
- }
-
- // Reset pixel shader to null to work around a bug that only happens with Intel GPUs.
- // http://crbug.com/110343
- mDevice->SetPixelShader(NULL);
-
- markAllStateDirty();
-}
-
-// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
-void Context::markAllStateDirty()
-{
- for (int t = 0; t < MAX_TEXTURE_IMAGE_UNITS; t++)
- {
- mAppliedTextureSerialPS[t] = 0;
- }
-
- for (int t = 0; t < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; t++)
- {
- mAppliedTextureSerialVS[t] = 0;
- }
-
- mAppliedProgramBinarySerial = 0;
- mAppliedRenderTargetSerial = 0;
- mAppliedDepthbufferSerial = 0;
- mAppliedStencilbufferSerial = 0;
- mAppliedIBSerial = 0;
- mDepthStencilInitialized = false;
- mViewportInitialized = false;
- mRenderTargetDescInitialized = false;
-
- mVertexDeclarationCache.markStateDirty();
-
- mClearStateDirty = true;
- mCullStateDirty = true;
- mDepthStateDirty = true;
- mMaskStateDirty = true;
- mBlendStateDirty = true;
- mStencilStateDirty = true;
- mPolygonOffsetStateDirty = true;
- mScissorStateDirty = true;
- mSampleStateDirty = true;
- mDitherStateDirty = true;
- mFrontFaceDirty = true;
- mDxUniformsDirty = true;
-}
-
-void Context::markDxUniformsDirty()
-{
- mDxUniformsDirty = true;
}
+// NOTE: this function should not assume that this context is current!
void Context::markContextLost()
{
if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
@@ -452,57 +348,37 @@ void Context::setClearStencil(int stencil)
void Context::setCullFace(bool enabled)
{
- if (mState.cullFace != enabled)
- {
- mState.cullFace = enabled;
- mCullStateDirty = true;
- }
+ mState.rasterizer.cullFace = enabled;
}
bool Context::isCullFaceEnabled() const
{
- return mState.cullFace;
+ return mState.rasterizer.cullFace;
}
void Context::setCullMode(GLenum mode)
{
- if (mState.cullMode != mode)
- {
- mState.cullMode = mode;
- mCullStateDirty = true;
- }
+ mState.rasterizer.cullMode = mode;
}
void Context::setFrontFace(GLenum front)
{
- if (mState.frontFace != front)
- {
- mState.frontFace = front;
- mFrontFaceDirty = true;
- }
+ mState.rasterizer.frontFace = front;
}
void Context::setDepthTest(bool enabled)
{
- if (mState.depthTest != enabled)
- {
- mState.depthTest = enabled;
- mDepthStateDirty = true;
- }
+ mState.depthStencil.depthTest = enabled;
}
bool Context::isDepthTestEnabled() const
{
- return mState.depthTest;
+ return mState.depthStencil.depthTest;
}
void Context::setDepthFunc(GLenum depthFunc)
{
- if (mState.depthFunc != depthFunc)
- {
- mState.depthFunc = depthFunc;
- mDepthStateDirty = true;
- }
+ mState.depthStencil.depthFunc = depthFunc;
}
void Context::setDepthRange(float zNear, float zFar)
@@ -513,190 +389,114 @@ void Context::setDepthRange(float zNear, float zFar)
void Context::setBlend(bool enabled)
{
- if (mState.blend != enabled)
- {
- mState.blend = enabled;
- mBlendStateDirty = true;
- }
+ mState.blend.blend = enabled;
}
bool Context::isBlendEnabled() const
{
- return mState.blend;
+ return mState.blend.blend;
}
void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
{
- if (mState.sourceBlendRGB != sourceRGB ||
- mState.sourceBlendAlpha != sourceAlpha ||
- mState.destBlendRGB != destRGB ||
- mState.destBlendAlpha != destAlpha)
- {
- mState.sourceBlendRGB = sourceRGB;
- mState.destBlendRGB = destRGB;
- mState.sourceBlendAlpha = sourceAlpha;
- mState.destBlendAlpha = destAlpha;
- mBlendStateDirty = true;
- }
+ mState.blend.sourceBlendRGB = sourceRGB;
+ mState.blend.destBlendRGB = destRGB;
+ mState.blend.sourceBlendAlpha = sourceAlpha;
+ mState.blend.destBlendAlpha = destAlpha;
}
void Context::setBlendColor(float red, float green, float blue, float alpha)
{
- if (mState.blendColor.red != red ||
- mState.blendColor.green != green ||
- mState.blendColor.blue != blue ||
- mState.blendColor.alpha != alpha)
- {
- mState.blendColor.red = red;
- mState.blendColor.green = green;
- mState.blendColor.blue = blue;
- mState.blendColor.alpha = alpha;
- mBlendStateDirty = true;
- }
+ mState.blendColor.red = red;
+ mState.blendColor.green = green;
+ mState.blendColor.blue = blue;
+ mState.blendColor.alpha = alpha;
}
void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
{
- if (mState.blendEquationRGB != rgbEquation ||
- mState.blendEquationAlpha != alphaEquation)
- {
- mState.blendEquationRGB = rgbEquation;
- mState.blendEquationAlpha = alphaEquation;
- mBlendStateDirty = true;
- }
+ mState.blend.blendEquationRGB = rgbEquation;
+ mState.blend.blendEquationAlpha = alphaEquation;
}
void Context::setStencilTest(bool enabled)
{
- if (mState.stencilTest != enabled)
- {
- mState.stencilTest = enabled;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilTest = enabled;
}
bool Context::isStencilTestEnabled() const
{
- return mState.stencilTest;
+ return mState.depthStencil.stencilTest;
}
void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
{
- if (mState.stencilFunc != stencilFunc ||
- mState.stencilRef != stencilRef ||
- mState.stencilMask != stencilMask)
- {
- mState.stencilFunc = stencilFunc;
- mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
- mState.stencilMask = stencilMask;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilFunc = stencilFunc;
+ mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
+ mState.depthStencil.stencilMask = stencilMask;
}
void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
{
- if (mState.stencilBackFunc != stencilBackFunc ||
- mState.stencilBackRef != stencilBackRef ||
- mState.stencilBackMask != stencilBackMask)
- {
- mState.stencilBackFunc = stencilBackFunc;
- mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
- mState.stencilBackMask = stencilBackMask;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilBackFunc = stencilBackFunc;
+ mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
+ mState.depthStencil.stencilBackMask = stencilBackMask;
}
void Context::setStencilWritemask(GLuint stencilWritemask)
{
- if (mState.stencilWritemask != stencilWritemask)
- {
- mState.stencilWritemask = stencilWritemask;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilWritemask = stencilWritemask;
}
void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
{
- if (mState.stencilBackWritemask != stencilBackWritemask)
- {
- mState.stencilBackWritemask = stencilBackWritemask;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
}
void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
{
- if (mState.stencilFail != stencilFail ||
- mState.stencilPassDepthFail != stencilPassDepthFail ||
- mState.stencilPassDepthPass != stencilPassDepthPass)
- {
- mState.stencilFail = stencilFail;
- mState.stencilPassDepthFail = stencilPassDepthFail;
- mState.stencilPassDepthPass = stencilPassDepthPass;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilFail = stencilFail;
+ mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
+ mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
}
void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
{
- if (mState.stencilBackFail != stencilBackFail ||
- mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
- mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
- {
- mState.stencilBackFail = stencilBackFail;
- mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
- mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
- mStencilStateDirty = true;
- }
+ mState.depthStencil.stencilBackFail = stencilBackFail;
+ mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
+ mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
}
void Context::setPolygonOffsetFill(bool enabled)
{
- if (mState.polygonOffsetFill != enabled)
- {
- mState.polygonOffsetFill = enabled;
- mPolygonOffsetStateDirty = true;
- }
+ mState.rasterizer.polygonOffsetFill = enabled;
}
bool Context::isPolygonOffsetFillEnabled() const
{
- return mState.polygonOffsetFill;
-
+ return mState.rasterizer.polygonOffsetFill;
}
void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
{
- if (mState.polygonOffsetFactor != factor ||
- mState.polygonOffsetUnits != units)
- {
- mState.polygonOffsetFactor = factor;
- mState.polygonOffsetUnits = units;
- mPolygonOffsetStateDirty = true;
- }
+ // An application can pass NaN values here, so handle this gracefully
+ mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
+ mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
}
void Context::setSampleAlphaToCoverage(bool enabled)
{
- if (mState.sampleAlphaToCoverage != enabled)
- {
- mState.sampleAlphaToCoverage = enabled;
- mSampleStateDirty = true;
- }
+ mState.blend.sampleAlphaToCoverage = enabled;
}
bool Context::isSampleAlphaToCoverageEnabled() const
{
- return mState.sampleAlphaToCoverage;
+ return mState.blend.sampleAlphaToCoverage;
}
void Context::setSampleCoverage(bool enabled)
{
- if (mState.sampleCoverage != enabled)
- {
- mState.sampleCoverage = enabled;
- mSampleStateDirty = true;
- }
+ mState.sampleCoverage = enabled;
}
bool Context::isSampleCoverageEnabled() const
@@ -706,22 +506,13 @@ bool Context::isSampleCoverageEnabled() const
void Context::setSampleCoverageParams(GLclampf value, bool invert)
{
- if (mState.sampleCoverageValue != value ||
- mState.sampleCoverageInvert != invert)
- {
- mState.sampleCoverageValue = value;
- mState.sampleCoverageInvert = invert;
- mSampleStateDirty = true;
- }
+ mState.sampleCoverageValue = value;
+ mState.sampleCoverageInvert = invert;
}
void Context::setScissorTest(bool enabled)
{
- if (mState.scissorTest != enabled)
- {
- mState.scissorTest = enabled;
- mScissorStateDirty = true;
- }
+ mState.scissorTest = enabled;
}
bool Context::isScissorTestEnabled() const
@@ -731,16 +522,12 @@ bool Context::isScissorTestEnabled() const
void Context::setDither(bool enabled)
{
- if (mState.dither != enabled)
- {
- mState.dither = enabled;
- mDitherStateDirty = true;
- }
+ mState.blend.dither = enabled;
}
bool Context::isDitherEnabled() const
{
- return mState.dither;
+ return mState.blend.dither;
}
void Context::setLineWidth(GLfloat width)
@@ -763,45 +550,31 @@ void Context::setFragmentShaderDerivativeHint(GLenum hint)
void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
{
- mState.viewportX = x;
- mState.viewportY = y;
- mState.viewportWidth = width;
- mState.viewportHeight = height;
+ mState.viewport.x = x;
+ mState.viewport.y = y;
+ mState.viewport.width = width;
+ mState.viewport.height = height;
}
void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
{
- if (mState.scissorX != x || mState.scissorY != y ||
- mState.scissorWidth != width || mState.scissorHeight != height)
- {
- mState.scissorX = x;
- mState.scissorY = y;
- mState.scissorWidth = width;
- mState.scissorHeight = height;
- mScissorStateDirty = true;
- }
+ mState.scissor.x = x;
+ mState.scissor.y = y;
+ mState.scissor.width = width;
+ mState.scissor.height = height;
}
void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
{
- if (mState.colorMaskRed != red || mState.colorMaskGreen != green ||
- mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
- {
- mState.colorMaskRed = red;
- mState.colorMaskGreen = green;
- mState.colorMaskBlue = blue;
- mState.colorMaskAlpha = alpha;
- mMaskStateDirty = true;
- }
+ mState.blend.colorMaskRed = red;
+ mState.blend.colorMaskGreen = green;
+ mState.blend.colorMaskBlue = blue;
+ mState.blend.colorMaskAlpha = alpha;
}
void Context::setDepthMask(bool mask)
{
- if (mState.depthMask != mask)
- {
- mState.depthMask = mask;
- mMaskStateDirty = true;
- }
+ mState.depthStencil.depthMask = mask;
}
void Context::setActiveSampler(unsigned int active)
@@ -881,11 +654,6 @@ const void *Context::getVertexAttribPointer(unsigned int attribNum) const
return mState.vertexAttribute[attribNum].mPointer;
}
-const VertexAttributeArray &Context::getVertexAttributes()
-{
- return mState.vertexAttribute;
-}
-
void Context::setPackAlignment(GLint alignment)
{
mState.packAlignment = alignment;
@@ -955,7 +723,7 @@ GLuint Context::createFence()
{
GLuint handle = mFenceHandleAllocator.allocate();
- mFenceMap[handle] = new Fence(mDisplay);
+ mFenceMap[handle] = new Fence(mRenderer);
return handle;
}
@@ -1117,7 +885,7 @@ void Context::bindReadFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer();
+ mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
}
mState.readFramebuffer = framebuffer;
@@ -1127,7 +895,7 @@ void Context::bindDrawFramebuffer(GLuint framebuffer)
{
if (!getFramebuffer(framebuffer))
{
- mFramebufferMap[framebuffer] = new Framebuffer();
+ mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
}
mState.drawFramebuffer = framebuffer;
@@ -1152,7 +920,6 @@ void Context::useProgram(GLuint program)
Program *newProgram = mResourceManager->getProgram(program);
Program *oldProgram = mResourceManager->getProgram(priorProgram);
mCurrentProgramBinary.set(NULL);
- mDxUniformsDirty = true;
if (newProgram)
{
@@ -1178,7 +945,6 @@ void Context::linkProgram(GLuint program)
if (linked && program == mState.currentProgram)
{
mCurrentProgramBinary.set(programObject->getProgramBinary());
- mDxUniformsDirty = true;
}
}
@@ -1193,7 +959,6 @@ void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
if (loaded && program == mState.currentProgram)
{
mCurrentProgramBinary.set(programObject->getProgramBinary());
- mDxUniformsDirty = true;
}
}
@@ -1219,7 +984,7 @@ void Context::beginQuery(GLenum target, GLuint query)
{
if (mState.activeQuery[i].get() != NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
@@ -1242,13 +1007,13 @@ void Context::beginQuery(GLenum target, GLuint query)
// check that name was obtained with glGenQueries
if (!queryObject)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// check for type mismatch
if (queryObject->getType() != target)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// set query as active for specified target
@@ -1279,7 +1044,7 @@ void Context::endQuery(GLenum target)
if (queryObject == NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
queryObject->end();
@@ -1297,8 +1062,31 @@ void Context::setFramebufferZero(Framebuffer *buffer)
}
}
-void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
{
+ RenderbufferStorage *renderbuffer = NULL;
+ switch (internalformat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
+ break;
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
+ break;
+ case GL_STENCIL_INDEX8:
+ renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
+ break;
+ case GL_DEPTH24_STENCIL8_OES:
+ renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
+ break;
+ default:
+ UNREACHABLE(); return;
+ }
+
Renderbuffer *renderbufferObject = mState.renderbuffer.get();
renderbufferObject->setStorage(renderbuffer);
}
@@ -1343,7 +1131,7 @@ Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
{
if (!query->second && create)
{
- query->second = new Query(handle, type);
+ query->second = new Query(mRenderer, type, handle);
query->second->addRef();
}
return query->second;
@@ -1396,25 +1184,25 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params)
{
switch (pname)
{
- case GL_SHADER_COMPILER: *params = GL_TRUE; break;
- case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
- case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break;
+ case GL_SHADER_COMPILER: *params = GL_TRUE; break;
+ case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break;
+ case GL_DEPTH_WRITEMASK: *params = mState.depthStencil.depthMask; break;
case GL_COLOR_WRITEMASK:
- params[0] = mState.colorMaskRed;
- params[1] = mState.colorMaskGreen;
- params[2] = mState.colorMaskBlue;
- params[3] = mState.colorMaskAlpha;
+ params[0] = mState.blend.colorMaskRed;
+ params[1] = mState.blend.colorMaskGreen;
+ params[2] = mState.blend.colorMaskBlue;
+ params[3] = mState.blend.colorMaskAlpha;
break;
- case GL_CULL_FACE: *params = mState.cullFace; break;
- case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break;
- case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break;
- case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
- case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
- case GL_STENCIL_TEST: *params = mState.stencilTest; break;
- case GL_DEPTH_TEST: *params = mState.depthTest; break;
- case GL_BLEND: *params = mState.blend; break;
- case GL_DITHER: *params = mState.dither; break;
- case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
+ case GL_CULL_FACE: *params = mState.rasterizer.cullFace; break;
+ case GL_POLYGON_OFFSET_FILL: *params = mState.rasterizer.polygonOffsetFill; break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.blend.sampleAlphaToCoverage; break;
+ case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break;
+ case GL_SCISSOR_TEST: *params = mState.scissorTest; break;
+ case GL_STENCIL_TEST: *params = mState.depthStencil.stencilTest; break;
+ case GL_DEPTH_TEST: *params = mState.depthStencil.depthTest; break;
+ case GL_BLEND: *params = mState.blend.blend; break;
+ case GL_DITHER: *params = mState.blend.dither; break;
+ case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break;
default:
return false;
}
@@ -1430,11 +1218,11 @@ bool Context::getFloatv(GLenum pname, GLfloat *params)
// case, this should make no difference to the calling application.
switch (pname)
{
- case GL_LINE_WIDTH: *params = mState.lineWidth; break;
- case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
- case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
- case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break;
- case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break;
+ case GL_LINE_WIDTH: *params = mState.lineWidth; break;
+ case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break;
+ case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break;
+ case GL_POLYGON_OFFSET_FACTOR: *params = mState.rasterizer.polygonOffsetFactor; break;
+ case GL_POLYGON_OFFSET_UNITS: *params = mState.rasterizer.polygonOffsetUnits; break;
case GL_ALIASED_LINE_WIDTH_RANGE:
params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
@@ -1475,6 +1263,22 @@ bool Context::getFloatv(GLenum pname, GLfloat *params)
bool Context::getIntegerv(GLenum pname, GLint *params)
{
+ if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ {
+ unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
+
+ if (colorAttachment >= mRenderer->getMaxRenderTargets())
+ {
+ // return true to stop further operation in the parent call
+ return gl::error(GL_INVALID_OPERATION, true);
+ }
+
+ Framebuffer *framebuffer = getDrawFramebuffer();
+
+ *params = framebuffer->getDrawBufferState(colorAttachment);
+ return true;
+ }
+
// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
// GetIntegerv as its native query function. As it would require conversion in any
@@ -1483,13 +1287,15 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
switch (pname)
{
case GL_MAX_VERTEX_ATTRIBS: *params = gl::MAX_VERTEX_ATTRIBS; break;
- case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = gl::MAX_VERTEX_UNIFORM_VECTORS; break;
- case GL_MAX_VARYING_VECTORS: *params = getMaximumVaryingVectors(); break;
- case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = getMaximumCombinedTextureImageUnits(); break;
- case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = getMaximumVertexTextureImageUnits(); break;
+ case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = mRenderer->getMaxVertexUniformVectors(); break;
+ case GL_MAX_VARYING_VECTORS: *params = mRenderer->getMaxVaryingVectors(); break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxCombinedTextureImageUnits(); break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = mRenderer->getMaxVertexTextureImageUnits(); break;
case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = getMaximumFragmentUniformVectors(); break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = mRenderer->getMaxFragmentUniformVectors(); break;
case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
+ case GL_MAX_DRAW_BUFFERS_EXT: *params = mRenderer->getMaxRenderTargets(); break;
case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
@@ -1505,27 +1311,27 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break;
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break;
- case GL_STENCIL_FUNC: *params = mState.stencilFunc; break;
- case GL_STENCIL_REF: *params = mState.stencilRef; break;
- case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break;
- case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break;
- case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
- case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break;
- case GL_STENCIL_FAIL: *params = mState.stencilFail; break;
- case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break;
- case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break;
- case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break;
- case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break;
- case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break;
- case GL_DEPTH_FUNC: *params = mState.depthFunc; break;
- case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break;
- case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break;
- case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break;
- case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break;
- case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break;
- case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break;
- case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break;
- case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break;
+ case GL_STENCIL_FUNC: *params = mState.depthStencil.stencilFunc; break;
+ case GL_STENCIL_REF: *params = mState.stencilRef; break;
+ case GL_STENCIL_VALUE_MASK: *params = mState.depthStencil.stencilMask; break;
+ case GL_STENCIL_BACK_FUNC: *params = mState.depthStencil.stencilBackFunc; break;
+ case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break;
+ case GL_STENCIL_BACK_VALUE_MASK: *params = mState.depthStencil.stencilBackMask; break;
+ case GL_STENCIL_FAIL: *params = mState.depthStencil.stencilFail; break;
+ case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilPassDepthFail; break;
+ case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilPassDepthPass; break;
+ case GL_STENCIL_BACK_FAIL: *params = mState.depthStencil.stencilBackFail; break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.depthStencil.stencilBackPassDepthFail; break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.depthStencil.stencilBackPassDepthPass; break;
+ case GL_DEPTH_FUNC: *params = mState.depthStencil.depthFunc; break;
+ case GL_BLEND_SRC_RGB: *params = mState.blend.sourceBlendRGB; break;
+ case GL_BLEND_SRC_ALPHA: *params = mState.blend.sourceBlendAlpha; break;
+ case GL_BLEND_DST_RGB: *params = mState.blend.destBlendRGB; break;
+ case GL_BLEND_DST_ALPHA: *params = mState.blend.destBlendAlpha; break;
+ case GL_BLEND_EQUATION_RGB: *params = mState.blend.blendEquationRGB; break;
+ case GL_BLEND_EQUATION_ALPHA: *params = mState.blend.blendEquationAlpha; break;
+ case GL_STENCIL_WRITEMASK: *params = mState.depthStencil.stencilWritemask; break;
+ case GL_STENCIL_BACK_WRITEMASK: *params = mState.depthStencil.stencilBackWritemask; break;
case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = getMaximumTextureDimension(); break;
@@ -1591,9 +1397,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_MAX_VIEWPORT_DIMS:
{
- int maxDimension = std::max(getMaximumRenderbufferDimension(), getMaximumTextureDimension());
- params[0] = maxDimension;
- params[1] = maxDimension;
+ params[0] = mMaxViewportDimension;
+ params[1] = mMaxViewportDimension;
}
break;
case GL_COMPRESSED_TEXTURE_FORMATS:
@@ -1614,35 +1419,35 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
}
break;
case GL_VIEWPORT:
- params[0] = mState.viewportX;
- params[1] = mState.viewportY;
- params[2] = mState.viewportWidth;
- params[3] = mState.viewportHeight;
+ params[0] = mState.viewport.x;
+ params[1] = mState.viewport.y;
+ params[2] = mState.viewport.width;
+ params[3] = mState.viewport.height;
break;
case GL_SCISSOR_BOX:
- params[0] = mState.scissorX;
- params[1] = mState.scissorY;
- params[2] = mState.scissorWidth;
- params[3] = mState.scissorHeight;
+ params[0] = mState.scissor.x;
+ params[1] = mState.scissor.y;
+ params[2] = mState.scissor.width;
+ params[3] = mState.scissor.height;
break;
- case GL_CULL_FACE_MODE: *params = mState.cullMode; break;
- case GL_FRONT_FACE: *params = mState.frontFace; break;
+ case GL_CULL_FACE_MODE: *params = mState.rasterizer.cullMode; break;
+ case GL_FRONT_FACE: *params = mState.rasterizer.frontFace; break;
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
{
gl::Framebuffer *framebuffer = getDrawFramebuffer();
- gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
+ gl::Renderbuffer *colorbuffer = framebuffer->getFirstColorbuffer();
if (colorbuffer)
{
switch (pname)
{
- case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
- case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
- case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
- case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
+ case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
+ case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
+ case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
+ case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
}
}
else
@@ -1683,9 +1488,9 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_TEXTURE_BINDING_2D:
{
- if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1)
+ if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
{
- error(GL_INVALID_OPERATION);
+ gl::error(GL_INVALID_OPERATION);
return false;
}
@@ -1694,9 +1499,9 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
{
- if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1)
+ if (mState.activeSampler > mRenderer->getMaxCombinedTextureImageUnits() - 1)
{
- error(GL_INVALID_OPERATION);
+ gl::error(GL_INVALID_OPERATION);
return false;
}
@@ -1721,6 +1526,13 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
{
+ if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ return true;
+ }
+
// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
// to the fact that it is stored internally as a float, and so would require conversion
@@ -1750,6 +1562,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_MAX_TEXTURE_IMAGE_UNITS:
case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
case GL_MAX_RENDERBUFFER_SIZE:
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ case GL_MAX_DRAW_BUFFERS_EXT:
case GL_NUM_SHADER_BINARY_FORMATS:
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
case GL_ARRAY_BUFFER_BINDING:
@@ -1901,186 +1715,25 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
}
// Applies the render target surface, depth stencil surface, viewport rectangle and
-// scissor rectangle to the Direct3D 9 device
-bool Context::applyRenderTarget(bool ignoreViewport)
+// scissor rectangle to the renderer
+bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
{
Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
}
- // if there is no color attachment we must synthesize a NULL colorattachment
- // to keep the D3D runtime happy. This should only be possible if depth texturing.
- Renderbuffer *renderbufferObject = NULL;
- if (framebufferObject->getColorbufferType() != GL_NONE)
- {
- renderbufferObject = framebufferObject->getColorbuffer();
- }
- else
- {
- renderbufferObject = framebufferObject->getNullColorbuffer();
- }
- if (!renderbufferObject)
- {
- ERR("unable to locate renderbuffer for FBO.");
- return false;
- }
-
- bool renderTargetChanged = false;
- unsigned int renderTargetSerial = renderbufferObject->getSerial();
- if (renderTargetSerial != mAppliedRenderTargetSerial)
- {
- IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget();
- if (!renderTarget)
- {
- ERR("render target pointer unexpectedly null.");
- return false; // Context must be lost
- }
- mDevice->SetRenderTarget(0, renderTarget);
- mAppliedRenderTargetSerial = renderTargetSerial;
- mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
- renderTargetChanged = true;
- renderTarget->Release();
- }
-
- IDirect3DSurface9 *depthStencil = NULL;
- unsigned int depthbufferSerial = 0;
- unsigned int stencilbufferSerial = 0;
- if (framebufferObject->getDepthbufferType() != GL_NONE)
- {
- Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer();
- depthStencil = depthbuffer->getDepthStencil();
- if (!depthStencil)
- {
- ERR("Depth stencil pointer unexpectedly null.");
- return false;
- }
-
- depthbufferSerial = depthbuffer->getSerial();
- }
- else if (framebufferObject->getStencilbufferType() != GL_NONE)
- {
- Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
- depthStencil = stencilbuffer->getDepthStencil();
- if (!depthStencil)
- {
- ERR("Depth stencil pointer unexpectedly null.");
- return false;
- }
-
- stencilbufferSerial = stencilbuffer->getSerial();
- }
-
- if (depthbufferSerial != mAppliedDepthbufferSerial ||
- stencilbufferSerial != mAppliedStencilbufferSerial ||
- !mDepthStencilInitialized)
- {
- mDevice->SetDepthStencilSurface(depthStencil);
- mAppliedDepthbufferSerial = depthbufferSerial;
- mAppliedStencilbufferSerial = stencilbufferSerial;
- mDepthStencilInitialized = true;
- }
-
- if (depthStencil)
- {
- depthStencil->Release();
- }
-
- if (!mRenderTargetDescInitialized || renderTargetChanged)
- {
- IDirect3DSurface9 *renderTarget = renderbufferObject->getRenderTarget();
- if (!renderTarget)
- {
- return false; // Context must be lost
- }
- renderTarget->GetDesc(&mRenderTargetDesc);
- mRenderTargetDescInitialized = true;
- renderTarget->Release();
- }
-
- D3DVIEWPORT9 viewport;
-
- float zNear = clamp01(mState.zNear);
- float zFar = clamp01(mState.zFar);
-
- if (ignoreViewport)
- {
- viewport.X = 0;
- viewport.Y = 0;
- viewport.Width = mRenderTargetDesc.Width;
- viewport.Height = mRenderTargetDesc.Height;
- viewport.MinZ = 0.0f;
- viewport.MaxZ = 1.0f;
- }
- else
- {
- viewport.X = clamp(mState.viewportX, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
- viewport.Y = clamp(mState.viewportY, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
- viewport.Width = clamp(mState.viewportWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X));
- viewport.Height = clamp(mState.viewportHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y));
- viewport.MinZ = zNear;
- viewport.MaxZ = zFar;
- }
-
- if (viewport.Width <= 0 || viewport.Height <= 0)
- {
- return false; // Nothing to render
- }
+ mRenderer->applyRenderTarget(framebufferObject);
- if (renderTargetChanged || !mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0)
+ if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
+ ignoreViewport))
{
- mDevice->SetViewport(&viewport);
- mSetViewport = viewport;
- mViewportInitialized = true;
- mDxUniformsDirty = true;
- }
-
- if (mScissorStateDirty)
- {
- if (mState.scissorTest)
- {
- RECT rect;
- rect.left = clamp(mState.scissorX, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
- rect.top = clamp(mState.scissorY, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
- rect.right = clamp(mState.scissorX + mState.scissorWidth, 0L, static_cast<LONG>(mRenderTargetDesc.Width));
- rect.bottom = clamp(mState.scissorY + mState.scissorHeight, 0L, static_cast<LONG>(mRenderTargetDesc.Height));
- mDevice->SetScissorRect(&rect);
- mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
- }
- else
- {
- mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
- }
-
- mScissorStateDirty = false;
+ return false;
}
- if (mState.currentProgram && mDxUniformsDirty)
- {
- ProgramBinary *programBinary = getCurrentProgramBinary();
-
- GLint halfPixelSize = programBinary->getDxHalfPixelSizeLocation();
- GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height};
- programBinary->setUniform2fv(halfPixelSize, 1, xy);
-
- // These values are used for computing gl_FragCoord in Program::linkVaryings().
- GLint coord = programBinary->getDxCoordLocation();
- GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f,
- (float)mState.viewportX + mState.viewportWidth / 2.0f,
- (float)mState.viewportY + mState.viewportHeight / 2.0f};
- programBinary->setUniform4fv(coord, 1, whxy);
-
- GLint depth = programBinary->getDxDepthLocation();
- GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
- programBinary->setUniform2fv(depth, 1, dz);
-
- GLint depthRange = programBinary->getDxDepthRangeLocation();
- GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
- programBinary->setUniform3fv(depthRange, 1, nearFarDiff);
- mDxUniformsDirty = false;
- }
+ mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
return true;
}
@@ -2088,290 +1741,42 @@ bool Context::applyRenderTarget(bool ignoreViewport)
// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
void Context::applyState(GLenum drawMode)
{
- ProgramBinary *programBinary = getCurrentProgramBinary();
-
- Framebuffer *framebufferObject = getDrawFramebuffer();
+ mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
+ mRenderer->setRasterizerState(mState.rasterizer);
- GLint frontCCW = programBinary->getDxFrontCCWLocation();
- GLint ccw = (mState.frontFace == GL_CCW);
- programBinary->setUniform1iv(frontCCW, 1, &ccw);
-
- GLint pointsOrLines = programBinary->getDxPointsOrLinesLocation();
- GLint alwaysFront = !isTriangleMode(drawMode);
- programBinary->setUniform1iv(pointsOrLines, 1, &alwaysFront);
-
- D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
- bool zeroColorMaskAllowed = identifier->VendorId != 0x1002;
- // Apparently some ATI cards have a bug where a draw with a zero color
- // write mask can cause later draws to have incorrect results. Instead,
- // set a nonzero color write mask but modify the blend state so that no
- // drawing is done.
- // http://code.google.com/p/angleproject/issues/detail?id=169
-
- if (mCullStateDirty || mFrontFaceDirty)
+ unsigned int mask = 0;
+ if (mState.sampleCoverage)
{
- if (mState.cullFace)
- {
- mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace));
- }
- else
+ if (mState.sampleCoverageValue != 0)
{
- mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- }
-
- mCullStateDirty = false;
- }
+ Framebuffer *framebufferObject = getDrawFramebuffer();
+ float threshold = 0.5f;
- if (mDepthStateDirty)
- {
- if (mState.depthTest)
- {
- mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
- mDevice->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
- }
- else
- {
- mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
- }
-
- mDepthStateDirty = false;
- }
-
- if (!zeroColorMaskAllowed && (mMaskStateDirty || mBlendStateDirty))
- {
- mBlendStateDirty = true;
- mMaskStateDirty = true;
- }
-
- if (mBlendStateDirty)
- {
- if (mState.blend)
- {
- mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
-
- if (mState.sourceBlendRGB != GL_CONSTANT_ALPHA && mState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
- mState.destBlendRGB != GL_CONSTANT_ALPHA && mState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+ for (int i = 0; i < framebufferObject->getSamples(); ++i)
{
- mDevice->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor));
- }
- else
- {
- mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha),
- unorm<8>(mState.blendColor.alpha),
- unorm<8>(mState.blendColor.alpha),
- unorm<8>(mState.blendColor.alpha)));
- }
-
- mDevice->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB));
- mDevice->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB));
- mDevice->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB));
-
- if (mState.sourceBlendRGB != mState.sourceBlendAlpha ||
- mState.destBlendRGB != mState.destBlendAlpha ||
- mState.blendEquationRGB != mState.blendEquationAlpha)
- {
- mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+ mask <<= 1;
- mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha));
- mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha));
- mDevice->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha));
- }
- else
- {
- mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
- }
- }
- else
- {
- mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
- }
-
- mBlendStateDirty = false;
- }
-
- if (mStencilStateDirty || mFrontFaceDirty)
- {
- if (mState.stencilTest && framebufferObject->hasStencil())
- {
- mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
- mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
-
- // FIXME: Unsupported by D3D9
- const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
- const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
- const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
- if (mState.stencilWritemask != mState.stencilBackWritemask ||
- mState.stencilRef != mState.stencilBackRef ||
- mState.stencilMask != mState.stencilBackMask)
- {
- ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
- return error(GL_INVALID_OPERATION);
- }
-
- // get the maximum size of the stencil ref
- gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
- GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
-
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
- es2dx::ConvertComparison(mState.stencilFunc));
-
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask);
-
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
- es2dx::ConvertStencilOp(mState.stencilFail));
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
- es2dx::ConvertStencilOp(mState.stencilPassDepthFail));
- mDevice->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
- es2dx::ConvertStencilOp(mState.stencilPassDepthPass));
-
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask);
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
- es2dx::ConvertComparison(mState.stencilBackFunc));
-
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask);
-
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
- es2dx::ConvertStencilOp(mState.stencilBackFail));
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
- es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail));
- mDevice->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
- es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass));
- }
- else
- {
- mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- }
-
- mStencilStateDirty = false;
- mFrontFaceDirty = false;
- }
-
- if (mMaskStateDirty)
- {
- int colorMask = es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen,
- mState.colorMaskBlue, mState.colorMaskAlpha);
- if (colorMask == 0 && !zeroColorMaskAllowed)
- {
- // Enable green channel, but set blending so nothing will be drawn.
- mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
- mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
-
- mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
- mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
- mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
- }
- else
- {
- mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
- }
- mDevice->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE);
-
- mMaskStateDirty = false;
- }
-
- if (mPolygonOffsetStateDirty)
- {
- if (mState.polygonOffsetFill)
- {
- gl::Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer();
- if (depthbuffer)
- {
- mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
- float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
- mDevice->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias));
- }
- }
- else
- {
- mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
- mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
- }
-
- mPolygonOffsetStateDirty = false;
- }
-
- if (mSampleStateDirty)
- {
- if (mState.sampleAlphaToCoverage)
- {
- FIXME("Sample alpha to coverage is unimplemented.");
- }
-
- mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
- if (mState.sampleCoverage)
- {
- unsigned int mask = 0;
- if (mState.sampleCoverageValue != 0)
- {
- float threshold = 0.5f;
-
- for (int i = 0; i < framebufferObject->getSamples(); ++i)
+ if ((i + 1) * mState.sampleCoverageValue >= threshold)
{
- mask <<= 1;
-
- if ((i + 1) * mState.sampleCoverageValue >= threshold)
- {
- threshold += 1.0f;
- mask |= 1;
- }
+ threshold += 1.0f;
+ mask |= 1;
}
}
-
- if (mState.sampleCoverageInvert)
- {
- mask = ~mask;
- }
-
- mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
}
- else
+
+ if (mState.sampleCoverageInvert)
{
- mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+ mask = ~mask;
}
-
- mSampleStateDirty = false;
- }
-
- if (mDitherStateDirty)
- {
- mDevice->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE);
-
- mDitherStateDirty = false;
}
-}
-
-GLenum Context::applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw)
-{
- TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
-
- GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instances);
- if (err != GL_NO_ERROR)
- {
- return err;
- }
-
- ProgramBinary *programBinary = getCurrentProgramBinary();
- return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, repeatDraw);
-}
-
-// Applies the indices and element array bindings to the Direct3D 9 device
-GLenum Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
-{
- GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
-
- if (err == GL_NO_ERROR)
+ else
{
- if (indexInfo->serial != mAppliedIBSerial)
- {
- mDevice->SetIndices(indexInfo->indexBuffer);
- mAppliedIBSerial = indexInfo->serial;
- }
+ mask = 0xFFFFFFFF;
}
+ mRenderer->setBlendState(mState.blend, mState.blendColor, mask);
- return err;
+ mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
+ mState.rasterizer.frontFace == GL_CCW);
}
// Applies the shaders and shader constants to the Direct3D 9 device
@@ -2379,17 +1784,8 @@ void Context::applyShaders()
{
ProgramBinary *programBinary = getCurrentProgramBinary();
- if (programBinary->getSerial() != mAppliedProgramBinarySerial)
- {
- IDirect3DVertexShader9 *vertexShader = programBinary->getVertexShader();
- IDirect3DPixelShader9 *pixelShader = programBinary->getPixelShader();
-
- mDevice->SetPixelShader(pixelShader);
- mDevice->SetVertexShader(vertexShader);
- programBinary->dirtyAllUniforms();
- mAppliedProgramBinarySerial = programBinary->getSerial();
- }
-
+ mRenderer->applyShaders(programBinary);
+
programBinary->applyUniforms();
}
@@ -2411,84 +1807,43 @@ void Context::applyTextures(SamplerType type)
{
ProgramBinary *programBinary = getCurrentProgramBinary();
- int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type
- unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS;
- int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+ // Range of Direct3D samplers of given sampler type
+ int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits();
int samplerRange = programBinary->getUsedSamplerRange(type);
for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++)
{
int textureUnit = programBinary->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index
- int d3dSampler = samplerIndex + d3dSamplerOffset;
if (textureUnit != -1)
{
TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex);
-
Texture *texture = getSamplerTexture(textureUnit, textureType);
- unsigned int texSerial = texture->getTextureSerial();
- if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyParameters() || texture->hasDirtyImages())
+ if (texture->isSamplerComplete())
{
- IDirect3DBaseTexture9 *d3dTexture = texture->getTexture();
-
- if (d3dTexture)
- {
- if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyParameters())
- {
- GLenum wrapS = texture->getWrapS();
- GLenum wrapT = texture->getWrapT();
- GLenum minFilter = texture->getMinFilter();
- GLenum magFilter = texture->getMagFilter();
- float maxAnisotropy = texture->getMaxAnisotropy();
-
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
-
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter, maxAnisotropy));
- D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
- es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter, maxAnisotropy);
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, texture->getLodOffset());
-
- if (supportsTextureFilterAnisotropy())
- {
- mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)maxAnisotropy);
- }
- }
+ SamplerState samplerState;
+ texture->getSamplerState(&samplerState);
+ mRenderer->setSamplerState(type, samplerIndex, samplerState);
- if (appliedTextureSerial[samplerIndex] != texSerial || texture->hasDirtyImages())
- {
- mDevice->SetTexture(d3dSampler, d3dTexture);
- }
- }
- else
- {
- mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture());
- }
+ mRenderer->setTexture(type, samplerIndex, texture);
- appliedTextureSerial[samplerIndex] = texSerial;
texture->resetDirty();
}
+ else
+ {
+ mRenderer->setTexture(type, samplerIndex, getIncompleteTexture(textureType));
+ }
}
else
{
- if (appliedTextureSerial[samplerIndex] != 0)
- {
- mDevice->SetTexture(d3dSampler, NULL);
- appliedTextureSerial[samplerIndex] = 0;
- }
+ mRenderer->setTexture(type, samplerIndex, NULL);
}
}
for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++)
{
- if (appliedTextureSerial[samplerIndex] != 0)
- {
- mDevice->SetTexture(samplerIndex + d3dSamplerOffset, NULL);
- appliedTextureSerial[samplerIndex] = 0;
- }
+ mRenderer->setTexture(type, samplerIndex, NULL);
}
}
@@ -2499,339 +1854,26 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), mState.packAlignment);
+ GLsizei outputPitch = ComputePitch(width, ConvertSizedInternalFormat(format, type), getPackAlignment());
// sized query sanity check
if (bufSize)
{
int requiredSize = outputPitch * height;
if (requiredSize > *bufSize)
{
- return error(GL_INVALID_OPERATION);
- }
- }
-
- IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
- if (!renderTarget)
- {
- return; // Context must be lost, return silently
- }
-
- D3DSURFACE_DESC desc;
- renderTarget->GetDesc(&desc);
-
- if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
- {
- UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target
- renderTarget->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- HRESULT result;
- IDirect3DSurface9 *systemSurface = NULL;
- bool directToPixels = !getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() &&
- x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height &&
- desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
- if (directToPixels)
- {
- // Use the pixels ptr as a shared handle to write directly into client's memory
- result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
- D3DPOOL_SYSTEMMEM, &systemSurface, &pixels);
- if (FAILED(result))
- {
- // Try again without the shared handle
- directToPixels = false;
- }
- }
-
- if (!directToPixels)
- {
- result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
- D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- renderTarget->Release();
- return error(GL_OUT_OF_MEMORY);
- }
- }
-
- result = mDevice->GetRenderTargetData(renderTarget, systemSurface);
- renderTarget->Release();
- renderTarget = NULL;
-
- if (FAILED(result))
- {
- systemSurface->Release();
-
- // It turns out that D3D will sometimes produce more error
- // codes than those documented.
- if (checkDeviceLost(result))
- return error(GL_OUT_OF_MEMORY);
- else
- {
- UNREACHABLE();
- return;
- }
-
- }
-
- if (directToPixels)
- {
- systemSurface->Release();
- return;
- }
-
- RECT rect;
- rect.left = clamp(x, 0L, static_cast<LONG>(desc.Width));
- rect.top = clamp(y, 0L, static_cast<LONG>(desc.Height));
- rect.right = clamp(x + width, 0L, static_cast<LONG>(desc.Width));
- rect.bottom = clamp(y + height, 0L, static_cast<LONG>(desc.Height));
-
- D3DLOCKED_RECT lock;
- result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
-
- if (FAILED(result))
- {
- UNREACHABLE();
- systemSurface->Release();
-
- return; // No sensible error to generate
- }
-
- unsigned char *dest = (unsigned char*)pixels;
- unsigned short *dest16 = (unsigned short*)pixels;
-
- unsigned char *source;
- int inputPitch;
- if (getPackReverseRowOrder())
- {
- source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
- inputPitch = -lock.Pitch;
- }
- else
- {
- source = (unsigned char*)lock.pBits;
- inputPitch = lock.Pitch;
- }
-
- unsigned int fastPixelSize = 0;
-
- if (desc.Format == D3DFMT_A8R8G8B8 &&
- format == GL_BGRA_EXT &&
- type == GL_UNSIGNED_BYTE)
- {
- fastPixelSize = 4;
- }
- else if ((desc.Format == D3DFMT_A4R4G4B4 &&
- format == GL_BGRA_EXT &&
- type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) ||
- (desc.Format == D3DFMT_A1R5G5B5 &&
- format == GL_BGRA_EXT &&
- type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT))
- {
- fastPixelSize = 2;
- }
- else if (desc.Format == D3DFMT_A16B16G16R16F &&
- format == GL_RGBA &&
- type == GL_HALF_FLOAT_OES)
- {
- fastPixelSize = 8;
- }
- else if (desc.Format == D3DFMT_A32B32G32R32F &&
- format == GL_RGBA &&
- type == GL_FLOAT)
- {
- fastPixelSize = 16;
- }
-
- for (int j = 0; j < rect.bottom - rect.top; j++)
- {
- if (fastPixelSize != 0)
- {
- // Fast path for formats which require no translation:
- // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE
- // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT
- // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT
- // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES
- // D3DFMT_A32B32G32R32F to RGBA/FLOAT
- //
- // Note that buffers with no alpha go through the slow path below.
- memcpy(dest + j * outputPitch,
- source + j * inputPitch,
- (rect.right - rect.left) * fastPixelSize);
- continue;
- }
-
- for (int i = 0; i < rect.right - rect.left; i++)
- {
- float r;
- float g;
- float b;
- float a;
-
- switch (desc.Format)
- {
- case D3DFMT_R5G6B5:
- {
- unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
-
- a = 1.0f;
- b = (rgb & 0x001F) * (1.0f / 0x001F);
- g = (rgb & 0x07E0) * (1.0f / 0x07E0);
- r = (rgb & 0xF800) * (1.0f / 0xF800);
- }
- break;
- case D3DFMT_A1R5G5B5:
- {
- unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
-
- a = (argb & 0x8000) ? 1.0f : 0.0f;
- b = (argb & 0x001F) * (1.0f / 0x001F);
- g = (argb & 0x03E0) * (1.0f / 0x03E0);
- r = (argb & 0x7C00) * (1.0f / 0x7C00);
- }
- break;
- case D3DFMT_A8R8G8B8:
- {
- unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
- a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
- b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
- g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
- r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
- }
- break;
- case D3DFMT_X8R8G8B8:
- {
- unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
- a = 1.0f;
- b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
- g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
- r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
- }
- break;
- case D3DFMT_A2R10G10B10:
- {
- unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
-
- a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
- b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
- g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
- r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
- }
- break;
- case D3DFMT_A32B32G32R32F:
- {
- // float formats in D3D are stored rgba, rather than the other way round
- r = *((float*)(source + 16 * i + j * inputPitch) + 0);
- g = *((float*)(source + 16 * i + j * inputPitch) + 1);
- b = *((float*)(source + 16 * i + j * inputPitch) + 2);
- a = *((float*)(source + 16 * i + j * inputPitch) + 3);
- }
- break;
- case D3DFMT_A16B16G16R16F:
- {
- // float formats in D3D are stored rgba, rather than the other way round
- r = float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0));
- g = float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1));
- b = float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2));
- a = float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3));
- }
- break;
- default:
- UNIMPLEMENTED(); // FIXME
- UNREACHABLE();
- return;
- }
-
- switch (format)
- {
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
- dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
- dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
- dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
- break;
- default: UNREACHABLE();
- }
- break;
- case GL_BGRA_EXT:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
- dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
- dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
- dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
- break;
- case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
- // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
- // this type is packed as follows:
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // --------------------------------------------------------------------------------
- // | 4th | 3rd | 2nd | 1st component |
- // --------------------------------------------------------------------------------
- // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
- dest16[i + j * outputPitch / sizeof(unsigned short)] =
- ((unsigned short)(15 * a + 0.5f) << 12)|
- ((unsigned short)(15 * r + 0.5f) << 8) |
- ((unsigned short)(15 * g + 0.5f) << 4) |
- ((unsigned short)(15 * b + 0.5f) << 0);
- break;
- case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
- // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
- // this type is packed as follows:
- // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
- // --------------------------------------------------------------------------------
- // | 4th | 3rd | 2nd | 1st component |
- // --------------------------------------------------------------------------------
- // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
- dest16[i + j * outputPitch / sizeof(unsigned short)] =
- ((unsigned short)( a + 0.5f) << 15) |
- ((unsigned short)(31 * r + 0.5f) << 10) |
- ((unsigned short)(31 * g + 0.5f) << 5) |
- ((unsigned short)(31 * b + 0.5f) << 0);
- break;
- default: UNREACHABLE();
- }
- break;
- case GL_RGB:
- switch (type)
- {
- case GL_UNSIGNED_SHORT_5_6_5:
- dest16[i + j * outputPitch / sizeof(unsigned short)] =
- ((unsigned short)(31 * b + 0.5f) << 0) |
- ((unsigned short)(63 * g + 0.5f) << 5) |
- ((unsigned short)(31 * r + 0.5f) << 11);
- break;
- case GL_UNSIGNED_BYTE:
- dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
- dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
- dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
- break;
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
- }
+ return gl::error(GL_INVALID_OPERATION);
}
}
- systemSurface->UnlockRect();
-
- systemSurface->Release();
+ mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, getPackReverseRowOrder(), getPackAlignment(), pixels);
}
void Context::clear(GLbitfield mask)
@@ -2840,300 +1882,112 @@ void Context::clear(GLbitfield mask)
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
DWORD flags = 0;
+ GLbitfield finalMask = 0;
if (mask & GL_COLOR_BUFFER_BIT)
{
mask &= ~GL_COLOR_BUFFER_BIT;
- if (framebufferObject->getColorbufferType() != GL_NONE)
+ if (framebufferObject->hasEnabledColorAttachment())
{
- flags |= D3DCLEAR_TARGET;
+ finalMask |= GL_COLOR_BUFFER_BIT;
}
}
if (mask & GL_DEPTH_BUFFER_BIT)
{
mask &= ~GL_DEPTH_BUFFER_BIT;
- if (mState.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
+ if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
{
- flags |= D3DCLEAR_ZBUFFER;
+ finalMask |= GL_DEPTH_BUFFER_BIT;
}
}
- GLuint stencilUnmasked = 0x0;
-
if (mask & GL_STENCIL_BUFFER_BIT)
{
mask &= ~GL_STENCIL_BUFFER_BIT;
if (framebufferObject->getStencilbufferType() != GL_NONE)
{
- IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
if (!depthStencil)
{
ERR("Depth stencil pointer unexpectedly null.");
return;
}
-
- D3DSURFACE_DESC desc;
- depthStencil->GetDesc(&desc);
- depthStencil->Release();
-
- unsigned int stencilSize = dx2es::GetStencilSize(desc.Format);
- stencilUnmasked = (0x1 << stencilSize) - 1;
- if (stencilUnmasked != 0x0)
+ if (GetStencilSize(depthStencil->getActualFormat()) > 0)
{
- flags |= D3DCLEAR_STENCIL;
+ finalMask |= GL_STENCIL_BUFFER_BIT;
}
}
}
if (mask != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
- if (!applyRenderTarget(true)) // Clips the clear to the scissor rectangle but not the viewport
+ if (!applyRenderTarget(GL_TRIANGLES, true)) // Clips the clear to the scissor rectangle but not the viewport
{
return;
}
- D3DCOLOR color = D3DCOLOR_ARGB(unorm<8>(mState.colorClearValue.alpha),
- unorm<8>(mState.colorClearValue.red),
- unorm<8>(mState.colorClearValue.green),
- unorm<8>(mState.colorClearValue.blue));
- float depth = clamp01(mState.depthClearValue);
- int stencil = mState.stencilClearValue & 0x000000FF;
-
- bool alphaUnmasked = (dx2es::GetAlphaSize(mRenderTargetDesc.Format) == 0) || mState.colorMaskAlpha;
-
- const bool needMaskedStencilClear = (flags & D3DCLEAR_STENCIL) &&
- (mState.stencilWritemask & stencilUnmasked) != stencilUnmasked;
- const bool needMaskedColorClear = (flags & D3DCLEAR_TARGET) &&
- !(mState.colorMaskRed && mState.colorMaskGreen &&
- mState.colorMaskBlue && alphaUnmasked);
-
- if (needMaskedColorClear || needMaskedStencilClear)
- {
- // State which is altered in all paths from this point to the clear call is saved.
- // State which is altered in only some paths will be flagged dirty in the case that
- // that path is taken.
- HRESULT hr;
- if (mMaskedClearSavedState == NULL)
- {
- hr = mDevice->BeginStateBlock();
- ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
-
- mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
- mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
- mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
- mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
- mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- mDevice->SetPixelShader(NULL);
- mDevice->SetVertexShader(NULL);
- mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
- mDevice->SetStreamSource(0, NULL, 0, 0);
- mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
- mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
- mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
- mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
-
- for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mDevice->SetStreamSourceFreq(i, 1);
- }
-
- hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
- ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
- }
-
- ASSERT(mMaskedClearSavedState != NULL);
-
- if (mMaskedClearSavedState != NULL)
- {
- hr = mMaskedClearSavedState->Capture();
- ASSERT(SUCCEEDED(hr));
- }
-
- mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
- mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
- mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
- mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
-
- if (flags & D3DCLEAR_TARGET)
- {
- mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
- }
- else
- {
- mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
- }
-
- if (stencilUnmasked != 0x0 && (flags & D3DCLEAR_STENCIL))
- {
- mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
- mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
- mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
- mDevice->SetRenderState(D3DRS_STENCILREF, stencil);
- mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask);
- mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
- mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
- mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
- mStencilStateDirty = true;
- }
- else
- {
- mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
- }
-
- mDevice->SetPixelShader(NULL);
- mDevice->SetVertexShader(NULL);
- mDevice->SetFVF(D3DFVF_XYZRHW);
- mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
- mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
- mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
- mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
- mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
- mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
-
- for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mDevice->SetStreamSourceFreq(i, 1);
- }
-
- float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
- quad[0][0] = -0.5f;
- quad[0][1] = mRenderTargetDesc.Height - 0.5f;
- quad[0][2] = 0.0f;
- quad[0][3] = 1.0f;
-
- quad[1][0] = mRenderTargetDesc.Width - 0.5f;
- quad[1][1] = mRenderTargetDesc.Height - 0.5f;
- quad[1][2] = 0.0f;
- quad[1][3] = 1.0f;
-
- quad[2][0] = -0.5f;
- quad[2][1] = -0.5f;
- quad[2][2] = 0.0f;
- quad[2][3] = 1.0f;
-
- quad[3][0] = mRenderTargetDesc.Width - 0.5f;
- quad[3][1] = -0.5f;
- quad[3][2] = 0.0f;
- quad[3][3] = 1.0f;
-
- mDisplay->startScene();
- mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
+ ClearParameters clearParams;
+ clearParams.mask = finalMask;
+ clearParams.colorClearValue = mState.colorClearValue;
+ clearParams.colorMaskRed = mState.blend.colorMaskRed;
+ clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
+ clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
+ clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
+ clearParams.depthClearValue = mState.depthClearValue;
+ clearParams.stencilClearValue = mState.stencilClearValue;
+ clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
- if (flags & D3DCLEAR_ZBUFFER)
- {
- mDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
- mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
- mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
- }
-
- if (mMaskedClearSavedState != NULL)
- {
- mMaskedClearSavedState->Apply();
- }
- }
- else if (flags)
- {
- mDevice->Clear(0, NULL, flags, color, depth, stencil);
- }
+ mRenderer->clear(clearParams, framebufferObject);
}
void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
if (!mState.currentProgram)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- D3DPRIMITIVETYPE primitiveType;
- int primitiveCount;
-
- if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
- return error(GL_INVALID_ENUM);
-
- if (primitiveCount <= 0)
+ if (!mRenderer->applyPrimitiveType(mode, count))
{
return;
}
- if (!applyRenderTarget(false))
+ if (!applyRenderTarget(mode, false))
{
return;
}
applyState(mode);
- GLsizei repeatDraw = 1;
- GLenum err = applyVertexBuffer(first, count, instances, &repeatDraw);
+ ProgramBinary *programBinary = getCurrentProgramBinary();
+
+ GLenum err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, first, count, instances);
if (err != GL_NO_ERROR)
{
- return error(err);
+ return gl::error(err);
}
applyShaders();
applyTextures();
- if (!getCurrentProgramBinary()->validateSamplers(NULL))
+ if (!programBinary->validateSamplers(NULL))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!skipDraw(mode))
{
- mDisplay->startScene();
-
- if (mode == GL_LINE_LOOP)
- {
- drawLineLoop(count, GL_NONE, NULL, 0);
- }
- else if (instances > 0)
- {
- StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count);
- if (countingIB)
- {
- if (mAppliedIBSerial != countingIB->getSerial())
- {
- mDevice->SetIndices(countingIB->getBuffer());
- mAppliedIBSerial = countingIB->getSerial();
- }
-
- for (int i = 0; i < repeatDraw; i++)
- {
- mDevice->DrawIndexedPrimitive(primitiveType, 0, 0, count, 0, primitiveCount);
- }
- }
- else
- {
- ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
- return error(GL_OUT_OF_MEMORY);
- }
- }
- else // Regular case
- {
- mDevice->DrawPrimitive(primitiveType, 0, primitiveCount);
- }
+ mRenderer->drawArrays(mode, count, instances);
}
}
@@ -3141,222 +1995,60 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid
{
if (!mState.currentProgram)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!indices && !mState.elementArrayBuffer)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
-
- D3DPRIMITIVETYPE primitiveType;
- int primitiveCount;
-
- if(!es2dx::ConvertPrimitiveType(mode, count, &primitiveType, &primitiveCount))
- return error(GL_INVALID_ENUM);
-
- if (primitiveCount <= 0)
+
+ if (!mRenderer->applyPrimitiveType(mode, count))
{
return;
}
- if (!applyRenderTarget(false))
+ if (!applyRenderTarget(mode, false))
{
return;
}
applyState(mode);
- TranslatedIndexData indexInfo;
- GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
+ rx::TranslatedIndexData indexInfo;
+ GLenum err = mRenderer->applyIndexBuffer(indices, mState.elementArrayBuffer.get(), count, mode, type, &indexInfo);
if (err != GL_NO_ERROR)
{
- return error(err);
+ return gl::error(err);
}
+ ProgramBinary *programBinary = getCurrentProgramBinary();
+
GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
- GLsizei repeatDraw = 1;
- err = applyVertexBuffer(indexInfo.minIndex, vertexCount, instances, &repeatDraw);
+ err = mRenderer->applyVertexBuffer(programBinary, mState.vertexAttribute, indexInfo.minIndex, vertexCount, instances);
if (err != GL_NO_ERROR)
{
- return error(err);
+ return gl::error(err);
}
applyShaders();
applyTextures();
- if (!getCurrentProgramBinary()->validateSamplers(false))
+ if (!programBinary->validateSamplers(NULL))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!skipDraw(mode))
{
- mDisplay->startScene();
-
- if (mode == GL_LINE_LOOP)
- {
- drawLineLoop(count, type, indices, indexInfo.minIndex);
- }
- else
- {
- for (int i = 0; i < repeatDraw; i++)
- {
- mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
- }
- }
+ mRenderer->drawElements(mode, count, type, indices, mState.elementArrayBuffer.get(), indexInfo, instances);
}
}
// Implements glFlush when block is false, glFinish when block is true
void Context::sync(bool block)
{
- mDisplay->sync(block);
-}
-
-void Context::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex)
-{
- // Get the raw indices for an indexed draw
- if (type != GL_NONE && mState.elementArrayBuffer.get())
- {
- Buffer *indexBuffer = mState.elementArrayBuffer.get();
- intptr_t offset = reinterpret_cast<intptr_t>(indices);
- indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
- }
-
- UINT startIndex = 0;
- bool succeeded = false;
-
- if (supports32bitIndices())
- {
- const int spaceNeeded = (count + 1) * sizeof(unsigned int);
-
- if (!mLineLoopIB)
- {
- mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
- }
-
- if (mLineLoopIB)
- {
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
-
- UINT offset = 0;
- unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 4;
-
- if (data)
- {
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
- }
- }
- }
- else
- {
- const int spaceNeeded = (count + 1) * sizeof(unsigned short);
-
- if (!mLineLoopIB)
- {
- mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
- }
-
- if (mLineLoopIB)
- {
- mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
- UINT offset = 0;
- unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset));
- startIndex = offset / 2;
-
- if (data)
- {
- switch (type)
- {
- case GL_NONE: // Non-indexed draw
- for (int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- data[count] = 0;
- break;
- case GL_UNSIGNED_BYTE:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLubyte*>(indices)[i];
- }
- data[count] = static_cast<const GLubyte*>(indices)[0];
- break;
- case GL_UNSIGNED_SHORT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLushort*>(indices)[i];
- }
- data[count] = static_cast<const GLushort*>(indices)[0];
- break;
- case GL_UNSIGNED_INT:
- for (int i = 0; i < count; i++)
- {
- data[i] = static_cast<const GLuint*>(indices)[i];
- }
- data[count] = static_cast<const GLuint*>(indices)[0];
- break;
- default: UNREACHABLE();
- }
-
- mLineLoopIB->unmap();
- succeeded = true;
- }
- }
- }
-
- if (succeeded)
- {
- if (mAppliedIBSerial != mLineLoopIB->getSerial())
- {
- mDevice->SetIndices(mLineLoopIB->getBuffer());
- mAppliedIBSerial = mLineLoopIB->getSerial();
- }
-
- mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
- }
- else
- {
- ERR("Could not create a looping index buffer for GL_LINE_LOOP.");
- return error(GL_OUT_OF_MEMORY);
- }
+ mRenderer->sync(block);
}
void Context::recordInvalidEnum()
@@ -3428,21 +2120,20 @@ GLenum Context::getError()
GLenum Context::getResetStatus()
{
- if (mResetStatus == GL_NO_ERROR)
+ if (mResetStatus == GL_NO_ERROR && !mContextLost)
{
- bool lost = mDisplay->testDeviceLost();
-
- if (lost)
- {
- mDisplay->notifyDeviceLost(); // Sets mResetStatus
- }
+ // mResetStatus will be set by the markContextLost callback
+ // in the case a notification is sent
+ mRenderer->testDeviceLost(true);
}
GLenum status = mResetStatus;
if (mResetStatus != GL_NO_ERROR)
{
- if (mDisplay->testDeviceResettable())
+ ASSERT(mContextLost);
+
+ if (mRenderer->testDeviceResettable())
{
mResetStatus = GL_NO_ERROR;
}
@@ -3456,63 +2147,29 @@ bool Context::isResetNotificationEnabled()
return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
}
-bool Context::supportsShaderModel3() const
+int Context::getMajorShaderModel() const
{
- return mSupportsShaderModel3;
+ return mMajorShaderModel;
}
float Context::getMaximumPointSize() const
{
- return mSupportsShaderModel3 ? mMaximumPointSize : ALIASED_POINT_SIZE_RANGE_MAX_SM2;
-}
-
-int Context::getMaximumVaryingVectors() const
-{
- return mSupportsShaderModel3 ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
-}
-
-unsigned int Context::getMaximumVertexTextureImageUnits() const
-{
- return mSupportsVertexTexture ? MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF : 0;
+ return mMaximumPointSize;
}
unsigned int Context::getMaximumCombinedTextureImageUnits() const
{
- return MAX_TEXTURE_IMAGE_UNITS + getMaximumVertexTextureImageUnits();
-}
-
-int Context::getMaximumFragmentUniformVectors() const
-{
- return mSupportsShaderModel3 ? MAX_FRAGMENT_UNIFORM_VECTORS_SM3 : MAX_FRAGMENT_UNIFORM_VECTORS_SM2;
+ return mRenderer->getMaxCombinedTextureImageUnits();
}
int Context::getMaxSupportedSamples() const
{
- return mMaxSupportedSamples;
+ return mRenderer->getMaxSupportedSamples();
}
-int Context::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+unsigned int Context::getMaximumRenderTargets() const
{
- if (requested == 0)
- {
- return requested;
- }
-
- std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
- if (itr == mMultiSampleSupport.end())
- {
- return -1;
- }
-
- for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
- {
- if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
- {
- return i;
- }
- }
-
- return -1;
+ return mRenderer->getMaxRenderTargets();
}
bool Context::supportsEventQueries() const
@@ -3525,6 +2182,11 @@ bool Context::supportsOcclusionQueries() const
return mSupportsOcclusionQueries;
}
+bool Context::supportsBGRATextures() const
+{
+ return mSupportsBGRATextures;
+}
+
bool Context::supportsDXT1Textures() const
{
return mSupportsDXT1Textures;
@@ -3635,20 +2297,17 @@ bool Context::getCurrentReadFormatType(GLenum *format, GLenum *type)
Framebuffer *framebuffer = getReadFramebuffer();
if (!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
- Renderbuffer *renderbuffer = framebuffer->getColorbuffer();
+ Renderbuffer *renderbuffer = framebuffer->getReadColorbuffer();
if (!renderbuffer)
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
- if(!dx2es::ConvertReadBufferFormat(renderbuffer->getD3DFormat(), format, type))
- {
- ASSERT(false);
- return false;
- }
+ *format = gl::ExtractFormat(renderbuffer->getActualFormat());
+ *type = gl::ExtractType(renderbuffer->getActualFormat());
return true;
}
@@ -3686,7 +2345,7 @@ void Context::detachTexture(GLuint texture)
for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
{
- for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++)
+ for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
{
if (mState.samplerTexture[type][sampler].id() == texture)
{
@@ -3777,7 +2436,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_2D:
{
- Texture2D *incomplete2d = new Texture2D(Texture::INCOMPLETE_TEXTURE_ID);
+ Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
t = incomplete2d;
}
@@ -3785,7 +2444,7 @@ Texture *Context::getIncompleteTexture(TextureType type)
case TEXTURE_CUBE:
{
- TextureCubeMap *incompleteCube = new TextureCubeMap(Texture::INCOMPLETE_TEXTURE_ID);
+ TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
@@ -3821,9 +2480,9 @@ bool Context::skipDraw(GLenum drawMode)
return true;
}
}
- else if (isTriangleMode(drawMode))
+ else if (IsTriangleMode(drawMode))
{
- if (mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK)
+ if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
{
return true;
}
@@ -3832,25 +2491,6 @@ bool Context::skipDraw(GLenum drawMode)
return false;
}
-bool Context::isTriangleMode(GLenum drawMode)
-{
- switch (drawMode)
- {
- case GL_TRIANGLES:
- case GL_TRIANGLE_FAN:
- case GL_TRIANGLE_STRIP:
- return true;
- case GL_POINTS:
- case GL_LINES:
- case GL_LINE_LOOP:
- case GL_LINE_STRIP:
- return false;
- default: UNREACHABLE();
- }
-
- return false;
-}
-
void Context::setVertexAttrib(GLuint index, const GLfloat *values)
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
@@ -3859,8 +2499,6 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mState.vertexAttribute[index].mCurrentValue[1] = values[1];
mState.vertexAttribute[index].mCurrentValue[2] = values[2];
mState.vertexAttribute[index].mCurrentValue[3] = values[3];
-
- mVertexDataManager->dirtyCurrentValue(index);
}
void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
@@ -3876,124 +2514,139 @@ void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
// Vendor extensions
void Context::initExtensionString()
{
- mExtensionString = "";
+ std::string extensionString = "";
// OES extensions
if (supports32bitIndices())
{
- mExtensionString += "GL_OES_element_index_uint ";
+ extensionString += "GL_OES_element_index_uint ";
}
- mExtensionString += "GL_OES_packed_depth_stencil ";
- mExtensionString += "GL_OES_get_program_binary ";
- mExtensionString += "GL_OES_rgb8_rgba8 ";
- mExtensionString += "GL_OES_standard_derivatives ";
+ extensionString += "GL_OES_packed_depth_stencil ";
+ extensionString += "GL_OES_get_program_binary ";
+ extensionString += "GL_OES_rgb8_rgba8 ";
+ if (mRenderer->getDerivativeInstructionSupport())
+ {
+ extensionString += "GL_OES_standard_derivatives ";
+ }
if (supportsFloat16Textures())
{
- mExtensionString += "GL_OES_texture_half_float ";
+ extensionString += "GL_OES_texture_half_float ";
}
if (supportsFloat16LinearFilter())
{
- mExtensionString += "GL_OES_texture_half_float_linear ";
+ extensionString += "GL_OES_texture_half_float_linear ";
}
if (supportsFloat32Textures())
{
- mExtensionString += "GL_OES_texture_float ";
+ extensionString += "GL_OES_texture_float ";
}
if (supportsFloat32LinearFilter())
{
- mExtensionString += "GL_OES_texture_float_linear ";
+ extensionString += "GL_OES_texture_float_linear ";
}
if (supportsNonPower2Texture())
{
- mExtensionString += "GL_OES_texture_npot ";
+ extensionString += "GL_OES_texture_npot ";
}
// Multi-vendor (EXT) extensions
if (supportsOcclusionQueries())
{
- mExtensionString += "GL_EXT_occlusion_query_boolean ";
+ extensionString += "GL_EXT_occlusion_query_boolean ";
}
- mExtensionString += "GL_EXT_read_format_bgra ";
- mExtensionString += "GL_EXT_robustness ";
+ extensionString += "GL_EXT_read_format_bgra ";
+ extensionString += "GL_EXT_robustness ";
if (supportsDXT1Textures())
{
- mExtensionString += "GL_EXT_texture_compression_dxt1 ";
+ extensionString += "GL_EXT_texture_compression_dxt1 ";
}
if (supportsTextureFilterAnisotropy())
{
- mExtensionString += "GL_EXT_texture_filter_anisotropic ";
+ extensionString += "GL_EXT_texture_filter_anisotropic ";
+ }
+
+ if (supportsBGRATextures())
+ {
+ extensionString += "GL_EXT_texture_format_BGRA8888 ";
+ }
+
+ if (mRenderer->getMaxRenderTargets() > 1)
+ {
+ extensionString += "GL_EXT_draw_buffers ";
}
- mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
- mExtensionString += "GL_EXT_texture_storage ";
+ extensionString += "GL_EXT_texture_storage ";
// ANGLE-specific extensions
if (supportsDepthTextures())
{
- mExtensionString += "GL_ANGLE_depth_texture ";
+ extensionString += "GL_ANGLE_depth_texture ";
}
- mExtensionString += "GL_ANGLE_framebuffer_blit ";
+ extensionString += "GL_ANGLE_framebuffer_blit ";
if (getMaxSupportedSamples() != 0)
{
- mExtensionString += "GL_ANGLE_framebuffer_multisample ";
+ extensionString += "GL_ANGLE_framebuffer_multisample ";
}
if (supportsInstancing())
{
- mExtensionString += "GL_ANGLE_instanced_arrays ";
+ extensionString += "GL_ANGLE_instanced_arrays ";
}
- mExtensionString += "GL_ANGLE_pack_reverse_row_order ";
+ extensionString += "GL_ANGLE_pack_reverse_row_order ";
if (supportsDXT3Textures())
{
- mExtensionString += "GL_ANGLE_texture_compression_dxt3 ";
+ extensionString += "GL_ANGLE_texture_compression_dxt3 ";
}
if (supportsDXT5Textures())
{
- mExtensionString += "GL_ANGLE_texture_compression_dxt5 ";
+ extensionString += "GL_ANGLE_texture_compression_dxt5 ";
}
- mExtensionString += "GL_ANGLE_texture_usage ";
- mExtensionString += "GL_ANGLE_translated_shader_source ";
+ extensionString += "GL_ANGLE_texture_usage ";
+ extensionString += "GL_ANGLE_translated_shader_source ";
// Other vendor-specific extensions
if (supportsEventQueries())
{
- mExtensionString += "GL_NV_fence ";
+ extensionString += "GL_NV_fence ";
}
- std::string::size_type end = mExtensionString.find_last_not_of(' ');
+ std::string::size_type end = extensionString.find_last_not_of(' ');
if (end != std::string::npos)
{
- mExtensionString.resize(end+1);
+ extensionString.resize(end+1);
}
+
+ mExtensionString = makeStaticString(extensionString);
}
const char *Context::getExtensionString() const
{
- return mExtensionString.c_str();
+ return mExtensionString;
}
void Context::initRendererString()
{
- D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier();
+ std::ostringstream rendererString;
+ rendererString << "ANGLE (";
+ rendererString << mRenderer->getRendererDescription();
+ rendererString << ")";
- mRendererString = "ANGLE (";
- mRendererString += identifier->Description;
- mRendererString += ")";
+ mRendererString = makeStaticString(rendererString.str());
}
const char *Context::getRendererString() const
{
- return mRendererString.c_str();
+ return mRendererString;
}
void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
@@ -4006,179 +2659,216 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
!drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
if (drawFramebuffer->getSamples() != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ Renderbuffer *readColorBuffer = readFramebuffer->getReadColorbuffer();
+ Renderbuffer *drawColorBuffer = drawFramebuffer->getFirstColorbuffer();
+
+ if (drawColorBuffer == NULL)
+ {
+ ERR("Draw buffers formats don't match, which is not supported in this implementation of BlitFramebufferANGLE");
+ return gl::error(GL_INVALID_OPERATION);
}
- int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth();
- int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight();
- int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth();
- int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight();
+ int readBufferWidth = readColorBuffer->getWidth();
+ int readBufferHeight = readColorBuffer->getHeight();
+ int drawBufferWidth = drawColorBuffer->getWidth();
+ int drawBufferHeight = drawColorBuffer->getHeight();
- RECT sourceRect;
- RECT destRect;
+ Rectangle sourceRect;
+ Rectangle destRect;
if (srcX0 < srcX1)
{
- sourceRect.left = srcX0;
- sourceRect.right = srcX1;
- destRect.left = dstX0;
- destRect.right = dstX1;
+ sourceRect.x = srcX0;
+ destRect.x = dstX0;
+ sourceRect.width = srcX1 - srcX0;
+ destRect.width = dstX1 - dstX0;
}
else
{
- sourceRect.left = srcX1;
- destRect.left = dstX1;
- sourceRect.right = srcX0;
- destRect.right = dstX0;
+ sourceRect.x = srcX1;
+ destRect.x = dstX1;
+ sourceRect.width = srcX0 - srcX1;
+ destRect.width = dstX0 - dstX1;
}
if (srcY0 < srcY1)
{
- sourceRect.bottom = srcY1;
- destRect.bottom = dstY1;
- sourceRect.top = srcY0;
- destRect.top = dstY0;
+ sourceRect.height = srcY1 - srcY0;
+ destRect.height = dstY1 - dstY0;
+ sourceRect.y = srcY0;
+ destRect.y = dstY0;
}
else
{
- sourceRect.bottom = srcY0;
- destRect.bottom = dstY0;
- sourceRect.top = srcY1;
- destRect.top = dstY1;
+ sourceRect.height = srcY0 - srcY1;
+ destRect.height = dstY0 - srcY1;
+ sourceRect.y = srcY1;
+ destRect.y = dstY1;
}
- RECT sourceScissoredRect = sourceRect;
- RECT destScissoredRect = destRect;
+ Rectangle sourceScissoredRect = sourceRect;
+ Rectangle destScissoredRect = destRect;
if (mState.scissorTest)
{
- // Only write to parts of the destination framebuffer which pass the scissor test
- // Please note: the destRect is now in D3D-style coordinates, so the *top* of the
- // rect will be checked against scissorY, rather than the bottom.
- if (destRect.left < mState.scissorX)
+ // Only write to parts of the destination framebuffer which pass the scissor test.
+ if (destRect.x < mState.scissor.x)
{
- int xDiff = mState.scissorX - destRect.left;
- destScissoredRect.left = mState.scissorX;
- sourceScissoredRect.left += xDiff;
+ int xDiff = mState.scissor.x - destRect.x;
+ destScissoredRect.x = mState.scissor.x;
+ destScissoredRect.width -= xDiff;
+ sourceScissoredRect.x += xDiff;
+ sourceScissoredRect.width -= xDiff;
+
}
- if (destRect.right > mState.scissorX + mState.scissorWidth)
+ if (destRect.x + destRect.width > mState.scissor.x + mState.scissor.width)
{
- int xDiff = destRect.right - (mState.scissorX + mState.scissorWidth);
- destScissoredRect.right = mState.scissorX + mState.scissorWidth;
- sourceScissoredRect.right -= xDiff;
+ int xDiff = (destRect.x + destRect.width) - (mState.scissor.x + mState.scissor.width);
+ destScissoredRect.width -= xDiff;
+ sourceScissoredRect.width -= xDiff;
}
- if (destRect.top < mState.scissorY)
+ if (destRect.y < mState.scissor.y)
{
- int yDiff = mState.scissorY - destRect.top;
- destScissoredRect.top = mState.scissorY;
- sourceScissoredRect.top += yDiff;
+ int yDiff = mState.scissor.y - destRect.y;
+ destScissoredRect.y = mState.scissor.y;
+ destScissoredRect.height -= yDiff;
+ sourceScissoredRect.y += yDiff;
+ sourceScissoredRect.height -= yDiff;
}
- if (destRect.bottom > mState.scissorY + mState.scissorHeight)
+ if (destRect.y + destRect.height > mState.scissor.y + mState.scissor.height)
{
- int yDiff = destRect.bottom - (mState.scissorY + mState.scissorHeight);
- destScissoredRect.bottom = mState.scissorY + mState.scissorHeight;
- sourceScissoredRect.bottom -= yDiff;
+ int yDiff = (destRect.y + destRect.height) - (mState.scissor.y + mState.scissor.height);
+ destScissoredRect.height -= yDiff;
+ sourceScissoredRect.height -= yDiff;
}
}
bool blitRenderTarget = false;
bool blitDepthStencil = false;
- RECT sourceTrimmedRect = sourceScissoredRect;
- RECT destTrimmedRect = destScissoredRect;
+ Rectangle sourceTrimmedRect = sourceScissoredRect;
+ Rectangle destTrimmedRect = destScissoredRect;
// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
// the actual draw and read surfaces.
- if (sourceTrimmedRect.left < 0)
+ if (sourceTrimmedRect.x < 0)
{
- int xDiff = 0 - sourceTrimmedRect.left;
- sourceTrimmedRect.left = 0;
- destTrimmedRect.left += xDiff;
+ int xDiff = 0 - sourceTrimmedRect.x;
+ sourceTrimmedRect.x = 0;
+ sourceTrimmedRect.width -= xDiff;
+ destTrimmedRect.x += xDiff;
+ destTrimmedRect.width -= xDiff;
}
- if (sourceTrimmedRect.right > readBufferWidth)
+ if (sourceTrimmedRect.x + sourceTrimmedRect.width > readBufferWidth)
{
- int xDiff = sourceTrimmedRect.right - readBufferWidth;
- sourceTrimmedRect.right = readBufferWidth;
- destTrimmedRect.right -= xDiff;
+ int xDiff = (sourceTrimmedRect.x + sourceTrimmedRect.width) - readBufferWidth;
+ sourceTrimmedRect.width -= xDiff;
+ destTrimmedRect.width -= xDiff;
}
- if (sourceTrimmedRect.top < 0)
+ if (sourceTrimmedRect.y < 0)
{
- int yDiff = 0 - sourceTrimmedRect.top;
- sourceTrimmedRect.top = 0;
- destTrimmedRect.top += yDiff;
+ int yDiff = 0 - sourceTrimmedRect.y;
+ sourceTrimmedRect.y = 0;
+ sourceTrimmedRect.height -= yDiff;
+ destTrimmedRect.y += yDiff;
+ destTrimmedRect.height -= yDiff;
}
- if (sourceTrimmedRect.bottom > readBufferHeight)
+ if (sourceTrimmedRect.y + sourceTrimmedRect.height > readBufferHeight)
{
- int yDiff = sourceTrimmedRect.bottom - readBufferHeight;
- sourceTrimmedRect.bottom = readBufferHeight;
- destTrimmedRect.bottom -= yDiff;
+ int yDiff = (sourceTrimmedRect.y + sourceTrimmedRect.height) - readBufferHeight;
+ sourceTrimmedRect.height -= yDiff;
+ destTrimmedRect.height -= yDiff;
}
- if (destTrimmedRect.left < 0)
+ if (destTrimmedRect.x < 0)
{
- int xDiff = 0 - destTrimmedRect.left;
- destTrimmedRect.left = 0;
- sourceTrimmedRect.left += xDiff;
+ int xDiff = 0 - destTrimmedRect.x;
+ destTrimmedRect.x = 0;
+ destTrimmedRect.width -= xDiff;
+ sourceTrimmedRect.x += xDiff;
+ sourceTrimmedRect.width -= xDiff;
}
- if (destTrimmedRect.right > drawBufferWidth)
+ if (destTrimmedRect.x + destTrimmedRect.width > drawBufferWidth)
{
- int xDiff = destTrimmedRect.right - drawBufferWidth;
- destTrimmedRect.right = drawBufferWidth;
- sourceTrimmedRect.right -= xDiff;
+ int xDiff = (destTrimmedRect.x + destTrimmedRect.width) - drawBufferWidth;
+ destTrimmedRect.width -= xDiff;
+ sourceTrimmedRect.width -= xDiff;
}
- if (destTrimmedRect.top < 0)
+ if (destTrimmedRect.y < 0)
{
- int yDiff = 0 - destTrimmedRect.top;
- destTrimmedRect.top = 0;
- sourceTrimmedRect.top += yDiff;
+ int yDiff = 0 - destTrimmedRect.y;
+ destTrimmedRect.y = 0;
+ destTrimmedRect.height -= yDiff;
+ sourceTrimmedRect.y += yDiff;
+ sourceTrimmedRect.height -= yDiff;
}
- if (destTrimmedRect.bottom > drawBufferHeight)
+ if (destTrimmedRect.y + destTrimmedRect.height > drawBufferHeight)
{
- int yDiff = destTrimmedRect.bottom - drawBufferHeight;
- destTrimmedRect.bottom = drawBufferHeight;
- sourceTrimmedRect.bottom -= yDiff;
+ int yDiff = (destTrimmedRect.y + destTrimmedRect.height) - drawBufferHeight;
+ destTrimmedRect.height -= yDiff;
+ sourceTrimmedRect.height -= yDiff;
}
bool partialBufferCopy = false;
- if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readBufferHeight ||
- sourceTrimmedRect.right - sourceTrimmedRect.left < readBufferWidth ||
- destTrimmedRect.bottom - destTrimmedRect.top < drawBufferHeight ||
- destTrimmedRect.right - destTrimmedRect.left < drawBufferWidth ||
- sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
+ if (sourceTrimmedRect.height < readBufferHeight ||
+ sourceTrimmedRect.width < readBufferWidth ||
+ destTrimmedRect.height < drawBufferHeight ||
+ destTrimmedRect.width < drawBufferWidth ||
+ sourceTrimmedRect.y != 0 || destTrimmedRect.y != 0 || sourceTrimmedRect.x != 0 || destTrimmedRect.x != 0)
{
partialBufferCopy = true;
}
if (mask & GL_COLOR_BUFFER_BIT)
{
- const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
- readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
- const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
- drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
- if (!validReadType || !validDrawType ||
- readFramebuffer->getColorbuffer()->getD3DFormat() != drawFramebuffer->getColorbuffer()->getD3DFormat())
+ const GLenum readColorbufferType = readFramebuffer->getReadColorbufferType();
+ const bool validReadType = (readColorbufferType == GL_TEXTURE_2D) || (readColorbufferType == GL_RENDERBUFFER);
+ bool validDrawType = true;
+ bool validDrawFormat = true;
+
+ for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ if (drawFramebuffer->isEnabledColorAttachment(colorAttachment))
+ {
+ if (drawFramebuffer->getColorbufferType(colorAttachment) != GL_TEXTURE_2D &&
+ drawFramebuffer->getColorbufferType(colorAttachment) != GL_RENDERBUFFER)
+ {
+ validDrawType = false;
+ }
+
+ if (drawFramebuffer->getColorbuffer(colorAttachment)->getActualFormat() != readColorBuffer->getActualFormat())
+ {
+ validDrawFormat = false;
+ }
+ }
+ }
+
+ if (!validReadType || !validDrawType || !validDrawFormat)
{
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (partialBufferCopy && readFramebuffer->getSamples() != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
blitRenderTarget = true;
@@ -4198,9 +2888,9 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
{
if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
- readFramebuffer->getDepthbuffer()->getD3DFormat() != drawFramebuffer->getDepthbuffer()->getD3DFormat())
+ readFramebuffer->getDepthbuffer()->getActualFormat() != drawFramebuffer->getDepthbuffer()->getActualFormat())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
@@ -4214,9 +2904,9 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
{
if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
- readFramebuffer->getStencilbuffer()->getD3DFormat() != drawFramebuffer->getStencilbuffer()->getD3DFormat())
+ readFramebuffer->getStencilbuffer()->getActualFormat() != drawFramebuffer->getStencilbuffer()->getActualFormat())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
blitDepthStencil = true;
@@ -4228,255 +2918,29 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (partialBufferCopy)
{
ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
- return error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
+ return gl::error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
}
if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
(readDSBuffer && readDSBuffer->getSamples() != 0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
if (blitRenderTarget || blitDepthStencil)
{
- mDisplay->endScene();
-
- if (blitRenderTarget)
- {
- IDirect3DSurface9* readRenderTarget = readFramebuffer->getRenderTarget();
- IDirect3DSurface9* drawRenderTarget = drawFramebuffer->getRenderTarget();
-
- HRESULT result = mDevice->StretchRect(readRenderTarget, &sourceTrimmedRect,
- drawRenderTarget, &destTrimmedRect, D3DTEXF_NONE);
-
- readRenderTarget->Release();
- drawRenderTarget->Release();
-
- if (FAILED(result))
- {
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return;
- }
- }
-
- if (blitDepthStencil)
- {
- IDirect3DSurface9* readDepthStencil = readFramebuffer->getDepthStencil();
- IDirect3DSurface9* drawDepthStencil = drawFramebuffer->getDepthStencil();
-
- HRESULT result = mDevice->StretchRect(readDepthStencil, NULL, drawDepthStencil, NULL, D3DTEXF_NONE);
-
- readDepthStencil->Release();
- drawDepthStencil->Release();
-
- if (FAILED(result))
- {
- ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
- return;
- }
- }
- }
-}
-
-VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
-{
- for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
- {
- mVertexDeclCache[i].vertexDeclaration = NULL;
- mVertexDeclCache[i].lruCount = 0;
+ mRenderer->blitRect(readFramebuffer, sourceTrimmedRect, drawFramebuffer, destTrimmedRect, blitRenderTarget, blitDepthStencil);
}
}
-VertexDeclarationCache::~VertexDeclarationCache()
-{
- for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
- {
- if (mVertexDeclCache[i].vertexDeclaration)
- {
- mVertexDeclCache[i].vertexDeclaration->Release();
- }
- }
-}
-
-GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
-{
- *repeatDraw = 1;
-
- int indexedAttribute = MAX_VERTEX_ATTRIBS;
- int instancedAttribute = MAX_VERTEX_ATTRIBS;
-
- if (instances > 0)
- {
- // Find an indexed attribute to be mapped to D3D stream 0
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].active)
- {
- if (indexedAttribute == MAX_VERTEX_ATTRIBS)
- {
- if (attributes[i].divisor == 0)
- {
- indexedAttribute = i;
- }
- }
- else if (instancedAttribute == MAX_VERTEX_ATTRIBS)
- {
- if (attributes[i].divisor != 0)
- {
- instancedAttribute = i;
- }
- }
- else break; // Found both an indexed and instanced attribute
- }
- }
-
- if (indexedAttribute == MAX_VERTEX_ATTRIBS)
- {
- return GL_INVALID_OPERATION;
- }
- }
-
- D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1];
- D3DVERTEXELEMENT9 *element = &elements[0];
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].active)
- {
- int stream = i;
-
- if (instances > 0)
- {
- // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
- if (instancedAttribute == MAX_VERTEX_ATTRIBS)
- {
- *repeatDraw = instances;
- }
- else
- {
- if (i == indexedAttribute)
- {
- stream = 0;
- }
- else if (i == 0)
- {
- stream = indexedAttribute;
- }
-
- UINT frequency = 1;
-
- if (attributes[i].divisor == 0)
- {
- frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
- }
- else
- {
- frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
- }
-
- device->SetStreamSourceFreq(stream, frequency);
- mInstancingEnabled = true;
- }
- }
-
- if (mAppliedVBs[stream].serial != attributes[i].serial ||
- mAppliedVBs[stream].stride != attributes[i].stride ||
- mAppliedVBs[stream].offset != attributes[i].offset)
- {
- device->SetStreamSource(stream, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
- mAppliedVBs[stream].serial = attributes[i].serial;
- mAppliedVBs[stream].stride = attributes[i].stride;
- mAppliedVBs[stream].offset = attributes[i].offset;
- }
-
- element->Stream = stream;
- element->Offset = 0;
- element->Type = attributes[i].type;
- element->Method = D3DDECLMETHOD_DEFAULT;
- element->Usage = D3DDECLUSAGE_TEXCOORD;
- element->UsageIndex = programBinary->getSemanticIndex(i);
- element++;
- }
- }
-
- if (instances == 0 || instancedAttribute == MAX_VERTEX_ATTRIBS)
- {
- if (mInstancingEnabled)
- {
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- device->SetStreamSourceFreq(i, 1);
- }
-
- mInstancingEnabled = false;
- }
- }
-
- static const D3DVERTEXELEMENT9 end = D3DDECL_END();
- *(element++) = end;
-
- for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
- {
- VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
- if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
- {
- entry->lruCount = ++mMaxLru;
- if(entry->vertexDeclaration != mLastSetVDecl)
- {
- device->SetVertexDeclaration(entry->vertexDeclaration);
- mLastSetVDecl = entry->vertexDeclaration;
- }
-
- return GL_NO_ERROR;
- }
- }
-
- VertexDeclCacheEntry *lastCache = mVertexDeclCache;
-
- for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
- {
- if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
- {
- lastCache = &mVertexDeclCache[i];
- }
- }
-
- if (lastCache->vertexDeclaration != NULL)
- {
- lastCache->vertexDeclaration->Release();
- lastCache->vertexDeclaration = NULL;
- // mLastSetVDecl is set to the replacement, so we don't have to worry
- // about it.
- }
-
- memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
- device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
- device->SetVertexDeclaration(lastCache->vertexDeclaration);
- mLastSetVDecl = lastCache->vertexDeclaration;
- lastCache->lruCount = ++mMaxLru;
-
- return GL_NO_ERROR;
-}
-
-void VertexDeclarationCache::markStateDirty()
-{
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mAppliedVBs[i].serial = 0;
- }
-
- mLastSetVDecl = NULL;
- mInstancingEnabled = true; // Forces it to be disabled when not used
-}
-
}
extern "C"
{
-gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
+gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
{
- return new gl::Context(config, shareContext, notifyResets, robustAccess);
+ return new gl::Context(shareContext, renderer, notifyResets, robustAccess);
}
void glDestroyContext(gl::Context *context)
@@ -4498,4 +2962,5 @@ gl::Context *glGetCurrentContext()
{
return gl::getContext();
}
+
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
index 2bbae76ef8..9c222be24d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -15,7 +15,6 @@
#include <GLES2/gl2ext.h>
#define EGLAPI
#include <EGL/egl.h>
-#include <d3d9.h>
#include <string>
#include <map>
@@ -27,22 +26,23 @@
#include "common/angleutils.h"
#include "common/RefCountObject.h"
-#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/HandleAllocator.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/Constants.h"
+
+namespace rx
+{
+class Renderer;
+}
namespace egl
{
class Display;
class Surface;
-class Config;
}
namespace gl
{
-struct TranslatedAttribute;
-struct TranslatedIndexData;
-
-class Buffer;
class Shader;
class Program;
class ProgramBinary;
@@ -54,35 +54,12 @@ class Renderbuffer;
class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
-class StreamingIndexBuffer;
class Stencilbuffer;
class DepthStencilbuffer;
-class VertexDataManager;
-class IndexDataManager;
-class Blit;
class Fence;
class Query;
-
-enum
-{
- D3D9_MAX_FLOAT_CONSTANTS = 256,
- D3D9_MAX_BOOL_CONSTANTS = 16,
- D3D9_MAX_INT_CONSTANTS = 16,
-
- MAX_VERTEX_ATTRIBS = 16,
- MAX_VERTEX_UNIFORM_VECTORS = D3D9_MAX_FLOAT_CONSTANTS - 2, // Reserve space for dx_HalfPixelSize and dx_DepthRange.
- MAX_VARYING_VECTORS_SM2 = 8,
- MAX_VARYING_VECTORS_SM3 = 10,
- MAX_TEXTURE_IMAGE_UNITS = 16,
- MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF = 4, // For devices supporting vertex texture fetch
- MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF,
- MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3, // Reserve space for dx_Coord, dx_Depth, and dx_DepthRange. dx_PointOrLines and dx_FrontCCW use separate bool registers.
- MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3,
- MAX_DRAW_BUFFERS = 1,
-
- GL_BGRA4_ANGLEX = 0x6ABC,
- GL_BGR5_A1_ANGLEX = 0x6ABD
-};
+class ResourceManager;
+class Buffer;
enum QueryType
{
@@ -92,19 +69,6 @@ enum QueryType
QUERY_TYPE_COUNT
};
-const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
-const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MAX_SM2 = 1.0f;
-
-struct Color
-{
- float red;
- float green;
- float blue;
- float alpha;
-};
-
// Helper structure describing a single vertex attribute
class VertexAttribute
{
@@ -155,8 +119,6 @@ class VertexAttribute
unsigned int mDivisor;
};
-typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
-
// Helper structure to store all raw state
struct State
{
@@ -164,67 +126,29 @@ struct State
GLclampf depthClearValue;
int stencilClearValue;
- bool cullFace;
- GLenum cullMode;
- GLenum frontFace;
- bool depthTest;
- GLenum depthFunc;
- bool blend;
- GLenum sourceBlendRGB;
- GLenum destBlendRGB;
- GLenum sourceBlendAlpha;
- GLenum destBlendAlpha;
- GLenum blendEquationRGB;
- GLenum blendEquationAlpha;
+ RasterizerState rasterizer;
+ bool scissorTest;
+ Rectangle scissor;
+
+ BlendState blend;
Color blendColor;
- bool stencilTest;
- GLenum stencilFunc;
- GLint stencilRef;
- GLuint stencilMask;
- GLenum stencilFail;
- GLenum stencilPassDepthFail;
- GLenum stencilPassDepthPass;
- GLuint stencilWritemask;
- GLenum stencilBackFunc;
- GLint stencilBackRef;
- GLuint stencilBackMask;
- GLenum stencilBackFail;
- GLenum stencilBackPassDepthFail;
- GLenum stencilBackPassDepthPass;
- GLuint stencilBackWritemask;
- bool polygonOffsetFill;
- GLfloat polygonOffsetFactor;
- GLfloat polygonOffsetUnits;
- bool sampleAlphaToCoverage;
bool sampleCoverage;
GLclampf sampleCoverageValue;
bool sampleCoverageInvert;
- bool scissorTest;
- bool dither;
+
+ DepthStencilState depthStencil;
+ GLint stencilRef;
+ GLint stencilBackRef;
GLfloat lineWidth;
GLenum generateMipmapHint;
GLenum fragmentShaderDerivativeHint;
- GLint viewportX;
- GLint viewportY;
- GLsizei viewportWidth;
- GLsizei viewportHeight;
+ Rectangle viewport;
float zNear;
float zFar;
- GLint scissorX;
- GLint scissorY;
- GLsizei scissorWidth;
- GLsizei scissorHeight;
-
- bool colorMaskRed;
- bool colorMaskGreen;
- bool colorMaskBlue;
- bool colorMaskAlpha;
- bool depthMask;
-
unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> arrayBuffer;
BindingPointer<Buffer> elementArrayBuffer;
@@ -234,7 +158,7 @@ struct State
GLuint currentProgram;
VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
- BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
+ BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT];
GLint unpackAlignment;
@@ -242,52 +166,14 @@ struct State
bool packReverseRowOrder;
};
-// Helper class to construct and cache vertex declarations
-class VertexDeclarationCache
-{
- public:
- VertexDeclarationCache();
- ~VertexDeclarationCache();
-
- GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
-
- void markStateDirty();
-
- private:
- UINT mMaxLru;
-
- enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
-
- struct VBData
- {
- unsigned int serial;
- unsigned int stride;
- unsigned int offset;
- };
-
- VBData mAppliedVBs[MAX_VERTEX_ATTRIBS];
- IDirect3DVertexDeclaration9 *mLastSetVDecl;
- bool mInstancingEnabled;
-
- struct VertexDeclCacheEntry
- {
- D3DVERTEXELEMENT9 cachedElements[MAX_VERTEX_ATTRIBS + 1];
- UINT lruCount;
- IDirect3DVertexDeclaration9 *vertexDeclaration;
- } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
-};
-
class Context
{
public:
- Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
+ Context(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
~Context();
- void makeCurrent(egl::Display *display, egl::Surface *surface);
-
- virtual void markAllStateDirty();
- void markDxUniformsDirty();
+ void makeCurrent(egl::Surface *surface);
virtual void markContextLost();
bool isContextLost();
@@ -377,8 +263,6 @@ class Context
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
- const VertexAttributeArray &getVertexAttributes();
-
void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const;
@@ -430,7 +314,7 @@ class Context
void setFramebufferZero(Framebuffer *framebuffer);
- void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
+ void setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples);
void setVertexAttrib(GLuint index, const GLfloat *values);
void setVertexAttribDivisor(GLuint index, GLuint divisor);
@@ -465,8 +349,6 @@ class Context
void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances);
void sync(bool block); // flush/finish
- void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex);
-
void recordInvalidEnum();
void recordInvalidValue();
void recordInvalidOperation();
@@ -477,22 +359,20 @@ class Context
GLenum getResetStatus();
virtual bool isResetNotificationEnabled();
- bool supportsShaderModel3() const;
+ int getMajorShaderModel() const;
float getMaximumPointSize() const;
- int getMaximumVaryingVectors() const;
- unsigned int getMaximumVertexTextureImageUnits() const;
unsigned int getMaximumCombinedTextureImageUnits() const;
- int getMaximumFragmentUniformVectors() const;
int getMaximumRenderbufferDimension() const;
int getMaximumTextureDimension() const;
int getMaximumCubeTextureDimension() const;
int getMaximumTextureLevel() const;
+ unsigned int getMaximumRenderTargets() const;
GLsizei getMaxSupportedSamples() const;
- int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
const char *getRendererString() const;
bool supportsEventQueries() const;
bool supportsOcclusionQueries() const;
+ bool supportsBGRATextures() const;
bool supportsDXT1Textures() const;
bool supportsDXT3Textures() const;
bool supportsDXT5Textures() const;
@@ -518,17 +398,11 @@ class Context
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask);
- Blit *getBlitter() { return mBlit; }
-
- const D3DCAPS9 &getDeviceCaps() { return mDeviceCaps; }
-
private:
DISALLOW_COPY_AND_ASSIGN(Context);
- bool applyRenderTarget(bool ignoreViewport);
+ bool applyRenderTarget(GLenum drawMode, bool ignoreViewport);
void applyState(GLenum drawMode);
- GLenum applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw);
- GLenum applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void applyTextures(SamplerType type);
@@ -541,14 +415,11 @@ class Context
Texture *getIncompleteTexture(TextureType type);
bool skipDraw(GLenum drawMode);
- bool isTriangleMode(GLenum drawMode);
void initExtensionString();
void initRendererString();
- const egl::Config *const mConfig;
- egl::Display *mDisplay;
- IDirect3DDevice9 *mDevice;
+ rx::Renderer *const mRenderer;
State mState;
@@ -575,15 +446,8 @@ class Context
QueryMap mQueryMap;
HandleAllocator mQueryHandleAllocator;
- std::string mExtensionString;
- std::string mRendererString;
-
- VertexDataManager *mVertexDataManager;
- IndexDataManager *mIndexDataManager;
-
- Blit *mBlit;
-
- StreamingIndexBuffer *mLineLoopIB;
+ const char *mExtensionString;
+ const char *mRendererString;
BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT];
@@ -601,36 +465,23 @@ class Context
GLenum mResetStrategy;
bool mRobustAccess;
- unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS];
- unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
- unsigned int mAppliedProgramBinarySerial;
- unsigned int mAppliedRenderTargetSerial;
- unsigned int mAppliedDepthbufferSerial;
- unsigned int mAppliedStencilbufferSerial;
- unsigned int mAppliedIBSerial;
- bool mDepthStencilInitialized;
- bool mViewportInitialized;
- D3DVIEWPORT9 mSetViewport;
- bool mRenderTargetDescInitialized;
- D3DSURFACE_DESC mRenderTargetDesc;
- bool mDxUniformsDirty;
BindingPointer<ProgramBinary> mCurrentProgramBinary;
Framebuffer *mBoundDrawFramebuffer;
- bool mSupportsShaderModel3;
+ int mMajorShaderModel;
float mMaximumPointSize;
bool mSupportsVertexTexture;
bool mSupportsNonPower2Texture;
bool mSupportsInstancing;
+ int mMaxViewportDimension;
int mMaxRenderbufferDimension;
int mMaxTextureDimension;
int mMaxCubeTextureDimension;
int mMaxTextureLevel;
float mMaxTextureAnisotropy;
- std::map<D3DFORMAT, bool *> mMultiSampleSupport;
- GLsizei mMaxSupportedSamples;
bool mSupportsEventQueries;
bool mSupportsOcclusionQueries;
+ bool mSupportsBGRATextures;
bool mSupportsDXT1Textures;
bool mSupportsDXT3Textures;
bool mSupportsDXT5Textures;
@@ -647,39 +498,8 @@ class Context
bool mSupportsTextureFilterAnisotropy;
int mNumCompressedTextureFormats;
- // state caching flags
- bool mClearStateDirty;
- bool mCullStateDirty;
- bool mDepthStateDirty;
- bool mMaskStateDirty;
- bool mPixelPackingStateDirty;
- bool mBlendStateDirty;
- bool mStencilStateDirty;
- bool mPolygonOffsetStateDirty;
- bool mScissorStateDirty;
- bool mSampleStateDirty;
- bool mFrontFaceDirty;
- bool mDitherStateDirty;
-
- IDirect3DStateBlock9 *mMaskedClearSavedState;
-
- D3DCAPS9 mDeviceCaps;
-
ResourceManager *mResourceManager;
-
- VertexDeclarationCache mVertexDeclarationCache;
};
}
-extern "C"
-{
-// Exported functions for use by EGL
-gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess);
-void glDestroyContext(gl::Context *context);
-void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
-gl::Context *glGetCurrentContext();
-__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
-bool __stdcall glBindTexImage(egl::Surface *surface);
-}
-
#endif // INCLUDE_CONTEXT_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp b/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp
deleted file mode 100644
index e136951bec..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// D3DConstantTable.cpp: Implements the D3DConstantTable class which parses
-// information about constants from the CTAB comment in a D3D shader blob.
-// Restructures the constant table as a hierarchy of constants in the same
-// way as D3DX.
-
-#include "libGLESv2/D3DConstantTable.h"
-
-#include <d3d9.h>
-#include <d3d9types.h>
-#include <windows.h>
-#include <mmsystem.h>
-
-#include "libGLESv2/BinaryStream.h"
-
-const static int SHADER_VERSION_MASK = D3DVS_VERSION(0, 0);
-const static int FOURCC_CTAB = MAKEFOURCC('C','T','A','B');
-
-namespace gl
-{
-// These structs and constants correspond to the format of the constant table in a shader binary.
-// They match the corresponding structures in d3dx9shader.h.
-namespace ctab
-{
-struct ConstantTable
-{
- DWORD size;
- DWORD creator;
- DWORD version;
- DWORD constants;
- DWORD constantInfos;
- DWORD flags;
- DWORD target;
-};
-
-struct ConstantInfo
-{
- DWORD name;
- WORD registerSet;
- WORD registerIndex;
- WORD registerCount;
- WORD reserved;
- DWORD typeInfo;
- DWORD defaultValue;
-};
-
-struct TypeInfo
-{
- WORD typeClass;
- WORD type;
- WORD rows;
- WORD columns;
- WORD elements;
- WORD structMembers;
- DWORD structMemberInfos;
-};
-
-struct StructMemberInfo
-{
- DWORD name;
- DWORD typeInfo;
-};
-}
-
-D3DConstant::D3DConstant(const char *base, const ctab::ConstantInfo *constantInfo)
-{
- const ctab::TypeInfo *typeInfo = reinterpret_cast<const ctab::TypeInfo*>(base + constantInfo->typeInfo);
-
- name = base + constantInfo->name;
- registerSet = static_cast<RegisterSet>(constantInfo->registerSet);
- registerIndex = constantInfo->registerIndex;
- registerCount = constantInfo->registerCount;
- typeClass = static_cast<Class>(typeInfo->typeClass);
- type = static_cast<Type>(typeInfo->type);
- rows = typeInfo->rows;
- columns = typeInfo->columns;
- elements = typeInfo->elements;
-
- if (typeClass == CLASS_STRUCT)
- {
- addStructMembers(base, registerSet, registerIndex, typeInfo);
- }
-}
-
-D3DConstant::D3DConstant(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::StructMemberInfo *memberInfo)
- : registerSet(registerSet), registerIndex(registerIndex)
-{
- const ctab::TypeInfo *typeInfo = reinterpret_cast<const ctab::TypeInfo*>(base + memberInfo->typeInfo);
-
- name = base + memberInfo->name;
- registerCount = typeInfo->rows * typeInfo->elements;
- typeClass = static_cast<Class>(typeInfo->typeClass);
- type = static_cast<Type>(typeInfo->type);
- rows = typeInfo->rows;
- columns = typeInfo->columns;
- elements = typeInfo->elements;
-
- if (typeClass == CLASS_STRUCT)
- {
- registerCount = addStructMembers(base, registerSet, registerIndex, typeInfo);
- }
-}
-
-D3DConstant::~D3DConstant()
-{
- for (size_t j = 0; j < structMembers.size(); ++j)
- {
- for (size_t i = 0; i < structMembers[j].size(); ++i)
- {
- delete structMembers[j][i];
- }
- }
-}
-
-unsigned D3DConstant::addStructMembers(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::TypeInfo *typeInfo)
-{
- const ctab::StructMemberInfo *memberInfos = reinterpret_cast<const ctab::StructMemberInfo*>(
- base + typeInfo->structMemberInfos);
-
- unsigned memberIndex = registerIndex;
-
- structMembers.resize(elements);
-
- for (unsigned j = 0; j < elements; ++j)
- {
- structMembers[j].resize(typeInfo->structMembers);
-
- for (unsigned i = 0; i < typeInfo->structMembers; ++i)
- {
- const ctab::TypeInfo *memberTypeInfo = reinterpret_cast<const ctab::TypeInfo*>(
- base + memberInfos[i].typeInfo);
-
- D3DConstant *member = new D3DConstant(base, registerSet, memberIndex, memberInfos + i);
- memberIndex += member->registerCount;
-
- structMembers[j][i] = member;
- }
- }
-
- return memberIndex - registerIndex;
-}
-
-D3DConstantTable::D3DConstantTable(void *blob, size_t size) : mError(false)
-{
- BinaryInputStream stream(blob, size);
-
- int version;
- stream.read(&version);
- if ((version & SHADER_VERSION_MASK) != SHADER_VERSION_MASK)
- {
- mError = true;
- return;
- }
-
- const ctab::ConstantTable* constantTable = NULL;
-
- while (!stream.error())
- {
- int token;
- stream.read(&token);
-
- if ((token & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT)
- {
- size_t length = ((token & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT) * sizeof(DWORD);
-
- int fourcc;
- stream.read(&fourcc);
- if (fourcc == FOURCC_CTAB)
- {
- constantTable = reinterpret_cast<const ctab::ConstantTable*>(static_cast<const char*>(blob) + stream.offset());
- break;
- }
-
- stream.skip(length - sizeof(fourcc));
- }
- else if (token == D3DSIO_END)
- {
- break;
- }
- }
-
- mError = !constantTable || stream.error();
- if (mError)
- {
- return;
- }
-
- const char *base = reinterpret_cast<const char*>(constantTable);
-
- mConstants.resize(constantTable->constants);
- const ctab::ConstantInfo *constantInfos =
- reinterpret_cast<const ctab::ConstantInfo*>(base + constantTable->constantInfos);
- for (size_t i = 0; i < constantTable->constants; ++i)
- {
- mConstants[i] = new D3DConstant(base, constantInfos + i);
- }
-}
-
-D3DConstantTable::~D3DConstantTable()
-{
- for (size_t i = 0; i < mConstants.size(); ++i)
- {
- delete mConstants[i];
- }
-}
-
-const D3DConstant *D3DConstantTable::getConstant(unsigned index) const
-{
- return mConstants[index];
-}
-
-const D3DConstant *D3DConstantTable::getConstantByName(const char *name) const
-{
- for (size_t i = 0; i < mConstants.size(); ++i)
- {
- const D3DConstant *constant = getConstant(i);
- if (constant->name == name)
- {
- return constant;
- }
- }
-
- return NULL;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.h b/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.h
deleted file mode 100644
index ca6f3b9a3f..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/D3DConstantTable.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//
-// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// D3DConstantTable.h: Implements the D3DConstantTable class which parses
-// information about constants from the CTAB comment in a D3D shader blob.
-// Restructures the constant table as a hierarchy of constants in the same
-// way as D3DX.
-
-#ifndef LIBGLESV2_D3DCONSTANTTABLE_H_
-#define LIBGLESV2_D3DCONSTANTTABLE_H_
-
-#include <vector>
-#include <string>
-
-#include "common/angleutils.h"
-
-namespace gl
-{
-
-namespace ctab
-{
-struct ConstantTable;
-struct ConstantInfo;
-struct TypeInfo;
-struct StructMemberInfo;
-}
-
-struct D3DConstant
-{
- // These enums match those in d3dx9shader.h.
- enum Class
- {
- CLASS_SCALAR,
- CLASS_VECTOR,
- CLASS_MATRIX_ROWS,
- CLASS_MATRIX_COLUMNS,
- CLASS_OBJECT,
- CLASS_STRUCT,
- };
-
- enum RegisterSet
- {
- RS_BOOL,
- RS_INT4,
- RS_FLOAT4,
- RS_SAMPLER,
- };
-
- enum Type
- {
- PT_VOID,
- PT_BOOL,
- PT_INT,
- PT_FLOAT,
- PT_STRING,
- PT_TEXTURE,
- PT_TEXTURE1D,
- PT_TEXTURE2D,
- PT_TEXTURE3D,
- PT_TEXTURECUBE,
- PT_SAMPLER,
- PT_SAMPLER1D,
- PT_SAMPLER2D,
- PT_SAMPLER3D,
- PT_SAMPLERCUBE,
- PT_PIXELSHADER,
- PT_VERTEXSHADER,
- PT_PIXELFRAGMENT,
- PT_VERTEXFRAGMENT,
- PT_UNSUPPORTED,
- };
-
- D3DConstant(const char *base, const ctab::ConstantInfo *constantInfo);
- ~D3DConstant();
-
- std::string name;
- RegisterSet registerSet;
- unsigned registerIndex;
- unsigned registerCount;
- Class typeClass;
- Type type;
- unsigned rows;
- unsigned columns;
- unsigned elements;
-
- // Array of structure members.
- std::vector<std::vector<const D3DConstant*> > structMembers;
-
- private:
- D3DConstant(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::StructMemberInfo *memberInfo);
- unsigned addStructMembers(const char *base, RegisterSet registerSet, unsigned registerIndex, const ctab::TypeInfo *typeInfo);
-};
-
-class D3DConstantTable
-{
- public:
- D3DConstantTable(void *blob, size_t size);
- ~D3DConstantTable();
-
- bool error() const { return mError; }
-
- unsigned constants() const { return mConstants.size(); }
- const D3DConstant *getConstant(unsigned index) const;
- const D3DConstant *getConstantByName(const char *name) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(D3DConstantTable);
- std::vector<const D3DConstant*> mConstants;
- bool mError;
-};
-
-}
-
-#endif // LIBGLESV2_D3DCONSTANTTABLE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.cpp b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
index 14d1239abf..e4218bbeec 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -7,126 +8,45 @@
// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
#include "libGLESv2/Fence.h"
-
-#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/FenceImpl.h"
+#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
-Fence::Fence(egl::Display* display)
+Fence::Fence(rx::Renderer *renderer)
{
- mDisplay = display;
- mQuery = NULL;
- mCondition = GL_NONE;
- mStatus = GL_FALSE;
+ mFence = renderer->createFence();
}
Fence::~Fence()
{
- if (mQuery != NULL)
- {
- mDisplay->freeEventQuery(mQuery);
- }
+ delete mFence;
}
GLboolean Fence::isFence()
{
- // GL_NV_fence spec:
- // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
- return mQuery != NULL;
+ return mFence->isFence();
}
void Fence::setFence(GLenum condition)
{
- if (!mQuery)
- {
- mQuery = mDisplay->allocateEventQuery();
- if (!mQuery)
- {
- return error(GL_OUT_OF_MEMORY);
- }
- }
-
- HRESULT result = mQuery->Issue(D3DISSUE_END);
- ASSERT(SUCCEEDED(result));
-
- mCondition = condition;
- mStatus = GL_FALSE;
+ mFence->setFence(condition);
}
GLboolean Fence::testFence()
{
- if (mQuery == NULL)
- {
- return error(GL_INVALID_OPERATION, GL_TRUE);
- }
-
- HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
-
- if (checkDeviceLost(result))
- {
- return error(GL_OUT_OF_MEMORY, GL_TRUE);
- }
-
- ASSERT(result == S_OK || result == S_FALSE);
- mStatus = result == S_OK;
- return mStatus;
+ return mFence->testFence();
}
void Fence::finishFence()
{
- if (mQuery == NULL)
- {
- return error(GL_INVALID_OPERATION);
- }
-
- while (!testFence())
- {
- Sleep(0);
- }
+ mFence->finishFence();
}
void Fence::getFenceiv(GLenum pname, GLint *params)
{
- if (mQuery == NULL)
- {
- return error(GL_INVALID_OPERATION);
- }
-
- 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)
- {
- params[0] = GL_TRUE;
- return;
- }
-
- HRESULT result = mQuery->GetData(NULL, 0, 0);
-
- if (checkDeviceLost(result))
- {
- params[0] = GL_TRUE;
- return error(GL_OUT_OF_MEMORY);
- }
-
- ASSERT(result == S_OK || result == S_FALSE);
- mStatus = result == S_OK;
- params[0] = mStatus;
-
- break;
- }
- case GL_FENCE_CONDITION_NV:
- params[0] = mCondition;
- break;
- default:
- return error(GL_INVALID_ENUM);
- break;
- }
+ mFence->getFenceiv(pname, params);
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Fence.h b/src/3rdparty/angle/src/libGLESv2/Fence.h
index 9626cb0ff0..1cedebb112 100644
--- a/src/3rdparty/angle/src/libGLESv2/Fence.h
+++ b/src/3rdparty/angle/src/libGLESv2/Fence.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,15 +9,12 @@
#ifndef LIBGLESV2_FENCE_H_
#define LIBGLESV2_FENCE_H_
-#define GL_APICALL
-#include <GLES2/gl2.h>
-#include <d3d9.h>
-
#include "common/angleutils.h"
-namespace egl
+namespace rx
{
-class Display;
+class Renderer;
+class FenceImpl;
}
namespace gl
@@ -26,7 +23,7 @@ namespace gl
class Fence
{
public:
- explicit Fence(egl::Display* display);
+ explicit Fence(rx::Renderer *renderer);
virtual ~Fence();
GLboolean isFence();
@@ -38,10 +35,7 @@ class Fence
private:
DISALLOW_COPY_AND_ASSIGN(Fence);
- egl::Display* mDisplay;
- IDirect3DQuery9* mQuery;
- GLenum mCondition;
- GLboolean mStatus;
+ rx::FenceImpl *mFence;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
index 5bf7b3fce8..b90d2f6023 100644
--- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
index ae646ffa12..cf039bfc21 100644
--- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
+++ b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
@@ -56,22 +56,22 @@ namespace gl
print "const static unsigned g_mantissa[2048] = {"
for i in range(0, 2048):
- print " %08x," % convertMantissa(i)
+ print " %#010x," % convertMantissa(i)
print "};\n"
print "const static unsigned g_exponent[64] = {"
for i in range(0, 64):
- print " %08x," % convertExponent(i)
+ print " %#010x," % convertExponent(i)
print "};\n"
print "const static unsigned g_offset[64] = {"
for i in range(0, 64):
- print " %08x," % convertOffset(i)
+ print " %#010x," % convertOffset(i)
print "};\n"
print """float float16ToFloat32(unsigned short h)
{
- unsigned i32 = =g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
+ unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
return *(float*) &i32;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
index 77d79c0be2..42fee3bbad 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,26 +11,38 @@
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/main.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Texture.h"
#include "libGLESv2/utilities.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Renderbuffer.h"
namespace gl
{
-Framebuffer::Framebuffer()
+Framebuffer::Framebuffer(rx::Renderer *renderer)
+ : mRenderer(renderer)
{
- mColorbufferType = GL_NONE;
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ mColorbufferTypes[colorAttachment] = GL_NONE;
+ mDrawBufferStates[colorAttachment] = GL_NONE;
+ }
+ mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
+ mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
+
mDepthbufferType = GL_NONE;
mStencilbufferType = GL_NONE;
}
Framebuffer::~Framebuffer()
{
- mColorbufferPointer.set(NULL);
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ mColorbufferPointers[colorAttachment].set(NULL);
+ }
mDepthbufferPointer.set(NULL);
mStencilbufferPointer.set(NULL);
- mNullColorbufferPointer.set(NULL);
}
Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
@@ -57,10 +70,11 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
return buffer;
}
-void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
+void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer)
{
- mColorbufferType = (colorbuffer != 0) ? type : GL_NONE;
- mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
+ ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ mColorbufferTypes[colorAttachment] = (colorbuffer != 0) ? type : GL_NONE;
+ mColorbufferPointers[colorAttachment].set(lookupRenderbuffer(type, colorbuffer));
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
@@ -77,10 +91,13 @@ void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
void Framebuffer::detachTexture(GLuint texture)
{
- if (mColorbufferPointer.id() == texture && IsInternalTextureTarget(mColorbufferType))
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
- mColorbufferType = GL_NONE;
- mColorbufferPointer.set(NULL);
+ if (mColorbufferPointers[colorAttachment].id() == texture && IsInternalTextureTarget(mColorbufferTypes[colorAttachment]))
+ {
+ mColorbufferTypes[colorAttachment] = GL_NONE;
+ mColorbufferPointers[colorAttachment].set(NULL);
+ }
}
if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType))
@@ -98,10 +115,13 @@ void Framebuffer::detachTexture(GLuint texture)
void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
- if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
- mColorbufferType = GL_NONE;
- mColorbufferPointer.set(NULL);
+ if (mColorbufferPointers[colorAttachment].id() == renderbuffer && mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER)
+ {
+ mColorbufferTypes[colorAttachment] = GL_NONE;
+ mColorbufferPointers[colorAttachment].set(NULL);
+ }
}
if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
@@ -117,9 +137,11 @@ void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
}
}
-unsigned int Framebuffer::getRenderTargetSerial()
+unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
{
- Renderbuffer *colorbuffer = mColorbufferPointer.get();
+ ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ Renderbuffer *colorbuffer = mColorbufferPointers[colorAttachment].get();
if (colorbuffer)
{
@@ -129,40 +151,7 @@ unsigned int Framebuffer::getRenderTargetSerial()
return 0;
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Framebuffer::getRenderTarget()
-{
- Renderbuffer *colorbuffer = mColorbufferPointer.get();
-
- if (colorbuffer)
- {
- return colorbuffer->getRenderTarget();
- }
-
- return NULL;
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Framebuffer::getDepthStencil()
-{
- Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
-
- if (!depthstencilbuffer)
- {
- depthstencilbuffer = mStencilbufferPointer.get();
- }
-
- if (depthstencilbuffer)
- {
- return depthstencilbuffer->getDepthStencil();
- }
-
- return NULL;
-}
-
-unsigned int Framebuffer::getDepthbufferSerial()
+unsigned int Framebuffer::getDepthbufferSerial() const
{
Renderbuffer *depthbuffer = mDepthbufferPointer.get();
@@ -174,7 +163,7 @@ unsigned int Framebuffer::getDepthbufferSerial()
return 0;
}
-unsigned int Framebuffer::getStencilbufferSerial()
+unsigned int Framebuffer::getStencilbufferSerial() const
{
Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
@@ -186,80 +175,124 @@ unsigned int Framebuffer::getStencilbufferSerial()
return 0;
}
-Renderbuffer *Framebuffer::getColorbuffer()
+Renderbuffer *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
{
- return mColorbufferPointer.get();
+ ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ return mColorbufferPointers[colorAttachment].get();
}
-Renderbuffer *Framebuffer::getDepthbuffer()
+Renderbuffer *Framebuffer::getDepthbuffer() const
{
return mDepthbufferPointer.get();
}
-Renderbuffer *Framebuffer::getStencilbuffer()
+Renderbuffer *Framebuffer::getStencilbuffer() const
{
return mStencilbufferPointer.get();
}
-Renderbuffer *Framebuffer::getNullColorbuffer()
+Renderbuffer *Framebuffer::getDepthOrStencilbuffer() const
{
- Renderbuffer *nullbuffer = mNullColorbufferPointer.get();
- Renderbuffer *depthbuffer = getDepthbuffer();
-
- if (!depthbuffer)
+ Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
+
+ if (!depthstencilbuffer)
{
- ERR("Unexpected null depthbuffer for depth-only FBO.");
- return NULL;
+ depthstencilbuffer = mStencilbufferPointer.get();
}
- GLsizei width = depthbuffer->getWidth();
- GLsizei height = depthbuffer->getHeight();
+ return depthstencilbuffer;
+}
- if (!nullbuffer ||
- width != nullbuffer->getWidth() || height != nullbuffer->getHeight())
+Renderbuffer *Framebuffer::getReadColorbuffer() const
+{
+ // Will require more logic if glReadBuffers is supported
+ return mColorbufferPointers[0].get();
+}
+
+GLenum Framebuffer::getReadColorbufferType() const
+{
+ // Will require more logic if glReadBuffers is supported
+ return mColorbufferTypes[0];
+}
+
+Renderbuffer *Framebuffer::getFirstColorbuffer() const
+{
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
- nullbuffer = new Renderbuffer(0, new Colorbuffer(width, height, GL_NONE, 0));
- mNullColorbufferPointer.set(nullbuffer);
+ if (mColorbufferTypes[colorAttachment] != GL_NONE)
+ {
+ return mColorbufferPointers[colorAttachment].get();
+ }
}
- return nullbuffer;
+ return NULL;
}
-GLenum Framebuffer::getColorbufferType()
+GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
{
- return mColorbufferType;
+ ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ return mColorbufferTypes[colorAttachment];
}
-GLenum Framebuffer::getDepthbufferType()
+GLenum Framebuffer::getDepthbufferType() const
{
return mDepthbufferType;
}
-GLenum Framebuffer::getStencilbufferType()
+GLenum Framebuffer::getStencilbufferType() const
{
return mStencilbufferType;
}
-GLuint Framebuffer::getColorbufferHandle()
+GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
{
- return mColorbufferPointer.id();
+ ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ return mColorbufferPointers[colorAttachment].id();
}
-GLuint Framebuffer::getDepthbufferHandle()
+GLuint Framebuffer::getDepthbufferHandle() const
{
return mDepthbufferPointer.id();
}
-GLuint Framebuffer::getStencilbufferHandle()
+GLuint Framebuffer::getStencilbufferHandle() const
{
return mStencilbufferPointer.id();
}
-bool Framebuffer::hasStencil()
+GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
+{
+ return mDrawBufferStates[colorAttachment];
+}
+
+void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
+{
+ mDrawBufferStates[colorAttachment] = drawBuffer;
+}
+
+bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
+{
+ return (mColorbufferTypes[colorAttachment] != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
+}
+
+bool Framebuffer::hasEnabledColorAttachment() const
+{
+ for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ if (isEnabledColorAttachment(colorAttachment))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool Framebuffer::hasStencil() const
{
if (mStencilbufferType != GL_NONE)
{
- Renderbuffer *stencilbufferObject = getStencilbuffer();
+ const Renderbuffer *stencilbufferObject = getStencilbuffer();
if (stencilbufferObject)
{
@@ -270,73 +303,112 @@ bool Framebuffer::hasStencil()
return false;
}
-GLenum Framebuffer::completeness()
+GLenum Framebuffer::completeness() const
{
- gl::Context *context = gl::getContext();
int width = 0;
int height = 0;
+ int colorbufferSize = 0;
int samples = -1;
bool missingAttachment = true;
- if (mColorbufferType != GL_NONE)
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
{
- Renderbuffer *colorbuffer = getColorbuffer();
-
- if (!colorbuffer)
+ if (mColorbufferTypes[colorAttachment] != GL_NONE)
{
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
+ const Renderbuffer *colorbuffer = getColorbuffer(colorAttachment);
- if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
- {
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
-
- if (mColorbufferType == GL_RENDERBUFFER)
- {
- if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
+ if (!colorbuffer)
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- }
- else if (IsInternalTextureTarget(mColorbufferType))
- {
- GLint internalformat = colorbuffer->getInternalFormat();
- GLenum format = gl::ExtractFormat(internalformat);
- if (IsCompressed(format) ||
- format == GL_ALPHA ||
- format == GL_LUMINANCE ||
- format == GL_LUMINANCE_ALPHA)
+ if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
{
- return GL_FRAMEBUFFER_UNSUPPORTED;
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- if ((gl::IsFloat32Format(internalformat) && !context->supportsFloat32RenderableTextures()) ||
- (gl::IsFloat16Format(internalformat) && !context->supportsFloat16RenderableTextures()))
+ if (mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER)
{
- return GL_FRAMEBUFFER_UNSUPPORTED;
+ if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
}
-
- if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
+ else if (IsInternalTextureTarget(mColorbufferTypes[colorAttachment]))
{
+ GLint internalformat = colorbuffer->getInternalFormat();
+ GLenum format = gl::ExtractFormat(internalformat);
+
+ if (IsCompressed(format) ||
+ format == GL_ALPHA ||
+ format == GL_LUMINANCE ||
+ format == GL_LUMINANCE_ALPHA)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ bool filtering, renderable;
+
+ if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
+ (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+ else
+ {
+ UNREACHABLE();
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- }
- else
- {
- UNREACHABLE();
- return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- }
- width = colorbuffer->getWidth();
- height = colorbuffer->getHeight();
- samples = colorbuffer->getSamples();
- missingAttachment = false;
+ if (!missingAttachment)
+ {
+ // all color attachments must have the same width and height
+ if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
+ }
+
+ // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
+ // all color attachments have the same number of samples for the FBO to be complete.
+ if (colorbuffer->getSamples() != samples)
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
+ }
+
+ // all color attachments attachments must have the same number of bitplanes
+ if (gl::ComputePixelSize(colorbuffer->getInternalFormat()) != colorbufferSize)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
+ for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
+ {
+ if (mColorbufferPointers[colorAttachment].get() == mColorbufferPointers[previousColorAttachment].get())
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+ }
+ else
+ {
+ width = colorbuffer->getWidth();
+ height = colorbuffer->getHeight();
+ samples = colorbuffer->getSamples();
+ colorbufferSize = gl::ComputePixelSize(colorbuffer->getInternalFormat());
+ missingAttachment = false;
+ }
+ }
}
- Renderbuffer *depthbuffer = NULL;
- Renderbuffer *stencilbuffer = NULL;
+ const Renderbuffer *depthbuffer = NULL;
+ const Renderbuffer *stencilbuffer = NULL;
if (mDepthbufferType != GL_NONE)
{
@@ -364,7 +436,7 @@ GLenum Framebuffer::completeness()
GLint internalformat = depthbuffer->getInternalFormat();
// depth texture attachments require OES/ANGLE_depth_texture
- if (!context->supportsDepthTextures())
+ if (!mRenderer->getDepthTextureSupport())
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -424,7 +496,7 @@ GLenum Framebuffer::completeness()
// texture stencil attachments come along as part
// of OES_packed_depth_stencil + OES/ANGLE_depth_texture
- if (!context->supportsDepthTextures())
+ if (!mRenderer->getDepthTextureSupport())
{
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
@@ -473,36 +545,45 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_COMPLETE;
}
-DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
+DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
+ : Framebuffer(renderer)
{
- mColorbufferPointer.set(new Renderbuffer(0, colorbuffer));
+ mColorbufferPointers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer));
- Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
+ Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
mDepthbufferPointer.set(depthStencilRenderbuffer);
mStencilbufferPointer.set(depthStencilRenderbuffer);
- mColorbufferType = GL_RENDERBUFFER;
+ mColorbufferTypes[0] = GL_RENDERBUFFER;
mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
+
+ mDrawBufferStates[0] = GL_BACK;
+ mReadBufferState = GL_BACK;
}
-int Framebuffer::getSamples()
+int Framebuffer::getSamples() const
{
if (completeness() == GL_FRAMEBUFFER_COMPLETE)
{
- return getColorbuffer()->getSamples();
- }
- else
- {
- return 0;
+ // for a complete framebuffer, all attachments must have the same sample count
+ // in this case return the first nonzero sample size
+ for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ if (mColorbufferTypes[colorAttachment] != GL_NONE)
+ {
+ return getColorbuffer(colorAttachment)->getSamples();
+ }
+ }
}
+
+ return 0;
}
-GLenum DefaultFramebuffer::completeness()
+GLenum DefaultFramebuffer::completeness() const
{
- // The default framebuffer should always be complete
- ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
-
+ // The default framebuffer *must* always be complete, though it may not be
+ // subject to the same rules as application FBOs. ie, it could have 0x0 size.
return GL_FRAMEBUFFER_COMPLETE;
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
index 14d9c2a74c..66acdc4c37 100644
--- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,12 +10,14 @@
#ifndef LIBGLESV2_FRAMEBUFFER_H_
#define LIBGLESV2_FRAMEBUFFER_H_
-#define GL_APICALL
-#include <GLES2/gl2.h>
-#include <d3d9.h>
-
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+#include "constants.h"
+
+namespace rx
+{
+class Renderer;
+}
namespace gl
{
@@ -28,45 +30,52 @@ class DepthStencilbuffer;
class Framebuffer
{
public:
- Framebuffer();
+ explicit Framebuffer(rx::Renderer *renderer);
virtual ~Framebuffer();
- void setColorbuffer(GLenum type, GLuint colorbuffer);
+ void setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer);
void setDepthbuffer(GLenum type, GLuint depthbuffer);
void setStencilbuffer(GLenum type, GLuint stencilbuffer);
void detachTexture(GLuint texture);
void detachRenderbuffer(GLuint renderbuffer);
- IDirect3DSurface9 *getRenderTarget();
- IDirect3DSurface9 *getDepthStencil();
+ unsigned int getRenderTargetSerial(unsigned int colorAttachment) const;
+ unsigned int getDepthbufferSerial() const;
+ unsigned int getStencilbufferSerial() const;
- unsigned int getRenderTargetSerial();
- unsigned int getDepthbufferSerial();
- unsigned int getStencilbufferSerial();
+ Renderbuffer *getColorbuffer(unsigned int colorAttachment) const;
+ Renderbuffer *getDepthbuffer() const;
+ Renderbuffer *getStencilbuffer() const;
+ Renderbuffer *getDepthOrStencilbuffer() const;
+ Renderbuffer *getReadColorbuffer() const;
+ GLenum getReadColorbufferType() const;
+ Renderbuffer *getFirstColorbuffer() const;
- Renderbuffer *getColorbuffer();
- Renderbuffer *getDepthbuffer();
- Renderbuffer *getStencilbuffer();
- Renderbuffer *getNullColorbuffer();
+ GLenum getColorbufferType(unsigned int colorAttachment) const;
+ GLenum getDepthbufferType() const;
+ GLenum getStencilbufferType() const;
- GLenum getColorbufferType();
- GLenum getDepthbufferType();
- GLenum getStencilbufferType();
+ GLuint getColorbufferHandle(unsigned int colorAttachment) const;
+ GLuint getDepthbufferHandle() const;
+ GLuint getStencilbufferHandle() const;
- GLuint getColorbufferHandle();
- GLuint getDepthbufferHandle();
- GLuint getStencilbufferHandle();
+ GLenum getDrawBufferState(unsigned int colorAttachment) const;
+ void setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer);
- bool hasStencil();
- int getSamples();
+ bool isEnabledColorAttachment(unsigned int colorAttachment) const;
+ bool hasEnabledColorAttachment() const;
+ bool hasStencil() const;
+ int getSamples() const;
- virtual GLenum completeness();
+ virtual GLenum completeness() const;
protected:
- GLenum mColorbufferType;
- BindingPointer<Renderbuffer> mColorbufferPointer;
+ GLenum mColorbufferTypes[IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ BindingPointer<Renderbuffer> mColorbufferPointers[IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ GLenum mDrawBufferStates[IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ GLenum mReadBufferState;
GLenum mDepthbufferType;
BindingPointer<Renderbuffer> mDepthbufferPointer;
@@ -74,7 +83,7 @@ class Framebuffer
GLenum mStencilbufferType;
BindingPointer<Renderbuffer> mStencilbufferPointer;
- BindingPointer<Renderbuffer> mNullColorbufferPointer;
+ rx::Renderer *mRenderer;
private:
DISALLOW_COPY_AND_ASSIGN(Framebuffer);
@@ -85,9 +94,9 @@ class Framebuffer
class DefaultFramebuffer : public Framebuffer
{
public:
- DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
+ DefaultFramebuffer(rx::Renderer *Renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil);
- virtual GLenum completeness();
+ virtual GLenum completeness() const;
private:
DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
diff --git a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
index c498f8a178..37da99aa18 100644
--- a/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/HandleAllocator.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
diff --git a/src/3rdparty/angle/src/libGLESv2/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/IndexDataManager.cpp
deleted file mode 100644
index 3dc0aef3f1..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/IndexDataManager.cpp
+++ /dev/null
@@ -1,473 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// IndexDataManager.cpp: Defines the IndexDataManager, a class that
-// runs the Buffer translation process for index buffers.
-
-#include "libGLESv2/IndexDataManager.h"
-
-#include "common/debug.h"
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/mathutil.h"
-#include "libGLESv2/main.h"
-
-namespace gl
-{
-unsigned int IndexBuffer::mCurrentSerial = 1;
-
-IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
-{
- mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
-
- if (context->supports32bitIndices())
- {
- mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
-
- if (!mStreamingBufferInt)
- {
- // Don't leave it in a half-initialized state
- delete mStreamingBufferShort;
- mStreamingBufferShort = NULL;
- }
- }
- else
- {
- mStreamingBufferInt = NULL;
- }
-
- if (!mStreamingBufferShort)
- {
- ERR("Failed to allocate the streaming index buffer(s).");
- }
-
- mCountingBuffer = NULL;
-}
-
-IndexDataManager::~IndexDataManager()
-{
- delete mStreamingBufferShort;
- delete mStreamingBufferInt;
- delete mCountingBuffer;
-}
-
-void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
-{
- if (type == GL_UNSIGNED_BYTE)
- {
- const GLubyte *in = static_cast<const GLubyte*>(input);
- GLushort *out = static_cast<GLushort*>(output);
-
- for (GLsizei i = 0; i < count; i++)
- {
- out[i] = in[i];
- }
- }
- else if (type == GL_UNSIGNED_INT)
- {
- memcpy(output, input, count * sizeof(GLuint));
- }
- else if (type == GL_UNSIGNED_SHORT)
- {
- memcpy(output, input, count * sizeof(GLushort));
- }
- else UNREACHABLE();
-}
-
-template <class IndexType>
-void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
-{
- *minIndex = indices[0];
- *maxIndex = indices[0];
-
- for (GLsizei i = 0; i < count; i++)
- {
- if (*minIndex > indices[i]) *minIndex = indices[i];
- if (*maxIndex < indices[i]) *maxIndex = indices[i];
- }
-}
-
-void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
-{
- if (type == GL_UNSIGNED_BYTE)
- {
- computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
- }
- else if (type == GL_UNSIGNED_INT)
- {
- computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
- }
- else if (type == GL_UNSIGNED_SHORT)
- {
- computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
- }
- else UNREACHABLE();
-}
-
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
-{
- if (!mStreamingBufferShort)
- {
- return GL_OUT_OF_MEMORY;
- }
-
- D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
- intptr_t offset = reinterpret_cast<intptr_t>(indices);
- bool alignedOffset = false;
-
- if (buffer != NULL)
- {
- switch (type)
- {
- case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
- case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
- case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
- default: UNREACHABLE(); alignedOffset = false;
- }
-
- if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
- {
- return GL_INVALID_OPERATION;
- }
-
- indices = static_cast<const GLubyte*>(buffer->data()) + offset;
- }
-
- StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
-
- StaticIndexBuffer *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
- IndexBuffer *indexBuffer = streamingBuffer;
- UINT streamOffset = 0;
-
- if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
- {
- indexBuffer = staticBuffer;
- streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
-
- if (streamOffset == -1)
- {
- streamOffset = (offset / typeSize(type)) * indexSize(format);
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
- staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
- }
- }
- else
- {
- int convertCount = count;
-
- if (staticBuffer)
- {
- if (staticBuffer->size() == 0 && alignedOffset)
- {
- indexBuffer = staticBuffer;
- convertCount = buffer->size() / typeSize(type);
- }
- else
- {
- buffer->invalidateStaticData();
- staticBuffer = NULL;
- }
- }
-
- void *output = NULL;
-
- if (indexBuffer)
- {
- indexBuffer->reserveSpace(convertCount * indexSize(format), type);
- output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
- }
-
- if (output == NULL)
- {
- ERR("Failed to map index buffer.");
- return GL_OUT_OF_MEMORY;
- }
-
- convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
- indexBuffer->unmap();
-
- computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-
- if (staticBuffer)
- {
- streamOffset = (offset / typeSize(type)) * indexSize(format);
- staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
- }
- }
-
- translated->indexBuffer = indexBuffer->getBuffer();
- translated->serial = indexBuffer->getSerial();
- translated->startIndex = streamOffset / indexSize(format);
-
- if (buffer)
- {
- buffer->promoteStaticUsage(count * typeSize(type));
- }
-
- return GL_NO_ERROR;
-}
-
-std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
-{
- return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short);
-}
-
-std::size_t IndexDataManager::typeSize(GLenum type) const
-{
- switch (type)
- {
- case GL_UNSIGNED_INT: return sizeof(GLuint);
- case GL_UNSIGNED_SHORT: return sizeof(GLushort);
- case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
- default: UNREACHABLE(); return sizeof(GLushort);
- }
-}
-
-StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count)
-{
- if (count <= 65536) // 16-bit indices
- {
- const unsigned int spaceNeeded = count * sizeof(unsigned short);
-
- if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
- {
- delete mCountingBuffer;
- mCountingBuffer = new StaticIndexBuffer(mDevice);
- mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
- UINT offset;
- unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset));
-
- if (data)
- {
- for(int i = 0; i < count; i++)
- {
- data[i] = i;
- }
-
- mCountingBuffer->unmap();
- }
- }
- }
- else if (mStreamingBufferInt) // 32-bit indices supported
- {
- const unsigned int spaceNeeded = count * sizeof(unsigned int);
-
- if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded)
- {
- delete mCountingBuffer;
- mCountingBuffer = new StaticIndexBuffer(mDevice);
- mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT);
-
- UINT offset;
- unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset));
-
- if (data)
- {
- for(int i = 0; i < count; i++)
- {
- data[i] = i;
- }
-
- mCountingBuffer->unmap();
- }
- }
- }
- else return NULL;
-
- return mCountingBuffer;
-}
-
-IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
-{
- if (size > 0)
- {
- D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
- HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating an index buffer of size %lu.", size);
- }
- }
-}
-
-IndexBuffer::~IndexBuffer()
-{
- if (mIndexBuffer)
- {
- mIndexBuffer->Release();
- }
-}
-
-IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
-{
- return mIndexBuffer;
-}
-
-unsigned int IndexBuffer::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int IndexBuffer::issueSerial()
-{
- return mCurrentSerial++;
-}
-
-void IndexBuffer::unmap()
-{
- if (mIndexBuffer)
- {
- mIndexBuffer->Unlock();
- }
-}
-
-StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format)
-{
- mWritePosition = 0;
-}
-
-StreamingIndexBuffer::~StreamingIndexBuffer()
-{
-}
-
-void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
-{
- void *mapPtr = NULL;
-
- if (mIndexBuffer)
- {
- HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
-
- if (FAILED(result))
- {
- ERR(" Lock failed with error 0x%08x", result);
- return NULL;
- }
-
- *offset = mWritePosition;
- mWritePosition += requiredSpace;
- }
-
- return mapPtr;
-}
-
-void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
-{
- if (requiredSpace > mBufferSize)
- {
- if (mIndexBuffer)
- {
- mIndexBuffer->Release();
- mIndexBuffer = NULL;
- }
-
- mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
-
- D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
- HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
- }
-
- mWritePosition = 0;
- }
- else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
- {
- void *dummy;
- mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
- mIndexBuffer->Unlock();
-
- mWritePosition = 0;
- }
-}
-
-StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN)
-{
- mCacheType = GL_NONE;
-}
-
-StaticIndexBuffer::~StaticIndexBuffer()
-{
-}
-
-void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset)
-{
- void *mapPtr = NULL;
-
- if (mIndexBuffer)
- {
- HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0);
-
- if (FAILED(result))
- {
- ERR(" Lock failed with error 0x%08x", result);
- return NULL;
- }
-
- *offset = 0;
- }
-
- return mapPtr;
-}
-
-void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
-{
- if (!mIndexBuffer && mBufferSize == 0)
- {
- D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
- HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
- }
-
- mBufferSize = requiredSpace;
- mCacheType = type;
- }
- else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
- {
- // Already allocated
- }
- else UNREACHABLE(); // Static index buffers can't be resized
-}
-
-bool StaticIndexBuffer::lookupType(GLenum type)
-{
- return mCacheType == type;
-}
-
-UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
-{
- IndexRange range = {offset, count};
-
- std::map<IndexRange, IndexResult>::iterator res = mCache.find(range);
-
- if (res == mCache.end())
- {
- return -1;
- }
-
- *minIndex = res->second.minIndex;
- *maxIndex = res->second.maxIndex;
- return res->second.streamOffset;
-}
-
-void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
-{
- IndexRange indexRange = {offset, count};
- IndexResult indexResult = {minIndex, maxIndex, streamOffset};
- mCache[indexRange] = indexResult;
-}
-
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/IndexDataManager.h
deleted file mode 100644
index c1d4168315..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/IndexDataManager.h
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// IndexDataManager.h: Defines the IndexDataManager, a class that
-// runs the Buffer translation process for index buffers.
-
-#ifndef LIBGLESV2_INDEXDATAMANAGER_H_
-#define LIBGLESV2_INDEXDATAMANAGER_H_
-
-#include <vector>
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "libGLESv2/Context.h"
-
-namespace
-{
- enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
-}
-
-namespace gl
-{
-
-struct TranslatedIndexData
-{
- UINT minIndex;
- UINT maxIndex;
- UINT startIndex;
-
- IDirect3DIndexBuffer9 *indexBuffer;
- unsigned int serial;
-};
-
-class IndexBuffer
-{
- public:
- IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format);
- virtual ~IndexBuffer();
-
- UINT size() const { return mBufferSize; }
- virtual void *map(UINT requiredSpace, UINT *offset) = 0;
- void unmap();
- virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0;
-
- IDirect3DIndexBuffer9 *getBuffer() const;
- unsigned int getSerial() const;
-
- protected:
- IDirect3DDevice9 *const mDevice;
-
- IDirect3DIndexBuffer9 *mIndexBuffer;
- UINT mBufferSize;
-
- unsigned int mSerial;
- static unsigned int issueSerial();
- static unsigned int mCurrentSerial;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
-};
-
-class StreamingIndexBuffer : public IndexBuffer
-{
- public:
- StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format);
- ~StreamingIndexBuffer();
-
- virtual void *map(UINT requiredSpace, UINT *offset);
- virtual void reserveSpace(UINT requiredSpace, GLenum type);
-
- private:
- UINT mWritePosition;
-};
-
-class StaticIndexBuffer : public IndexBuffer
-{
- public:
- explicit StaticIndexBuffer(IDirect3DDevice9 *device);
- ~StaticIndexBuffer();
-
- virtual void *map(UINT requiredSpace, UINT *offset);
- virtual void reserveSpace(UINT requiredSpace, GLenum type);
-
- bool lookupType(GLenum type);
- UINT lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex); // Returns the offset into the index buffer, or -1 if not found
- void addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset);
-
- private:
- GLenum mCacheType;
-
- struct IndexRange
- {
- intptr_t offset;
- GLsizei count;
-
- bool operator<(const IndexRange& rhs) const
- {
- if (offset != rhs.offset)
- {
- return offset < rhs.offset;
- }
- if (count != rhs.count)
- {
- return count < rhs.count;
- }
- return false;
- }
- };
-
- struct IndexResult
- {
- UINT minIndex;
- UINT maxIndex;
- UINT streamOffset;
- };
-
- std::map<IndexRange, IndexResult> mCache;
-};
-
-class IndexDataManager
-{
- public:
- IndexDataManager(Context *context, IDirect3DDevice9 *evice);
- virtual ~IndexDataManager();
-
- GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
- StaticIndexBuffer *getCountingIndices(GLsizei count);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
-
- std::size_t typeSize(GLenum type) const;
- std::size_t indexSize(D3DFORMAT format) const;
-
- IDirect3DDevice9 *const mDevice;
-
- StreamingIndexBuffer *mStreamingBufferShort;
- StreamingIndexBuffer *mStreamingBufferInt;
- StaticIndexBuffer *mCountingBuffer;
-};
-
-}
-
-#endif // LIBGLESV2_INDEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.cpp b/src/3rdparty/angle/src/libGLESv2/Program.cpp
index 5f53a1f581..c38aa5a61a 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Program.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,14 +10,7 @@
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
-
-#include "common/debug.h"
-
-#include "libGLESv2/main.h"
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/utilities.h"
-
-#include <string>
+#include "libGLESv2/ResourceManager.h"
namespace gl
{
@@ -91,7 +85,7 @@ void InfoLog::appendSanitized(const char *message)
}
while (found != std::string::npos);
- append("%s\n", msg.c_str());
+ append("%s", msg.c_str());
}
void InfoLog::append(const char *format, ...)
@@ -112,15 +106,17 @@ void InfoLog::append(const char *format, ...)
if (!mInfoLog)
{
- mInfoLog = new char[infoLength + 1];
+ mInfoLog = new char[infoLength + 2];
strcpy(mInfoLog, info);
+ strcpy(mInfoLog + infoLength, "\n");
}
else
{
size_t logLength = strlen(mInfoLog);
- char *newLog = new char[logLength + infoLength + 1];
+ char *newLog = new char[logLength + infoLength + 2];
strcpy(newLog, mInfoLog);
strcpy(newLog + logLength, info);
+ strcpy(newLog + logLength + infoLength, "\n");
delete[] mInfoLog;
mInfoLog = newLog;
@@ -136,7 +132,7 @@ void InfoLog::reset()
}
}
-Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
+Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
{
mFragmentShader = NULL;
mVertexShader = NULL;
@@ -144,6 +140,7 @@ Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(man
mDeleteStatus = false;
mLinked = false;
mRefCount = 0;
+ mRenderer = renderer;
}
Program::~Program()
@@ -247,7 +244,7 @@ bool Program::link()
mInfoLog.reset();
- mProgramBinary.set(new ProgramBinary());
+ mProgramBinary.set(new ProgramBinary(mRenderer));
mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader);
return mLinked;
@@ -304,7 +301,7 @@ bool Program::setProgramBinary(const void *binary, GLsizei length)
mInfoLog.reset();
- mProgramBinary.set(new ProgramBinary());
+ mProgramBinary.set(new ProgramBinary(mRenderer));
mLinked = mProgramBinary->load(mInfoLog, binary, length);
if (!mLinked)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Program.h b/src/3rdparty/angle/src/libGLESv2/Program.h
index 1c4716bfe8..a9db83403d 100644
--- a/src/3rdparty/angle/src/libGLESv2/Program.h
+++ b/src/3rdparty/angle/src/libGLESv2/Program.h
@@ -13,14 +13,22 @@
#include <string>
#include <set>
-#include "libGLESv2/Shader.h"
-#include "libGLESv2/Context.h"
+#include "common/angleutils.h"
+#include "common/RefCountObject.h"
+#include "libGLESv2/Constants.h"
+
+namespace rx
+{
+class Renderer;
+}
namespace gl
{
class ResourceManager;
class FragmentShader;
class VertexShader;
+class ProgramBinary;
+class Shader;
extern const char * const g_fakepath;
@@ -57,7 +65,7 @@ class InfoLog
class Program
{
public:
- Program(ResourceManager *manager, GLuint handle);
+ Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle);
~Program();
@@ -112,6 +120,7 @@ class Program
unsigned int mRefCount;
ResourceManager *mResourceManager;
+ rx::Renderer *mRenderer;
const GLuint mHandle;
InfoLog mInfoLog;
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
index b3f5e3b867..14e6c94ca4 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -8,21 +9,21 @@
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
#include "libGLESv2/BinaryStream.h"
-#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/renderer/ShaderExecutable.h"
#include "common/debug.h"
#include "common/version.h"
+#include "utilities.h"
#include "libGLESv2/main.h"
#include "libGLESv2/Shader.h"
-#include "libGLESv2/utilities.h"
-
-#include <string>
+#include "libGLESv2/Program.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/VertexDataManager.h"
-#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
-#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
-#endif
+#undef near
+#undef far
namespace gl
{
@@ -33,43 +34,18 @@ std::string str(int i)
return buffer;
}
-Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize)
- : type(type), _name(_name), name(ProgramBinary::undecorateUniform(_name)), arraySize(arraySize)
-{
- int bytes = UniformInternalSize(type) * arraySize;
- data = new unsigned char[bytes];
- memset(data, 0, bytes);
- dirty = true;
-}
-
-Uniform::~Uniform()
-{
- delete[] data;
-}
-
-bool Uniform::isArray()
-{
- size_t dot = _name.find_last_of('.');
- if (dot == std::string::npos) dot = -1;
-
- return _name.compare(dot + 1, dot + 4, "ar_") == 0;
-}
-
-UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index)
- : name(ProgramBinary::undecorateUniform(_name)), element(element), index(index)
+UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index)
+ : name(name), element(element), index(index)
{
}
unsigned int ProgramBinary::mCurrentSerial = 1;
-ProgramBinary::ProgramBinary() : RefCountObject(0), mSerial(issueSerial())
+ProgramBinary::ProgramBinary(rx::Renderer *renderer) : mRenderer(renderer), RefCountObject(0), mSerial(issueSerial())
{
- mDevice = getDevice();
-
mPixelExecutable = NULL;
mVertexExecutable = NULL;
- mConstantTablePS = NULL;
- mConstantTableVS = NULL;
+ mGeometryExecutable = NULL;
mValidated = false;
@@ -83,36 +59,26 @@ ProgramBinary::ProgramBinary() : RefCountObject(0), mSerial(issueSerial())
mSamplersPS[index].active = false;
}
- for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++)
+ for (int index = 0; index < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
{
mSamplersVS[index].active = false;
}
mUsedVertexSamplerRange = 0;
mUsedPixelSamplerRange = 0;
-
- mDxDepthRangeLocation = -1;
- mDxDepthLocation = -1;
- mDxCoordLocation = -1;
- mDxHalfPixelSizeLocation = -1;
- mDxFrontCCWLocation = -1;
- mDxPointsOrLinesLocation = -1;
+ mUsesPointSize = false;
}
ProgramBinary::~ProgramBinary()
{
- if (mPixelExecutable)
- {
- mPixelExecutable->Release();
- }
+ delete mPixelExecutable;
+ mPixelExecutable = NULL;
- if (mVertexExecutable)
- {
- mVertexExecutable->Release();
- }
+ delete mVertexExecutable;
+ mVertexExecutable = NULL;
- delete mConstantTablePS;
- delete mConstantTableVS;
+ delete mGeometryExecutable;
+ mGeometryExecutable = NULL;
while (!mUniforms.empty())
{
@@ -131,16 +97,21 @@ unsigned int ProgramBinary::issueSerial()
return mCurrentSerial++;
}
-IDirect3DPixelShader9 *ProgramBinary::getPixelShader()
+rx::ShaderExecutable *ProgramBinary::getPixelExecutable()
{
return mPixelExecutable;
}
-IDirect3DVertexShader9 *ProgramBinary::getVertexShader()
+rx::ShaderExecutable *ProgramBinary::getVertexExecutable()
{
return mVertexExecutable;
}
+rx::ShaderExecutable *ProgramBinary::getGeometryExecutable()
+{
+ return mGeometryExecutable;
+}
+
GLuint ProgramBinary::getAttributeLocation(const char *name)
{
if (name)
@@ -184,6 +155,16 @@ bool ProgramBinary::usesPointSize() const
return mUsesPointSize;
}
+bool ProgramBinary::usesPointSpriteEmulation() const
+{
+ return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
+}
+
+bool ProgramBinary::usesGeometryShader() const
+{
+ return usesPointSpriteEmulation();
+}
+
// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler
// index (0-15 for the pixel shader and 0-3 for the vertex shader).
GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerIndex)
@@ -211,7 +192,7 @@ GLint ProgramBinary::getSamplerMapping(SamplerType type, unsigned int samplerInd
default: UNREACHABLE();
}
- if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)getContext()->getMaximumCombinedTextureImageUnits())
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)mRenderer->getMaxCombinedTextureImageUnits())
{
return logicalTextureUnit;
}
@@ -275,15 +256,15 @@ bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat*
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_FLOAT)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+ if (targetUniform->type == GL_FLOAT)
+ {
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
@@ -298,24 +279,16 @@ bool ProgramBinary::setUniform1fv(GLint location, GLsizei count, const GLfloat*
}
else if (targetUniform->type == GL_BOOL)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (int i = 0; i < count; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0.0f)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = GL_FALSE;
+ boolParams[2] = GL_FALSE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 1;
}
}
else
@@ -336,15 +309,15 @@ bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_FLOAT_VEC2)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+ if (targetUniform->type == GL_FLOAT_VEC2)
+ {
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
@@ -359,25 +332,16 @@ bool ProgramBinary::setUniform2fv(GLint location, GLsizei count, const GLfloat *
}
else if (targetUniform->type == GL_BOOL_VEC2)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
-
- for (int i = 0; i < count * 2; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0.0f)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = GL_FALSE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 2;
}
}
else
@@ -398,15 +362,15 @@ bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_FLOAT_VEC3)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+ if (targetUniform->type == GL_FLOAT_VEC3)
+ {
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
for (int i = 0; i < count; i++)
@@ -421,24 +385,16 @@ bool ProgramBinary::setUniform3fv(GLint location, GLsizei count, const GLfloat *
}
else if (targetUniform->type == GL_BOOL_VEC3)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (int i = 0; i < count * 3; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0.0f)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 3;
}
}
else
@@ -459,38 +415,39 @@ bool ProgramBinary::setUniform4fv(GLint location, GLsizei count, const GLfloat *
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_FLOAT_VEC4)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+
+ if (targetUniform->type == GL_FLOAT_VEC4)
+ {
+ GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
- memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 4,
- v, 4 * sizeof(GLfloat) * count);
+ for (int i = 0; i < count; i++)
+ {
+ target[0] = v[0];
+ target[1] = v[1];
+ target[2] = v[2];
+ target[3] = v[3];
+ target += 4;
+ v += 4;
+ }
}
else if (targetUniform->type == GL_BOOL_VEC4)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (int i = 0; i < count * 4; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0.0f)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = (v[2] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams[3] = (v[3] == 0.0f) ? GL_FALSE : GL_TRUE;
+ boolParams += 4;
+ v += 4;
}
}
else
@@ -547,14 +504,14 @@ bool ProgramBinary::setUniformMatrix2fv(GLint location, GLsizei count, const GLf
return false;
}
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
+ if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
-
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8;
+
for (int i = 0; i < count; i++)
{
transposeMatrix<GLfloat,4,2,2,2>(target, value);
@@ -580,14 +537,14 @@ bool ProgramBinary::setUniformMatrix3fv(GLint location, GLsizei count, const GLf
return false;
}
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
+ if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
-
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12;
+
for (int i = 0; i < count; i++)
{
transposeMatrix<GLfloat,4,3,3,3>(target, value);
@@ -614,14 +571,14 @@ bool ProgramBinary::setUniformMatrix4fv(GLint location, GLsizei count, const GLf
return false;
}
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
+ if (elementCount == 1 && count > 1)
return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
-
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16);
+
for (int i = 0; i < count; i++)
{
transposeMatrix<GLfloat,4,4,4,4>(target, value);
@@ -642,40 +599,41 @@ bool ProgramBinary::setUniform1iv(GLint location, GLsizei count, const GLint *v)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
+ int elementCount = targetUniform->elementCount();
+
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
+
if (targetUniform->type == GL_INT ||
targetUniform->type == GL_SAMPLER_2D ||
targetUniform->type == GL_SAMPLER_CUBE)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint),
- v, sizeof(GLint) * count);
+ for (int i = 0; i < count; i++)
+ {
+ target[0] = v[0];
+ target[1] = 0;
+ target[2] = 0;
+ target[3] = 0;
+ target += 4;
+ v += 1;
+ }
}
else if (targetUniform->type == GL_BOOL)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (int i = 0; i < count; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = GL_FALSE;
+ boolParams[2] = GL_FALSE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 1;
}
}
else
@@ -696,38 +654,39 @@ bool ProgramBinary::setUniform2iv(GLint location, GLsizei count, const GLint *v)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_INT_VEC2)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
+
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ if (targetUniform->type == GL_INT_VEC2)
+ {
+ GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 2,
- v, 2 * sizeof(GLint) * count);
+ for (int i = 0; i < count; i++)
+ {
+ target[0] = v[0];
+ target[1] = v[1];
+ target[2] = 0;
+ target[3] = 0;
+ target += 4;
+ v += 2;
+ }
}
else if (targetUniform->type == GL_BOOL_VEC2)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2;
-
- for (int i = 0; i < count * 2; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = GL_FALSE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 2;
}
}
else
@@ -748,38 +707,39 @@ bool ProgramBinary::setUniform3iv(GLint location, GLsizei count, const GLint *v)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_INT_VEC3)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
- memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 3,
- v, 3 * sizeof(GLint) * count);
+ if (targetUniform->type == GL_INT_VEC3)
+ {
+ GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ target[0] = v[0];
+ target[1] = v[1];
+ target[2] = v[2];
+ target[3] = 0;
+ target += 4;
+ v += 3;
+ }
}
else if (targetUniform->type == GL_BOOL_VEC3)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
-
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (int i = 0; i < count * 3; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[3] = GL_FALSE;
+ boolParams += 4;
+ v += 3;
}
}
else
@@ -800,38 +760,39 @@ bool ProgramBinary::setUniform4iv(GLint location, GLsizei count, const GLint *v)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_INT_VEC4)
- {
- int arraySize = targetUniform->arraySize;
+ int elementCount = targetUniform->elementCount();
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (elementCount == 1 && count > 1)
+ return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
+ count = std::min(elementCount - (int)mUniformIndex[location].element, count);
- memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLint) * 4,
- v, 4 * sizeof(GLint) * count);
+ if (targetUniform->type == GL_INT_VEC4)
+ {
+ GLint *target = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
+
+ for (int i = 0; i < count; i++)
+ {
+ target[0] = v[0];
+ target[1] = v[1];
+ target[2] = v[2];
+ target[3] = v[3];
+ target += 4;
+ v += 4;
+ }
}
else if (targetUniform->type == GL_BOOL_VEC4)
{
- int arraySize = targetUniform->arraySize;
-
- if (arraySize == 1 && count > 1)
- return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- count = std::min(arraySize - (int)mUniformIndex[location].element, count);
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4;
-
- for (int i = 0; i < count * 4; ++i)
+ for (int i = 0; i < count; i++)
{
- if (v[i] == 0)
- {
- boolParams[i] = GL_FALSE;
- }
- else
- {
- boolParams[i] = GL_TRUE;
- }
+ boolParams[0] = (v[0] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[1] = (v[1] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[2] = (v[2] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams[3] = (v[3] == 0) ? GL_FALSE : GL_TRUE;
+ boolParams += 4;
+ v += 4;
}
}
else
@@ -874,30 +835,29 @@ bool ProgramBinary::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *para
break;
default:
{
- unsigned int count = UniformExternalComponentCount(targetUniform->type);
- unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
+ unsigned int size = UniformComponentCount(targetUniform->type);
switch (UniformComponentType(targetUniform->type))
{
case GL_BOOL:
{
- GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * internalCount;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; ++i)
+ for (unsigned int i = 0; i < size; i++)
{
params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
}
}
break;
case GL_FLOAT:
- memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLfloat),
- count * sizeof(GLfloat));
+ memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLfloat),
+ size * sizeof(GLfloat));
break;
case GL_INT:
{
- GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * internalCount;
+ GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; ++i)
+ for (unsigned int i = 0; i < size; i++)
{
params[i] = (float)intParams[i];
}
@@ -933,50 +893,43 @@ bool ProgramBinary::getUniformiv(GLint location, GLsizei *bufSize, GLint *params
switch (targetUniform->type)
{
case GL_FLOAT_MAT2:
- {
- transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
- }
+ transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8);
break;
case GL_FLOAT_MAT3:
- {
- transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
- }
+ transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12);
break;
case GL_FLOAT_MAT4:
- {
- transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
- }
+ transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16);
break;
default:
{
- unsigned int count = UniformExternalComponentCount(targetUniform->type);
- unsigned int internalCount = UniformInternalComponentCount(targetUniform->type);
+ unsigned int size = VariableColumnCount(targetUniform->type);
switch (UniformComponentType(targetUniform->type))
{
case GL_BOOL:
{
- GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * internalCount;
+ GLint *boolParams = (GLint*)targetUniform->data + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; ++i)
+ for (unsigned int i = 0; i < size; i++)
{
- params[i] = (GLint)boolParams[i];
+ params[i] = boolParams[i];
}
}
break;
case GL_FLOAT:
{
- GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * internalCount;
+ GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4;
- for (unsigned int i = 0; i < count; ++i)
+ for (unsigned int i = 0; i < size; i++)
{
params[i] = (GLint)floatParams[i];
}
}
break;
case GL_INT:
- memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLint),
- count * sizeof(GLint));
+ memcpy(params, targetUniform->data + mUniformIndex[location].element * 4 * sizeof(GLint),
+ size * sizeof(GLint));
break;
default: UNREACHABLE();
}
@@ -995,153 +948,67 @@ void ProgramBinary::dirtyAllUniforms()
}
}
-// Applies all the uniforms set for this program object to the Direct3D 9 device
+// Applies all the uniforms set for this program object to the renderer
void ProgramBinary::applyUniforms()
{
- for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) {
+ // Retrieve sampler uniform values
+ for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub)
+ {
Uniform *targetUniform = *ub;
if (targetUniform->dirty)
{
- int arraySize = targetUniform->arraySize;
- GLfloat *f = (GLfloat*)targetUniform->data;
- GLint *i = (GLint*)targetUniform->data;
- GLboolean *b = (GLboolean*)targetUniform->data;
-
- switch (targetUniform->type)
+ if (targetUniform->type == GL_SAMPLER_2D ||
+ targetUniform->type == GL_SAMPLER_CUBE)
{
- case GL_BOOL: applyUniformnbv(targetUniform, arraySize, 1, b); break;
- case GL_BOOL_VEC2: applyUniformnbv(targetUniform, arraySize, 2, b); break;
- case GL_BOOL_VEC3: applyUniformnbv(targetUniform, arraySize, 3, b); break;
- case GL_BOOL_VEC4: applyUniformnbv(targetUniform, arraySize, 4, b); break;
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_FLOAT_VEC4:
- case GL_FLOAT_MAT2:
- case GL_FLOAT_MAT3:
- case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break;
- case GL_SAMPLER_2D:
- case GL_SAMPLER_CUBE:
- case GL_INT: applyUniform1iv(targetUniform, arraySize, i); break;
- case GL_INT_VEC2: applyUniform2iv(targetUniform, arraySize, i); break;
- case GL_INT_VEC3: applyUniform3iv(targetUniform, arraySize, i); break;
- case GL_INT_VEC4: applyUniform4iv(targetUniform, arraySize, i); break;
- default:
- UNREACHABLE();
- }
-
- targetUniform->dirty = false;
- }
- }
-}
+ int count = targetUniform->elementCount();
+ GLint (*v)[4] = (GLint(*)[4])targetUniform->data;
-// Compiles the HLSL code of the attached shaders into executable binaries
-ID3D10Blob *ProgramBinary::compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, D3DConstantTable **constantTable)
-{
- if (!hlsl)
- {
- return NULL;
- }
-
- DWORD result = NOERROR;
- UINT flags = 0;
- std::string sourceText;
- if (perfActive())
- {
- flags |= D3DCOMPILE_DEBUG;
-#ifdef NDEBUG
- flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
-#else
- flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
-#endif
-
- std::string sourcePath = getTempPath();
- sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
- writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
- }
- else
- {
- flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL;
- sourceText = hlsl;
- }
-
- // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
- // Try the default flags first and if compilation fails, try some alternatives.
- const static UINT extraFlags[] =
- {
- 0,
- D3DCOMPILE_AVOID_FLOW_CONTROL,
- D3DCOMPILE_PREFER_FLOW_CONTROL
- };
-
- const static char * const extraFlagNames[] =
- {
- "default",
- "avoid flow control",
- "prefer flow control"
- };
-
- for (int i = 0; i < sizeof(extraFlags) / sizeof(UINT); ++i)
- {
- ID3D10Blob *errorMessage = NULL;
- ID3D10Blob *binary = NULL;
- result = D3DCompile(hlsl, strlen(hlsl), g_fakepath, NULL, NULL, "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
-
- if (errorMessage)
- {
- const char *message = (const char*)errorMessage->GetBufferPointer();
+ if (targetUniform->psRegisterIndex >= 0)
+ {
+ unsigned int firstIndex = targetUniform->psRegisterIndex;
- infoLog.appendSanitized(message);
- TRACE("\n%s", hlsl);
- TRACE("\n%s", message);
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
- errorMessage->Release();
- errorMessage = NULL;
- }
+ if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+ {
+ ASSERT(mSamplersPS[samplerIndex].active);
+ mSamplersPS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
- if (SUCCEEDED(result))
- {
- D3DConstantTable *table = new D3DConstantTable(binary->GetBufferPointer(), binary->GetBufferSize());
- if (table->error())
- {
- delete table;
- binary->Release();
- return NULL;
- }
+ if (targetUniform->vsRegisterIndex >= 0)
+ {
+ unsigned int firstIndex = targetUniform->vsRegisterIndex;
- *constantTable = table;
-
- return binary;
- }
- else
- {
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- return error(GL_OUT_OF_MEMORY, (ID3D10Blob*) NULL);
- }
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int samplerIndex = firstIndex + i;
- infoLog.append("Warning: D3D shader compilation failed with ");
- infoLog.append(extraFlagNames[i]);
- infoLog.append(" flags.");
- if (i + 1 < sizeof(extraFlagNames) / sizeof(char*))
- {
- infoLog.append(" Retrying with ");
- infoLog.append(extraFlagNames[i + 1]);
- infoLog.append(".\n");
+ if (samplerIndex < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS)
+ {
+ ASSERT(mSamplersVS[samplerIndex].active);
+ mSamplersVS[samplerIndex].logicalTextureUnit = v[i][0];
+ }
+ }
+ }
}
}
}
- return NULL;
+ mRenderer->applyUniforms(this, &mUniforms);
}
// Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111
// Returns the number of used varying registers, or -1 if unsuccesful
int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader)
{
- Context *context = getContext();
- const int maxVaryingVectors = context->getMaximumVaryingVectors();
+ const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
+
+ fragmentShader->resetVaryingsRegisterAssignment();
for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{
@@ -1286,47 +1153,39 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], F
return registers;
}
-bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader)
+bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
+ std::string& pixelHLSL, std::string& vertexHLSL,
+ FragmentShader *fragmentShader, VertexShader *vertexShader)
{
if (pixelHLSL.empty() || vertexHLSL.empty())
{
return false;
}
- // Reset the varying register assignments
- for (VaryingList::iterator fragVar = fragmentShader->mVaryings.begin(); fragVar != fragmentShader->mVaryings.end(); fragVar++)
- {
- fragVar->reg = -1;
- fragVar->col = -1;
- }
-
- for (VaryingList::iterator vtxVar = vertexShader->mVaryings.begin(); vtxVar != vertexShader->mVaryings.end(); vtxVar++)
- {
- vtxVar->reg = -1;
- vtxVar->col = -1;
- }
-
- // Map the varyings to the register file
- const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
- int registers = packVaryings(infoLog, packing, fragmentShader);
-
- if (registers < 0)
+ bool usesMRT = fragmentShader->mUsesMultipleRenderTargets;
+ bool usesFragColor = fragmentShader->mUsesFragColor;
+ bool usesFragData = fragmentShader->mUsesFragData;
+ if (usesMRT && usesFragColor && usesFragData)
{
+ infoLog.append("Cannot use both gl_FragColor and gl_FragData in the same fragment shader.");
return false;
}
// Write the HLSL input/output declarations
- Context *context = getContext();
- const bool sm3 = context->supportsShaderModel3();
- const int maxVaryingVectors = context->getMaximumVaryingVectors();
+ const int shaderModel = mRenderer->getMajorShaderModel();
+ const int maxVaryingVectors = mRenderer->getMaxVaryingVectors();
- if (registers == maxVaryingVectors && fragmentShader->mUsesFragCoord)
+ const int registersNeeded = registers + (fragmentShader->mUsesFragCoord ? 1 : 0) + (fragmentShader->mUsesPointCoord ? 1 : 0);
+
+ if (registersNeeded > maxVaryingVectors)
{
- infoLog.append("No varying registers left to support gl_FragCoord");
+ infoLog.append("No varying registers left to support gl_FragCoord/gl_PointCoord");
return false;
}
+ vertexShader->resetVaryingsRegisterAssignment();
+
for (VaryingList::iterator input = fragmentShader->mVaryings.begin(); input != fragmentShader->mVaryings.end(); input++)
{
bool matched = false;
@@ -1359,10 +1218,38 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
}
mUsesPointSize = vertexShader->mUsesPointSize;
- std::string varyingSemantic = (mUsesPointSize && sm3) ? "COLOR" : "TEXCOORD";
+ std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
+ std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
+ std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
+
+ const unsigned int renderTargetCount = usesMRT ? mRenderer->getMaxRenderTargets() : 1;
+
+ // special varyings that use reserved registers
+ int reservedRegisterIndex = registers;
+ std::string fragCoordSemantic;
+ std::string pointCoordSemantic;
+
+ if (fragmentShader->mUsesFragCoord)
+ {
+ fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
+ }
+
+ if (fragmentShader->mUsesPointCoord)
+ {
+ // Shader model 3 uses a special TEXCOORD semantic for point sprite texcoords.
+ // In DX11 we compute this in the GS.
+ if (shaderModel == 3)
+ {
+ pointCoordSemantic = "TEXCOORD0";
+ }
+ else if (shaderModel >= 4)
+ {
+ pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
+ }
+ }
vertexHLSL += "struct VS_INPUT\n"
- "{\n";
+ "{\n";
int semanticIndex = 0;
for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
@@ -1385,10 +1272,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
}
vertexHLSL += "};\n"
- "\n"
- "struct VS_OUTPUT\n"
- "{\n"
- " float4 gl_Position : POSITION;\n";
+ "\n"
+ "struct VS_OUTPUT\n"
+ "{\n";
+
+ if (shaderModel < 4)
+ {
+ vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n";
+ }
for (int r = 0; r < registers; r++)
{
@@ -1399,18 +1290,23 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
if (fragmentShader->mUsesFragCoord)
{
- vertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ vertexHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
}
- if (vertexShader->mUsesPointSize && sm3)
+ if (vertexShader->mUsesPointSize && shaderModel >= 3)
{
vertexHLSL += " float gl_PointSize : PSIZE;\n";
}
+ if (shaderModel >= 4)
+ {
+ vertexHLSL += " float4 gl_Position : " + positionSemantic + ";\n";
+ }
+
vertexHLSL += "};\n"
- "\n"
- "VS_OUTPUT main(VS_INPUT input)\n"
- "{\n";
+ "\n"
+ "VS_OUTPUT main(VS_INPUT input)\n"
+ "{\n";
for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{
@@ -1424,16 +1320,30 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
vertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n";
}
- vertexHLSL += "\n"
- " gl_main();\n"
- "\n"
- " VS_OUTPUT output;\n"
- " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n"
- " output.gl_Position.y = -(gl_Position.y + dx_HalfPixelSize.y * gl_Position.w);\n"
- " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
- " output.gl_Position.w = gl_Position.w;\n";
+ if (shaderModel >= 4)
+ {
+ vertexHLSL += "\n"
+ " gl_main();\n"
+ "\n"
+ " VS_OUTPUT output;\n"
+ " output.gl_Position.x = gl_Position.x;\n"
+ " output.gl_Position.y = -gl_Position.y;\n"
+ " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ " output.gl_Position.w = gl_Position.w;\n";
+ }
+ else
+ {
+ vertexHLSL += "\n"
+ " gl_main();\n"
+ "\n"
+ " VS_OUTPUT output;\n"
+ " output.gl_Position.x = gl_Position.x * dx_ViewAdjust.z + dx_ViewAdjust.x * gl_Position.w;\n"
+ " output.gl_Position.y = -(gl_Position.y * dx_ViewAdjust.w + dx_ViewAdjust.y * gl_Position.w);\n"
+ " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
+ " output.gl_Position.w = gl_Position.w;\n";
+ }
- if (vertexShader->mUsesPointSize && sm3)
+ if (vertexShader->mUsesPointSize && shaderModel >= 3)
{
vertexHLSL += " output.gl_PointSize = gl_PointSize;\n";
}
@@ -1505,11 +1415,11 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
}
vertexHLSL += "\n"
- " return output;\n"
- "}\n";
+ " return output;\n"
+ "}\n";
pixelHLSL += "struct PS_INPUT\n"
- "{\n";
+ "{\n";
for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{
@@ -1521,7 +1431,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
for (int j = 0; j < rows; j++)
{
std::string n = str(varying->reg + i * rows + j);
- pixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n";
+ pixelHLSL += " float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n";
}
}
}
@@ -1530,53 +1440,91 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
if (fragmentShader->mUsesFragCoord)
{
- pixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
- if (sm3) {
+ pixelHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
+ }
+
+ if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
+ {
+ pixelHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
+ }
+
+ // Must consume the PSIZE element if the geometry shader is not active
+ // We won't know if we use a GS until we draw
+ if (vertexShader->mUsesPointSize && shaderModel >= 4)
+ {
+ pixelHLSL += " float gl_PointSize : PSIZE;\n";
+ }
+
+ if (fragmentShader->mUsesFragCoord)
+ {
+ if (shaderModel >= 4)
+ {
+ pixelHLSL += " float4 dx_VPos : SV_Position;\n";
+ }
+ else if (shaderModel >= 3)
+ {
pixelHLSL += " float2 dx_VPos : VPOS;\n";
}
}
- if (fragmentShader->mUsesPointCoord && sm3)
+ pixelHLSL += "};\n"
+ "\n"
+ "struct PS_OUTPUT\n"
+ "{\n";
+
+ for (unsigned int i = 0; i < renderTargetCount; i++)
{
- pixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n";
+ pixelHLSL += " float4 gl_Color" + str(i) + " : " + targetSemantic + str(i) + ";\n";
}
+ pixelHLSL += "};\n"
+ "\n";
+
if (fragmentShader->mUsesFrontFacing)
{
- pixelHLSL += " float vFace : VFACE;\n";
+ if (shaderModel >= 4)
+ {
+ pixelHLSL += "PS_OUTPUT main(PS_INPUT input, bool isFrontFace : SV_IsFrontFace)\n"
+ "{\n";
+ }
+ else
+ {
+ pixelHLSL += "PS_OUTPUT main(PS_INPUT input, float vFace : VFACE)\n"
+ "{\n";
+ }
+ }
+ else
+ {
+ pixelHLSL += "PS_OUTPUT main(PS_INPUT input)\n"
+ "{\n";
}
-
- pixelHLSL += "};\n"
- "\n"
- "struct PS_OUTPUT\n"
- "{\n"
- " float4 gl_Color[1] : COLOR;\n"
- "};\n"
- "\n"
- "PS_OUTPUT main(PS_INPUT input)\n"
- "{\n";
if (fragmentShader->mUsesFragCoord)
{
pixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
- if (sm3)
+ if (shaderModel >= 4)
+ {
+ pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n"
+ " gl_FragCoord.y = input.dx_VPos.y;\n";
+ }
+ else if (shaderModel >= 3)
{
pixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n"
- " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
+ " gl_FragCoord.y = input.dx_VPos.y + 0.5;\n";
}
else
{
- // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget()
- pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n"
- " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n";
+ // dx_ViewCoords contains the viewport width/2, height/2, center.x and center.y. See Renderer::setViewport()
+ pixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_ViewCoords.x + dx_ViewCoords.z;\n"
+ " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_ViewCoords.y + dx_ViewCoords.w;\n";
}
- pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
- " gl_FragCoord.w = rhw;\n";
+ pixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_DepthFront.x + dx_DepthFront.y;\n"
+ " gl_FragCoord.w = rhw;\n";
}
- if (fragmentShader->mUsesPointCoord && sm3)
+ if (fragmentShader->mUsesPointCoord && shaderModel >= 3)
{
pixelHLSL += " gl_PointCoord.x = input.gl_PointCoord.x;\n";
pixelHLSL += " gl_PointCoord.y = 1.0 - input.gl_PointCoord.y;\n";
@@ -1584,7 +1532,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
if (fragmentShader->mUsesFrontFacing)
{
- pixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
+ if (shaderModel <= 3)
+ {
+ pixelHLSL += " gl_FrontFacing = (vFace * dx_DepthFront.z >= 0.0);\n";
+ }
+ else
+ {
+ pixelHLSL += " gl_FrontFacing = isFrontFace;\n";
+ }
}
for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
@@ -1609,7 +1564,14 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
pixelHLSL += "[" + str(j) + "]";
}
- pixelHLSL += " = input.v" + n + ";\n";
+ switch (VariableColumnCount(varying->type))
+ {
+ case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break;
+ case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break;
+ case 3: pixelHLSL += " = input.v" + n + ".xyz;\n"; break;
+ case 4: pixelHLSL += " = input.v" + n + ";\n"; break;
+ default: UNREACHABLE();
+ }
}
}
}
@@ -1617,13 +1579,20 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::
}
pixelHLSL += "\n"
- " gl_main();\n"
- "\n"
- " PS_OUTPUT output;\n"
- " output.gl_Color[0] = gl_Color[0];\n"
- "\n"
- " return output;\n"
- "}\n";
+ " gl_main();\n"
+ "\n"
+ " PS_OUTPUT output;\n";
+
+ for (unsigned int i = 0; i < renderTargetCount; i++)
+ {
+ unsigned int sourceColor = fragmentShader->mUsesFragData ? i : 0;
+
+ pixelHLSL += " output.gl_Color" + str(i) + " = gl_Color[" + str(sourceColor) + "];\n";
+ }
+
+ pixelHLSL += "\n"
+ " return output;\n"
+ "}\n";
return true;
}
@@ -1642,7 +1611,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
int version = 0;
stream.read(&version);
- if (version != BUILD_REVISION)
+ if (version != VERSION_DWORD)
{
infoLog.append("Invalid program binary version.");
return false;
@@ -1667,7 +1636,7 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
mSamplersPS[i].textureType = (TextureType) textureType;
}
- for (unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; ++i)
+ for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
{
stream.read(&mSamplersVS[i].active);
stream.read(&mSamplersVS[i].logicalTextureUnit);
@@ -1679,8 +1648,9 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.read(&mUsedVertexSamplerRange);
stream.read(&mUsedPixelSamplerRange);
+ stream.read(&mUsesPointSize);
- unsigned int size;
+ size_t size;
stream.read(&size);
if (stream.error())
{
@@ -1692,24 +1662,20 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
for (unsigned int i = 0; i < size; ++i)
{
GLenum type;
- std::string _name;
+ GLenum precision;
+ std::string name;
unsigned int arraySize;
stream.read(&type);
- stream.read(&_name);
+ stream.read(&precision);
+ stream.read(&name);
stream.read(&arraySize);
- mUniforms[i] = new Uniform(type, _name, arraySize);
+ mUniforms[i] = new Uniform(type, precision, name, arraySize);
- stream.read(&mUniforms[i]->ps.float4Index);
- stream.read(&mUniforms[i]->ps.samplerIndex);
- stream.read(&mUniforms[i]->ps.boolIndex);
- stream.read(&mUniforms[i]->ps.registerCount);
-
- stream.read(&mUniforms[i]->vs.float4Index);
- stream.read(&mUniforms[i]->vs.samplerIndex);
- stream.read(&mUniforms[i]->vs.boolIndex);
- stream.read(&mUniforms[i]->vs.registerCount);
+ stream.read(&mUniforms[i]->psRegisterIndex);
+ stream.read(&mUniforms[i]->vsRegisterIndex);
+ stream.read(&mUniforms[i]->registerCount);
}
stream.read(&size);
@@ -1727,26 +1693,22 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
stream.read(&mUniformIndex[i].index);
}
- stream.read(&mDxDepthRangeLocation);
- stream.read(&mDxDepthLocation);
- stream.read(&mDxCoordLocation);
- stream.read(&mDxHalfPixelSizeLocation);
- stream.read(&mDxFrontCCWLocation);
- stream.read(&mDxPointsOrLinesLocation);
-
unsigned int pixelShaderSize;
stream.read(&pixelShaderSize);
unsigned int vertexShaderSize;
stream.read(&vertexShaderSize);
+ unsigned int geometryShaderSize;
+ stream.read(&geometryShaderSize);
+
const char *ptr = (const char*) binary + stream.offset();
- const D3DCAPS9 *binaryIdentifier = (const D3DCAPS9*) ptr;
+ const GUID *binaryIdentifier = (const GUID *) ptr;
ptr += sizeof(GUID);
- D3DADAPTER_IDENTIFIER9 *currentIdentifier = getDisplay()->getAdapterIdentifier();
- if (memcmp(&currentIdentifier->DeviceIdentifier, binaryIdentifier, sizeof(GUID)) != 0)
+ GUID identifier = mRenderer->getAdapterIdentifier();
+ if (memcmp(&identifier, binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog.append("Invalid program binary.");
return false;
@@ -1758,22 +1720,46 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length)
const char *vertexShaderFunction = ptr;
ptr += vertexShaderSize;
- mPixelExecutable = getDisplay()->createPixelShader(reinterpret_cast<const DWORD*>(pixelShaderFunction), pixelShaderSize);
+ const char *geometryShaderFunction = geometryShaderSize > 0 ? ptr : NULL;
+ ptr += geometryShaderSize;
+
+ mPixelExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(pixelShaderFunction),
+ pixelShaderSize, rx::SHADER_PIXEL);
if (!mPixelExecutable)
{
infoLog.append("Could not create pixel shader.");
return false;
}
- mVertexExecutable = getDisplay()->createVertexShader(reinterpret_cast<const DWORD*>(vertexShaderFunction), vertexShaderSize);
+ mVertexExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(vertexShaderFunction),
+ vertexShaderSize, rx::SHADER_VERTEX);
if (!mVertexExecutable)
{
infoLog.append("Could not create vertex shader.");
- mPixelExecutable->Release();
+ delete mPixelExecutable;
mPixelExecutable = NULL;
return false;
}
+ if (geometryShaderFunction != NULL && geometryShaderSize > 0)
+ {
+ mGeometryExecutable = mRenderer->loadExecutable(reinterpret_cast<const DWORD*>(geometryShaderFunction),
+ geometryShaderSize, rx::SHADER_GEOMETRY);
+ if (!mGeometryExecutable)
+ {
+ infoLog.append("Could not create geometry shader.");
+ delete mPixelExecutable;
+ mPixelExecutable = NULL;
+ delete mVertexExecutable;
+ mVertexExecutable = NULL;
+ return false;
+ }
+ }
+ else
+ {
+ mGeometryExecutable = NULL;
+ }
+
return true;
}
@@ -1782,7 +1768,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
BinaryOutputStream stream;
stream.write(GL_PROGRAM_BINARY_ANGLE);
- stream.write(BUILD_REVISION);
+ stream.write(VERSION_DWORD);
for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
{
@@ -1798,7 +1784,7 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.write((int) mSamplersPS[i].textureType);
}
- for (unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; ++i)
+ for (unsigned int i = 0; i < IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; ++i)
{
stream.write(mSamplersVS[i].active);
stream.write(mSamplersVS[i].logicalTextureUnit);
@@ -1807,23 +1793,19 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.write(mUsedVertexSamplerRange);
stream.write(mUsedPixelSamplerRange);
+ stream.write(mUsesPointSize);
stream.write(mUniforms.size());
for (unsigned int i = 0; i < mUniforms.size(); ++i)
{
stream.write(mUniforms[i]->type);
- stream.write(mUniforms[i]->_name);
+ stream.write(mUniforms[i]->precision);
+ stream.write(mUniforms[i]->name);
stream.write(mUniforms[i]->arraySize);
- stream.write(mUniforms[i]->ps.float4Index);
- stream.write(mUniforms[i]->ps.samplerIndex);
- stream.write(mUniforms[i]->ps.boolIndex);
- stream.write(mUniforms[i]->ps.registerCount);
-
- stream.write(mUniforms[i]->vs.float4Index);
- stream.write(mUniforms[i]->vs.samplerIndex);
- stream.write(mUniforms[i]->vs.boolIndex);
- stream.write(mUniforms[i]->vs.registerCount);
+ stream.write(mUniforms[i]->psRegisterIndex);
+ stream.write(mUniforms[i]->vsRegisterIndex);
+ stream.write(mUniforms[i]->registerCount);
}
stream.write(mUniformIndex.size());
@@ -1834,29 +1816,21 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
stream.write(mUniformIndex[i].index);
}
- stream.write(mDxDepthRangeLocation);
- stream.write(mDxDepthLocation);
- stream.write(mDxCoordLocation);
- stream.write(mDxHalfPixelSizeLocation);
- stream.write(mDxFrontCCWLocation);
- stream.write(mDxPointsOrLinesLocation);
-
- UINT pixelShaderSize;
- HRESULT result = mPixelExecutable->GetFunction(NULL, &pixelShaderSize);
- ASSERT(SUCCEEDED(result));
+ UINT pixelShaderSize = mPixelExecutable->getLength();
stream.write(pixelShaderSize);
- UINT vertexShaderSize;
- result = mVertexExecutable->GetFunction(NULL, &vertexShaderSize);
- ASSERT(SUCCEEDED(result));
+ UINT vertexShaderSize = mVertexExecutable->getLength();
stream.write(vertexShaderSize);
- D3DADAPTER_IDENTIFIER9 *identifier = getDisplay()->getAdapterIdentifier();
+ UINT geometryShaderSize = (mGeometryExecutable != NULL) ? mGeometryExecutable->getLength() : 0;
+ stream.write(geometryShaderSize);
+
+ GUID identifier = mRenderer->getAdapterIdentifier();
GLsizei streamLength = stream.length();
const void *streamData = stream.data();
- GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize;
+ GLsizei totalLength = streamLength + sizeof(GUID) + pixelShaderSize + vertexShaderSize + geometryShaderSize;
if (totalLength > bufSize)
{
if (length)
@@ -1874,17 +1848,21 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length)
memcpy(ptr, streamData, streamLength);
ptr += streamLength;
- memcpy(ptr, &identifier->DeviceIdentifier, sizeof(GUID));
+ memcpy(ptr, &identifier, sizeof(GUID));
ptr += sizeof(GUID);
- result = mPixelExecutable->GetFunction(ptr, &pixelShaderSize);
- ASSERT(SUCCEEDED(result));
+ memcpy(ptr, mPixelExecutable->getFunction(), pixelShaderSize);
ptr += pixelShaderSize;
- result = mVertexExecutable->GetFunction(ptr, &vertexShaderSize);
- ASSERT(SUCCEEDED(result));
+ memcpy(ptr, mVertexExecutable->getFunction(), vertexShaderSize);
ptr += vertexShaderSize;
+ if (mGeometryExecutable != NULL && geometryShaderSize > 0)
+ {
+ memcpy(ptr, mGeometryExecutable->getFunction(), geometryShaderSize);
+ ptr += geometryShaderSize;
+ }
+
ASSERT(ptr - totalLength == binary);
}
@@ -1924,69 +1902,54 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin
std::string pixelHLSL = fragmentShader->getHLSL();
std::string vertexHLSL = vertexShader->getHLSL();
- if (!linkVaryings(infoLog, pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
+ // Map the varyings to the register file
+ const Varying *packing[IMPLEMENTATION_MAX_VARYING_VECTORS][4] = {NULL};
+ int registers = packVaryings(infoLog, packing, fragmentShader);
+
+ if (registers < 0)
{
return false;
}
- Context *context = getContext();
- const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
- const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
-
- ID3D10Blob *vertexBinary = compileToBinary(infoLog, vertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
- ID3D10Blob *pixelBinary = compileToBinary(infoLog, pixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
-
- if (vertexBinary && pixelBinary)
+ if (!linkVaryings(infoLog, registers, packing, pixelHLSL, vertexHLSL, fragmentShader, vertexShader))
{
- mVertexExecutable = getDisplay()->createVertexShader((DWORD*)vertexBinary->GetBufferPointer(), vertexBinary->GetBufferSize());
- if (!mVertexExecutable)
- {
- return error(GL_OUT_OF_MEMORY, false);
- }
-
- mPixelExecutable = getDisplay()->createPixelShader((DWORD*)pixelBinary->GetBufferPointer(), pixelBinary->GetBufferSize());
- if (!mPixelExecutable)
- {
- mVertexExecutable->Release();
- mVertexExecutable = NULL;
- return error(GL_OUT_OF_MEMORY, false);
- }
+ return false;
+ }
- vertexBinary->Release();
- pixelBinary->Release();
- vertexBinary = NULL;
- pixelBinary = NULL;
+ bool success = true;
+ mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX);
+ mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL);
- if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
- {
- return false;
- }
-
- if (!linkUniforms(infoLog, GL_FRAGMENT_SHADER, mConstantTablePS))
- {
- return false;
- }
+ if (usesGeometryShader())
+ {
+ std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader);
+ mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY);
+ }
- if (!linkUniforms(infoLog, GL_VERTEX_SHADER, mConstantTableVS))
- {
- return false;
- }
+ if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable))
+ {
+ infoLog.append("Failed to create D3D shaders.");
+ success = false;
- // these uniforms are searched as already-decorated because gl_ and dx_
- // are reserved prefixes, and do not receive additional decoration
- mDxDepthRangeLocation = getUniformLocation("dx_DepthRange");
- mDxDepthLocation = getUniformLocation("dx_Depth");
- mDxCoordLocation = getUniformLocation("dx_Coord");
- mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize");
- mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW");
- mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines");
+ delete mVertexExecutable;
+ mVertexExecutable = NULL;
+ delete mPixelExecutable;
+ mPixelExecutable = NULL;
+ delete mGeometryExecutable;
+ mGeometryExecutable = NULL;
+ }
- context->markDxUniformsDirty();
+ if (!linkAttributes(infoLog, attributeBindings, fragmentShader, vertexShader))
+ {
+ success = false;
+ }
- return true;
+ if (!linkUniforms(infoLog, vertexShader->getUniforms(), fragmentShader->getUniforms()))
+ {
+ success = false;
}
- return false;
+ return success;
}
// Determines the mapping between GL attributes and Direct3D 9 vertex stream usage indices
@@ -2059,13 +2022,19 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
return true;
}
-bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, D3DConstantTable *constantTable)
+bool ProgramBinary::linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms)
{
- for (unsigned int constantIndex = 0; constantIndex < constantTable->constants(); constantIndex++)
+ for (sh::ActiveUniforms::const_iterator uniform = vertexUniforms.begin(); uniform != vertexUniforms.end(); uniform++)
{
- const D3DConstant *constant = constantTable->getConstant(constantIndex);
+ if (!defineUniform(GL_VERTEX_SHADER, *uniform, infoLog))
+ {
+ return false;
+ }
+ }
- if (!defineUniform(infoLog, shader, constant))
+ for (sh::ActiveUniforms::const_iterator uniform = fragmentUniforms.begin(); uniform != fragmentUniforms.end(); uniform++)
+ {
+ if (!defineUniform(GL_FRAGMENT_SHADER, *uniform, infoLog))
{
return false;
}
@@ -2074,432 +2043,271 @@ bool ProgramBinary::linkUniforms(InfoLog &infoLog, GLenum shader, D3DConstantTab
return true;
}
-// Adds the description of a constant found in the binary shader to the list of uniforms
-// Returns true if succesful (uniform not already defined)
-bool ProgramBinary::defineUniform(InfoLog &infoLog, GLenum shader, const D3DConstant *constant, std::string name)
+bool ProgramBinary::defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog)
{
- if (constant->registerSet == D3DConstant::RS_SAMPLER)
+ if (constant.type == GL_SAMPLER_2D ||
+ constant.type == GL_SAMPLER_CUBE)
{
- for (unsigned int i = 0; i < constant->registerCount; i++)
+ unsigned int samplerIndex = constant.registerIndex;
+
+ do
{
- const D3DConstant *psConstant = mConstantTablePS->getConstantByName(constant->name.c_str());
- const D3DConstant *vsConstant = mConstantTableVS->getConstantByName(constant->name.c_str());
-
- if (psConstant)
+ if (shader == GL_VERTEX_SHADER)
{
- unsigned int samplerIndex = psConstant->registerIndex + i;
-
- if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < mRenderer->getMaxVertexTextureImageUnits())
{
- mSamplersPS[samplerIndex].active = true;
- mSamplersPS[samplerIndex].textureType = (constant->type == D3DConstant::PT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
- mSamplersPS[samplerIndex].logicalTextureUnit = 0;
- mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
+ mSamplersVS[samplerIndex].active = true;
+ mSamplersVS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+ mSamplersVS[samplerIndex].logicalTextureUnit = 0;
+ mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
}
else
{
- infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
+ infoLog.append("Vertex shader sampler count exceeds the maximum vertex texture units (%d).", mRenderer->getMaxVertexTextureImageUnits());
return false;
}
}
-
- if (vsConstant)
+ else if (shader == GL_FRAGMENT_SHADER)
{
- unsigned int samplerIndex = vsConstant->registerIndex + i;
-
- if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits())
+ if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{
- mSamplersVS[samplerIndex].active = true;
- mSamplersVS[samplerIndex].textureType = (constant->type == D3DConstant::PT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D;
- mSamplersVS[samplerIndex].logicalTextureUnit = 0;
- mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange);
+ mSamplersPS[samplerIndex].active = true;
+ mSamplersPS[samplerIndex].textureType = (constant.type == GL_SAMPLER_CUBE) ? TEXTURE_CUBE : TEXTURE_2D;
+ mSamplersPS[samplerIndex].logicalTextureUnit = 0;
+ mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange);
}
else
{
- infoLog.append("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits());
+ infoLog.append("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
return false;
}
}
+ else UNREACHABLE();
+
+ samplerIndex++;
}
+ while (samplerIndex < constant.registerIndex + constant.arraySize);
}
- switch(constant->typeClass)
- {
- case D3DConstant::CLASS_STRUCT:
- {
- for (unsigned int arrayIndex = 0; arrayIndex < constant->elements; arrayIndex++)
- {
- for (unsigned int field = 0; field < constant->structMembers[arrayIndex].size(); field++)
- {
- const D3DConstant *fieldConstant = constant->structMembers[arrayIndex][field];
+ Uniform *uniform = NULL;
+ GLint location = getUniformLocation(constant.name);
- std::string structIndex = (constant->elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
+ if (location >= 0) // Previously defined, type and precision must match
+ {
+ uniform = mUniforms[mUniformIndex[location].index];
- if (!defineUniform(infoLog, shader, fieldConstant, name + constant->name + structIndex + "."))
- {
- return false;
- }
- }
- }
+ if (uniform->type != constant.type)
+ {
+ infoLog.append("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+ return false;
+ }
- return true;
+ if (uniform->precision != constant.precision)
+ {
+ infoLog.append("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
+ return false;
}
- case D3DConstant::CLASS_SCALAR:
- case D3DConstant::CLASS_VECTOR:
- case D3DConstant::CLASS_MATRIX_COLUMNS:
- case D3DConstant::CLASS_OBJECT:
- return defineUniform(shader, constant, name + constant->name);
- default:
- UNREACHABLE();
- return false;
}
-}
-
-bool ProgramBinary::defineUniform(GLenum shader, const D3DConstant *constant, const std::string &_name)
-{
- Uniform *uniform = createUniform(constant, _name);
+ else
+ {
+ uniform = new Uniform(constant.type, constant.precision, constant.name, constant.arraySize);
+ }
- if(!uniform)
+ if (!uniform)
{
return false;
}
- // Check if already defined
- GLint location = getUniformLocation(uniform->name);
- GLenum type = uniform->type;
-
- if (location >= 0)
+ if (shader == GL_FRAGMENT_SHADER)
{
- delete uniform;
- uniform = mUniforms[mUniformIndex[location].index];
+ uniform->psRegisterIndex = constant.registerIndex;
}
-
- if (shader == GL_FRAGMENT_SHADER) uniform->ps.set(constant);
- if (shader == GL_VERTEX_SHADER) uniform->vs.set(constant);
+ else if (shader == GL_VERTEX_SHADER)
+ {
+ uniform->vsRegisterIndex = constant.registerIndex;
+ }
+ else UNREACHABLE();
if (location >= 0)
{
- return uniform->type == type;
+ return uniform->type == constant.type;
}
mUniforms.push_back(uniform);
unsigned int uniformIndex = mUniforms.size() - 1;
- for (unsigned int i = 0; i < uniform->arraySize; ++i)
+ for (unsigned int i = 0; i < uniform->elementCount(); i++)
{
- mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex));
+ mUniformIndex.push_back(UniformLocation(constant.name, i, uniformIndex));
}
- return true;
-}
-
-Uniform *ProgramBinary::createUniform(const D3DConstant *constant, const std::string &_name)
-{
- if (constant->rows == 1) // Vectors and scalars
+ if (shader == GL_VERTEX_SHADER)
{
- switch (constant->type)
+ if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedVertexUniformVectors() + mRenderer->getMaxVertexUniformVectors())
{
- case D3DConstant::PT_SAMPLER2D:
- switch (constant->columns)
- {
- case 1: return new Uniform(GL_SAMPLER_2D, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- case D3DConstant::PT_SAMPLERCUBE:
- switch (constant->columns)
- {
- case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- case D3DConstant::PT_BOOL:
- switch (constant->columns)
- {
- case 1: return new Uniform(GL_BOOL, _name, constant->elements);
- case 2: return new Uniform(GL_BOOL_VEC2, _name, constant->elements);
- case 3: return new Uniform(GL_BOOL_VEC3, _name, constant->elements);
- case 4: return new Uniform(GL_BOOL_VEC4, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- case D3DConstant::PT_INT:
- switch (constant->columns)
- {
- case 1: return new Uniform(GL_INT, _name, constant->elements);
- case 2: return new Uniform(GL_INT_VEC2, _name, constant->elements);
- case 3: return new Uniform(GL_INT_VEC3, _name, constant->elements);
- case 4: return new Uniform(GL_INT_VEC4, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- case D3DConstant::PT_FLOAT:
- switch (constant->columns)
- {
- case 1: return new Uniform(GL_FLOAT, _name, constant->elements);
- case 2: return new Uniform(GL_FLOAT_VEC2, _name, constant->elements);
- case 3: return new Uniform(GL_FLOAT_VEC3, _name, constant->elements);
- case 4: return new Uniform(GL_FLOAT_VEC4, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- default:
- UNREACHABLE();
+ infoLog.append("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%u)", mRenderer->getMaxVertexUniformVectors());
+ return false;
}
}
- else if (constant->rows == constant->columns) // Square matrices
+ else if (shader == GL_FRAGMENT_SHADER)
{
- switch (constant->type)
+ if (constant.registerIndex + uniform->registerCount > mRenderer->getReservedFragmentUniformVectors() + mRenderer->getMaxFragmentUniformVectors())
{
- case D3DConstant::PT_FLOAT:
- switch (constant->rows)
- {
- case 2: return new Uniform(GL_FLOAT_MAT2, _name, constant->elements);
- case 3: return new Uniform(GL_FLOAT_MAT3, _name, constant->elements);
- case 4: return new Uniform(GL_FLOAT_MAT4, _name, constant->elements);
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
+ infoLog.append("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%u)", mRenderer->getMaxFragmentUniformVectors());
+ return false;
}
}
else UNREACHABLE();
- return 0;
+ return true;
}
-// This method needs to match OutputHLSL::decorate
-std::string ProgramBinary::decorateAttribute(const std::string &name)
+std::string ProgramBinary::generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
{
- if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
- {
- return "_" + name;
- }
-
- return name;
+ // for now we only handle point sprite emulation
+ ASSERT(usesPointSpriteEmulation());
+ return generatePointSpriteHLSL(registers, packing, fragmentShader, vertexShader);
}
-std::string ProgramBinary::undecorateUniform(const std::string &_name)
+std::string ProgramBinary::generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const
{
- std::string name = _name;
-
- // Remove any structure field decoration
- size_t pos = 0;
- while ((pos = name.find("._", pos)) != std::string::npos)
- {
- name.replace(pos, 2, ".");
- }
+ ASSERT(registers >= 0);
+ ASSERT(vertexShader->mUsesPointSize);
+ ASSERT(mRenderer->getMajorShaderModel() >= 4);
- // Remove the leading decoration
- if (name[0] == '_')
- {
- return name.substr(1);
- }
- else if (name.compare(0, 3, "ar_") == 0)
- {
- return name.substr(3);
- }
-
- return name;
-}
+ std::string geomHLSL;
-void ProgramBinary::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v)
-{
- float vector[D3D9_MAX_FLOAT_CONSTANTS * 4];
- BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS];
+ std::string varyingSemantic = "TEXCOORD";
- if (targetUniform->ps.float4Index >= 0 || targetUniform->vs.float4Index >= 0)
- {
- ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
- for (int i = 0; i < count; i++)
- {
- for (int j = 0; j < 4; j++)
- {
- if (j < width)
- {
- vector[i * 4 + j] = (v[i * width + j] == GL_FALSE) ? 0.0f : 1.0f;
- }
- else
- {
- vector[i * 4 + j] = 0.0f;
- }
- }
- }
- }
+ std::string fragCoordSemantic;
+ std::string pointCoordSemantic;
- if (targetUniform->ps.boolIndex >= 0 || targetUniform->vs.boolIndex >= 0)
- {
- int psCount = targetUniform->ps.boolIndex >= 0 ? targetUniform->ps.registerCount : 0;
- int vsCount = targetUniform->vs.boolIndex >= 0 ? targetUniform->vs.registerCount : 0;
- int copyCount = std::min(count * width, std::max(psCount, vsCount));
- ASSERT(copyCount <= D3D9_MAX_BOOL_CONSTANTS);
- for (int i = 0; i < copyCount; i++)
- {
- boolVector[i] = v[i] != GL_FALSE;
- }
- }
+ int reservedRegisterIndex = registers;
- if (targetUniform->ps.float4Index >= 0)
- {
- mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, vector, targetUniform->ps.registerCount);
- }
-
- if (targetUniform->ps.boolIndex >= 0)
- {
- mDevice->SetPixelShaderConstantB(targetUniform->ps.boolIndex, boolVector, targetUniform->ps.registerCount);
- }
-
- if (targetUniform->vs.float4Index >= 0)
+ if (fragmentShader->mUsesFragCoord)
{
- mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, vector, targetUniform->vs.registerCount);
+ fragCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
}
-
- if (targetUniform->vs.boolIndex >= 0)
+
+ if (fragmentShader->mUsesPointCoord)
{
- mDevice->SetVertexShaderConstantB(targetUniform->vs.boolIndex, boolVector, targetUniform->vs.registerCount);
+ pointCoordSemantic = varyingSemantic + str(reservedRegisterIndex++);
}
-}
-bool ProgramBinary::applyUniformnfv(Uniform *targetUniform, const GLfloat *v)
-{
- if (targetUniform->ps.registerCount)
+ geomHLSL += "uniform float4 dx_ViewCoords : register(c1);\n"
+ "\n"
+ "struct GS_INPUT\n"
+ "{\n";
+
+ for (int r = 0; r < registers; r++)
{
- mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, v, targetUniform->ps.registerCount);
+ int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
+
+ geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
}
- if (targetUniform->vs.registerCount)
+ if (fragmentShader->mUsesFragCoord)
{
- mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, v, targetUniform->vs.registerCount);
+ geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
}
- return true;
-}
-
-bool ProgramBinary::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v)
-{
- ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
- Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+ geomHLSL += " float gl_PointSize : PSIZE;\n"
+ " float4 gl_Position : SV_Position;\n"
+ "};\n"
+ "\n"
+ "struct GS_OUTPUT\n"
+ "{\n";
- for (int i = 0; i < count; i++)
+ for (int r = 0; r < registers; r++)
{
- vector[i] = Vector4((float)v[i], 0, 0, 0);
+ int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
+
+ geomHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
}
- if (targetUniform->ps.registerCount)
+ if (fragmentShader->mUsesFragCoord)
{
- if (targetUniform->ps.samplerIndex >= 0)
- {
- unsigned int firstIndex = targetUniform->ps.samplerIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
- {
- ASSERT(mSamplersPS[samplerIndex].active);
- mSamplersPS[samplerIndex].logicalTextureUnit = v[i];
- }
- }
- }
- else
- {
- ASSERT(targetUniform->ps.float4Index >= 0);
- mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float*)vector, targetUniform->ps.registerCount);
- }
+ geomHLSL += " float4 gl_FragCoord : " + fragCoordSemantic + ";\n";
}
- if (targetUniform->vs.registerCount)
+ if (fragmentShader->mUsesPointCoord)
{
- if (targetUniform->vs.samplerIndex >= 0)
- {
- unsigned int firstIndex = targetUniform->vs.samplerIndex;
-
- for (int i = 0; i < count; i++)
- {
- unsigned int samplerIndex = firstIndex + i;
-
- if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF)
- {
- ASSERT(mSamplersVS[samplerIndex].active);
- mSamplersVS[samplerIndex].logicalTextureUnit = v[i];
- }
- }
- }
- else
- {
- ASSERT(targetUniform->vs.float4Index >= 0);
- mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount);
- }
+ geomHLSL += " float2 gl_PointCoord : " + pointCoordSemantic + ";\n";
}
- return true;
-}
-
-bool ProgramBinary::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v)
-{
- ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
- Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
+ geomHLSL += " float gl_PointSize : PSIZE;\n"
+ " float4 gl_Position : SV_Position;\n"
+ "};\n"
+ "\n"
+ "static float2 pointSpriteCorners[] = \n"
+ "{\n"
+ " float2( 0.5f, -0.5f),\n"
+ " float2( 0.5f, 0.5f),\n"
+ " float2(-0.5f, -0.5f),\n"
+ " float2(-0.5f, 0.5f)\n"
+ "};\n"
+ "\n"
+ "static float2 pointSpriteTexcoords[] = \n"
+ "{\n"
+ " float2(1.0f, 1.0f),\n"
+ " float2(1.0f, 0.0f),\n"
+ " float2(0.0f, 1.0f),\n"
+ " float2(0.0f, 0.0f)\n"
+ "};\n"
+ "\n"
+ "static float minPointSize = " + str(ALIASED_POINT_SIZE_RANGE_MIN) + ".0f;\n"
+ "static float maxPointSize = " + str(mRenderer->getMaxPointSize()) + ".0f;\n"
+ "\n"
+ "[maxvertexcount(4)]\n"
+ "void main(point GS_INPUT input[1], inout TriangleStream<GS_OUTPUT> outStream)\n"
+ "{\n"
+ " GS_OUTPUT output = (GS_OUTPUT)0;\n"
+ " output.gl_PointSize = input[0].gl_PointSize;\n";
- for (int i = 0; i < count; i++)
+ for (int r = 0; r < registers; r++)
{
- vector[i] = Vector4((float)v[0], (float)v[1], 0, 0);
-
- v += 2;
+ geomHLSL += " output.v" + str(r) + " = input[0].v" + str(r) + ";\n";
}
- applyUniformniv(targetUniform, count, vector);
-
- return true;
-}
-
-bool ProgramBinary::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v)
-{
- ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
- Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
-
- for (int i = 0; i < count; i++)
+ if (fragmentShader->mUsesFragCoord)
{
- vector[i] = Vector4((float)v[0], (float)v[1], (float)v[2], 0);
-
- v += 3;
+ geomHLSL += " output.gl_FragCoord = input[0].gl_FragCoord;\n";
}
- applyUniformniv(targetUniform, count, vector);
-
- return true;
-}
+ geomHLSL += " \n"
+ " float gl_PointSize = clamp(input[0].gl_PointSize, minPointSize, maxPointSize);\n"
+ " float4 gl_Position = input[0].gl_Position;\n"
+ " float2 viewportScale = float2(1.0f / dx_ViewCoords.x, 1.0f / dx_ViewCoords.y) * gl_Position.w;\n";
-bool ProgramBinary::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v)
-{
- ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS);
- Vector4 vector[D3D9_MAX_FLOAT_CONSTANTS];
-
- for (int i = 0; i < count; i++)
+ for (int corner = 0; corner < 4; corner++)
{
- vector[i] = Vector4((float)v[0], (float)v[1], (float)v[2], (float)v[3]);
+ geomHLSL += " \n"
+ " output.gl_Position = gl_Position + float4(pointSpriteCorners[" + str(corner) + "] * viewportScale * gl_PointSize, 0.0f, 0.0f);\n";
+
+ if (fragmentShader->mUsesPointCoord)
+ {
+ geomHLSL += " output.gl_PointCoord = pointSpriteTexcoords[" + str(corner) + "];\n";
+ }
- v += 4;
+ geomHLSL += " outStream.Append(output);\n";
}
- applyUniformniv(targetUniform, count, vector);
+ geomHLSL += " \n"
+ " outStream.RestartStrip();\n"
+ "}\n";
- return true;
+ return geomHLSL;
}
-void ProgramBinary::applyUniformniv(Uniform *targetUniform, GLsizei count, const Vector4 *vector)
+// This method needs to match OutputHLSL::decorate
+std::string ProgramBinary::decorateAttribute(const std::string &name)
{
- if (targetUniform->ps.registerCount)
- {
- ASSERT(targetUniform->ps.float4Index >= 0);
- mDevice->SetPixelShaderConstantF(targetUniform->ps.float4Index, (const float *)vector, targetUniform->ps.registerCount);
- }
-
- if (targetUniform->vs.registerCount)
+ if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0)
{
- ASSERT(targetUniform->vs.float4Index >= 0);
- mDevice->SetVertexShaderConstantF(targetUniform->vs.float4Index, (const float *)vector, targetUniform->vs.registerCount);
+ return "_" + name;
}
+
+ return name;
}
bool ProgramBinary::isValidated() const
@@ -2507,7 +2315,7 @@ bool ProgramBinary::isValidated() const
return mValidated;
}
-void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
{
// Skip over inactive attributes
unsigned int activeAttribute = 0;
@@ -2545,7 +2353,7 @@ void ProgramBinary::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *l
*type = mLinkedAttribute[attribute].type;
}
-GLint ProgramBinary::getActiveAttributeCount()
+GLint ProgramBinary::getActiveAttributeCount() const
{
int count = 0;
@@ -2560,7 +2368,7 @@ GLint ProgramBinary::getActiveAttributeCount()
return count;
}
-GLint ProgramBinary::getActiveAttributeMaxLength()
+GLint ProgramBinary::getActiveAttributeMaxLength() const
{
int maxLength = 0;
@@ -2575,33 +2383,15 @@ GLint ProgramBinary::getActiveAttributeMaxLength()
return maxLength;
}
-void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
+void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
{
- // Skip over internal uniforms
- unsigned int activeUniform = 0;
- unsigned int uniform;
- for (uniform = 0; uniform < mUniforms.size(); uniform++)
- {
- if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0)
- {
- continue;
- }
-
- if (activeUniform == index)
- {
- break;
- }
-
- activeUniform++;
- }
-
- ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+ ASSERT(index < mUniforms.size()); // index must be smaller than getActiveUniformCount()
if (bufsize > 0)
{
- std::string string = mUniforms[uniform]->name;
+ std::string string = mUniforms[index]->name;
- if (mUniforms[uniform]->isArray())
+ if (mUniforms[index]->isArray())
{
string += "[0]";
}
@@ -2615,35 +2405,24 @@ void ProgramBinary::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *len
}
}
- *size = mUniforms[uniform]->arraySize;
+ *size = mUniforms[index]->elementCount();
- *type = mUniforms[uniform]->type;
+ *type = mUniforms[index]->type;
}
-GLint ProgramBinary::getActiveUniformCount()
+GLint ProgramBinary::getActiveUniformCount() const
{
- int count = 0;
-
- unsigned int numUniforms = mUniforms.size();
- for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
- {
- if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
- {
- count++;
- }
- }
-
- return count;
+ return mUniforms.size();
}
-GLint ProgramBinary::getActiveUniformMaxLength()
+GLint ProgramBinary::getActiveUniformMaxLength() const
{
int maxLength = 0;
unsigned int numUniforms = mUniforms.size();
for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
{
- if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0)
+ if (!mUniforms[uniformIndex]->name.empty())
{
int length = (int)(mUniforms[uniformIndex]->name.length() + 1);
if (mUniforms[uniformIndex]->isArray())
@@ -2676,10 +2455,10 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
// texture image unit, and this is the current program, then ValidateProgram will fail, and
// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
- const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits();
- TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF];
+ const unsigned int maxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
+ TextureType textureUnitType[IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS];
- for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i)
+ for (unsigned int i = 0; i < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
{
textureUnitType[i] = TEXTURE_UNKNOWN;
}
@@ -2694,7 +2473,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
}
return false;
@@ -2729,7 +2508,7 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
{
if (infoLog)
{
- infoLog->append("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
+ infoLog->append("Sampler uniform (%d) exceeds IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits);
}
return false;
@@ -2757,38 +2536,51 @@ bool ProgramBinary::validateSamplers(InfoLog *infoLog)
return true;
}
-GLint ProgramBinary::getDxDepthRangeLocation() const
+ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
{
- return mDxDepthRangeLocation;
}
-GLint ProgramBinary::getDxDepthLocation() const
+struct AttributeSorter
{
- return mDxDepthLocation;
-}
+ AttributeSorter(const int (&semanticIndices)[MAX_VERTEX_ATTRIBS])
+ : originalIndices(semanticIndices)
+ {
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ indices[i] = i;
+ }
-GLint ProgramBinary::getDxCoordLocation() const
-{
- return mDxCoordLocation;
-}
+ std::sort(&indices[0], &indices[MAX_VERTEX_ATTRIBS], *this);
+ }
-GLint ProgramBinary::getDxHalfPixelSizeLocation() const
-{
- return mDxHalfPixelSizeLocation;
-}
+ bool operator()(int a, int b)
+ {
+ return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b];
+ }
-GLint ProgramBinary::getDxFrontCCWLocation() const
-{
- return mDxFrontCCWLocation;
-}
+ int indices[MAX_VERTEX_ATTRIBS];
+ const int (&originalIndices)[MAX_VERTEX_ATTRIBS];
+};
-GLint ProgramBinary::getDxPointsOrLinesLocation() const
+void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const
{
- return mDxPointsOrLinesLocation;
-}
+ AttributeSorter sorter(mSemanticIndex);
-ProgramBinary::Sampler::Sampler() : active(false), logicalTextureUnit(0), textureType(TEXTURE_2D)
-{
+ int oldIndices[MAX_VERTEX_ATTRIBS];
+ rx::TranslatedAttribute oldTranslatedAttributes[MAX_VERTEX_ATTRIBS];
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ oldIndices[i] = mSemanticIndex[i];
+ oldTranslatedAttributes[i] = attributes[i];
+ }
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ int oldIndex = sorter.indices[i];
+ sortedSemanticIndices[i] = oldIndices[oldIndex];
+ attributes[i] = oldTranslatedAttributes[oldIndex];
+ }
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
index 9ffe70b617..2386c0bd6f 100644
--- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
+++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.h
@@ -14,71 +14,30 @@
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <d3dcompiler.h>
#include <string>
#include <vector>
-#include "libGLESv2/Context.h"
-#include "libGLESv2/D3DConstantTable.h"
+#include "common/RefCountObject.h"
+#include "angletypes.h"
#include "libGLESv2/mathutil.h"
+#include "libGLESv2/Uniform.h"
#include "libGLESv2/Shader.h"
+#include "libGLESv2/Constants.h"
+
+namespace rx
+{
+class ShaderExecutable;
+class Renderer;
+struct TranslatedAttribute;
+}
namespace gl
{
class FragmentShader;
class VertexShader;
-
-// Helper struct representing a single shader uniform
-struct Uniform
-{
- Uniform(GLenum type, const std::string &_name, unsigned int arraySize);
-
- ~Uniform();
-
- bool isArray();
-
- const GLenum type;
- const std::string _name; // Decorated name
- const std::string name; // Undecorated name
- const unsigned int arraySize;
-
- unsigned char *data;
- bool dirty;
-
- struct RegisterInfo
- {
- RegisterInfo()
- {
- float4Index = -1;
- samplerIndex = -1;
- boolIndex = -1;
- registerCount = 0;
- }
-
- void set(const D3DConstant *constant)
- {
- switch(constant->registerSet)
- {
- case D3DConstant::RS_BOOL: boolIndex = constant->registerIndex; break;
- case D3DConstant::RS_FLOAT4: float4Index = constant->registerIndex; break;
- case D3DConstant::RS_SAMPLER: samplerIndex = constant->registerIndex; break;
- default: UNREACHABLE();
- }
-
- ASSERT(registerCount == 0 || registerCount == (int)constant->registerCount);
- registerCount = constant->registerCount;
- }
-
- int float4Index;
- int samplerIndex;
- int boolIndex;
-
- int registerCount;
- };
-
- RegisterInfo ps;
- RegisterInfo vs;
-};
+class InfoLog;
+class AttributeBindings;
+struct Varying;
// Struct used for correlating uniforms/elements of uniform arrays to handles
struct UniformLocation
@@ -87,7 +46,7 @@ struct UniformLocation
{
}
- UniformLocation(const std::string &_name, unsigned int element, unsigned int index);
+ UniformLocation(const std::string &name, unsigned int element, unsigned int index);
std::string name;
unsigned int element;
@@ -98,11 +57,12 @@ struct UniformLocation
class ProgramBinary : public RefCountObject
{
public:
- ProgramBinary();
+ explicit ProgramBinary(rx::Renderer *renderer);
~ProgramBinary();
- IDirect3DPixelShader9 *getPixelShader();
- IDirect3DVertexShader9 *getVertexShader();
+ rx::ShaderExecutable *getPixelExecutable();
+ rx::ShaderExecutable *getVertexExecutable();
+ rx::ShaderExecutable *getGeometryExecutable();
GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex);
@@ -111,6 +71,8 @@ class ProgramBinary : public RefCountObject
TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex);
GLint getUsedSamplerRange(SamplerType type);
bool usesPointSize() const;
+ bool usesPointSpriteEmulation() const;
+ bool usesGeometryShader() const;
GLint getUniformLocation(std::string name);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
@@ -128,13 +90,6 @@ class ProgramBinary : public RefCountObject
bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params);
bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params);
- GLint getDxDepthRangeLocation() const;
- GLint getDxDepthLocation() const;
- GLint getDxCoordLocation() const;
- GLint getDxHalfPixelSizeLocation() const;
- GLint getDxFrontCCWLocation() const;
- GLint getDxPointsOrLinesLocation() const;
-
void dirtyAllUniforms();
void applyUniforms();
@@ -145,13 +100,13 @@ class ProgramBinary : public RefCountObject
bool link(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders);
- void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
- GLint getActiveAttributeCount();
- GLint getActiveAttributeMaxLength();
+ void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+ GLint getActiveAttributeCount() const;
+ GLint getActiveAttributeMaxLength() const;
- void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
- GLint getActiveUniformCount();
- GLint getActiveUniformMaxLength();
+ void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const;
+ GLint getActiveUniformCount() const;
+ GLint getActiveUniformMaxLength() const;
void validate(InfoLog &infoLog);
bool validateSamplers(InfoLog *infoLog);
@@ -159,39 +114,31 @@ class ProgramBinary : public RefCountObject
unsigned int getSerial() const;
+ void sortAttributesByLayout(rx::TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], int sortedSemanticIndices[MAX_VERTEX_ATTRIBS]) const;
+
static std::string decorateAttribute(const std::string &name); // Prepend an underscore
- static std::string undecorateUniform(const std::string &_name); // Remove leading underscore
private:
DISALLOW_COPY_AND_ASSIGN(ProgramBinary);
- ID3D10Blob *compileToBinary(InfoLog &infoLog, const char *hlsl, const char *profile, D3DConstantTable **constantTable);
-
int packVaryings(InfoLog &infoLog, const Varying *packing[][4], FragmentShader *fragmentShader);
- bool linkVaryings(InfoLog &infoLog, std::string& pixelHLSL, std::string& vertexHLSL, FragmentShader *fragmentShader, VertexShader *vertexShader);
+ bool linkVaryings(InfoLog &infoLog, int registers, const Varying *packing[][4],
+ std::string& pixelHLSL, std::string& vertexHLSL,
+ FragmentShader *fragmentShader, VertexShader *vertexShader);
bool linkAttributes(InfoLog &infoLog, const AttributeBindings &attributeBindings, FragmentShader *fragmentShader, VertexShader *vertexShader);
- bool linkUniforms(InfoLog &infoLog, GLenum shader, D3DConstantTable *constantTable);
- bool defineUniform(InfoLog &infoLog, GLenum shader, const D3DConstant *constant, std::string name = "");
- bool defineUniform(GLenum shader, const D3DConstant *constant, const std::string &name);
- Uniform *createUniform( const D3DConstant *constant, const std::string &name);
- bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v);
- bool applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v);
- bool applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v);
- bool applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v);
- bool applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v);
- void applyUniformniv(Uniform *targetUniform, GLsizei count, const Vector4 *vector);
- void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v);
+ bool linkUniforms(InfoLog &infoLog, const sh::ActiveUniforms &vertexUniforms, const sh::ActiveUniforms &fragmentUniforms);
+ bool defineUniform(GLenum shader, const sh::Uniform &constant, InfoLog &infoLog);
+
+ std::string generateGeometryShaderHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
+ std::string generatePointSpriteHLSL(int registers, const Varying *packing[][4], FragmentShader *fragmentShader, VertexShader *vertexShader) const;
- IDirect3DDevice9 *mDevice;
+ rx::Renderer *const mRenderer;
- IDirect3DPixelShader9 *mPixelExecutable;
- IDirect3DVertexShader9 *mVertexExecutable;
-
- // These are only used during linking.
- D3DConstantTable *mConstantTablePS;
- D3DConstantTable *mConstantTableVS;
+ rx::ShaderExecutable *mPixelExecutable;
+ rx::ShaderExecutable *mVertexExecutable;
+ rx::ShaderExecutable *mGeometryExecutable;
Attribute mLinkedAttribute[MAX_VERTEX_ATTRIBS];
int mSemanticIndex[MAX_VERTEX_ATTRIBS];
@@ -206,23 +153,15 @@ class ProgramBinary : public RefCountObject
};
Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS];
- Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF];
+ Sampler mSamplersVS[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
GLuint mUsedVertexSamplerRange;
GLuint mUsedPixelSamplerRange;
bool mUsesPointSize;
- typedef std::vector<Uniform*> UniformArray;
UniformArray mUniforms;
typedef std::vector<UniformLocation> UniformIndex;
UniformIndex mUniformIndex;
- GLint mDxDepthRangeLocation;
- GLint mDxDepthLocation;
- GLint mDxCoordLocation;
- GLint mDxHalfPixelSizeLocation;
- GLint mDxFrontCCWLocation;
- GLint mDxPointsOrLinesLocation;
-
bool mValidated;
const unsigned int mSerial;
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.cpp b/src/3rdparty/angle/src/libGLESv2/Query.cpp
index 10edda5c57..bd987954f1 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Query.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -7,122 +8,45 @@
// Query.cpp: Implements the gl::Query class
#include "libGLESv2/Query.h"
-
-#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/QueryImpl.h"
+#include "libGLESv2/renderer/Renderer.h"
namespace gl
{
-Query::Query(GLuint id, GLenum type) : RefCountObject(id)
+Query::Query(rx::Renderer *renderer, GLenum type, GLuint id) : RefCountObject(id)
{
- mQuery = NULL;
- mStatus = GL_FALSE;
- mResult = GL_FALSE;
- mType = type;
+ mQuery = renderer->createQuery(type);
}
Query::~Query()
{
- if (mQuery != NULL)
- {
- mQuery->Release();
- mQuery = NULL;
- }
+ delete mQuery;
}
void Query::begin()
{
- if (mQuery == NULL)
- {
- if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
- {
- return error(GL_OUT_OF_MEMORY);
- }
- }
-
- HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
- ASSERT(SUCCEEDED(result));
+ mQuery->begin();
}
void Query::end()
{
- if (mQuery == NULL)
- {
- return error(GL_INVALID_OPERATION);
- }
-
- HRESULT result = mQuery->Issue(D3DISSUE_END);
- ASSERT(SUCCEEDED(result));
-
- mStatus = GL_FALSE;
- mResult = GL_FALSE;
+ mQuery->end();
}
GLuint Query::getResult()
{
- if (mQuery != NULL)
- {
- while (!testQuery())
- {
- Sleep(0);
- // explicitly check for device loss
- // some drivers seem to return S_FALSE even if the device is lost
- // instead of D3DERR_DEVICELOST like they should
- if (gl::getDisplay()->testDeviceLost())
- {
- gl::getDisplay()->notifyDeviceLost();
- return error(GL_OUT_OF_MEMORY, 0);
- }
- }
- }
-
- return (GLuint)mResult;
+ return mQuery->getResult();
}
GLboolean Query::isResultAvailable()
{
- if (mQuery != NULL)
- {
- testQuery();
- }
-
- return mStatus;
+ return mQuery->isResultAvailable();
}
GLenum Query::getType() const
{
- return mType;
+ return mQuery->getType();
}
-GLboolean Query::testQuery()
-{
- if (mQuery != NULL && mStatus != GL_TRUE)
- {
- DWORD numPixels = 0;
-
- HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
- if (hres == S_OK)
- {
- mStatus = GL_TRUE;
-
- switch (mType)
- {
- case GL_ANY_SAMPLES_PASSED_EXT:
- case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
- mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
- break;
- default:
- ASSERT(false);
- }
- }
- else if (checkDeviceLost(hres))
- {
- return error(GL_OUT_OF_MEMORY, GL_TRUE);
- }
-
- return mStatus;
- }
-
- return GL_TRUE; // prevent blocking when query is null
-}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Query.h b/src/3rdparty/angle/src/libGLESv2/Query.h
index 79357a0583..e9b95b729b 100644
--- a/src/3rdparty/angle/src/libGLESv2/Query.h
+++ b/src/3rdparty/angle/src/libGLESv2/Query.h
@@ -11,22 +11,28 @@
#define GL_APICALL
#include <GLES2/gl2.h>
-#include <d3d9.h>
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+namespace rx
+{
+class Renderer;
+class QueryImpl;
+}
+
namespace gl
{
class Query : public RefCountObject
{
public:
- Query(GLuint id, GLenum type);
+ Query(rx::Renderer *renderer, GLenum type, GLuint id);
virtual ~Query();
void begin();
void end();
+
GLuint getResult();
GLboolean isResultAvailable();
@@ -35,12 +41,7 @@ class Query : public RefCountObject
private:
DISALLOW_COPY_AND_ASSIGN(Query);
- GLboolean testQuery();
-
- IDirect3DQuery9* mQuery;
- GLenum mType;
- GLboolean mStatus;
- GLint mResult;
+ rx::QueryImpl *mQuery;
};
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
index 4b911e8120..127513741c 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -9,9 +10,10 @@
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
-#include "libGLESv2/main.h"
#include "libGLESv2/Texture.h"
+#include "libGLESv2/renderer/Renderer.h"
#include "libGLESv2/utilities.h"
namespace gl
@@ -35,32 +37,32 @@ void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
GLuint RenderbufferInterface::getRedSize() const
{
- return dx2es::GetRedSize(getD3DFormat());
+ return gl::GetRedSize(getActualFormat());
}
GLuint RenderbufferInterface::getGreenSize() const
{
- return dx2es::GetGreenSize(getD3DFormat());
+ return gl::GetGreenSize(getActualFormat());
}
GLuint RenderbufferInterface::getBlueSize() const
{
- return dx2es::GetBlueSize(getD3DFormat());
+ return gl::GetBlueSize(getActualFormat());
}
GLuint RenderbufferInterface::getAlphaSize() const
{
- return dx2es::GetAlphaSize(getD3DFormat());
+ return gl::GetAlphaSize(getActualFormat());
}
GLuint RenderbufferInterface::getDepthSize() const
{
- return dx2es::GetDepthSize(getD3DFormat());
+ return gl::GetDepthSize(getActualFormat());
}
GLuint RenderbufferInterface::getStencilSize() const
{
- return dx2es::GetStencilSize(getD3DFormat());
+ return gl::GetStencilSize(getActualFormat());
}
///// RenderbufferTexture2D Implementation ////////
@@ -87,16 +89,12 @@ void RenderbufferTexture2D::releaseProxy(const Renderbuffer *proxy)
mTexture2D->releaseProxy(proxy);
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferTexture2D::getRenderTarget()
+rx::RenderTarget *RenderbufferTexture2D::getRenderTarget()
{
return mTexture2D->getRenderTarget(mTarget);
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferTexture2D::getDepthStencil()
+rx::RenderTarget *RenderbufferTexture2D::getDepthStencil()
{
return mTexture2D->getDepthStencil(mTarget);
}
@@ -116,9 +114,9 @@ GLenum RenderbufferTexture2D::getInternalFormat() const
return mTexture2D->getInternalFormat(0);
}
-D3DFORMAT RenderbufferTexture2D::getD3DFormat() const
+GLenum RenderbufferTexture2D::getActualFormat() const
{
- return mTexture2D->getD3DFormat(0);
+ return mTexture2D->getActualFormat(0);
}
GLsizei RenderbufferTexture2D::getSamples() const
@@ -155,16 +153,12 @@ void RenderbufferTextureCubeMap::releaseProxy(const Renderbuffer *proxy)
mTextureCubeMap->releaseProxy(proxy);
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferTextureCubeMap::getRenderTarget()
+rx::RenderTarget *RenderbufferTextureCubeMap::getRenderTarget()
{
return mTextureCubeMap->getRenderTarget(mTarget);
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferTextureCubeMap::getDepthStencil()
+rx::RenderTarget *RenderbufferTextureCubeMap::getDepthStencil()
{
return NULL;
}
@@ -184,9 +178,9 @@ GLenum RenderbufferTextureCubeMap::getInternalFormat() const
return mTextureCubeMap->getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
}
-D3DFORMAT RenderbufferTextureCubeMap::getD3DFormat() const
+GLenum RenderbufferTextureCubeMap::getActualFormat() const
{
- return mTextureCubeMap->getD3DFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
+ return mTextureCubeMap->getActualFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0);
}
GLsizei RenderbufferTextureCubeMap::getSamples() const
@@ -201,7 +195,7 @@ unsigned int RenderbufferTextureCubeMap::getSerial() const
////// Renderbuffer Implementation //////
-Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
+Renderbuffer::Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *instance) : RefCountObject(id)
{
ASSERT(instance != NULL);
mInstance = instance;
@@ -228,16 +222,12 @@ void Renderbuffer::release() const
RefCountObject::release();
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+rx::RenderTarget *Renderbuffer::getRenderTarget()
{
return mInstance->getRenderTarget();
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+rx::RenderTarget *Renderbuffer::getDepthStencil()
{
return mInstance->getDepthStencil();
}
@@ -257,9 +247,9 @@ GLenum Renderbuffer::getInternalFormat() const
return mInstance->getInternalFormat();
}
-D3DFORMAT Renderbuffer::getD3DFormat() const
+GLenum Renderbuffer::getActualFormat() const
{
- return mInstance->getD3DFormat();
+ return mInstance->getActualFormat();
}
GLuint Renderbuffer::getRedSize() const
@@ -315,7 +305,7 @@ RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
mWidth = 0;
mHeight = 0;
mInternalFormat = GL_RGBA4;
- mD3DFormat = D3DFMT_A8R8G8B8;
+ mActualFormat = GL_RGBA8_OES;
mSamples = 0;
}
@@ -323,16 +313,12 @@ RenderbufferStorage::~RenderbufferStorage()
{
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
+rx::RenderTarget *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
+rx::RenderTarget *RenderbufferStorage::getDepthStencil()
{
return NULL;
}
@@ -352,9 +338,9 @@ GLenum RenderbufferStorage::getInternalFormat() const
return mInternalFormat;
}
-D3DFORMAT RenderbufferStorage::getD3DFormat() const
+GLenum RenderbufferStorage::getActualFormat() const
{
- return mD3DFormat;
+ return mActualFormat;
}
GLsizei RenderbufferStorage::getSamples() const
@@ -379,164 +365,96 @@ unsigned int RenderbufferStorage::issueCubeSerials()
return firstSerial;
}
-Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget)
+Colorbuffer::Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
{
- if (renderTarget)
- {
- renderTarget->AddRef();
-
- D3DSURFACE_DESC description;
- renderTarget->GetDesc(&description);
+ mRenderTarget = renderer->createRenderTarget(swapChain, false);
- mWidth = description.Width;
- mHeight = description.Height;
- mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format);
- mD3DFormat = description.Format;
- mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
+ if (mRenderTarget)
+ {
+ mWidth = mRenderTarget->getWidth();
+ mHeight = mRenderTarget->getHeight();
+ mInternalFormat = mRenderTarget->getInternalFormat();
+ mActualFormat = mRenderTarget->getActualFormat();
+ mSamples = mRenderTarget->getSamples();
}
}
-Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
+Colorbuffer::Colorbuffer(rx::Renderer *renderer, int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL)
{
- IDirect3DDevice9 *device = getDevice();
-
- D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
- int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
+ mRenderTarget = renderer->createRenderTarget(width, height, format, samples, false);
- if (supportedSamples == -1)
+ if (mRenderTarget)
{
- error(GL_OUT_OF_MEMORY);
-
- return;
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = format;
+ mActualFormat = mRenderTarget->getActualFormat();
+ mSamples = mRenderTarget->getSamples();
}
-
- if (width > 0 && height > 0)
- {
- HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
- es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- error(GL_OUT_OF_MEMORY);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
- }
-
- mWidth = width;
- mHeight = height;
- mInternalFormat = format;
- mD3DFormat = requestedFormat;
- mSamples = supportedSamples;
}
Colorbuffer::~Colorbuffer()
{
if (mRenderTarget)
{
- mRenderTarget->Release();
+ delete mRenderTarget;
}
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Colorbuffer::getRenderTarget()
+rx::RenderTarget *Colorbuffer::getRenderTarget()
{
if (mRenderTarget)
{
- mRenderTarget->AddRef();
+ return mRenderTarget;
}
- return mRenderTarget;
+ return NULL;
}
-DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain)
{
- if (depthStencil)
+ mDepthStencil = renderer->createRenderTarget(swapChain, true);
+ if (mDepthStencil)
{
- depthStencil->AddRef();
-
- D3DSURFACE_DESC description;
- depthStencil->GetDesc(&description);
-
- mWidth = description.Width;
- mHeight = description.Height;
- mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format);
- mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType);
- mD3DFormat = description.Format;
+ mWidth = mDepthStencil->getWidth();
+ mHeight = mDepthStencil->getHeight();
+ mInternalFormat = mDepthStencil->getInternalFormat();
+ mSamples = mDepthStencil->getSamples();
+ mActualFormat = mDepthStencil->getActualFormat();
}
}
-DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
+DepthStencilbuffer::DepthStencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples)
{
- IDirect3DDevice9 *device = getDevice();
- mDepthStencil = NULL;
-
- int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
+ mDepthStencil = renderer->createRenderTarget(width, height, GL_DEPTH24_STENCIL8_OES, samples, true);
- if (supportedSamples == -1)
- {
- error(GL_OUT_OF_MEMORY);
-
- return;
- }
-
- if (width > 0 && height > 0)
- {
- HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
- 0, FALSE, &mDepthStencil, 0);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- error(GL_OUT_OF_MEMORY);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
- }
-
- mWidth = width;
- mHeight = height;
+ mWidth = mDepthStencil->getWidth();
+ mHeight = mDepthStencil->getHeight();
mInternalFormat = GL_DEPTH24_STENCIL8_OES;
- mD3DFormat = D3DFMT_D24S8;
- mSamples = supportedSamples;
+ mActualFormat = mDepthStencil->getActualFormat();
+ mSamples = mDepthStencil->getSamples();
}
DepthStencilbuffer::~DepthStencilbuffer()
{
if (mDepthStencil)
{
- mDepthStencil->Release();
+ delete mDepthStencil;
}
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
+rx::RenderTarget *DepthStencilbuffer::getDepthStencil()
{
if (mDepthStencil)
{
- mDepthStencil->AddRef();
+ return mDepthStencil;
}
- return mDepthStencil;
-}
-
-Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
-{
- if (depthStencil)
- {
- 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
- }
+ return NULL;
}
-Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
+Depthbuffer::Depthbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
{
if (mDepthStencil)
{
@@ -550,17 +468,7 @@ Depthbuffer::~Depthbuffer()
{
}
-Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
-{
- if (depthStencil)
- {
- 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(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
+Stencilbuffer::Stencilbuffer(rx::Renderer *renderer, int width, int height, GLsizei samples) : DepthStencilbuffer(renderer, width, height, samples)
{
if (mDepthStencil)
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
index e6d5ddb875..eca2f3a780 100644
--- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
+++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h
@@ -14,11 +14,17 @@
#define GL_APICALL
#include <GLES2/gl2.h>
-#include <d3d9.h>
#include "common/angleutils.h"
#include "common/RefCountObject.h"
+namespace rx
+{
+class Renderer;
+class SwapChain;
+class RenderTarget;
+}
+
namespace gl
{
class Texture2D;
@@ -37,13 +43,13 @@ class RenderbufferInterface
virtual void addProxyRef(const Renderbuffer *proxy);
virtual void releaseProxy(const Renderbuffer *proxy);
- virtual IDirect3DSurface9 *getRenderTarget() = 0;
- virtual IDirect3DSurface9 *getDepthStencil() = 0;
+ virtual rx::RenderTarget *getRenderTarget() = 0;
+ virtual rx::RenderTarget *getDepthStencil() = 0;
virtual GLsizei getWidth() const = 0;
virtual GLsizei getHeight() const = 0;
virtual GLenum getInternalFormat() const = 0;
- virtual D3DFORMAT getD3DFormat() const = 0;
+ virtual GLenum getActualFormat() const = 0;
virtual GLsizei getSamples() const = 0;
GLuint getRedSize() const;
@@ -69,13 +75,13 @@ class RenderbufferTexture2D : public RenderbufferInterface
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
- IDirect3DSurface9 *getRenderTarget();
- IDirect3DSurface9 *getDepthStencil();
+ rx::RenderTarget *getRenderTarget();
+ rx::RenderTarget *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
- virtual D3DFORMAT getD3DFormat() const;
+ virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
@@ -97,13 +103,13 @@ class RenderbufferTextureCubeMap : public RenderbufferInterface
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
- IDirect3DSurface9 *getRenderTarget();
- IDirect3DSurface9 *getDepthStencil();
+ rx::RenderTarget *getRenderTarget();
+ rx::RenderTarget *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
- virtual D3DFORMAT getD3DFormat() const;
+ virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
@@ -125,13 +131,13 @@ class RenderbufferStorage : public RenderbufferInterface
virtual ~RenderbufferStorage() = 0;
- virtual IDirect3DSurface9 *getRenderTarget();
- virtual IDirect3DSurface9 *getDepthStencil();
+ virtual rx::RenderTarget *getRenderTarget();
+ virtual rx::RenderTarget *getDepthStencil();
virtual GLsizei getWidth() const;
virtual GLsizei getHeight() const;
virtual GLenum getInternalFormat() const;
- virtual D3DFORMAT getD3DFormat() const;
+ virtual GLenum getActualFormat() const;
virtual GLsizei getSamples() const;
virtual unsigned int getSerial() const;
@@ -143,7 +149,7 @@ class RenderbufferStorage : public RenderbufferInterface
GLsizei mWidth;
GLsizei mHeight;
GLenum mInternalFormat;
- D3DFORMAT mD3DFormat;
+ GLenum mActualFormat;
GLsizei mSamples;
private:
@@ -160,7 +166,7 @@ class RenderbufferStorage : public RenderbufferInterface
class Renderbuffer : public RefCountObject
{
public:
- Renderbuffer(GLuint id, RenderbufferInterface *storage);
+ Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *storage);
virtual ~Renderbuffer();
@@ -171,13 +177,13 @@ class Renderbuffer : public RefCountObject
void addRef() const;
void release() const;
- IDirect3DSurface9 *getRenderTarget();
- IDirect3DSurface9 *getDepthStencil();
+ rx::RenderTarget *getRenderTarget();
+ rx::RenderTarget *getDepthStencil();
GLsizei getWidth() const;
GLsizei getHeight() const;
GLenum getInternalFormat() const;
- D3DFORMAT getD3DFormat() const;
+ GLenum getActualFormat() const;
GLuint getRedSize() const;
GLuint getGreenSize() const;
GLuint getBlueSize() const;
@@ -199,31 +205,31 @@ class Renderbuffer : public RefCountObject
class Colorbuffer : public RenderbufferStorage
{
public:
- explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
- Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ Colorbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
+ Colorbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
virtual ~Colorbuffer();
- virtual IDirect3DSurface9 *getRenderTarget();
+ virtual rx::RenderTarget *getRenderTarget();
private:
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
- IDirect3DSurface9 *mRenderTarget;
+ rx::RenderTarget *mRenderTarget;
};
class DepthStencilbuffer : public RenderbufferStorage
{
public:
- explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
- DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+ DepthStencilbuffer(rx::Renderer *renderer, rx::SwapChain *swapChain);
+ DepthStencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
~DepthStencilbuffer();
- virtual IDirect3DSurface9 *getDepthStencil();
+ virtual rx::RenderTarget *getDepthStencil();
protected:
- IDirect3DSurface9 *mDepthStencil;
+ rx::RenderTarget *mDepthStencil;
private:
DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
@@ -232,8 +238,7 @@ class DepthStencilbuffer : public RenderbufferStorage
class Depthbuffer : public DepthStencilbuffer
{
public:
- explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
- Depthbuffer(GLsizei width, GLsizei height, GLsizei samples);
+ Depthbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
virtual ~Depthbuffer();
@@ -244,8 +249,7 @@ class Depthbuffer : public DepthStencilbuffer
class Stencilbuffer : public DepthStencilbuffer
{
public:
- explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
- Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples);
+ Stencilbuffer(rx::Renderer *renderer, GLsizei width, GLsizei height, GLsizei samples);
virtual ~Stencilbuffer();
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
index 4b97e9c113..58dd44fd95 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -17,9 +18,10 @@
namespace gl
{
-ResourceManager::ResourceManager()
+ResourceManager::ResourceManager(rx::Renderer *renderer)
{
mRefCount = 1;
+ mRenderer = renderer;
}
ResourceManager::~ResourceManager()
@@ -80,11 +82,11 @@ GLuint ResourceManager::createShader(GLenum type)
if (type == GL_VERTEX_SHADER)
{
- mShaderMap[handle] = new VertexShader(this, handle);
+ mShaderMap[handle] = new VertexShader(this, mRenderer, handle);
}
else if (type == GL_FRAGMENT_SHADER)
{
- mShaderMap[handle] = new FragmentShader(this, handle);
+ mShaderMap[handle] = new FragmentShader(this, mRenderer, handle);
}
else UNREACHABLE();
@@ -96,7 +98,7 @@ GLuint ResourceManager::createProgram()
{
GLuint handle = mProgramShaderHandleAllocator.allocate();
- mProgramMap[handle] = new Program(this, handle);
+ mProgramMap[handle] = new Program(mRenderer, this, handle);
return handle;
}
@@ -276,7 +278,7 @@ void ResourceManager::checkBufferAllocation(unsigned int buffer)
{
if (buffer != 0 && !getBuffer(buffer))
{
- Buffer *bufferObject = new Buffer(buffer);
+ Buffer *bufferObject = new Buffer(mRenderer, buffer);
mBufferMap[buffer] = bufferObject;
bufferObject->addRef();
}
@@ -290,11 +292,11 @@ void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type)
if (type == TEXTURE_2D)
{
- textureObject = new Texture2D(texture);
+ textureObject = new Texture2D(mRenderer, texture);
}
else if (type == TEXTURE_CUBE)
{
- textureObject = new TextureCubeMap(texture);
+ textureObject = new TextureCubeMap(mRenderer, texture);
}
else
{
@@ -311,7 +313,7 @@ void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
{
if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
{
- Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
+ Renderbuffer *renderbufferObject = new Renderbuffer(mRenderer, renderbuffer, new Colorbuffer(mRenderer, 0, 0, GL_RGBA4, 0));
mRenderbufferMap[renderbuffer] = renderbufferObject;
renderbufferObject->addRef();
}
diff --git a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
index ae4f1b04a5..e99c77c35d 100644
--- a/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
+++ b/src/3rdparty/angle/src/libGLESv2/ResourceManager.h
@@ -20,8 +20,14 @@
#endif
#include "common/angleutils.h"
+#include "libGLESv2/angletypes.h"
#include "libGLESv2/HandleAllocator.h"
+namespace rx
+{
+class Renderer;
+}
+
namespace gl
{
class Buffer;
@@ -30,25 +36,10 @@ class Program;
class Texture;
class Renderbuffer;
-enum TextureType
-{
- TEXTURE_2D,
- TEXTURE_CUBE,
-
- TEXTURE_TYPE_COUNT,
- TEXTURE_UNKNOWN
-};
-
-enum SamplerType
-{
- SAMPLER_PIXEL,
- SAMPLER_VERTEX
-};
-
class ResourceManager
{
public:
- ResourceManager();
+ explicit ResourceManager(rx::Renderer *renderer);
~ResourceManager();
void addRef();
@@ -82,6 +73,7 @@ class ResourceManager
DISALLOW_COPY_AND_ASSIGN(ResourceManager);
std::size_t mRefCount;
+ rx::Renderer *mRenderer;
#ifndef HASH_MAP
# ifdef _MSC_VER
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index 1087f11b4a..abddab427b 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,18 +11,19 @@
#include "libGLESv2/Shader.h"
-#include <string>
-
#include "GLSLANG/ShaderLang.h"
-#include "libGLESv2/main.h"
#include "libGLESv2/utilities.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Constants.h"
+#include "libGLESv2/ResourceManager.h"
namespace gl
{
void *Shader::mFragmentCompiler = NULL;
void *Shader::mVertexCompiler = NULL;
-Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
+Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
+ : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
{
mSource = NULL;
mHlsl = NULL;
@@ -174,6 +176,11 @@ void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
getSourceImpl(mHlsl, bufSize, length, buffer);
}
+const sh::ActiveUniforms &Shader::getUniforms()
+{
+ return mActiveUniforms;
+}
+
bool Shader::isCompiled()
{
return mHlsl != NULL;
@@ -223,23 +230,26 @@ void Shader::initializeCompiler()
if (result)
{
+ ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
+
ShBuiltInResources resources;
ShInitBuiltInResources(&resources);
- Context *context = getContext();
resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
- resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
- resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
- resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits();
- resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits();
+ resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
+ resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
+ resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
+ resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
- resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
- resources.OES_standard_derivatives = 1;
- // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported.
-
- mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
- mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources);
+ resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
+ resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets();
+ resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
+ resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
+ // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
+ resources.FragmentPrecisionHigh = 1; // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
+
+ mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
+ mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
}
}
}
@@ -287,6 +297,9 @@ void Shader::parseVaryings()
input = strstr(input, ";") + 2;
}
+ mUsesMultipleRenderTargets = strstr(mHlsl, "GL_USES_MRT") != NULL;
+ mUsesFragColor = strstr(mHlsl, "GL_USES_FRAG_COLOR") != NULL;
+ mUsesFragData = strstr(mHlsl, "GL_USES_FRAG_DATA") != NULL;
mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
@@ -294,6 +307,15 @@ void Shader::parseVaryings()
}
}
+void Shader::resetVaryingsRegisterAssignment()
+{
+ for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
+ {
+ var->reg = -1;
+ var->col = -1;
+ }
+}
+
// initialize/clean up previous state
void Shader::uncompile()
{
@@ -306,16 +328,21 @@ void Shader::uncompile()
// set by parseVaryings
mVaryings.clear();
+ mUsesMultipleRenderTargets = false;
+ mUsesFragColor = false;
+ mUsesFragData = false;
mUsesFragCoord = false;
mUsesFrontFacing = false;
mUsesPointSize = false;
mUsesPointCoord = false;
+
+ mActiveUniforms.clear();
}
void Shader::compileToHLSL(void *compiler)
{
// ensure we don't pass a NULL source to the compiler
- char *source = "\0";
+ const char *source = "\0";
if (mSource)
{
source = mSource;
@@ -351,14 +378,18 @@ void Shader::compileToHLSL(void *compiler)
if (result)
{
- int objCodeLen = 0;
+ size_t objCodeLen = 0;
ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
mHlsl = new char[objCodeLen];
ShGetObjectCode(compiler, mHlsl);
+
+ void *activeUniforms;
+ ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
+ mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
}
else
{
- int infoLogLen = 0;
+ size_t infoLogLen = 0;
ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
mInfoLog = new char[infoLogLen];
ShGetInfoLog(compiler, mInfoLog);
@@ -485,7 +516,8 @@ bool Shader::compareVarying(const Varying &x, const Varying &y)
return false;
}
-VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
+VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
+ : Shader(manager, renderer, handle)
{
}
@@ -504,7 +536,7 @@ void VertexShader::uncompile()
// set by ParseAttributes
mAttributes.clear();
-};
+}
void VertexShader::compile()
{
@@ -560,7 +592,8 @@ void VertexShader::parseAttributes()
}
}
-FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
+FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
+ : Shader(manager, renderer, handle)
{
}
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h
index b73fc288a1..f471968550 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.h
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -18,10 +18,18 @@
#include <list>
#include <vector>
-#include "libGLESv2/ResourceManager.h"
+#include "compiler/Uniform.h"
+#include "common/angleutils.h"
+
+namespace rx
+{
+class Renderer;
+}
namespace gl
{
+class ResourceManager;
+
struct Varying
{
Varying(GLenum type, const std::string &name, int size, bool array)
@@ -45,7 +53,7 @@ class Shader
friend class ProgramBinary;
public:
- Shader(ResourceManager *manager, GLuint handle);
+ Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
virtual ~Shader();
@@ -60,6 +68,7 @@ class Shader
void getSource(GLsizei bufSize, GLsizei *length, char *buffer);
int getTranslatedSourceLength() const;
void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer);
+ const sh::ActiveUniforms &getUniforms();
virtual void compile() = 0;
virtual void uncompile();
@@ -76,6 +85,7 @@ class Shader
protected:
void parseVaryings();
+ void resetVaryingsRegisterAssignment();
void compileToHLSL(void *compiler);
@@ -84,8 +94,13 @@ class Shader
static GLenum parseType(const std::string &type);
static bool compareVarying(const Varying &x, const Varying &y);
+ const rx::Renderer *const mRenderer;
+
VaryingList mVaryings;
+ bool mUsesMultipleRenderTargets;
+ bool mUsesFragColor;
+ bool mUsesFragData;
bool mUsesFragCoord;
bool mUsesFrontFacing;
bool mUsesPointSize;
@@ -106,6 +121,7 @@ class Shader
char *mSource;
char *mHlsl;
char *mInfoLog;
+ sh::ActiveUniforms mActiveUniforms;
ResourceManager *mResourceManager;
};
@@ -131,7 +147,7 @@ class VertexShader : public Shader
friend class ProgramBinary;
public:
- VertexShader(ResourceManager *manager, GLuint handle);
+ VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle);
~VertexShader();
@@ -151,7 +167,7 @@ class VertexShader : public Shader
class FragmentShader : public Shader
{
public:
- FragmentShader(ResourceManager *manager, GLuint handle);
+ FragmentShader(ResourceManager *manager,const rx::Renderer *renderer, GLuint handle);
~FragmentShader();
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
index 0ea475d088..461357a1ce 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -10,1320 +11,34 @@
#include "libGLESv2/Texture.h"
-#include <algorithm>
-
-#include "common/debug.h"
-
-#include "libEGL/Display.h"
-
#include "libGLESv2/main.h"
#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
-#include "libGLESv2/Blit.h"
-#include "libGLESv2/Framebuffer.h"
-
-namespace gl
-{
-unsigned int TextureStorage::mCurrentTextureSerial = 1;
-
-static D3DFORMAT ConvertTextureInternalFormat(GLint internalformat)
-{
- switch (internalformat)
- {
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT32_OES:
- case GL_DEPTH24_STENCIL8_OES:
- return D3DFMT_INTZ;
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- return D3DFMT_DXT1;
- case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
- return D3DFMT_DXT3;
- case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- return D3DFMT_DXT5;
- case GL_RGBA32F_EXT:
- case GL_RGB32F_EXT:
- case GL_ALPHA32F_EXT:
- case GL_LUMINANCE32F_EXT:
- case GL_LUMINANCE_ALPHA32F_EXT:
- return D3DFMT_A32B32G32R32F;
- case GL_RGBA16F_EXT:
- case GL_RGB16F_EXT:
- case GL_ALPHA16F_EXT:
- case GL_LUMINANCE16F_EXT:
- case GL_LUMINANCE_ALPHA16F_EXT:
- return D3DFMT_A16B16G16R16F;
- case GL_LUMINANCE8_EXT:
- if (getContext()->supportsLuminanceTextures())
- {
- return D3DFMT_L8;
- }
- break;
- case GL_LUMINANCE8_ALPHA8_EXT:
- if (getContext()->supportsLuminanceAlphaTextures())
- {
- return D3DFMT_A8L8;
- }
- break;
- case GL_RGB8_OES:
- case GL_RGB565:
- return D3DFMT_X8R8G8B8;
- }
-
- return D3DFMT_A8R8G8B8;
-}
-
-static bool IsTextureFormatRenderable(D3DFORMAT format)
-{
- if (format == D3DFMT_INTZ)
- {
- return true;
- }
- switch(format)
- {
- case D3DFMT_L8:
- case D3DFMT_A8L8:
- case D3DFMT_DXT1:
- case D3DFMT_DXT3:
- case D3DFMT_DXT5:
- return false;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A16B16G16R16F:
- case D3DFMT_A32B32G32R32F:
- return true;
- default:
- UNREACHABLE();
- }
-
- return false;
-}
-
-static inline DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
-{
- DWORD d3dusage = 0;
-
- if (d3dfmt == D3DFMT_INTZ)
- {
- d3dusage |= D3DUSAGE_DEPTHSTENCIL;
- }
- else if(forceRenderable || (IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
- {
- d3dusage |= D3DUSAGE_RENDERTARGET;
- }
- return d3dusage;
-}
-
-static void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
-{
- int upsampleCount = 0;
-
- if (isCompressed)
- {
- // Don't expand the size of full textures that are at least 4x4
- // already.
- if (isImage || *requestWidth < 4 || *requestHeight < 4)
- {
- while (*requestWidth % 4 != 0 || *requestHeight % 4 != 0)
- {
- *requestWidth <<= 1;
- *requestHeight <<= 1;
- upsampleCount++;
- }
- }
- }
- *levelOffset = upsampleCount;
-}
-
-static void CopyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
-{
- D3DLOCKED_RECT sourceLock = {0};
- D3DLOCKED_RECT destLock = {0};
-
- source->LockRect(&sourceLock, NULL, 0);
- dest->LockRect(&destLock, NULL, 0);
-
- if (sourceLock.pBits && destLock.pBits)
- {
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
-
- int rows = dx::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height;
- int bytes = dx::ComputeRowSize(desc.Format, desc.Width);
- ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch);
-
- for(int i = 0; i < rows; i++)
- {
- memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
- }
-
- source->UnlockRect();
- dest->UnlockRect();
- }
- else UNREACHABLE();
-}
-
-Image::Image()
-{
- mWidth = 0;
- mHeight = 0;
- mInternalFormat = GL_NONE;
-
- mSurface = NULL;
-
- mDirty = false;
-
- mD3DPool = D3DPOOL_SYSTEMMEM;
- mD3DFormat = D3DFMT_UNKNOWN;
-}
-
-Image::~Image()
-{
- if (mSurface)
- {
- mSurface->Release();
- }
-}
-
-bool Image::redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
-{
- if (mWidth != width ||
- mHeight != height ||
- mInternalFormat != internalformat ||
- forceRelease)
- {
- mWidth = width;
- mHeight = height;
- mInternalFormat = internalformat;
- // compute the d3d format that will be used
- mD3DFormat = ConvertTextureInternalFormat(internalformat);
-
- if (mSurface)
- {
- mSurface->Release();
- mSurface = NULL;
- }
-
- return true;
- }
-
- return false;
-}
-
-void Image::createSurface()
-{
- if(mSurface)
- {
- return;
- }
-
- IDirect3DTexture9 *newTexture = NULL;
- IDirect3DSurface9 *newSurface = NULL;
- const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
- const D3DFORMAT d3dFormat = getD3DFormat();
- ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures
-
- if (mWidth != 0 && mHeight != 0)
- {
- int levelToFetch = 0;
- GLsizei requestWidth = mWidth;
- GLsizei requestHeight = mHeight;
- MakeValidSize(true, IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch);
-
- HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, d3dFormat,
- poolToUse, &newTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- ERR("Creating image surface failed.");
- return error(GL_OUT_OF_MEMORY);
- }
-
- newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
- newTexture->Release();
- }
-
- mSurface = newSurface;
- mDirty = false;
- mD3DPool = poolToUse;
-}
-
-HRESULT Image::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
-{
- createSurface();
-
- HRESULT result = D3DERR_INVALIDCALL;
-
- if (mSurface)
- {
- result = mSurface->LockRect(lockedRect, rect, 0);
- ASSERT(SUCCEEDED(result));
-
- mDirty = true;
- }
-
- return result;
-}
-
-void Image::unlock()
-{
- if (mSurface)
- {
- HRESULT result = mSurface->UnlockRect();
- ASSERT(SUCCEEDED(result));
- }
-}
-
-bool Image::isRenderableFormat() const
-{
- return IsTextureFormatRenderable(getD3DFormat());
-}
-
-D3DFORMAT Image::getD3DFormat() const
-{
- // this should only happen if the image hasn't been redefined first
- // which would be a bug by the caller
- ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
-
- return mD3DFormat;
-}
-
-IDirect3DSurface9 *Image::getSurface()
-{
- createSurface();
-
- return mSurface;
-}
-
-void Image::setManagedSurface(IDirect3DSurface9 *surface)
-{
- D3DSURFACE_DESC desc;
- surface->GetDesc(&desc);
- ASSERT(desc.Pool == D3DPOOL_MANAGED);
-
- if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight)
- {
- if (mSurface)
- {
- CopyLockableSurfaces(surface, mSurface);
- mSurface->Release();
- }
-
- mSurface = surface;
- mD3DPool = desc.Pool;
- }
-}
-
-void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
-{
- IDirect3DSurface9 *sourceSurface = getSurface();
-
- if (sourceSurface && sourceSurface != destSurface)
- {
- RECT rect;
- rect.left = xoffset;
- rect.top = yoffset;
- rect.right = xoffset + width;
- rect.bottom = yoffset + height;
-
- POINT point = {rect.left, rect.top};
-
- if (mD3DPool == D3DPOOL_MANAGED)
- {
- D3DSURFACE_DESC desc;
- sourceSurface->GetDesc(&desc);
-
- IDirect3DSurface9 *surf = 0;
- HRESULT result = getDevice()->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
-
- if (SUCCEEDED(result))
- {
- CopyLockableSurfaces(surf, sourceSurface);
- result = getDevice()->UpdateSurface(surf, &rect, destSurface, &point);
- ASSERT(SUCCEEDED(result));
- surf->Release();
- }
- }
- else
- {
- // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
- HRESULT result = getDevice()->UpdateSurface(sourceSurface, &rect, destSurface, &point);
- ASSERT(SUCCEEDED(result));
- }
- }
-}
-
-// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
-// into the target pixel rectangle.
-void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLint unpackAlignment, const void *input)
-{
- RECT lockRect =
- {
- xoffset, yoffset,
- xoffset + width, yoffset + height
- };
-
- D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
- {
- return;
- }
-
-
- GLsizei inputPitch = ComputePitch(width, mInternalFormat, unpackAlignment);
-
- switch (mInternalFormat)
- {
- case GL_ALPHA8_EXT:
-#if defined(__SSE2__)
- if (supportsSSE2())
- {
- loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- }
- else
-#endif
- {
- loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- }
- break;
- case GL_LUMINANCE8_EXT:
- loadLuminanceData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
- break;
- case GL_ALPHA32F_EXT:
- loadAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_LUMINANCE32F_EXT:
- loadLuminanceFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_ALPHA16F_EXT:
- loadAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_LUMINANCE16F_EXT:
- loadLuminanceHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_LUMINANCE8_ALPHA8_EXT:
- loadLuminanceAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
- break;
- case GL_LUMINANCE_ALPHA32F_EXT:
- loadLuminanceAlphaFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_LUMINANCE_ALPHA16F_EXT:
- loadLuminanceAlphaHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGB8_OES:
- loadRGBUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGB565:
- loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGBA8_OES:
-#if defined(__SSE2__)
- if (supportsSSE2())
- {
- loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- }
- else
+#if defined(ANGLE_ENABLE_D3D11)
+# define D3DFMT_UNKNOWN DXGI_FORMAT_UNKNOWN
+#else
+# include "libGLESv2/renderer/Blit.h"
#endif
- {
- loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- }
- break;
- case GL_RGBA4:
- loadRGBA4444Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGB5_A1:
- loadRGBA5551Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_BGRA8_EXT:
- loadBGRAData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
- case GL_RGB32F_EXT:
- loadRGBFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGB16F_EXT:
- loadRGBHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGBA32F_EXT:
- loadRGBAFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- case GL_RGBA16F_EXT:
- loadRGBAHalfFloatData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
- break;
- default: UNREACHABLE();
- }
-
- unlock();
-}
-
-void Image::loadAlphaData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = 0;
- dest[4 * x + 1] = 0;
- dest[4 * x + 2] = 0;
- dest[4 * x + 3] = source[x];
- }
- }
-}
-
-void Image::loadAlphaFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const float *source = NULL;
- float *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = 0;
- dest[4 * x + 1] = 0;
- dest[4 * x + 2] = 0;
- dest[4 * x + 3] = source[x];
- }
- }
-}
-
-void Image::loadAlphaHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned short *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = 0;
- dest[4 * x + 1] = 0;
- dest[4 * x + 2] = 0;
- dest[4 * x + 3] = source[x];
- }
- }
-}
-
-void Image::loadLuminanceData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
-
- if (!native) // BGRA8 destination format
- {
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x];
- dest[4 * x + 1] = source[x];
- dest[4 * x + 2] = source[x];
- dest[4 * x + 3] = 0xFF;
- }
- }
- else // L8 destination format
- {
- memcpy(dest, source, width);
- }
- }
-}
-
-void Image::loadLuminanceFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const float *source = NULL;
- float *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x];
- dest[4 * x + 1] = source[x];
- dest[4 * x + 2] = source[x];
- dest[4 * x + 3] = 1.0f;
- }
- }
-}
-
-void Image::loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned short *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x];
- dest[4 * x + 1] = source[x];
- dest[4 * x + 2] = source[x];
- dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
- }
- }
-}
-
-void Image::loadLuminanceAlphaData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
-
- if (!native) // BGRA8 destination format
- {
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[2*x+0];
- dest[4 * x + 1] = source[2*x+0];
- dest[4 * x + 2] = source[2*x+0];
- dest[4 * x + 3] = source[2*x+1];
- }
- }
- else
- {
- memcpy(dest, source, width * 2);
- }
- }
-}
-
-void Image::loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const float *source = NULL;
- float *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[2*x+0];
- dest[4 * x + 1] = source[2*x+0];
- dest[4 * x + 2] = source[2*x+0];
- dest[4 * x + 3] = source[2*x+1];
- }
- }
-}
-
-void Image::loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned short *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[2*x+0];
- dest[4 * x + 1] = source[2*x+0];
- dest[4 * x + 2] = source[2*x+0];
- dest[4 * x + 3] = source[2*x+1];
- }
- }
-}
-
-void Image::loadRGBUByteData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x * 3 + 2];
- dest[4 * x + 1] = source[x * 3 + 1];
- dest[4 * x + 2] = source[x * 3 + 0];
- dest[4 * x + 3] = 0xFF;
- }
- }
-}
-
-void Image::loadRGB565Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- for (int x = 0; x < width; x++)
- {
- unsigned short rgba = source[x];
- dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
- dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
- dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- dest[4 * x + 3] = 0xFF;
- }
- }
-}
-
-void Image::loadRGBFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const float *source = NULL;
- float *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x * 3 + 0];
- dest[4 * x + 1] = source[x * 3 + 1];
- dest[4 * x + 2] = source[x * 3 + 2];
- dest[4 * x + 3] = 1.0f;
- }
- }
-}
-
-void Image::loadRGBHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned short *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
- for (int x = 0; x < width; x++)
- {
- dest[4 * x + 0] = source[x * 3 + 0];
- dest[4 * x + 1] = source[x * 3 + 1];
- dest[4 * x + 2] = source[x * 3 + 2];
- dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
- }
- }
-}
-
-void Image::loadRGBAUByteData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned int *source = NULL;
- unsigned int *dest = NULL;
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
-
- for (int x = 0; x < width; x++)
- {
- unsigned int rgba = source[x];
- dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
- }
- }
-}
-
-void Image::loadRGBA4444Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- for (int x = 0; x < width; x++)
- {
- unsigned short rgba = source[x];
- dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
- dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
- dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
- dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
- }
- }
-}
-
-void Image::loadRGBA5551Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned short *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- for (int x = 0; x < width; x++)
- {
- unsigned short rgba = source[x];
- dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
- dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
- dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
- }
- }
-}
-
-void Image::loadRGBAFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const float *source = NULL;
- float *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
- dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
- memcpy(dest, source, width * 16);
- }
-}
-
-void Image::loadRGBAHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- memcpy(dest, source, width * 8);
- }
-}
-
-void Image::loadBGRAData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
-{
- const unsigned char *source = NULL;
- unsigned char *dest = NULL;
-
- for (int y = 0; y < height; y++)
- {
- source = static_cast<const unsigned char*>(input) + y * inputPitch;
- dest = static_cast<unsigned char*>(output) + y * outputPitch;
- memcpy(dest, source, width*4);
- }
-}
-
-void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- const void *input) {
- ASSERT(xoffset % 4 == 0);
- ASSERT(yoffset % 4 == 0);
-
- RECT lockRect = {
- xoffset, yoffset,
- xoffset + width, yoffset + height
- };
-
- D3DLOCKED_RECT locked;
- HRESULT result = lock(&locked, &lockRect);
- if (FAILED(result))
- {
- return;
- }
-
- GLsizei inputSize = ComputeCompressedSize(width, height, mInternalFormat);
- GLsizei inputPitch = ComputeCompressedPitch(width, mInternalFormat);
- int rows = inputSize / inputPitch;
- for (int i = 0; i < rows; ++i)
- {
- memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
- }
-
- unlock();
-}
-
-// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
-void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
-{
- IDirect3DDevice9 *device = getDevice();
- IDirect3DSurface9 *renderTargetData = NULL;
- D3DSURFACE_DESC description;
- renderTarget->GetDesc(&description);
-
- HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL);
-
- if (FAILED(result))
- {
- ERR("Could not create matching destination surface.");
- return error(GL_OUT_OF_MEMORY);
- }
-
- result = device->GetRenderTargetData(renderTarget, renderTargetData);
-
- if (FAILED(result))
- {
- ERR("GetRenderTargetData unexpectedly failed.");
- renderTargetData->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- RECT sourceRect = {x, y, x + width, y + height};
- RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
-
- D3DLOCKED_RECT sourceLock = {0};
- result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
-
- if (FAILED(result))
- {
- ERR("Failed to lock the source surface (rectangle might be invalid).");
- renderTargetData->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- D3DLOCKED_RECT destLock = {0};
- result = lock(&destLock, &destRect);
-
- if (FAILED(result))
- {
- ERR("Failed to lock the destination surface (rectangle might be invalid).");
- renderTargetData->UnlockRect();
- renderTargetData->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- if (destLock.pBits && sourceLock.pBits)
- {
- unsigned char *source = (unsigned char*)sourceLock.pBits;
- unsigned char *dest = (unsigned char*)destLock.pBits;
-
- switch (description.Format)
- {
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- switch(getD3DFormat())
- {
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
- {
- memcpy(dest, source, 4 * width);
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- dest[x] = source[x * 4 + 2];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- dest[x * 2 + 0] = source[x * 4 + 2];
- dest[x * 2 + 1] = source[x * 4 + 3];
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- default:
- UNREACHABLE();
- }
- break;
- case D3DFMT_R5G6B5:
- switch(getD3DFormat())
- {
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned short rgb = ((unsigned short*)source)[x];
- unsigned char red = (rgb & 0xF800) >> 8;
- unsigned char green = (rgb & 0x07E0) >> 3;
- unsigned char blue = (rgb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 6);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0xF8;
- dest[x] = red | (red >> 5);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- default:
- UNREACHABLE();
- }
- break;
- case D3DFMT_A1R5G5B5:
- switch(getD3DFormat())
- {
- case D3DFMT_X8R8G8B8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = 0xFF;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_A8R8G8B8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned short argb = ((unsigned short*)source)[x];
- unsigned char red = (argb & 0x7C00) >> 7;
- unsigned char green = (argb & 0x03E0) >> 2;
- unsigned char blue = (argb & 0x001F) << 3;
- unsigned char alpha = (signed short)argb >> 15;
- dest[x + 0] = blue | (blue >> 5);
- dest[x + 1] = green | (green >> 5);
- dest[x + 2] = red | (red >> 5);
- dest[x + 3] = alpha;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x] = (red << 1) | (red >> 4);
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- case D3DFMT_A8L8:
- for(int y = 0; y < height; y++)
- {
- for(int x = 0; x < width; x++)
- {
- unsigned char red = source[x * 2 + 1] & 0x7C;
- dest[x * 2 + 0] = (red << 1) | (red >> 4);
- dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
- }
-
- source += sourceLock.Pitch;
- dest += destLock.Pitch;
- }
- break;
- default:
- UNREACHABLE();
- }
- break;
- default:
- UNREACHABLE();
- }
- }
-
- unlock();
- renderTargetData->UnlockRect();
-
- renderTargetData->Release();
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/Image.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/TextureStorage.h"
+#include "libEGL/Surface.h"
- mDirty = true;
-}
-
-namespace
-{
-struct L8
-{
- unsigned char L;
-
- static void average(L8 *dst, const L8 *src1, const L8 *src2)
- {
- dst->L = ((src1->L ^ src2->L) >> 1) + (src1->L & src2->L);
- }
-};
-
-struct A8L8
-{
- unsigned char L;
- unsigned char A;
-
- static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2)
- {
- *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2);
- }
-};
-
-struct A8R8G8B8
-{
- unsigned char B;
- unsigned char G;
- unsigned char R;
- unsigned char A;
-
- static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2)
- {
- *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2);
- }
-};
-
-struct A16B16G16R16F
-{
- unsigned short R;
- unsigned short G;
- unsigned short B;
- unsigned short A;
-
- static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2)
- {
- dst->R = float32ToFloat16((float16ToFloat32(src1->R) + float16ToFloat32(src2->R)) * 0.5f);
- dst->G = float32ToFloat16((float16ToFloat32(src1->G) + float16ToFloat32(src2->G)) * 0.5f);
- dst->B = float32ToFloat16((float16ToFloat32(src1->B) + float16ToFloat32(src2->B)) * 0.5f);
- dst->A = float32ToFloat16((float16ToFloat32(src1->A) + float16ToFloat32(src2->A)) * 0.5f);
- }
-};
-
-struct A32B32G32R32F
-{
- float R;
- float G;
- float B;
- float A;
-
- static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2)
- {
- dst->R = (src1->R + src2->R) * 0.5f;
- dst->G = (src1->G + src2->G) * 0.5f;
- dst->B = (src1->B + src2->B) * 0.5f;
- dst->A = (src1->A + src2->A) * 0.5f;
- }
-};
-
-template <typename T>
-void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight,
- const unsigned char *sourceData, int sourcePitch,
- unsigned char *destData, int destPitch)
-{
- unsigned int mipWidth = std::max(1U, sourceWidth >> 1);
- unsigned int mipHeight = std::max(1U, sourceHeight >> 1);
-
- if (sourceHeight == 1)
- {
- ASSERT(sourceWidth != 1);
-
- const T *src = (const T*)sourceData;
- T *dst = (T*)destData;
-
- for (unsigned int x = 0; x < mipWidth; x++)
- {
- T::average(&dst[x], &src[x * 2], &src[x * 2 + 1]);
- }
- }
- else if (sourceWidth == 1)
- {
- ASSERT(sourceHeight != 1);
-
- for (unsigned int y = 0; y < mipHeight; y++)
- {
- const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch);
- const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch);
- T *dst = (T*)(destData + y * destPitch);
-
- T::average(dst, src0, src1);
- }
- }
- else
- {
- for (unsigned int y = 0; y < mipHeight; y++)
- {
- const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch);
- const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch);
- T *dst = (T*)(destData + y * destPitch);
-
- for (unsigned int x = 0; x < mipWidth; x++)
- {
- T tmp0;
- T tmp1;
-
- T::average(&tmp0, &src0[x * 2], &src0[x * 2 + 1]);
- T::average(&tmp1, &src1[x * 2], &src1[x * 2 + 1]);
- T::average(&dst[x], &tmp0, &tmp1);
- }
- }
- }
-}
-
-void GenerateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
-{
- D3DSURFACE_DESC destDesc;
- HRESULT result = destSurface->GetDesc(&destDesc);
- ASSERT(SUCCEEDED(result));
-
- D3DSURFACE_DESC sourceDesc;
- result = sourceSurface->GetDesc(&sourceDesc);
- ASSERT(SUCCEEDED(result));
-
- ASSERT(sourceDesc.Format == destDesc.Format);
- ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
- ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
-
- D3DLOCKED_RECT sourceLocked = {0};
- result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
- ASSERT(SUCCEEDED(result));
-
- D3DLOCKED_RECT destLocked = {0};
- result = destSurface->LockRect(&destLocked, NULL, 0);
- ASSERT(SUCCEEDED(result));
-
- const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(sourceLocked.pBits);
- unsigned char *destData = reinterpret_cast<unsigned char*>(destLocked.pBits);
-
- if (sourceData && destData)
- {
- switch (sourceDesc.Format)
- {
- case D3DFMT_L8:
- GenerateMip<L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
- break;
- case D3DFMT_A8L8:
- GenerateMip<A8L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
- break;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
- GenerateMip<A8R8G8B8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
- break;
- case D3DFMT_A16B16G16R16F:
- GenerateMip<A16B16G16R16F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
- break;
- case D3DFMT_A32B32G32R32F:
- GenerateMip<A32B32G32R32F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
- break;
- default:
- UNREACHABLE();
- break;
- }
-
- destSurface->UnlockRect();
- sourceSurface->UnlockRect();
- }
-}
-}
-
-TextureStorage::TextureStorage(DWORD usage)
- : mD3DUsage(usage),
- mD3DPool(getDisplay()->getTexturePool(usage)),
- mTextureSerial(issueTextureSerial()),
- mLodOffset(0)
-{
-}
-
-TextureStorage::~TextureStorage()
-{
-}
-
-bool TextureStorage::isRenderTarget() const
-{
- return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
-}
-
-bool TextureStorage::isManaged() const
-{
- return (mD3DPool == D3DPOOL_MANAGED);
-}
-
-D3DPOOL TextureStorage::getPool() const
-{
- return mD3DPool;
-}
-
-DWORD TextureStorage::getUsage() const
-{
- return mD3DUsage;
-}
-
-unsigned int TextureStorage::getTextureSerial() const
-{
- return mTextureSerial;
-}
-
-unsigned int TextureStorage::issueTextureSerial()
+namespace gl
{
- return mCurrentTextureSerial++;
-}
-int TextureStorage::getLodOffset() const
+Texture::Texture(rx::Renderer *renderer, GLuint id) : RefCountObject(id)
{
- return mLodOffset;
-}
+ mRenderer = renderer;
-Texture::Texture(GLuint id) : RefCountObject(id)
-{
- mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
- mMagFilter = GL_LINEAR;
- mWrapS = GL_REPEAT;
- mWrapT = GL_REPEAT;
- mDirtyParameters = true;
+ mSamplerState.minFilter = GL_NEAREST_MIPMAP_LINEAR;
+ mSamplerState.magFilter = GL_LINEAR;
+ mSamplerState.wrapS = GL_REPEAT;
+ mSamplerState.wrapT = GL_REPEAT;
+ mSamplerState.maxAnisotropy = 1.0f;
+ mSamplerState.lodOffset = 0;
mUsage = GL_NONE;
- mMaxAnisotropy = 1.0f;
mDirtyImages = true;
@@ -1345,14 +60,8 @@ bool Texture::setMinFilter(GLenum filter)
case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR:
- {
- if (mMinFilter != filter)
- {
- mMinFilter = filter;
- mDirtyParameters = true;
- }
- return true;
- }
+ mSamplerState.minFilter = filter;
+ return true;
default:
return false;
}
@@ -1365,14 +74,8 @@ bool Texture::setMagFilter(GLenum filter)
{
case GL_NEAREST:
case GL_LINEAR:
- {
- if (mMagFilter != filter)
- {
- mMagFilter = filter;
- mDirtyParameters = true;
- }
- return true;
- }
+ mSamplerState.magFilter = filter;
+ return true;
default:
return false;
}
@@ -1386,14 +89,8 @@ bool Texture::setWrapS(GLenum wrap)
case GL_REPEAT:
case GL_CLAMP_TO_EDGE:
case GL_MIRRORED_REPEAT:
- {
- if (mWrapS != wrap)
- {
- mWrapS = wrap;
- mDirtyParameters = true;
- }
- return true;
- }
+ mSamplerState.wrapS = wrap;
+ return true;
default:
return false;
}
@@ -1407,14 +104,8 @@ bool Texture::setWrapT(GLenum wrap)
case GL_REPEAT:
case GL_CLAMP_TO_EDGE:
case GL_MIRRORED_REPEAT:
- {
- if (mWrapT != wrap)
- {
- mWrapT = wrap;
- mDirtyParameters = true;
- }
- return true;
- }
+ mSamplerState.wrapT = wrap;
+ return true;
default:
return false;
}
@@ -1428,11 +119,9 @@ bool Texture::setMaxAnisotropy(float textureMaxAnisotropy, float contextMaxAniso
{
return false;
}
- if (mMaxAnisotropy != textureMaxAnisotropy)
- {
- mMaxAnisotropy = textureMaxAnisotropy;
- mDirtyParameters = true;
- }
+
+ mSamplerState.maxAnisotropy = textureMaxAnisotropy;
+
return true;
}
@@ -1452,27 +141,39 @@ bool Texture::setUsage(GLenum usage)
GLenum Texture::getMinFilter() const
{
- return mMinFilter;
+ return mSamplerState.minFilter;
}
GLenum Texture::getMagFilter() const
{
- return mMagFilter;
+ return mSamplerState.magFilter;
}
GLenum Texture::getWrapS() const
{
- return mWrapS;
+ return mSamplerState.wrapS;
}
GLenum Texture::getWrapT() const
{
- return mWrapT;
+ return mSamplerState.wrapT;
}
float Texture::getMaxAnisotropy() const
{
- return mMaxAnisotropy;
+ return mSamplerState.maxAnisotropy;
+}
+
+int Texture::getLodOffset()
+{
+ rx::TextureStorageInterface *texture = getStorage(false);
+ return texture ? texture->getLodOffset() : 0;
+}
+
+void Texture::getSamplerState(SamplerState *sampler)
+{
+ *sampler = mSamplerState;
+ sampler->lodOffset = getLodOffset();
}
GLenum Texture::getUsage() const
@@ -1480,7 +181,24 @@ GLenum Texture::getUsage() const
return mUsage;
}
-void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image)
+bool Texture::isMipmapFiltered() const
+{
+ switch (mSamplerState.minFilter)
+ {
+ case GL_NEAREST:
+ case GL_LINEAR:
+ return false;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ case GL_LINEAR_MIPMAP_NEAREST:
+ case GL_NEAREST_MIPMAP_LINEAR:
+ case GL_LINEAR_MIPMAP_LINEAR:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+void Texture::setImage(GLint unpackAlignment, const void *pixels, rx::Image *image)
{
if (pixels != NULL)
{
@@ -1489,7 +207,7 @@ void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image)
}
}
-void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image)
+void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image)
{
if (pixels != NULL)
{
@@ -1498,7 +216,7 @@ void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *i
}
}
-bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image)
+bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, rx::Image *image)
{
if (pixels != NULL)
{
@@ -1509,7 +227,7 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
return true;
}
-bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image)
+bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image)
{
if (pixels != NULL)
{
@@ -1520,27 +238,17 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
return true;
}
-IDirect3DBaseTexture9 *Texture::getTexture()
+rx::TextureStorageInterface *Texture::getNativeTexture()
{
- if (!isSamplerComplete())
- {
- return NULL;
- }
-
// ensure the underlying texture is created
- if (getStorage(false) == NULL)
+
+ rx::TextureStorageInterface *storage = getStorage(false);
+ if (storage)
{
- return NULL;
+ updateTexture();
}
- updateTexture();
-
- return getBaseTexture();
-}
-
-bool Texture::hasDirtyParameters() const
-{
- return mDirtyParameters;
+ return storage;
}
bool Texture::hasDirtyImages() const
@@ -1550,19 +258,18 @@ bool Texture::hasDirtyImages() const
void Texture::resetDirty()
{
- mDirtyParameters = false;
mDirtyImages = false;
}
unsigned int Texture::getTextureSerial()
{
- TextureStorage *texture = getStorage(false);
+ rx::TextureStorageInterface *texture = getStorage(false);
return texture ? texture->getTextureSerial() : 0;
}
unsigned int Texture::getRenderTargetSerial(GLenum target)
{
- TextureStorage *texture = getStorage(true);
+ rx::TextureStorageInterface *texture = getStorage(true);
return texture ? texture->getRenderTargetSerial(target) : 0;
}
@@ -1571,15 +278,9 @@ bool Texture::isImmutable() const
return mImmutable;
}
-int Texture::getLodOffset()
-{
- TextureStorage *texture = getStorage(false);
- return texture ? texture->getLodOffset() : 0;
-}
-
GLint Texture::creationLevels(GLsizei width, GLsizei height) const
{
- if ((isPow2(width) && isPow2(height)) || getContext()->supportsNonPower2Texture())
+ if ((isPow2(width) && isPow2(height)) || mRenderer->getNonPower2TextureSupport())
{
return 0; // Maximum number of levels
}
@@ -1595,127 +296,17 @@ GLint Texture::creationLevels(GLsizei size) const
return creationLevels(size, size);
}
-int Texture::levelCount()
-{
- return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
-}
-
-Blit *Texture::getBlitter()
-{
- Context *context = getContext();
- return context->getBlitter();
-}
-
-bool Texture::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
-{
- if (source && dest)
- {
- HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
-
- if (fromManaged)
- {
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
-
- IDirect3DSurface9 *surf = 0;
- result = getDevice()->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
-
- if (SUCCEEDED(result))
- {
- CopyLockableSurfaces(surf, source);
- result = getDevice()->UpdateSurface(surf, NULL, dest, NULL);
- surf->Release();
- }
- }
- else
- {
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = display->getDevice();
-
- display->endScene();
- result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- }
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return false;
- }
- }
-
- return true;
-}
-
-TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(D3DUSAGE_RENDERTARGET), mRenderTargetSerial(RenderbufferStorage::issueSerial())
-{
- mTexture = surfaceTexture;
-}
-
-TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height)
- : TextureStorage(usage), mRenderTargetSerial(RenderbufferStorage::issueSerial())
-{
- mTexture = NULL;
- // if the width or height is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (width > 0 && height > 0)
- {
- IDirect3DDevice9 *device = getDevice();
- MakeValidSize(false, dx::IsCompressedFormat(format), &width, &height, &mLodOffset);
- HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), format, getPool(), &mTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- error(GL_OUT_OF_MEMORY);
- }
- }
-}
-
-TextureStorage2D::~TextureStorage2D()
-{
- if (mTexture)
- {
- mTexture->Release();
- }
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
-{
- IDirect3DSurface9 *surface = NULL;
-
- if (mTexture)
- {
- HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
- ASSERT(SUCCEEDED(result));
-
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
- {
- mTexture->AddDirtyRect(NULL);
- }
- }
-
- return surface;
-}
-
-IDirect3DBaseTexture9 *TextureStorage2D::getBaseTexture() const
-{
- return mTexture;
-}
-
-unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const
-{
- return mRenderTargetSerial;
-}
-
-Texture2D::Texture2D(GLuint id) : Texture(id)
+Texture2D::Texture2D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id)
{
mTexStorage = NULL;
mSurface = NULL;
mColorbufferProxy = NULL;
mProxyRefs = 0;
+
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
+ {
+ mImageArray[i] = renderer->createImage();
+ }
}
Texture2D::~Texture2D()
@@ -1730,6 +321,11 @@ Texture2D::~Texture2D()
mSurface->setBoundTexture(NULL);
mSurface = NULL;
}
+
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
+ {
+ delete mImageArray[i];
+ }
}
// We need to maintain a count of references to renderbuffers acting as
@@ -1757,7 +353,7 @@ GLenum Texture2D::getTarget() const
GLsizei Texture2D::getWidth(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[level].getWidth();
+ return mImageArray[level]->getWidth();
else
return 0;
}
@@ -1765,7 +361,7 @@ GLsizei Texture2D::getWidth(GLint level) const
GLsizei Texture2D::getHeight(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[level].getHeight();
+ return mImageArray[level]->getHeight();
else
return 0;
}
@@ -1773,15 +369,15 @@ GLsizei Texture2D::getHeight(GLint level) const
GLenum Texture2D::getInternalFormat(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[level].getInternalFormat();
+ return mImageArray[level]->getInternalFormat();
else
return GL_NONE;
}
-D3DFORMAT Texture2D::getD3DFormat(GLint level) const
+GLenum Texture2D::getActualFormat(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[level].getD3DFormat();
+ return mImageArray[level]->getActualFormat();
else
return D3DFMT_UNKNOWN;
}
@@ -1790,18 +386,31 @@ void Texture2D::redefineImage(GLint level, GLint internalformat, GLsizei width,
{
releaseTexImage();
- bool redefined = mImageArray[level].redefine(internalformat, width, height, false);
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, mImageArray[0]->getWidth() >> level);
+ const int storageHeight = std::max(1, mImageArray[0]->getHeight() >> level);
+ const int storageFormat = mImageArray[0]->getInternalFormat();
+
+ mImageArray[level]->redefine(mRenderer, internalformat, width, height, false);
- if (mTexStorage && redefined)
+ if (mTexStorage)
{
- for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ const int storageLevels = mTexStorage->levelCount();
+
+ if ((level >= storageLevels && storageLevels != 0) ||
+ width != storageWidth ||
+ height != storageHeight ||
+ internalformat != storageFormat) // Discard mismatched storage
{
- mImageArray[i].markDirty();
- }
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mImageArray[i]->markDirty();
+ }
- delete mTexStorage;
- mTexStorage = NULL;
- mDirtyImages = true;
+ delete mTexStorage;
+ mTexStorage = NULL;
+ mDirtyImages = true;
+ }
}
}
@@ -1810,32 +419,19 @@ void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum form
GLint internalformat = ConvertSizedInternalFormat(format, type);
redefineImage(level, internalformat, width, height);
- Texture::setImage(unpackAlignment, pixels, &mImageArray[level]);
+ Texture::setImage(unpackAlignment, pixels, mImageArray[level]);
}
void Texture2D::bindTexImage(egl::Surface *surface)
{
releaseTexImage();
- GLint internalformat;
-
- switch(surface->getFormat())
- {
- case D3DFMT_A8R8G8B8:
- internalformat = GL_RGBA8_OES;
- break;
- case D3DFMT_X8R8G8B8:
- internalformat = GL_RGB8_OES;
- break;
- default:
- UNIMPLEMENTED();
- return;
- }
+ GLint internalformat = surface->getFormat();
- mImageArray[0].redefine(internalformat, surface->getWidth(), surface->getHeight(), true);
+ mImageArray[0]->redefine(mRenderer, internalformat, surface->getWidth(), surface->getHeight(), true);
delete mTexStorage;
- mTexStorage = new TextureStorage2D(surface->getOffscreenTexture());
+ mTexStorage = new rx::TextureStorageInterface2D(mRenderer, surface->getSwapChain());
mDirtyImages = true;
mSurface = surface;
@@ -1857,7 +453,7 @@ void Texture2D::releaseTexImage()
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
- mImageArray[i].redefine(GL_RGBA8_OES, 0, 0, true);
+ mImageArray[i]->redefine(mRenderer, GL_NONE, 0, 0, true);
}
}
}
@@ -1867,23 +463,16 @@ void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GL
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(level, format, width, height);
- Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]);
+ Texture::setCompressedImage(imageSize, pixels, mImageArray[level]);
}
void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
- ASSERT(mImageArray[level].getSurface() != NULL);
-
if (level < levelCount())
{
- IDirect3DSurface9 *destLevel = mTexStorage->getSurfaceLevel(level, true);
-
- if (destLevel)
+ rx::Image *image = mImageArray[level];
+ if (image->updateSurface(mTexStorage, level, xoffset, yoffset, width, height))
{
- Image *image = &mImageArray[level];
- image->updateSurface(destLevel, xoffset, yoffset, width, height);
-
- destLevel->Release();
image->markClean();
}
}
@@ -1891,7 +480,7 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]))
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, mImageArray[level]))
{
commitRect(level, xoffset, yoffset, width, height);
}
@@ -1899,7 +488,7 @@ void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei widt
void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
- if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[level]))
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, mImageArray[level]))
{
commitRect(level, xoffset, yoffset, width, height);
}
@@ -1907,20 +496,12 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- IDirect3DSurface9 *renderTarget = source->getRenderTarget();
-
- if (!renderTarget)
- {
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
- }
-
GLint internalformat = ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(level, internalformat, width, height);
-
- if (!mImageArray[level].isRenderableFormat())
+
+ if (!mImageArray[level]->isRenderableFormat())
{
- mImageArray[level].copy(0, 0, x, y, width, height, renderTarget);
+ mImageArray[level]->copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
@@ -1930,47 +511,31 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
convertToRenderTarget();
}
- mImageArray[level].markClean();
+ mImageArray[level]->markClean();
if (width != 0 && height != 0 && level < levelCount())
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
-
- IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level, true);
-
- if (dest)
- {
- getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
- dest->Release();
- }
+ gl::Rectangle sourceRect;
+ sourceRect.x = x;
+ sourceRect.width = width;
+ sourceRect.y = y;
+ sourceRect.height = height;
+
+ mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, level);
}
}
-
- renderTarget->Release();
}
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- if (xoffset + width > mImageArray[level].getWidth() || yoffset + height > mImageArray[level].getHeight())
- {
- return error(GL_INVALID_VALUE);
- }
-
- IDirect3DSurface9 *renderTarget = source->getRenderTarget();
-
- if (!renderTarget)
+ if (xoffset + width > mImageArray[level]->getWidth() || yoffset + height > mImageArray[level]->getHeight())
{
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_INVALID_VALUE);
}
- if (!mImageArray[level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
+ if (!mImageArray[level]->isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
{
- mImageArray[level].copy(xoffset, yoffset, x, y, width, height, renderTarget);
+ mImageArray[level]->copy(xoffset, yoffset, x, y, width, height, source);
mDirtyImages = true;
}
else
@@ -1984,46 +549,35 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
if (level < levelCount())
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
-
- IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level, true);
+ gl::Rectangle sourceRect;
+ sourceRect.x = x;
+ sourceRect.width = width;
+ sourceRect.y = y;
+ sourceRect.height = height;
- if (dest)
- {
- getBlitter()->copy(renderTarget, sourceRect,
- gl::ExtractFormat(mImageArray[0].getInternalFormat()),
- xoffset, yoffset, dest);
- dest->Release();
- }
+ mRenderer->copyImage(source, sourceRect,
+ gl::ExtractFormat(mImageArray[0]->getInternalFormat()),
+ xoffset, yoffset, mTexStorage, level);
}
}
-
- renderTarget->Release();
}
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
{
- D3DFORMAT d3dfmt = ConvertTextureInternalFormat(internalformat);
- DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
-
delete mTexStorage;
- mTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height);
+ mTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, mUsage, false, width, height);
mImmutable = true;
for (int level = 0; level < levels; level++)
{
- mImageArray[level].redefine(internalformat, width, height, true);
+ mImageArray[level]->redefine(mRenderer, internalformat, width, height, true);
width = std::max(1, width >> 1);
height = std::max(1, height >> 1);
}
for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
- mImageArray[level].redefine(GL_NONE, 0, 0, true);
+ mImageArray[level]->redefine(mRenderer, GL_NONE, 0, 0, true);
}
if (mTexStorage->isManaged())
@@ -2032,8 +586,7 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
for (int level = 0; level < levels; level++)
{
- IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level, false);
- mImageArray[level].setManagedSurface(surface);
+ mImageArray[level]->setManagedSurface(mTexStorage, level);
}
}
}
@@ -2041,46 +594,33 @@ void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GL
// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85.
bool Texture2D::isSamplerComplete() const
{
- GLsizei width = mImageArray[0].getWidth();
- GLsizei height = mImageArray[0].getHeight();
+ GLsizei width = mImageArray[0]->getWidth();
+ GLsizei height = mImageArray[0]->getHeight();
if (width <= 0 || height <= 0)
{
return false;
}
- bool mipmapping = false;
-
- switch (mMinFilter)
- {
- case GL_NEAREST:
- case GL_LINEAR:
- mipmapping = false;
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- case GL_LINEAR_MIPMAP_NEAREST:
- case GL_NEAREST_MIPMAP_LINEAR:
- case GL_LINEAR_MIPMAP_LINEAR:
- mipmapping = true;
- break;
- default: UNREACHABLE();
- }
+ bool mipmapping = isMipmapFiltered();
+ bool filtering, renderable;
- if ((IsFloat32Format(getInternalFormat(0)) && !getContext()->supportsFloat32LinearFilter()) ||
- (IsFloat16Format(getInternalFormat(0)) && !getContext()->supportsFloat16LinearFilter()))
+ if ((IsFloat32Format(getInternalFormat(0)) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
+ (IsFloat16Format(getInternalFormat(0)) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
{
- if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+ if (mSamplerState.magFilter != GL_NEAREST ||
+ (mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
- bool npotSupport = getContext()->supportsNonPower2Texture();
+ bool npotSupport = mRenderer->getNonPower2TextureSupport();
if (!npotSupport)
{
- if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width)) ||
- (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
+ if ((mSamplerState.wrapS != GL_CLAMP_TO_EDGE && !isPow2(width)) ||
+ (mSamplerState.wrapT != GL_CLAMP_TO_EDGE && !isPow2(height)))
{
return false;
}
@@ -2113,8 +653,8 @@ bool Texture2D::isMipmapComplete() const
return true;
}
- GLsizei width = mImageArray[0].getWidth();
- GLsizei height = mImageArray[0].getHeight();
+ GLsizei width = mImageArray[0]->getWidth();
+ GLsizei height = mImageArray[0]->getHeight();
if (width <= 0 || height <= 0)
{
@@ -2125,17 +665,17 @@ bool Texture2D::isMipmapComplete() const
for (int level = 1; level <= q; level++)
{
- if (mImageArray[level].getInternalFormat() != mImageArray[0].getInternalFormat())
+ if (mImageArray[level]->getInternalFormat() != mImageArray[0]->getInternalFormat())
{
return false;
}
- if (mImageArray[level].getWidth() != std::max(1, width >> level))
+ if (mImageArray[level]->getWidth() != std::max(1, width >> level))
{
return false;
}
- if (mImageArray[level].getHeight() != std::max(1, height >> level))
+ if (mImageArray[level]->getHeight() != std::max(1, height >> level))
{
return false;
}
@@ -2154,26 +694,20 @@ bool Texture2D::isDepth(GLint level) const
return IsDepthTexture(getInternalFormat(level));
}
-IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const
-{
- return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
-}
-
-// Constructs a Direct3D 9 texture resource from the texture images
+// Constructs a native texture resource from the texture images
void Texture2D::createTexture()
{
- GLsizei width = mImageArray[0].getWidth();
- GLsizei height = mImageArray[0].getHeight();
+ GLsizei width = mImageArray[0]->getWidth();
+ GLsizei height = mImageArray[0]->getHeight();
if (!(width > 0 && height > 0))
- return; // do not attempt to create d3d textures for nonexistant data
+ return; // do not attempt to create native textures for nonexistant data
GLint levels = creationLevels(width, height);
- D3DFORMAT d3dfmt = mImageArray[0].getD3DFormat();
- DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
+ GLenum internalformat = mImageArray[0]->getInternalFormat();
delete mTexStorage;
- mTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height);
+ mTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, mUsage, false, width, height);
if (mTexStorage->isManaged())
{
@@ -2181,8 +715,7 @@ void Texture2D::createTexture()
for (int level = 0; level < levels; level++)
{
- IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level, false);
- mImageArray[level].setManagedSurface(surface);
+ mImageArray[level]->setManagedSurface(mTexStorage, level);
}
}
@@ -2191,51 +724,40 @@ void Texture2D::createTexture()
void Texture2D::updateTexture()
{
- int levels = levelCount();
+ bool mipmapping = (isMipmapFiltered() && isMipmapComplete());
+
+ int levels = (mipmapping ? levelCount() : 1);
for (int level = 0; level < levels; level++)
{
- Image *image = &mImageArray[level];
+ rx::Image *image = mImageArray[level];
if (image->isDirty())
{
- commitRect(level, 0, 0, mImageArray[level].getWidth(), mImageArray[level].getHeight());
+ commitRect(level, 0, 0, mImageArray[level]->getWidth(), mImageArray[level]->getHeight());
}
}
}
void Texture2D::convertToRenderTarget()
{
- TextureStorage2D *newTexStorage = NULL;
+ rx::TextureStorageInterface2D *newTexStorage = NULL;
- if (mImageArray[0].getWidth() != 0 && mImageArray[0].getHeight() != 0)
+ if (mImageArray[0]->getWidth() != 0 && mImageArray[0]->getHeight() != 0)
{
- GLsizei width = mImageArray[0].getWidth();
- GLsizei height = mImageArray[0].getHeight();
- GLint levels = creationLevels(width, height);
- D3DFORMAT d3dfmt = mImageArray[0].getD3DFormat();
- DWORD d3dusage = GetTextureUsage(d3dfmt, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true);
+ GLsizei width = mImageArray[0]->getWidth();
+ GLsizei height = mImageArray[0]->getHeight();
+ GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(width, height);
+ GLenum internalformat = mImageArray[0]->getInternalFormat();
- newTexStorage = new TextureStorage2D(levels, d3dfmt, d3dusage, width, height);
+ newTexStorage = new rx::TextureStorageInterface2D(mRenderer, levels, internalformat, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true, width, height);
if (mTexStorage != NULL)
{
- int levels = levelCount();
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *source = mTexStorage->getSurfaceLevel(i, false);
- IDirect3DSurface9 *dest = newTexStorage->getSurfaceLevel(i, true);
-
- if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
- {
- delete newTexStorage;
- if (source) source->Release();
- if (dest) dest->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- if (source) source->Release();
- if (dest) dest->Release();
+ if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage))
+ {
+ delete newTexStorage;
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
}
@@ -2248,53 +770,37 @@ void Texture2D::convertToRenderTarget()
void Texture2D::generateMipmaps()
{
- if (!getContext()->supportsNonPower2Texture())
+ if (!mRenderer->getNonPower2TextureSupport())
{
- if (!isPow2(mImageArray[0].getWidth()) || !isPow2(mImageArray[0].getHeight()))
+ if (!isPow2(mImageArray[0]->getWidth()) || !isPow2(mImageArray[0]->getHeight()))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- unsigned int q = log2(std::max(mImageArray[0].getWidth(), mImageArray[0].getHeight()));
+ unsigned int q = log2(std::max(mImageArray[0]->getWidth(), mImageArray[0]->getHeight()));
for (unsigned int i = 1; i <= q; i++)
{
- redefineImage(i, mImageArray[0].getInternalFormat(),
- std::max(mImageArray[0].getWidth() >> i, 1),
- std::max(mImageArray[0].getHeight() >> i, 1));
+ redefineImage(i, mImageArray[0]->getInternalFormat(),
+ std::max(mImageArray[0]->getWidth() >> i, 1),
+ std::max(mImageArray[0]->getHeight() >> i, 1));
}
if (mTexStorage && mTexStorage->isRenderTarget())
{
for (unsigned int i = 1; i <= q; i++)
{
- IDirect3DSurface9 *upper = mTexStorage->getSurfaceLevel(i - 1, false);
- IDirect3DSurface9 *lower = mTexStorage->getSurfaceLevel(i, true);
-
- if (upper != NULL && lower != NULL)
- {
- getBlitter()->boxFilter(upper, lower);
- }
-
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
+ mTexStorage->generateMipmap(i);
- mImageArray[i].markClean();
+ mImageArray[i]->markClean();
}
}
else
{
for (unsigned int i = 1; i <= q; i++)
{
- if (mImageArray[i].getSurface() == NULL)
- {
- return error(GL_OUT_OF_MEMORY);
- }
-
- GenerateMip(mImageArray[i].getSurface(), mImageArray[i - 1].getSurface());
-
- mImageArray[i].markDirty();
+ mRenderer->generateMipmap(mImageArray[i], mImageArray[i - 1]);
}
}
}
@@ -2303,20 +809,18 @@ Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
{
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
+ return gl::error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
if (mColorbufferProxy == NULL)
{
- mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture2D(this, target));
+ mColorbufferProxy = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2D(this, target));
}
return mColorbufferProxy;
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
+rx::RenderTarget *Texture2D::getRenderTarget(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
@@ -2333,12 +837,11 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
{
return NULL;
}
- return mTexStorage->getSurfaceLevel(0, false);
+
+ return mTexStorage->getRenderTarget();
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target)
+rx::RenderTarget *Texture2D::getDepthStencil(GLenum target)
{
ASSERT(target == GL_TEXTURE_2D);
@@ -2355,10 +858,15 @@ IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target)
{
return NULL;
}
- return mTexStorage->getSurfaceLevel(0, false);
+ return mTexStorage->getRenderTarget();
+}
+
+int Texture2D::levelCount()
+{
+ return mTexStorage ? mTexStorage->levelCount() : 0;
}
-TextureStorage *Texture2D::getStorage(bool renderTarget)
+rx::TextureStorageInterface *Texture2D::getStorage(bool renderTarget)
{
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
{
@@ -2375,74 +883,18 @@ TextureStorage *Texture2D::getStorage(bool renderTarget)
return mTexStorage;
}
-TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size)
- : TextureStorage(usage), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials())
-{
- mTexture = NULL;
- // if the size is not positive this should be treated as an incomplete texture
- // we handle that here by skipping the d3d texture creation
- if (size > 0)
- {
- IDirect3DDevice9 *device = getDevice();
- int height = size;
- MakeValidSize(false, dx::IsCompressedFormat(format), &size, &height, &mLodOffset);
- HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(), format, getPool(), &mTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- error(GL_OUT_OF_MEMORY);
- }
- }
-}
-
-TextureStorageCubeMap::~TextureStorageCubeMap()
-{
- if (mTexture)
- {
- mTexture->Release();
- }
-}
-
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
-{
- IDirect3DSurface9 *surface = NULL;
-
- if (mTexture)
- {
- D3DCUBEMAP_FACES face = es2dx::ConvertCubeFace(faceTarget);
- HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
- ASSERT(SUCCEEDED(result));
-
- // With managed textures the driver needs to be informed of updates to the lower mipmap levels
- if (level != 0 && isManaged() && dirty)
- {
- mTexture->AddDirtyRect(face, NULL);
- }
- }
-
- return surface;
-}
-
-IDirect3DBaseTexture9 *TextureStorageCubeMap::getBaseTexture() const
-{
- return mTexture;
-}
-
-unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
-{
- return mFirstRenderTargetSerial + TextureCubeMap::faceIndex(target);
-}
-
-TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
+TextureCubeMap::TextureCubeMap(rx::Renderer *renderer, GLuint id) : Texture(renderer, id)
{
mTexStorage = NULL;
for (int i = 0; i < 6; i++)
{
mFaceProxies[i] = NULL;
mFaceProxyRefs[i] = 0;
+
+ for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
+ {
+ mImageArray[i][j] = renderer->createImage();
+ }
}
}
@@ -2451,6 +903,11 @@ TextureCubeMap::~TextureCubeMap()
for (int i = 0; i < 6; i++)
{
mFaceProxies[i] = NULL;
+
+ for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
+ {
+ delete mImageArray[i][j];
+ }
}
delete mTexStorage;
@@ -2494,7 +951,7 @@ GLenum TextureCubeMap::getTarget() const
GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[faceIndex(target)][level].getWidth();
+ return mImageArray[faceIndex(target)][level]->getWidth();
else
return 0;
}
@@ -2502,7 +959,7 @@ GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[faceIndex(target)][level].getHeight();
+ return mImageArray[faceIndex(target)][level]->getHeight();
else
return 0;
}
@@ -2510,15 +967,15 @@ GLsizei TextureCubeMap::getHeight(GLenum target, GLint level) const
GLenum TextureCubeMap::getInternalFormat(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[faceIndex(target)][level].getInternalFormat();
+ return mImageArray[faceIndex(target)][level]->getInternalFormat();
else
return GL_NONE;
}
-D3DFORMAT TextureCubeMap::getD3DFormat(GLenum target, GLint level) const
+GLenum TextureCubeMap::getActualFormat(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
- return mImageArray[faceIndex(target)][level].getD3DFormat();
+ return mImageArray[faceIndex(target)][level]->getActualFormat();
else
return D3DFMT_UNKNOWN;
}
@@ -2558,32 +1015,22 @@ void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format,
// compressed formats don't have separate sized internal formats-- we can just use the compressed format directly
redefineImage(faceIndex(face), level, format, width, height);
- Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]);
+ Texture::setCompressedImage(imageSize, pixels, mImageArray[faceIndex(face)][level]);
}
void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
- ASSERT(mImageArray[face][level].getSurface() != NULL);
-
if (level < levelCount())
{
- IDirect3DSurface9 *destLevel = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
- ASSERT(destLevel != NULL);
-
- if (destLevel != NULL)
- {
- Image *image = &mImageArray[face][level];
- image->updateSurface(destLevel, xoffset, yoffset, width, height);
-
- destLevel->Release();
+ rx::Image *image = mImageArray[face][level];
+ if (image->updateSurface(mTexStorage, face, level, xoffset, yoffset, width, height))
image->markClean();
- }
}
}
void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(target)][level]))
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, mImageArray[faceIndex(target)][level]))
{
commitRect(faceIndex(target), level, xoffset, yoffset, width, height);
}
@@ -2591,7 +1038,7 @@ void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint y
void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
{
- if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(target)][level]))
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, mImageArray[faceIndex(target)][level]))
{
commitRect(faceIndex(target), level, xoffset, yoffset, width, height);
}
@@ -2600,39 +1047,24 @@ void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffse
// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86.
bool TextureCubeMap::isSamplerComplete() const
{
- int size = mImageArray[0][0].getWidth();
+ int size = mImageArray[0][0]->getWidth();
- bool mipmapping;
-
- switch (mMinFilter)
- {
- case GL_NEAREST:
- case GL_LINEAR:
- mipmapping = false;
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- case GL_LINEAR_MIPMAP_NEAREST:
- case GL_NEAREST_MIPMAP_LINEAR:
- case GL_LINEAR_MIPMAP_LINEAR:
- mipmapping = true;
- break;
- default:
- UNREACHABLE();
- return false;
- }
+ bool mipmapping = isMipmapFiltered();
+ bool filtering, renderable;
- if ((gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) ||
- (gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES) && !getContext()->supportsFloat16LinearFilter()))
+ if ((gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0)) == GL_FLOAT && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
+ (gl::ExtractType(getInternalFormat(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0) == GL_HALF_FLOAT_OES) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
{
- if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+ if (mSamplerState.magFilter != GL_NEAREST ||
+ (mSamplerState.minFilter != GL_NEAREST && mSamplerState.minFilter != GL_NEAREST_MIPMAP_NEAREST))
{
return false;
}
}
- if (!isPow2(size) && !getContext()->supportsNonPower2Texture())
+ if (!isPow2(size) && !mRenderer->getNonPower2TextureSupport())
{
- if (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE || mipmapping)
+ if (mSamplerState.wrapS != GL_CLAMP_TO_EDGE || mSamplerState.wrapT != GL_CLAMP_TO_EDGE || mipmapping)
{
return false;
}
@@ -2659,16 +1091,16 @@ bool TextureCubeMap::isSamplerComplete() const
// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
bool TextureCubeMap::isCubeComplete() const
{
- if (mImageArray[0][0].getWidth() <= 0 || mImageArray[0][0].getHeight() != mImageArray[0][0].getWidth())
+ if (mImageArray[0][0]->getWidth() <= 0 || mImageArray[0][0]->getHeight() != mImageArray[0][0]->getWidth())
{
return false;
}
for (unsigned int face = 1; face < 6; face++)
{
- if (mImageArray[face][0].getWidth() != mImageArray[0][0].getWidth() ||
- mImageArray[face][0].getWidth() != mImageArray[0][0].getHeight() ||
- mImageArray[face][0].getInternalFormat() != mImageArray[0][0].getInternalFormat())
+ if (mImageArray[face][0]->getWidth() != mImageArray[0][0]->getWidth() ||
+ mImageArray[face][0]->getWidth() != mImageArray[0][0]->getHeight() ||
+ mImageArray[face][0]->getInternalFormat() != mImageArray[0][0]->getInternalFormat())
{
return false;
}
@@ -2689,7 +1121,7 @@ bool TextureCubeMap::isMipmapCubeComplete() const
return false;
}
- GLsizei size = mImageArray[0][0].getWidth();
+ GLsizei size = mImageArray[0][0]->getWidth();
int q = log2(size);
@@ -2697,12 +1129,12 @@ bool TextureCubeMap::isMipmapCubeComplete() const
{
for (int level = 1; level <= q; level++)
{
- if (mImageArray[face][level].getInternalFormat() != mImageArray[0][0].getInternalFormat())
+ if (mImageArray[face][level]->getInternalFormat() != mImageArray[0][0]->getInternalFormat())
{
return false;
}
- if (mImageArray[face][level].getWidth() != std::max(1, size >> level))
+ if (mImageArray[face][level]->getWidth() != std::max(1, size >> level))
{
return false;
}
@@ -2717,25 +1149,19 @@ bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
return IsCompressed(getInternalFormat(target, level));
}
-IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const
-{
- return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
-}
-
-// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
+// Constructs a native texture resource from the texture images, or returns an existing one
void TextureCubeMap::createTexture()
{
- GLsizei size = mImageArray[0][0].getWidth();
+ GLsizei size = mImageArray[0][0]->getWidth();
if (!(size > 0))
- return; // do not attempt to create d3d textures for nonexistant data
+ return; // do not attempt to create native textures for nonexistant data
GLint levels = creationLevels(size);
- D3DFORMAT d3dfmt = mImageArray[0][0].getD3DFormat();
- DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
+ GLenum internalformat = mImageArray[0][0]->getInternalFormat();
delete mTexStorage;
- mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size);
+ mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, mUsage, false, size);
if (mTexStorage->isManaged())
{
@@ -2745,8 +1171,7 @@ void TextureCubeMap::createTexture()
{
for (int level = 0; level < levels; level++)
{
- IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false);
- mImageArray[face][level].setManagedSurface(surface);
+ mImageArray[face][level]->setManagedSurface(mTexStorage, face, level);
}
}
}
@@ -2756,12 +1181,15 @@ void TextureCubeMap::createTexture()
void TextureCubeMap::updateTexture()
{
+ bool mipmapping = isMipmapFiltered() && isMipmapCubeComplete();
+
for (int face = 0; face < 6; face++)
{
- int levels = levelCount();
+ int levels = (mipmapping ? levelCount() : 1);
+
for (int level = 0; level < levels; level++)
{
- Image *image = &mImageArray[face][level];
+ rx::Image *image = mImageArray[face][level];
if (image->isDirty())
{
@@ -2773,38 +1201,22 @@ void TextureCubeMap::updateTexture()
void TextureCubeMap::convertToRenderTarget()
{
- TextureStorageCubeMap *newTexStorage = NULL;
+ rx::TextureStorageInterfaceCube *newTexStorage = NULL;
- if (mImageArray[0][0].getWidth() != 0)
+ if (mImageArray[0][0]->getWidth() != 0)
{
- GLsizei size = mImageArray[0][0].getWidth();
- GLint levels = creationLevels(size);
- D3DFORMAT d3dfmt = mImageArray[0][0].getD3DFormat();
- DWORD d3dusage = GetTextureUsage(d3dfmt, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true);
+ GLsizei size = mImageArray[0][0]->getWidth();
+ GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(size);
+ GLenum internalformat = mImageArray[0][0]->getInternalFormat();
- newTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size);
+ newTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, GL_FRAMEBUFFER_ATTACHMENT_ANGLE, true, size);
if (mTexStorage != NULL)
{
- int levels = levelCount();
- for (int f = 0; f < 6; f++)
+ if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage))
{
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *source = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
- IDirect3DSurface9 *dest = newTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
-
- if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
- {
- delete newTexStorage;
- if (source) source->Release();
- if (dest) dest->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- if (source) source->Release();
- if (dest) dest->Release();
- }
+ delete newTexStorage;
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
}
@@ -2820,7 +1232,7 @@ void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei
GLint internalformat = ConvertSizedInternalFormat(format, type);
redefineImage(faceIndex, level, internalformat, width, height);
- Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]);
+ Texture::setImage(unpackAlignment, pixels, mImageArray[faceIndex][level]);
}
unsigned int TextureCubeMap::faceIndex(GLenum face)
@@ -2836,42 +1248,47 @@ unsigned int TextureCubeMap::faceIndex(GLenum face)
void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat, GLsizei width, GLsizei height)
{
- bool redefined = mImageArray[face][level].redefine(internalformat, width, height, false);
+ // If there currently is a corresponding storage texture image, it has these parameters
+ const int storageWidth = std::max(1, mImageArray[0][0]->getWidth() >> level);
+ const int storageHeight = std::max(1, mImageArray[0][0]->getHeight() >> level);
+ const int storageFormat = mImageArray[0][0]->getInternalFormat();
+
+ mImageArray[face][level]->redefine(mRenderer, internalformat, width, height, false);
- if (mTexStorage && redefined)
+ if (mTexStorage)
{
- for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ const int storageLevels = mTexStorage->levelCount();
+
+ if ((level >= storageLevels && storageLevels != 0) ||
+ width != storageWidth ||
+ height != storageHeight ||
+ internalformat != storageFormat) // Discard mismatched storage
{
- for (int f = 0; f < 6; f++)
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
- mImageArray[f][i].markDirty();
+ for (int f = 0; f < 6; f++)
+ {
+ mImageArray[f][i]->markDirty();
+ }
}
- }
- delete mTexStorage;
- mTexStorage = NULL;
+ delete mTexStorage;
+ mTexStorage = NULL;
- mDirtyImages = true;
+ mDirtyImages = true;
+ }
}
}
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- IDirect3DSurface9 *renderTarget = source->getRenderTarget();
-
- if (!renderTarget)
- {
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
- }
-
unsigned int faceindex = faceIndex(target);
GLint internalformat = gl::ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(faceindex, level, internalformat, width, height);
- if (!mImageArray[faceindex][level].isRenderableFormat())
+ if (!mImageArray[faceindex][level]->isRenderableFormat())
{
- mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget);
+ mImageArray[faceindex][level]->copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
@@ -2881,53 +1298,37 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
convertToRenderTarget();
}
- mImageArray[faceindex][level].markClean();
+ mImageArray[faceindex][level]->markClean();
ASSERT(width == height);
if (width > 0 && level < levelCount())
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
+ gl::Rectangle sourceRect;
+ sourceRect.x = x;
+ sourceRect.width = width;
+ sourceRect.y = y;
+ sourceRect.height = height;
- IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level, true);
-
- if (dest)
- {
- getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
- dest->Release();
- }
+ mRenderer->copyImage(source, sourceRect, format, 0, 0, mTexStorage, target, level);
}
}
-
- renderTarget->Release();
}
void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
- GLsizei size = mImageArray[faceIndex(target)][level].getWidth();
+ GLsizei size = mImageArray[faceIndex(target)][level]->getWidth();
if (xoffset + width > size || yoffset + height > size)
{
- return error(GL_INVALID_VALUE);
- }
-
- IDirect3DSurface9 *renderTarget = source->getRenderTarget();
-
- if (!renderTarget)
- {
- ERR("Failed to retrieve the render target.");
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_INVALID_VALUE);
}
unsigned int faceindex = faceIndex(target);
- if (!mImageArray[faceindex][level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
+ if (!mImageArray[faceindex][level]->isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
{
- mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget);
+ mImageArray[faceindex][level]->copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
@@ -2941,39 +1342,29 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
if (level < levelCount())
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
-
- IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level, true);
+ gl::Rectangle sourceRect;
+ sourceRect.x = x;
+ sourceRect.width = width;
+ sourceRect.y = y;
+ sourceRect.height = height;
- if (dest)
- {
- getBlitter()->copy(renderTarget, sourceRect, gl::ExtractFormat(mImageArray[0][0].getInternalFormat()), xoffset, yoffset, dest);
- dest->Release();
- }
+ mRenderer->copyImage(source, sourceRect, gl::ExtractFormat(mImageArray[0][0]->getInternalFormat()),
+ xoffset, yoffset, mTexStorage, target, level);
}
}
-
- renderTarget->Release();
}
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
{
- D3DFORMAT d3dfmt = ConvertTextureInternalFormat(internalformat);
- DWORD d3dusage = GetTextureUsage(d3dfmt, mUsage, false);
-
delete mTexStorage;
- mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, d3dusage, size);
+ mTexStorage = new rx::TextureStorageInterfaceCube(mRenderer, levels, internalformat, mUsage, false, size);
mImmutable = true;
for (int level = 0; level < levels; level++)
{
for (int face = 0; face < 6; face++)
{
- mImageArray[face][level].redefine(internalformat, size, size, true);
+ mImageArray[face][level]->redefine(mRenderer, internalformat, size, size, true);
size = std::max(1, size >> 1);
}
}
@@ -2982,7 +1373,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
{
for (int face = 0; face < 6; face++)
{
- mImageArray[face][level].redefine(GL_NONE, 0, 0, true);
+ mImageArray[face][level]->redefine(mRenderer, GL_NONE, 0, 0, true);
}
}
@@ -2994,8 +1385,7 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size
{
for (int level = 0; level < levels; level++)
{
- IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false);
- mImageArray[face][level].setManagedSurface(surface);
+ mImageArray[face][level]->setManagedSurface(mTexStorage, face, level);
}
}
}
@@ -3005,26 +1395,26 @@ void TextureCubeMap::generateMipmaps()
{
if (!isCubeComplete())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- if (!getContext()->supportsNonPower2Texture())
+ if (!mRenderer->getNonPower2TextureSupport())
{
- if (!isPow2(mImageArray[0][0].getWidth()))
+ if (!isPow2(mImageArray[0][0]->getWidth()))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
// Purge array levels 1 through q and reset them to represent the generated mipmap levels.
- unsigned int q = log2(mImageArray[0][0].getWidth());
+ unsigned int q = log2(mImageArray[0][0]->getWidth());
for (unsigned int f = 0; f < 6; f++)
{
for (unsigned int i = 1; i <= q; i++)
{
- redefineImage(f, i, mImageArray[f][0].getInternalFormat(),
- std::max(mImageArray[f][0].getWidth() >> i, 1),
- std::max(mImageArray[f][0].getWidth() >> i, 1));
+ redefineImage(f, i, mImageArray[f][0]->getInternalFormat(),
+ std::max(mImageArray[f][0]->getWidth() >> i, 1),
+ std::max(mImageArray[f][0]->getWidth() >> i, 1));
}
}
@@ -3034,18 +1424,9 @@ void TextureCubeMap::generateMipmaps()
{
for (unsigned int i = 1; i <= q; i++)
{
- IDirect3DSurface9 *upper = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i - 1, false);
- IDirect3DSurface9 *lower = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
-
- if (upper != NULL && lower != NULL)
- {
- getBlitter()->boxFilter(upper, lower);
- }
-
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
+ mTexStorage->generateMipmap(f, i);
- mImageArray[f][i].markClean();
+ mImageArray[f][i]->markClean();
}
}
}
@@ -3055,14 +1436,7 @@ void TextureCubeMap::generateMipmaps()
{
for (unsigned int i = 1; i <= q; i++)
{
- if (mImageArray[f][i].getSurface() == NULL)
- {
- return error(GL_OUT_OF_MEMORY);
- }
-
- GenerateMip(mImageArray[f][i].getSurface(), mImageArray[f][i - 1].getSurface());
-
- mImageArray[f][i].markDirty();
+ mRenderer->generateMipmap(mImageArray[f][i], mImageArray[f][i - 1]);
}
}
}
@@ -3072,22 +1446,20 @@ Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
{
if (!IsCubemapTextureTarget(target))
{
- return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
+ return gl::error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
unsigned int face = faceIndex(target);
if (mFaceProxies[face] == NULL)
{
- mFaceProxies[face] = new Renderbuffer(id(), new RenderbufferTextureCubeMap(this, target));
+ mFaceProxies[face] = new Renderbuffer(mRenderer, id(), new RenderbufferTextureCubeMap(this, target));
}
return mFaceProxies[face];
}
-// Increments refcount on surface.
-// caller must Release() the returned surface
-IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
+rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target)
{
ASSERT(IsCubemapTextureTarget(target));
@@ -3099,10 +1471,15 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
updateTexture();
- return mTexStorage->getCubeMapSurface(target, 0, false);
+ return mTexStorage->getRenderTarget(target);
+}
+
+int TextureCubeMap::levelCount()
+{
+ return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0;
}
-TextureStorage *TextureCubeMap::getStorage(bool renderTarget)
+rx::TextureStorageInterface *TextureCubeMap::getStorage(bool renderTarget)
{
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
{
diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.h b/src/3rdparty/angle/src/libGLESv2/Texture.h
index 7d7378f88b..4f5fab28d0 100644
--- a/src/3rdparty/angle/src/libGLESv2/Texture.h
+++ b/src/3rdparty/angle/src/libGLESv2/Texture.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -15,22 +15,30 @@
#define GL_APICALL
#include <GLES2/gl2.h>
-#include <d3d9.h>
#include "common/debug.h"
#include "common/RefCountObject.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/utilities.h"
+#include "libGLESv2/angletypes.h"
namespace egl
{
class Surface;
}
+namespace rx
+{
+class Renderer;
+class TextureStorageInterface;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+class RenderTarget;
+class Image;
+}
+
namespace gl
{
-class Blit;
class Framebuffer;
+class Renderbuffer;
enum
{
@@ -43,132 +51,10 @@ enum
IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
};
-class Image
-{
- public:
- Image();
- ~Image();
-
- bool redefine(GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
- void markDirty() {mDirty = true;}
- void markClean() {mDirty = false;}
-
- bool isRenderableFormat() const;
- D3DFORMAT getD3DFormat() const;
-
- GLsizei getWidth() const {return mWidth;}
- GLsizei getHeight() const {return mHeight;}
- GLenum getInternalFormat() const {return mInternalFormat;}
- bool isDirty() const {return mSurface && mDirty;}
- IDirect3DSurface9 *getSurface();
-
- void setManagedSurface(IDirect3DSurface9 *surface);
- void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
-
- void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- GLint unpackAlignment, const void *input);
-
- void loadAlphaData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadAlphaDataSSE2(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadAlphaFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadAlphaHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadLuminanceData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
- void loadLuminanceFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadLuminanceHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadLuminanceAlphaData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
- void loadLuminanceAlphaFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadLuminanceAlphaHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBUByteData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGB565Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBAUByteData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBA4444Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBA5551Data(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBAFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadRGBAHalfFloatData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadBGRAData(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- const void *input);
-
- void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Image);
-
- void createSurface();
-
- HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
- void unlock();
-
- GLsizei mWidth;
- GLsizei mHeight;
- GLint mInternalFormat;
-
- bool mDirty;
-
- D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
- D3DFORMAT mD3DFormat;
-
- IDirect3DSurface9 *mSurface;
-};
-
-class TextureStorage
-{
- public:
- explicit TextureStorage(DWORD usage);
-
- virtual ~TextureStorage();
-
- bool isRenderTarget() const;
- bool isManaged() const;
- D3DPOOL getPool() const;
- DWORD getUsage() const;
- unsigned int getTextureSerial() const;
- virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
- int getLodOffset() const;
-
- protected:
- int mLodOffset;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage);
-
- const DWORD mD3DUsage;
- const D3DPOOL mD3DPool;
-
- const unsigned int mTextureSerial;
- static unsigned int issueTextureSerial();
-
- static unsigned int mCurrentTextureSerial;
-};
-
class Texture : public RefCountObject
{
public:
- explicit Texture(GLuint id);
+ Texture(rx::Renderer *renderer, GLuint id);
virtual ~Texture();
@@ -189,11 +75,14 @@ class Texture : public RefCountObject
GLenum getWrapS() const;
GLenum getWrapT() const;
float getMaxAnisotropy() const;
+ int getLodOffset();
+ void getSamplerState(SamplerState *sampler);
GLenum getUsage() const;
+ bool isMipmapFiltered() const;
virtual bool isSamplerComplete() const = 0;
- IDirect3DBaseTexture9 *getTexture();
+ rx::TextureStorageInterface *getNativeTexture();
virtual Renderbuffer *getRenderbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
@@ -206,36 +95,28 @@ class Texture : public RefCountObject
unsigned int getRenderTargetSerial(GLenum target);
bool isImmutable() const;
- int getLodOffset();
static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
protected:
- void setImage(GLint unpackAlignment, const void *pixels, Image *image);
- bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
- void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
- bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
+ void setImage(GLint unpackAlignment, const void *pixels, rx::Image *image);
+ bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, rx::Image *image);
+ void setCompressedImage(GLsizei imageSize, const void *pixels, rx::Image *image);
+ bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, rx::Image *image);
GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0;
virtual void updateTexture() = 0;
virtual void convertToRenderTarget() = 0;
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
+ virtual rx::RenderTarget *getRenderTarget(GLenum target) = 0;
- int levelCount();
+ virtual int levelCount() = 0;
- static Blit *getBlitter();
- static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+ rx::Renderer *mRenderer;
- GLenum mMinFilter;
- GLenum mMagFilter;
- GLenum mWrapS;
- GLenum mWrapT;
- float mMaxAnisotropy;
- bool mDirtyParameters;
+ SamplerState mSamplerState;
GLenum mUsage;
bool mDirtyImages;
@@ -245,33 +126,13 @@ class Texture : public RefCountObject
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
- virtual TextureStorage *getStorage(bool renderTarget) = 0;
-};
-
-class TextureStorage2D : public TextureStorage
-{
- public:
- explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture);
- TextureStorage2D(int levels, D3DFORMAT format, DWORD usage, int width, int height);
-
- virtual ~TextureStorage2D();
-
- IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
- IDirect3DBaseTexture9 *getBaseTexture() const;
-
- virtual unsigned int getRenderTargetSerial(GLenum target) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorage2D);
-
- IDirect3DTexture9 *mTexture;
- const unsigned int mRenderTargetSerial;
+ virtual rx::TextureStorageInterface *getStorage(bool renderTarget) = 0;
};
class Texture2D : public Texture
{
public:
- explicit Texture2D(GLuint id);
+ Texture2D(rx::Renderer *renderer, GLuint id);
~Texture2D();
@@ -283,7 +144,7 @@ class Texture2D : public Texture
GLsizei getWidth(GLint level) const;
GLsizei getHeight(GLint level) const;
GLenum getInternalFormat(GLint level) const;
- D3DFORMAT getD3DFormat(GLint level) const;
+ GLenum getActualFormat(GLint level) const;
bool isCompressed(GLint level) const;
bool isDepth(GLint level) const;
@@ -305,26 +166,26 @@ class Texture2D : public Texture
protected:
friend class RenderbufferTexture2D;
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
- virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
+ virtual rx::RenderTarget *getRenderTarget(GLenum target);
+ virtual rx::RenderTarget *getDepthStencil(GLenum target);
+ virtual int levelCount();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
- virtual TextureStorage *getStorage(bool renderTarget);
+ virtual rx::TextureStorageInterface *getStorage(bool renderTarget);
bool isMipmapComplete() const;
void redefineImage(GLint level, GLint internalformat, GLsizei width, GLsizei height);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ rx::Image *mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
- TextureStorage2D *mTexStorage;
+ rx::TextureStorageInterface2D *mTexStorage;
egl::Surface *mSurface;
// A specific internal reference count is kept for colorbuffer proxy references,
@@ -336,29 +197,10 @@ class Texture2D : public Texture
unsigned int mProxyRefs;
};
-class TextureStorageCubeMap : public TextureStorage
-{
- public:
- TextureStorageCubeMap(int levels, D3DFORMAT format, DWORD usage, int size);
-
- virtual ~TextureStorageCubeMap();
-
- IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
- IDirect3DBaseTexture9 *getBaseTexture() const;
-
- virtual unsigned int getRenderTargetSerial(GLenum target) const;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap);
-
- IDirect3DCubeTexture9 *mTexture;
- const unsigned int mFirstRenderTargetSerial;
-};
-
class TextureCubeMap : public Texture
{
public:
- explicit TextureCubeMap(GLuint id);
+ TextureCubeMap(rx::Renderer *renderer, GLuint id);
~TextureCubeMap();
@@ -370,7 +212,7 @@ class TextureCubeMap : public Texture
GLsizei getWidth(GLenum target, GLint level) const;
GLsizei getHeight(GLenum target, GLint level) const;
GLenum getInternalFormat(GLenum target, GLint level) const;
- D3DFORMAT getD3DFormat(GLenum target, GLint level) const;
+ GLenum getActualFormat(GLenum target, GLint level) const;
bool isCompressed(GLenum target, GLint level) const;
void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
@@ -398,16 +240,16 @@ class TextureCubeMap : public Texture
protected:
friend class RenderbufferTextureCubeMap;
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ virtual rx::RenderTarget *getRenderTarget(GLenum target);
+ virtual int levelCount();
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
- virtual TextureStorage *getStorage(bool renderTarget);
+ virtual rx::TextureStorageInterface *getStorage(bool renderTarget);
bool isCubeComplete() const;
bool isMipmapCubeComplete() const;
@@ -416,9 +258,9 @@ class TextureCubeMap : public Texture
void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void redefineImage(int faceIndex, GLint level, GLint internalformat, GLsizei width, GLsizei height);
- Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+ rx::Image *mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
- TextureStorageCubeMap *mTexStorage;
+ rx::TextureStorageInterfaceCube *mTexStorage;
// A specific internal reference count is kept for colorbuffer proxy references,
// because, as the renderbuffer acting as proxy will maintain a binding pointer
diff --git a/src/3rdparty/angle/src/libGLESv2/Uniform.cpp b/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
new file mode 100644
index 0000000000..5424e271b5
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Uniform.cpp
@@ -0,0 +1,43 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2010-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "libGLESv2/Uniform.h"
+
+#include "libGLESv2/utilities.h"
+
+namespace gl
+{
+
+Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize)
+ : type(type), precision(precision), name(name), arraySize(arraySize)
+{
+ int bytes = gl::UniformInternalSize(type) * elementCount();
+ data = new unsigned char[bytes];
+ memset(data, 0, bytes);
+ dirty = true;
+
+ psRegisterIndex = -1;
+ vsRegisterIndex = -1;
+ registerCount = VariableRowCount(type) * elementCount();
+}
+
+Uniform::~Uniform()
+{
+ delete[] data;
+}
+
+bool Uniform::isArray() const
+{
+ return arraySize > 0;
+}
+
+unsigned int Uniform::elementCount() const
+{
+ return arraySize > 0 ? arraySize : 1;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/Uniform.h b/src/3rdparty/angle/src/libGLESv2/Uniform.h
new file mode 100644
index 0000000000..8ab0fbe234
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/Uniform.h
@@ -0,0 +1,48 @@
+//
+// Copyright (c) 2010-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef LIBGLESV2_UNIFORM_H_
+#define LIBGLESV2_UNIFORM_H_
+
+#include <string>
+#include <vector>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+// Helper struct representing a single shader uniform
+struct Uniform
+{
+ Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize);
+
+ ~Uniform();
+
+ bool isArray() const;
+ unsigned int elementCount() const;
+
+ const GLenum type;
+ const GLenum precision;
+ const std::string name;
+ const unsigned int arraySize;
+
+ unsigned char *data;
+ bool dirty;
+
+ int psRegisterIndex;
+ int vsRegisterIndex;
+ unsigned int registerCount;
+};
+
+typedef std::vector<Uniform*> UniformArray;
+
+}
+
+#endif // LIBGLESV2_UNIFORM_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/VertexDataManager.cpp
deleted file mode 100644
index 32c40182d3..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/VertexDataManager.cpp
+++ /dev/null
@@ -1,783 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#include "libGLESv2/VertexDataManager.h"
-
-#include "common/debug.h"
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Program.h"
-#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/main.h"
-
-#include "libGLESv2/vertexconversion.h"
-#include "libGLESv2/IndexDataManager.h"
-
-namespace
-{
- enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
- // This has to be at least 4k or else it fails on ATI cards.
- enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
-}
-
-namespace gl
-{
-unsigned int VertexBuffer::mCurrentSerial = 1;
-
-int elementsInBuffer(const VertexAttribute &attribute, int size)
-{
- int stride = attribute.stride();
- return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
-}
-
-VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
-{
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- mDirtyCurrentValue[i] = true;
- mCurrentValueBuffer[i] = NULL;
- mCurrentValueOffsets[i] = 0;
- }
-
- const D3DCAPS9 &caps = context->getDeviceCaps();
- checkVertexCaps(caps.DeclTypes);
-
- mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
-
- if (!mStreamingBuffer)
- {
- ERR("Failed to allocate the streaming vertex buffer.");
- }
-}
-
-VertexDataManager::~VertexDataManager()
-{
- delete mStreamingBuffer;
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- delete mCurrentValueBuffer[i];
- }
-}
-
-std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances)
-{
- Buffer *buffer = attribute.mBoundBuffer.get();
-
- int inputStride = attribute.stride();
- int elementSize = attribute.typeSize();
- const FormatConverter &converter = formatConverter(attribute);
- std::size_t streamOffset = 0;
-
- void *output = NULL;
-
- if (vertexBuffer)
- {
- output = vertexBuffer->map(attribute, spaceRequired(attribute, count, instances), &streamOffset);
- }
-
- if (output == NULL)
- {
- ERR("Failed to map vertex buffer.");
- return -1;
- }
-
- const char *input = NULL;
-
- if (buffer)
- {
- int offset = attribute.mOffset;
-
- input = static_cast<const char*>(buffer->data()) + offset;
- }
- else
- {
- input = static_cast<const char*>(attribute.mPointer);
- }
-
- if (instances == 0 || attribute.mDivisor == 0)
- {
- input += inputStride * start;
- }
-
- if (converter.identity && inputStride == elementSize)
- {
- memcpy(output, input, count * inputStride);
- }
- else
- {
- converter.convertArray(input, inputStride, count, output);
- }
-
- vertexBuffer->unmap();
-
- return streamOffset;
-}
-
-GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
-{
- if (!mStreamingBuffer)
- {
- return GL_OUT_OF_MEMORY;
- }
-
- const VertexAttributeArray &attribs = mContext->getVertexAttributes();
- ProgramBinary *programBinary = mContext->getCurrentProgramBinary();
-
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
- {
- translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
- }
-
- // Determine the required storage size per used buffer, and invalidate static buffers that don't contain matching attributes
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (translated[i].active && attribs[i].mArrayEnabled)
- {
- Buffer *buffer = attribs[i].mBoundBuffer.get();
- StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
-
- if (staticBuffer)
- {
- if (staticBuffer->size() == 0)
- {
- int totalCount = elementsInBuffer(attribs[i], buffer->size());
- staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount, 0));
- }
- else if (staticBuffer->lookupAttribute(attribs[i]) == -1)
- {
- // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer
- // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer
- for (int previous = 0; previous < i; previous++)
- {
- if (translated[previous].active && attribs[previous].mArrayEnabled)
- {
- Buffer *previousBuffer = attribs[previous].mBoundBuffer.get();
- StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL;
-
- if (staticBuffer == previousStaticBuffer)
- {
- mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances));
- }
- }
- }
-
- mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances));
-
- buffer->invalidateStaticData();
- }
- }
- else
- {
- mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances));
- }
- }
- }
-
- // Reserve the required space per used buffer
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (translated[i].active && attribs[i].mArrayEnabled)
- {
- Buffer *buffer = attribs[i].mBoundBuffer.get();
- ArrayVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
- ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;
-
- if (vertexBuffer)
- {
- vertexBuffer->reserveRequiredSpace();
- }
- }
- }
-
- // Perform the vertex data translations
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (translated[i].active)
- {
- if (attribs[i].mArrayEnabled)
- {
- Buffer *buffer = attribs[i].mBoundBuffer.get();
-
- if (!buffer && attribs[i].mPointer == NULL)
- {
- // This is an application error that would normally result in a crash, but we catch it and return an error
- ERR("An enabled vertex array has no buffer and no pointer.");
- return GL_INVALID_OPERATION;
- }
-
- const FormatConverter &converter = formatConverter(attribs[i]);
-
- StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
- ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer);
-
- std::size_t streamOffset = -1;
-
- if (staticBuffer)
- {
- streamOffset = staticBuffer->lookupAttribute(attribs[i]);
-
- if (streamOffset == -1)
- {
- // Convert the entire buffer
- int totalCount = elementsInBuffer(attribs[i], buffer->size());
- int startIndex = attribs[i].mOffset / attribs[i].stride();
-
- streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i], 0);
- }
-
- if (streamOffset != -1)
- {
- streamOffset += (attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
-
- if (instances == 0 || attribs[i].mDivisor == 0)
- {
- streamOffset += start * converter.outputElementSize;
- }
- }
- }
- else
- {
- streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i], instances);
- }
-
- if (streamOffset == -1)
- {
- return GL_OUT_OF_MEMORY;
- }
-
- translated[i].vertexBuffer = vertexBuffer->getBuffer();
- translated[i].serial = vertexBuffer->getSerial();
- translated[i].divisor = attribs[i].mDivisor;
-
- translated[i].type = converter.d3dDeclType;
- translated[i].stride = converter.outputElementSize;
- translated[i].offset = streamOffset;
- }
- else
- {
- if (!mCurrentValueBuffer[i])
- {
- mCurrentValueBuffer[i] = new StreamingVertexBuffer(mDevice, CONSTANT_VERTEX_BUFFER_SIZE);
- }
-
- StreamingVertexBuffer *buffer = mCurrentValueBuffer[i];
-
- if (mDirtyCurrentValue[i])
- {
- const int requiredSpace = 4 * sizeof(float);
- buffer->addRequiredSpace(requiredSpace);
- buffer->reserveRequiredSpace();
- float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i]));
- if (data)
- {
- data[0] = attribs[i].mCurrentValue[0];
- data[1] = attribs[i].mCurrentValue[1];
- data[2] = attribs[i].mCurrentValue[2];
- data[3] = attribs[i].mCurrentValue[3];
- buffer->unmap();
- mDirtyCurrentValue[i] = false;
- }
- }
-
- translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
- translated[i].serial = mCurrentValueBuffer[i]->getSerial();
- translated[i].divisor = 0;
-
- translated[i].type = D3DDECLTYPE_FLOAT4;
- translated[i].stride = 0;
- translated[i].offset = mCurrentValueOffsets[i];
- }
- }
- }
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (translated[i].active && attribs[i].mArrayEnabled)
- {
- Buffer *buffer = attribs[i].mBoundBuffer.get();
-
- if (buffer)
- {
- buffer->promoteStaticUsage(count * attribs[i].typeSize());
- }
- }
- }
-
- return GL_NO_ERROR;
-}
-
-std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const
-{
- size_t elementSize = formatConverter(attrib).outputElementSize;
-
- if (instances == 0 || attrib.mDivisor == 0)
- {
- return elementSize * count;
- }
- else
- {
- return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor);
- }
-}
-
-// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
-//
-// BYTE SHORT (Cast)
-// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
-// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
-// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
-// SHORT SHORT (Identity)
-// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
-// UNSIGNED_SHORT FLOAT (Cast)
-// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
-// FIXED (not in WebGL) FLOAT (FixedToFloat)
-// FLOAT FLOAT (Identity)
-
-// GLToCType maps from GL type (as GLenum) to the C typedef.
-template <GLenum GLType> struct GLToCType { };
-
-template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
-template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
-template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
-template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
-template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
-template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
-
-// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
-enum D3DVertexType
-{
- D3DVT_FLOAT,
- D3DVT_SHORT,
- D3DVT_SHORT_NORM,
- D3DVT_UBYTE,
- D3DVT_UBYTE_NORM,
- D3DVT_USHORT_NORM
-};
-
-// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
-template <unsigned int D3DType> struct D3DToCType { };
-
-template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
-template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
-template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
-template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
-template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
-
-// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
-template <unsigned int type, int size>
-struct WidenRule
-{
-};
-
-template <int size> struct WidenRule<D3DVT_FLOAT, size> : gl::NoWiden<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT, size> : gl::WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : gl::WidenToEven<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE, size> : gl::WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : gl::WidenToFour<size> { };
-template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : gl::WidenToEven<size> { };
-
-// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
-template <unsigned int d3dtype, int size>
-struct VertexTypeFlags
-{
-};
-
-template <unsigned int _capflag, unsigned int _declflag>
-struct VertexTypeFlagsHelper
-{
- enum { capflag = _capflag };
- enum { declflag = _declflag };
-};
-
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
-template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
-template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
-template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
-
-
-// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
-template <GLenum GLtype, bool normalized>
-struct VertexTypeMapping
-{
-};
-
-template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
-struct VertexTypeMappingBase
-{
- enum { preferred = Preferred };
- enum { fallback = Fallback };
-};
-
-template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast
-template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize
-template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity
-template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast
-template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
-template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat
-template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity
-
-
-// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
-// The conversion rules themselves are defined in vertexconversion.h.
-
-// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
-template <GLenum fromType, bool normalized, unsigned int toType>
-struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type>
-{
-};
-
-// All conversions from normalized types to float use the Normalize operator.
-template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { };
-
-// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules.
-template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<GLint, 16> { };
-template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLint, 16> { };
-
-// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
-// whether it is normalized or not.
-template <class T, bool normalized>
-struct DefaultVertexValuesStage2
-{
-};
-
-template <class T> struct DefaultVertexValuesStage2<T, true> : gl::NormalizedDefaultValues<T> { };
-template <class T> struct DefaultVertexValuesStage2<T, false> : gl::SimpleDefaultValues<T> { };
-
-// Work out the default value rule for a D3D type (expressed as the C type) and
-template <class T, bool normalized>
-struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized>
-{
-};
-
-template <bool normalized> struct DefaultVertexValues<float, normalized> : gl::SimpleDefaultValues<float> { };
-
-// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
-// The fallback conversion produces an output that all D3D9 devices must support.
-template <class T> struct UsePreferred { enum { type = T::preferred }; };
-template <class T> struct UseFallback { enum { type = T::fallback }; };
-
-// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
-// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
-// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
-template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
-struct Converter
- : gl::VertexDataConverter<typename GLToCType<fromType>::type,
- WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
- ConversionRule<fromType,
- normalized,
- PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
- DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
-{
-private:
- enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
- enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
-
-public:
- enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
- enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
-};
-
-// Initialise a TranslationInfo
-#define TRANSLATION(type, norm, size, preferred) \
- { \
- Converter<type, norm, size, preferred>::identity, \
- Converter<type, norm, size, preferred>::finalSize, \
- Converter<type, norm, size, preferred>::convertArray, \
- static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
- }
-
-#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
- { \
- Converter<type, norm, size, UsePreferred>::capflag, \
- TRANSLATION(type, norm, size, UsePreferred), \
- TRANSLATION(type, norm, size, UseFallback) \
- }
-
-#define TRANSLATIONS_FOR_TYPE(type) \
- { \
- { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
- { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
- }
-
-#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \
- { \
- { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
- { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
- }
-
-const VertexDataManager::TranslationDescription VertexDataManager::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
-{
- TRANSLATIONS_FOR_TYPE(GL_BYTE),
- TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
- TRANSLATIONS_FOR_TYPE(GL_SHORT),
- TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
- TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
- TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
-};
-
-void VertexDataManager::checkVertexCaps(DWORD declTypes)
-{
- for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
- {
- for (unsigned int j = 0; j < 2; j++)
- {
- for (unsigned int k = 0; k < 4; k++)
- {
- if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
- {
- mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
- }
- else
- {
- mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
- }
- }
- }
- }
-}
-
-// This is used to index mAttributeTypes and mPossibleTranslations.
-unsigned int VertexDataManager::typeIndex(GLenum type) const
-{
- switch (type)
- {
- case GL_BYTE: return 0;
- case GL_UNSIGNED_BYTE: return 1;
- case GL_SHORT: return 2;
- case GL_UNSIGNED_SHORT: return 3;
- case GL_FIXED: return 4;
- case GL_FLOAT: return 5;
-
- default: UNREACHABLE(); return 5;
- }
-}
-
-VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL)
-{
- if (size > 0)
- {
- D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
- HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", size);
- }
- }
-}
-
-VertexBuffer::~VertexBuffer()
-{
- if (mVertexBuffer)
- {
- mVertexBuffer->Release();
- }
-}
-
-void VertexBuffer::unmap()
-{
- if (mVertexBuffer)
- {
- mVertexBuffer->Unlock();
- }
-}
-
-IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const
-{
- return mVertexBuffer;
-}
-
-unsigned int VertexBuffer::getSerial() const
-{
- return mSerial;
-}
-
-unsigned int VertexBuffer::issueSerial()
-{
- return mCurrentSerial++;
-}
-
-ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags)
-{
- mBufferSize = size;
- mWritePosition = 0;
- mRequiredSpace = 0;
-}
-
-ArrayVertexBuffer::~ArrayVertexBuffer()
-{
-}
-
-void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
-{
- mRequiredSpace += requiredSpace;
-}
-
-StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
-{
-}
-
-StreamingVertexBuffer::~StreamingVertexBuffer()
-{
-}
-
-void *StreamingVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset)
-{
- void *mapPtr = NULL;
-
- if (mVertexBuffer)
- {
- HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
-
- if (FAILED(result))
- {
- ERR("Lock failed with error 0x%08x", result);
- return NULL;
- }
-
- *offset = mWritePosition;
- mWritePosition += requiredSpace;
- }
-
- return mapPtr;
-}
-
-void StreamingVertexBuffer::reserveRequiredSpace()
-{
- if (mRequiredSpace > mBufferSize)
- {
- if (mVertexBuffer)
- {
- mVertexBuffer->Release();
- mVertexBuffer = NULL;
- }
-
- mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2); // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
-
- D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
- HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
- }
-
- mWritePosition = 0;
- }
- else if (mWritePosition + mRequiredSpace > mBufferSize) // Recycle
- {
- if (mVertexBuffer)
- {
- void *dummy;
- mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
- mVertexBuffer->Unlock();
- }
-
- mWritePosition = 0;
- }
-
- mRequiredSpace = 0;
-}
-
-StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY)
-{
-}
-
-StaticVertexBuffer::~StaticVertexBuffer()
-{
-}
-
-void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset)
-{
- void *mapPtr = NULL;
-
- if (mVertexBuffer)
- {
- HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
-
- if (FAILED(result))
- {
- ERR("Lock failed with error 0x%08x", result);
- return NULL;
- }
-
- int attributeOffset = attribute.mOffset % attribute.stride();
- VertexElement element = {attribute.mType, attribute.mSize, attribute.stride(), attribute.mNormalized, attributeOffset, mWritePosition};
- mCache.push_back(element);
-
- *streamOffset = mWritePosition;
- mWritePosition += requiredSpace;
- }
-
- return mapPtr;
-}
-
-void StaticVertexBuffer::reserveRequiredSpace()
-{
- if (!mVertexBuffer && mBufferSize == 0)
- {
- D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
- HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
- mSerial = issueSerial();
-
- if (FAILED(result))
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
- }
-
- mBufferSize = mRequiredSpace;
- }
- else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
- {
- // Already allocated
- }
- else UNREACHABLE(); // Static vertex buffers can't be resized
-
- mRequiredSpace = 0;
-}
-
-std::size_t StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute)
-{
- for (unsigned int element = 0; element < mCache.size(); element++)
- {
- if (mCache[element].type == attribute.mType &&
- mCache[element].size == attribute.mSize &&
- mCache[element].stride == attribute.stride() &&
- mCache[element].normalized == attribute.mNormalized)
- {
- if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
- {
- return mCache[element].streamOffset;
- }
- }
- }
-
- return -1;
-}
-
-const VertexDataManager::FormatConverter &VertexDataManager::formatConverter(const VertexAttribute &attribute) const
-{
- return mAttributeTypes[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
-}
-}
diff --git a/src/3rdparty/angle/src/libGLESv2/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/VertexDataManager.h
deleted file mode 100644
index 857591ac29..0000000000
--- a/src/3rdparty/angle/src/libGLESv2/VertexDataManager.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-// VertexDataManager.h: Defines the VertexDataManager, a class that
-// runs the Buffer translation process.
-
-#ifndef LIBGLESV2_VERTEXDATAMANAGER_H_
-#define LIBGLESV2_VERTEXDATAMANAGER_H_
-
-#include <vector>
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "libGLESv2/Context.h"
-
-namespace gl
-{
-
-struct TranslatedAttribute
-{
- bool active;
-
- D3DDECLTYPE type;
- UINT offset;
- UINT stride; // 0 means not to advance the read pointer at all
-
- IDirect3DVertexBuffer9 *vertexBuffer;
- unsigned int serial;
- unsigned int divisor;
-};
-
-class VertexBuffer
-{
- public:
- VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
- virtual ~VertexBuffer();
-
- void unmap();
-
- IDirect3DVertexBuffer9 *getBuffer() const;
- unsigned int getSerial() const;
-
- protected:
- IDirect3DDevice9 *const mDevice;
- IDirect3DVertexBuffer9 *mVertexBuffer;
-
- unsigned int mSerial;
- static unsigned int issueSerial();
- static unsigned int mCurrentSerial;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
-};
-
-class ArrayVertexBuffer : public VertexBuffer
-{
- public:
- ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
- ~ArrayVertexBuffer();
-
- std::size_t size() const { return mBufferSize; }
- virtual void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) = 0;
- virtual void reserveRequiredSpace() = 0;
- void addRequiredSpace(UINT requiredSpace);
-
- protected:
- std::size_t mBufferSize;
- std::size_t mWritePosition;
- std::size_t mRequiredSpace;
-};
-
-class StreamingVertexBuffer : public ArrayVertexBuffer
-{
- public:
- StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize);
- ~StreamingVertexBuffer();
-
- void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset);
- void reserveRequiredSpace();
-};
-
-class StaticVertexBuffer : public ArrayVertexBuffer
-{
- public:
- explicit StaticVertexBuffer(IDirect3DDevice9 *device);
- ~StaticVertexBuffer();
-
- void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset);
- void reserveRequiredSpace();
-
- std::size_t lookupAttribute(const VertexAttribute &attribute); // Returns the offset into the vertex buffer, or -1 if not found
-
- private:
- struct VertexElement
- {
- GLenum type;
- GLint size;
- GLsizei stride;
- bool normalized;
- int attributeOffset;
-
- std::size_t streamOffset;
- };
-
- std::vector<VertexElement> mCache;
-};
-
-class VertexDataManager
-{
- public:
- VertexDataManager(Context *context, IDirect3DDevice9 *backend);
- virtual ~VertexDataManager();
-
- void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
-
- GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
-
- std::size_t spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const;
- std::size_t writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances);
-
- Context *const mContext;
- IDirect3DDevice9 *const mDevice;
-
- StreamingVertexBuffer *mStreamingBuffer;
-
- bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
- StreamingVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS];
- std::size_t mCurrentValueOffsets[MAX_VERTEX_ATTRIBS];
-
- // Attribute format conversion
- struct FormatConverter
- {
- bool identity;
- std::size_t outputElementSize;
- void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
- D3DDECLTYPE d3dDeclType;
- };
-
- enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
-
- FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
-
- struct TranslationDescription
- {
- DWORD capsFlag;
- FormatConverter preferredConversion;
- FormatConverter fallbackConversion;
- };
-
- // This table is used to generate mAttributeTypes.
- static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
-
- void checkVertexCaps(DWORD declTypes);
-
- unsigned int typeIndex(GLenum type) const;
- const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
-};
-
-}
-
-#endif // LIBGLESV2_VERTEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/angletypes.h b/src/3rdparty/angle/src/libGLESv2/angletypes.h
new file mode 100644
index 0000000000..37f67f41ac
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/angletypes.h
@@ -0,0 +1,128 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
+
+#ifndef LIBGLESV2_ANGLETYPES_H_
+#define LIBGLESV2_ANGLETYPES_H_
+
+namespace gl
+{
+
+enum TextureType
+{
+ TEXTURE_2D,
+ TEXTURE_CUBE,
+
+ TEXTURE_TYPE_COUNT,
+ TEXTURE_UNKNOWN
+};
+
+enum SamplerType
+{
+ SAMPLER_PIXEL,
+ SAMPLER_VERTEX
+};
+
+struct Color
+{
+ float red;
+ float green;
+ float blue;
+ float alpha;
+};
+
+struct Rectangle
+{
+ int x;
+ int y;
+ int width;
+ int height;
+};
+
+struct RasterizerState
+{
+ bool cullFace;
+ GLenum cullMode;
+ GLenum frontFace;
+
+ bool polygonOffsetFill;
+ GLfloat polygonOffsetFactor;
+ GLfloat polygonOffsetUnits;
+
+ bool pointDrawMode;
+};
+
+struct BlendState
+{
+ bool blend;
+ GLenum sourceBlendRGB;
+ GLenum destBlendRGB;
+ GLenum sourceBlendAlpha;
+ GLenum destBlendAlpha;
+ GLenum blendEquationRGB;
+ GLenum blendEquationAlpha;
+
+ bool colorMaskRed;
+ bool colorMaskGreen;
+ bool colorMaskBlue;
+ bool colorMaskAlpha;
+
+ bool sampleAlphaToCoverage;
+
+ bool dither;
+};
+
+struct DepthStencilState
+{
+ bool depthTest;
+ GLenum depthFunc;
+ bool depthMask;
+
+ bool stencilTest;
+ GLenum stencilFunc;
+ GLuint stencilMask;
+ GLenum stencilFail;
+ GLenum stencilPassDepthFail;
+ GLenum stencilPassDepthPass;
+ GLuint stencilWritemask;
+ GLenum stencilBackFunc;
+ GLuint stencilBackMask;
+ GLenum stencilBackFail;
+ GLenum stencilBackPassDepthFail;
+ GLenum stencilBackPassDepthPass;
+ GLuint stencilBackWritemask;
+};
+
+struct SamplerState
+{
+ GLenum minFilter;
+ GLenum magFilter;
+ GLenum wrapS;
+ GLenum wrapT;
+ float maxAnisotropy;
+ int lodOffset;
+};
+
+struct ClearParameters
+{
+ GLbitfield mask;
+
+ Color colorClearValue;
+ bool colorMaskRed;
+ bool colorMaskGreen;
+ bool colorMaskBlue;
+ bool colorMaskAlpha;
+
+ float depthClearValue;
+
+ GLint stencilClearValue;
+ GLuint stencilWriteMask;
+};
+
+}
+
+#endif // LIBGLESV2_ANGLETYPES_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/constants.h b/src/3rdparty/angle/src/libGLESv2/constants.h
new file mode 100644
index 0000000000..9f24d66a7d
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/constants.h
@@ -0,0 +1,34 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Contants.h: Defines some implementation specific and gl constants
+
+#ifndef LIBGLESV2_CONSTANTS_H_
+#define LIBGLESV2_CONSTANTS_H_
+
+namespace gl
+{
+
+enum
+{
+ MAX_VERTEX_ATTRIBS = 16,
+ MAX_TEXTURE_IMAGE_UNITS = 16,
+
+ // Implementation upper limits, real maximums depend on the hardware
+ IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 16,
+ IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
+
+ IMPLEMENTATION_MAX_VARYING_VECTORS = 32,
+ IMPLEMENTATION_MAX_DRAW_BUFFERS = 8
+};
+
+const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
+const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
+
+}
+
+#endif // LIBGLESV2_CONSTANTS_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
index 16d9c1775d..64f67d7d6d 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -6,29 +7,19 @@
// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
-#define GL_APICALL
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
-#include <exception>
-#include <limits>
-
-#include "common/debug.h"
#include "common/version.h"
#include "libGLESv2/main.h"
-#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/Buffer.h"
-#include "libGLESv2/Context.h"
#include "libGLESv2/Fence.h"
#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
-#include "libGLESv2/Renderbuffer.h"
-#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/Query.h"
+#include "libGLESv2/Context.h"
bool validImageSize(GLint level, GLsizei width, GLsizei height)
{
@@ -71,7 +62,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_DEPTH_STENCIL_OES:
break;
default:
- return error(GL_INVALID_ENUM, false);
+ return gl::error(GL_INVALID_ENUM, false);
}
// invalid <type> -> sets INVALID_ENUM
@@ -89,7 +80,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_LUMINANCE_ALPHA:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
case GL_FLOAT:
@@ -103,7 +94,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_LUMINANCE_ALPHA:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
case GL_UNSIGNED_SHORT_4_4_4_4:
@@ -113,7 +104,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_RGBA:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
case GL_UNSIGNED_SHORT_5_6_5:
@@ -122,7 +113,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_RGB:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
case GL_UNSIGNED_SHORT:
@@ -132,7 +123,7 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_DEPTH_COMPONENT:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
case GL_UNSIGNED_INT_24_8_OES:
@@ -141,11 +132,11 @@ bool checkTextureFormatType(GLenum format, GLenum type)
case GL_DEPTH_STENCIL_OES:
return true;
default:
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
default:
- return error(GL_INVALID_ENUM, false);
+ return gl::error(GL_INVALID_ENUM, false);
}
}
@@ -155,12 +146,12 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
{
if (!texture)
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
if (compressed != texture->isCompressed(level))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
if (format != GL_NONE)
@@ -168,7 +159,7 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
if (internalformat != texture->getInternalFormat(level))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
}
@@ -177,14 +168,14 @@ bool validateSubImageParams2D(bool compressed, GLsizei width, GLsizei height,
if ((width % 4 != 0 && width != texture->getWidth(0)) ||
(height % 4 != 0 && height != texture->getHeight(0)))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
}
if (xoffset + width > texture->getWidth(level) ||
yoffset + height > texture->getHeight(level))
{
- return error(GL_INVALID_VALUE, false);
+ return gl::error(GL_INVALID_VALUE, false);
}
return true;
@@ -196,12 +187,12 @@ bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
{
if (!texture)
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
if (compressed != texture->isCompressed(target, level))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
if (format != GL_NONE)
@@ -209,7 +200,7 @@ bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
GLenum internalformat = gl::ConvertSizedInternalFormat(format, type);
if (internalformat != texture->getInternalFormat(target, level))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
}
@@ -218,14 +209,14 @@ bool validateSubImageParamsCube(bool compressed, GLsizei width, GLsizei height,
if ((width % 4 != 0 && width != texture->getWidth(target, 0)) ||
(height % 4 != 0 && height != texture->getHeight(target, 0)))
{
- return error(GL_INVALID_OPERATION, false);
+ return gl::error(GL_INVALID_OPERATION, false);
}
}
if (xoffset + width > texture->getWidth(target, level) ||
yoffset + height > texture->getHeight(target, level))
{
- return error(GL_INVALID_VALUE, false);
+ return gl::error(GL_INVALID_VALUE, false);
}
return true;
@@ -277,7 +268,7 @@ void __stdcall glActiveTexture(GLenum texture)
{
if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
context->setActiveSampler(texture - GL_TEXTURE0);
@@ -285,7 +276,7 @@ void __stdcall glActiveTexture(GLenum texture)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -306,11 +297,11 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -318,23 +309,23 @@ void __stdcall glAttachShader(GLuint program, GLuint shader)
{
if (context->getProgram(shader))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
if (!programObject->attachShader(shaderObject))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -350,12 +341,12 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (id == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getNonLostContext();
@@ -367,7 +358,7 @@ void __stdcall glBeginQueryEXT(GLenum target, GLuint id)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -379,7 +370,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -392,17 +383,17 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
if (strncmp(name, "gl_", 3) == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
programObject->bindAttributeLocation(index, name);
@@ -410,7 +401,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar*
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -433,13 +424,13 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer)
context->bindElementArrayBuffer(buffer);
return;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -451,7 +442,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
{
if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -471,7 +462,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -483,7 +474,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
if (target != GL_RENDERBUFFER)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -495,7 +486,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -513,7 +504,7 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
if (textureObject && textureObject->getTarget() != target && texture != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (target)
@@ -525,13 +516,13 @@ void __stdcall glBindTexture(GLenum target, GLuint texture)
context->bindTextureCubeMap(texture);
return;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -551,7 +542,7 @@ void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -573,7 +564,7 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
case GL_FUNC_REVERSE_SUBTRACT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (modeAlpha)
@@ -583,7 +574,7 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
case GL_FUNC_REVERSE_SUBTRACT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -595,7 +586,7 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -630,7 +621,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
case GL_SRC_ALPHA_SATURATE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (dstRGB)
@@ -651,7 +642,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
case GL_ONE_MINUS_CONSTANT_ALPHA:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (srcAlpha)
@@ -673,7 +664,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
case GL_SRC_ALPHA_SATURATE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (dstAlpha)
@@ -694,7 +685,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
case GL_ONE_MINUS_CONSTANT_ALPHA:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
@@ -706,7 +697,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
if (constantColorUsed && constantAlphaUsed)
{
ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getNonLostContext();
@@ -718,7 +709,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -731,7 +722,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
{
if (size < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (usage)
@@ -741,7 +732,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
case GL_DYNAMIC_DRAW:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -759,12 +750,12 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
buffer = context->getElementArrayBuffer();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (!buffer)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
buffer->bufferData(data, size, usage);
@@ -772,7 +763,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -785,7 +776,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
{
if (size < 0 || offset < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (data == NULL)
@@ -808,17 +799,17 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
buffer = context->getElementArrayBuffer();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (!buffer)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if ((size_t)size + offset > buffer->size())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
buffer->bufferSubData(data, size, offset);
@@ -826,7 +817,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -838,7 +829,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
{
if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM, 0);
+ return gl::error(GL_INVALID_ENUM, 0);
}
gl::Context *context = gl::getNonLostContext();
@@ -860,7 +851,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, 0);
+ return gl::error(GL_OUT_OF_MEMORY, 0);
}
return 0;
@@ -881,7 +872,7 @@ void __stdcall glClear(GLbitfield mask)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -901,7 +892,7 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -920,7 +911,7 @@ void __stdcall glClearDepthf(GLclampf depth)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -939,7 +930,7 @@ void __stdcall glClearStencil(GLint s)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -959,7 +950,7 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -979,11 +970,11 @@ void __stdcall glCompileShader(GLuint shader)
{
if (context->getProgram(shader))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -992,7 +983,7 @@ void __stdcall glCompileShader(GLuint shader)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1007,7 +998,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
{
if (!validImageSize(level, width, height) || border != 0 || imageSize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (internalformat)
@@ -1018,12 +1009,22 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (border != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ if (width != 1 && width != 2 && width % 4 != 0)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ if (height != 1 && height != 2 && height % 4 != 0)
+ {
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getNonLostContext();
@@ -1032,7 +1033,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (target)
@@ -1041,7 +1042,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
if (width > (context->getMaximumTextureDimension() >> level) ||
height > (context->getMaximumTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -1052,17 +1053,17 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (width != height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (width > (context->getMaximumCubeTextureDimension() >> level) ||
height > (context->getMaximumCubeTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (internalformat) {
@@ -1070,19 +1071,19 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->supportsDXT1Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->supportsDXT3Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->supportsDXT5Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
default: UNREACHABLE();
@@ -1090,7 +1091,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (target == GL_TEXTURE_2D)
@@ -1099,12 +1100,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
@@ -1115,12 +1116,12 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (target)
@@ -1141,7 +1142,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1157,12 +1158,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
{
if (!gl::IsInternalTextureTarget(target))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (format)
@@ -1173,7 +1174,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (width == 0 || height == 0 || data == NULL)
@@ -1187,7 +1188,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (format) {
@@ -1195,19 +1196,19 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->supportsDXT1Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->supportsDXT3Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->supportsDXT5Textures())
{
- return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ return gl::error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
}
break;
default: UNREACHABLE();
@@ -1215,12 +1216,12 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
if (imageSize != gl::ComputeCompressedSize(width, height, format))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (xoffset % 4 != 0 || yoffset % 4 != 0)
{
- return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
+ return gl::error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
// does not exist unless DXT textures are supported.
}
@@ -1248,7 +1249,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1262,12 +1263,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
if (!validImageSize(level, width, height))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (border != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1276,7 +1277,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (target)
@@ -1285,7 +1286,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (width > (context->getMaximumTextureDimension() >> level) ||
height > (context->getMaximumTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -1296,32 +1297,32 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (width != height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (width > (context->getMaximumCubeTextureDimension() >> level) ||
height > (context->getMaximumCubeTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Framebuffer *framebuffer = context->getReadFramebuffer();
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
- if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- gl::Renderbuffer *source = framebuffer->getColorbuffer();
+ gl::Renderbuffer *source = framebuffer->getReadColorbuffer();
GLenum colorbufferFormat = source->getInternalFormat();
// [OpenGL ES 2.0.24] table 3.9
@@ -1331,9 +1332,10 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (colorbufferFormat != GL_ALPHA8_EXT &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_LUMINANCE:
@@ -1342,49 +1344,51 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
colorbufferFormat != GL_RGB8_OES &&
colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
if (colorbufferFormat != GL_RGBA4 &&
colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_BGRA8_EXT &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->supportsDXT1Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->supportsDXT3Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->supportsDXT5Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_DEPTH_COMPONENT:
@@ -1394,14 +1398,14 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_DEPTH24_STENCIL8_OES:
if (context->supportsDepthTextures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (target == GL_TEXTURE_2D)
@@ -1410,12 +1414,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
@@ -1426,12 +1430,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);
@@ -1441,7 +1445,7 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1455,17 +1459,17 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
{
if (!gl::IsInternalTextureTarget(target))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (width == 0 || height == 0)
@@ -1479,22 +1483,22 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Framebuffer *framebuffer = context->getReadFramebuffer();
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
- return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION);
}
- if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- gl::Renderbuffer *source = framebuffer->getColorbuffer();
+ gl::Renderbuffer *source = framebuffer->getReadColorbuffer();
GLenum colorbufferFormat = source->getInternalFormat();
gl::Texture *texture = NULL;
GLenum textureFormat = GL_RGBA;
@@ -1532,7 +1536,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_LUMINANCE:
@@ -1543,7 +1547,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_LUMINANCE_ALPHA:
@@ -1552,19 +1556,19 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
colorbufferFormat != GL_RGB5_A1 &&
colorbufferFormat != GL_RGBA8_OES)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
@@ -1573,7 +1577,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1592,7 +1596,7 @@ GLuint __stdcall glCreateProgram(void)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, 0);
+ return gl::error(GL_OUT_OF_MEMORY, 0);
}
return 0;
@@ -1614,13 +1618,13 @@ GLuint __stdcall glCreateShader(GLenum type)
case GL_VERTEX_SHADER:
return context->createShader(type);
default:
- return error(GL_INVALID_ENUM, 0);
+ return gl::error(GL_INVALID_ENUM, 0);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, 0);
+ return gl::error(GL_OUT_OF_MEMORY, 0);
}
return 0;
@@ -1647,12 +1651,12 @@ void __stdcall glCullFace(GLenum mode)
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1664,7 +1668,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1679,7 +1683,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1691,7 +1695,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1706,7 +1710,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1718,7 +1722,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1736,7 +1740,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1759,11 +1763,11 @@ void __stdcall glDeleteProgram(GLuint program)
{
if(context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -1772,7 +1776,7 @@ void __stdcall glDeleteProgram(GLuint program)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1784,7 +1788,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1799,7 +1803,7 @@ void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1811,7 +1815,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1826,7 +1830,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1849,11 +1853,11 @@ void __stdcall glDeleteShader(GLuint shader)
{
if(context->getProgram(shader))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -1862,7 +1866,7 @@ void __stdcall glDeleteShader(GLuint shader)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1874,7 +1878,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -1892,7 +1896,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1914,7 +1918,7 @@ void __stdcall glDepthFunc(GLenum func)
case GL_NOTEQUAL:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -1926,7 +1930,7 @@ void __stdcall glDepthFunc(GLenum func)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1945,7 +1949,7 @@ void __stdcall glDepthMask(GLboolean flag)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1964,7 +1968,7 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -1988,11 +1992,11 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
shaderByProgramHandle = context->getShader(program);
if (!shaderByProgramHandle)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
else
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
@@ -2001,23 +2005,23 @@ void __stdcall glDetachShader(GLuint program, GLuint shader)
gl::Program *programByShaderHandle = context->getProgram(shader);
if (!programByShaderHandle)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
else
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
if (!programObject->detachShader(shaderObject))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2043,13 +2047,13 @@ void __stdcall glDisable(GLenum cap)
case GL_BLEND: context->setBlend(false); break;
case GL_DITHER: context->setDither(false); break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2061,7 +2065,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2073,7 +2077,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2085,7 +2089,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
if (count < 0 || first < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2097,7 +2101,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2109,7 +2113,7 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
{
if (count < 0 || first < 0 || primcount < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (primcount > 0)
@@ -2124,7 +2128,7 @@ void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei coun
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2137,7 +2141,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2152,11 +2156,11 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
context->drawElements(mode, count, type, indices, 0);
@@ -2164,7 +2168,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2177,7 +2181,7 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
{
if (count < 0 || primcount < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (primcount > 0)
@@ -2194,11 +2198,11 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
case GL_UNSIGNED_INT:
if (!context->supports32bitIndices())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
context->drawElements(mode, count, type, indices, primcount);
@@ -2207,7 +2211,7 @@ void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum t
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2233,13 +2237,13 @@ void __stdcall glEnable(GLenum cap)
case GL_BLEND: context->setBlend(true); break;
case GL_DITHER: context->setDither(true); break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2251,7 +2255,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2263,7 +2267,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2279,7 +2283,7 @@ void __stdcall glEndQueryEXT(GLenum target)
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -2291,7 +2295,7 @@ void __stdcall glEndQueryEXT(GLenum target)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2309,7 +2313,7 @@ void __stdcall glFinishFenceNV(GLuint fence)
if (fenceObject == NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
fenceObject->finishFence();
@@ -2317,7 +2321,7 @@ void __stdcall glFinishFenceNV(GLuint fence)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2336,7 +2340,7 @@ void __stdcall glFinish(void)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2355,7 +2359,7 @@ void __stdcall glFlush(void)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2369,7 +2373,7 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
|| (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -2391,28 +2395,39 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- switch (attachment)
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{
- case GL_COLOR_ATTACHMENT0:
- framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
- break;
- case GL_DEPTH_ATTACHMENT:
- framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
- break;
- case GL_STENCIL_ATTACHMENT:
- framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
- break;
- default:
- return error(GL_INVALID_ENUM);
+ const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+
+ if (colorAttachment >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_VALUE);
+ }
+
+ framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer);
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_DEPTH_ATTACHMENT:
+ framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
+ break;
+ case GL_STENCIL_ATTACHMENT:
+ framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM);
+ }
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2425,23 +2440,34 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
{
if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
- }
-
- switch (attachment)
- {
- case GL_COLOR_ATTACHMENT0:
- case GL_DEPTH_ATTACHMENT:
- case GL_STENCIL_ATTACHMENT:
- break;
- default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
if (context)
{
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
+ {
+ const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+
+ if (colorAttachment >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_VALUE);
+ }
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_DEPTH_ATTACHMENT:
+ case GL_STENCIL_ATTACHMENT:
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM);
+ }
+ }
+
if (texture == 0)
{
textarget = GL_NONE;
@@ -2452,7 +2478,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
if (tex == NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (textarget)
@@ -2461,12 +2487,12 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
{
if (tex->getTarget() != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Texture2D *tex2d = static_cast<gl::Texture2D *>(tex);
if (tex2d->isCompressed(0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
}
@@ -2480,23 +2506,23 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
{
if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::TextureCubeMap *texcube = static_cast<gl::TextureCubeMap *>(tex);
if (texcube->isCompressed(textarget, level))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
}
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (level != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -2515,20 +2541,33 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
if (framebufferHandle == 0 || !framebuffer)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
- switch (attachment)
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{
- case GL_COLOR_ATTACHMENT0: framebuffer->setColorbuffer(textarget, texture); break;
- case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
- case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
+ const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+
+ if (colorAttachment >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_VALUE);
+ }
+
+ framebuffer->setColorbuffer(colorAttachment, textarget, texture);
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break;
+ case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
+ }
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2552,12 +2591,12 @@ void __stdcall glFrontFace(GLenum mode)
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2569,7 +2608,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2584,7 +2623,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2606,11 +2645,11 @@ void __stdcall glGenerateMipmap(GLenum target)
if (tex2d->isCompressed(0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (tex2d->isDepth(0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
tex2d->generateMipmaps();
@@ -2623,7 +2662,7 @@ void __stdcall glGenerateMipmap(GLenum target)
if (texcube->isCompressed(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texcube->generateMipmaps();
@@ -2631,13 +2670,13 @@ void __stdcall glGenerateMipmap(GLenum target)
}
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2649,7 +2688,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2664,7 +2703,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2676,7 +2715,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2691,7 +2730,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2703,7 +2742,7 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2718,7 +2757,7 @@ void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2730,7 +2769,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2745,7 +2784,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2757,7 +2796,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures)
{
if (n < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2772,7 +2811,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2786,7 +2825,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2799,17 +2838,17 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
if (index >= (GLuint)programObject->getActiveAttributeCount())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
programObject->getActiveAttribute(index, bufsize, length, size, type, name);
@@ -2817,7 +2856,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2831,7 +2870,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2844,17 +2883,17 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
if (index >= (GLuint)programObject->getActiveUniformCount())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
programObject->getActiveUniform(index, bufsize, length, size, type, name);
@@ -2862,7 +2901,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2875,7 +2914,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
{
if (maxcount < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -2888,11 +2927,11 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -2901,7 +2940,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -2922,18 +2961,18 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION, -1);
+ return gl::error(GL_INVALID_OPERATION, -1);
}
else
{
- return error(GL_INVALID_VALUE, -1);
+ return gl::error(GL_INVALID_VALUE, -1);
}
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programObject->isLinked() || !programBinary)
{
- return error(GL_INVALID_OPERATION, -1);
+ return gl::error(GL_INVALID_OPERATION, -1);
}
return programBinary->getAttributeLocation(name);
@@ -2941,7 +2980,7 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, -1);
+ return gl::error(GL_OUT_OF_MEMORY, -1);
}
return -1;
@@ -2962,7 +3001,7 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
GLenum nativeType;
unsigned int numParams = 0;
if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
if (numParams == 0)
return; // it is known that the pname is valid, but there are no parameters to return
@@ -3006,7 +3045,7 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3030,13 +3069,13 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params
case GL_ELEMENT_ARRAY_BUFFER:
buffer = context->getElementArrayBuffer();
break;
- default: return error(GL_INVALID_ENUM);
+ default: return gl::error(GL_INVALID_ENUM);
}
if (!buffer)
{
// A null buffer means that "0" is bound to the requested buffer target
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (pname)
@@ -3047,13 +3086,13 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params
case GL_BUFFER_SIZE:
*params = buffer->size();
break;
- default: return error(GL_INVALID_ENUM);
+ default: return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3086,7 +3125,7 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
if (fenceObject == NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
fenceObject->getFenceiv(pname, params);
@@ -3094,7 +3133,7 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3113,7 +3152,7 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
GLenum nativeType;
unsigned int numParams = 0;
if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
if (numParams == 0)
return; // it is known that the pname is valid, but that there are no parameters to return.
@@ -3154,7 +3193,7 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3171,7 +3210,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
{
if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Framebuffer *framebuffer = NULL;
@@ -3179,7 +3218,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
{
if(context->getReadFramebufferHandle() == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
framebuffer = context->getReadFramebuffer();
@@ -3188,7 +3227,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
{
if (context->getDrawFramebufferHandle() == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
framebuffer = context->getDrawFramebuffer();
@@ -3196,21 +3235,33 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
GLenum attachmentType;
GLuint attachmentHandle;
- switch (attachment)
+
+ if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT)
{
- case GL_COLOR_ATTACHMENT0:
- attachmentType = framebuffer->getColorbufferType();
- attachmentHandle = framebuffer->getColorbufferHandle();
- break;
- case GL_DEPTH_ATTACHMENT:
- attachmentType = framebuffer->getDepthbufferType();
- attachmentHandle = framebuffer->getDepthbufferHandle();
- break;
- case GL_STENCIL_ATTACHMENT:
- attachmentType = framebuffer->getStencilbufferType();
- attachmentHandle = framebuffer->getStencilbufferHandle();
- break;
- default: return error(GL_INVALID_ENUM);
+ const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT);
+
+ if (colorAttachment >= context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_ENUM);
+ }
+
+ attachmentType = framebuffer->getColorbufferType(colorAttachment);
+ attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment);
+ }
+ else
+ {
+ switch (attachment)
+ {
+ case GL_DEPTH_ATTACHMENT:
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferHandle();
+ break;
+ case GL_STENCIL_ATTACHMENT:
+ attachmentType = framebuffer->getStencilbufferType();
+ attachmentHandle = framebuffer->getStencilbufferHandle();
+ break;
+ default: return gl::error(GL_INVALID_ENUM);
+ }
}
GLenum attachmentObjectType; // Type category
@@ -3240,7 +3291,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
@@ -3250,7 +3301,7 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
@@ -3267,17 +3318,17 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3317,7 +3368,7 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params)
GLenum nativeType;
unsigned int numParams = 0;
if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
if (numParams == 0)
return; // it is known that pname is valid, but there are no parameters to return
@@ -3363,7 +3414,7 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3381,7 +3432,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
if (!programObject)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (pname)
@@ -3417,13 +3468,13 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
*params = programObject->getProgramBinaryLength();
return;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3436,7 +3487,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -3447,7 +3498,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len
if (!programObject)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
programObject->getInfoLog(bufsize, length, infolog);
@@ -3455,7 +3506,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3470,7 +3521,7 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
case GL_CURRENT_QUERY_EXT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -3482,7 +3533,7 @@ void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3498,7 +3549,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
case GL_QUERY_RESULT_AVAILABLE_EXT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -3508,12 +3559,12 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
if (!queryObject)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (context->getActiveQuery(queryObject->getType()) == id)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch(pname)
@@ -3531,7 +3582,7 @@ void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3547,12 +3598,12 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
{
if (target != GL_RENDERBUFFER)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (context->getRenderbufferHandle() == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
@@ -3575,17 +3626,17 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3603,7 +3654,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
if (!shaderObject)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (pname)
@@ -3627,13 +3678,13 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
*params = shaderObject->getTranslatedSourceLength();
return;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3646,7 +3697,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -3657,7 +3708,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt
if (!shaderObject)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
shaderObject->getInfoLog(bufsize, length, infolog);
@@ -3665,7 +3716,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3682,7 +3733,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp
case GL_FRAGMENT_SHADER:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (precisiontype)
@@ -3705,12 +3756,12 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp
*precision = 0;
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3723,7 +3774,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -3734,7 +3785,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length
if (!shaderObject)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
shaderObject->getSource(bufsize, length, source);
@@ -3742,7 +3793,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3755,7 +3806,7 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize,
{
if (bufsize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -3766,7 +3817,7 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize,
if (!shaderObject)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
shaderObject->getTranslatedSource(bufsize, length, source);
@@ -3774,7 +3825,7 @@ void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3799,12 +3850,12 @@ const GLubyte* __stdcall glGetString(GLenum name)
case GL_EXTENSIONS:
return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
default:
- return error(GL_INVALID_ENUM, (GLubyte*)NULL);
+ return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL);
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
+ return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
}
}
@@ -3829,7 +3880,7 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
texture = context->getTextureCubeMap();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (pname)
@@ -3855,18 +3906,18 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->supportsTextureFilterAnisotropy())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
*params = (GLfloat)texture->getMaxAnisotropy();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3891,7 +3942,7 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
texture = context->getTextureCubeMap();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (pname)
@@ -3917,18 +3968,18 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->supportsTextureFilterAnisotropy())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
*params = (GLint)texture->getMaxAnisotropy();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3941,7 +3992,7 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
{
if (bufSize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -3950,31 +4001,31 @@ void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSiz
{
if (program == 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->getUniformfv(location, &bufSize, params))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -3990,31 +4041,31 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
if (program == 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->getUniformfv(location, NULL, params))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4027,7 +4078,7 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
{
if (bufSize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4036,31 +4087,31 @@ void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSiz
{
if (program == 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->getUniformiv(location, &bufSize, params))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4076,31 +4127,31 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
{
if (program == 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Program *programObject = context->getProgram(program);
if (!programObject || !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->getUniformiv(location, NULL, params))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4125,18 +4176,18 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION, -1);
+ return gl::error(GL_INVALID_OPERATION, -1);
}
else
{
- return error(GL_INVALID_VALUE, -1);
+ return gl::error(GL_INVALID_VALUE, -1);
}
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programObject->isLinked() || !programBinary)
{
- return error(GL_INVALID_OPERATION, -1);
+ return gl::error(GL_INVALID_OPERATION, -1);
}
return programBinary->getUniformLocation(name);
@@ -4144,7 +4195,7 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, -1);
+ return gl::error(GL_OUT_OF_MEMORY, -1);
}
return -1;
@@ -4162,7 +4213,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
@@ -4196,13 +4247,13 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
*params = (GLfloat)attribState.mDivisor;
break;
- default: return error(GL_INVALID_ENUM);
+ default: return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4218,7 +4269,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
@@ -4253,13 +4304,13 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE:
*params = (GLint)attribState.mDivisor;
break;
- default: return error(GL_INVALID_ENUM);
+ default: return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4275,12 +4326,12 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
@@ -4288,7 +4339,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4305,7 +4356,7 @@ void __stdcall glHint(GLenum target, GLenum mode)
case GL_DONT_CARE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -4318,12 +4369,12 @@ void __stdcall glHint(GLenum target, GLenum mode)
if (context) context->setFragmentShaderDerivativeHint(mode);
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4347,7 +4398,7 @@ GLboolean __stdcall glIsBuffer(GLuint buffer)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4375,13 +4426,13 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
case GL_BLEND: return context->isBlendEnabled();
case GL_DITHER: return context->isDitherEnabled();
default:
- return error(GL_INVALID_ENUM, false);
+ return gl::error(GL_INVALID_ENUM, false);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, false);
+ return gl::error(GL_OUT_OF_MEMORY, false);
}
return false;
@@ -4409,7 +4460,7 @@ GLboolean __stdcall glIsFenceNV(GLuint fence)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4435,7 +4486,7 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4461,7 +4512,7 @@ GLboolean __stdcall glIsProgram(GLuint program)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4492,7 +4543,7 @@ GLboolean __stdcall glIsQueryEXT(GLuint id)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4518,7 +4569,7 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4544,7 +4595,7 @@ GLboolean __stdcall glIsShader(GLuint shader)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4570,7 +4621,7 @@ GLboolean __stdcall glIsTexture(GLuint texture)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ return gl::error(GL_OUT_OF_MEMORY, GL_FALSE);
}
return GL_FALSE;
@@ -4584,7 +4635,7 @@ void __stdcall glLineWidth(GLfloat width)
{
if (width <= 0.0f)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4596,7 +4647,7 @@ void __stdcall glLineWidth(GLfloat width)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4616,11 +4667,11 @@ void __stdcall glLinkProgram(GLuint program)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -4629,7 +4680,7 @@ void __stdcall glLinkProgram(GLuint program)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4648,7 +4699,7 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
case GL_UNPACK_ALIGNMENT:
if (param != 1 && param != 2 && param != 4 && param != 8)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
context->setUnpackAlignment(param);
@@ -4657,7 +4708,7 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
case GL_PACK_ALIGNMENT:
if (param != 1 && param != 2 && param != 4 && param != 8)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
context->setPackAlignment(param);
@@ -4668,13 +4719,13 @@ void __stdcall glPixelStorei(GLenum pname, GLint param)
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4693,7 +4744,7 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4709,7 +4760,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
{
if (width < 0 || height < 0 || bufSize < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4726,7 +4777,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
context->readPixels(x, y, width, height, format, type, &bufSize, data);
@@ -4734,7 +4785,7 @@ void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4749,7 +4800,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
{
if (width < 0 || height < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4766,7 +4817,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
if (!(currentFormat == format && currentType == type) && !validReadFormatType(format, type))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
context->readPixels(x, y, width, height, format, type, NULL, pixels);
@@ -4774,7 +4825,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4788,7 +4839,7 @@ void __stdcall glReleaseShaderCompiler(void)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4804,17 +4855,17 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
case GL_RENDERBUFFER:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (width < 0 || height < 0 || samples < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4825,41 +4876,35 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
height > context->getMaximumRenderbufferDimension() ||
samples > context->getMaxSupportedSamples())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
GLuint handle = context->getRenderbufferHandle();
if (handle == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
- context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
- break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
case GL_RGB8_OES:
case GL_RGBA8_OES:
- context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
- break;
case GL_STENCIL_INDEX8:
- context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
- break;
case GL_DEPTH24_STENCIL8_OES:
- context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
+ context->setRenderbufferStorage(width, height, internalformat, samples);
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4883,7 +4928,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4895,7 +4940,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
{
if (condition != GL_ALL_COMPLETED_NV)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -4906,7 +4951,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
if (fenceObject == NULL)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
fenceObject->setFence(condition);
@@ -4914,7 +4959,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4926,7 +4971,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
if (width < 0 || height < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context* context = gl::getNonLostContext();
@@ -4938,7 +4983,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4951,11 +4996,11 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor
try
{
// No binary shader formats are supported.
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -4968,7 +5013,7 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** strin
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -4981,11 +5026,11 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** strin
{
if (context->getProgram(shader))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -4994,7 +5039,7 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** strin
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5016,7 +5061,7 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint
case GL_FRONT_AND_BACK:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (func)
@@ -5031,7 +5076,7 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint
case GL_NOTEQUAL:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -5051,7 +5096,7 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5073,7 +5118,7 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
case GL_FRONT_AND_BACK:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -5093,7 +5138,7 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5116,7 +5161,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
case GL_FRONT_AND_BACK:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (fail)
@@ -5131,7 +5176,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
case GL_DECR_WRAP:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (zfail)
@@ -5146,7 +5191,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
case GL_DECR_WRAP:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (zpass)
@@ -5161,7 +5206,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
case GL_DECR_WRAP:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -5181,7 +5226,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5199,7 +5244,7 @@ GLboolean __stdcall glTestFenceNV(GLuint fence)
if (fenceObject == NULL)
{
- return error(GL_INVALID_OPERATION, GL_TRUE);
+ return gl::error(GL_INVALID_OPERATION, GL_TRUE);
}
return fenceObject->testFence();
@@ -5207,7 +5252,7 @@ GLboolean __stdcall glTestFenceNV(GLuint fence)
}
catch(std::bad_alloc&)
{
- error(GL_OUT_OF_MEMORY);
+ gl::error(GL_OUT_OF_MEMORY);
}
return GL_TRUE;
@@ -5224,12 +5269,12 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{
if (!validImageSize(level, width, height))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (internalformat != GLint(format))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// validate <type> by itself (used as secondary key below)
@@ -5246,7 +5291,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_FLOAT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
// validate <format> + <type> combinations
@@ -5264,7 +5309,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_HALF_FLOAT_OES:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_RGB:
@@ -5276,7 +5321,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_HALF_FLOAT_OES:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_RGBA:
@@ -5289,7 +5334,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_HALF_FLOAT_OES:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_BGRA_EXT:
@@ -5298,7 +5343,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_BYTE:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
@@ -5313,7 +5358,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_INT:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
case GL_DEPTH_STENCIL_OES:
@@ -5322,16 +5367,16 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_INT_24_8_OES:
break;
default:
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (border != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -5340,7 +5385,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (target)
@@ -5349,7 +5394,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (width > (context->getMaximumTextureDimension() >> level) ||
height > (context->getMaximumTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
@@ -5360,17 +5405,17 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (width != height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (width > (context->getMaximumCubeTextureDimension() >> level) ||
height > (context->getMaximumCubeTextureDimension() >> level))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (format) {
@@ -5378,48 +5423,48 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (context->supportsDXT1Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (context->supportsDXT3Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (context->supportsDXT5Textures())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_DEPTH_COMPONENT:
case GL_DEPTH_STENCIL_OES:
if (!context->supportsDepthTextures())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// OES_depth_texture supports loading depth data and multiple levels,
// but ANGLE_depth_texture does not
if (pixels != NULL || level != 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
default:
@@ -5430,14 +5475,14 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{
if (!context->supportsFloat32Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
else if (type == GL_HALF_FLOAT_OES)
{
if (!context->supportsFloat16Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
@@ -5447,12 +5492,12 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels);
@@ -5463,12 +5508,12 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (!texture)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
switch (target)
@@ -5498,7 +5543,7 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5523,7 +5568,7 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
texture = context->getTextureCubeMap();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (pname)
@@ -5531,51 +5576,51 @@ void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
case GL_TEXTURE_WRAP_S:
if (!texture->setWrapS((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_WRAP_T:
if (!texture->setWrapT((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MIN_FILTER:
if (!texture->setMinFilter((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MAG_FILTER:
if (!texture->setMagFilter((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_USAGE_ANGLE:
if (!texture->setUsage((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->supportsTextureFilterAnisotropy())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5605,7 +5650,7 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
texture = context->getTextureCubeMap();
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
switch (pname)
@@ -5613,51 +5658,51 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
case GL_TEXTURE_WRAP_S:
if (!texture->setWrapS((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_WRAP_T:
if (!texture->setWrapT((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MIN_FILTER:
if (!texture->setMinFilter((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MAG_FILTER:
if (!texture->setMagFilter((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_USAGE_ANGLE:
if (!texture->setUsage((GLenum)param))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (!context->supportsTextureFilterAnisotropy())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (!texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()))
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5675,22 +5720,22 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
{
if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (width < 1 || height < 1 || levels < 1)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (target == GL_TEXTURE_CUBE_MAP && width != height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
GLenum format = gl::ExtractFormat(internalformat);
@@ -5698,7 +5743,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
if (format == GL_NONE || type == GL_NONE)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getNonLostContext();
@@ -5711,25 +5756,25 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
if (width > context->getMaximumTextureDimension() ||
height > context->getMaximumTextureDimension())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
case GL_TEXTURE_CUBE_MAP:
if (width > context->getMaximumCubeTextureDimension() ||
height > context->getMaximumCubeTextureDimension())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (levels != 1 && !context->supportsNonPower2Texture())
{
if (!gl::isPow2(width) || !gl::isPow2(height))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
@@ -5739,19 +5784,19 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
if (!context->supportsDXT1Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
if (!context->supportsDXT3Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
if (!context->supportsDXT5Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_RGBA32F_EXT:
@@ -5761,7 +5806,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
case GL_LUMINANCE_ALPHA32F_EXT:
if (!context->supportsFloat32Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_RGBA16F_EXT:
@@ -5771,7 +5816,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
case GL_LUMINANCE_ALPHA16F_EXT:
if (!context->supportsFloat16Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
break;
case GL_DEPTH_COMPONENT16:
@@ -5779,16 +5824,16 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
case GL_DEPTH24_STENCIL8_OES:
if (!context->supportsDepthTextures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// ANGLE_depth_texture only supports 1-level textures
if (levels != 1)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
break;
default:
@@ -5801,12 +5846,12 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
if (!texture || texture->id() == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->storage(levels, internalformat, width, height);
@@ -5817,12 +5862,12 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
if (!texture || texture->id() == 0)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (texture->isImmutable())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
texture->storage(levels, internalformat, width);
@@ -5832,7 +5877,7 @@ void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalf
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5848,17 +5893,17 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
{
if (!gl::IsInternalTextureTarget(target))
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (!checkTextureFormatType(format, type))
@@ -5872,35 +5917,35 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
{
if (level > context->getMaximumTextureLevel())
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (format == GL_FLOAT)
{
if (!context->supportsFloat32Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
else if (format == GL_HALF_FLOAT_OES)
{
if (!context->supportsFloat16Textures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
}
else if (gl::IsDepthTexture(format))
{
if (!context->supportsDepthTextures())
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
// OES_depth_texture supports loading depth data, but ANGLE_depth_texture does not
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (width == 0 || height == 0 || pixels == NULL)
@@ -5932,7 +5977,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5949,7 +5994,7 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -5964,18 +6009,18 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform1fv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -5992,7 +6037,7 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6007,18 +6052,18 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform1iv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6037,7 +6082,7 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6052,18 +6097,18 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform2fv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6082,7 +6127,7 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6097,18 +6142,18 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform2iv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6127,7 +6172,7 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6142,18 +6187,18 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform3fv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6172,7 +6217,7 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6187,18 +6232,18 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform3iv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6217,7 +6262,7 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6232,18 +6277,18 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform4fv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6262,7 +6307,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
{
if (count < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6277,18 +6322,18 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniform4iv(location, count, v))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6301,7 +6346,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
{
if (count < 0 || transpose != GL_FALSE)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6316,18 +6361,18 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix2fv(location, count, value))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6340,7 +6385,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
{
if (count < 0 || transpose != GL_FALSE)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6355,18 +6400,18 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix3fv(location, count, value))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6379,7 +6424,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
{
if (count < 0 || transpose != GL_FALSE)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (location == -1)
@@ -6394,18 +6439,18 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans
gl::ProgramBinary *programBinary = context->getCurrentProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->setUniformMatrix4fv(location, count, value))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
}
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6425,17 +6470,17 @@ void __stdcall glUseProgram(GLuint program)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
if (program != 0 && !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
context->useProgram(program);
@@ -6443,7 +6488,7 @@ void __stdcall glUseProgram(GLuint program)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6463,11 +6508,11 @@ void __stdcall glValidateProgram(GLuint program)
{
if (context->getShader(program))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
else
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
}
@@ -6476,7 +6521,7 @@ void __stdcall glValidateProgram(GLuint program)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6488,7 +6533,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6501,7 +6546,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6513,7 +6558,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6526,7 +6571,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6538,7 +6583,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6551,7 +6596,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6563,7 +6608,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6576,7 +6621,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6588,7 +6633,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6601,7 +6646,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6613,7 +6658,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6626,7 +6671,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6638,7 +6683,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6651,7 +6696,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6663,7 +6708,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6675,7 +6720,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6687,7 +6732,7 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6699,7 +6744,7 @@ void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6713,12 +6758,12 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
{
if (index >= gl::MAX_VERTEX_ATTRIBS)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (size < 1 || size > 4)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
switch (type)
@@ -6731,12 +6776,12 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
case GL_FLOAT:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if (stride < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6748,7 +6793,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6760,7 +6805,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
if (width < 0 || height < 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
gl::Context *context = gl::getNonLostContext();
@@ -6772,7 +6817,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6791,18 +6836,18 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
case GL_NEAREST:
break;
default:
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
{
- return error(GL_INVALID_VALUE);
+ return gl::error(GL_INVALID_VALUE);
}
if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
{
ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::Context *context = gl::getNonLostContext();
@@ -6812,7 +6857,7 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
{
ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
@@ -6820,7 +6865,7 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6838,7 +6883,7 @@ void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6858,19 +6903,19 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l
if (!programObject || !programObject->isLinked())
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
gl::ProgramBinary *programBinary = programObject->getProgramBinary();
if (!programBinary)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
if (!programBinary->save(binary, bufSize, length))
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
*binaryFormat = GL_PROGRAM_BINARY_ANGLE;
@@ -6878,7 +6923,7 @@ void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *l
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6896,14 +6941,14 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
{
if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ return gl::error(GL_INVALID_ENUM);
}
gl::Program *programObject = context->getProgram(program);
if (!programObject)
{
- return error(GL_INVALID_OPERATION);
+ return gl::error(GL_INVALID_OPERATION);
}
context->setProgramBinary(program, binary, length);
@@ -6911,7 +6956,63 @@ void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat,
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+}
+
+void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs)
+{
+ EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs);
+
+ try
+ {
+ gl::Context *context = gl::getNonLostContext();
+
+ if (context)
+ {
+ if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets())
+ {
+ return gl::error(GL_INVALID_VALUE);
+ }
+
+ if (context->getDrawFramebufferHandle() == 0)
+ {
+ if (n > 1)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ if (n == 1)
+ {
+ if (bufs[0] != GL_NONE && bufs[0] != GL_BACK)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+ }
+ }
+ else
+ {
+ for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+ {
+ const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment;
+ if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+ }
+ }
+
+ gl::Framebuffer *framebuffer = context->getDrawFramebuffer();
+
+ for (int colorAttachment = 0; colorAttachment < n; colorAttachment++)
+ {
+ framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]);
+ }
+ }
+ }
+ catch (std::bad_alloc&)
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
@@ -6948,13 +7049,14 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
{"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT},
{"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT},
{"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT},
+ {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT},
{"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE},
{"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE},
{"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE},
{"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES},
{"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, };
- for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
+ for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++)
{
if (strcmp(procname, glExtensions[ext].name) == 0)
{
@@ -6993,7 +7095,7 @@ bool __stdcall glBindTexImage(egl::Surface *surface)
}
catch(std::bad_alloc&)
{
- return error(GL_OUT_OF_MEMORY, false);
+ return gl::error(GL_OUT_OF_MEMORY, false);
}
return true;
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
index 5f935c3733..71398b3142 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.def
@@ -172,6 +172,7 @@ EXPORTS
glDrawElementsInstancedANGLE @174
glProgramBinaryOES @175
glGetProgramBinaryOES @176
+ glDrawBuffersEXT @179
; EGL dependencies
glCreateContext @144 NONAME
@@ -180,3 +181,5 @@ EXPORTS
glGetCurrentContext @147 NONAME
glGetProcAddress @148 NONAME
glBindTexImage @158 NONAME
+ glCreateRenderer @177 NONAME
+ glDestroyRenderer @178 NONAME \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
index c20864aa31..2b3b34009e 100644
--- a/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
+++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2d.def
@@ -180,3 +180,5 @@ EXPORTS
glGetCurrentContext @147 NONAME
glGetProcAddress @148 NONAME
glBindTexImage @158 NONAME
+ glCreateRenderer @177 NONAME
+ glDestroyRenderer @178 NONAME
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 3853e41c23..5d23e8e70f 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -7,12 +8,8 @@
// main.cpp: DLL entry point and management of thread-local data.
#include "libGLESv2/main.h"
-#include "libGLESv2/utilities.h"
-#include "common/debug.h"
-#include "libEGL/Surface.h"
-
-#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Context.h"
#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
@@ -101,7 +98,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
if (context && display && surface)
{
- context->makeCurrent(display, surface);
+ context->makeCurrent(surface);
}
}
@@ -118,7 +115,7 @@ Context *getNonLostContext()
{
if (context->isContextLost())
{
- error(GL_OUT_OF_MEMORY);
+ gl::error(GL_OUT_OF_MEMORY);
return NULL;
}
else
@@ -134,27 +131,6 @@ egl::Display *getDisplay()
return current()->display;
}
-IDirect3DDevice9 *getDevice()
-{
- egl::Display *display = getDisplay();
-
- return display->getDevice();
-}
-
-bool checkDeviceLost(HRESULT errorCode)
-{
- egl::Display *display = NULL;
-
- if (isDeviceLostError(errorCode))
- {
- display = gl::getDisplay();
- display->notifyDeviceLost();
- return true;
- }
- return false;
-}
-}
-
// Records an error code
void error(GLenum errorCode)
{
@@ -188,3 +164,6 @@ void error(GLenum errorCode)
}
}
}
+
+}
+
diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h
index 504848aa65..9168a2212e 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.h
+++ b/src/3rdparty/angle/src/libGLESv2/main.h
@@ -9,17 +9,19 @@
#ifndef LIBGLESV2_MAIN_H_
#define LIBGLESV2_MAIN_H_
-#define GL_APICALL
-#include <GLES2/gl2.h>
-#include <GLES2/gl2ext.h>
-
#include "common/debug.h"
-#include "libEGL/Display.h"
+#include "common/system.h"
-#include "libGLESv2/Context.h"
+namespace egl
+{
+class Display;
+class Surface;
+}
namespace gl
{
+class Context;
+
struct Current
{
Context *context;
@@ -32,11 +34,6 @@ Context *getContext();
Context *getNonLostContext();
egl::Display *getDisplay();
-IDirect3DDevice9 *getDevice();
-
-bool checkDeviceLost(HRESULT errorCode);
-}
-
void error(GLenum errorCode);
template<class T>
@@ -47,4 +44,25 @@ const T &error(GLenum errorCode, const T &returnValue)
return returnValue;
}
+}
+
+namespace rx
+{
+class Renderer;
+}
+
+extern "C"
+{
+// Exported functions for use by EGL
+gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess);
+void glDestroyContext(gl::Context *context);
+void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
+gl::Context *glGetCurrentContext();
+rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, bool softwareDevice);
+void glDestroyRenderer(rx::Renderer *renderer);
+
+__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname);
+bool __stdcall glBindTexImage(egl::Surface *surface);
+}
+
#endif // LIBGLESV2_MAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h
index 790ecd89fa..672c443c11 100644
--- a/src/3rdparty/angle/src/libGLESv2/mathutil.h
+++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h
@@ -9,9 +9,8 @@
#ifndef LIBGLESV2_MATHUTIL_H_
#define LIBGLESV2_MATHUTIL_H_
-#include <intrin.h>
-#include <math.h>
-#include <windows.h>
+#include "common/system.h"
+#include "common/debug.h"
namespace gl
{
@@ -54,7 +53,8 @@ inline unsigned int ceilPow2(unsigned int x)
template<typename T, typename MIN, typename MAX>
inline T clamp(T x, MIN min, MAX max)
{
- return x < min ? min : (x > max ? max : x);
+ // Since NaNs fail all comparison tests, a NaN value will default to min
+ return x > min ? (x > max ? max : x) : min;
}
inline float clamp01(float x)
@@ -142,4 +142,18 @@ float float16ToFloat32(unsigned short h);
}
+namespace rx
+{
+
+struct Range
+{
+ Range() {}
+ Range(int lo, int hi) : start(lo), end(hi) { ASSERT(lo <= hi); }
+
+ int start;
+ int end;
+};
+
+}
+
#endif // LIBGLESV2_MATHUTIL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.cpp b/src/3rdparty/angle/src/libGLESv2/precompiled.cpp
new file mode 100644
index 0000000000..2621cd6ce3
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/precompiled.cpp
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// precompiled.cpp: Precompiled header source file for libGLESv2.
+
+#include "precompiled.h"
diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
new file mode 100644
index 0000000000..b8b043c964
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// precompiled.h: Precompiled header file for libGLESv2.
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+#define EGLAPI
+#include <EGL/egl.h>
+
+#include <assert.h>
+#include <cstddef>
+#include <float.h>
+#include <intrin.h>
+#include <math.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <algorithm> // for std::min and std::max
+#include <limits>
+#include <map>
+#include <set>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#if defined(ANGLE_ENABLE_D3D11)
+# include <D3D11.h>
+# include <dxgi.h>
+#else
+# include <d3d9.h>
+#endif
+#include <D3Dcompiler.h>
+
+#ifdef _MSC_VER
+#include <hash_map>
+#endif
diff --git a/src/3rdparty/angle/src/libGLESv2/Blit.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp
index 28f3fbffbb..2a3ce39c63 100644
--- a/src/3rdparty/angle/src/libGLESv2/Blit.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp
@@ -1,3 +1,4 @@
+#include "precompiled.h"
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
@@ -6,20 +7,23 @@
// Blit.cpp: Surface copy utility class.
-#include "libGLESv2/Blit.h"
-
-#include "common/debug.h"
+#include "libGLESv2/renderer/Blit.h"
#include "libGLESv2/main.h"
-#include "libGLESv2/utilities.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/Renderer9.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
namespace
{
-#include "libGLESv2/shaders/standardvs.h"
-#include "libGLESv2/shaders/flipyvs.h"
-#include "libGLESv2/shaders/passthroughps.h"
-#include "libGLESv2/shaders/luminanceps.h"
-#include "libGLESv2/shaders/componentmaskps.h"
+#include "libGLESv2/renderer/shaders/compiled/standardvs.h"
+#include "libGLESv2/renderer/shaders/compiled/flipyvs.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughps.h"
+#include "libGLESv2/renderer/shaders/compiled/luminanceps.h"
+#include "libGLESv2/renderer/shaders/compiled/componentmaskps.h"
const BYTE* const g_shaderCode[] =
{
@@ -40,10 +44,10 @@ const size_t g_shaderSize[] =
};
}
-namespace gl
+namespace rx
{
-Blit::Blit(Context *context)
- : mContext(context), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL), mSavedStateBlock(NULL)
+Blit::Blit(rx::Renderer9 *renderer)
+ : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
{
initGeometry();
memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
@@ -74,14 +78,14 @@ void Blit::initGeometry()
1, 1
};
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
void *lockPtr = NULL;
@@ -90,7 +94,7 @@ void Blit::initGeometry()
if (FAILED(result) || lockPtr == NULL)
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
memcpy(lockPtr, quad, sizeof(quad));
@@ -107,17 +111,16 @@ void Blit::initGeometry()
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY);
+ return gl::error(GL_OUT_OF_MEMORY);
}
}
template <class D3DShaderType>
bool Blit::setShader(ShaderId source, const char *profile,
- D3DShaderType *(egl::Display::*createShader)(const DWORD *, size_t length),
+ D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
{
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = display->getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
D3DShaderType *shader;
@@ -130,7 +133,7 @@ bool Blit::setShader(ShaderId source, const char *profile,
const BYTE* shaderCode = g_shaderCode[source];
size_t shaderSize = g_shaderSize[source];
- shader = (display->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
+ shader = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize);
if (!shader)
{
ERR("Failed to create shader for blit operation");
@@ -153,12 +156,12 @@ bool Blit::setShader(ShaderId source, const char *profile,
bool Blit::setVertexShader(ShaderId shader)
{
- return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &egl::Display::createVertexShader, &IDirect3DDevice9::SetVertexShader);
+ return setShader<IDirect3DVertexShader9>(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader);
}
bool Blit::setPixelShader(ShaderId shader)
{
- return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &egl::Display::createPixelShader, &IDirect3DDevice9::SetPixelShader);
+ return setShader<IDirect3DPixelShader9>(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader);
}
RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
@@ -183,7 +186,7 @@ bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
return false;
}
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
saveState();
@@ -208,9 +211,86 @@ bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
return true;
}
+bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+ RenderTarget9 *renderTarget = NULL;
+ IDirect3DSurface9 *source = NULL;
+ gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+
+ if (colorbuffer)
+ {
+ renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+ }
+
+ if (renderTarget)
+ {
+ source = renderTarget->getSurface();
+ }
+
+ if (!source)
+ {
+ ERR("Failed to retrieve the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+ IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true);
+ bool result = false;
+
+ if (destSurface)
+ {
+ result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ destSurface->Release();
+ }
+
+ source->Release();
+ return result;
+}
+
+bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+ RenderTarget9 *renderTarget = NULL;
+ IDirect3DSurface9 *source = NULL;
+ gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+
+ if (colorbuffer)
+ {
+ renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+ }
+
+ if (renderTarget)
+ {
+ source = renderTarget->getSurface();
+ }
+
+ if (!source)
+ {
+ ERR("Failed to retrieve the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+ IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true);
+ bool result = false;
+
+ if (destSurface)
+ {
+ result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+ destSurface->Release();
+ }
+
+ source->Release();
+ return result;
+}
+
bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
- IDirect3DDevice9 *device = getDevice();
+ if (!dest)
+ {
+ return false;
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
D3DSURFACE_DESC sourceDesc;
D3DSURFACE_DESC destDesc;
@@ -218,7 +298,7 @@ bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFo
dest->GetDesc(&destDesc);
if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
- dx2es::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
+ d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
{
RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
@@ -226,14 +306,13 @@ bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFo
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY, false);
+ return gl::error(GL_OUT_OF_MEMORY, false);
}
}
else
{
return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
}
-
return true;
}
@@ -245,7 +324,7 @@ bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLen
return false;
}
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
saveState();
@@ -325,7 +404,7 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
break;
}
- getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
+ mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1);
return true;
}
@@ -337,8 +416,7 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
return NULL;
}
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
D3DSURFACE_DESC sourceDesc;
surface->GetDesc(&sourceDesc);
@@ -350,7 +428,7 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
}
IDirect3DSurface9 *textureSurface;
@@ -360,10 +438,10 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release();
- return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
}
- display->endScene();
+ mRenderer->endScene();
result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
textureSurface->Release();
@@ -372,7 +450,7 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
texture->Release();
- return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+ return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
}
return texture;
@@ -380,7 +458,7 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
{
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
D3DVIEWPORT9 vp;
vp.X = xoffset;
@@ -397,7 +475,7 @@ void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset)
void Blit::setCommonBlitState()
{
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
device->SetDepthStencilSurface(NULL);
@@ -419,7 +497,7 @@ void Blit::setCommonBlitState()
RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
device->SetScissorRect(&scissorRect);
- for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
{
device->SetStreamSourceFreq(i, 1);
}
@@ -427,19 +505,18 @@ void Blit::setCommonBlitState()
void Blit::render()
{
- egl::Display *display = getDisplay();
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
hr = device->SetVertexDeclaration(mQuadVertexDeclaration);
- display->startScene();
+ mRenderer->startScene();
hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
}
void Blit::saveState()
{
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
HRESULT hr;
@@ -491,7 +568,7 @@ void Blit::saveState()
void Blit::restoreState()
{
- IDirect3DDevice9 *device = getDevice();
+ IDirect3DDevice9 *device = mRenderer->getDevice();
device->SetDepthStencilSurface(mSavedDepthStencil);
if (mSavedDepthStencil != NULL)
diff --git a/src/3rdparty/angle/src/libGLESv2/Blit.h b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.h
index a9bb4956eb..3718028e66 100644
--- a/src/3rdparty/angle/src/libGLESv2/Blit.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.h
@@ -9,30 +9,29 @@
#ifndef LIBGLESV2_BLIT_H_
#define LIBGLESV2_BLIT_H_
-#include <map>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include <d3d9.h>
-
#include "common/angleutils.h"
-#include "libEGL/Display.h"
-
namespace gl
{
-class Context;
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer9;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
class Blit
{
public:
- explicit Blit(Context *context);
+ explicit Blit(Renderer9 *renderer);
~Blit();
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
- bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+ bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+ bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
@@ -44,7 +43,7 @@ class Blit
bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
private:
- Context *mContext;
+ rx::Renderer9 *mRenderer;
IDirect3DVertexBuffer9 *mQuadVertexBuffer;
IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;
@@ -53,6 +52,7 @@ class Blit
bool setFormatConvertShaders(GLenum destFormat);
+ bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect);
void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset);
void setCommonBlitState();
@@ -74,7 +74,7 @@ class Blit
template <class D3DShaderType>
bool setShader(ShaderId source, const char *profile,
- D3DShaderType *(egl::Display::*createShader)(const DWORD *, size_t length),
+ D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length),
HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
bool setVertexShader(ShaderId shader);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.cpp
new file mode 100644
index 0000000000..a49b7bab84
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.cpp
@@ -0,0 +1,40 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage.cpp Defines the abstract BufferStorage class.
+
+#include "libGLESv2/renderer/BufferStorage.h"
+
+namespace rx
+{
+
+unsigned int BufferStorage::mNextSerial = 1;
+
+BufferStorage::BufferStorage()
+{
+ updateSerial();
+}
+
+BufferStorage::~BufferStorage()
+{
+}
+
+unsigned int BufferStorage::getSerial() const
+{
+ return mSerial;
+}
+
+void BufferStorage::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+void BufferStorage::markBufferUsage()
+{
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
new file mode 100644
index 0000000000..ace1a11bae
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage.h Defines the abstract BufferStorage class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
+#define LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class BufferStorage
+{
+ public:
+ BufferStorage();
+ virtual ~BufferStorage();
+
+ // The data returned is only guaranteed valid until next non-const method.
+ virtual void *getData() = 0;
+ virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0;
+ virtual void clear() = 0;
+ virtual unsigned int getSize() const = 0;
+ virtual bool supportsDirectBinding() const = 0;
+ virtual void markBufferUsage();
+ unsigned int getSerial() const;
+
+ protected:
+ void updateSerial();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BufferStorage);
+
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
new file mode 100644
index 0000000000..7fe9e6b762
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
@@ -0,0 +1,352 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage11.cpp Defines the BufferStorage11 class.
+
+#include "libGLESv2/renderer/BufferStorage11.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+namespace rx
+{
+
+BufferStorage11::BufferStorage11(Renderer11 *renderer)
+{
+ mRenderer = renderer;
+
+ mStagingBuffer = NULL;
+ mStagingBufferSize = 0;
+
+ mBuffer = NULL;
+ mBufferSize = 0;
+
+ mSize = 0;
+
+ mResolvedData = NULL;
+ mResolvedDataSize = 0;
+ mResolvedDataValid = false;
+
+ mReadUsageCount = 0;
+ mWriteUsageCount = 0;
+}
+
+BufferStorage11::~BufferStorage11()
+{
+ if (mStagingBuffer)
+ {
+ mStagingBuffer->Release();
+ mStagingBuffer = NULL;
+ }
+
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ }
+
+ if (mResolvedData)
+ {
+ free(mResolvedData);
+ mResolvedData = NULL;
+ }
+}
+
+BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
+ return static_cast<BufferStorage11*>(bufferStorage);
+}
+
+void *BufferStorage11::getData()
+{
+ if (!mResolvedDataValid)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ HRESULT result;
+
+ if (!mStagingBuffer || mStagingBufferSize < mBufferSize)
+ {
+ if (mStagingBuffer)
+ {
+ mStagingBuffer->Release();
+ mStagingBuffer = NULL;
+ mStagingBufferSize = 0;
+ }
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = mSize;
+ bufferDesc.Usage = D3D11_USAGE_STAGING;
+ bufferDesc.BindFlags = 0;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ }
+
+ mStagingBufferSize = bufferDesc.ByteWidth;
+ }
+
+ if (!mResolvedData || mResolvedDataSize < mBufferSize)
+ {
+ free(mResolvedData);
+ mResolvedData = malloc(mSize);
+ mResolvedDataSize = mSize;
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = 0;
+ srcBox.right = mSize;
+ srcBox.top = 0;
+ srcBox.bottom = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ context->CopySubresourceRegion(mStagingBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+ }
+
+ memcpy(mResolvedData, mappedResource.pData, mSize);
+
+ context->Unmap(mStagingBuffer, 0);
+
+ mResolvedDataValid = true;
+ }
+
+ mReadUsageCount = 0;
+
+ return mResolvedData;
+}
+
+void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
+{
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+ HRESULT result;
+
+ unsigned int requiredBufferSize = size + offset;
+ unsigned int requiredStagingSize = size;
+ bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset);
+
+ if (!directInitialization)
+ {
+ if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize)
+ {
+ if (mStagingBuffer)
+ {
+ mStagingBuffer->Release();
+ mStagingBuffer = NULL;
+ mStagingBufferSize = 0;
+ }
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = size;
+ bufferDesc.Usage = D3D11_USAGE_STAGING;
+ bufferDesc.BindFlags = 0;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ D3D11_SUBRESOURCE_DATA initialData;
+ initialData.pSysMem = data;
+ initialData.SysMemPitch = size;
+ initialData.SysMemSlicePitch = 0;
+
+ result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ mStagingBufferSize = size;
+ }
+ else
+ {
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ if (data)
+ memcpy(mappedResource.pData, data, size);
+
+ context->Unmap(mStagingBuffer, 0);
+ }
+ }
+
+ if (!mBuffer || mBufferSize < size + offset)
+ {
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = requiredBufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DEFAULT;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.CPUAccessFlags = 0;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ if (directInitialization)
+ {
+ // Since the data will fill the entire buffer (being larger than the initial size and having
+ // no offset), the buffer can be initialized with the data so no staging buffer is required
+
+ // No longer need the old buffer
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ mBufferSize = 0;
+ }
+
+
+ if (data)
+ {
+ D3D11_SUBRESOURCE_DATA initialData;
+ initialData.pSysMem = data;
+ initialData.SysMemPitch = size;
+ initialData.SysMemSlicePitch = 0;
+
+ result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
+ }
+ else
+ {
+ result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ }
+
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+ else if (mBuffer && offset > 0)
+ {
+ // If offset is greater than zero and the buffer is non-null, need to preserve the data from
+ // the old buffer up to offset
+ ID3D11Buffer *newBuffer = NULL;
+
+ result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = 0;
+ srcBox.right = std::min(offset, mBufferSize);
+ srcBox.top = 0;
+ srcBox.bottom = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox);
+
+ mBuffer->Release();
+ mBuffer = newBuffer;
+ }
+ else
+ {
+ // Simple case, nothing needs to be copied from the old buffer to the new one, just create
+ // a new buffer
+
+ // No longer need the old buffer
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ mBufferSize = 0;
+ }
+
+ // Create a new buffer for data storage
+ result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ updateSerial();
+ mBufferSize = bufferDesc.ByteWidth;
+ }
+
+ if (!directInitialization)
+ {
+ ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize);
+
+ // Data is already put into the staging buffer, copy it over to the data buffer
+ D3D11_BOX srcBox;
+ srcBox.left = 0;
+ srcBox.right = size;
+ srcBox.top = 0;
+ srcBox.bottom = 1;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox);
+ }
+
+ mSize = std::max(mSize, offset + size);
+
+ mWriteUsageCount = 0;
+
+ mResolvedDataValid = false;
+}
+
+void BufferStorage11::clear()
+{
+ mResolvedDataValid = false;
+ mSize = 0;
+}
+
+unsigned int BufferStorage11::getSize() const
+{
+ return mSize;
+}
+
+bool BufferStorage11::supportsDirectBinding() const
+{
+ return true;
+}
+
+void BufferStorage11::markBufferUsage()
+{
+ mReadUsageCount++;
+ mWriteUsageCount++;
+
+ static const unsigned int usageLimit = 5;
+
+ if (mReadUsageCount > usageLimit && mResolvedData)
+ {
+ free(mResolvedData);
+ mResolvedData = NULL;
+ mResolvedDataSize = 0;
+ mResolvedDataValid = false;
+ }
+
+ if (mReadUsageCount > usageLimit && mWriteUsageCount > usageLimit && mStagingBuffer)
+ {
+ mStagingBuffer->Release();
+ mStagingBuffer = NULL;
+ mStagingBufferSize = 0;
+ }
+}
+
+ID3D11Buffer *BufferStorage11::getBuffer() const
+{
+ return mBuffer;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
new file mode 100644
index 0000000000..b62348b0c9
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage11.h Defines the BufferStorage11 class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
+#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
+
+#include "libGLESv2/renderer/BufferStorage.h"
+
+namespace rx
+{
+class Renderer11;
+
+class BufferStorage11 : public BufferStorage
+{
+ public:
+ explicit BufferStorage11(Renderer11 *renderer);
+ virtual ~BufferStorage11();
+
+ static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+ virtual void setData(const void* data, unsigned int size, unsigned int offset);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+ virtual void markBufferUsage();
+
+ ID3D11Buffer *getBuffer() const;
+
+ private:
+ Renderer11 *mRenderer;
+
+ ID3D11Buffer *mStagingBuffer;
+ unsigned int mStagingBufferSize;
+
+ ID3D11Buffer *mBuffer;
+ unsigned int mBufferSize;
+
+ unsigned int mSize;
+
+ void *mResolvedData;
+ unsigned int mResolvedDataSize;
+ bool mResolvedDataValid;
+
+ unsigned int mReadUsageCount;
+ unsigned int mWriteUsageCount;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
new file mode 100644
index 0000000000..4468461871
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
@@ -0,0 +1,76 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage9.cpp Defines the BufferStorage9 class.
+
+#include "libGLESv2/renderer/BufferStorage9.h"
+#include "common/debug.h"
+
+namespace rx
+{
+
+BufferStorage9::BufferStorage9()
+{
+ mMemory = NULL;
+ mAllocatedSize = 0;
+ mSize = 0;
+}
+
+BufferStorage9::~BufferStorage9()
+{
+ delete[] mMemory;
+}
+
+BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage));
+ return static_cast<BufferStorage9*>(bufferStorage);
+}
+
+void *BufferStorage9::getData()
+{
+ return mMemory;
+}
+
+void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset)
+{
+ if (!mMemory || offset + size > mAllocatedSize)
+ {
+ unsigned int newAllocatedSize = offset + size;
+ void *newMemory = new char[newAllocatedSize];
+
+ if (offset > 0 && mMemory && mAllocatedSize > 0)
+ {
+ memcpy(newMemory, mMemory, std::min(offset, mAllocatedSize));
+ }
+
+ delete[] mMemory;
+ mMemory = newMemory;
+ mAllocatedSize = newAllocatedSize;
+ }
+
+ mSize = std::max(mSize, offset + size);
+ if (data)
+ memcpy(reinterpret_cast<char*>(mMemory) + offset, data, size);
+}
+
+void BufferStorage9::clear()
+{
+ mSize = 0;
+}
+
+unsigned int BufferStorage9::getSize() const
+{
+ return mSize;
+}
+
+bool BufferStorage9::supportsDirectBinding() const
+{
+ return false;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
new file mode 100644
index 0000000000..3e803969bc
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h
@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage9.h Defines the BufferStorage9 class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
+#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
+
+#include "libGLESv2/renderer/BufferStorage.h"
+
+namespace rx
+{
+
+class BufferStorage9 : public BufferStorage
+{
+ public:
+ BufferStorage9();
+ virtual ~BufferStorage9();
+
+ static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
+
+ virtual void *getData();
+ virtual void setData(const void* data, unsigned int size, unsigned int offset);
+ virtual void clear();
+ virtual unsigned int getSize() const;
+ virtual bool supportsDirectBinding() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(BufferStorage9);
+
+ void *mMemory;
+ unsigned int mAllocatedSize;
+
+ unsigned int mSize;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp
new file mode 100644
index 0000000000..9d11c9a0fc
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp
@@ -0,0 +1,134 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
+
+#include "libGLESv2/renderer/Fence11.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+namespace rx
+{
+
+Fence11::Fence11(rx::Renderer11 *renderer)
+{
+ mRenderer = renderer;
+ mQuery = NULL;
+}
+
+Fence11::~Fence11()
+{
+ if (mQuery)
+ {
+ mQuery->Release();
+ mQuery = NULL;
+ }
+}
+
+GLboolean Fence11::isFence()
+{
+ // GL_NV_fence spec:
+ // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+ return mQuery != NULL;
+}
+
+void Fence11::setFence(GLenum condition)
+{
+ if (!mQuery)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ mRenderer->getDeviceContext()->End(mQuery);
+
+ setCondition(condition);
+ setStatus(GL_FALSE);
+}
+
+GLboolean Fence11::testFence()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+ }
+
+ HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0);
+
+ if (mRenderer->isDeviceLost())
+ {
+ return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ setStatus(result == S_OK);
+ return getStatus();
+}
+
+void Fence11::finishFence()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ while (!testFence())
+ {
+ Sleep(0);
+ }
+}
+
+void Fence11::getFenceiv(GLenum pname, GLint *params)
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ 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 (getStatus())
+ {
+ params[0] = GL_TRUE;
+ return;
+ }
+
+ HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+
+ if (mRenderer->isDeviceLost())
+ {
+ params[0] = GL_TRUE;
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ setStatus(result == S_OK);
+ params[0] = getStatus();
+
+ break;
+ }
+ case GL_FENCE_CONDITION_NV:
+ params[0] = getCondition();
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM);
+ break;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h
new file mode 100644
index 0000000000..a5398bca14
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl.
+
+#ifndef LIBGLESV2_RENDERER_Fence11_H_
+#define LIBGLESV2_RENDERER_Fence11_H_
+
+#include "libGLESv2/renderer/FenceImpl.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Fence11 : public FenceImpl
+{
+ public:
+ explicit Fence11(rx::Renderer11 *renderer);
+ virtual ~Fence11();
+
+ GLboolean isFence();
+ void setFence(GLenum condition);
+ GLboolean testFence();
+ void finishFence();
+ void getFenceiv(GLenum pname, GLint *params);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Fence11);
+
+ rx::Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FENCE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp
new file mode 100644
index 0000000000..86064d7e52
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp
@@ -0,0 +1,135 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence9.cpp: Defines the rx::Fence9 class.
+
+#include "libGLESv2/renderer/Fence9.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+namespace rx
+{
+
+Fence9::Fence9(rx::Renderer9 *renderer)
+{
+ mRenderer = renderer;
+ mQuery = NULL;
+}
+
+Fence9::~Fence9()
+{
+ if (mQuery)
+ {
+ mRenderer->freeEventQuery(mQuery);
+ mQuery = NULL;
+ }
+}
+
+GLboolean Fence9::isFence()
+{
+ // GL_NV_fence spec:
+ // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+ return mQuery != NULL;
+}
+
+void Fence9::setFence(GLenum condition)
+{
+ if (!mQuery)
+ {
+ mQuery = mRenderer->allocateEventQuery();
+ if (!mQuery)
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ HRESULT result = mQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+
+ setCondition(condition);
+ setStatus(GL_FALSE);
+}
+
+GLboolean Fence9::testFence()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+ }
+
+ HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ setStatus(result == S_OK);
+ return getStatus();
+}
+
+void Fence9::finishFence()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ while (!testFence())
+ {
+ Sleep(0);
+ }
+}
+
+void Fence9::getFenceiv(GLenum pname, GLint *params)
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ 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 (getStatus())
+ {
+ params[0] = GL_TRUE;
+ return;
+ }
+
+ HRESULT result = mQuery->GetData(NULL, 0, 0);
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ params[0] = GL_TRUE;
+ mRenderer->notifyDeviceLost();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ setStatus(result == S_OK);
+ params[0] = getStatus();
+
+ break;
+ }
+ case GL_FENCE_CONDITION_NV:
+ params[0] = getCondition();
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM);
+ break;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h
new file mode 100644
index 0000000000..9f17641e51
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl.
+
+#ifndef LIBGLESV2_RENDERER_FENCE9_H_
+#define LIBGLESV2_RENDERER_FENCE9_H_
+
+#include "libGLESv2/renderer/FenceImpl.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Fence9 : public FenceImpl
+{
+ public:
+ explicit Fence9(rx::Renderer9 *renderer);
+ virtual ~Fence9();
+
+ GLboolean isFence();
+ void setFence(GLenum condition);
+ GLboolean testFence();
+ void finishFence();
+ void getFenceiv(GLenum pname, GLint *params);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Fence9);
+
+ rx::Renderer9 *mRenderer;
+ IDirect3DQuery9 *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FENCE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
new file mode 100644
index 0000000000..d7f2102a2e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/FenceImpl.h
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// FenceImpl.h: Defines the rx::FenceImpl class.
+
+#ifndef LIBGLESV2_RENDERER_FENCEIMPL_H_
+#define LIBGLESV2_RENDERER_FENCEIMPL_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class FenceImpl
+{
+ public:
+ FenceImpl() : mStatus(GL_FALSE), mCondition(GL_NONE) { };
+ virtual ~FenceImpl() { };
+
+ virtual GLboolean isFence() = 0;
+ virtual void setFence(GLenum condition) = 0;
+ virtual GLboolean testFence() = 0;
+ virtual void finishFence() = 0;
+ virtual void getFenceiv(GLenum pname, GLint *params) = 0;
+
+ protected:
+ void setStatus(GLboolean status) { mStatus = status; }
+ GLboolean getStatus() const { return mStatus; }
+
+ void setCondition(GLuint condition) { mCondition = condition; }
+ GLuint getCondition() const { return mCondition; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FenceImpl);
+
+ GLboolean mStatus;
+ GLenum mCondition;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FENCEIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
new file mode 100644
index 0000000000..57239ef74f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.cpp
@@ -0,0 +1,548 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image.h: Implements the rx::Image class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#include "libGLESv2/renderer/Image.h"
+
+namespace rx
+{
+
+Image::Image()
+{
+ mWidth = 0;
+ mHeight = 0;
+ mInternalFormat = GL_NONE;
+ mActualFormat = GL_NONE;
+}
+
+void Image::loadAlphaDataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
+ }
+ }
+}
+
+void Image::loadAlphaDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ memcpy(dest, source, width);
+ }
+}
+
+void Image::loadAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
+ }
+ }
+}
+
+void Image::loadAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned short *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
+ }
+ }
+}
+
+void Image::loadLuminanceDataToNativeOrBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+
+ if (!native) // BGRA8 destination format
+ {
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x];
+ dest[4 * x + 1] = source[x];
+ dest[4 * x + 2] = source[x];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+ else // L8 destination format
+ {
+ memcpy(dest, source, width);
+ }
+ }
+}
+
+void Image::loadLuminanceFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x];
+ dest[4 * x + 1] = source[x];
+ dest[4 * x + 2] = source[x];
+ dest[4 * x + 3] = 1.0f;
+ }
+ }
+}
+
+void Image::loadLuminanceFloatDataToRGB(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[3 * x + 0] = source[x];
+ dest[3 * x + 1] = source[x];
+ dest[3 * x + 2] = source[x];
+ }
+ }
+}
+
+void Image::loadLuminanceHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned short *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x];
+ dest[4 * x + 1] = source[x];
+ dest[4 * x + 2] = source[x];
+ dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
+ }
+ }
+}
+
+void Image::loadLuminanceAlphaDataToNativeOrBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output, bool native)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+
+ if (!native) // BGRA8 destination format
+ {
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+ else
+ {
+ memcpy(dest, source, width * 2);
+ }
+ }
+}
+
+void Image::loadLuminanceAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+}
+
+void Image::loadLuminanceAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned short *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+}
+
+void Image::loadRGBUByteDataToBGRX(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 2];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 0];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
+
+void Image::loadRGBUByteDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 0];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 2];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
+
+void Image::loadRGB565DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
+ dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
+
+void Image::loadRGB565DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
+ dest[4 * x + 2] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
+
+void Image::loadRGBFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 0];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 2];
+ dest[4 * x + 3] = 1.0f;
+ }
+ }
+}
+
+void Image::loadRGBFloatDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ memcpy(dest, source, width * 12);
+ }
+}
+
+void Image::loadRGBHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned short *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned short*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 0];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 2];
+ dest[4 * x + 3] = 0x3C00; // SEEEEEMMMMMMMMMM, S = 0, E = 15, M = 0: 16bit flpt representation of 1
+ }
+ }
+}
+
+void Image::loadRGBAUByteDataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned int *source = NULL;
+ unsigned int *dest = NULL;
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
+
+ for (int x = 0; x < width; x++)
+ {
+ unsigned int rgba = source[x];
+ dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00);
+ }
+ }
+}
+
+void Image::loadRGBAUByteDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned int *source = NULL;
+ unsigned int *dest = NULL;
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + y * outputPitch);
+
+ memcpy(dest, source, width * 4);
+ }
+}
+
+void Image::loadRGBA4444DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
+ dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
+ dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
+ }
+ }
+}
+
+void Image::loadRGBA4444DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
+ dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
+ dest[4 * x + 2] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
+ dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
+ }
+ }
+}
+
+void Image::loadRGBA5551DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
+ dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
+ }
+ }
+}
+
+void Image::loadRGBA5551DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
+ dest[4 * x + 2] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
+ dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
+ }
+ }
+}
+
+void Image::loadRGBAFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const float *source = NULL;
+ float *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const float*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = reinterpret_cast<float*>(static_cast<unsigned char*>(output) + y * outputPitch);
+ memcpy(dest, source, width * 16);
+ }
+}
+
+void Image::loadRGBAHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ memcpy(dest, source, width * 8);
+ }
+}
+
+void Image::loadBGRADataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + y * outputPitch;
+ memcpy(dest, source, width*4);
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
new file mode 100644
index 0000000000..454e83e21e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image.h
@@ -0,0 +1,131 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image.h: Defines the rx::Image class, an abstract base class for the
+// renderer-specific classes which will define the interface to the underlying
+// surfaces or resources.
+
+#ifndef LIBGLESV2_RENDERER_IMAGE_H_
+#define LIBGLESV2_RENDERER_IMAGE_H_
+
+#include "common/debug.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Image
+{
+ public:
+ Image();
+ virtual ~Image() {};
+
+ GLsizei getWidth() const { return mWidth; }
+ GLsizei getHeight() const { return mHeight; }
+ GLenum getInternalFormat() const { return mInternalFormat; }
+ GLenum getActualFormat() const { return mActualFormat; }
+
+ void markDirty() {mDirty = true;}
+ void markClean() {mDirty = false;}
+ virtual bool isDirty() const = 0;
+
+ virtual void setManagedSurface(TextureStorageInterface2D *storage, int level) {};
+ virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) {};
+ virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
+ virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) = 0;
+
+ virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) = 0;
+
+ virtual bool isRenderableFormat() const = 0;
+
+ virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint unpackAlignment, const void *input) = 0;
+ virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ const void *input) = 0;
+
+ virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) = 0;
+
+ static void loadAlphaDataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadAlphaDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadAlphaDataToBGRASSE2(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadLuminanceDataToNativeOrBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output, bool native);
+ static void loadLuminanceFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadLuminanceFloatDataToRGB(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadLuminanceHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadLuminanceAlphaDataToNativeOrBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output, bool native);
+ static void loadLuminanceAlphaFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadLuminanceAlphaHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBUByteDataToBGRX(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBUByteDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGB565DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGB565DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBFloatDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBAUByteDataToBGRASSE2(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBAUByteDataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBAUByteDataToNative(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBA4444DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBA4444DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBA5551DataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBA5551DataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBAFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadRGBAHalfFloatDataToRGBA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+ static void loadBGRADataToBGRA(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output);
+
+ protected:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLint mInternalFormat;
+ GLenum mActualFormat;
+
+ bool mDirty;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Image);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
new file mode 100644
index 0000000000..8c78c7d750
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp
@@ -0,0 +1,457 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image11.h: Implements the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/renderer/Image11.h"
+#include "libGLESv2/renderer/TextureStorage11.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/utilities.h"
+#include "libGLESv2/renderer/renderer11_utils.h"
+#include "libGLESv2/renderer/generatemip.h"
+
+namespace rx
+{
+
+Image11::Image11()
+{
+ mStagingTexture = NULL;
+ mRenderer = NULL;
+ mDXGIFormat = DXGI_FORMAT_UNKNOWN;
+}
+
+Image11::~Image11()
+{
+ if (mStagingTexture)
+ {
+ mStagingTexture->Release();
+ }
+}
+
+Image11 *Image11::makeImage11(Image *img)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
+ return static_cast<rx::Image11*>(img);
+}
+
+void Image11::generateMipmap(Image11 *dest, Image11 *src)
+{
+ ASSERT(src->getDXGIFormat() == dest->getDXGIFormat());
+ ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth());
+ ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight());
+
+ D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped;
+ dest->map(&destMapped);
+ src->map(&srcMapped);
+
+ const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(srcMapped.pData);
+ unsigned char *destData = reinterpret_cast<unsigned char*>(destMapped.pData);
+
+ if (sourceData && destData)
+ {
+ switch (src->getDXGIFormat())
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ GenerateMip<R8G8B8A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_A8_UNORM:
+ GenerateMip<A8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R8_UNORM:
+ GenerateMip<R8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ GenerateMip<A32B32G32R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ GenerateMip<R32G32B32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ GenerateMip<A16B16G16R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R8G8_UNORM:
+ GenerateMip<R8G8>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R16_FLOAT:
+ GenerateMip<R16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R16G16_FLOAT:
+ GenerateMip<R16G16F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R32_FLOAT:
+ GenerateMip<R32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ case DXGI_FORMAT_R32G32_FLOAT:
+ GenerateMip<R32G32F>(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ dest->unmap();
+ src->unmap();
+ }
+
+ dest->markDirty();
+}
+
+bool Image11::isDirty() const
+{
+ return (mStagingTexture && mDirty);
+}
+
+bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+ TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
+ return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height);
+}
+
+bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+ TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
+ return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height);
+}
+
+bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
+{
+ if (mWidth != width ||
+ mHeight != height ||
+ mInternalFormat != internalformat ||
+ forceRelease)
+ {
+ mRenderer = Renderer11::makeRenderer11(renderer);
+
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = internalformat;
+ // compute the d3d format that will be used
+ mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
+
+ if (mStagingTexture)
+ {
+ mStagingTexture->Release();
+ mStagingTexture = NULL;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool Image11::isRenderableFormat() const
+{
+ return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat);
+}
+
+DXGI_FORMAT Image11::getDXGIFormat() const
+{
+ // this should only happen if the image hasn't been redefined first
+ // which would be a bug by the caller
+ ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
+
+ return mDXGIFormat;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
+// into the target pixel rectangle.
+void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint unpackAlignment, const void *input)
+{
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ HRESULT result = map(&mappedImage);
+ if (FAILED(result))
+ {
+ ERR("Could not map image for loading.");
+ return;
+ }
+
+ GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
+ size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8;
+ void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize));
+
+ switch (mInternalFormat)
+ {
+ case GL_ALPHA8_EXT:
+ loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE8_EXT:
+ loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+ break;
+ case GL_ALPHA32F_EXT:
+ loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE32F_EXT:
+ loadLuminanceFloatDataToRGB(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_ALPHA16F_EXT:
+ loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE16F_EXT:
+ loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+ break;
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGB8_OES:
+ loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGB565:
+ loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGBA8_OES:
+ loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGBA4:
+ loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGB5_A1:
+ loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_BGRA8_EXT:
+ loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGB32F_EXT:
+ loadRGBFloatDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGB16F_EXT:
+ loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGBA32F_EXT:
+ loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ case GL_RGBA16F_EXT:
+ loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+ break;
+ default: UNREACHABLE();
+ }
+
+ unmap();
+}
+
+void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ const void *input)
+{
+ ASSERT(xoffset % 4 == 0);
+ ASSERT(yoffset % 4 == 0);
+
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ HRESULT result = map(&mappedImage);
+ if (FAILED(result))
+ {
+ ERR("Could not map image for loading.");
+ return;
+ }
+
+ // Size computation assumes a 4x4 block compressed texture format
+ size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8;
+ void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize));
+
+ GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
+ GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
+ int rows = inputSize / inputPitch;
+ for (int i = 0; i < rows; ++i)
+ {
+ memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
+ }
+
+ unmap();
+}
+
+void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+ gl::Renderbuffer *colorbuffer = source->getReadColorbuffer();
+
+ if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat)
+ {
+ // No conversion needed-- use copyback fastpath
+ ID3D11Texture2D *colorBufferTexture = NULL;
+ unsigned int subresourceIndex = 0;
+
+ if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ {
+ D3D11_TEXTURE2D_DESC textureDesc;
+ colorBufferTexture->GetDesc(&textureDesc);
+
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ ID3D11Texture2D* srcTex = NULL;
+ if (textureDesc.SampleDesc.Count > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = textureDesc.Width;
+ resolveDesc.Height = textureDesc.Height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureDesc.Format;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ if (FAILED(result))
+ {
+ ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result);
+ return;
+ }
+
+ deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
+ subresourceIndex = 0;
+ }
+ else
+ {
+ srcTex = colorBufferTexture;
+ srcTex->AddRef();
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = x;
+ srcBox.right = x + width;
+ srcBox.top = y;
+ srcBox.bottom = y + height;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox);
+
+ srcTex->Release();
+ colorBufferTexture->Release();
+ }
+ }
+ else
+ {
+ // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
+ D3D11_MAPPED_SUBRESOURCE mappedImage;
+ HRESULT result = map(&mappedImage);
+
+ // determine the offset coordinate into the destination buffer
+ GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset;
+ void *dataOffset = static_cast<unsigned char*>(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset;
+
+ mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat),
+ gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset);
+
+ unmap();
+ }
+}
+
+ID3D11Texture2D *Image11::getStagingTexture()
+{
+ createStagingTexture();
+
+ return mStagingTexture;
+}
+
+unsigned int Image11::getStagingSubresource()
+{
+ createStagingTexture();
+
+ return mStagingSubresource;
+}
+
+void Image11::createStagingTexture()
+{
+ if (mStagingTexture)
+ {
+ return;
+ }
+
+ ID3D11Texture2D *newTexture = NULL;
+ int lodOffset = 1;
+ const DXGI_FORMAT dxgiFormat = getDXGIFormat();
+ ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures
+
+ if (mWidth != 0 && mHeight != 0)
+ {
+ GLsizei width = mWidth;
+ GLsizei height = mHeight;
+
+ // adjust size if needed for compressed textures
+ gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset);
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = lodOffset + 1;
+ desc.ArraySize = 1;
+ desc.Format = dxgiFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_STAGING;
+ desc.BindFlags = 0;
+ desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ ERR("Creating image failed.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ mStagingTexture = newTexture;
+ mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+ mDirty = false;
+}
+
+HRESULT Image11::map(D3D11_MAPPED_SUBRESOURCE *map)
+{
+ createStagingTexture();
+
+ HRESULT result = E_FAIL;
+
+ if (mStagingTexture)
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ result = deviceContext->Map(mStagingTexture, mStagingSubresource, D3D11_MAP_WRITE, 0, map);
+
+ // this can fail if the device is removed (from TDR)
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ }
+ else if (SUCCEEDED(result))
+ {
+ mDirty = true;
+ }
+ }
+
+ return result;
+}
+
+void Image11::unmap()
+{
+ if (mStagingTexture)
+ {
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ deviceContext->Unmap(mStagingTexture, mStagingSubresource);
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h
new file mode 100644
index 0000000000..4d5f1c1780
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h
@@ -0,0 +1,76 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image11.h: Defines the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#ifndef LIBGLESV2_RENDERER_IMAGE11_H_
+#define LIBGLESV2_RENDERER_IMAGE11_H_
+
+#include "libGLESv2/renderer/Image.h"
+
+#include "common/debug.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Image11 : public Image
+{
+ public:
+ Image11();
+ virtual ~Image11();
+
+ static Image11 *makeImage11(Image *img);
+
+ static void generateMipmap(Image11 *dest, Image11 *src);
+
+ virtual bool isDirty() const;
+
+ virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
+
+ virtual bool isRenderableFormat() const;
+ DXGI_FORMAT getDXGIFormat() const;
+
+ virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint unpackAlignment, const void *input);
+ virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ const void *input);
+
+ virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+
+ protected:
+ HRESULT map(D3D11_MAPPED_SUBRESOURCE *map);
+ void unmap();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Image11);
+
+ ID3D11Texture2D *getStagingTexture();
+ unsigned int getStagingSubresource();
+ void createStagingTexture();
+
+ Renderer11 *mRenderer;
+
+ DXGI_FORMAT mDXGIFormat;
+ ID3D11Texture2D *mStagingTexture;
+ unsigned int mStagingSubresource;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp
new file mode 100644
index 0000000000..53030b7f1e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp
@@ -0,0 +1,736 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#include "libGLESv2/renderer/Image9.h"
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/renderer/Renderer9.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/generatemip.h"
+
+namespace rx
+{
+
+Image9::Image9()
+{
+ mSurface = NULL;
+ mRenderer = NULL;
+
+ mD3DPool = D3DPOOL_SYSTEMMEM;
+ mD3DFormat = D3DFMT_UNKNOWN;
+}
+
+Image9::~Image9()
+{
+ if (mSurface)
+ {
+ mSurface->Release();
+ }
+}
+
+void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
+{
+ D3DSURFACE_DESC destDesc;
+ HRESULT result = destSurface->GetDesc(&destDesc);
+ ASSERT(SUCCEEDED(result));
+
+ D3DSURFACE_DESC sourceDesc;
+ result = sourceSurface->GetDesc(&sourceDesc);
+ ASSERT(SUCCEEDED(result));
+
+ ASSERT(sourceDesc.Format == destDesc.Format);
+ ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
+ ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
+
+ D3DLOCKED_RECT sourceLocked = {0};
+ result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY);
+ ASSERT(SUCCEEDED(result));
+
+ D3DLOCKED_RECT destLocked = {0};
+ result = destSurface->LockRect(&destLocked, NULL, 0);
+ ASSERT(SUCCEEDED(result));
+
+ const unsigned char *sourceData = reinterpret_cast<const unsigned char*>(sourceLocked.pBits);
+ unsigned char *destData = reinterpret_cast<unsigned char*>(destLocked.pBits);
+
+ if (sourceData && destData)
+ {
+ switch (sourceDesc.Format)
+ {
+ case D3DFMT_L8:
+ GenerateMip<L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+ break;
+ case D3DFMT_A8L8:
+ GenerateMip<A8L8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+ break;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ GenerateMip<A8R8G8B8>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+ break;
+ case D3DFMT_A16B16G16R16F:
+ GenerateMip<A16B16G16R16F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+ break;
+ case D3DFMT_A32B32G32R32F:
+ GenerateMip<A32B32G32R32F>(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ destSurface->UnlockRect();
+ sourceSurface->UnlockRect();
+ }
+}
+
+Image9 *Image9::makeImage9(Image *img)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img));
+ return static_cast<rx::Image9*>(img);
+}
+
+void Image9::generateMipmap(Image9 *dest, Image9 *source)
+{
+ IDirect3DSurface9 *sourceSurface = source->getSurface();
+ if (sourceSurface == NULL)
+ return gl::error(GL_OUT_OF_MEMORY);
+
+ IDirect3DSurface9 *destSurface = dest->getSurface();
+ generateMip(destSurface, sourceSurface);
+
+ dest->markDirty();
+}
+
+void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
+{
+ D3DLOCKED_RECT sourceLock = {0};
+ D3DLOCKED_RECT destLock = {0};
+
+ source->LockRect(&sourceLock, NULL, 0);
+ dest->LockRect(&destLock, NULL, 0);
+
+ if (sourceLock.pBits && destLock.pBits)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
+
+ int rows = d3d9::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height;
+ int bytes = d3d9::ComputeRowSize(desc.Format, desc.Width);
+ ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch);
+
+ for(int i = 0; i < rows; i++)
+ {
+ memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
+ }
+
+ source->UnlockRect();
+ dest->UnlockRect();
+ }
+ else UNREACHABLE();
+}
+
+bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
+{
+ if (mWidth != width ||
+ mHeight != height ||
+ mInternalFormat != internalformat ||
+ forceRelease)
+ {
+ mRenderer = Renderer9::makeRenderer9(renderer);
+
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = internalformat;
+ // compute the d3d format that will be used
+ mD3DFormat = mRenderer->ConvertTextureInternalFormat(internalformat);
+ mActualFormat = d3d9_gl::GetEquivalentFormat(mD3DFormat);
+
+ if (mSurface)
+ {
+ mSurface->Release();
+ mSurface = NULL;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+void Image9::createSurface()
+{
+ if(mSurface)
+ {
+ return;
+ }
+
+ IDirect3DTexture9 *newTexture = NULL;
+ IDirect3DSurface9 *newSurface = NULL;
+ const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
+ const D3DFORMAT d3dFormat = getD3DFormat();
+ ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures
+
+ if (mWidth != 0 && mHeight != 0)
+ {
+ int levelToFetch = 0;
+ GLsizei requestWidth = mWidth;
+ GLsizei requestHeight = mHeight;
+ gl::MakeValidSize(true, gl::IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch);
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat,
+ poolToUse, &newTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ ERR("Creating image surface failed.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
+ newTexture->Release();
+ }
+
+ mSurface = newSurface;
+ mDirty = false;
+ mD3DPool = poolToUse;
+}
+
+HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
+{
+ createSurface();
+
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ if (mSurface)
+ {
+ result = mSurface->LockRect(lockedRect, rect, 0);
+ ASSERT(SUCCEEDED(result));
+
+ mDirty = true;
+ }
+
+ return result;
+}
+
+void Image9::unlock()
+{
+ if (mSurface)
+ {
+ HRESULT result = mSurface->UnlockRect();
+ ASSERT(SUCCEEDED(result));
+ }
+}
+
+bool Image9::isRenderableFormat() const
+{
+ return TextureStorage9::IsTextureFormatRenderable(getD3DFormat());
+}
+
+D3DFORMAT Image9::getD3DFormat() const
+{
+ // this should only happen if the image hasn't been redefined first
+ // which would be a bug by the caller
+ ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
+
+ return mD3DFormat;
+}
+
+IDirect3DSurface9 *Image9::getSurface()
+{
+ createSurface();
+
+ return mSurface;
+}
+
+void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level)
+{
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+ setManagedSurface(storage9->getSurfaceLevel(level, false));
+}
+
+void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level)
+{
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+ setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+}
+
+void Image9::setManagedSurface(IDirect3DSurface9 *surface)
+{
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+ ASSERT(desc.Pool == D3DPOOL_MANAGED);
+
+ if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight)
+ {
+ if (mSurface)
+ {
+ copyLockableSurfaces(surface, mSurface);
+ mSurface->Release();
+ }
+
+ mSurface = surface;
+ mD3DPool = desc.Pool;
+ }
+}
+
+bool Image9::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+ ASSERT(getSurface() != NULL);
+ TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance());
+ return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+}
+
+bool Image9::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+ ASSERT(getSurface() != NULL);
+ TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance());
+ return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
+}
+
+bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+ if (!destSurface)
+ return false;
+
+ IDirect3DSurface9 *sourceSurface = getSurface();
+
+ if (sourceSurface && sourceSurface != destSurface)
+ {
+ RECT rect;
+ rect.left = xoffset;
+ rect.top = yoffset;
+ rect.right = xoffset + width;
+ rect.bottom = yoffset + height;
+
+ POINT point = {rect.left, rect.top};
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ if (mD3DPool == D3DPOOL_MANAGED)
+ {
+ D3DSURFACE_DESC desc;
+ sourceSurface->GetDesc(&desc);
+
+ IDirect3DSurface9 *surf = 0;
+ HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+
+ if (SUCCEEDED(result))
+ {
+ copyLockableSurfaces(surf, sourceSurface);
+ result = device->UpdateSurface(surf, &rect, destSurface, &point);
+ ASSERT(SUCCEEDED(result));
+ surf->Release();
+ }
+ }
+ else
+ {
+ // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools
+ HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point);
+ ASSERT(SUCCEEDED(result));
+ }
+ }
+
+ destSurface->Release();
+ return true;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
+// into the target pixel rectangle.
+void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint unpackAlignment, const void *input)
+{
+ RECT lockRect =
+ {
+ xoffset, yoffset,
+ xoffset + width, yoffset + height
+ };
+
+ D3DLOCKED_RECT locked;
+ HRESULT result = lock(&locked, &lockRect);
+ if (FAILED(result))
+ {
+ return;
+ }
+
+
+ GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
+
+ switch (mInternalFormat)
+ {
+ case GL_ALPHA8_EXT:
+#if defined(__SSE2__)
+ if (gl::supportsSSE2())
+ {
+ loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ }
+ else
+#endif
+ {
+ loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ }
+ break;
+ case GL_LUMINANCE8_EXT:
+ loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
+ break;
+ case GL_ALPHA32F_EXT:
+ loadAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_LUMINANCE32F_EXT:
+ loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_ALPHA16F_EXT:
+ loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_LUMINANCE16F_EXT:
+ loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
+ break;
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGB8_OES:
+ loadRGBUByteDataToBGRX(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGB565:
+ loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGBA8_OES:
+#if defined(__SSE2__)
+ if (gl::supportsSSE2())
+ {
+ loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ }
+ else
+#endif
+ {
+ loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ }
+ break;
+ case GL_RGBA4:
+ loadRGBA4444DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGB5_A1:
+ loadRGBA5551DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_BGRA8_EXT:
+ loadBGRADataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+ case GL_RGB32F_EXT:
+ loadRGBFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGB16F_EXT:
+ loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGBA32F_EXT:
+ loadRGBAFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ case GL_RGBA16F_EXT:
+ loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ break;
+ default: UNREACHABLE();
+ }
+
+ unlock();
+}
+
+void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ const void *input)
+{
+ ASSERT(xoffset % 4 == 0);
+ ASSERT(yoffset % 4 == 0);
+
+ RECT lockRect = {
+ xoffset, yoffset,
+ xoffset + width, yoffset + height
+ };
+
+ D3DLOCKED_RECT locked;
+ HRESULT result = lock(&locked, &lockRect);
+ if (FAILED(result))
+ {
+ return;
+ }
+
+ GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
+ GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
+ int rows = inputSize / inputPitch;
+ for (int i = 0; i < rows; ++i)
+ {
+ memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
+ }
+
+ unlock();
+}
+
+// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
+void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+ RenderTarget9 *renderTarget = NULL;
+ IDirect3DSurface9 *surface = NULL;
+ gl::Renderbuffer *colorbuffer = source->getColorbuffer(0);
+
+ if (colorbuffer)
+ {
+ renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+ }
+
+ if (renderTarget)
+ {
+ surface = renderTarget->getSurface();
+ }
+
+ if (!surface)
+ {
+ ERR("Failed to retrieve the render target.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ IDirect3DSurface9 *renderTargetData = NULL;
+ D3DSURFACE_DESC description;
+ surface->GetDesc(&description);
+
+ HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL);
+
+ if (FAILED(result))
+ {
+ ERR("Could not create matching destination surface.");
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ result = device->GetRenderTargetData(surface, renderTargetData);
+
+ if (FAILED(result))
+ {
+ ERR("GetRenderTargetData unexpectedly failed.");
+ renderTargetData->Release();
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ RECT sourceRect = {x, y, x + width, y + height};
+ RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+
+ D3DLOCKED_RECT sourceLock = {0};
+ result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
+
+ if (FAILED(result))
+ {
+ ERR("Failed to lock the source surface (rectangle might be invalid).");
+ renderTargetData->Release();
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ D3DLOCKED_RECT destLock = {0};
+ result = lock(&destLock, &destRect);
+
+ if (FAILED(result))
+ {
+ ERR("Failed to lock the destination surface (rectangle might be invalid).");
+ renderTargetData->UnlockRect();
+ renderTargetData->Release();
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ if (destLock.pBits && sourceLock.pBits)
+ {
+ unsigned char *source = (unsigned char*)sourceLock.pBits;
+ unsigned char *dest = (unsigned char*)destLock.pBits;
+
+ switch (description.Format)
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ switch(getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ for(int y = 0; y < height; y++)
+ {
+ memcpy(dest, source, 4 * width);
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ dest[x] = source[x * 4 + 2];
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ dest[x * 2 + 0] = source[x * 4 + 2];
+ dest[x * 2 + 1] = source[x * 4 + 3];
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_R5G6B5:
+ switch(getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned short rgb = ((unsigned short*)source)[x];
+ unsigned char red = (rgb & 0xF800) >> 8;
+ unsigned char green = (rgb & 0x07E0) >> 3;
+ unsigned char blue = (rgb & 0x001F) << 3;
+ dest[x + 0] = blue | (blue >> 5);
+ dest[x + 1] = green | (green >> 6);
+ dest[x + 2] = red | (red >> 5);
+ dest[x + 3] = 0xFF;
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned char red = source[x * 2 + 1] & 0xF8;
+ dest[x] = red | (red >> 5);
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ case D3DFMT_A1R5G5B5:
+ switch(getD3DFormat())
+ {
+ case D3DFMT_X8R8G8B8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned short argb = ((unsigned short*)source)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ dest[x + 0] = blue | (blue >> 5);
+ dest[x + 1] = green | (green >> 5);
+ dest[x + 2] = red | (red >> 5);
+ dest[x + 3] = 0xFF;
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8R8G8B8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned short argb = ((unsigned short*)source)[x];
+ unsigned char red = (argb & 0x7C00) >> 7;
+ unsigned char green = (argb & 0x03E0) >> 2;
+ unsigned char blue = (argb & 0x001F) << 3;
+ unsigned char alpha = (signed short)argb >> 15;
+ dest[x + 0] = blue | (blue >> 5);
+ dest[x + 1] = green | (green >> 5);
+ dest[x + 2] = red | (red >> 5);
+ dest[x + 3] = alpha;
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_L8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned char red = source[x * 2 + 1] & 0x7C;
+ dest[x] = (red << 1) | (red >> 4);
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ case D3DFMT_A8L8:
+ for(int y = 0; y < height; y++)
+ {
+ for(int x = 0; x < width; x++)
+ {
+ unsigned char red = source[x * 2 + 1] & 0x7C;
+ dest[x * 2 + 0] = (red << 1) | (red >> 4);
+ dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7;
+ }
+
+ source += sourceLock.Pitch;
+ dest += destLock.Pitch;
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ unlock();
+ renderTargetData->UnlockRect();
+
+ renderTargetData->Release();
+ surface->Release();
+
+ mDirty = true;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h
new file mode 100644
index 0000000000..2fbbca3124
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h
@@ -0,0 +1,79 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image9.h: Defines the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#ifndef LIBGLESV2_RENDERER_IMAGE9_H_
+#define LIBGLESV2_RENDERER_IMAGE9_H_
+
+#include "libGLESv2/renderer/Image.h"
+#include "common/debug.h"
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class Renderer9;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Image9 : public Image
+{
+ public:
+ Image9();
+ ~Image9();
+
+ static Image9 *makeImage9(Image *img);
+
+ static void generateMipmap(Image9 *dest, Image9 *source);
+ static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
+ static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
+
+ virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
+
+ virtual bool isRenderableFormat() const;
+ D3DFORMAT getD3DFormat() const;
+
+ virtual bool isDirty() const {return mSurface && mDirty;}
+ IDirect3DSurface9 *getSurface();
+
+ virtual void setManagedSurface(TextureStorageInterface2D *storage, int level);
+ virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level);
+ virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+ virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ GLint unpackAlignment, const void *input);
+ virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ const void *input);
+
+ virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Image9);
+
+ void createSurface();
+ void setManagedSurface(IDirect3DSurface9 *surface);
+ bool updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
+ void unlock();
+
+ Renderer9 *mRenderer;
+
+ D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
+ D3DFORMAT mD3DFormat;
+
+ IDirect3DSurface9 *mSurface;
+};
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/TextureSSE2.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ImageSSE2.cpp
index 48ea6643bc..b2a90ca961 100644
--- a/src/3rdparty/angle/src/libGLESv2/TextureSSE2.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ImageSSE2.cpp
@@ -1,22 +1,22 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-// TextureSSE2.cpp: Implements SSE2-based functions of gl::Image class. It's
+// ImageSSE2.cpp: Implements SSE2-based functions of rx::Image class. It's
// in a separated file for GCC, which can enable SSE usage only per-file,
// not for code blocks that use SSE2 explicitly.
#include "libGLESv2/Texture.h"
+#include "libGLESv2/renderer/Image.h"
-#include <intrin.h>
-
-namespace gl
+namespace rx
{
-void Image::loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
+void Image::loadRGBAUByteDataToBGRASSE2(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
{
const unsigned int *source = NULL;
unsigned int *dest = NULL;
@@ -57,8 +57,8 @@ void Image::loadRGBAUByteDataSSE2(GLsizei width, GLsizei height,
}
}
-void Image::loadAlphaDataSSE2(GLsizei width, GLsizei height,
- int inputPitch, const void *input, size_t outputPitch, void *output) const
+void Image::loadAlphaDataToBGRASSE2(GLsizei width, GLsizei height,
+ int inputPitch, const void *input, size_t outputPitch, void *output)
{
const unsigned char *source = NULL;
unsigned int *dest = NULL;
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp
new file mode 100644
index 0000000000..16fd782315
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.cpp
@@ -0,0 +1,202 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
+// class with derivations, classes that perform graphics API agnostic index buffer operations.
+
+#include "libGLESv2/renderer/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
+
+namespace rx
+{
+
+unsigned int IndexBuffer::mNextSerial = 1;
+
+IndexBuffer::IndexBuffer()
+{
+ updateSerial();
+}
+
+IndexBuffer::~IndexBuffer()
+{
+}
+
+unsigned int IndexBuffer::getSerial() const
+{
+ return mSerial;
+}
+
+void IndexBuffer::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+
+IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
+{
+ mIndexBuffer = renderer->createIndexBuffer();
+
+ mDynamic = dynamic;
+ mWritePosition = 0;
+}
+
+IndexBufferInterface::~IndexBufferInterface()
+{
+ if (mIndexBuffer)
+ {
+ delete mIndexBuffer;
+ }
+}
+
+GLenum IndexBufferInterface::getIndexType() const
+{
+ return mIndexBuffer->getIndexType();
+}
+
+unsigned int IndexBufferInterface::getBufferSize() const
+{
+ return mIndexBuffer->getBufferSize();
+}
+
+unsigned int IndexBufferInterface::getSerial() const
+{
+ return mIndexBuffer->getSerial();
+}
+
+int IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory)
+{
+ if (!mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory))
+ {
+ *outMappedMemory = NULL;
+ return -1;
+ }
+
+ int oldWritePos = static_cast<int>(mWritePosition);
+ mWritePosition += size;
+
+ return oldWritePos;
+}
+
+bool IndexBufferInterface::unmapBuffer()
+{
+ return mIndexBuffer->unmapBuffer();
+}
+
+IndexBuffer * IndexBufferInterface::getIndexBuffer() const
+{
+ return mIndexBuffer;
+}
+
+unsigned int IndexBufferInterface::getWritePosition() const
+{
+ return mWritePosition;
+}
+
+void IndexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+ mWritePosition = writePosition;
+}
+
+bool IndexBufferInterface::discard()
+{
+ return mIndexBuffer->discard();
+}
+
+bool IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
+{
+ if (mIndexBuffer->getBufferSize() == 0)
+ {
+ return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
+ }
+ else
+ {
+ return mIndexBuffer->setSize(bufferSize, indexType);
+ }
+}
+
+StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
+{
+}
+
+StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
+{
+}
+
+bool StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
+{
+ bool result = true;
+ unsigned int curBufferSize = getBufferSize();
+ if (size > curBufferSize)
+ {
+ result = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
+ setWritePosition(0);
+ }
+ else if (getWritePosition() + size > curBufferSize)
+ {
+ if (!discard())
+ {
+ return false;
+ }
+ setWritePosition(0);
+ }
+
+ return result;
+}
+
+
+StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
+{
+}
+
+StaticIndexBufferInterface::~StaticIndexBufferInterface()
+{
+}
+
+bool StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
+{
+ unsigned int curSize = getBufferSize();
+ if (curSize == 0)
+ {
+ return setBufferSize(size, indexType);
+ }
+ else if (curSize >= size && indexType == getIndexType())
+ {
+ return true;
+ }
+ else
+ {
+ ERR("Static index buffers can't be resized");
+ UNREACHABLE();
+ return false;
+ }
+}
+
+unsigned int StaticIndexBufferInterface::lookupRange(intptr_t offset, GLsizei count, unsigned int *minIndex, unsigned int *maxIndex)
+{
+ IndexRange range = {offset, count};
+
+ std::map<IndexRange, IndexResult>::iterator res = mCache.find(range);
+
+ if (res == mCache.end())
+ {
+ return -1;
+ }
+
+ *minIndex = res->second.minIndex;
+ *maxIndex = res->second.maxIndex;
+ return res->second.streamOffset;
+}
+
+void StaticIndexBufferInterface::addRange(intptr_t offset, GLsizei count, unsigned int minIndex, unsigned int maxIndex, unsigned int streamOffset)
+{
+ IndexRange indexRange = {offset, count};
+ IndexResult indexResult = {minIndex, maxIndex, streamOffset};
+ mCache[indexRange] = indexResult;
+}
+
+}
+
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h
new file mode 100644
index 0000000000..1afbd626fa
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer.h
@@ -0,0 +1,137 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer.h: Defines the abstract IndexBuffer class and IndexBufferInterface
+// class with derivations, classes that perform graphics API agnostic index buffer operations.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+class Renderer;
+
+class IndexBuffer
+{
+ public:
+ IndexBuffer();
+ virtual ~IndexBuffer();
+
+ virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) = 0;
+
+ virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) = 0;
+ virtual bool unmapBuffer() = 0;
+
+ virtual bool discard() = 0;
+
+ virtual GLenum getIndexType() const = 0;
+ virtual unsigned int getBufferSize() const = 0;
+ virtual bool setSize(unsigned int bufferSize, GLenum indexType) = 0;
+
+ unsigned int getSerial() const;
+
+ protected:
+ void updateSerial();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
+
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+};
+
+class IndexBufferInterface
+{
+ public:
+ IndexBufferInterface(Renderer *renderer, bool dynamic);
+ virtual ~IndexBufferInterface();
+
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType) = 0;
+
+ GLenum getIndexType() const;
+ unsigned int getBufferSize() const;
+
+ unsigned int getSerial() const;
+
+ int mapBuffer(unsigned int size, void** outMappedMemory);
+ bool unmapBuffer();
+
+ IndexBuffer *getIndexBuffer() const;
+
+ protected:
+ unsigned int getWritePosition() const;
+ void setWritePosition(unsigned int writePosition);
+
+ bool discard();
+
+ bool setBufferSize(unsigned int bufferSize, GLenum indexType);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexBufferInterface);
+
+ rx::Renderer *const mRenderer;
+
+ IndexBuffer* mIndexBuffer;
+
+ unsigned int mWritePosition;
+ bool mDynamic;
+};
+
+class StreamingIndexBufferInterface : public IndexBufferInterface
+{
+ public:
+ StreamingIndexBufferInterface(Renderer *renderer);
+ ~StreamingIndexBufferInterface();
+
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
+};
+
+class StaticIndexBufferInterface : public IndexBufferInterface
+{
+ public:
+ explicit StaticIndexBufferInterface(Renderer *renderer);
+ ~StaticIndexBufferInterface();
+
+ virtual bool reserveBufferSpace(unsigned int size, GLenum indexType);
+
+ unsigned int lookupRange(intptr_t offset, GLsizei count, unsigned int *minIndex, unsigned int *maxIndex); // Returns the offset into the index buffer, or -1 if not found
+ void addRange(intptr_t offset, GLsizei count, unsigned int minIndex, unsigned int maxIndex, unsigned int streamOffset);
+
+ private:
+ struct IndexRange
+ {
+ intptr_t offset;
+ GLsizei count;
+
+ bool operator<(const IndexRange& rhs) const
+ {
+ if (offset != rhs.offset)
+ {
+ return offset < rhs.offset;
+ }
+ if (count != rhs.count)
+ {
+ return count < rhs.count;
+ }
+ return false;
+ }
+ };
+
+ struct IndexResult
+ {
+ unsigned int minIndex;
+ unsigned int maxIndex;
+ unsigned int streamOffset;
+ };
+
+ std::map<IndexRange, IndexResult> mCache;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
new file mode 100644
index 0000000000..2a442ecd1a
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp
@@ -0,0 +1,182 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
+
+#include "libGLESv2/renderer/IndexBuffer11.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+namespace rx
+{
+
+IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
+{
+ mBuffer = NULL;
+ mBufferSize = 0;
+ mDynamicUsage = false;
+}
+
+IndexBuffer11::~IndexBuffer11()
+{
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ }
+}
+
+bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ }
+
+ updateSerial();
+
+ if (bufferSize > 0)
+ {
+ ID3D11Device* dxDevice = mRenderer->getDevice();
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = bufferSize;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ if (FAILED(result))
+ {
+ return false;
+ }
+ }
+
+ mBufferSize = bufferSize;
+ mIndexType = indexType;
+ mDynamicUsage = dynamic;
+
+ return true;
+}
+
+IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
+ return static_cast<IndexBuffer11*>(indexBuffer);
+}
+
+bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+ if (mBuffer)
+ {
+ if (offset + size > mBufferSize)
+ {
+ ERR("Index buffer map range is not inside the buffer.");
+ return false;
+ }
+
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Index buffer map failed with error 0x%08x", result);
+ return false;
+ }
+
+ *outMappedMemory = reinterpret_cast<char*>(mappedResource.pData) + offset;
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+bool IndexBuffer11::unmapBuffer()
+{
+ if (mBuffer)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+ dxContext->Unmap(mBuffer, 0);
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+GLenum IndexBuffer11::getIndexType() const
+{
+ return mIndexType;
+}
+
+unsigned int IndexBuffer11::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
+{
+ if (bufferSize > mBufferSize || indexType != mIndexType)
+ {
+ return initialize(bufferSize, indexType, mDynamicUsage);
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool IndexBuffer11::discard()
+{
+ if (mBuffer)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Index buffer map failed with error 0x%08x", result);
+ return false;
+ }
+
+ dxContext->Unmap(mBuffer, 0);
+
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+{
+ switch (mIndexType)
+ {
+ case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT;
+ case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT;
+ case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT;
+ default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+ID3D11Buffer *IndexBuffer11::getBuffer() const
+{
+ return mBuffer;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h
new file mode 100644
index 0000000000..39a61946ad
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+
+#include "libGLESv2/renderer/IndexBuffer.h"
+
+namespace rx
+{
+class Renderer11;
+
+class IndexBuffer11 : public IndexBuffer
+{
+ public:
+ explicit IndexBuffer11(Renderer11 *const renderer);
+ virtual ~IndexBuffer11();
+
+ virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+
+ static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer);
+
+ virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+ virtual bool unmapBuffer();
+
+ virtual GLenum getIndexType() const;
+ virtual unsigned int getBufferSize() const;
+ virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+
+ virtual bool discard();
+
+ DXGI_FORMAT getIndexFormat() const;
+ ID3D11Buffer *getBuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
+
+ rx::Renderer11 *const mRenderer;
+
+ ID3D11Buffer *mBuffer;
+ unsigned int mBufferSize;
+ GLenum mIndexType;
+ bool mDynamicUsage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp
new file mode 100644
index 0000000000..c6d83c5dca
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp
@@ -0,0 +1,207 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
+
+#include "libGLESv2/renderer/IndexBuffer9.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+namespace rx
+{
+
+IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
+{
+ mIndexBuffer = NULL;
+ mBufferSize = 0;
+ mIndexType = 0;
+ mDynamic = false;
+}
+
+IndexBuffer9::~IndexBuffer9()
+{
+ if (mIndexBuffer)
+ {
+ mIndexBuffer->Release();
+ mIndexBuffer = NULL;
+ }
+}
+
+bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+ if (mIndexBuffer)
+ {
+ mIndexBuffer->Release();
+ mIndexBuffer = NULL;
+ }
+
+ updateSerial();
+
+ if (bufferSize > 0)
+ {
+ D3DFORMAT format;
+ if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
+ {
+ format = D3DFMT_INDEX16;
+ }
+ else if (indexType == GL_UNSIGNED_INT)
+ {
+ if (mRenderer->get32BitIndexSupport())
+ {
+ format = D3DFMT_INDEX32;
+ }
+ else
+ {
+ ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.");
+ return false;
+ }
+ }
+ else
+ {
+ ERR("Invalid index type %u.", indexType);
+ return false;
+ }
+
+ DWORD usageFlags = D3DUSAGE_WRITEONLY;
+ if (dynamic)
+ {
+ usageFlags |= D3DUSAGE_DYNAMIC;
+ }
+
+ HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer);
+ if (FAILED(result))
+ {
+ ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result);
+ return false;
+ }
+ }
+
+ mBufferSize = bufferSize;
+ mIndexType = indexType;
+ mDynamic = dynamic;
+
+ return true;
+}
+
+IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
+ return static_cast<IndexBuffer9*>(indexBuffer);
+}
+
+bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+ if (mIndexBuffer)
+ {
+ DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
+
+ void *mapPtr = NULL;
+ HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags);
+ if (FAILED(result))
+ {
+ ERR("Index buffer lock failed with error 0x%08x", result);
+ return false;
+ }
+
+ *outMappedMemory = mapPtr;
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+bool IndexBuffer9::unmapBuffer()
+{
+ if (mIndexBuffer)
+ {
+ HRESULT result = mIndexBuffer->Unlock();
+ if (FAILED(result))
+ {
+ ERR("Index buffer unlock failed with error 0x%08x", result);
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+GLenum IndexBuffer9::getIndexType() const
+{
+ return mIndexType;
+}
+
+unsigned int IndexBuffer9::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
+{
+ if (bufferSize > mBufferSize || indexType != mIndexType)
+ {
+ return initialize(bufferSize, indexType, mDynamic);
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool IndexBuffer9::discard()
+{
+ if (mIndexBuffer)
+ {
+ void *dummy;
+ HRESULT result;
+
+ result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+ if (FAILED(result))
+ {
+ ERR("Discard lock failed with error 0x%08x", result);
+ return false;
+ }
+
+ result = mIndexBuffer->Unlock();
+ if (FAILED(result))
+ {
+ ERR("Discard unlock failed with error 0x%08x", result);
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ ERR("Index buffer not initialized.");
+ return false;
+ }
+}
+
+D3DFORMAT IndexBuffer9::getIndexFormat() const
+{
+ switch (mIndexType)
+ {
+ case GL_UNSIGNED_BYTE: return D3DFMT_INDEX16;
+ case GL_UNSIGNED_SHORT: return D3DFMT_INDEX16;
+ case GL_UNSIGNED_INT: return D3DFMT_INDEX32;
+ default: UNREACHABLE(); return D3DFMT_UNKNOWN;
+ }
+}
+
+IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
+{
+ return mIndexBuffer;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h
new file mode 100644
index 0000000000..6801867532
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h
@@ -0,0 +1,53 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Indexffer9.h: Defines the D3D9 IndexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+
+#include "libGLESv2/renderer/IndexBuffer.h"
+
+namespace rx
+{
+class Renderer9;
+
+class IndexBuffer9 : public IndexBuffer
+{
+ public:
+ explicit IndexBuffer9(Renderer9 *const renderer);
+ virtual ~IndexBuffer9();
+
+ virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+
+ static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer);
+
+ virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+ virtual bool unmapBuffer();
+
+ virtual GLenum getIndexType() const;
+ virtual unsigned int getBufferSize() const;
+ virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+
+ virtual bool discard();
+
+ D3DFORMAT getIndexFormat() const;
+ IDirect3DIndexBuffer9 *getBuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexBuffer9);
+
+ rx::Renderer9 *const mRenderer;
+
+ IDirect3DIndexBuffer9 *mIndexBuffer;
+ unsigned int mBufferSize;
+ GLenum mIndexType;
+ bool mDynamic;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp
new file mode 100644
index 0000000000..84b79b4109
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.cpp
@@ -0,0 +1,316 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexDataManager.cpp: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#include "libGLESv2/renderer/IndexDataManager.h"
+#include "libGLESv2/renderer/BufferStorage.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/IndexBuffer.h"
+
+namespace rx
+{
+
+IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
+{
+ mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+ if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
+ {
+ delete mStreamingBufferShort;
+ mStreamingBufferShort = NULL;
+ }
+
+ mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+ if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ {
+ delete mStreamingBufferInt;
+ mStreamingBufferInt = NULL;
+ }
+
+ if (!mStreamingBufferShort)
+ {
+ // Make sure both buffers are deleted.
+ delete mStreamingBufferInt;
+ mStreamingBufferInt = NULL;
+
+ ERR("Failed to allocate the streaming index buffer(s).");
+ }
+
+ mCountingBuffer = NULL;
+}
+
+IndexDataManager::~IndexDataManager()
+{
+ delete mStreamingBufferShort;
+ delete mStreamingBufferInt;
+ delete mCountingBuffer;
+}
+
+static unsigned int indexTypeSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_UNSIGNED_INT: return sizeof(GLuint);
+ case GL_UNSIGNED_SHORT: return sizeof(GLushort);
+ case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ default: UNREACHABLE(); return sizeof(GLushort);
+ }
+}
+
+static void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
+{
+ if (type == GL_UNSIGNED_BYTE)
+ {
+ const GLubyte *in = static_cast<const GLubyte*>(input);
+ GLushort *out = static_cast<GLushort*>(output);
+
+ for (GLsizei i = 0; i < count; i++)
+ {
+ out[i] = in[i];
+ }
+ }
+ else if (type == GL_UNSIGNED_INT)
+ {
+ memcpy(output, input, count * sizeof(GLuint));
+ }
+ else if (type == GL_UNSIGNED_SHORT)
+ {
+ memcpy(output, input, count * sizeof(GLushort));
+ }
+ else UNREACHABLE();
+}
+
+template <class IndexType>
+static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+ *minIndex = indices[0];
+ *maxIndex = indices[0];
+
+ for (GLsizei i = 0; i < count; i++)
+ {
+ if (*minIndex > indices[i]) *minIndex = indices[i];
+ if (*maxIndex < indices[i]) *maxIndex = indices[i];
+ }
+}
+
+static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+{
+ if (type == GL_UNSIGNED_BYTE)
+ {
+ computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
+ }
+ else if (type == GL_UNSIGNED_INT)
+ {
+ computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
+ }
+ else if (type == GL_UNSIGNED_SHORT)
+ {
+ computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
+ }
+ else UNREACHABLE();
+}
+
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+{
+ if (!mStreamingBufferShort)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
+ GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ bool alignedOffset = false;
+
+ BufferStorage *storage = NULL;
+
+ if (buffer != NULL)
+ {
+ storage = buffer->getStorage();
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break;
+ case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
+ case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break;
+ default: UNREACHABLE(); alignedOffset = false;
+ }
+
+ if (indexTypeSize(type) * count + offset > storage->getSize())
+ {
+ return GL_INVALID_OPERATION;
+ }
+
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
+ StreamingIndexBufferInterface *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
+
+ StaticIndexBufferInterface *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
+ IndexBufferInterface *indexBuffer = streamingBuffer;
+ bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
+ destinationIndexType == type;
+ UINT streamOffset = 0;
+
+ if (directStorage)
+ {
+ indexBuffer = streamingBuffer;
+ streamOffset = offset;
+ storage->markBufferUsage();
+ computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+ }
+ else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
+ {
+ indexBuffer = staticBuffer;
+ streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
+
+ if (streamOffset == -1)
+ {
+ streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType);
+ computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+ staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
+ }
+ }
+ else
+ {
+ int convertCount = count;
+
+ if (staticBuffer)
+ {
+ if (staticBuffer->getBufferSize() == 0 && alignedOffset)
+ {
+ indexBuffer = staticBuffer;
+ convertCount = storage->getSize() / indexTypeSize(type);
+ }
+ else
+ {
+ buffer->invalidateStaticData();
+ staticBuffer = NULL;
+ }
+ }
+
+ if (!indexBuffer)
+ {
+ ERR("No valid index buffer.");
+ return GL_INVALID_OPERATION;
+ }
+
+ unsigned int bufferSizeRequired = convertCount * indexTypeSize(destinationIndexType);
+ indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+
+ void* output = NULL;
+ streamOffset = indexBuffer->mapBuffer(bufferSizeRequired, &output);
+ if (streamOffset == -1 || output == NULL)
+ {
+ ERR("Failed to map index buffer.");
+ return GL_OUT_OF_MEMORY;
+ }
+
+ convertIndices(type, staticBuffer ? storage->getData() : indices, convertCount, output);
+
+ if (!indexBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap index buffer.");
+ return GL_OUT_OF_MEMORY;
+ }
+
+ computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
+
+ if (staticBuffer)
+ {
+ streamOffset = (offset / indexTypeSize(type)) * indexTypeSize(destinationIndexType);
+ staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
+ }
+ }
+
+ translated->storage = directStorage ? storage : NULL;
+ translated->indexBuffer = indexBuffer->getIndexBuffer();
+ translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
+ translated->startIndex = streamOffset / indexTypeSize(destinationIndexType);
+ translated->startOffset = streamOffset;
+
+ if (buffer)
+ {
+ buffer->promoteStaticUsage(count * indexTypeSize(type));
+ }
+
+ return GL_NO_ERROR;
+}
+
+StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
+{
+ if (count <= 65536) // 16-bit indices
+ {
+ const unsigned int spaceNeeded = count * sizeof(unsigned short);
+
+ if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+ {
+ delete mCountingBuffer;
+ mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
+ mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
+
+ void* mappedMemory = NULL;
+ if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL)
+ {
+ ERR("Failed to map counting buffer.");
+ return NULL;
+ }
+
+ unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
+ for(int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+
+ if (!mCountingBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap counting buffer.");
+ return NULL;
+ }
+ }
+ }
+ else if (mStreamingBufferInt) // 32-bit indices supported
+ {
+ const unsigned int spaceNeeded = count * sizeof(unsigned int);
+
+ if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+ {
+ delete mCountingBuffer;
+ mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
+ mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
+
+ void* mappedMemory = NULL;
+ if (mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory) == -1 || mappedMemory == NULL)
+ {
+ ERR("Failed to map counting buffer.");
+ return NULL;
+ }
+
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ for(int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+
+ if (!mCountingBuffer->unmapBuffer())
+ {
+ ERR("Failed to unmap counting buffer.");
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+ return mCountingBuffer;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.h
new file mode 100644
index 0000000000..0e77c81d1b
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/IndexDataManager.h
@@ -0,0 +1,66 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexDataManager.h: Defines the IndexDataManager, a class that
+// runs the Buffer translation process for index buffers.
+
+#ifndef LIBGLESV2_INDEXDATAMANAGER_H_
+#define LIBGLESV2_INDEXDATAMANAGER_H_
+
+#include "common/angleutils.h"
+
+namespace
+{
+ enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) };
+}
+
+namespace gl
+{
+class Buffer;
+}
+
+namespace rx
+{
+class StaticIndexBufferInterface;
+class StreamingIndexBufferInterface;
+class IndexBuffer;
+class BufferStorage;
+class Renderer;
+
+struct TranslatedIndexData
+{
+ unsigned int minIndex;
+ unsigned int maxIndex;
+ unsigned int startIndex;
+ unsigned int startOffset; // In bytes
+
+ IndexBuffer *indexBuffer;
+ BufferStorage *storage;
+ unsigned int serial;
+};
+
+class IndexDataManager
+{
+ public:
+ explicit IndexDataManager(Renderer *renderer);
+ virtual ~IndexDataManager();
+
+ GLenum prepareIndexData(GLenum type, GLsizei count, gl::Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated);
+ StaticIndexBufferInterface *getCountingIndices(GLsizei count);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
+
+ Renderer *const mRenderer;
+
+ StreamingIndexBufferInterface *mStreamingBufferShort;
+ StreamingIndexBufferInterface *mStreamingBufferInt;
+ StaticIndexBufferInterface *mCountingBuffer;
+};
+
+}
+
+#endif // LIBGLESV2_INDEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp
new file mode 100644
index 0000000000..0402bb35ac
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp
@@ -0,0 +1,166 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#include "libGLESv2/renderer/InputLayoutCache.h"
+#include "libGLESv2/renderer/VertexBuffer11.h"
+#include "libGLESv2/renderer/BufferStorage11.h"
+#include "libGLESv2/renderer/ShaderExecutable11.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/VertexDataManager.h"
+
+#include "third_party/murmurhash/MurmurHash3.h"
+
+namespace rx
+{
+
+const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
+
+InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
+{
+ mCounter = 0;
+ mDevice = NULL;
+ mDeviceContext = NULL;
+}
+
+InputLayoutCache::~InputLayoutCache()
+{
+ clear();
+}
+
+void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context)
+{
+ clear();
+ mDevice = device;
+ mDeviceContext = context;
+}
+
+void InputLayoutCache::clear()
+{
+ for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ {
+ i->second.inputLayout->Release();
+ }
+ mInputLayoutMap.clear();
+}
+
+GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+ gl::ProgramBinary *programBinary)
+{
+ int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
+ programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices);
+
+ if (!mDevice || !mDeviceContext)
+ {
+ ERR("InputLayoutCache is not initialized.");
+ return GL_INVALID_OPERATION;
+ }
+
+ InputLayoutKey ilKey = { 0 };
+
+ ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL };
+ UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 };
+ UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 };
+
+ static const char* semanticName = "TEXCOORD";
+
+ for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (attributes[i].active)
+ {
+ VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
+ BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
+
+ D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
+
+ // Record the type of the associated vertex shader vector in our key
+ // This will prevent mismatched vertex shaders from using the same input layout
+ GLint attributeSize;
+ programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.glslElementType[ilKey.elementCount], NULL);
+
+ ilKey.elements[ilKey.elementCount].SemanticName = semanticName;
+ ilKey.elements[ilKey.elementCount].SemanticIndex = sortedSemanticIndices[i];
+ ilKey.elements[ilKey.elementCount].Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
+ ilKey.elements[ilKey.elementCount].InputSlot = i;
+ ilKey.elements[ilKey.elementCount].AlignedByteOffset = 0;
+ ilKey.elements[ilKey.elementCount].InputSlotClass = inputClass;
+ ilKey.elements[ilKey.elementCount].InstanceDataStepRate = attributes[i].divisor;
+ ilKey.elementCount++;
+
+ vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer();
+ vertexStrides[i] = attributes[i].stride;
+ vertexOffsets[i] = attributes[i].offset;
+ }
+ }
+
+ ID3D11InputLayout *inputLayout = NULL;
+
+ InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey);
+ if (i != mInputLayoutMap.end())
+ {
+ inputLayout = i->second.inputLayout;
+ i->second.lastUsedTime = mCounter++;
+ }
+ else
+ {
+ ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
+
+ HRESULT result = mDevice->CreateInputLayout(ilKey.elements, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout);
+ if (FAILED(result))
+ {
+ ERR("Failed to crate input layout, result: 0x%08x", result);
+ return GL_INVALID_OPERATION;
+ }
+
+ if (mInputLayoutMap.size() >= kMaxInputLayouts)
+ {
+ TRACE("Overflowed the limit of %u input layouts, removing the least recently used "
+ "to make room.", kMaxInputLayouts);
+
+ InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
+ for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+ {
+ if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ leastRecentlyUsed->second.inputLayout->Release();
+ mInputLayoutMap.erase(leastRecentlyUsed);
+ }
+
+ InputLayoutCounterPair inputCounterPair;
+ inputCounterPair.inputLayout = inputLayout;
+ inputCounterPair.lastUsedTime = mCounter++;
+
+ mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
+ }
+
+ mDeviceContext->IASetInputLayout(inputLayout);
+ mDeviceContext->IASetVertexBuffers(0, gl::MAX_VERTEX_ATTRIBS, vertexBuffers, vertexStrides, vertexOffsets);
+
+ return GL_NO_ERROR;
+}
+
+std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout)
+{
+ static const unsigned int seed = 0xDEADBEEF;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(&inputLayout, sizeof(InputLayoutKey), seed, &hash);
+ return hash;
+}
+
+bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b)
+{
+ return memcmp(&a, &b, sizeof(InputLayoutKey)) == 0;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h
new file mode 100644
index 0000000000..d95f39fae4
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#ifndef LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+#define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+
+#include "libGLESv2/Constants.h"
+#include "common/angleutils.h"
+
+namespace gl
+{
+class ProgramBinary;
+}
+
+namespace rx
+{
+struct TranslatedAttribute;
+
+class InputLayoutCache
+{
+ public:
+ InputLayoutCache();
+ virtual ~InputLayoutCache();
+
+ void initialize(ID3D11Device *device, ID3D11DeviceContext *context);
+ void clear();
+
+ GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+ gl::ProgramBinary *programBinary);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
+
+ struct InputLayoutKey
+ {
+ unsigned int elementCount;
+ D3D11_INPUT_ELEMENT_DESC elements[gl::MAX_VERTEX_ATTRIBS];
+ GLenum glslElementType[gl::MAX_VERTEX_ATTRIBS];
+ };
+
+ struct InputLayoutCounterPair
+ {
+ ID3D11InputLayout *inputLayout;
+ unsigned long long lastUsedTime;
+ };
+
+ static std::size_t hashInputLayout(const InputLayoutKey &inputLayout);
+ static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b);
+
+ typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &);
+ typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &, const InputLayoutKey &);
+ typedef std::unordered_map<InputLayoutKey,
+ InputLayoutCounterPair,
+ InputLayoutHashFunction,
+ InputLayoutEqualityFunction> InputLayoutMap;
+ InputLayoutMap mInputLayoutMap;
+
+ static const unsigned int kMaxInputLayouts;
+
+ unsigned long long mCounter;
+
+ ID3D11Device *mDevice;
+ ID3D11DeviceContext *mDeviceContext;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp
new file mode 100644
index 0000000000..13210fc929
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp
@@ -0,0 +1,122 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#include "libGLESv2/renderer/Query11.h"
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type)
+{
+ mRenderer = renderer;
+ mQuery = NULL;
+}
+
+Query11::~Query11()
+{
+ if (mQuery)
+ {
+ mQuery->Release();
+ mQuery = NULL;
+ }
+}
+
+void Query11::begin()
+{
+ if (mQuery == NULL)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_OCCLUSION;
+ queryDesc.MiscFlags = 0;
+
+ if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery)))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ mRenderer->getDeviceContext()->Begin(mQuery);
+}
+
+void Query11::end()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ mRenderer->getDeviceContext()->End(mQuery);
+
+ mStatus = GL_FALSE;
+ mResult = GL_FALSE;
+}
+
+GLuint Query11::getResult()
+{
+ if (mQuery != NULL)
+ {
+ while (!testQuery())
+ {
+ Sleep(0);
+ // explicitly check for device loss, some drivers seem to return S_FALSE
+ // if the device is lost
+ if (mRenderer->testDeviceLost(true))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, 0);
+ }
+ }
+ }
+
+ return mResult;
+}
+
+GLboolean Query11::isResultAvailable()
+{
+ if (mQuery != NULL)
+ {
+ testQuery();
+ }
+
+ return mStatus;
+}
+
+GLboolean Query11::testQuery()
+{
+ if (mQuery != NULL && mStatus != GL_TRUE)
+ {
+ UINT64 numPixels = 0;
+ HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, &numPixels, sizeof(UINT64), 0);
+ if (result == S_OK)
+ {
+ mStatus = GL_TRUE;
+
+ switch (getType())
+ {
+ case GL_ANY_SAMPLES_PASSED_EXT:
+ case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+ mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ else if (mRenderer->testDeviceLost(true))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+ }
+
+ return mStatus;
+ }
+
+ return GL_TRUE; // prevent blocking when query is null
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h
new file mode 100644
index 0000000000..0a03de77ca
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#ifndef LIBGLESV2_RENDERER_QUERY11_H_
+#define LIBGLESV2_RENDERER_QUERY11_H_
+
+#include "libGLESv2/renderer/QueryImpl.h"
+
+namespace rx
+{
+class Renderer11;
+
+class Query11 : public QueryImpl
+{
+ public:
+ Query11(rx::Renderer11 *renderer, GLenum type);
+ virtual ~Query11();
+
+ void begin();
+ void end();
+ GLuint getResult();
+ GLboolean isResultAvailable();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Query11);
+
+ GLboolean testQuery();
+
+ rx::Renderer11 *mRenderer;
+ ID3D11Query *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_QUERY11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp
new file mode 100644
index 0000000000..ef694267dd
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp
@@ -0,0 +1,125 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+
+#include "libGLESv2/renderer/Query9.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+namespace rx
+{
+
+Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type)
+{
+ mRenderer = renderer;
+ mQuery = NULL;
+}
+
+Query9::~Query9()
+{
+ if (mQuery)
+ {
+ mQuery->Release();
+ mQuery = NULL;
+ }
+}
+
+void Query9::begin()
+{
+ if (mQuery == NULL)
+ {
+ if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery)))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ HRESULT result = mQuery->Issue(D3DISSUE_BEGIN);
+ ASSERT(SUCCEEDED(result));
+}
+
+void Query9::end()
+{
+ if (mQuery == NULL)
+ {
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ HRESULT result = mQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+
+ mStatus = GL_FALSE;
+ mResult = GL_FALSE;
+}
+
+GLuint Query9::getResult()
+{
+ if (mQuery != NULL)
+ {
+ while (!testQuery())
+ {
+ Sleep(0);
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ if (mRenderer->testDeviceLost(true))
+ {
+ return gl::error(GL_OUT_OF_MEMORY, 0);
+ }
+ }
+ }
+
+ return mResult;
+}
+
+GLboolean Query9::isResultAvailable()
+{
+ if (mQuery != NULL)
+ {
+ testQuery();
+ }
+
+ return mStatus;
+}
+
+GLboolean Query9::testQuery()
+{
+ if (mQuery != NULL && mStatus != GL_TRUE)
+ {
+ DWORD numPixels = 0;
+
+ HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
+ if (hres == S_OK)
+ {
+ mStatus = GL_TRUE;
+
+ switch (getType())
+ {
+ case GL_ANY_SAMPLES_PASSED_EXT:
+ case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+ mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE;
+ break;
+ default:
+ ASSERT(false);
+ }
+ }
+ else if (d3d9::isDeviceLostError(hres))
+ {
+ mRenderer->notifyDeviceLost();
+ return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+ }
+
+ return mStatus;
+ }
+
+ return GL_TRUE; // prevent blocking when query is null
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h
new file mode 100644
index 0000000000..47eef89336
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+#ifndef LIBGLESV2_RENDERER_QUERY9_H_
+#define LIBGLESV2_RENDERER_QUERY9_H_
+
+#include "libGLESv2/renderer/QueryImpl.h"
+
+namespace rx
+{
+class Renderer9;
+
+class Query9 : public QueryImpl
+{
+ public:
+ Query9(rx::Renderer9 *renderer, GLenum type);
+ virtual ~Query9();
+
+ void begin();
+ void end();
+ GLuint getResult();
+ GLboolean isResultAvailable();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Query9);
+
+ GLboolean testQuery();
+
+ rx::Renderer9 *mRenderer;
+ IDirect3DQuery9 *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_QUERY9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h b/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h
new file mode 100644
index 0000000000..a874047b0c
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/QueryImpl.h
@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// QueryImpl.h: Defines the abstract rx::QueryImpl class.
+
+#ifndef LIBGLESV2_RENDERER_QUERYIMPL_H_
+#define LIBGLESV2_RENDERER_QUERYIMPL_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class QueryImpl
+{
+ public:
+ explicit QueryImpl(GLenum type) : mType(type), mStatus(GL_FALSE), mResult(0) { }
+ virtual ~QueryImpl() { }
+
+ virtual void begin() = 0;
+ virtual void end() = 0;
+ virtual GLuint getResult() = 0;
+ virtual GLboolean isResultAvailable() = 0;
+
+ GLenum getType() const { return mType; }
+
+ protected:
+ GLuint mResult;
+ GLboolean mStatus;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QueryImpl);
+
+ GLenum mType;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_QUERYIMPL_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
new file mode 100644
index 0000000000..f60a88f97a
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp
@@ -0,0 +1,406 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#include "libGLESv2/renderer/RenderStateCache.h"
+#include "libGLESv2/renderer/renderer11_utils.h"
+
+#include "common/debug.h"
+#include "third_party/murmurhash/MurmurHash3.h"
+
+namespace rx
+{
+
+// MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState,
+// ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum
+// number of unique states of each type an application can create is 4096
+const unsigned int RenderStateCache::kMaxBlendStates = 4096;
+const unsigned int RenderStateCache::kMaxRasterizerStates = 4096;
+const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096;
+const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
+
+RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0),
+ mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
+ mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
+ mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
+ mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
+{
+}
+
+RenderStateCache::~RenderStateCache()
+{
+ clear();
+}
+
+void RenderStateCache::initialize(ID3D11Device *device)
+{
+ clear();
+ mDevice = device;
+}
+
+void RenderStateCache::clear()
+{
+ for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
+ {
+ i->second.first->Release();
+ }
+ mBlendStateCache.clear();
+
+ for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
+ {
+ i->second.first->Release();
+ }
+ mRasterizerStateCache.clear();
+
+ for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+ {
+ i->second.first->Release();
+ }
+ mDepthStencilStateCache.clear();
+
+ for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
+ {
+ i->second.first->Release();
+ }
+ mSamplerStateCache.clear();
+}
+
+std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState)
+{
+ static const unsigned int seed = 0xABCDEF98;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(&blendState, sizeof(gl::BlendState), seed, &hash);
+ return hash;
+}
+
+bool RenderStateCache::compareBlendStates(const gl::BlendState &a, const gl::BlendState &b)
+{
+ return memcmp(&a, &b, sizeof(gl::BlendState)) == 0;
+}
+
+ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendState)
+{
+ if (!mDevice)
+ {
+ ERR("RenderStateCache is not initialized.");
+ return NULL;
+ }
+
+ BlendStateMap::iterator i = mBlendStateCache.find(blendState);
+ if (i != mBlendStateCache.end())
+ {
+ BlendStateCounterPair &state = i->second;
+ state.second = mCounter++;
+ return state.first;
+ }
+ else
+ {
+ if (mBlendStateCache.size() >= kMaxBlendStates)
+ {
+ TRACE("Overflowed the limit of %u blend states, removing the least recently used "
+ "to make room.", kMaxBlendStates);
+
+ BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin();
+ for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
+ {
+ if (i->second.second < leastRecentlyUsed->second.second)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ leastRecentlyUsed->second.first->Release();
+ mBlendStateCache.erase(leastRecentlyUsed);
+ }
+
+ // Create a new blend state and insert it into the cache
+ D3D11_BLEND_DESC blendDesc = { 0 };
+ blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage;
+ blendDesc.IndependentBlendEnable = FALSE;
+
+ for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+ {
+ D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = blendDesc.RenderTarget[i];
+
+ rtBlend.BlendEnable = blendState.blend;
+ if (blendState.blend)
+ {
+ rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false);
+ rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false);
+ rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB);
+
+ rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true);
+ rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true);
+ rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha);
+ }
+
+ rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendState.colorMaskRed,
+ blendState.colorMaskGreen,
+ blendState.colorMaskBlue,
+ blendState.colorMaskAlpha);
+ }
+
+ ID3D11BlendState *dx11BlendState = NULL;
+ HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState);
+ if (FAILED(result) || !dx11BlendState)
+ {
+ ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result);
+ return NULL;
+ }
+
+ mBlendStateCache.insert(std::make_pair(blendState, std::make_pair(dx11BlendState, mCounter++)));
+
+ return dx11BlendState;
+ }
+}
+
+std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &rasterState)
+{
+ static const unsigned int seed = 0xABCDEF98;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(&rasterState, sizeof(RasterizerStateKey), seed, &hash);
+ return hash;
+}
+
+bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b)
+{
+ return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0;
+}
+
+ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState,
+ bool scissorEnabled, unsigned int depthSize)
+{
+ if (!mDevice)
+ {
+ ERR("RenderStateCache is not initialized.");
+ return NULL;
+ }
+
+ RasterizerStateKey key;
+ key.rasterizerState = rasterState;
+ key.scissorEnabled = scissorEnabled;
+ key.depthSize = depthSize;
+
+ RasterizerStateMap::iterator i = mRasterizerStateCache.find(key);
+ if (i != mRasterizerStateCache.end())
+ {
+ RasterizerStateCounterPair &state = i->second;
+ state.second = mCounter++;
+ return state.first;
+ }
+ else
+ {
+ if (mRasterizerStateCache.size() >= kMaxRasterizerStates)
+ {
+ TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used "
+ "to make room.", kMaxRasterizerStates);
+
+ RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin();
+ for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
+ {
+ if (i->second.second < leastRecentlyUsed->second.second)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ leastRecentlyUsed->second.first->Release();
+ mRasterizerStateCache.erase(leastRecentlyUsed);
+ }
+
+ D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
+
+ // Disable culling if drawing points
+ if (rasterState.pointDrawMode)
+ {
+ cullMode = D3D11_CULL_NONE;
+ }
+
+ D3D11_RASTERIZER_DESC rasterDesc;
+ rasterDesc.FillMode = D3D11_FILL_SOLID;
+ rasterDesc.CullMode = cullMode;
+ rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE;
+ rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(depthSize));
+ rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though.
+ rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor;
+ rasterDesc.DepthClipEnable = TRUE;
+ rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE;
+ rasterDesc.MultisampleEnable = TRUE;
+ rasterDesc.AntialiasedLineEnable = FALSE;
+
+ ID3D11RasterizerState *dx11RasterizerState = NULL;
+ HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState);
+ if (FAILED(result) || !dx11RasterizerState)
+ {
+ ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result);
+ return NULL;
+ }
+
+ mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++)));
+
+ return dx11RasterizerState;
+ }
+}
+
+std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &dsState)
+{
+ static const unsigned int seed = 0xABCDEF98;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(&dsState, sizeof(gl::DepthStencilState), seed, &hash);
+ return hash;
+}
+
+bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b)
+{
+ return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0;
+}
+
+ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState)
+{
+ if (!mDevice)
+ {
+ ERR("RenderStateCache is not initialized.");
+ return NULL;
+ }
+
+ DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState);
+ if (i != mDepthStencilStateCache.end())
+ {
+ DepthStencilStateCounterPair &state = i->second;
+ state.second = mCounter++;
+ return state.first;
+ }
+ else
+ {
+ if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates)
+ {
+ TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used "
+ "to make room.", kMaxDepthStencilStates);
+
+ DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin();
+ for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+ {
+ if (i->second.second < leastRecentlyUsed->second.second)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ leastRecentlyUsed->second.first->Release();
+ mDepthStencilStateCache.erase(leastRecentlyUsed);
+ }
+
+ D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
+ dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE;
+ dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask);
+ dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc);
+ dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE;
+ dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask);
+ dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask);
+ dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail);
+ dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail);
+ dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass);
+ dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc);
+ dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail);
+ dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail);
+ dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass);
+ dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc);
+
+ ID3D11DepthStencilState *dx11DepthStencilState = NULL;
+ HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState);
+ if (FAILED(result) || !dx11DepthStencilState)
+ {
+ ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
+ return NULL;
+ }
+
+ mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
+
+ return dx11DepthStencilState;
+ }
+}
+
+std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState)
+{
+ static const unsigned int seed = 0xABCDEF98;
+
+ std::size_t hash = 0;
+ MurmurHash3_x86_32(&samplerState, sizeof(gl::SamplerState), seed, &hash);
+ return hash;
+}
+
+bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b)
+{
+ return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0;
+}
+
+ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState)
+{
+ if (!mDevice)
+ {
+ ERR("RenderStateCache is not initialized.");
+ return NULL;
+ }
+
+ SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState);
+ if (i != mSamplerStateCache.end())
+ {
+ SamplerStateCounterPair &state = i->second;
+ state.second = mCounter++;
+ return state.first;
+ }
+ else
+ {
+ if (mSamplerStateCache.size() >= kMaxSamplerStates)
+ {
+ TRACE("Overflowed the limit of %u sampler states, removing the least recently used "
+ "to make room.", kMaxSamplerStates);
+
+ SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin();
+ for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
+ {
+ if (i->second.second < leastRecentlyUsed->second.second)
+ {
+ leastRecentlyUsed = i;
+ }
+ }
+ leastRecentlyUsed->second.first->Release();
+ mSamplerStateCache.erase(leastRecentlyUsed);
+ }
+
+ D3D11_SAMPLER_DESC samplerDesc;
+ samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy);
+ samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS);
+ samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT);
+ samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.MipLODBias = static_cast<float>(samplerState.lodOffset);
+ samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy;
+ samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ samplerDesc.BorderColor[0] = 0.0f;
+ samplerDesc.BorderColor[1] = 0.0f;
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
+ samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
+
+ ID3D11SamplerState *dx11SamplerState = NULL;
+ HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState);
+ if (FAILED(result) || !dx11SamplerState)
+ {
+ ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result);
+ return NULL;
+ }
+
+ mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++)));
+
+ return dx11SamplerState;
+ }
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h
new file mode 100644
index 0000000000..f8b5111de4
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h
@@ -0,0 +1,101 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#ifndef LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
+#define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
+
+#include "libGLESv2/angletypes.h"
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class RenderStateCache
+{
+ public:
+ RenderStateCache();
+ virtual ~RenderStateCache();
+
+ void initialize(ID3D11Device *device);
+ void clear();
+
+ // Increments refcount on the returned blend state, Release() must be called.
+ ID3D11BlendState *getBlendState(const gl::BlendState &blendState);
+ ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState,
+ bool scissorEnabled, unsigned int depthSize);
+ ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState);
+ ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
+
+ unsigned long long mCounter;
+
+ // Blend state cache
+ static std::size_t hashBlendState(const gl::BlendState &blendState);
+ static bool compareBlendStates(const gl::BlendState &a, const gl::BlendState &b);
+ static const unsigned int kMaxBlendStates;
+
+ typedef std::size_t (*BlendStateHashFunction)(const gl::BlendState &);
+ typedef bool (*BlendStateEqualityFunction)(const gl::BlendState &, const gl::BlendState &);
+ typedef std::pair<ID3D11BlendState*, unsigned long long> BlendStateCounterPair;
+ typedef std::unordered_map<gl::BlendState, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction> BlendStateMap;
+ BlendStateMap mBlendStateCache;
+
+ // Rasterizer state cache
+ struct RasterizerStateKey
+ {
+ gl::RasterizerState rasterizerState;
+ bool scissorEnabled;
+ unsigned int depthSize;
+ };
+ static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState);
+ static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b);
+ static const unsigned int kMaxRasterizerStates;
+
+ typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &);
+ typedef bool (*RasterizerStateEqualityFunction)(const RasterizerStateKey &, const RasterizerStateKey &);
+ typedef std::pair<ID3D11RasterizerState*, unsigned long long> RasterizerStateCounterPair;
+ typedef std::unordered_map<RasterizerStateKey, RasterizerStateCounterPair, RasterizerStateHashFunction, RasterizerStateEqualityFunction> RasterizerStateMap;
+ RasterizerStateMap mRasterizerStateCache;
+
+ // Depth stencil state cache
+ static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState);
+ static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b);
+ static const unsigned int kMaxDepthStencilStates;
+
+ typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &);
+ typedef bool (*DepthStencilStateEqualityFunction)(const gl::DepthStencilState &, const gl::DepthStencilState &);
+ typedef std::pair<ID3D11DepthStencilState*, unsigned long long> DepthStencilStateCounterPair;
+ typedef std::unordered_map<gl::DepthStencilState,
+ DepthStencilStateCounterPair,
+ DepthStencilStateHashFunction,
+ DepthStencilStateEqualityFunction> DepthStencilStateMap;
+ DepthStencilStateMap mDepthStencilStateCache;
+
+ // Sample state cache
+ static std::size_t hashSamplerState(const gl::SamplerState &samplerState);
+ static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b);
+ static const unsigned int kMaxSamplerStates;
+
+ typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &);
+ typedef bool (*SamplerStateEqualityFunction)(const gl::SamplerState &, const gl::SamplerState &);
+ typedef std::pair<ID3D11SamplerState*, unsigned long long> SamplerStateCounterPair;
+ typedef std::unordered_map<gl::SamplerState,
+ SamplerStateCounterPair,
+ SamplerStateHashFunction,
+ SamplerStateEqualityFunction> SamplerStateMap;
+ SamplerStateMap mSamplerStateCache;
+
+ ID3D11Device *mDevice;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
new file mode 100644
index 0000000000..80de39f4f7
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget.h
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget.h: Defines an abstract wrapper class to manage IDirect3DSurface9
+// and ID3D11View objects belonging to renderbuffers.
+
+#ifndef LIBGLESV2_RENDERER_RENDERTARGET_H_
+#define LIBGLESV2_RENDERER_RENDERTARGET_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+class RenderTarget
+{
+ public:
+ RenderTarget()
+ {
+ mWidth = 0;
+ mHeight = 0;
+ mInternalFormat = GL_NONE;
+ mActualFormat = GL_NONE;
+ mSamples = 0;
+ }
+
+ virtual ~RenderTarget() {};
+
+ GLsizei getWidth() { return mWidth; }
+ GLsizei getHeight() { return mHeight; }
+ GLenum getInternalFormat() { return mInternalFormat; }
+ GLenum getActualFormat() { return mActualFormat; }
+ GLsizei getSamples() { return mSamples; }
+
+ struct Desc {
+ GLsizei width;
+ GLsizei height;
+ GLenum format;
+ };
+
+ protected:
+ GLsizei mWidth;
+ GLsizei mHeight;
+ GLenum mInternalFormat;
+ GLenum mActualFormat;
+ GLsizei mSamples;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderTarget);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERTARGET_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp
new file mode 100644
index 0000000000..cf226de17b
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp
@@ -0,0 +1,378 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#include "libGLESv2/renderer/RenderTarget11.h"
+#include "libGLESv2/renderer/Renderer11.h"
+
+#include "libGLESv2/renderer/renderer11_utils.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
+{
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ view->GetDesc(&rtvDesc);
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ texture->GetDesc(&texDesc);
+
+ unsigned int mipSlice = 0;
+ unsigned int arraySlice = 0;
+ unsigned int mipLevels = texDesc.MipLevels;
+
+ switch (rtvDesc.ViewDimension)
+ {
+ case D3D11_RTV_DIMENSION_TEXTURE1D:
+ mipSlice = rtvDesc.Texture1D.MipSlice;
+ arraySlice = 0;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
+ mipSlice = rtvDesc.Texture1DArray.MipSlice;
+ arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE2D:
+ mipSlice = rtvDesc.Texture2D.MipSlice;
+ arraySlice = 0;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
+ mipSlice = rtvDesc.Texture2DArray.MipSlice;
+ arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE2DMS:
+ mipSlice = 0;
+ arraySlice = 0;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
+ mipSlice = 0;
+ arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
+ break;
+
+ case D3D11_RTV_DIMENSION_TEXTURE3D:
+ mipSlice = rtvDesc.Texture3D.MipSlice;
+ arraySlice = 0;
+ break;
+
+ case D3D11_RTV_DIMENSION_UNKNOWN:
+ case D3D11_RTV_DIMENSION_BUFFER:
+ UNIMPLEMENTED();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
+{
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ view->GetDesc(&dsvDesc);
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ texture->GetDesc(&texDesc);
+
+ unsigned int mipSlice = 0;
+ unsigned int arraySlice = 0;
+ unsigned int mipLevels = texDesc.MipLevels;
+
+ switch (dsvDesc.ViewDimension)
+ {
+ case D3D11_DSV_DIMENSION_TEXTURE1D:
+ mipSlice = dsvDesc.Texture1D.MipSlice;
+ arraySlice = 0;
+ break;
+
+ case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
+ mipSlice = dsvDesc.Texture1DArray.MipSlice;
+ arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
+ break;
+
+ case D3D11_DSV_DIMENSION_TEXTURE2D:
+ mipSlice = dsvDesc.Texture2D.MipSlice;
+ arraySlice = 0;
+ break;
+
+ case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
+ mipSlice = dsvDesc.Texture2DArray.MipSlice;
+ arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
+ break;
+
+ case D3D11_DSV_DIMENSION_TEXTURE2DMS:
+ mipSlice = 0;
+ arraySlice = 0;
+ break;
+
+ case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
+ mipSlice = 0;
+ arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
+ break;
+
+ case D3D11_RTV_DIMENSION_UNKNOWN:
+ UNIMPLEMENTED();
+ break;
+
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+{
+ mRenderer = Renderer11::makeRenderer11(renderer);
+ mTexture = tex;
+ mRenderTarget = rtv;
+ mDepthStencil = NULL;
+ mShaderResource = srv;
+ mSubresourceIndex = 0;
+
+ if (mRenderTarget && mTexture)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC desc;
+ mRenderTarget->GetDesc(&desc);
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ mTexture->GetDesc(&texDesc);
+
+ mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
+ mWidth = width;
+ mHeight = height;
+ mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
+
+ mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+ }
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+{
+ mRenderer = Renderer11::makeRenderer11(renderer);
+ mTexture = tex;
+ mRenderTarget = NULL;
+ mDepthStencil = dsv;
+ mShaderResource = srv;
+ mSubresourceIndex = 0;
+
+ if (mDepthStencil && mTexture)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+ mDepthStencil->GetDesc(&desc);
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ mTexture->GetDesc(&texDesc);
+
+ mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
+ mWidth = width;
+ mHeight = height;
+ mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0;
+
+ mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+ }
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
+{
+ mRenderer = Renderer11::makeRenderer11(renderer);
+ mTexture = NULL;
+ mRenderTarget = NULL;
+ mDepthStencil = NULL;
+ mShaderResource = NULL;
+
+ DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
+
+ int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
+ if (supportedSamples < 0)
+ {
+ gl::error(GL_OUT_OF_MEMORY);
+ return;
+ }
+
+ if (width > 0 && height > 0)
+ {
+ // Create texture resource
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width;
+ desc.Height = height;
+ desc.MipLevels = 1;
+ desc.ArraySize = 1;
+ desc.Format = requestedFormat;
+ desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+ desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
+
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ gl::error(GL_OUT_OF_MEMORY);
+ return;
+ }
+ ASSERT(SUCCEEDED(result));
+
+ if (depth)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = requestedFormat;
+ dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+ dsvDesc.Texture2D.MipSlice = 0;
+ dsvDesc.Flags = 0;
+ result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ ASSERT(SUCCEEDED(result));
+ }
+ else
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = requestedFormat;
+ rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+ rtvDesc.Texture2D.MipSlice = 0;
+ result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ gl::error(GL_OUT_OF_MEMORY);
+ return;
+ }
+ ASSERT(SUCCEEDED(result));
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = requestedFormat;
+ srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+ srvDesc.Texture2D.MostDetailedMip = 0;
+ srvDesc.Texture2D.MipLevels = 1;
+ result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ mRenderTarget->Release();
+ mRenderTarget = NULL;
+ gl::error(GL_OUT_OF_MEMORY);
+ return;
+ }
+ ASSERT(SUCCEEDED(result));
+ }
+ }
+
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = format;
+ mSamples = supportedSamples;
+ mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
+ mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
+}
+
+RenderTarget11::~RenderTarget11()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ }
+
+ if (mRenderTarget)
+ {
+ mRenderTarget->Release();
+ mRenderTarget = NULL;
+ }
+
+ if (mDepthStencil)
+ {
+ mDepthStencil->Release();
+ mDepthStencil = NULL;
+ }
+
+ if (mShaderResource)
+ {
+ mShaderResource->Release();
+ mShaderResource = NULL;
+ }
+}
+
+RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
+ return static_cast<rx::RenderTarget11*>(target);
+}
+
+ID3D11Texture2D *RenderTarget11::getTexture() const
+{
+ if (mTexture)
+ {
+ mTexture->AddRef();
+ }
+
+ return mTexture;
+}
+
+// Adds reference, caller must call Release
+ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
+{
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
+ return mRenderTarget;
+}
+
+// Adds reference, caller must call Release
+ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
+{
+ if (mDepthStencil)
+ {
+ mDepthStencil->AddRef();
+ }
+
+ return mDepthStencil;
+}
+
+// Adds reference, caller must call Release
+ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
+{
+ if (mShaderResource)
+ {
+ mShaderResource->AddRef();
+ }
+
+ return mShaderResource;
+}
+
+unsigned int RenderTarget11::getSubresourceIndex() const
+{
+ return mSubresourceIndex;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h
new file mode 100644
index 0000000000..dc697cf0e3
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#ifndef LIBGLESV2_RENDERER_RENDERTARGET11_H_
+#define LIBGLESV2_RENDERER_RENDERTARGET11_H_
+
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+
+class RenderTarget11 : public RenderTarget
+{
+ public:
+ RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+ RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+ RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth);
+ virtual ~RenderTarget11();
+
+ static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
+
+ // Adds reference, caller must call Release
+ ID3D11Texture2D *getTexture() const;
+
+ // Adds reference, caller must call Release
+ ID3D11RenderTargetView *getRenderTargetView() const;
+
+ // Adds reference, caller must call Release
+ ID3D11DepthStencilView *getDepthStencilView() const;
+
+ // Adds reference, caller must call Release
+ ID3D11ShaderResourceView *getShaderResourceView() const;
+
+ unsigned int getSubresourceIndex() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
+
+ unsigned int mSubresourceIndex;
+ ID3D11Texture2D *mTexture;
+ ID3D11RenderTargetView *mRenderTarget;
+ ID3D11DepthStencilView *mDepthStencil;
+ ID3D11ShaderResourceView *mShaderResource;
+
+ Renderer11 *mRenderer;
+};
+
+}
+
+#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp
new file mode 100644
index 0000000000..a84c709059
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp
@@ -0,0 +1,113 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
+// pointers retained by renderbuffers.
+
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
+{
+ mRenderer = Renderer9::makeRenderer9(renderer);
+ mRenderTarget = surface;
+
+ if (mRenderTarget)
+ {
+ D3DSURFACE_DESC description;
+ mRenderTarget->GetDesc(&description);
+
+ mWidth = description.Width;
+ mHeight = description.Height;
+
+ mInternalFormat = d3d9_gl::GetEquivalentFormat(description.Format);
+ mActualFormat = d3d9_gl::GetEquivalentFormat(description.Format);
+ mSamples = d3d9_gl::GetSamplesFromMultisampleType(description.MultiSampleType);
+ }
+}
+
+RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples)
+{
+ mRenderer = Renderer9::makeRenderer9(renderer);
+ mRenderTarget = NULL;
+
+ D3DFORMAT requestedFormat = gl_d3d9::ConvertRenderbufferFormat(format);
+ int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples);
+
+ if (supportedSamples == -1)
+ {
+ gl::error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ if (width > 0 && height > 0)
+ {
+ if (requestedFormat == D3DFMT_D24S8)
+ {
+ result = mRenderer->getDevice()->CreateDepthStencilSurface(width, height, requestedFormat,
+ gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples),
+ 0, FALSE, &mRenderTarget, NULL);
+ }
+ else
+ {
+ result = mRenderer->getDevice()->CreateRenderTarget(width, height, requestedFormat,
+ gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples),
+ 0, FALSE, &mRenderTarget, NULL);
+ }
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ {
+ gl::error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ ASSERT(SUCCEEDED(result));
+ }
+
+ mWidth = width;
+ mHeight = height;
+ mInternalFormat = format;
+ mSamples = supportedSamples;
+ mActualFormat = d3d9_gl::GetEquivalentFormat(requestedFormat);
+}
+
+RenderTarget9::~RenderTarget9()
+{
+ if (mRenderTarget)
+ {
+ mRenderTarget->Release();
+ }
+}
+
+RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
+ return static_cast<rx::RenderTarget9*>(target);
+}
+
+IDirect3DSurface9 *RenderTarget9::getSurface()
+{
+ // Caller is responsible for releasing the returned surface reference.
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
+ return mRenderTarget;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h
new file mode 100644
index 0000000000..faf8ad1c6d
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h
@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers
+// retained by Renderbuffers.
+
+#ifndef LIBGLESV2_RENDERER_RENDERTARGET9_H_
+#define LIBGLESV2_RENDERER_RENDERTARGET9_H_
+
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace rx
+{
+class Renderer;
+class Renderer9;
+
+class RenderTarget9 : public RenderTarget
+{
+ public:
+ RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface);
+ RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+ virtual ~RenderTarget9();
+
+ static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget);
+ IDirect3DSurface9 *getSurface();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(RenderTarget9);
+
+ IDirect3DSurface9 *mRenderTarget;
+
+ Renderer9 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERTARGET9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
new file mode 100644
index 0000000000..41cdb8b278
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
@@ -0,0 +1,201 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer.cpp: Implements EGL dependencies for creating and destroying Renderer instances.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/Program.h"
+#include "libGLESv2/renderer/Renderer.h"
+#if defined(ANGLE_ENABLE_D3D11)
+# include "libGLESv2/renderer/Renderer11.h"
+# define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT( 1, 0x876, 380 )
+#else
+# include "libGLESv2/renderer/Renderer9.h"
+#endif
+#include "libGLESv2/utilities.h"
+
+#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+#endif
+
+namespace rx
+{
+
+Renderer::Renderer(egl::Display *display) : mDisplay(display)
+{
+ mD3dCompilerModule = NULL;
+ mD3DCompileFunc = NULL;
+}
+
+Renderer::~Renderer()
+{
+ if (mD3dCompilerModule)
+ {
+ FreeLibrary(mD3dCompilerModule);
+ mD3dCompilerModule = NULL;
+ }
+}
+
+bool Renderer::initializeCompiler()
+{
+#if defined(ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES)
+ // Find a D3DCompiler module that had already been loaded based on a predefined list of versions.
+ static TCHAR* d3dCompilerNames[] = ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES;
+
+ for (size_t i = 0; i < ArraySize(d3dCompilerNames); ++i)
+ {
+ if (GetModuleHandleEx(0, d3dCompilerNames[i], &mD3dCompilerModule))
+ {
+ break;
+ }
+ }
+#else
+ // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with.
+ mD3dCompilerModule = LoadLibrary(D3DCOMPILER_DLL);
+#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES
+
+ if (!mD3dCompilerModule)
+ {
+ ERR("No D3D compiler module found - aborting!\n");
+ return false;
+ }
+
+ mD3DCompileFunc = reinterpret_cast<pCompileFunc>(GetProcAddress(mD3dCompilerModule, "D3DCompile"));
+ ASSERT(mD3DCompileFunc);
+
+ return mD3DCompileFunc != NULL;
+}
+
+// Compiles HLSL code into executable binaries
+ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags)
+{
+ if (!hlsl)
+ {
+ return NULL;
+ }
+
+ HRESULT result = S_OK;
+ UINT flags = 0;
+ std::string sourceText;
+ if (gl::perfActive())
+ {
+ flags |= D3DCOMPILE_DEBUG;
+
+#ifdef NDEBUG
+ flags |= optimizationFlags;
+#else
+ flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
+#endif
+
+ std::string sourcePath = getTempPath();
+ sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl);
+ writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size());
+ }
+ else
+ {
+ flags |= optimizationFlags;
+ sourceText = hlsl;
+ }
+
+ // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options.
+ // Try the default flags first and if compilation fails, try some alternatives.
+ const static UINT extraFlags[] =
+ {
+ 0,
+ D3DCOMPILE_AVOID_FLOW_CONTROL,
+ D3DCOMPILE_PREFER_FLOW_CONTROL
+ };
+
+ const static char * const extraFlagNames[] =
+ {
+ "default",
+ "avoid flow control",
+ "prefer flow control"
+ };
+
+ int attempts = alternateFlags ? ArraySize(extraFlags) : 1;
+ pD3DCompile compileFunc = reinterpret_cast<pD3DCompile>(mD3DCompileFunc);
+ for (int i = 0; i < attempts; ++i)
+ {
+ ID3DBlob *errorMessage = NULL;
+ ID3DBlob *binary = NULL;
+
+ result = compileFunc(hlsl, strlen(hlsl), gl::g_fakepath, NULL, NULL,
+ "main", profile, flags | extraFlags[i], 0, &binary, &errorMessage);
+ if (errorMessage)
+ {
+ const char *message = (const char*)errorMessage->GetBufferPointer();
+
+ infoLog.appendSanitized(message);
+ TRACE("\n%s", hlsl);
+ TRACE("\n%s", message);
+
+ errorMessage->Release();
+ errorMessage = NULL;
+ }
+
+ if (SUCCEEDED(result))
+ {
+ return (ShaderBlob*)binary;
+ }
+ else
+ {
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ {
+ return gl::error(GL_OUT_OF_MEMORY, (ShaderBlob*) NULL);
+ }
+
+ infoLog.append("Warning: D3D shader compilation failed with ");
+ infoLog.append(extraFlagNames[i]);
+ infoLog.append(" flags.");
+ if (i + 1 < attempts)
+ {
+ infoLog.append(" Retrying with ");
+ infoLog.append(extraFlagNames[i + 1]);
+ infoLog.append(".\n");
+ }
+ }
+ }
+
+ return NULL;
+}
+
+}
+
+extern "C"
+{
+
+rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, bool softwareDevice)
+{
+ rx::Renderer *renderer = NULL;
+ EGLint status = EGL_BAD_ALLOC;
+
+#if defined(ANGLE_ENABLE_D3D11)
+ renderer = new rx::Renderer11(display, hDc);
+#else
+ renderer = new rx::Renderer9(display, hDc, softwareDevice);
+#endif
+
+ if (renderer)
+ {
+ status = renderer->initialize();
+ }
+
+ if (status == EGL_SUCCESS)
+ {
+ return renderer;
+ }
+
+ return NULL;
+}
+
+void glDestroyRenderer(rx::Renderer *renderer)
+{
+ delete renderer;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
new file mode 100644
index 0000000000..656cb0f1bf
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h
@@ -0,0 +1,238 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer.h: Defines a back-end specific class that hides the details of the
+// implementation-specific renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER_H_
+#define LIBGLESV2_RENDERER_RENDERER_H_
+
+#include "libGLESv2/Uniform.h"
+#include "libGLESv2/angletypes.h"
+
+const int versionWindowsVista = MAKEWORD(0x00, 0x06);
+const int versionWindows7 = MAKEWORD(0x01, 0x06);
+
+// Return the version of the operating system in a format suitable for ordering
+// comparison.
+inline int getComparableOSVersion()
+{
+ DWORD version = GetVersion();
+ int majorVersion = LOBYTE(LOWORD(version));
+ int minorVersion = HIBYTE(LOWORD(version));
+ return MAKEWORD(minorVersion, majorVersion);
+}
+
+namespace egl
+{
+class Display;
+}
+
+namespace gl
+{
+class InfoLog;
+class ProgramBinary;
+class VertexAttribute;
+class Buffer;
+class Texture;
+class Framebuffer;
+}
+
+namespace rx
+{
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+class VertexBuffer;
+class IndexBuffer;
+class QueryImpl;
+class FenceImpl;
+class BufferStorage;
+class Blit;
+struct TranslatedIndexData;
+class ShaderExecutable;
+class SwapChain;
+class RenderTarget;
+class Image;
+class TextureStorage;
+
+typedef void * ShaderBlob;
+typedef void (*pCompileFunc)();
+
+struct ConfigDesc
+{
+ GLenum renderTargetFormat;
+ GLenum depthStencilFormat;
+ GLint multiSample;
+ bool fastConfig;
+};
+
+struct dx_VertexConstants
+{
+ float depthRange[4];
+ float viewAdjust[4];
+};
+
+struct dx_PixelConstants
+{
+ float depthRange[4];
+ float viewCoords[4];
+ float depthFront[4];
+};
+
+enum ShaderType
+{
+ SHADER_VERTEX,
+ SHADER_PIXEL,
+ SHADER_GEOMETRY
+};
+
+class Renderer
+{
+ public:
+ explicit Renderer(egl::Display *display);
+ virtual ~Renderer();
+
+ virtual EGLint initialize() = 0;
+ virtual bool resetDevice() = 0;
+
+ virtual int generateConfigs(ConfigDesc **configDescList) = 0;
+ virtual void deleteConfigs(ConfigDesc *configDescList) = 0;
+
+ virtual void sync(bool block) = 0;
+
+ virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler) = 0;
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0;
+
+ virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0;
+ virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
+ unsigned int sampleMask) = 0;
+ virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW) = 0;
+
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled) = 0;
+ virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport) = 0;
+
+ virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer) = 0;
+ virtual void applyShaders(gl::ProgramBinary *programBinary) = 0;
+ virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) = 0;
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount) = 0;
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) = 0;
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) = 0;
+
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances) = 0;
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) = 0;
+
+ virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) = 0;
+
+ virtual void markAllStateDirty() = 0;
+
+ // lost device
+ virtual void notifyDeviceLost() = 0;
+ virtual bool isDeviceLost() = 0;
+ virtual bool testDeviceLost(bool notify) = 0;
+ virtual bool testDeviceResettable() = 0;
+
+ // Renderer capabilities
+ virtual DWORD getAdapterVendor() const = 0;
+ virtual std::string getRendererDescription() const = 0;
+ virtual GUID getAdapterIdentifier() const = 0;
+
+ virtual bool getBGRATextureSupport() const = 0;
+ virtual bool getDXT1TextureSupport() = 0;
+ virtual bool getDXT3TextureSupport() = 0;
+ virtual bool getDXT5TextureSupport() = 0;
+ virtual bool getEventQuerySupport() = 0;
+ virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable) = 0;
+ virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable) = 0;
+ virtual bool getLuminanceTextureSupport() = 0;
+ virtual bool getLuminanceAlphaTextureSupport() = 0;
+ bool getVertexTextureSupport() const { return getMaxVertexTextureImageUnits() > 0; }
+ virtual unsigned int getMaxVertexTextureImageUnits() const = 0;
+ virtual unsigned int getMaxCombinedTextureImageUnits() const = 0;
+ virtual unsigned int getReservedVertexUniformVectors() const = 0;
+ virtual unsigned int getReservedFragmentUniformVectors() const = 0;
+ virtual unsigned int getMaxVertexUniformVectors() const = 0;
+ virtual unsigned int getMaxFragmentUniformVectors() const = 0;
+ virtual unsigned int getMaxVaryingVectors() const = 0;
+ virtual bool getNonPower2TextureSupport() const = 0;
+ virtual bool getDepthTextureSupport() const = 0;
+ virtual bool getOcclusionQuerySupport() const = 0;
+ virtual bool getInstancingSupport() const = 0;
+ virtual bool getTextureFilterAnisotropySupport() const = 0;
+ virtual float getTextureMaxAnisotropy() const = 0;
+ virtual bool getShareHandleSupport() const = 0;
+ virtual bool getDerivativeInstructionSupport() const = 0;
+ virtual bool getPostSubBufferSupport() const = 0;
+
+ virtual int getMajorShaderModel() const = 0;
+ virtual float getMaxPointSize() const = 0;
+ virtual int getMaxViewportDimension() const = 0;
+ virtual int getMaxTextureWidth() const = 0;
+ virtual int getMaxTextureHeight() const = 0;
+ virtual bool get32BitIndexSupport() const = 0;
+ virtual int getMinSwapInterval() const = 0;
+ virtual int getMaxSwapInterval() const = 0;
+
+ virtual GLsizei getMaxSupportedSamples() const = 0;
+
+ virtual unsigned int getMaxRenderTargets() const = 0;
+
+ // Pixel operations
+ virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) = 0;
+ virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) = 0;
+
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) = 0;
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) = 0;
+
+ virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ bool blitRenderTarget, bool blitDepthStencil) = 0;
+ virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) = 0;
+
+ // RenderTarget creation
+ virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth) = 0;
+ virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) = 0;
+
+ // Shader operations
+ virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type) = 0;
+ virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type) = 0;
+
+ // Image operations
+ virtual Image *createImage() = 0;
+ virtual void generateMipmap(Image *dest, Image *source) = 0;
+ virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain) = 0;
+ virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) = 0;
+ virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) = 0;
+
+ // Buffer creation
+ virtual VertexBuffer *createVertexBuffer() = 0;
+ virtual IndexBuffer *createIndexBuffer() = 0;
+ virtual BufferStorage *createBufferStorage() = 0;
+
+ // Query and Fence creation
+ virtual QueryImpl *createQuery(GLenum type) = 0;
+ virtual FenceImpl *createFence() = 0;
+
+ protected:
+ bool initializeCompiler();
+ ShaderBlob *compileToBinary(gl::InfoLog &infoLog, const char *hlsl, const char *profile, UINT optimizationFlags, bool alternateFlags);
+
+ egl::Display *mDisplay;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Renderer);
+
+ HMODULE mD3dCompilerModule;
+ pCompileFunc mD3DCompileFunc;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_RENDERER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
new file mode 100644
index 0000000000..cf083963e1
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp
@@ -0,0 +1,3531 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/utilities.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/RenderBuffer.h"
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/renderer/RenderTarget11.h"
+#include "libGLESv2/renderer/renderer11_utils.h"
+#include "libGLESv2/renderer/ShaderExecutable11.h"
+#include "libGLESv2/renderer/SwapChain11.h"
+#include "libGLESv2/renderer/Image11.h"
+#include "libGLESv2/renderer/VertexBuffer11.h"
+#include "libGLESv2/renderer/IndexBuffer11.h"
+#include "libGLESv2/renderer/BufferStorage11.h"
+#include "libGLESv2/renderer/VertexDataManager.h"
+#include "libGLESv2/renderer/IndexDataManager.h"
+#include "libGLESv2/renderer/TextureStorage11.h"
+#include "libGLESv2/renderer/Query11.h"
+#include "libGLESv2/renderer/Fence11.h"
+
+#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h"
+
+#include "libGLESv2/renderer/shaders/compiled/clear11vs.h"
+#include "libGLESv2/renderer/shaders/compiled/clear11ps.h"
+
+#include "libEGL/Display.h"
+
+#ifdef _DEBUG
+// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
+// and conformance tests. to enable all warnings, remove this define.
+#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
+#endif
+
+namespace rx
+{
+static const DXGI_FORMAT RenderTargetFormats[] =
+ {
+ DXGI_FORMAT_B8G8R8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM
+ };
+
+static const DXGI_FORMAT DepthStencilFormats[] =
+ {
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ DXGI_FORMAT_D16_UNORM
+ };
+
+enum
+{
+ MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
+};
+
+Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
+{
+ mVertexDataManager = NULL;
+ mIndexDataManager = NULL;
+
+ mLineLoopIB = NULL;
+ mTriangleFanIB = NULL;
+
+ mCopyResourcesInitialized = false;
+ mCopyVB = NULL;
+ mCopySampler = NULL;
+ mCopyIL = NULL;
+ mCopyVS = NULL;
+ mCopyRGBAPS = NULL;
+ mCopyRGBPS = NULL;
+ mCopyLumPS = NULL;
+ mCopyLumAlphaPS = NULL;
+
+ mClearResourcesInitialized = false;
+ mClearVB = NULL;
+ mClearIL = NULL;
+ mClearVS = NULL;
+ mClearPS = NULL;
+ mClearScissorRS = NULL;
+ mClearNoScissorRS = NULL;
+
+ mSyncQuery = NULL;
+
+ mD3d11Module = NULL;
+ mDxgiModule = NULL;
+
+ mDeviceLost = false;
+
+ mMaxSupportedSamples = 0;
+
+ mDevice = NULL;
+ mDeviceContext = NULL;
+ mDxgiAdapter = NULL;
+ mDxgiFactory = NULL;
+
+ mDriverConstantBufferVS = NULL;
+ mDriverConstantBufferPS = NULL;
+
+ mBGRATextureSupport = false;
+
+ mIsGeometryShaderActive = false;
+}
+
+Renderer11::~Renderer11()
+{
+ release();
+}
+
+Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
+ return static_cast<rx::Renderer11*>(renderer);
+}
+
+#ifndef __d3d11_1_h__
+#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
+#endif
+
+EGLint Renderer11::initialize()
+{
+ if (!initializeCompiler())
+ {
+ return EGL_NOT_INITIALIZED;
+ }
+
+ mDxgiModule = LoadLibrary(TEXT("dxgi.dll"));
+ mD3d11Module = LoadLibrary(TEXT("d3d11.dll"));
+
+ if (mD3d11Module == NULL || mDxgiModule == NULL)
+ {
+ ERR("Could not load D3D11 or DXGI library - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ // create the D3D11 device
+ ASSERT(mDevice == NULL);
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+
+ if (D3D11CreateDevice == NULL)
+ {
+ ERR("Could not retrieve D3D11CreateDevice address - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ };
+
+ HRESULT result = D3D11CreateDevice(NULL,
+ D3D_DRIVER_TYPE_HARDWARE,
+ NULL,
+ #if defined(_DEBUG)
+ D3D11_CREATE_DEVICE_DEBUG,
+ #else
+ 0,
+ #endif
+ featureLevels,
+ ArraySize(featureLevels),
+ D3D11_SDK_VERSION,
+ &mDevice,
+ &mFeatureLevel,
+ &mDeviceContext);
+
+ if (!mDevice || FAILED(result))
+ {
+ ERR("Could not create D3D11 device - aborting!\n");
+ return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer
+ }
+
+ IDXGIDevice *dxgiDevice = NULL;
+ result = mDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&dxgiDevice);
+
+ if (FAILED(result))
+ {
+ ERR("Could not query DXGI device - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter);
+
+ if (FAILED(result))
+ {
+ ERR("Could not retrieve DXGI adapter - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ dxgiDevice->Release();
+
+ mDxgiAdapter->GetDesc(&mAdapterDescription);
+ memset(mDescription, 0, sizeof(mDescription));
+ wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
+
+ result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory);
+
+ if (!mDxgiFactory || FAILED(result))
+ {
+ ERR("Could not create DXGI factory - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG)
+ ID3D11InfoQueue *infoQueue;
+ result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue);
+
+ if (SUCCEEDED(result))
+ {
+ D3D11_MESSAGE_ID hideMessages[] =
+ {
+ D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD,
+ D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD,
+ D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
+ };
+
+ D3D11_INFO_QUEUE_FILTER filter = {0};
+ filter.DenyList.NumIDs = ArraySize(hideMessages);
+ filter.DenyList.pIDList = hideMessages;
+
+ infoQueue->AddStorageFilterEntries(&filter);
+
+ infoQueue->Release();
+ }
+#endif
+
+ unsigned int maxSupportedSamples = 0;
+ unsigned int rtFormatCount = ArraySize(RenderTargetFormats);
+ unsigned int dsFormatCount = ArraySize(DepthStencilFormats);
+ for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i)
+ {
+ DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount];
+ if (format != DXGI_FORMAT_UNKNOWN)
+ {
+ UINT formatSupport;
+ result = mDevice->CheckFormatSupport(format, &formatSupport);
+ if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
+ {
+ MultisampleSupportInfo supportInfo;
+
+ for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++)
+ {
+ result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]);
+ if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0)
+ {
+ maxSupportedSamples = std::max(j, maxSupportedSamples);
+ }
+ else
+ {
+ supportInfo.qualityLevels[j - 1] = 0;
+ }
+ }
+
+ mMultisampleSupportMap.insert(std::make_pair(format, supportInfo));
+ }
+ }
+ }
+ mMaxSupportedSamples = maxSupportedSamples;
+
+ initializeDevice();
+
+ // BGRA texture support is optional in feature levels 10 and 10_1
+ UINT formatSupport;
+ result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
+ if (FAILED(result))
+ {
+ ERR("Error checking BGRA format support: 0x%08X", result);
+ }
+ else
+ {
+ const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
+ mBGRATextureSupport = (formatSupport & flags) == flags;
+ }
+
+ // Check floating point texture support
+ static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
+ static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
+ static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
+
+ DXGI_FORMAT float16Formats[] =
+ {
+ DXGI_FORMAT_R16_FLOAT,
+ DXGI_FORMAT_R16G16_FLOAT,
+ DXGI_FORMAT_R16G16B16A16_FLOAT,
+ };
+
+ DXGI_FORMAT float32Formats[] =
+ {
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ };
+
+ mFloat16TextureSupport = true;
+ mFloat16FilterSupport = true;
+ mFloat16RenderSupport = true;
+ for (unsigned int i = 0; i < ArraySize(float16Formats); i++)
+ {
+ if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport)))
+ {
+ mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
+ mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
+ mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
+ }
+ else
+ {
+ mFloat16TextureSupport = false;
+ mFloat16RenderSupport = false;
+ mFloat16FilterSupport = false;
+ }
+ }
+
+ mFloat32TextureSupport = true;
+ mFloat32FilterSupport = true;
+ mFloat32RenderSupport = true;
+ for (unsigned int i = 0; i < ArraySize(float32Formats); i++)
+ {
+ if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport)))
+ {
+ mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags;
+ mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags;
+ mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags;
+ }
+ else
+ {
+ mFloat32TextureSupport = false;
+ mFloat32FilterSupport = false;
+ mFloat32RenderSupport = false;
+ }
+ }
+
+ // Check compressed texture support
+ const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
+
+ if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport)))
+ {
+ mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+ }
+ else
+ {
+ mDXT1TextureSupport = false;
+ }
+
+ if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport)))
+ {
+ mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+ }
+ else
+ {
+ mDXT3TextureSupport = false;
+ }
+
+ if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport)))
+ {
+ mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+ }
+ else
+ {
+ mDXT5TextureSupport = false;
+ }
+
+ // Check depth texture support
+ DXGI_FORMAT depthTextureFormats[] =
+ {
+ DXGI_FORMAT_D16_UNORM,
+ DXGI_FORMAT_D24_UNORM_S8_UINT,
+ };
+
+ static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
+ D3D11_FORMAT_SUPPORT_TEXTURE2D;
+
+ mDepthTextureSupport = true;
+ for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++)
+ {
+ if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport)))
+ {
+ mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags);
+ }
+ else
+ {
+ mDepthTextureSupport = false;
+ }
+ }
+
+ return EGL_SUCCESS;
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+void Renderer11::initializeDevice()
+{
+ mStateCache.initialize(mDevice);
+ mInputLayoutCache.initialize(mDevice, mDeviceContext);
+
+ ASSERT(!mVertexDataManager && !mIndexDataManager);
+ mVertexDataManager = new VertexDataManager(this);
+ mIndexDataManager = new IndexDataManager(this);
+
+ markAllStateDirty();
+}
+
+int Renderer11::generateConfigs(ConfigDesc **configDescList)
+{
+ unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
+ unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
+ (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
+ int numConfigs = 0;
+
+ for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
+ {
+ for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+ {
+ DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
+
+ UINT formatSupport = 0;
+ HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport);
+
+ if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET))
+ {
+ DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
+
+ bool depthStencilFormatOK = true;
+
+ if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ UINT formatSupport = 0;
+ result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport);
+ depthStencilFormatOK = SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
+ }
+
+ if (depthStencilFormatOK)
+ {
+ ConfigDesc newConfig;
+ newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
+ newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
+ newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
+ newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast
+
+ (*configDescList)[numConfigs++] = newConfig;
+ }
+ }
+ }
+ }
+
+ return numConfigs;
+}
+
+void Renderer11::deleteConfigs(ConfigDesc *configDescList)
+{
+ delete [] (configDescList);
+}
+
+void Renderer11::sync(bool block)
+{
+ if (block)
+ {
+ HRESULT result;
+
+ if (!mSyncQuery)
+ {
+ D3D11_QUERY_DESC queryDesc;
+ queryDesc.Query = D3D11_QUERY_EVENT;
+ queryDesc.MiscFlags = 0;
+
+ result = mDevice->CreateQuery(&queryDesc, &mSyncQuery);
+ ASSERT(SUCCEEDED(result));
+ }
+
+ mDeviceContext->End(mSyncQuery);
+ mDeviceContext->Flush();
+
+ do
+ {
+ result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+
+ // Keep polling, but allow other threads to do something useful first
+ Sleep(0);
+
+ if (testDeviceLost(true))
+ {
+ return;
+ }
+ }
+ while (result == S_FALSE);
+ }
+ else
+ {
+ mDeviceContext->Flush();
+ }
+}
+
+SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+{
+ return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+}
+
+void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+{
+ if (type == gl::SAMPLER_PIXEL)
+ {
+ if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
+ {
+ ERR("Pixel shader sampler index %i is not valid.", index);
+ return;
+ }
+
+ if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ {
+ ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
+
+ if (!dxSamplerState)
+ {
+ ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
+ "sampler state for pixel shaders at slot %i.", index);
+ }
+
+ mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState);
+
+ mCurPixelSamplerStates[index] = samplerState;
+ }
+
+ mForceSetPixelSamplerStates[index] = false;
+ }
+ else if (type == gl::SAMPLER_VERTEX)
+ {
+ if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
+ {
+ ERR("Vertex shader sampler index %i is not valid.", index);
+ return;
+ }
+
+ if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+ {
+ ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
+
+ if (!dxSamplerState)
+ {
+ ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default"
+ "sampler state for vertex shaders at slot %i.", index);
+ }
+
+ mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState);
+
+ mCurVertexSamplerStates[index] = samplerState;
+ }
+
+ mForceSetVertexSamplerStates[index] = false;
+ }
+ else UNREACHABLE();
+}
+
+void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
+{
+ ID3D11ShaderResourceView *textureSRV = NULL;
+ unsigned int serial = 0;
+ bool forceSetTexture = false;
+
+ if (texture)
+ {
+ TextureStorageInterface *texStorage = texture->getNativeTexture();
+ if (texStorage)
+ {
+ TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance());
+ textureSRV = storage11->getSRV();
+ }
+
+ // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
+ // missing the shader resource view
+ ASSERT(textureSRV != NULL);
+
+ serial = texture->getTextureSerial();
+ forceSetTexture = texture->hasDirtyImages();
+ }
+
+ if (type == gl::SAMPLER_PIXEL)
+ {
+ if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS)
+ {
+ ERR("Pixel shader sampler index %i is not valid.", index);
+ return;
+ }
+
+ if (forceSetTexture || mCurPixelTextureSerials[index] != serial)
+ {
+ mDeviceContext->PSSetShaderResources(index, 1, &textureSRV);
+ }
+
+ mCurPixelTextureSerials[index] = serial;
+ }
+ else if (type == gl::SAMPLER_VERTEX)
+ {
+ if (index < 0 || index >= (int)getMaxVertexTextureImageUnits())
+ {
+ ERR("Vertex shader sampler index %i is not valid.", index);
+ return;
+ }
+
+ if (forceSetTexture || mCurVertexTextureSerials[index] != serial)
+ {
+ mDeviceContext->VSSetShaderResources(index, 1, &textureSRV);
+ }
+
+ mCurVertexTextureSerials[index] = serial;
+ }
+ else UNREACHABLE();
+}
+
+void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState)
+{
+ if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0)
+ {
+ ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
+ mCurDepthSize);
+ if (!dxRasterState)
+ {
+ ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default"
+ "rasterizer state.");
+ }
+
+ mDeviceContext->RSSetState(dxRasterState);
+
+ mCurRasterState = rasterState;
+ }
+
+ mForceSetRasterState = false;
+}
+
+void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
+ unsigned int sampleMask)
+{
+ if (mForceSetBlendState ||
+ memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 ||
+ memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 ||
+ sampleMask != mCurSampleMask)
+ {
+ ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState);
+ if (!dxBlendState)
+ {
+ ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default "
+ "blend state.");
+ }
+
+ const float blendColors[] = { blendColor.red, blendColor.green, blendColor.blue, blendColor.alpha };
+ mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask);
+
+ mCurBlendState = blendState;
+ mCurBlendColor = blendColor;
+ mCurSampleMask = sampleMask;
+ }
+
+ mForceSetBlendState = false;
+}
+
+void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW)
+{
+ if (mForceSetDepthStencilState ||
+ memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
+ stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
+ {
+ if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
+ stencilRef != stencilBackRef ||
+ depthStencilState.stencilMask != depthStencilState.stencilBackMask)
+ {
+ ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are "
+ "invalid under WebGL.");
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
+ if (!dxDepthStencilState)
+ {
+ ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, "
+ "setting the default depth stencil state.");
+ }
+
+ mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast<UINT>(stencilRef));
+
+ mCurDepthStencilState = depthStencilState;
+ mCurStencilRef = stencilRef;
+ mCurStencilBackRef = stencilBackRef;
+ }
+
+ mForceSetDepthStencilState = false;
+}
+
+void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
+{
+ if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+ enabled != mScissorEnabled)
+ {
+ if (enabled)
+ {
+ D3D11_RECT rect;
+ rect.left = std::max(0, scissor.x);
+ rect.top = std::max(0, scissor.y);
+ rect.right = scissor.x + std::max(0, scissor.width);
+ rect.bottom = scissor.y + std::max(0, scissor.height);
+
+ mDeviceContext->RSSetScissorRects(1, &rect);
+ }
+
+ if (enabled != mScissorEnabled)
+ {
+ mForceSetRasterState = true;
+ }
+
+ mCurScissor = scissor;
+ mScissorEnabled = enabled;
+ }
+
+ mForceSetScissor = false;
+}
+
+bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport)
+{
+ gl::Rectangle actualViewport = viewport;
+ float actualZNear = gl::clamp01(zNear);
+ float actualZFar = gl::clamp01(zFar);
+ if (ignoreViewport)
+ {
+ actualViewport.x = 0;
+ actualViewport.y = 0;
+ actualViewport.width = mRenderTargetDesc.width;
+ actualViewport.height = mRenderTargetDesc.height;
+ actualZNear = 0.0f;
+ actualZFar = 1.0f;
+ }
+
+ // Get D3D viewport bounds, which depends on the feature level
+ const Range& viewportBounds = getViewportBounds();
+
+ // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
+ D3D11_VIEWPORT dxViewport;
+ dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
+ dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
+ dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
+ dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
+ dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast<int>(dxViewport.TopLeftX));
+ dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast<int>(dxViewport.TopLeftY));
+ dxViewport.MinDepth = actualZNear;
+ dxViewport.MaxDepth = actualZFar;
+
+ if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
+ {
+ return false; // Nothing to render
+ }
+
+ bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+ actualZNear != mCurNear || actualZFar != mCurFar;
+
+ if (viewportChanged)
+ {
+ mDeviceContext->RSSetViewports(1, &dxViewport);
+
+ mCurViewport = actualViewport;
+ mCurNear = actualZNear;
+ mCurFar = actualZFar;
+
+ mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f;
+ mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
+ mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
+ mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+
+ mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+ mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+
+ mVertexConstants.depthRange[0] = actualZNear;
+ mVertexConstants.depthRange[1] = actualZFar;
+ mVertexConstants.depthRange[2] = actualZFar - actualZNear;
+
+ mPixelConstants.depthRange[0] = actualZNear;
+ mPixelConstants.depthRange[1] = actualZFar;
+ mPixelConstants.depthRange[2] = actualZFar - actualZNear;
+ }
+
+ mForceSetViewport = false;
+ return true;
+}
+
+bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+ D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
+
+ switch (mode)
+ {
+ case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; break;
+ case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; break;
+ case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
+ case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; break;
+ case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
+ case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; break;
+ // emulate fans via rewriting index buffer
+ case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; break;
+ default:
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ mDeviceContext->IASetPrimitiveTopology(primitiveTopology);
+
+ return count > 0;
+}
+
+bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
+{
+ // Get the color render buffer and serial
+ // Also extract the render target dimensions and view
+ unsigned int renderTargetWidth = 0;
+ unsigned int renderTargetHeight = 0;
+ GLenum renderTargetFormat = 0;
+ unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
+ ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
+ bool missingColorRenderTarget = true;
+
+ for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment);
+
+ if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE)
+ {
+ // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order)
+ ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
+
+ gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment);
+
+ if (!colorbuffer)
+ {
+ ERR("render target pointer unexpectedly null.");
+ return false;
+ }
+
+ // check for zero-sized default framebuffer, which is a special case.
+ // in this case we do not wish to modify any state and just silently return false.
+ // this will not report any gl error but will cause the calling method to return.
+ if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
+ {
+ return false;
+ }
+
+ renderTargetSerials[colorAttachment] = colorbuffer->getSerial();
+
+ // Extract the render target dimensions and view
+ RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+ if (!renderTarget)
+ {
+ ERR("render target pointer unexpectedly null.");
+ return false;
+ }
+
+ framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView();
+ if (!framebufferRTVs[colorAttachment])
+ {
+ ERR("render target view pointer unexpectedly null.");
+ return false;
+ }
+
+ if (missingColorRenderTarget)
+ {
+ renderTargetWidth = colorbuffer->getWidth();
+ renderTargetHeight = colorbuffer->getHeight();
+ renderTargetFormat = colorbuffer->getActualFormat();
+ missingColorRenderTarget = false;
+ }
+ }
+ }
+
+ // Get the depth stencil render buffer and serials
+ gl::Renderbuffer *depthStencil = NULL;
+ unsigned int depthbufferSerial = 0;
+ unsigned int stencilbufferSerial = 0;
+ if (framebuffer->getDepthbufferType() != GL_NONE)
+ {
+ depthStencil = framebuffer->getDepthbuffer();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ SafeRelease(framebufferRTVs);
+ return false;
+ }
+
+ depthbufferSerial = depthStencil->getSerial();
+ }
+ else if (framebuffer->getStencilbufferType() != GL_NONE)
+ {
+ depthStencil = framebuffer->getStencilbuffer();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ SafeRelease(framebufferRTVs);
+ return false;
+ }
+
+ stencilbufferSerial = depthStencil->getSerial();
+ }
+
+ // Extract the depth stencil sizes and view
+ unsigned int depthSize = 0;
+ unsigned int stencilSize = 0;
+ ID3D11DepthStencilView* framebufferDSV = NULL;
+ if (depthStencil)
+ {
+ RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil());
+ if (!depthStencilRenderTarget)
+ {
+ ERR("render target pointer unexpectedly null.");
+ SafeRelease(framebufferRTVs);
+ return false;
+ }
+
+ framebufferDSV = depthStencilRenderTarget->getDepthStencilView();
+ if (!framebufferDSV)
+ {
+ ERR("depth stencil view pointer unexpectedly null.");
+ SafeRelease(framebufferRTVs);
+ return false;
+ }
+
+ // If there is no render buffer, the width, height and format values come from
+ // the depth stencil
+ if (missingColorRenderTarget)
+ {
+ renderTargetWidth = depthStencil->getWidth();
+ renderTargetHeight = depthStencil->getHeight();
+ renderTargetFormat = depthStencil->getActualFormat();
+ }
+
+ depthSize = depthStencil->getDepthSize();
+ stencilSize = depthStencil->getStencilSize();
+ }
+
+ // Apply the render target and depth stencil
+ if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
+ memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
+ depthbufferSerial != mAppliedDepthbufferSerial ||
+ stencilbufferSerial != mAppliedStencilbufferSerial)
+ {
+ mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
+
+ mRenderTargetDesc.width = renderTargetWidth;
+ mRenderTargetDesc.height = renderTargetHeight;
+ mRenderTargetDesc.format = renderTargetFormat;
+ mForceSetViewport = true;
+ mForceSetScissor = true;
+
+ if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
+ {
+ mCurDepthSize = depthSize;
+ mForceSetRasterState = true;
+ }
+
+ mCurStencilSize = stencilSize;
+
+ for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ {
+ mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
+ }
+ mAppliedDepthbufferSerial = depthbufferSerial;
+ mAppliedStencilbufferSerial = stencilbufferSerial;
+ mRenderTargetDescInitialized = true;
+ mDepthStencilInitialized = true;
+ }
+
+ SafeRelease(framebufferRTVs);
+ SafeRelease(framebufferDSV);
+
+ return true;
+}
+
+GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+{
+ TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
+ GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+ if (err != GL_NO_ERROR)
+ {
+ return err;
+ }
+
+ return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
+}
+
+GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+ GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+
+ if (err == GL_NO_ERROR)
+ {
+ if (indexInfo->storage)
+ {
+ if (indexInfo->serial != mAppliedStorageIBSerial || indexInfo->startOffset != mAppliedIBOffset)
+ {
+ BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage);
+ IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
+
+ mDeviceContext->IASetIndexBuffer(storage->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset);
+
+ mAppliedIBSerial = 0;
+ mAppliedStorageIBSerial = storage->getSerial();
+ mAppliedIBOffset = indexInfo->startOffset;
+ }
+ }
+ else if (indexInfo->serial != mAppliedIBSerial || indexInfo->startOffset != mAppliedIBOffset)
+ {
+ IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer);
+
+ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset);
+
+ mAppliedIBSerial = indexInfo->serial;
+ mAppliedStorageIBSerial = 0;
+ mAppliedIBOffset = indexInfo->startOffset;
+ }
+ }
+
+ return err;
+}
+
+void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+ if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, GL_NONE, NULL, 0, NULL);
+ }
+ else if (mode == GL_TRIANGLE_FAN)
+ {
+ drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
+ }
+ else if (instances > 0)
+ {
+ mDeviceContext->DrawInstanced(count, instances, 0, 0);
+ }
+ else
+ {
+ mDeviceContext->Draw(count, 0);
+ }
+}
+
+void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances)
+{
+ if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+ }
+ else if (mode == GL_TRIANGLE_FAN)
+ {
+ drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
+ }
+ else if (instances > 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast<int>(indexInfo.minIndex), 0);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexed(count, 0, -static_cast<int>(indexInfo.minIndex));
+ }
+}
+
+void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+ // Get the raw indices for an indexed draw
+ if (type != GL_NONE && elementArrayBuffer)
+ {
+ gl::Buffer *indexBuffer = elementArrayBuffer;
+ BufferStorage *storage = indexBuffer->getStorage();
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ const int spaceNeeded = (count + 1) * sizeof(unsigned int);
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+ {
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ void* mappedMemory = NULL;
+ int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
+ {
+ ERR("Could not map index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ unsigned int indexBufferOffset = static_cast<unsigned int>(offset);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
+ {
+ IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer());
+
+ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
+ mAppliedIBSerial = mLineLoopIB->getSerial();
+ mAppliedStorageIBSerial = 0;
+ mAppliedIBOffset = indexBufferOffset;
+ }
+
+ mDeviceContext->DrawIndexed(count + 1, 0, -minIndex);
+}
+
+void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
+{
+ // Get the raw indices for an indexed draw
+ if (type != GL_NONE && elementArrayBuffer)
+ {
+ gl::Buffer *indexBuffer = elementArrayBuffer;
+ BufferStorage *storage = indexBuffer->getStorage();
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
+ if (!mTriangleFanIB)
+ {
+ mTriangleFanIB = new StreamingIndexBufferInterface(this);
+ if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ {
+ delete mTriangleFanIB;
+ mTriangleFanIB = NULL;
+
+ ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ const int numTris = count - 2;
+ const int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+ if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+ {
+ ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ void* mappedMemory = NULL;
+ int offset = mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
+ {
+ ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+ unsigned int indexBufferOffset = static_cast<unsigned int>(offset);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = 0;
+ data[i*3 + 1] = i + 1;
+ data[i*3 + 2] = i + 2;
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLubyte*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLubyte*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLubyte*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLushort*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLushort*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLushort*>(indices)[i + 2];
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < numTris; i++)
+ {
+ data[i*3 + 0] = static_cast<const GLuint*>(indices)[0];
+ data[i*3 + 1] = static_cast<const GLuint*>(indices)[i + 1];
+ data[i*3 + 2] = static_cast<const GLuint*>(indices)[i + 2];
+ }
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!mTriangleFanIB->unmapBuffer())
+ {
+ ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ if (mAppliedIBSerial != mTriangleFanIB->getSerial() || mAppliedIBOffset != indexBufferOffset)
+ {
+ IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer());
+
+ mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset);
+ mAppliedIBSerial = mTriangleFanIB->getSerial();
+ mAppliedStorageIBSerial = 0;
+ mAppliedIBOffset = indexBufferOffset;
+ }
+
+ if (instances > 0)
+ {
+ mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
+ }
+ else
+ {
+ mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex);
+ }
+}
+
+void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
+{
+ unsigned int programBinarySerial = programBinary->getSerial();
+ const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial);
+
+ if (updateProgramState)
+ {
+ ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+ ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
+
+ ID3D11VertexShader *vertexShader = NULL;
+ if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader();
+
+ ID3D11PixelShader *pixelShader = NULL;
+ if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader();
+
+ mDeviceContext->PSSetShader(pixelShader, NULL, 0);
+ mDeviceContext->VSSetShader(vertexShader, NULL, 0);
+
+ programBinary->dirtyAllUniforms();
+
+ mAppliedProgramBinarySerial = programBinarySerial;
+ }
+
+ // Only use the geometry shader currently for point sprite drawing
+ const bool usesGeometryShader = (programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode);
+
+ if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive)
+ {
+ if (usesGeometryShader)
+ {
+ ShaderExecutable *geometryExe = programBinary->getGeometryExecutable();
+ ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader();
+ mDeviceContext->GSSetShader(geometryShader, NULL, 0);
+ }
+ else
+ {
+ mDeviceContext->GSSetShader(NULL, NULL, 0);
+ }
+
+ mIsGeometryShaderActive = usesGeometryShader;
+ }
+}
+
+void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
+{
+ ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable());
+ ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable());
+
+ unsigned int totalRegisterCountVS = 0;
+ unsigned int totalRegisterCountPS = 0;
+
+ bool vertexUniformsDirty = false;
+ bool pixelUniformsDirty = false;
+
+ for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
+ {
+ const gl::Uniform *uniform = *uniform_iterator;
+
+ if (uniform->vsRegisterIndex >= 0)
+ {
+ totalRegisterCountVS += uniform->registerCount;
+ vertexUniformsDirty = vertexUniformsDirty || uniform->dirty;
+ }
+
+ if (uniform->psRegisterIndex >= 0)
+ {
+ totalRegisterCountPS += uniform->registerCount;
+ pixelUniformsDirty = pixelUniformsDirty || uniform->dirty;
+ }
+ }
+
+ ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS);
+ ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS);
+
+ float (*mapVS)[4] = NULL;
+ float (*mapPS)[4] = NULL;
+
+ if (totalRegisterCountVS > 0 && vertexUniformsDirty)
+ {
+ D3D11_MAPPED_SUBRESOURCE map = {0};
+ HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
+ ASSERT(SUCCEEDED(result));
+ mapVS = (float(*)[4])map.pData;
+ }
+
+ if (totalRegisterCountPS > 0 && pixelUniformsDirty)
+ {
+ D3D11_MAPPED_SUBRESOURCE map = {0};
+ HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map);
+ ASSERT(SUCCEEDED(result));
+ mapPS = (float(*)[4])map.pData;
+ }
+
+ for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++)
+ {
+ gl::Uniform *uniform = *uniform_iterator;
+
+ if (uniform->type != GL_SAMPLER_2D && uniform->type != GL_SAMPLER_CUBE)
+ {
+ if (uniform->vsRegisterIndex >= 0 && mapVS)
+ {
+ memcpy(mapVS + uniform->vsRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4]));
+ }
+
+ if (uniform->psRegisterIndex >= 0 && mapPS)
+ {
+ memcpy(mapPS + uniform->psRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4]));
+ }
+ }
+
+ uniform->dirty = false;
+ }
+
+ if (mapVS)
+ {
+ mDeviceContext->Unmap(vertexConstantBuffer, 0);
+ }
+
+ if (mapPS)
+ {
+ mDeviceContext->Unmap(pixelConstantBuffer, 0);
+ }
+
+ mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer);
+ mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer);
+
+ // Driver uniforms
+ if (!mDriverConstantBufferVS)
+ {
+ D3D11_BUFFER_DESC constantBufferDescription = {0};
+ constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
+ constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
+ constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ constantBufferDescription.CPUAccessFlags = 0;
+ constantBufferDescription.MiscFlags = 0;
+ constantBufferDescription.StructureByteStride = 0;
+
+ HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS);
+ ASSERT(SUCCEEDED(result));
+
+ mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS);
+ }
+
+ if (!mDriverConstantBufferPS)
+ {
+ D3D11_BUFFER_DESC constantBufferDescription = {0};
+ constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
+ constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
+ constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ constantBufferDescription.CPUAccessFlags = 0;
+ constantBufferDescription.MiscFlags = 0;
+ constantBufferDescription.StructureByteStride = 0;
+
+ HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS);
+ ASSERT(SUCCEEDED(result));
+
+ mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS);
+ }
+
+ if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
+ {
+ mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0);
+ memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants));
+ }
+
+ if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
+ {
+ mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0);
+ memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants));
+ }
+
+ // needed for the point sprite geometry shader
+ mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS);
+}
+
+void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+{
+ bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
+ bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
+ !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
+ clearParams.colorMaskBlue && alphaUnmasked);
+
+ unsigned int stencilUnmasked = 0x0;
+ if (frameBuffer->hasStencil())
+ {
+ unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
+ stencilUnmasked = (0x1 << stencilSize) - 1;
+ }
+ bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
+ (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+
+ bool needScissoredClear = mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 ||
+ mCurScissor.x + mCurScissor.width < mRenderTargetDesc.width ||
+ mCurScissor.y + mCurScissor.height < mRenderTargetDesc.height);
+
+ if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear)
+ {
+ maskedClear(clearParams);
+ }
+ else
+ {
+ if (clearParams.mask & GL_COLOR_BUFFER_BIT)
+ {
+ for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ if (frameBuffer->isEnabledColorAttachment(colorAttachment))
+ {
+ gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer(colorAttachment);
+ if (renderbufferObject)
+ {
+ RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget());
+ if (!renderTarget)
+ {
+ ERR("render target pointer unexpectedly null.");
+ return;
+ }
+
+ ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView();
+ if (!framebufferRTV)
+ {
+ ERR("render target view pointer unexpectedly null.");
+ return;
+ }
+
+ const float clearValues[4] = { clearParams.colorClearValue.red,
+ clearParams.colorClearValue.green,
+ clearParams.colorClearValue.blue,
+ clearParams.colorClearValue.alpha };
+ mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues);
+
+ framebufferRTV->Release();
+ }
+ }
+ }
+ }
+ if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT)
+ {
+ gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer();
+ if (renderbufferObject)
+ {
+ RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getDepthStencil());
+ if (!renderTarget)
+ {
+ ERR("render target pointer unexpectedly null.");
+ return;
+ }
+
+ ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView();
+ if (!framebufferDSV)
+ {
+ ERR("depth stencil view pointer unexpectedly null.");
+ return;
+ }
+
+ UINT clearFlags = 0;
+ if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
+ {
+ clearFlags |= D3D11_CLEAR_DEPTH;
+ }
+ if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
+ {
+ clearFlags |= D3D11_CLEAR_STENCIL;
+ }
+
+ float depthClear = gl::clamp01(clearParams.depthClearValue);
+ UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF;
+
+ mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
+
+ framebufferDSV->Release();
+ }
+ }
+ }
+}
+
+void Renderer11::maskedClear(const gl::ClearParameters &clearParams)
+{
+ HRESULT result;
+
+ if (!mClearResourcesInitialized)
+ {
+ ASSERT(!mClearVB && !mClearVS && !mClearPS && !mClearScissorRS && !mClearNoScissorRS);
+
+ D3D11_BUFFER_DESC vbDesc;
+ vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4;
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
+ vbDesc.StructureByteStride = 0;
+
+ result = mDevice->CreateBuffer(&vbDesc, NULL, &mClearVB);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearVB, "Renderer11 masked clear vertex buffer");
+
+ D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &mClearIL);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearIL, "Renderer11 masked clear input layout");
+
+ result = mDevice->CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &mClearVS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader");
+
+ result = mDevice->CreatePixelShader(g_PS_Clear, sizeof(g_PS_Clear), NULL, &mClearPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearPS, "Renderer11 masked clear pixel shader");
+
+ D3D11_RASTERIZER_DESC rsScissorDesc;
+ rsScissorDesc.FillMode = D3D11_FILL_SOLID;
+ rsScissorDesc.CullMode = D3D11_CULL_NONE;
+ rsScissorDesc.FrontCounterClockwise = FALSE;
+ rsScissorDesc.DepthBias = 0;
+ rsScissorDesc.DepthBiasClamp = 0.0f;
+ rsScissorDesc.SlopeScaledDepthBias = 0.0f;
+ rsScissorDesc.DepthClipEnable = FALSE;
+ rsScissorDesc.ScissorEnable = TRUE;
+ rsScissorDesc.MultisampleEnable = FALSE;
+ rsScissorDesc.AntialiasedLineEnable = FALSE;
+
+ result = mDevice->CreateRasterizerState(&rsScissorDesc, &mClearScissorRS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearScissorRS, "Renderer11 masked clear scissor rasterizer state");
+
+ D3D11_RASTERIZER_DESC rsNoScissorDesc;
+ rsNoScissorDesc.FillMode = D3D11_FILL_SOLID;
+ rsNoScissorDesc.CullMode = D3D11_CULL_NONE;
+ rsNoScissorDesc.FrontCounterClockwise = FALSE;
+ rsNoScissorDesc.DepthBias = 0;
+ rsNoScissorDesc.DepthBiasClamp = 0.0f;
+ rsNoScissorDesc.SlopeScaledDepthBias = 0.0f;
+ rsNoScissorDesc.DepthClipEnable = FALSE;
+ rsNoScissorDesc.ScissorEnable = FALSE;
+ rsNoScissorDesc.MultisampleEnable = FALSE;
+ rsNoScissorDesc.AntialiasedLineEnable = FALSE;
+
+ result = mDevice->CreateRasterizerState(&rsNoScissorDesc, &mClearNoScissorRS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mClearNoScissorRS, "Renderer11 masked clear no scissor rasterizer state");
+
+ mClearResourcesInitialized = true;
+ }
+
+ // Prepare the depth stencil state to write depth values if the depth should be cleared
+ // and stencil values if the stencil should be cleared
+ gl::DepthStencilState glDSState;
+ glDSState.depthTest = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0;
+ glDSState.depthFunc = GL_ALWAYS;
+ glDSState.depthMask = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0;
+ glDSState.stencilTest = (clearParams.mask & GL_STENCIL_BUFFER_BIT) != 0;
+ glDSState.stencilFunc = GL_ALWAYS;
+ glDSState.stencilMask = 0;
+ glDSState.stencilFail = GL_REPLACE;
+ glDSState.stencilPassDepthFail = GL_REPLACE;
+ glDSState.stencilPassDepthPass = GL_REPLACE;
+ glDSState.stencilWritemask = clearParams.stencilWriteMask;
+ glDSState.stencilBackFunc = GL_ALWAYS;
+ glDSState.stencilBackMask = 0;
+ glDSState.stencilBackFail = GL_REPLACE;
+ glDSState.stencilBackPassDepthFail = GL_REPLACE;
+ glDSState.stencilBackPassDepthPass = GL_REPLACE;
+ glDSState.stencilBackWritemask = clearParams.stencilWriteMask;
+
+ int stencilClear = clearParams.stencilClearValue & 0x000000FF;
+
+ ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState);
+
+ // Prepare the blend state to use a write mask if the color buffer should be cleared
+ gl::BlendState glBlendState;
+ glBlendState.blend = false;
+ glBlendState.sourceBlendRGB = GL_ONE;
+ glBlendState.destBlendRGB = GL_ZERO;
+ glBlendState.sourceBlendAlpha = GL_ONE;
+ glBlendState.destBlendAlpha = GL_ZERO;
+ glBlendState.blendEquationRGB = GL_FUNC_ADD;
+ glBlendState.blendEquationAlpha = GL_FUNC_ADD;
+ glBlendState.colorMaskRed = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false;
+ glBlendState.colorMaskGreen = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false;
+ glBlendState.colorMaskBlue = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false;
+ glBlendState.colorMaskAlpha = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false;
+ glBlendState.sampleAlphaToCoverage = false;
+ glBlendState.dither = false;
+
+ static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ static const UINT sampleMask = 0xFFFFFFFF;
+
+ ID3D11BlendState *blendState = mStateCache.getBlendState(glBlendState);
+
+ // Set the vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ result = mDeviceContext->Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result);
+ return;
+ }
+
+ d3d11::PositionDepthColorVertex *vertices = reinterpret_cast<d3d11::PositionDepthColorVertex*>(mappedResource.pData);
+
+ float depthClear = gl::clamp01(clearParams.depthClearValue);
+ d3d11::SetPositionDepthColorVertex(&vertices[0], -1.0f, 1.0f, depthClear, clearParams.colorClearValue);
+ d3d11::SetPositionDepthColorVertex(&vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue);
+ d3d11::SetPositionDepthColorVertex(&vertices[2], 1.0f, 1.0f, depthClear, clearParams.colorClearValue);
+ d3d11::SetPositionDepthColorVertex(&vertices[3], 1.0f, -1.0f, depthClear, clearParams.colorClearValue);
+
+ mDeviceContext->Unmap(mClearVB, 0);
+
+ // Apply state
+ mDeviceContext->OMSetBlendState(blendState, blendFactors, sampleMask);
+ mDeviceContext->OMSetDepthStencilState(dsState, stencilClear);
+ mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS);
+
+ // Apply shaders
+ mDeviceContext->IASetInputLayout(mClearIL);
+ mDeviceContext->VSSetShader(mClearVS, NULL, 0);
+ mDeviceContext->PSSetShader(mClearPS, NULL, 0);
+ mDeviceContext->GSSetShader(NULL, NULL, 0);
+
+ // Apply vertex buffer
+ static UINT stride = sizeof(d3d11::PositionDepthColorVertex);
+ static UINT startIdx = 0;
+ mDeviceContext->IASetVertexBuffers(0, 1, &mClearVB, &stride, &startIdx);
+ mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ // Draw the clear quad
+ mDeviceContext->Draw(4, 0);
+
+ // Clean up
+ markAllStateDirty();
+}
+
+void Renderer11::markAllStateDirty()
+{
+ for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ {
+ mAppliedRenderTargetSerials[rtIndex] = 0;
+ }
+ mAppliedDepthbufferSerial = 0;
+ mAppliedStencilbufferSerial = 0;
+ mDepthStencilInitialized = false;
+ mRenderTargetDescInitialized = false;
+
+ for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+ {
+ mForceSetVertexSamplerStates[i] = true;
+ mCurVertexTextureSerials[i] = 0;
+ }
+ for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+ {
+ mForceSetPixelSamplerStates[i] = true;
+ mCurPixelTextureSerials[i] = 0;
+ }
+
+ mForceSetBlendState = true;
+ mForceSetRasterState = true;
+ mForceSetDepthStencilState = true;
+ mForceSetScissor = true;
+ mForceSetViewport = true;
+
+ mAppliedIBSerial = 0;
+ mAppliedStorageIBSerial = 0;
+ mAppliedIBOffset = 0;
+
+ mAppliedProgramBinarySerial = 0;
+ memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
+ memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
+}
+
+void Renderer11::releaseDeviceResources()
+{
+ mStateCache.clear();
+ mInputLayoutCache.clear();
+
+ delete mVertexDataManager;
+ mVertexDataManager = NULL;
+
+ delete mIndexDataManager;
+ mIndexDataManager = NULL;
+
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ delete mTriangleFanIB;
+ mTriangleFanIB = NULL;
+
+ if (mCopyVB)
+ {
+ mCopyVB->Release();
+ mCopyVB = NULL;
+ }
+
+ if (mCopySampler)
+ {
+ mCopySampler->Release();
+ mCopySampler = NULL;
+ }
+
+ if (mCopyIL)
+ {
+ mCopyIL->Release();
+ mCopyIL = NULL;
+ }
+
+ if (mCopyVS)
+ {
+ mCopyVS->Release();
+ mCopyVS = NULL;
+ }
+
+ if (mCopyRGBAPS)
+ {
+ mCopyRGBAPS->Release();
+ mCopyRGBAPS = NULL;
+ }
+
+ if (mCopyRGBPS)
+ {
+ mCopyRGBPS->Release();
+ mCopyRGBPS = NULL;
+ }
+
+ if (mCopyLumPS)
+ {
+ mCopyLumPS->Release();
+ mCopyLumPS = NULL;
+ }
+
+ if (mCopyLumAlphaPS)
+ {
+ mCopyLumAlphaPS->Release();
+ mCopyLumAlphaPS = NULL;
+ }
+
+ mCopyResourcesInitialized = false;
+
+ if (mClearVB)
+ {
+ mClearVB->Release();
+ mClearVB = NULL;
+ }
+
+ if (mClearIL)
+ {
+ mClearIL->Release();
+ mClearIL = NULL;
+ }
+
+ if (mClearVS)
+ {
+ mClearVS->Release();
+ mClearVS = NULL;
+ }
+
+ if (mClearPS)
+ {
+ mClearPS->Release();
+ mClearPS = NULL;
+ }
+
+ if (mClearScissorRS)
+ {
+ mClearScissorRS->Release();
+ mClearScissorRS = NULL;
+ }
+
+ if (mClearNoScissorRS)
+ {
+ mClearNoScissorRS->Release();
+ mClearNoScissorRS = NULL;
+ }
+
+ mClearResourcesInitialized = false;
+
+ if (mDriverConstantBufferVS)
+ {
+ mDriverConstantBufferVS->Release();
+ mDriverConstantBufferVS = NULL;
+ }
+
+ if (mDriverConstantBufferPS)
+ {
+ mDriverConstantBufferPS->Release();
+ mDriverConstantBufferPS = NULL;
+ }
+
+ if (mSyncQuery)
+ {
+ mSyncQuery->Release();
+ mSyncQuery = NULL;
+ }
+}
+
+void Renderer11::notifyDeviceLost()
+{
+ mDeviceLost = true;
+ mDisplay->notifyDeviceLost();
+}
+
+bool Renderer11::isDeviceLost()
+{
+ return mDeviceLost;
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer11::testDeviceLost(bool notify)
+{
+ bool isLost = false;
+
+ // GetRemovedReason is used to test if the device is removed
+ HRESULT result = mDevice->GetDeviceRemovedReason();
+ isLost = d3d11::isDeviceLostError(result);
+
+ if (isLost)
+ {
+ // Log error if this is a new device lost event
+ if (mDeviceLost == false)
+ {
+ ERR("The D3D11 device was removed: 0x%08X", result);
+ }
+
+ // ensure we note the device loss --
+ // we'll probably get this done again by notifyDeviceLost
+ // but best to remember it!
+ // Note that we don't want to clear the device loss status here
+ // -- this needs to be done by resetDevice
+ mDeviceLost = true;
+ if (notify)
+ {
+ notifyDeviceLost();
+ }
+ }
+
+ return isLost;
+}
+
+bool Renderer11::testDeviceResettable()
+{
+ // determine if the device is resettable by creating a dummy device
+ PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice");
+
+ if (D3D11CreateDevice == NULL)
+ {
+ return false;
+ }
+
+ D3D_FEATURE_LEVEL featureLevels[] =
+ {
+ D3D_FEATURE_LEVEL_11_0,
+ D3D_FEATURE_LEVEL_10_1,
+ D3D_FEATURE_LEVEL_10_0,
+ };
+
+ ID3D11Device* dummyDevice;
+ D3D_FEATURE_LEVEL dummyFeatureLevel;
+ ID3D11DeviceContext* dummyContext;
+
+ HRESULT result = D3D11CreateDevice(NULL,
+ D3D_DRIVER_TYPE_HARDWARE,
+ NULL,
+ #if defined(_DEBUG)
+ D3D11_CREATE_DEVICE_DEBUG,
+ #else
+ 0,
+ #endif
+ featureLevels,
+ ArraySize(featureLevels),
+ D3D11_SDK_VERSION,
+ &dummyDevice,
+ &dummyFeatureLevel,
+ &dummyContext);
+
+ if (!mDevice || FAILED(result))
+ {
+ return false;
+ }
+
+ dummyContext->Release();
+ dummyDevice->Release();
+
+ return true;
+}
+
+void Renderer11::release()
+{
+ releaseDeviceResources();
+
+ if (mDxgiFactory)
+ {
+ mDxgiFactory->Release();
+ mDxgiFactory = NULL;
+ }
+
+ if (mDxgiAdapter)
+ {
+ mDxgiAdapter->Release();
+ mDxgiAdapter = NULL;
+ }
+
+ if (mDeviceContext)
+ {
+ mDeviceContext->ClearState();
+ mDeviceContext->Flush();
+ mDeviceContext->Release();
+ mDeviceContext = NULL;
+ }
+
+ if (mDevice)
+ {
+ mDevice->Release();
+ mDevice = NULL;
+ }
+
+ if (mD3d11Module)
+ {
+ FreeLibrary(mD3d11Module);
+ mD3d11Module = NULL;
+ }
+
+ if (mDxgiModule)
+ {
+ FreeLibrary(mDxgiModule);
+ mDxgiModule = NULL;
+ }
+}
+
+bool Renderer11::resetDevice()
+{
+ // recreate everything
+ release();
+ EGLint result = initialize();
+
+ if (result != EGL_SUCCESS)
+ {
+ ERR("Could not reinitialize D3D11 device: %08X", result);
+ return false;
+ }
+
+ mDeviceLost = false;
+
+ return true;
+}
+
+DWORD Renderer11::getAdapterVendor() const
+{
+ return mAdapterDescription.VendorId;
+}
+
+std::string Renderer11::getRendererDescription() const
+{
+ std::ostringstream rendererString;
+
+ rendererString << mDescription;
+ rendererString << " Direct3D11";
+
+ rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel();
+ rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel();
+
+ return rendererString.str();
+}
+
+GUID Renderer11::getAdapterIdentifier() const
+{
+ // Use the adapter LUID as our adapter ID
+ // This number is local to a machine is only guaranteed to be unique between restarts
+ META_ASSERT(sizeof(LUID) <= sizeof(GUID));
+ GUID adapterId = {0};
+ memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
+ return adapterId;
+}
+
+bool Renderer11::getBGRATextureSupport() const
+{
+ return mBGRATextureSupport;
+}
+
+bool Renderer11::getDXT1TextureSupport()
+{
+ return mDXT1TextureSupport;
+}
+
+bool Renderer11::getDXT3TextureSupport()
+{
+ return mDXT3TextureSupport;
+}
+
+bool Renderer11::getDXT5TextureSupport()
+{
+ return mDXT5TextureSupport;
+}
+
+bool Renderer11::getDepthTextureSupport() const
+{
+ return mDepthTextureSupport;
+}
+
+bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
+{
+ *renderable = mFloat32RenderSupport;
+ *filtering = mFloat32FilterSupport;
+ return mFloat32TextureSupport;
+}
+
+bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
+{
+ *renderable = mFloat16RenderSupport;
+ *filtering = mFloat16FilterSupport;
+ return mFloat16TextureSupport;
+}
+
+bool Renderer11::getLuminanceTextureSupport()
+{
+ return false;
+}
+
+bool Renderer11::getLuminanceAlphaTextureSupport()
+{
+ return false;
+}
+
+bool Renderer11::getTextureFilterAnisotropySupport() const
+{
+ return true;
+}
+
+float Renderer11::getTextureMaxAnisotropy() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_MAX_MAXANISOTROPY;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_MAX_MAXANISOTROPY;
+ default: UNREACHABLE();
+ return 0;
+ }
+}
+
+bool Renderer11::getEventQuerySupport()
+{
+ return true;
+}
+
+Range Renderer11::getViewportBounds() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
+ default: UNREACHABLE();
+ return Range(0, 0);
+ }
+}
+
+unsigned int Renderer11::getMaxVertexTextureImageUnits() const
+{
+ META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
+ default: UNREACHABLE();
+ return 0;
+ }
+}
+
+unsigned int Renderer11::getMaxCombinedTextureImageUnits() const
+{
+ return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
+}
+
+unsigned int Renderer11::getReservedVertexUniformVectors() const
+{
+ return 0; // Driver uniforms are stored in a separate constant buffer
+}
+
+unsigned int Renderer11::getReservedFragmentUniformVectors() const
+{
+ return 0; // Driver uniforms are stored in a separate constant buffer
+}
+
+unsigned int Renderer11::getMaxVertexUniformVectors() const
+{
+ META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+ ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+ return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
+}
+
+unsigned int Renderer11::getMaxFragmentUniformVectors() const
+{
+ META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+ ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_10_0);
+ return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
+}
+
+unsigned int Renderer11::getMaxVaryingVectors() const
+{
+ META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_VS_OUTPUT_REGISTER_COUNT;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_VS_OUTPUT_REGISTER_COUNT;
+ default: UNREACHABLE();
+ return 0;
+ }
+}
+
+bool Renderer11::getNonPower2TextureSupport() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+bool Renderer11::getOcclusionQuerySupport() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+bool Renderer11::getInstancingSupport() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+bool Renderer11::getShareHandleSupport() const
+{
+ // We only currently support share handles with BGRA surfaces, because
+ // chrome needs BGRA. Once chrome fixes this, we should always support them.
+ // PIX doesn't seem to support using share handles, so disable them.
+ return getBGRATextureSupport() && !gl::perfActive();
+}
+
+bool Renderer11::getDerivativeInstructionSupport() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return true;
+ default: UNREACHABLE();
+ return false;
+ }
+}
+
+bool Renderer11::getPostSubBufferSupport() const
+{
+ // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
+ return false;
+}
+
+int Renderer11::getMajorShaderModel() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5
+ case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+int Renderer11::getMinorShaderModel() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0
+ case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+float Renderer11::getMaxPointSize() const
+{
+ // choose a reasonable maximum. we enforce this in the shader.
+ // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
+ return 1024.0f;
+}
+
+int Renderer11::getMaxViewportDimension() const
+{
+ // Maximum viewport size must be at least as large as the largest render buffer (or larger).
+ // In our case return the maximum texture size, which is the maximum render buffer size.
+ META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX);
+ META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX);
+
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ default: UNREACHABLE();
+ return 0;
+ }
+}
+
+int Renderer11::getMaxTextureWidth() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+int Renderer11::getMaxTextureHeight() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192
+ default: UNREACHABLE(); return 0;
+ }
+}
+
+bool Renderer11::get32BitIndexSupport() const
+{
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true
+ default: UNREACHABLE(); return false;
+ }
+}
+
+int Renderer11::getMinSwapInterval() const
+{
+ return 0;
+}
+
+int Renderer11::getMaxSwapInterval() const
+{
+ return 4;
+}
+
+int Renderer11::getMaxSupportedSamples() const
+{
+ return mMaxSupportedSamples;
+}
+
+int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
+{
+ if (requested == 0)
+ {
+ return 0;
+ }
+
+ MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
+ if (iter != mMultisampleSupportMap.end())
+ {
+ const MultisampleSupportInfo& info = iter->second;
+ for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
+ {
+ if (info.qualityLevels[i] > 0)
+ {
+ return i + 1;
+ }
+ }
+ }
+
+ return -1;
+}
+
+unsigned int Renderer11::getMaxRenderTargets() const
+{
+ META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+ META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+ switch (mFeatureLevel)
+ {
+ case D3D_FEATURE_LEVEL_11_0:
+ return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8
+ default:
+ UNREACHABLE();
+ return 1;
+ }
+}
+
+bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+{
+ if (source && dest)
+ {
+ TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance());
+ TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance());
+
+ mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture());
+ return true;
+ }
+
+ return false;
+}
+
+bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+{
+ if (source && dest)
+ {
+ TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance());
+ TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance());
+
+ mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture());
+ return true;
+ }
+
+ return false;
+}
+
+bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+ gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
+ if (!colorbuffer)
+ {
+ ERR("Failed to retrieve the color buffer from the frame buffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+ if (!sourceRenderTarget)
+ {
+ ERR("Failed to retrieve the render target from the frame buffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
+ if (!source)
+ {
+ ERR("Failed to retrieve the render target view from the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance());
+ if (!storage11)
+ {
+ source->Release();
+ ERR("Failed to retrieve the texture storage from the destination.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level));
+ if (!destRenderTarget)
+ {
+ source->Release();
+ ERR("Failed to retrieve the render target from the destination storage.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
+ if (!dest)
+ {
+ source->Release();
+ ERR("Failed to retrieve the render target view from the destination render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ gl::Rectangle destRect;
+ destRect.x = xoffset;
+ destRect.y = yoffset;
+ destRect.width = sourceRect.width;
+ destRect.height = sourceRect.height;
+
+ bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
+ dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
+
+ source->Release();
+ dest->Release();
+
+ return ret;
+}
+
+bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+ gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
+ if (!colorbuffer)
+ {
+ ERR("Failed to retrieve the color buffer from the frame buffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+ if (!sourceRenderTarget)
+ {
+ ERR("Failed to retrieve the render target from the frame buffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView();
+ if (!source)
+ {
+ ERR("Failed to retrieve the render target view from the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance());
+ if (!storage11)
+ {
+ source->Release();
+ ERR("Failed to retrieve the texture storage from the destination.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level));
+ if (!destRenderTarget)
+ {
+ source->Release();
+ ERR("Failed to retrieve the render target from the destination storage.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView();
+ if (!dest)
+ {
+ source->Release();
+ ERR("Failed to retrieve the render target view from the destination render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ gl::Rectangle destRect;
+ destRect.x = xoffset;
+ destRect.y = yoffset;
+ destRect.width = sourceRect.width;
+ destRect.height = sourceRect.height;
+
+ bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(),
+ dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat);
+
+ source->Release();
+ dest->Release();
+
+ return ret;
+}
+
+bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+ ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat)
+{
+ HRESULT result;
+
+ if (!mCopyResourcesInitialized)
+ {
+ ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS);
+
+ D3D11_BUFFER_DESC vbDesc;
+ vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
+ vbDesc.StructureByteStride = 0;
+
+ result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer");
+
+ D3D11_SAMPLER_DESC samplerDesc;
+ samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+ samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.MipLODBias = 0.0f;
+ samplerDesc.MaxAnisotropy = 0;
+ samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ samplerDesc.BorderColor[0] = 0.0f;
+ samplerDesc.BorderColor[1] = 0.0f;
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = 0.0f;
+ samplerDesc.MaxLOD = 0.0f;
+
+ result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler");
+
+ D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout");
+
+ result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader");
+
+ result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader");
+
+ result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader");
+
+ result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader");
+
+ result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader");
+
+ mCopyResourcesInitialized = true;
+ }
+
+ // Verify the source and destination area sizes
+ if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast<int>(sourceWidth) ||
+ sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast<int>(sourceHeight) ||
+ destArea.x < 0 || destArea.x + destArea.width > static_cast<int>(destWidth) ||
+ destArea.y < 0 || destArea.y + destArea.height > static_cast<int>(destHeight))
+ {
+ return gl::error(GL_INVALID_VALUE, false);
+ }
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result);
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+ // Create a quad in homogeneous coordinates
+ float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f;
+ float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f;
+ float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f;
+ float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f;
+
+ float u1 = sourceArea.x / float(sourceWidth);
+ float v1 = sourceArea.y / float(sourceHeight);
+ float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth);
+ float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight);
+
+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1);
+
+ mDeviceContext->Unmap(mCopyVB, 0);
+
+ static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+ static UINT startIdx = 0;
+ mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx);
+
+ // Apply state
+ mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF);
+ mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+ mDeviceContext->RSSetState(NULL);
+
+ // Apply shaders
+ mDeviceContext->IASetInputLayout(mCopyIL);
+ mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ mDeviceContext->VSSetShader(mCopyVS, NULL, 0);
+
+ ID3D11PixelShader *ps = NULL;
+ switch(destFormat)
+ {
+ case GL_RGBA: ps = mCopyRGBAPS; break;
+ case GL_RGB: ps = mCopyRGBPS; break;
+ case GL_ALPHA: ps = mCopyRGBAPS; break;
+ case GL_BGRA_EXT: ps = mCopyRGBAPS; break;
+ case GL_LUMINANCE: ps = mCopyLumPS; break;
+ case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break;
+ default: UNREACHABLE(); ps = NULL; break;
+ }
+
+ mDeviceContext->PSSetShader(ps, NULL, 0);
+ mDeviceContext->GSSetShader(NULL, NULL, 0);
+
+ // Unset the currently bound shader resource to avoid conflicts
+ static ID3D11ShaderResourceView *const nullSRV = NULL;
+ mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
+
+ // Apply render target
+ setOneTimeRenderTarget(dest);
+
+ // Set the viewport
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+ viewport.Width = destWidth;
+ viewport.Height = destHeight;
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+ mDeviceContext->RSSetViewports(1, &viewport);
+
+ // Apply textures
+ mDeviceContext->PSSetShaderResources(0, 1, &source);
+ mDeviceContext->PSSetSamplers(0, 1, &mCopySampler);
+
+ // Draw the quad
+ mDeviceContext->Draw(4, 0);
+
+ // Unbind textures and render targets and vertex buffer
+ mDeviceContext->PSSetShaderResources(0, 1, &nullSRV);
+
+ unapplyRenderTargets();
+
+ UINT zero = 0;
+ ID3D11Buffer *const nullBuffer = NULL;
+ mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero);
+
+ markAllStateDirty();
+
+ return true;
+}
+
+void Renderer11::unapplyRenderTargets()
+{
+ setOneTimeRenderTarget(NULL);
+}
+
+void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
+{
+ ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
+
+ rtvArray[0] = renderTargetView;
+
+ mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
+
+ // Do not preserve the serial for this one-time-use render target
+ for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+ {
+ mAppliedRenderTargetSerials[rtIndex] = 0;
+ }
+}
+
+RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
+{
+ SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
+ RenderTarget11 *renderTarget = NULL;
+
+ if (depth)
+ {
+ // Note: depth stencil may be NULL for 0 sized surfaces
+ renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(),
+ swapChain11->getDepthStencilTexture(), NULL,
+ swapChain11->getWidth(), swapChain11->getHeight());
+ }
+ else
+ {
+ // Note: render target may be NULL for 0 sized surfaces
+ renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(),
+ swapChain11->getOffscreenTexture(),
+ swapChain11->getRenderTargetShaderResource(),
+ swapChain11->getWidth(), swapChain11->getHeight());
+ }
+ return renderTarget;
+}
+
+RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
+{
+ RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth);
+ return renderTarget;
+}
+
+ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type)
+{
+ ShaderExecutable11 *executable = NULL;
+
+ switch (type)
+ {
+ case rx::SHADER_VERTEX:
+ {
+ ID3D11VertexShader *vshader = NULL;
+ HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader);
+ ASSERT(SUCCEEDED(result));
+
+ if (vshader)
+ {
+ executable = new ShaderExecutable11(function, length, vshader);
+ }
+ }
+ break;
+ case rx::SHADER_PIXEL:
+ {
+ ID3D11PixelShader *pshader = NULL;
+ HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader);
+ ASSERT(SUCCEEDED(result));
+
+ if (pshader)
+ {
+ executable = new ShaderExecutable11(function, length, pshader);
+ }
+ }
+ break;
+ case rx::SHADER_GEOMETRY:
+ {
+ ID3D11GeometryShader *gshader = NULL;
+ HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader);
+ ASSERT(SUCCEEDED(result));
+
+ if (gshader)
+ {
+ executable = new ShaderExecutable11(function, length, gshader);
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return executable;
+}
+
+ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
+{
+ const char *profile = NULL;
+
+ switch (type)
+ {
+ case rx::SHADER_VERTEX:
+ profile = "vs_4_0";
+ break;
+ case rx::SHADER_PIXEL:
+ profile = "ps_4_0";
+ break;
+ case rx::SHADER_GEOMETRY:
+ profile = "gs_4_0";
+ break;
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+
+ ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+ if (!binary)
+ return NULL;
+
+ ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type);
+ binary->Release();
+
+ return executable;
+}
+
+VertexBuffer *Renderer11::createVertexBuffer()
+{
+ return new VertexBuffer11(this);
+}
+
+IndexBuffer *Renderer11::createIndexBuffer()
+{
+ return new IndexBuffer11(this);
+}
+
+BufferStorage *Renderer11::createBufferStorage()
+{
+ return new BufferStorage11(this);
+}
+
+QueryImpl *Renderer11::createQuery(GLenum type)
+{
+ return new Query11(this, type);
+}
+
+FenceImpl *Renderer11::createFence()
+{
+ return new Fence11(this);
+}
+
+bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
+{
+ ASSERT(colorbuffer != NULL);
+
+ RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget());
+ if (renderTarget)
+ {
+ *subresourceIndex = renderTarget->getSubresourceIndex();
+
+ ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView();
+ if (colorBufferRTV)
+ {
+ ID3D11Resource *textureResource = NULL;
+ colorBufferRTV->GetResource(&textureResource);
+ colorBufferRTV->Release();
+
+ if (textureResource)
+ {
+ HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)resource);
+ textureResource->Release();
+
+ if (SUCCEEDED(result))
+ {
+ return true;
+ }
+ else
+ {
+ ERR("Failed to extract the ID3D11Texture2D from the render target resource, "
+ "HRESULT: 0x%X.", result);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ bool blitRenderTarget, bool blitDepthStencil)
+{
+ if (blitRenderTarget)
+ {
+ gl::Renderbuffer *readBuffer = readTarget->getReadColorbuffer();
+
+ if (!readBuffer)
+ {
+ ERR("Failed to retrieve the read buffer from the read framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget *readRenderTarget = readBuffer->getRenderTarget();
+
+ for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+ {
+ if (drawTarget->isEnabledColorAttachment(colorAttachment))
+ {
+ gl::Renderbuffer *drawBuffer = drawTarget->getColorbuffer(colorAttachment);
+
+ if (!drawBuffer)
+ {
+ ERR("Failed to retrieve the draw buffer from the draw framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget();
+
+ if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ if (blitDepthStencil)
+ {
+ gl::Renderbuffer *readBuffer = readTarget->getDepthOrStencilbuffer();
+ gl::Renderbuffer *drawBuffer = drawTarget->getDepthOrStencilbuffer();
+
+ if (!readBuffer)
+ {
+ ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ if (!drawBuffer)
+ {
+ ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget *readRenderTarget = readBuffer->getDepthStencil();
+ RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil();
+
+ if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
+{
+ ID3D11Texture2D *colorBufferTexture = NULL;
+ unsigned int subresourceIndex = 0;
+
+ gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer();
+
+ if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture))
+ {
+ gl::Rectangle area;
+ area.x = x;
+ area.y = y;
+ area.width = width;
+ area.height = height;
+
+ readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch,
+ packReverseRowOrder, packAlignment, pixels);
+
+ colorBufferTexture->Release();
+ colorBufferTexture = NULL;
+ }
+}
+
+Image *Renderer11::createImage()
+{
+ return new Image11();
+}
+
+void Renderer11::generateMipmap(Image *dest, Image *src)
+{
+ Image11 *dest11 = Image11::makeImage11(dest);
+ Image11 *src11 = Image11::makeImage11(src);
+ Image11::generateMipmap(dest11, src11);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
+{
+ SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
+ return new TextureStorage11_2D(this, swapChain11);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+{
+ return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height);
+}
+
+TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+{
+ return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size);
+}
+
+static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType)
+{
+ if (sourceFormat == DXGI_FORMAT_A8_UNORM &&
+ destFormat == GL_ALPHA &&
+ destType == GL_UNSIGNED_BYTE)
+ {
+ return 1;
+ }
+ else if (sourceFormat == DXGI_FORMAT_R8G8B8A8_UNORM &&
+ destFormat == GL_RGBA &&
+ destType == GL_UNSIGNED_BYTE)
+ {
+ return 4;
+ }
+ else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM &&
+ destFormat == GL_BGRA_EXT &&
+ destType == GL_UNSIGNED_BYTE)
+ {
+ return 4;
+ }
+ else if (sourceFormat == DXGI_FORMAT_R16G16B16A16_FLOAT &&
+ destFormat == GL_RGBA &&
+ destType == GL_HALF_FLOAT_OES)
+ {
+ return 8;
+ }
+ else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT &&
+ destFormat == GL_RGB &&
+ destType == GL_FLOAT)
+ {
+ return 12;
+ }
+ else if (sourceFormat == DXGI_FORMAT_R32G32B32A32_FLOAT &&
+ destFormat == GL_RGBA &&
+ destType == GL_FLOAT)
+ {
+ return 16;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, unsigned int x,
+ unsigned int y, int inputPitch, gl::Color *outColor)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ {
+ unsigned int rgba = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
+ outColor->red = (rgba & 0x000000FF) * (1.0f / 0x000000FF);
+ outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00);
+ outColor->blue = (rgba & 0x00FF0000) * (1.0f / 0x00FF0000);
+ outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000);
+ }
+ break;
+
+ case DXGI_FORMAT_A8_UNORM:
+ {
+ outColor->red = 0.0f;
+ outColor->green = 0.0f;
+ outColor->blue = 0.0f;
+ outColor->alpha = *(data + x + y * inputPitch) / 255.0f;
+ }
+ break;
+
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ {
+ outColor->red = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 0);
+ outColor->green = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 1);
+ outColor->blue = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 2);
+ outColor->alpha = *(reinterpret_cast<const float*>(data + 16 * x + y * inputPitch) + 3);
+ }
+ break;
+
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ {
+ outColor->red = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 0);
+ outColor->green = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 1);
+ outColor->blue = *(reinterpret_cast<const float*>(data + 12 * x + y * inputPitch) + 2);
+ outColor->alpha = 1.0f;
+ }
+ break;
+
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ {
+ outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 0));
+ outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 1));
+ outColor->blue = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 2));
+ outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 8 * x + y * inputPitch) + 3));
+ }
+ break;
+
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ {
+ unsigned int bgra = *reinterpret_cast<const unsigned int*>(data + 4 * x + y * inputPitch);
+ outColor->red = (bgra & 0x00FF0000) * (1.0f / 0x00FF0000);
+ outColor->blue = (bgra & 0x000000FF) * (1.0f / 0x000000FF);
+ outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00);
+ outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000);
+ }
+ break;
+
+ case DXGI_FORMAT_R8_UNORM:
+ {
+ outColor->red = *(data + x + y * inputPitch) / 255.0f;
+ outColor->green = 0.0f;
+ outColor->blue = 0.0f;
+ outColor->alpha = 1.0f;
+ }
+ break;
+
+ case DXGI_FORMAT_R8G8_UNORM:
+ {
+ unsigned short rg = *reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch);
+
+ outColor->red = (rg & 0xFF00) * (1.0f / 0xFF00);
+ outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF);
+ outColor->blue = 0.0f;
+ outColor->alpha = 1.0f;
+ }
+ break;
+
+ case DXGI_FORMAT_R16_FLOAT:
+ {
+ outColor->red = gl::float16ToFloat32(*reinterpret_cast<const unsigned short*>(data + 2 * x + y * inputPitch));
+ outColor->green = 0.0f;
+ outColor->blue = 0.0f;
+ outColor->alpha = 1.0f;
+ }
+ break;
+
+ case DXGI_FORMAT_R16G16_FLOAT:
+ {
+ outColor->red = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 0));
+ outColor->green = gl::float16ToFloat32(*(reinterpret_cast<const unsigned short*>(data + 4 * x + y * inputPitch) + 1));
+ outColor->blue = 0.0f;
+ outColor->alpha = 1.0f;
+ }
+ break;
+
+ default:
+ ERR("ReadPixelColor not implemented for DXGI format %u.", format);
+ UNIMPLEMENTED();
+ break;
+ }
+}
+
+static inline void writePixelColor(const gl::Color &color, GLenum format, GLenum type, unsigned int x,
+ unsigned int y, int outputPitch, void *outData)
+{
+ unsigned char* byteData = reinterpret_cast<unsigned char*>(outData);
+ unsigned short* shortData = reinterpret_cast<unsigned short*>(outData);
+
+ switch (format)
+ {
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f);
+ byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
+ byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f);
+ byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
+ break;
+
+ default:
+ ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type);
+ UNIMPLEMENTED();
+ break;
+ }
+ break;
+
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ byteData[4 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.blue + 0.5f);
+ byteData[4 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
+ byteData[4 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.red + 0.5f);
+ byteData[4 * x + y * outputPitch + 3] = static_cast<unsigned char>(255 * color.alpha + 0.5f);
+ break;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ shortData[x + y * outputPitch / sizeof(unsigned short)] =
+ (static_cast<unsigned short>(15 * color.alpha + 0.5f) << 12) |
+ (static_cast<unsigned short>(15 * color.red + 0.5f) << 8) |
+ (static_cast<unsigned short>(15 * color.green + 0.5f) << 4) |
+ (static_cast<unsigned short>(15 * color.blue + 0.5f) << 0);
+ break;
+
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ shortData[x + y * outputPitch / sizeof(unsigned short)] =
+ (static_cast<unsigned short>( color.alpha + 0.5f) << 15) |
+ (static_cast<unsigned short>(31 * color.red + 0.5f) << 10) |
+ (static_cast<unsigned short>(31 * color.green + 0.5f) << 5) |
+ (static_cast<unsigned short>(31 * color.blue + 0.5f) << 0);
+ break;
+
+ default:
+ ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type);
+ UNIMPLEMENTED();
+ break;
+ }
+ break;
+
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT_5_6_5:
+ shortData[x + y * outputPitch / sizeof(unsigned short)] =
+ (static_cast<unsigned short>(31 * color.blue + 0.5f) << 0) |
+ (static_cast<unsigned short>(63 * color.green + 0.5f) << 5) |
+ (static_cast<unsigned short>(31 * color.red + 0.5f) << 11);
+ break;
+
+ case GL_UNSIGNED_BYTE:
+ byteData[3 * x + y * outputPitch + 0] = static_cast<unsigned char>(255 * color.red + 0.5f);
+ byteData[3 * x + y * outputPitch + 1] = static_cast<unsigned char>(255 * color.green + 0.5f);
+ byteData[3 * x + y * outputPitch + 2] = static_cast<unsigned char>(255 * color.blue + 0.5f);
+ break;
+
+ default:
+ ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type);
+ UNIMPLEMENTED();
+ break;
+ }
+ break;
+
+ default:
+ ERR("WritePixelColor not implemented for format 0x%X.", format);
+ UNIMPLEMENTED();
+ break;
+ }
+}
+
+void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area,
+ GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
+ GLint packAlignment, void *pixels)
+{
+ D3D11_TEXTURE2D_DESC textureDesc;
+ texture->GetDesc(&textureDesc);
+
+ D3D11_TEXTURE2D_DESC stagingDesc;
+ stagingDesc.Width = area.width;
+ stagingDesc.Height = area.height;
+ stagingDesc.MipLevels = 1;
+ stagingDesc.ArraySize = 1;
+ stagingDesc.Format = textureDesc.Format;
+ stagingDesc.SampleDesc.Count = 1;
+ stagingDesc.SampleDesc.Quality = 0;
+ stagingDesc.Usage = D3D11_USAGE_STAGING;
+ stagingDesc.BindFlags = 0;
+ stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+ stagingDesc.MiscFlags = 0;
+
+ ID3D11Texture2D* stagingTex = NULL;
+ HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex);
+ if (FAILED(result))
+ {
+ ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result);
+ return;
+ }
+
+ ID3D11Texture2D* srcTex = NULL;
+ if (textureDesc.SampleDesc.Count > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = textureDesc.Width;
+ resolveDesc.Height = textureDesc.Height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureDesc.Format;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+ resolveDesc.BindFlags = 0;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex);
+ if (FAILED(result))
+ {
+ ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result);
+ stagingTex->Release();
+ return;
+ }
+
+ mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
+ subResource = 0;
+ }
+ else
+ {
+ srcTex = texture;
+ srcTex->AddRef();
+ }
+
+ D3D11_BOX srcBox;
+ srcBox.left = area.x;
+ srcBox.right = area.x + area.width;
+ srcBox.top = area.y;
+ srcBox.bottom = area.y + area.height;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox);
+
+ srcTex->Release();
+ srcTex = NULL;
+
+ D3D11_MAPPED_SUBRESOURCE mapping;
+ mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping);
+
+ unsigned char *source;
+ int inputPitch;
+ if (packReverseRowOrder)
+ {
+ source = static_cast<unsigned char*>(mapping.pData) + mapping.RowPitch * (area.height - 1);
+ inputPitch = -static_cast<int>(mapping.RowPitch);
+ }
+ else
+ {
+ source = static_cast<unsigned char*>(mapping.pData);
+ inputPitch = static_cast<int>(mapping.RowPitch);
+ }
+
+ unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, format, type);
+ if (fastPixelSize != 0)
+ {
+ unsigned char *dest = static_cast<unsigned char*>(pixels);
+ for (int j = 0; j < area.height; j++)
+ {
+ memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize);
+ }
+ }
+ else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM &&
+ format == GL_RGBA &&
+ type == GL_UNSIGNED_BYTE)
+ {
+ // Fast path for swapping red with blue
+ unsigned char *dest = static_cast<unsigned char*>(pixels);
+
+ for (int j = 0; j < area.height; j++)
+ {
+ for (int i = 0; i < area.width; i++)
+ {
+ unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+ *(unsigned int*)(dest + 4 * i + j * outputPitch) =
+ (argb & 0xFF00FF00) | // Keep alpha and green
+ (argb & 0x00FF0000) >> 16 | // Move red to blue
+ (argb & 0x000000FF) << 16; // Move blue to red
+ }
+ }
+ }
+ else
+ {
+ gl::Color pixelColor;
+ for (int j = 0; j < area.height; j++)
+ {
+ for (int i = 0; i < area.width; i++)
+ {
+ readPixelColor(source, textureDesc.Format, i, j, inputPitch, &pixelColor);
+ writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels);
+ }
+ }
+ }
+
+ mDeviceContext->Unmap(stagingTex, 0);
+
+ stagingTex->Release();
+ stagingTex = NULL;
+}
+
+bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, bool wholeBufferCopy)
+{
+ ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height);
+
+ RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
+ if (!readRenderTarget)
+ {
+ ERR("Failed to retrieve the read render target from the read framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11Texture2D *readTexture = NULL;
+ unsigned int readSubresource = 0;
+ if (readRenderTarget->getSamples() > 0)
+ {
+ ID3D11Texture2D *unresolvedTexture = readRenderTarget11->getTexture();
+
+ readTexture = resolveMultisampledTexture(unresolvedTexture, readRenderTarget11->getSubresourceIndex());
+ readSubresource = 0;
+
+ unresolvedTexture->Release();
+ }
+ else
+ {
+ readTexture = readRenderTarget11->getTexture();
+ readSubresource = readRenderTarget11->getSubresourceIndex();
+ }
+
+ if (!readTexture)
+ {
+ ERR("Failed to retrieve the read render target view from the read render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
+ if (!drawRenderTarget)
+ {
+ readTexture->Release();
+ ERR("Failed to retrieve the draw render target from the draw framebuffer.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture();
+ unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex();
+
+ D3D11_BOX readBox;
+ readBox.left = readRect.x;
+ readBox.right = readRect.x + readRect.width;
+ readBox.top = readRect.y;
+ readBox.bottom = readRect.y + readRect.height;
+ readBox.front = 0;
+ readBox.back = 1;
+
+ // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
+ // We also require complete framebuffer copies for depth-stencil blit.
+ D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox;
+
+ mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0,
+ readTexture, readSubresource, pSrcBox);
+
+ readTexture->Release();
+ drawTexture->Release();
+
+ return true;
+}
+
+ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
+{
+ D3D11_TEXTURE2D_DESC textureDesc;
+ source->GetDesc(&textureDesc);
+
+ if (textureDesc.SampleDesc.Count > 1)
+ {
+ D3D11_TEXTURE2D_DESC resolveDesc;
+ resolveDesc.Width = textureDesc.Width;
+ resolveDesc.Height = textureDesc.Height;
+ resolveDesc.MipLevels = 1;
+ resolveDesc.ArraySize = 1;
+ resolveDesc.Format = textureDesc.Format;
+ resolveDesc.SampleDesc.Count = 1;
+ resolveDesc.SampleDesc.Quality = 0;
+ resolveDesc.Usage = textureDesc.Usage;
+ resolveDesc.BindFlags = textureDesc.BindFlags;
+ resolveDesc.CPUAccessFlags = 0;
+ resolveDesc.MiscFlags = 0;
+
+ ID3D11Texture2D *resolveTexture = NULL;
+ HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture);
+ if (FAILED(result))
+ {
+ ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result);
+ return NULL;
+ }
+
+ mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
+ return resolveTexture;
+ }
+ else
+ {
+ source->AddRef();
+ return source;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
new file mode 100644
index 0000000000..a3e42e9048
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h
@@ -0,0 +1,348 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer11.h: Defines a back-end specific class for the D3D11 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER11_H_
+#define LIBGLESV2_RENDERER_RENDERER11_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/angletypes.h"
+#include "libGLESv2/mathutil.h"
+
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderStateCache.h"
+#include "libGLESv2/renderer/InputLayoutCache.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace gl
+{
+class Renderbuffer;
+}
+
+namespace rx
+{
+
+class VertexDataManager;
+class IndexDataManager;
+class StreamingIndexBufferInterface;
+
+enum
+{
+ MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
+ MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
+};
+
+class Renderer11 : public Renderer
+{
+ public:
+ Renderer11(egl::Display *display, HDC hDc);
+ virtual ~Renderer11();
+
+ static Renderer11 *makeRenderer11(Renderer *renderer);
+
+ virtual EGLint initialize();
+ virtual bool resetDevice();
+
+ virtual int generateConfigs(ConfigDesc **configDescList);
+ virtual void deleteConfigs(ConfigDesc *configDescList);
+
+ virtual void sync(bool block);
+
+ virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+
+ virtual void setRasterizerState(const gl::RasterizerState &rasterState);
+ virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
+ unsigned int sampleMask);
+ virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW);
+
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
+ virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport);
+
+ virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
+ virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
+ virtual void applyShaders(gl::ProgramBinary *programBinary);
+ virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
+
+ virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+
+ virtual void markAllStateDirty();
+
+ // lost device
+ void notifyDeviceLost();
+ virtual bool isDeviceLost();
+ virtual bool testDeviceLost(bool notify);
+ virtual bool testDeviceResettable();
+
+ // Renderer capabilities
+ virtual DWORD getAdapterVendor() const;
+ virtual std::string getRendererDescription() const;
+ virtual GUID getAdapterIdentifier() const;
+
+ virtual bool getBGRATextureSupport() const;
+ virtual bool getDXT1TextureSupport();
+ virtual bool getDXT3TextureSupport();
+ virtual bool getDXT5TextureSupport();
+ virtual bool getEventQuerySupport();
+ virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
+ virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
+ virtual bool getLuminanceTextureSupport();
+ virtual bool getLuminanceAlphaTextureSupport();
+ virtual unsigned int getMaxVertexTextureImageUnits() const;
+ virtual unsigned int getMaxCombinedTextureImageUnits() const;
+ virtual unsigned int getReservedVertexUniformVectors() const;
+ virtual unsigned int getReservedFragmentUniformVectors() const;
+ virtual unsigned int getMaxVertexUniformVectors() const;
+ virtual unsigned int getMaxFragmentUniformVectors() const;
+ virtual unsigned int getMaxVaryingVectors() const;
+ virtual bool getNonPower2TextureSupport() const;
+ virtual bool getDepthTextureSupport() const;
+ virtual bool getOcclusionQuerySupport() const;
+ virtual bool getInstancingSupport() const;
+ virtual bool getTextureFilterAnisotropySupport() const;
+ virtual float getTextureMaxAnisotropy() const;
+ virtual bool getShareHandleSupport() const;
+ virtual bool getDerivativeInstructionSupport() const;
+ virtual bool getPostSubBufferSupport() const;
+
+ virtual int getMajorShaderModel() const;
+ virtual float getMaxPointSize() const;
+ virtual int getMaxViewportDimension() const;
+ virtual int getMaxTextureWidth() const;
+ virtual int getMaxTextureHeight() const;
+ virtual bool get32BitIndexSupport() const;
+ virtual int getMinSwapInterval() const;
+ virtual int getMaxSwapInterval() const;
+
+ virtual GLsizei getMaxSupportedSamples() const;
+ int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const;
+
+ virtual unsigned int getMaxRenderTargets() const;
+
+ // Pixel operations
+ virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
+ virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
+
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+
+ bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+ ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat);
+
+ virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ bool blitRenderTarget, bool blitDepthStencil);
+ virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
+
+ // RenderTarget creation
+ virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
+ virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
+
+ // Shader operations
+ virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
+ virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type);
+
+ // Image operations
+ virtual Image *createImage();
+ virtual void generateMipmap(Image *dest, Image *source);
+ virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
+ virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+
+ // Buffer creation
+ virtual VertexBuffer *createVertexBuffer();
+ virtual IndexBuffer *createIndexBuffer();
+ virtual BufferStorage *createBufferStorage();
+
+ // Query and Fence creation
+ virtual QueryImpl *createQuery(GLenum type);
+ virtual FenceImpl *createFence();
+
+ // D3D11-renderer specific methods
+ ID3D11Device *getDevice() { return mDevice; }
+ ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+ IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+
+ bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
+ void unapplyRenderTargets();
+ void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Renderer11);
+
+ void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+ void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
+
+ void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area,
+ GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
+ GLint packAlignment, void *pixels);
+
+ void maskedClear(const gl::ClearParameters &clearParams);
+ rx::Range getViewportBounds() const;
+
+ bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget,
+ RenderTarget *drawRenderTarget, bool wholeBufferCopy);
+ ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
+
+ HMODULE mD3d11Module;
+ HMODULE mDxgiModule;
+ HDC mDc;
+
+ bool mDeviceLost;
+
+ void initializeDevice();
+ void releaseDeviceResources();
+ int getMinorShaderModel() const;
+ void release();
+
+ RenderStateCache mStateCache;
+
+ // Support flags
+ bool mFloat16TextureSupport;
+ bool mFloat16FilterSupport;
+ bool mFloat16RenderSupport;
+
+ bool mFloat32TextureSupport;
+ bool mFloat32FilterSupport;
+ bool mFloat32RenderSupport;
+
+ bool mDXT1TextureSupport;
+ bool mDXT3TextureSupport;
+ bool mDXT5TextureSupport;
+
+ bool mDepthTextureSupport;
+
+ // Multisample format support
+ struct MultisampleSupportInfo
+ {
+ unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT];
+ };
+
+ typedef std::unordered_map<DXGI_FORMAT, MultisampleSupportInfo> MultisampleSupportMap;
+ MultisampleSupportMap mMultisampleSupportMap;
+
+ unsigned int mMaxSupportedSamples;
+
+ // current render target states
+ unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
+ unsigned int mAppliedDepthbufferSerial;
+ unsigned int mAppliedStencilbufferSerial;
+ bool mDepthStencilInitialized;
+ bool mRenderTargetDescInitialized;
+ rx::RenderTarget::Desc mRenderTargetDesc;
+ unsigned int mCurDepthSize;
+ unsigned int mCurStencilSize;
+
+ // Currently applied sampler states
+ bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+ gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+ bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+ gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+ // Currently applied textures
+ unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+ unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+ // Currently applied blend state
+ bool mForceSetBlendState;
+ gl::BlendState mCurBlendState;
+ gl::Color mCurBlendColor;
+ unsigned int mCurSampleMask;
+
+ // Currently applied rasterizer state
+ bool mForceSetRasterState;
+ gl::RasterizerState mCurRasterState;
+
+ // Currently applied depth stencil state
+ bool mForceSetDepthStencilState;
+ gl::DepthStencilState mCurDepthStencilState;
+ int mCurStencilRef;
+ int mCurStencilBackRef;
+
+ // Currently applied scissor rectangle
+ bool mForceSetScissor;
+ bool mScissorEnabled;
+ gl::Rectangle mCurScissor;
+
+ // Currently applied viewport
+ bool mForceSetViewport;
+ gl::Rectangle mCurViewport;
+ float mCurNear;
+ float mCurFar;
+
+ unsigned int mAppliedIBSerial;
+ unsigned int mAppliedStorageIBSerial;
+ unsigned int mAppliedIBOffset;
+
+ unsigned int mAppliedProgramBinarySerial;
+ bool mIsGeometryShaderActive;
+
+ dx_VertexConstants mVertexConstants;
+ dx_VertexConstants mAppliedVertexConstants;
+ ID3D11Buffer *mDriverConstantBufferVS;
+
+ dx_PixelConstants mPixelConstants;
+ dx_PixelConstants mAppliedPixelConstants;
+ ID3D11Buffer *mDriverConstantBufferPS;
+
+ // Vertex, index and input layouts
+ VertexDataManager *mVertexDataManager;
+ IndexDataManager *mIndexDataManager;
+ InputLayoutCache mInputLayoutCache;
+
+ StreamingIndexBufferInterface *mLineLoopIB;
+ StreamingIndexBufferInterface *mTriangleFanIB;
+
+ // Texture copy resources
+ bool mCopyResourcesInitialized;
+ ID3D11Buffer *mCopyVB;
+ ID3D11SamplerState *mCopySampler;
+ ID3D11InputLayout *mCopyIL;
+ ID3D11VertexShader *mCopyVS;
+ ID3D11PixelShader *mCopyRGBAPS;
+ ID3D11PixelShader *mCopyRGBPS;
+ ID3D11PixelShader *mCopyLumPS;
+ ID3D11PixelShader *mCopyLumAlphaPS;
+
+ // Masked clear resources
+ bool mClearResourcesInitialized;
+ ID3D11Buffer *mClearVB;
+ ID3D11InputLayout *mClearIL;
+ ID3D11VertexShader *mClearVS;
+ ID3D11PixelShader *mClearPS;
+ ID3D11RasterizerState *mClearScissorRS;
+ ID3D11RasterizerState *mClearNoScissorRS;
+
+ // Sync query
+ ID3D11Query *mSyncQuery;
+
+ ID3D11Device *mDevice;
+ D3D_FEATURE_LEVEL mFeatureLevel;
+ ID3D11DeviceContext *mDeviceContext;
+ IDXGIAdapter *mDxgiAdapter;
+ DXGI_ADAPTER_DESC mAdapterDescription;
+ char mDescription[128];
+ IDXGIFactory *mDxgiFactory;
+
+ // Cached device caps
+ bool mBGRATextureSupport;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_RENDERER11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp
new file mode 100644
index 0000000000..8acbce4be7
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp
@@ -0,0 +1,3211 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/Framebuffer.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/renderer/IndexDataManager.h"
+#include "libGLESv2/renderer/Renderer9.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/ShaderExecutable9.h"
+#include "libGLESv2/renderer/SwapChain9.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+#include "libGLESv2/renderer/Image9.h"
+#include "libGLESv2/renderer/Blit.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/VertexBuffer9.h"
+#include "libGLESv2/renderer/IndexBuffer9.h"
+#include "libGLESv2/renderer/BufferStorage9.h"
+#include "libGLESv2/renderer/Query9.h"
+#include "libGLESv2/renderer/Fence9.h"
+
+#include "libEGL/Display.h"
+
+// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define REF_RAST 0
+
+// 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_ENABLE_D3D9EX=0" in your project file.
+#if !defined(ANGLE_ENABLE_D3D9EX)
+// Enables use of the IDirect3D9Ex interface, when available
+#define ANGLE_ENABLE_D3D9EX 1
+#endif // !defined(ANGLE_ENABLE_D3D9EX)
+
+#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+#endif
+
+namespace rx
+{
+static const D3DFORMAT RenderTargetFormats[] =
+ {
+ D3DFMT_A1R5G5B5,
+ // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+ D3DFMT_A8R8G8B8,
+ D3DFMT_R5G6B5,
+ // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
+ D3DFMT_X8R8G8B8
+ };
+
+static const D3DFORMAT DepthStencilFormats[] =
+ {
+ D3DFMT_UNKNOWN,
+ // D3DFMT_D16_LOCKABLE,
+ D3DFMT_D32,
+ // D3DFMT_D15S1,
+ D3DFMT_D24S8,
+ D3DFMT_D24X8,
+ // D3DFMT_D24X4S4,
+ D3DFMT_D16,
+ // D3DFMT_D32F_LOCKABLE,
+ // D3DFMT_D24FS8
+ };
+
+enum
+{
+ MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256,
+ MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32,
+ MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224,
+ MAX_VARYING_VECTORS_SM2 = 8,
+ MAX_VARYING_VECTORS_SM3 = 10,
+
+ MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
+};
+
+Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice)
+{
+ mD3d9Module = NULL;
+
+ mD3d9 = NULL;
+ mD3d9Ex = NULL;
+ mDevice = NULL;
+ mDeviceEx = NULL;
+ mDeviceWindow = NULL;
+ mBlit = NULL;
+
+ mAdapter = D3DADAPTER_DEFAULT;
+
+ #if REF_RAST == 1 || defined(FORCE_REF_RAST)
+ mDeviceType = D3DDEVTYPE_REF;
+ #else
+ mDeviceType = D3DDEVTYPE_HAL;
+ #endif
+
+ mDeviceLost = false;
+
+ mMaxSupportedSamples = 0;
+
+ mMaskedClearSavedState = NULL;
+
+ mVertexDataManager = NULL;
+ mIndexDataManager = NULL;
+ mLineLoopIB = NULL;
+
+ mMaxNullColorbufferLRU = 0;
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ mNullColorbufferCache[i].lruCount = 0;
+ mNullColorbufferCache[i].width = 0;
+ mNullColorbufferCache[i].height = 0;
+ mNullColorbufferCache[i].buffer = NULL;
+ }
+}
+
+Renderer9::~Renderer9()
+{
+ releaseDeviceResources();
+
+ if (mDevice)
+ {
+ // If the device is lost, reset it first to prevent leaving the driver in an unstable state
+ if (testDeviceLost(false))
+ {
+ resetDevice();
+ }
+
+ mDevice->Release();
+ mDevice = NULL;
+ }
+
+ if (mDeviceEx)
+ {
+ mDeviceEx->Release();
+ mDeviceEx = NULL;
+ }
+
+ if (mD3d9)
+ {
+ mD3d9->Release();
+ mD3d9 = NULL;
+ }
+
+ if (mDeviceWindow)
+ {
+ DestroyWindow(mDeviceWindow);
+ mDeviceWindow = NULL;
+ }
+
+ if (mD3d9Ex)
+ {
+ mD3d9Ex->Release();
+ mD3d9Ex = NULL;
+ }
+
+ if (mD3d9Module)
+ {
+ mD3d9Module = NULL;
+ }
+
+ while (!mMultiSampleSupport.empty())
+ {
+ delete [] mMultiSampleSupport.begin()->second;
+ mMultiSampleSupport.erase(mMultiSampleSupport.begin());
+ }
+}
+
+Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer));
+ return static_cast<rx::Renderer9*>(renderer);
+}
+
+EGLint Renderer9::initialize()
+{
+ if (!initializeCompiler())
+ {
+ return EGL_NOT_INITIALIZED;
+ }
+
+ if (mSoftwareDevice)
+ {
+ mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
+ }
+ else
+ {
+ mD3d9Module = GetModuleHandle(TEXT("d3d9.dll"));
+ }
+
+ if (mD3d9Module == NULL)
+ {
+ ERR("No D3D9 module found - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+ Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+ // Use Direct3D9Ex if available. Among other things, this version is less
+ // inclined to report a lost context, for example when the user switches
+ // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
+ if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex)))
+ {
+ ASSERT(mD3d9Ex);
+ mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+ ASSERT(mD3d9);
+ }
+ else
+ {
+ mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ }
+
+ if (!mD3d9)
+ {
+ ERR("Could not create D3D9 device - aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ if (mDc != NULL)
+ {
+ // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
+ }
+
+ HRESULT result;
+
+ // Give up on getting device caps after about one second.
+ for (int i = 0; i < 10; ++i)
+ {
+ result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
+ if (SUCCEEDED(result))
+ {
+ break;
+ }
+ else if (result == D3DERR_NOTAVAILABLE)
+ {
+ Sleep(100); // Give the driver some time to initialize/recover
+ }
+ else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
+ {
+ ERR("failed to get device caps (0x%x)\n", result);
+ return EGL_NOT_INITIALIZED;
+ }
+ }
+
+ if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
+ {
+ ERR("Renderer does not support PS 2.0. aborting!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
+ // This is required by Texture2D::convertToRenderTarget.
+ if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
+ {
+ ERR("Renderer does not support stretctrect from textures!\n");
+ return EGL_NOT_INITIALIZED;
+ }
+
+ mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier);
+
+ // ATI cards on XP have problems with non-power-of-two textures.
+ mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) &&
+ !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) &&
+ !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &&
+ !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD);
+
+ // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
+ mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2));
+
+ mMinSwapInterval = 4;
+ mMaxSwapInterval = 0;
+
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE)
+ {
+ mMinSwapInterval = std::min(mMinSwapInterval, 0);
+ mMaxSwapInterval = std::max(mMaxSwapInterval, 0);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE)
+ {
+ mMinSwapInterval = std::min(mMinSwapInterval, 1);
+ mMaxSwapInterval = std::max(mMaxSwapInterval, 1);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO)
+ {
+ mMinSwapInterval = std::min(mMinSwapInterval, 2);
+ mMaxSwapInterval = std::max(mMaxSwapInterval, 2);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE)
+ {
+ mMinSwapInterval = std::min(mMinSwapInterval, 3);
+ mMaxSwapInterval = std::max(mMaxSwapInterval, 3);
+ }
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR)
+ {
+ mMinSwapInterval = std::min(mMinSwapInterval, 4);
+ mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
+ }
+
+ int max = 0;
+ for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i)
+ {
+ bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+ getMultiSampleSupport(RenderTargetFormats[i], multisampleArray);
+ mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray;
+
+ for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
+ {
+ if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
+ {
+ max = j;
+ }
+ }
+ }
+
+ for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i)
+ {
+ if (DepthStencilFormats[i] == D3DFMT_UNKNOWN)
+ continue;
+
+ bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+ getMultiSampleSupport(DepthStencilFormats[i], multisampleArray);
+ mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray;
+
+ for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
+ {
+ if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
+ {
+ max = j;
+ }
+ }
+ }
+
+ mMaxSupportedSamples = max;
+
+ static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+ static const TCHAR className[] = TEXT("STATIC");
+
+ mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
+
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+ DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
+
+ result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
+ {
+ return EGL_BAD_ALLOC;
+ }
+
+ if (FAILED(result))
+ {
+ result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ if (mD3d9Ex)
+ {
+ result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx);
+ ASSERT(SUCCEEDED(result));
+ }
+
+ mVertexShaderCache.initialize(mDevice);
+ mPixelShaderCache.initialize(mDevice);
+
+ // Check occlusion query support
+ IDirect3DQuery9 *occlusionQuery = NULL;
+ if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery)
+ {
+ occlusionQuery->Release();
+ mOcclusionQuerySupport = true;
+ }
+ else
+ {
+ mOcclusionQuerySupport = false;
+ }
+
+ // Check event query support
+ IDirect3DQuery9 *eventQuery = NULL;
+ if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery)
+ {
+ eventQuery->Release();
+ mEventQuerySupport = true;
+ }
+ else
+ {
+ mEventQuerySupport = false;
+ }
+
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ // Check vertex texture support
+ // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+ // We test this using D3D9 by checking support for the R16F format.
+ mVertexTextureSupport = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+ D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F));
+
+ // Check depth texture support
+ // we use INTZ for depth textures in Direct3D9
+ // we also want NULL texture support to ensure the we can make depth-only FBOs
+ // see http://aras-p.info/texts/D3D9GPUHacks.html
+ mDepthTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+ D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+ D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
+
+ // Check 32 bit floating point texture support
+ mFloat32FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+ D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+
+ mFloat32RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+ D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+
+ if (!mFloat32FilterSupport && !mFloat32RenderSupport)
+ {
+ mFloat32TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+ D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+ }
+ else
+ {
+ mFloat32TextureSupport = true;
+ }
+
+ // Check 16 bit floating point texture support
+ mFloat16FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+ D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+
+ mFloat16RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+ D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+
+ if (!mFloat16FilterSupport && !mFloat16RenderSupport)
+ {
+ mFloat16TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+ D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &&
+ SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+ D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+ }
+ else
+ {
+ mFloat16TextureSupport = true;
+ }
+
+ // Check DXT texture support
+ mDXT1TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
+ mDXT3TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
+ mDXT5TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
+
+ // Check luminance[alpha] texture support
+ mLuminanceTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
+ mLuminanceAlphaTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
+
+ initializeDevice();
+
+ return EGL_SUCCESS;
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+void Renderer9::initializeDevice()
+{
+ // Permanent non-default states
+ mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE);
+
+ if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
+ {
+ mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize);
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f
+ }
+
+ markAllStateDirty();
+
+ mSceneStarted = false;
+
+ ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager);
+ mBlit = new Blit(this);
+ mVertexDataManager = new rx::VertexDataManager(this);
+ mIndexDataManager = new rx::IndexDataManager(this);
+}
+
+D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
+{
+ D3DPRESENT_PARAMETERS presentParameters = {0};
+
+ // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+ presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferWidth = 1;
+ presentParameters.BackBufferHeight = 1;
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = mDeviceWindow;
+ presentParameters.MultiSampleQuality = 0;
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+ presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+
+ return presentParameters;
+}
+
+int Renderer9::generateConfigs(ConfigDesc **configDescList)
+{
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
+ unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
+ (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
+ int numConfigs = 0;
+
+ for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++)
+ {
+ D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
+
+ HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+
+ if (SUCCEEDED(result))
+ {
+ for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++)
+ {
+ D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
+ HRESULT result = D3D_OK;
+
+ if(depthStencilFormat != D3DFMT_UNKNOWN)
+ {
+ result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ if(depthStencilFormat != D3DFMT_UNKNOWN)
+ {
+ result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+ }
+
+ if (SUCCEEDED(result))
+ {
+ ConfigDesc newConfig;
+ newConfig.renderTargetFormat = d3d9_gl::ConvertBackBufferFormat(renderTargetFormat);
+ newConfig.depthStencilFormat = d3d9_gl::ConvertDepthStencilFormat(depthStencilFormat);
+ newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
+ newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat);
+
+ (*configDescList)[numConfigs++] = newConfig;
+ }
+ }
+ }
+ }
+ }
+
+ return numConfigs;
+}
+
+void Renderer9::deleteConfigs(ConfigDesc *configDescList)
+{
+ delete [] (configDescList);
+}
+
+void Renderer9::startScene()
+{
+ if (!mSceneStarted)
+ {
+ long result = mDevice->BeginScene();
+ if (SUCCEEDED(result)) {
+ // This is defensive checking against the device being
+ // lost at unexpected times.
+ mSceneStarted = true;
+ }
+ }
+}
+
+void Renderer9::endScene()
+{
+ if (mSceneStarted)
+ {
+ // EndScene can fail if the device was lost, for example due
+ // to a TDR during a draw call.
+ mDevice->EndScene();
+ mSceneStarted = false;
+ }
+}
+
+void Renderer9::sync(bool block)
+{
+ HRESULT result;
+
+ IDirect3DQuery9* query = allocateEventQuery();
+ if (!query)
+ {
+ return;
+ }
+
+ result = query->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+
+ do
+ {
+ result = query->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+ if(block && result == S_FALSE)
+ {
+ // Keep polling, but allow other threads to do something useful first
+ Sleep(0);
+ // explicitly check for device loss
+ // some drivers seem to return S_FALSE even if the device is lost
+ // instead of D3DERR_DEVICELOST like they should
+ if (testDeviceLost(false))
+ {
+ result = D3DERR_DEVICELOST;
+ }
+ }
+ }
+ while(block && result == S_FALSE);
+
+ freeEventQuery(query);
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ }
+}
+
+SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+{
+ return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+}
+
+IDirect3DQuery9* Renderer9::allocateEventQuery()
+{
+ IDirect3DQuery9 *query = NULL;
+
+ if (mEventQueryPool.empty())
+ {
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+ ASSERT(SUCCEEDED(result));
+ }
+ else
+ {
+ query = mEventQueryPool.back();
+ mEventQueryPool.pop_back();
+ }
+
+ return query;
+}
+
+void Renderer9::freeEventQuery(IDirect3DQuery9* query)
+{
+ if (mEventQueryPool.size() > 1000)
+ {
+ query->Release();
+ }
+ else
+ {
+ mEventQueryPool.push_back(query);
+ }
+}
+
+IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length)
+{
+ return mVertexShaderCache.create(function, length);
+}
+
+IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length)
+{
+ return mPixelShaderCache.create(function, length);
+}
+
+HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer)
+{
+ D3DPOOL Pool = getBufferPool(Usage);
+ return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL);
+}
+
+VertexBuffer *Renderer9::createVertexBuffer()
+{
+ return new VertexBuffer9(this);
+}
+
+HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer)
+{
+ D3DPOOL Pool = getBufferPool(Usage);
+ return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL);
+}
+
+IndexBuffer *Renderer9::createIndexBuffer()
+{
+ return new IndexBuffer9(this);
+}
+
+BufferStorage *Renderer9::createBufferStorage()
+{
+ return new BufferStorage9();
+}
+
+QueryImpl *Renderer9::createQuery(GLenum type)
+{
+ return new Query9(this, type);
+}
+
+FenceImpl *Renderer9::createFence()
+{
+ return new Fence9(this);
+}
+
+void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState)
+{
+ bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
+ gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
+
+ if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0)
+ {
+ int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+ int d3dSampler = index + d3dSamplerOffset;
+
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
+
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
+ D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
+ gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset);
+ if (mSupportsTextureFilterAnisotropy)
+ {
+ mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
+ }
+ }
+
+ forceSetSamplers[index] = false;
+ appliedSamplers[index] = samplerState;
+}
+
+void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
+{
+ int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+ int d3dSampler = index + d3dSamplerOffset;
+ IDirect3DBaseTexture9 *d3dTexture = NULL;
+ unsigned int serial = 0;
+ bool forceSetTexture = false;
+
+ unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
+
+ if (texture)
+ {
+ TextureStorageInterface *texStorage = texture->getNativeTexture();
+ if (texStorage)
+ {
+ TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance());
+ d3dTexture = storage9->getBaseTexture();
+ }
+ // If we get NULL back from getBaseTexture here, something went wrong
+ // in the texture class and we're unexpectedly missing the d3d texture
+ ASSERT(d3dTexture != NULL);
+
+ serial = texture->getTextureSerial();
+ forceSetTexture = texture->hasDirtyImages();
+ }
+
+ if (forceSetTexture || appliedSerials[index] != serial)
+ {
+ mDevice->SetTexture(d3dSampler, d3dTexture);
+ }
+
+ appliedSerials[index] = serial;
+}
+
+void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState)
+{
+ bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0;
+
+ if (rasterStateChanged)
+ {
+ // Set the cull mode
+ if (rasterState.cullFace)
+ {
+ mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ }
+
+ if (rasterState.polygonOffsetFill)
+ {
+ if (mCurDepthSize > 0)
+ {
+ mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor);
+
+ float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast<int>(mCurDepthSize));
+ mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias);
+ }
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
+ mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
+ }
+
+ mCurRasterState = rasterState;
+ }
+
+ mForceSetRasterState = false;
+}
+
+void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, unsigned int sampleMask)
+{
+ bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0;
+ bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0;
+ bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask;
+
+ if (blendStateChanged || blendColorChanged)
+ {
+ if (blendState.blend)
+ {
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &&
+ blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+ {
+ mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha),
+ gl::unorm<8>(blendColor.alpha),
+ gl::unorm<8>(blendColor.alpha),
+ gl::unorm<8>(blendColor.alpha)));
+ }
+
+ mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB));
+ mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB));
+ mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB));
+
+ if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha ||
+ blendState.destBlendRGB != blendState.destBlendAlpha ||
+ blendState.blendEquationRGB != blendState.blendEquationAlpha)
+ {
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+
+ mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha));
+ mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha));
+ mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+ }
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ }
+
+ if (blendState.sampleAlphaToCoverage)
+ {
+ FIXME("Sample alpha to coverage is unimplemented.");
+ }
+
+ // Set the color mask
+ bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD;
+ // Apparently some ATI cards have a bug where a draw with a zero color
+ // write mask can cause later draws to have incorrect results. Instead,
+ // set a nonzero color write mask but modify the blend state so that no
+ // drawing is done.
+ // http://code.google.com/p/angleproject/issues/detail?id=169
+
+ DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
+ blendState.colorMaskBlue, blendState.colorMaskAlpha);
+ if (colorMask == 0 && !zeroColorMaskAllowed)
+ {
+ // Enable green channel, but set blending so nothing will be drawn.
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+ mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+ mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+ mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
+ }
+
+ mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE);
+
+ mCurBlendState = blendState;
+ mCurBlendColor = blendColor;
+ }
+
+ if (sampleMaskChanged)
+ {
+ // Set the multisample mask
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast<DWORD>(sampleMask));
+
+ mCurSampleMask = sampleMask;
+ }
+
+ mForceSetBlendState = false;
+}
+
+void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW)
+{
+ bool depthStencilStateChanged = mForceSetDepthStencilState ||
+ memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0;
+ bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef ||
+ stencilBackRef != mCurStencilBackRef;
+ bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW;
+
+ if (depthStencilStateChanged)
+ {
+ if (depthStencilState.depthTest)
+ {
+ mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+ mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ }
+
+ mCurDepthStencilState = depthStencilState;
+ }
+
+ if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged)
+ {
+ if (depthStencilState.stencilTest && mCurStencilSize > 0)
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
+
+ // FIXME: Unsupported by D3D9
+ const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
+ const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
+ const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
+ if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
+ stencilRef != stencilBackRef ||
+ depthStencilState.stencilMask != depthStencilState.stencilBackMask)
+ {
+ ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
+ return gl::error(GL_INVALID_OPERATION);
+ }
+
+ // get the maximum size of the stencil ref
+ unsigned int maxStencil = (1 << mCurStencilSize) - 1;
+
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
+ depthStencilState.stencilWritemask);
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+ gl_d3d9::ConvertComparison(depthStencilState.stencilFunc));
+
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+ (stencilRef < (int)maxStencil) ? stencilRef : maxStencil);
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
+ depthStencilState.stencilMask);
+
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail));
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail));
+ mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass));
+
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
+ depthStencilState.stencilBackWritemask);
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+ gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc));
+
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+ (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil);
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
+ depthStencilState.stencilBackMask);
+
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail));
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail));
+ mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+ gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE);
+
+ mCurStencilRef = stencilRef;
+ mCurStencilBackRef = stencilBackRef;
+ mCurFrontFaceCCW = frontFaceCCW;
+ }
+
+ mForceSetDepthStencilState = false;
+}
+
+void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled)
+{
+ bool scissorChanged = mForceSetScissor ||
+ memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+ enabled != mScissorEnabled;
+
+ if (scissorChanged)
+ {
+ if (enabled)
+ {
+ RECT rect;
+ rect.left = gl::clamp(scissor.x, 0, static_cast<int>(mRenderTargetDesc.width));
+ rect.top = gl::clamp(scissor.y, 0, static_cast<int>(mRenderTargetDesc.height));
+ rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast<int>(mRenderTargetDesc.width));
+ rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast<int>(mRenderTargetDesc.height));
+ mDevice->SetScissorRect(&rect);
+ }
+
+ mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE);
+
+ mScissorEnabled = enabled;
+ mCurScissor = scissor;
+ }
+
+ mForceSetScissor = false;
+}
+
+bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport)
+{
+ gl::Rectangle actualViewport = viewport;
+ float actualZNear = gl::clamp01(zNear);
+ float actualZFar = gl::clamp01(zFar);
+ if (ignoreViewport)
+ {
+ actualViewport.x = 0;
+ actualViewport.y = 0;
+ actualViewport.width = mRenderTargetDesc.width;
+ actualViewport.height = mRenderTargetDesc.height;
+ actualZNear = 0.0f;
+ actualZFar = 1.0f;
+ }
+
+ D3DVIEWPORT9 dxViewport;
+ dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast<int>(mRenderTargetDesc.width));
+ dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast<int>(mRenderTargetDesc.height));
+ dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast<int>(mRenderTargetDesc.width) - static_cast<int>(dxViewport.X));
+ dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast<int>(mRenderTargetDesc.height) - static_cast<int>(dxViewport.Y));
+ dxViewport.MinZ = actualZNear;
+ dxViewport.MaxZ = actualZFar;
+
+ if (dxViewport.Width <= 0 || dxViewport.Height <= 0)
+ {
+ return false; // Nothing to render
+ }
+
+ bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+ actualZNear != mCurNear || actualZFar != mCurFar;
+ if (viewportChanged)
+ {
+ mDevice->SetViewport(&dxViewport);
+
+ mCurViewport = actualViewport;
+ mCurNear = actualZNear;
+ mCurFar = actualZFar;
+
+ dx_VertexConstants vc = {0};
+ dx_PixelConstants pc = {0};
+
+ vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width;
+ vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height;
+ vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width;
+ vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height;
+
+ pc.viewCoords[0] = actualViewport.width * 0.5f;
+ pc.viewCoords[1] = actualViewport.height * 0.5f;
+ pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f);
+ pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+
+ pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+ pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+ pc.depthFront[2] = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);;
+
+ vc.depthRange[0] = actualZNear;
+ vc.depthRange[1] = actualZFar;
+ vc.depthRange[2] = actualZFar - actualZNear;
+
+ pc.depthRange[0] = actualZNear;
+ pc.depthRange[1] = actualZFar;
+ pc.depthRange[2] = actualZFar - actualZNear;
+
+ if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0)
+ {
+ mVertexConstants = vc;
+ mDxUniformsDirty = true;
+ }
+
+ if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0)
+ {
+ mPixelConstants = pc;
+ mDxUniformsDirty = true;
+ }
+ }
+
+ mForceSetViewport = false;
+ return true;
+}
+
+bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+ switch (mode)
+ {
+ case GL_POINTS:
+ mPrimitiveType = D3DPT_POINTLIST;
+ mPrimitiveCount = count;
+ break;
+ case GL_LINES:
+ mPrimitiveType = D3DPT_LINELIST;
+ mPrimitiveCount = count / 2;
+ break;
+ case GL_LINE_LOOP:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount = count - 1; // D3D doesn't support line loops, so we draw the last line separately
+ break;
+ case GL_LINE_STRIP:
+ mPrimitiveType = D3DPT_LINESTRIP;
+ mPrimitiveCount = count - 1;
+ break;
+ case GL_TRIANGLES:
+ mPrimitiveType = D3DPT_TRIANGLELIST;
+ mPrimitiveCount = count / 3;
+ break;
+ case GL_TRIANGLE_STRIP:
+ mPrimitiveType = D3DPT_TRIANGLESTRIP;
+ mPrimitiveCount = count - 2;
+ break;
+ case GL_TRIANGLE_FAN:
+ mPrimitiveType = D3DPT_TRIANGLEFAN;
+ mPrimitiveCount = count - 2;
+ break;
+ default:
+ return gl::error(GL_INVALID_ENUM, false);
+ }
+
+ return mPrimitiveCount > 0;
+}
+
+
+gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer)
+{
+ if (!depthbuffer)
+ {
+ ERR("Unexpected null depthbuffer for depth-only FBO.");
+ return NULL;
+ }
+
+ GLsizei width = depthbuffer->getWidth();
+ GLsizei height = depthbuffer->getHeight();
+
+ // search cached nullcolorbuffers
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ if (mNullColorbufferCache[i].buffer != NULL &&
+ mNullColorbufferCache[i].width == width &&
+ mNullColorbufferCache[i].height == height)
+ {
+ mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU;
+ return mNullColorbufferCache[i].buffer;
+ }
+ }
+
+ gl::Renderbuffer *nullbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+
+ // add nullbuffer to the cache
+ NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0];
+ for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ if (mNullColorbufferCache[i].lruCount < oldest->lruCount)
+ {
+ oldest = &mNullColorbufferCache[i];
+ }
+ }
+
+ delete oldest->buffer;
+ oldest->buffer = nullbuffer;
+ oldest->lruCount = ++mMaxNullColorbufferLRU;
+ oldest->width = width;
+ oldest->height = height;
+
+ return nullbuffer;
+}
+
+bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
+{
+ // if there is no color attachment we must synthesize a NULL colorattachment
+ // to keep the D3D runtime happy. This should only be possible if depth texturing.
+ gl::Renderbuffer *renderbufferObject = NULL;
+ if (framebuffer->getColorbufferType(0) != GL_NONE)
+ {
+ renderbufferObject = framebuffer->getColorbuffer(0);
+ }
+ else
+ {
+ renderbufferObject = getNullColorbuffer(framebuffer->getDepthbuffer());
+ }
+ if (!renderbufferObject)
+ {
+ ERR("unable to locate renderbuffer for FBO.");
+ return false;
+ }
+
+ bool renderTargetChanged = false;
+ unsigned int renderTargetSerial = renderbufferObject->getSerial();
+ if (renderTargetSerial != mAppliedRenderTargetSerial)
+ {
+ // Apply the render target on the device
+ IDirect3DSurface9 *renderTargetSurface = NULL;
+
+ RenderTarget *renderTarget = renderbufferObject->getRenderTarget();
+ if (renderTarget)
+ {
+ renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface();
+ }
+
+ if (!renderTargetSurface)
+ {
+ ERR("render target pointer unexpectedly null.");
+ return false; // Context must be lost
+ }
+
+ mDevice->SetRenderTarget(0, renderTargetSurface);
+ renderTargetSurface->Release();
+
+ mAppliedRenderTargetSerial = renderTargetSerial;
+ renderTargetChanged = true;
+ }
+
+ gl::Renderbuffer *depthStencil = NULL;
+ unsigned int depthbufferSerial = 0;
+ unsigned int stencilbufferSerial = 0;
+ if (framebuffer->getDepthbufferType() != GL_NONE)
+ {
+ depthStencil = framebuffer->getDepthbuffer();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ return false;
+ }
+
+ depthbufferSerial = depthStencil->getSerial();
+ }
+ else if (framebuffer->getStencilbufferType() != GL_NONE)
+ {
+ depthStencil = framebuffer->getStencilbuffer();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ return false;
+ }
+
+ stencilbufferSerial = depthStencil->getSerial();
+ }
+
+ if (depthbufferSerial != mAppliedDepthbufferSerial ||
+ stencilbufferSerial != mAppliedStencilbufferSerial ||
+ !mDepthStencilInitialized)
+ {
+ unsigned int depthSize = 0;
+ unsigned int stencilSize = 0;
+
+ // Apply the depth stencil on the device
+ if (depthStencil)
+ {
+ IDirect3DSurface9 *depthStencilSurface = NULL;
+ RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil();
+
+ if (depthStencilRenderTarget)
+ {
+ depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface();
+ }
+
+ if (!depthStencilSurface)
+ {
+ ERR("depth stencil pointer unexpectedly null.");
+ return false; // Context must be lost
+ }
+
+ mDevice->SetDepthStencilSurface(depthStencilSurface);
+ depthStencilSurface->Release();
+
+ depthSize = depthStencil->getDepthSize();
+ stencilSize = depthStencil->getStencilSize();
+ }
+ else
+ {
+ mDevice->SetDepthStencilSurface(NULL);
+ }
+
+ if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
+ {
+ mCurDepthSize = depthSize;
+ mForceSetRasterState = true;
+ }
+
+ if (!mDepthStencilInitialized || stencilSize != mCurStencilSize)
+ {
+ mCurStencilSize = stencilSize;
+ mForceSetDepthStencilState = true;
+ }
+
+ mAppliedDepthbufferSerial = depthbufferSerial;
+ mAppliedStencilbufferSerial = stencilbufferSerial;
+ mDepthStencilInitialized = true;
+ }
+
+ if (renderTargetChanged || !mRenderTargetDescInitialized)
+ {
+ mForceSetScissor = true;
+ mForceSetViewport = true;
+
+ mRenderTargetDesc.width = renderbufferObject->getWidth();
+ mRenderTargetDesc.height = renderbufferObject->getHeight();
+ mRenderTargetDesc.format = renderbufferObject->getActualFormat();
+ mRenderTargetDescInitialized = true;
+ }
+
+ return true;
+}
+
+GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+{
+ TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
+ GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+ if (err != GL_NO_ERROR)
+ {
+ return err;
+ }
+
+ return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw);
+}
+
+// Applies the indices and element array bindings to the Direct3D 9 device
+GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+ GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+
+ if (err == GL_NO_ERROR)
+ {
+ // Directly binding the storage buffer is not supported for d3d9
+ ASSERT(indexInfo->storage == NULL);
+
+ if (indexInfo->serial != mAppliedIBSerial)
+ {
+ IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer);
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = indexInfo->serial;
+ }
+ }
+
+ return err;
+}
+
+void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+ startScene();
+
+ if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, GL_NONE, NULL, 0, NULL);
+ }
+ else if (instances > 0)
+ {
+ StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count);
+ if (countingIB)
+ {
+ if (mAppliedIBSerial != countingIB->getSerial())
+ {
+ IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = countingIB->getSerial();
+ }
+
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
+ }
+ }
+ else
+ {
+ ERR("Could not create a counting index buffer for glDrawArraysInstanced.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+ else // Regular case
+ {
+ mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount);
+ }
+}
+
+void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/)
+{
+ startScene();
+
+ if (mode == GL_POINTS)
+ {
+ drawIndexedPoints(count, type, indices, elementArrayBuffer);
+ }
+ else if (mode == GL_LINE_LOOP)
+ {
+ drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+ }
+ else
+ {
+ for (int i = 0; i < mRepeatDraw; i++)
+ {
+ GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+ mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
+ }
+ }
+}
+
+void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+ // Get the raw indices for an indexed draw
+ if (type != GL_NONE && elementArrayBuffer)
+ {
+ gl::Buffer *indexBuffer = elementArrayBuffer;
+ BufferStorage *storage = indexBuffer->getStorage();
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
+ UINT startIndex = 0;
+
+ if (get32BitIndexSupport())
+ {
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ const int spaceNeeded = (count + 1) * sizeof(unsigned int);
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+ {
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ void* mappedMemory = NULL;
+ int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
+ {
+ ERR("Could not map index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ startIndex = static_cast<UINT>(offset) / 4;
+ unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+ else
+ {
+ if (!mLineLoopIB)
+ {
+ mLineLoopIB = new StreamingIndexBufferInterface(this);
+ if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
+ {
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ const int spaceNeeded = (count + 1) * sizeof(unsigned short);
+ if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT))
+ {
+ ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ void* mappedMemory = NULL;
+ int offset = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory);
+ if (offset == -1 || mappedMemory == NULL)
+ {
+ ERR("Could not map index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ startIndex = static_cast<UINT>(offset) / 2;
+ unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
+
+ switch (type)
+ {
+ case GL_NONE: // Non-indexed draw
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = i;
+ }
+ data[count] = 0;
+ break;
+ case GL_UNSIGNED_BYTE:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLubyte*>(indices)[i];
+ }
+ data[count] = static_cast<const GLubyte*>(indices)[0];
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLushort*>(indices)[i];
+ }
+ data[count] = static_cast<const GLushort*>(indices)[0];
+ break;
+ case GL_UNSIGNED_INT:
+ for (int i = 0; i < count; i++)
+ {
+ data[i] = static_cast<const GLuint*>(indices)[i];
+ }
+ data[count] = static_cast<const GLuint*>(indices)[0];
+ break;
+ default: UNREACHABLE();
+ }
+
+ if (!mLineLoopIB->unmapBuffer())
+ {
+ ERR("Could not unmap index buffer for GL_LINE_LOOP.");
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ if (mAppliedIBSerial != mLineLoopIB->getSerial())
+ {
+ IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer());
+
+ mDevice->SetIndices(indexBuffer->getBuffer());
+ mAppliedIBSerial = mLineLoopIB->getSerial();
+ }
+
+ mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
+}
+
+template <typename T>
+static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices)
+{
+ for (int i = 0; i < count; i++)
+ {
+ unsigned int indexValue = static_cast<unsigned int>(static_cast<const T*>(indices)[i]);
+ device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1);
+ }
+}
+
+void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer)
+{
+ // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call
+ // for each individual point. This call is not expected to happen often.
+
+ if (elementArrayBuffer)
+ {
+ BufferStorage *storage = elementArrayBuffer->getStorage();
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(storage->getData()) + offset;
+ }
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE: drawPoints<GLubyte>(mDevice, count, indices); break;
+ case GL_UNSIGNED_SHORT: drawPoints<GLushort>(mDevice, count, indices); break;
+ case GL_UNSIGNED_INT: drawPoints<GLuint>(mDevice, count, indices); break;
+ default: UNREACHABLE();
+ }
+}
+
+void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
+{
+ unsigned int programBinarySerial = programBinary->getSerial();
+ if (programBinarySerial != mAppliedProgramBinarySerial)
+ {
+ ShaderExecutable *vertexExe = programBinary->getVertexExecutable();
+ ShaderExecutable *pixelExe = programBinary->getPixelExecutable();
+
+ IDirect3DVertexShader9 *vertexShader = NULL;
+ if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader();
+
+ IDirect3DPixelShader9 *pixelShader = NULL;
+ if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader();
+
+ mDevice->SetPixelShader(pixelShader);
+ mDevice->SetVertexShader(vertexShader);
+ programBinary->dirtyAllUniforms();
+ mDxUniformsDirty = true;
+
+ mAppliedProgramBinarySerial = programBinarySerial;
+ }
+}
+
+void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
+{
+ for (std::vector<gl::Uniform*>::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub)
+ {
+ gl::Uniform *targetUniform = *ub;
+
+ if (targetUniform->dirty)
+ {
+ GLfloat *f = (GLfloat*)targetUniform->data;
+ GLint *i = (GLint*)targetUniform->data;
+
+ switch (targetUniform->type)
+ {
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
+ break;
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ applyUniformnbv(targetUniform, i);
+ break;
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT2:
+ case GL_FLOAT_MAT3:
+ case GL_FLOAT_MAT4:
+ applyUniformnfv(targetUniform, f);
+ break;
+ case GL_INT:
+ case GL_INT_VEC2:
+ case GL_INT_VEC3:
+ case GL_INT_VEC4:
+ applyUniformniv(targetUniform, i);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ targetUniform->dirty = false;
+ }
+ }
+
+ // Driver uniforms
+ if (mDxUniformsDirty)
+ {
+ mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4]));
+ mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4]));
+ mDxUniformsDirty = false;
+ }
+}
+
+void Renderer9::applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v)
+{
+ if (targetUniform->psRegisterIndex >= 0)
+ {
+ mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount);
+ }
+
+ if (targetUniform->vsRegisterIndex >= 0)
+ {
+ mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount);
+ }
+}
+
+void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v)
+{
+ ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+ GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+ for (unsigned int i = 0; i < targetUniform->registerCount; i++)
+ {
+ vector[i][0] = (GLfloat)v[4 * i + 0];
+ vector[i][1] = (GLfloat)v[4 * i + 1];
+ vector[i][2] = (GLfloat)v[4 * i + 2];
+ vector[i][3] = (GLfloat)v[4 * i + 3];
+ }
+
+ applyUniformnfv(targetUniform, (GLfloat*)vector);
+}
+
+void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v)
+{
+ ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+ GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+ for (unsigned int i = 0; i < targetUniform->registerCount; i++)
+ {
+ vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f;
+ vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f;
+ }
+
+ applyUniformnfv(targetUniform, (GLfloat*)vector);
+}
+
+void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer)
+{
+ D3DCOLOR color = D3DCOLOR_ARGB(gl::unorm<8>(clearParams.colorClearValue.alpha),
+ gl::unorm<8>(clearParams.colorClearValue.red),
+ gl::unorm<8>(clearParams.colorClearValue.green),
+ gl::unorm<8>(clearParams.colorClearValue.blue));
+ float depth = gl::clamp01(clearParams.depthClearValue);
+ int stencil = clearParams.stencilClearValue & 0x000000FF;
+
+ unsigned int stencilUnmasked = 0x0;
+ if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil())
+ {
+ unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat());
+ stencilUnmasked = (0x1 << stencilSize) - 1;
+ }
+
+ bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
+
+ const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) &&
+ (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked;
+ const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) &&
+ !(clearParams.colorMaskRed && clearParams.colorMaskGreen &&
+ clearParams.colorMaskBlue && alphaUnmasked);
+
+ if (needMaskedColorClear || needMaskedStencilClear)
+ {
+ // State which is altered in all paths from this point to the clear call is saved.
+ // State which is altered in only some paths will be flagged dirty in the case that
+ // that path is taken.
+ HRESULT hr;
+ if (mMaskedClearSavedState == NULL)
+ {
+ hr = mDevice->BeginStateBlock();
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ mDevice->SetPixelShader(NULL);
+ mDevice->SetVertexShader(NULL);
+ mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
+ mDevice->SetStreamSource(0, NULL, 0, 0);
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+ mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+ mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+ for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mDevice->SetStreamSourceFreq(i, 1);
+ }
+
+ hr = mDevice->EndStateBlock(&mMaskedClearSavedState);
+ ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+ }
+
+ ASSERT(mMaskedClearSavedState != NULL);
+
+ if (mMaskedClearSavedState != NULL)
+ {
+ hr = mMaskedClearSavedState->Capture();
+ ASSERT(SUCCEEDED(hr));
+ }
+
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+
+ if (clearParams.mask & GL_COLOR_BUFFER_BIT)
+ {
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE,
+ gl_d3d9::ConvertColorMask(clearParams.colorMaskRed,
+ clearParams.colorMaskGreen,
+ clearParams.colorMaskBlue,
+ clearParams.colorMaskAlpha));
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+ }
+
+ if (stencilUnmasked != 0x0 && (clearParams.mask & GL_STENCIL_BUFFER_BIT))
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+ mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ mDevice->SetRenderState(D3DRS_STENCILREF, stencil);
+ mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask);
+ mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
+ mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
+ mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+ }
+ else
+ {
+ mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ }
+
+ mDevice->SetPixelShader(NULL);
+ mDevice->SetVertexShader(NULL);
+ mDevice->SetFVF(D3DFVF_XYZRHW);
+ mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+ mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+ mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+ mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color);
+ mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+ for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mDevice->SetStreamSourceFreq(i, 1);
+ }
+
+ float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges
+ quad[0][0] = -0.5f;
+ quad[0][1] = mRenderTargetDesc.height - 0.5f;
+ quad[0][2] = 0.0f;
+ quad[0][3] = 1.0f;
+
+ quad[1][0] = mRenderTargetDesc.width - 0.5f;
+ quad[1][1] = mRenderTargetDesc.height - 0.5f;
+ quad[1][2] = 0.0f;
+ quad[1][3] = 1.0f;
+
+ quad[2][0] = -0.5f;
+ quad[2][1] = -0.5f;
+ quad[2][2] = 0.0f;
+ quad[2][3] = 1.0f;
+
+ quad[3][0] = mRenderTargetDesc.width - 0.5f;
+ quad[3][1] = -0.5f;
+ quad[3][2] = 0.0f;
+ quad[3][3] = 1.0f;
+
+ startScene();
+ mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
+
+ if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
+ {
+ mDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
+ mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+ mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
+ }
+
+ if (mMaskedClearSavedState != NULL)
+ {
+ mMaskedClearSavedState->Apply();
+ }
+ }
+ else if (clearParams.mask)
+ {
+ DWORD dxClearFlags = 0;
+ if (clearParams.mask & GL_COLOR_BUFFER_BIT)
+ {
+ dxClearFlags |= D3DCLEAR_TARGET;
+ }
+ if (clearParams.mask & GL_DEPTH_BUFFER_BIT)
+ {
+ dxClearFlags |= D3DCLEAR_ZBUFFER;
+ }
+ if (clearParams.mask & GL_STENCIL_BUFFER_BIT)
+ {
+ dxClearFlags |= D3DCLEAR_STENCIL;
+ }
+
+ mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil);
+ }
+}
+
+void Renderer9::markAllStateDirty()
+{
+ mAppliedRenderTargetSerial = 0;
+ mAppliedDepthbufferSerial = 0;
+ mAppliedStencilbufferSerial = 0;
+ mDepthStencilInitialized = false;
+ mRenderTargetDescInitialized = false;
+
+ mForceSetDepthStencilState = true;
+ mForceSetRasterState = true;
+ mForceSetScissor = true;
+ mForceSetViewport = true;
+ mForceSetBlendState = true;
+
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+ {
+ mForceSetVertexSamplerStates[i] = true;
+ mCurVertexTextureSerials[i] = 0;
+ }
+ for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+ {
+ mForceSetPixelSamplerStates[i] = true;
+ mCurPixelTextureSerials[i] = 0;
+ }
+
+ mAppliedIBSerial = 0;
+ mAppliedProgramBinarySerial = 0;
+ mDxUniformsDirty = true;
+
+ mVertexDeclarationCache.markStateDirty();
+}
+
+void Renderer9::releaseDeviceResources()
+{
+ while (!mEventQueryPool.empty())
+ {
+ mEventQueryPool.back()->Release();
+ mEventQueryPool.pop_back();
+ }
+
+ if (mMaskedClearSavedState)
+ {
+ mMaskedClearSavedState->Release();
+ mMaskedClearSavedState = NULL;
+ }
+
+ mVertexShaderCache.clear();
+ mPixelShaderCache.clear();
+
+ delete mBlit;
+ mBlit = NULL;
+
+ delete mVertexDataManager;
+ mVertexDataManager = NULL;
+
+ delete mIndexDataManager;
+ mIndexDataManager = NULL;
+
+ delete mLineLoopIB;
+ mLineLoopIB = NULL;
+
+ for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+ {
+ delete mNullColorbufferCache[i].buffer;
+ mNullColorbufferCache[i].buffer = NULL;
+ }
+
+}
+
+
+void Renderer9::notifyDeviceLost()
+{
+ mDeviceLost = true;
+ mDisplay->notifyDeviceLost();
+}
+
+bool Renderer9::isDeviceLost()
+{
+ return mDeviceLost;
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer9::testDeviceLost(bool notify)
+{
+ HRESULT status = S_OK;
+
+ if (mDeviceEx)
+ {
+ status = mDeviceEx->CheckDeviceState(NULL);
+
+ if (status == S_PRESENT_MODE_CHANGED)
+ {
+ // Reset the device so that D3D stops reporting S_PRESENT_MODE_CHANGED. Otherwise it will report
+ // it continuously, potentially masking a lost device. D3D resources are not lost on a mode change with WDDM.
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+ mDeviceEx->Reset(&presentParameters);
+
+ // Existing swap chains sometimes crash on the next present after a reset.
+ mDisplay->recreateSwapChains();
+
+ // Reset will not always cause the device loss to be reported so issue a dummy present.
+ mDeviceEx->Present(NULL, NULL, NULL, NULL);
+
+ // Retest the device status to see if the mode change really indicated a lost device.
+ status = mDeviceEx->CheckDeviceState(NULL);
+ }
+ }
+ else if (mDevice)
+ {
+ status = mDevice->TestCooperativeLevel();
+ }
+ else
+ {
+ // No device yet, so no reset required
+ }
+
+ bool isLost = FAILED(status) || d3d9::isDeviceLostError(status);
+
+ if (isLost)
+ {
+ // ensure we note the device loss --
+ // we'll probably get this done again by notifyDeviceLost
+ // but best to remember it!
+ // Note that we don't want to clear the device loss status here
+ // -- this needs to be done by resetDevice
+ mDeviceLost = true;
+ if (notify)
+ {
+ notifyDeviceLost();
+ }
+ }
+
+ return isLost;
+}
+
+bool Renderer9::testDeviceResettable()
+{
+ HRESULT status = D3D_OK;
+
+ if (mDeviceEx)
+ {
+ status = mDeviceEx->CheckDeviceState(NULL);
+ }
+ else if (mDevice)
+ {
+ status = mDevice->TestCooperativeLevel();
+ }
+
+ // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
+ // DEVICEREMOVED indicates the device has been stopped and must be recreated
+ switch (status)
+ {
+ case D3DERR_DEVICENOTRESET:
+ case D3DERR_DEVICEHUNG:
+ return true;
+ case D3DERR_DEVICELOST:
+ return (mDeviceEx != NULL);
+ case D3DERR_DEVICEREMOVED:
+ UNIMPLEMENTED();
+ return false;
+ default:
+ return false;
+ }
+}
+
+bool Renderer9::resetDevice()
+{
+ releaseDeviceResources();
+
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+
+ HRESULT result = D3D_OK;
+ bool lost = testDeviceLost(false);
+ int attempts = 3;
+
+ while (lost && attempts > 0)
+ {
+ if (mDeviceEx)
+ {
+ Sleep(500); // Give the graphics driver some CPU time
+ result = mDeviceEx->ResetEx(&presentParameters, NULL);
+ }
+ else
+ {
+ result = mDevice->TestCooperativeLevel();
+ while (result == D3DERR_DEVICELOST)
+ {
+ Sleep(100); // Give the graphics driver some CPU time
+ result = mDevice->TestCooperativeLevel();
+ }
+
+ if (result == D3DERR_DEVICENOTRESET)
+ {
+ result = mDevice->Reset(&presentParameters);
+ }
+ }
+
+ lost = testDeviceLost(false);
+ attempts --;
+ }
+
+ if (FAILED(result))
+ {
+ ERR("Reset/ResetEx failed multiple times: 0x%08X", result);
+ return false;
+ }
+
+ // reset device defaults
+ initializeDevice();
+ mDeviceLost = false;
+
+ return true;
+}
+
+DWORD Renderer9::getAdapterVendor() const
+{
+ return mAdapterIdentifier.VendorId;
+}
+
+std::string Renderer9::getRendererDescription() const
+{
+ std::ostringstream rendererString;
+
+ rendererString << mAdapterIdentifier.Description;
+ if (getShareHandleSupport())
+ {
+ rendererString << " Direct3D9Ex";
+ }
+ else
+ {
+ rendererString << " Direct3D9";
+ }
+
+ rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion);
+ rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
+
+ return rendererString.str();
+}
+
+GUID Renderer9::getAdapterIdentifier() const
+{
+ return mAdapterIdentifier.DeviceIdentifier;
+}
+
+void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
+{
+ for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
+ {
+ HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
+ TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+
+ multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
+ }
+}
+
+bool Renderer9::getBGRATextureSupport() const
+{
+ // DirectX 9 always supports BGRA
+ return true;
+}
+
+bool Renderer9::getDXT1TextureSupport()
+{
+ return mDXT1TextureSupport;
+}
+
+bool Renderer9::getDXT3TextureSupport()
+{
+ return mDXT3TextureSupport;
+}
+
+bool Renderer9::getDXT5TextureSupport()
+{
+ return mDXT5TextureSupport;
+}
+
+bool Renderer9::getDepthTextureSupport() const
+{
+ return mDepthTextureSupport;
+}
+
+bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable)
+{
+ *filtering = mFloat32FilterSupport;
+ *renderable = mFloat32RenderSupport;
+ return mFloat32TextureSupport;
+}
+
+bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable)
+{
+ *filtering = mFloat16FilterSupport;
+ *renderable = mFloat16RenderSupport;
+ return mFloat16TextureSupport;
+}
+
+bool Renderer9::getLuminanceTextureSupport()
+{
+ return mLuminanceTextureSupport;
+}
+
+bool Renderer9::getLuminanceAlphaTextureSupport()
+{
+ return mLuminanceAlphaTextureSupport;
+}
+
+bool Renderer9::getTextureFilterAnisotropySupport() const
+{
+ return mSupportsTextureFilterAnisotropy;
+}
+
+float Renderer9::getTextureMaxAnisotropy() const
+{
+ if (mSupportsTextureFilterAnisotropy)
+ {
+ return static_cast<float>(mDeviceCaps.MaxAnisotropy);
+ }
+ return 1.0f;
+}
+
+bool Renderer9::getEventQuerySupport()
+{
+ return mEventQuerySupport;
+}
+
+unsigned int Renderer9::getMaxVertexTextureImageUnits() const
+{
+ META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0;
+}
+
+unsigned int Renderer9::getMaxCombinedTextureImageUnits() const
+{
+ return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
+}
+
+unsigned int Renderer9::getReservedVertexUniformVectors() const
+{
+ return 2; // dx_ViewAdjust and dx_DepthRange.
+}
+
+unsigned int Renderer9::getReservedFragmentUniformVectors() const
+{
+ return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
+}
+
+unsigned int Renderer9::getMaxVertexUniformVectors() const
+{
+ return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors();
+}
+
+unsigned int Renderer9::getMaxFragmentUniformVectors() const
+{
+ const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2;
+
+ return maxPixelConstantVectors - getReservedFragmentUniformVectors();
+}
+
+unsigned int Renderer9::getMaxVaryingVectors() const
+{
+ return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
+}
+
+bool Renderer9::getNonPower2TextureSupport() const
+{
+ return mSupportsNonPower2Textures;
+}
+
+bool Renderer9::getOcclusionQuerySupport() const
+{
+ return mOcclusionQuerySupport;
+}
+
+bool Renderer9::getInstancingSupport() const
+{
+ return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0);
+}
+
+bool Renderer9::getShareHandleSupport() const
+{
+ // PIX doesn't seem to support using share handles, so disable them.
+ return (mD3d9Ex != NULL) && !gl::perfActive();
+}
+
+bool Renderer9::getDerivativeInstructionSupport() const
+{
+ return (mDeviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
+}
+
+bool Renderer9::getPostSubBufferSupport() const
+{
+ return true;
+}
+
+int Renderer9::getMajorShaderModel() const
+{
+ return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
+}
+
+float Renderer9::getMaxPointSize() const
+{
+ // Point size clamped at 1.0f for SM2
+ return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f;
+}
+
+int Renderer9::getMaxViewportDimension() const
+{
+ int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()),
+ (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
+ return maxTextureDimension;
+}
+
+int Renderer9::getMaxTextureWidth() const
+{
+ return (int)mDeviceCaps.MaxTextureWidth;
+}
+
+int Renderer9::getMaxTextureHeight() const
+{
+ return (int)mDeviceCaps.MaxTextureHeight;
+}
+
+bool Renderer9::get32BitIndexSupport() const
+{
+ return mDeviceCaps.MaxVertexIndex >= (1 << 16);
+}
+
+DWORD Renderer9::getCapsDeclTypes() const
+{
+ return mDeviceCaps.DeclTypes;
+}
+
+int Renderer9::getMinSwapInterval() const
+{
+ return mMinSwapInterval;
+}
+
+int Renderer9::getMaxSwapInterval() const
+{
+ return mMaxSwapInterval;
+}
+
+int Renderer9::getMaxSupportedSamples() const
+{
+ return mMaxSupportedSamples;
+}
+
+int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+{
+ if (requested == 0)
+ {
+ return requested;
+ }
+
+ std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
+ if (itr == mMultiSampleSupport.end())
+ {
+ if (format == D3DFMT_UNKNOWN)
+ return 0;
+ return -1;
+ }
+
+ for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
+ {
+ if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+unsigned int Renderer9::getMaxRenderTargets() const
+{
+ // we do not support MRT in d3d9
+ return 1;
+}
+
+D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLint internalformat)
+{
+ switch (internalformat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH_COMPONENT32_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return D3DFMT_INTZ;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return D3DFMT_DXT1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ return D3DFMT_DXT3;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ return D3DFMT_DXT5;
+ case GL_RGBA32F_EXT:
+ case GL_RGB32F_EXT:
+ case GL_ALPHA32F_EXT:
+ case GL_LUMINANCE32F_EXT:
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return D3DFMT_A32B32G32R32F;
+ case GL_RGBA16F_EXT:
+ case GL_RGB16F_EXT:
+ case GL_ALPHA16F_EXT:
+ case GL_LUMINANCE16F_EXT:
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ return D3DFMT_A16B16G16R16F;
+ case GL_LUMINANCE8_EXT:
+ if (getLuminanceTextureSupport())
+ {
+ return D3DFMT_L8;
+ }
+ break;
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ if (getLuminanceAlphaTextureSupport())
+ {
+ return D3DFMT_A8L8;
+ }
+ break;
+ case GL_RGB8_OES:
+ case GL_RGB565:
+ return D3DFMT_X8R8G8B8;
+ }
+
+ return D3DFMT_A8R8G8B8;
+}
+
+bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+{
+ bool result = false;
+
+ if (source && dest)
+ {
+ TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance());
+ TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance());
+
+ int levels = source9->levelCount();
+ for (int i = 0; i < levels; ++i)
+ {
+ IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false);
+ IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false);
+
+ result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
+
+ if (srcSurf) srcSurf->Release();
+ if (dstSurf) dstSurf->Release();
+
+ if (!result)
+ return false;
+ }
+ }
+
+ return result;
+}
+
+bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+{
+ bool result = false;
+
+ if (source && dest)
+ {
+ TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance());
+ TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance());
+ int levels = source9->levelCount();
+ for (int f = 0; f < 6; f++)
+ {
+ for (int i = 0; i < levels; i++)
+ {
+ IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
+ IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
+
+ result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged());
+
+ if (srcSurf) srcSurf->Release();
+ if (dstSurf) dstSurf->Release();
+
+ if (!result)
+ return false;
+ }
+ }
+ }
+
+ return result;
+}
+
+D3DPOOL Renderer9::getBufferPool(DWORD usage) const
+{
+ if (mD3d9Ex != NULL)
+ {
+ return D3DPOOL_DEFAULT;
+ }
+ else
+ {
+ if (!(usage & D3DUSAGE_DYNAMIC))
+ {
+ return D3DPOOL_MANAGED;
+ }
+ }
+
+ return D3DPOOL_DEFAULT;
+}
+
+bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+ RECT rect;
+ rect.left = sourceRect.x;
+ rect.top = sourceRect.y;
+ rect.right = sourceRect.x + sourceRect.width;
+ rect.bottom = sourceRect.y + sourceRect.height;
+
+ return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
+}
+
+bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+ RECT rect;
+ rect.left = sourceRect.x;
+ rect.top = sourceRect.y;
+ rect.right = sourceRect.x + sourceRect.width;
+ rect.bottom = sourceRect.y + sourceRect.height;
+
+ return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
+}
+
+bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect,
+ bool blitRenderTarget, bool blitDepthStencil)
+{
+ endScene();
+
+ if (blitRenderTarget)
+ {
+ gl::Renderbuffer *readBuffer = readFramebuffer->getColorbuffer(0);
+ gl::Renderbuffer *drawBuffer = drawFramebuffer->getColorbuffer(0);
+ RenderTarget9 *readRenderTarget = NULL;
+ RenderTarget9 *drawRenderTarget = NULL;
+ IDirect3DSurface9* readSurface = NULL;
+ IDirect3DSurface9* drawSurface = NULL;
+
+ if (readBuffer)
+ {
+ readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget());
+ }
+ if (drawBuffer)
+ {
+ drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget());
+ }
+
+ if (readRenderTarget)
+ {
+ readSurface = readRenderTarget->getSurface();
+ }
+ if (drawRenderTarget)
+ {
+ drawSurface = drawRenderTarget->getSurface();
+ }
+
+ if (!readSurface || !drawSurface)
+ {
+ ERR("Failed to retrieve the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ RECT srcRect;
+ srcRect.left = readRect.x;
+ srcRect.right = readRect.x + readRect.width;
+ srcRect.top = readRect.y;
+ srcRect.bottom = readRect.y + readRect.height;
+
+ RECT dstRect;
+ dstRect.left = drawRect.x;
+ dstRect.right = drawRect.x + drawRect.width;
+ dstRect.top = drawRect.y;
+ dstRect.bottom = drawRect.y + drawRect.height;
+
+ HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE);
+
+ readSurface->Release();
+ drawSurface->Release();
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return false;
+ }
+ }
+
+ if (blitDepthStencil)
+ {
+ gl::Renderbuffer *readBuffer = readFramebuffer->getDepthOrStencilbuffer();
+ gl::Renderbuffer *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer();
+ RenderTarget9 *readDepthStencil = NULL;
+ RenderTarget9 *drawDepthStencil = NULL;
+ IDirect3DSurface9* readSurface = NULL;
+ IDirect3DSurface9* drawSurface = NULL;
+
+ if (readBuffer)
+ {
+ readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil());
+ }
+ if (drawBuffer)
+ {
+ drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil());
+ }
+
+ if (readDepthStencil)
+ {
+ readSurface = readDepthStencil->getSurface();
+ }
+ if (drawDepthStencil)
+ {
+ drawSurface = drawDepthStencil->getSurface();
+ }
+
+ if (!readSurface || !drawSurface)
+ {
+ ERR("Failed to retrieve the render target.");
+ return gl::error(GL_OUT_OF_MEMORY, false);
+ }
+
+ HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
+
+ readSurface->Release();
+ drawSurface->Release();
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
+{
+ RenderTarget9 *renderTarget = NULL;
+ IDirect3DSurface9 *surface = NULL;
+ gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
+
+ if (colorbuffer)
+ {
+ renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget());
+ }
+
+ if (renderTarget)
+ {
+ surface = renderTarget->getSurface();
+ }
+
+ if (!surface)
+ {
+ // context must be lost
+ return;
+ }
+
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
+ {
+ UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+ HRESULT result;
+ IDirect3DSurface9 *systemSurface = NULL;
+ bool directToPixels = !packReverseRowOrder && packAlignment <= 4 && getShareHandleSupport() &&
+ x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height &&
+ desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE;
+ if (directToPixels)
+ {
+ // Use the pixels ptr as a shared handle to write directly into client's memory
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &systemSurface, &pixels);
+ if (FAILED(result))
+ {
+ // Try again without the shared handle
+ directToPixels = false;
+ }
+ }
+
+ if (!directToPixels)
+ {
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+ D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ surface->Release();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ result = mDevice->GetRenderTargetData(surface, systemSurface);
+ surface->Release();
+ surface = NULL;
+
+ if (FAILED(result))
+ {
+ systemSurface->Release();
+
+ // It turns out that D3D will sometimes produce more error
+ // codes than those documented.
+ if (d3d9::isDeviceLostError(result))
+ {
+ notifyDeviceLost();
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+ else
+ {
+ UNREACHABLE();
+ return;
+ }
+
+ }
+
+ if (directToPixels)
+ {
+ systemSurface->Release();
+ return;
+ }
+
+ RECT rect;
+ rect.left = gl::clamp(x, 0L, static_cast<LONG>(desc.Width));
+ rect.top = gl::clamp(y, 0L, static_cast<LONG>(desc.Height));
+ rect.right = gl::clamp(x + width, 0L, static_cast<LONG>(desc.Width));
+ rect.bottom = gl::clamp(y + height, 0L, static_cast<LONG>(desc.Height));
+
+ D3DLOCKED_RECT lock;
+ result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY);
+
+ if (FAILED(result))
+ {
+ UNREACHABLE();
+ systemSurface->Release();
+
+ return; // No sensible error to generate
+ }
+
+ unsigned char *dest = (unsigned char*)pixels;
+ unsigned short *dest16 = (unsigned short*)pixels;
+
+ unsigned char *source;
+ int inputPitch;
+ if (packReverseRowOrder)
+ {
+ source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
+ inputPitch = -lock.Pitch;
+ }
+ else
+ {
+ source = (unsigned char*)lock.pBits;
+ inputPitch = lock.Pitch;
+ }
+
+ unsigned int fastPixelSize = 0;
+
+ if (desc.Format == D3DFMT_A8R8G8B8 &&
+ format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_BYTE)
+ {
+ fastPixelSize = 4;
+ }
+ else if ((desc.Format == D3DFMT_A4R4G4B4 &&
+ format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) ||
+ (desc.Format == D3DFMT_A1R5G5B5 &&
+ format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT))
+ {
+ fastPixelSize = 2;
+ }
+ else if (desc.Format == D3DFMT_A16B16G16R16F &&
+ format == GL_RGBA &&
+ type == GL_HALF_FLOAT_OES)
+ {
+ fastPixelSize = 8;
+ }
+ else if (desc.Format == D3DFMT_A32B32G32R32F &&
+ format == GL_RGBA &&
+ type == GL_FLOAT)
+ {
+ fastPixelSize = 16;
+ }
+
+ for (int j = 0; j < rect.bottom - rect.top; j++)
+ {
+ if (fastPixelSize != 0)
+ {
+ // Fast path for formats which require no translation:
+ // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE
+ // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT
+ // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT
+ // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES
+ // D3DFMT_A32B32G32R32F to RGBA/FLOAT
+ //
+ // Note that buffers with no alpha go through the slow path below.
+ memcpy(dest + j * outputPitch,
+ source + j * inputPitch,
+ (rect.right - rect.left) * fastPixelSize);
+ continue;
+ }
+ else if (desc.Format == D3DFMT_A8R8G8B8 &&
+ format == GL_RGBA &&
+ type == GL_UNSIGNED_BYTE)
+ {
+ // Fast path for swapping red with blue
+ for (int i = 0; i < rect.right - rect.left; i++)
+ {
+ unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+ *(unsigned int*)(dest + 4 * i + j * outputPitch) =
+ (argb & 0xFF00FF00) | // Keep alpha and green
+ (argb & 0x00FF0000) >> 16 | // Move red to blue
+ (argb & 0x000000FF) << 16; // Move blue to red
+ }
+ continue;
+ }
+
+ for (int i = 0; i < rect.right - rect.left; i++)
+ {
+ float r;
+ float g;
+ float b;
+ float a;
+
+ switch (desc.Format)
+ {
+ case D3DFMT_R5G6B5:
+ {
+ unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+ a = 1.0f;
+ b = (rgb & 0x001F) * (1.0f / 0x001F);
+ g = (rgb & 0x07E0) * (1.0f / 0x07E0);
+ r = (rgb & 0xF800) * (1.0f / 0xF800);
+ }
+ break;
+ case D3DFMT_A1R5G5B5:
+ {
+ unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+ a = (argb & 0x8000) ? 1.0f : 0.0f;
+ b = (argb & 0x001F) * (1.0f / 0x001F);
+ g = (argb & 0x03E0) * (1.0f / 0x03E0);
+ r = (argb & 0x7C00) * (1.0f / 0x7C00);
+ }
+ break;
+ case D3DFMT_A8R8G8B8:
+ {
+ unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+ a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
+ b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
+ g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
+ r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
+ }
+ break;
+ case D3DFMT_X8R8G8B8:
+ {
+ unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+ a = 1.0f;
+ b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
+ g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
+ r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
+ }
+ break;
+ case D3DFMT_A2R10G10B10:
+ {
+ unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+ a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
+ b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
+ g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
+ r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
+ }
+ break;
+ case D3DFMT_A32B32G32R32F:
+ {
+ // float formats in D3D are stored rgba, rather than the other way round
+ r = *((float*)(source + 16 * i + j * inputPitch) + 0);
+ g = *((float*)(source + 16 * i + j * inputPitch) + 1);
+ b = *((float*)(source + 16 * i + j * inputPitch) + 2);
+ a = *((float*)(source + 16 * i + j * inputPitch) + 3);
+ }
+ break;
+ case D3DFMT_A16B16G16R16F:
+ {
+ // float formats in D3D are stored rgba, rather than the other way round
+ r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0));
+ g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1));
+ b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2));
+ a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3));
+ }
+ break;
+ default:
+ UNIMPLEMENTED(); // FIXME
+ UNREACHABLE();
+ return;
+ }
+
+ switch (format)
+ {
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
+ dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+ dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
+ dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+ dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+ dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+ dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)(15 * a + 0.5f) << 12)|
+ ((unsigned short)(15 * r + 0.5f) << 8) |
+ ((unsigned short)(15 * g + 0.5f) << 4) |
+ ((unsigned short)(15 * b + 0.5f) << 0);
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)( a + 0.5f) << 15) |
+ ((unsigned short)(31 * r + 0.5f) << 10) |
+ ((unsigned short)(31 * g + 0.5f) << 5) |
+ ((unsigned short)(31 * b + 0.5f) << 0);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_UNSIGNED_SHORT_5_6_5:
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)(31 * b + 0.5f) << 0) |
+ ((unsigned short)(63 * g + 0.5f) << 5) |
+ ((unsigned short)(31 * r + 0.5f) << 11);
+ break;
+ case GL_UNSIGNED_BYTE:
+ dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
+ dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+ dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
+ default: UNREACHABLE();
+ }
+ }
+ }
+
+ systemSurface->UnlockRect();
+
+ systemSurface->Release();
+}
+
+RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
+{
+ SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
+ IDirect3DSurface9 *surface = NULL;
+ if (depth)
+ {
+ surface = swapChain9->getDepthStencil();
+ }
+ else
+ {
+ surface = swapChain9->getRenderTarget();
+ }
+
+ RenderTarget9 *renderTarget = new RenderTarget9(this, surface);
+
+ return renderTarget;
+}
+
+RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
+{
+ RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples);
+ return renderTarget;
+}
+
+ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type)
+{
+ ShaderExecutable9 *executable = NULL;
+
+ switch (type)
+ {
+ case rx::SHADER_VERTEX:
+ {
+ IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length);
+ if (vshader)
+ {
+ executable = new ShaderExecutable9(function, length, vshader);
+ }
+ }
+ break;
+ case rx::SHADER_PIXEL:
+ {
+ IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length);
+ if (pshader)
+ {
+ executable = new ShaderExecutable9(function, length, pshader);
+ }
+ }
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ return executable;
+}
+
+ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type)
+{
+ const char *profile = NULL;
+
+ switch (type)
+ {
+ case rx::SHADER_VERTEX:
+ profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0";
+ break;
+ case rx::SHADER_PIXEL:
+ profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0";
+ break;
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+
+ ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, ANGLE_COMPILE_OPTIMIZATION_LEVEL, true);
+ if (!binary)
+ return NULL;
+
+ ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type);
+ binary->Release();
+
+ return executable;
+}
+
+bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+{
+ return mBlit->boxFilter(source, dest);
+}
+
+D3DPOOL Renderer9::getTexturePool(DWORD usage) const
+{
+ if (mD3d9Ex != NULL)
+ {
+ return D3DPOOL_DEFAULT;
+ }
+ else
+ {
+ if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
+ {
+ return D3DPOOL_MANAGED;
+ }
+ }
+
+ return D3DPOOL_DEFAULT;
+}
+
+bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
+{
+ if (source && dest)
+ {
+ HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+
+ if (fromManaged)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
+
+ IDirect3DSurface9 *surf = 0;
+ result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+
+ if (SUCCEEDED(result))
+ {
+ Image9::copyLockableSurfaces(surf, source);
+ result = mDevice->UpdateSurface(surf, NULL, dest, NULL);
+ surf->Release();
+ }
+ }
+ else
+ {
+ endScene();
+ result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
+ }
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Image *Renderer9::createImage()
+{
+ return new Image9();
+}
+
+void Renderer9::generateMipmap(Image *dest, Image *src)
+{
+ Image9 *src9 = Image9::makeImage9(src);
+ Image9 *dst9 = Image9::makeImage9(dest);
+ Image9::generateMipmap(dst9, src9);
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
+{
+ SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
+ return new TextureStorage9_2D(this, swapChain9);
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+{
+ return new TextureStorage9_2D(this, levels, internalformat, usage, forceRenderable, width, height);
+}
+
+TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+{
+ return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size);
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h
new file mode 100644
index 0000000000..527a5010ae
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h
@@ -0,0 +1,347 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer9.h: Defines a back-end specific class for the D3D9 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER9_H_
+#define LIBGLESV2_RENDERER_RENDERER9_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/mathutil.h"
+#include "libGLESv2/renderer/ShaderCache.h"
+#include "libGLESv2/renderer/VertexDeclarationCache.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/renderer/RenderTarget.h"
+
+namespace gl
+{
+class Renderbuffer;
+}
+
+namespace rx
+{
+class VertexDataManager;
+class IndexDataManager;
+class StreamingIndexBufferInterface;
+struct TranslatedAttribute;
+
+class Renderer9 : public Renderer
+{
+ public:
+ Renderer9(egl::Display *display, HDC hDc, bool softwareDevice);
+ virtual ~Renderer9();
+
+ static Renderer9 *makeRenderer9(Renderer *renderer);
+
+ virtual EGLint initialize();
+ virtual bool resetDevice();
+
+ virtual int generateConfigs(ConfigDesc **configDescList);
+ virtual void deleteConfigs(ConfigDesc *configDescList);
+
+ void startScene();
+ void endScene();
+
+ virtual void sync(bool block);
+
+ virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+ IDirect3DQuery9* allocateEventQuery();
+ void freeEventQuery(IDirect3DQuery9* query);
+
+ // resource creation
+ IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length);
+ IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
+ HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
+ HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
+#if 0
+ void *createTexture2D();
+ void *createTextureCube();
+ void *createQuery();
+ void *createIndexBuffer();
+ void *createVertexbuffer();
+
+ // state setup
+ void applyShaders();
+ void applyConstants();
+#endif
+ virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler);
+ virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+
+ virtual void setRasterizerState(const gl::RasterizerState &rasterState);
+ virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor,
+ unsigned int sampleMask);
+ virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef,
+ int stencilBackRef, bool frontFaceCCW);
+
+ virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled);
+ virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+ bool ignoreViewport);
+
+ virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
+ virtual void applyShaders(gl::ProgramBinary *programBinary);
+ virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
+ virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
+ virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+ virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+
+ virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+ virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances);
+
+ virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer);
+
+ virtual void markAllStateDirty();
+
+ // lost device
+ void notifyDeviceLost();
+ virtual bool isDeviceLost();
+ virtual bool testDeviceLost(bool notify);
+ virtual bool testDeviceResettable();
+
+ // Renderer capabilities
+ IDirect3DDevice9 *getDevice() { return mDevice; }
+ virtual DWORD getAdapterVendor() const;
+ virtual std::string getRendererDescription() const;
+ virtual GUID getAdapterIdentifier() const;
+
+ virtual bool getBGRATextureSupport() const;
+ virtual bool getDXT1TextureSupport();
+ virtual bool getDXT3TextureSupport();
+ virtual bool getDXT5TextureSupport();
+ virtual bool getEventQuerySupport();
+ virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
+ virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
+ virtual bool getLuminanceTextureSupport();
+ virtual bool getLuminanceAlphaTextureSupport();
+ virtual unsigned int getMaxVertexTextureImageUnits() const;
+ virtual unsigned int getMaxCombinedTextureImageUnits() const;
+ virtual unsigned int getReservedVertexUniformVectors() const;
+ virtual unsigned int getReservedFragmentUniformVectors() const;
+ virtual unsigned int getMaxVertexUniformVectors() const;
+ virtual unsigned int getMaxFragmentUniformVectors() const;
+ virtual unsigned int getMaxVaryingVectors() const;
+ virtual bool getNonPower2TextureSupport() const;
+ virtual bool getDepthTextureSupport() const;
+ virtual bool getOcclusionQuerySupport() const;
+ virtual bool getInstancingSupport() const;
+ virtual bool getTextureFilterAnisotropySupport() const;
+ virtual float getTextureMaxAnisotropy() const;
+ virtual bool getShareHandleSupport() const;
+ virtual bool getDerivativeInstructionSupport() const;
+ virtual bool getPostSubBufferSupport() const;
+
+ virtual int getMajorShaderModel() const;
+ virtual float getMaxPointSize() const;
+ virtual int getMaxViewportDimension() const;
+ virtual int getMaxTextureWidth() const;
+ virtual int getMaxTextureHeight() const;
+ virtual bool get32BitIndexSupport() const;
+ DWORD getCapsDeclTypes() const;
+ virtual int getMinSwapInterval() const;
+ virtual int getMaxSwapInterval() const;
+
+ virtual GLsizei getMaxSupportedSamples() const;
+ int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
+
+ virtual unsigned int getMaxRenderTargets() const;
+
+ D3DFORMAT ConvertTextureInternalFormat(GLint internalformat);
+
+ // Pixel operations
+ virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
+ virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
+
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+ virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat,
+ GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+
+ virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect,
+ bool blitRenderTarget, bool blitDepthStencil);
+ virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
+
+ // RenderTarget creation
+ virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
+ virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
+
+ // Shader operations
+ virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
+ virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type);
+
+ // Image operations
+ virtual Image *createImage();
+ virtual void generateMipmap(Image *dest, Image *source);
+ virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
+ virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+
+ // Buffer creation
+ virtual VertexBuffer *createVertexBuffer();
+ virtual IndexBuffer *createIndexBuffer();
+ virtual BufferStorage *createBufferStorage();
+
+ // Query and Fence creation
+ virtual QueryImpl *createQuery(GLenum type);
+ virtual FenceImpl *createFence();
+
+ // D3D9-renderer specific methods
+ bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+
+ D3DPOOL getTexturePool(DWORD usage) const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Renderer9);
+
+ void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v);
+ void applyUniformniv(gl::Uniform *targetUniform, const GLint *v);
+ void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v);
+
+ void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+ void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer);
+
+ void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
+ bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+ gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer);
+
+ D3DPOOL getBufferPool(DWORD usage) const;
+
+ HMODULE mD3d9Module;
+ HDC mDc;
+
+ void initializeDevice();
+ D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+ void releaseDeviceResources();
+
+ UINT mAdapter;
+ D3DDEVTYPE mDeviceType;
+ bool mSoftwareDevice; // FIXME: Deprecate
+ IDirect3D9 *mD3d9; // Always valid after successful initialization.
+ IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported.
+ IDirect3DDevice9 *mDevice;
+ IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported.
+
+ Blit *mBlit;
+
+ HWND mDeviceWindow;
+
+ bool mDeviceLost;
+ D3DCAPS9 mDeviceCaps;
+ D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
+
+ D3DPRIMITIVETYPE mPrimitiveType;
+ int mPrimitiveCount;
+ GLsizei mRepeatDraw;
+
+ bool mSceneStarted;
+ bool mSupportsNonPower2Textures;
+ bool mSupportsTextureFilterAnisotropy;
+ int mMinSwapInterval;
+ int mMaxSwapInterval;
+
+ bool mOcclusionQuerySupport;
+ bool mEventQuerySupport;
+ bool mVertexTextureSupport;
+
+ bool mDepthTextureSupport;
+
+ bool mFloat32TextureSupport;
+ bool mFloat32FilterSupport;
+ bool mFloat32RenderSupport;
+
+ bool mFloat16TextureSupport;
+ bool mFloat16FilterSupport;
+ bool mFloat16RenderSupport;
+
+ bool mDXT1TextureSupport;
+ bool mDXT3TextureSupport;
+ bool mDXT5TextureSupport;
+
+ bool mLuminanceTextureSupport;
+ bool mLuminanceAlphaTextureSupport;
+
+ std::map<D3DFORMAT, bool *> mMultiSampleSupport;
+ GLsizei mMaxSupportedSamples;
+
+ // current render target states
+ unsigned int mAppliedRenderTargetSerial;
+ unsigned int mAppliedDepthbufferSerial;
+ unsigned int mAppliedStencilbufferSerial;
+ bool mDepthStencilInitialized;
+ bool mRenderTargetDescInitialized;
+ rx::RenderTarget::Desc mRenderTargetDesc;
+ unsigned int mCurStencilSize;
+ unsigned int mCurDepthSize;
+
+ IDirect3DStateBlock9 *mMaskedClearSavedState;
+
+ // previously set render states
+ bool mForceSetDepthStencilState;
+ gl::DepthStencilState mCurDepthStencilState;
+ int mCurStencilRef;
+ int mCurStencilBackRef;
+ bool mCurFrontFaceCCW;
+
+ bool mForceSetRasterState;
+ gl::RasterizerState mCurRasterState;
+
+ bool mForceSetScissor;
+ gl::Rectangle mCurScissor;
+ bool mScissorEnabled;
+
+ bool mForceSetViewport;
+ gl::Rectangle mCurViewport;
+ float mCurNear;
+ float mCurFar;
+
+ bool mForceSetBlendState;
+ gl::BlendState mCurBlendState;
+ gl::Color mCurBlendColor;
+ GLuint mCurSampleMask;
+
+ // Currently applied sampler states
+ bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+ gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+ bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+ gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+ // Currently applied textures
+ unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+ unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+ unsigned int mAppliedIBSerial;
+ unsigned int mAppliedProgramBinarySerial;
+
+ rx::dx_VertexConstants mVertexConstants;
+ rx::dx_PixelConstants mPixelConstants;
+ bool mDxUniformsDirty;
+
+ // A pool of event queries that are currently unused.
+ std::vector<IDirect3DQuery9*> mEventQueryPool;
+ VertexShaderCache mVertexShaderCache;
+ PixelShaderCache mPixelShaderCache;
+
+ VertexDataManager *mVertexDataManager;
+ VertexDeclarationCache mVertexDeclarationCache;
+
+ IndexDataManager *mIndexDataManager;
+ StreamingIndexBufferInterface *mLineLoopIB;
+
+ enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 };
+ struct NullColorbufferCacheEntry
+ {
+ UINT lruCount;
+ int width;
+ int height;
+ gl::Renderbuffer *buffer;
+ } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES];
+ UINT mMaxNullColorbufferLRU;
+
+};
+
+}
+#endif // LIBGLESV2_RENDERER_RENDERER9_H_
diff --git a/src/3rdparty/angle/src/libEGL/ShaderCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderCache.h
index cfe523ba09..4391ac271a 100644
--- a/src/3rdparty/angle/src/libEGL/ShaderCache.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderCache.h
@@ -4,21 +4,15 @@
// found in the LICENSE file.
//
-// Display.h: Defines egl::ShaderCache, a cache of Direct3D shader objects
+// ShaderCache: Defines rx::ShaderCache, a cache of Direct3D shader objects
// keyed by their byte code.
-#ifndef LIBEGL_SHADER_CACHE_H_
-#define LIBEGL_SHADER_CACHE_H_
+#ifndef LIBGLESV2_RENDERER_SHADER_CACHE_H_
+#define LIBGLESV2_RENDERER_SHADER_CACHE_H_
-#include <d3d9.h>
+#include "common/debug.h"
-#ifdef _MSC_VER
-#include <hash_map>
-#else
-#include <unordered_map>
-#endif
-
-namespace egl
+namespace rx
{
template <typename ShaderObject>
class ShaderCache
@@ -48,7 +42,7 @@ class ShaderCache
it->second->AddRef();
return it->second;
}
-
+
ShaderObject *shader;
HRESULT result = createShader(function, &shader);
if (FAILED(result))
@@ -113,4 +107,4 @@ typedef ShaderCache<IDirect3DPixelShader9> PixelShaderCache;
}
-#endif // LIBEGL_SHADER_CACHE_H_
+#endif // LIBGLESV2_RENDERER_SHADER_CACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
new file mode 100644
index 0000000000..128d123fbe
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable.h
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable.h: Defines a renderer-agnostic class to contain shader
+// executable implementation details.
+
+#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
+#define LIBGLESV2_RENDERER_SHADEREXECUTABLE_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class ShaderExecutable
+{
+ public:
+ ShaderExecutable(const void *function, size_t length) : mLength(length)
+ {
+ mFunction = new char[length];
+ memcpy(mFunction, function, length);
+ }
+
+ virtual ~ShaderExecutable()
+ {
+ delete mFunction;
+ }
+
+ void *getFunction() const
+ {
+ return mFunction;
+ }
+
+ size_t getLength() const
+ {
+ return mLength;
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ShaderExecutable);
+
+ void *mFunction;
+ const size_t mLength;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp
new file mode 100644
index 0000000000..e1eb560334
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp
@@ -0,0 +1,109 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader
+// executable implementation details.
+
+#include "libGLESv2/renderer/ShaderExecutable11.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable)
+ : ShaderExecutable(function, length)
+{
+ mPixelExecutable = executable;
+ mVertexExecutable = NULL;
+ mGeometryExecutable = NULL;
+
+ mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable)
+ : ShaderExecutable(function, length)
+{
+ mVertexExecutable = executable;
+ mPixelExecutable = NULL;
+ mGeometryExecutable = NULL;
+
+ mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable)
+ : ShaderExecutable(function, length)
+{
+ mGeometryExecutable = executable;
+ mVertexExecutable = NULL;
+ mPixelExecutable = NULL;
+
+ mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::~ShaderExecutable11()
+{
+ if (mVertexExecutable)
+ {
+ mVertexExecutable->Release();
+ }
+ if (mPixelExecutable)
+ {
+ mPixelExecutable->Release();
+ }
+ if (mGeometryExecutable)
+ {
+ mGeometryExecutable->Release();
+ }
+
+ if (mConstantBuffer)
+ {
+ mConstantBuffer->Release();
+ }
+}
+
+ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable));
+ return static_cast<ShaderExecutable11*>(executable);
+}
+
+ID3D11VertexShader *ShaderExecutable11::getVertexShader() const
+{
+ return mVertexExecutable;
+}
+
+ID3D11PixelShader *ShaderExecutable11::getPixelShader() const
+{
+ return mPixelExecutable;
+}
+
+ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const
+{
+ return mGeometryExecutable;
+}
+
+ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount)
+{
+ if (!mConstantBuffer && registerCount > 0)
+ {
+ D3D11_BUFFER_DESC constantBufferDescription = {0};
+ constantBufferDescription.ByteWidth = registerCount * sizeof(float[4]);
+ constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
+ constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+ constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ constantBufferDescription.MiscFlags = 0;
+ constantBufferDescription.StructureByteStride = 0;
+
+ HRESULT result = device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer);
+ ASSERT(SUCCEEDED(result));
+ }
+
+ return mConstantBuffer;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h
new file mode 100644
index 0000000000..c6ec1cf7d2
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h
@@ -0,0 +1,47 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+#define LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+
+#include "libGLESv2/renderer/ShaderExecutable.h"
+
+namespace rx
+{
+
+class ShaderExecutable11 : public ShaderExecutable
+{
+ public:
+ ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable);
+ ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable);
+ ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable);
+
+ virtual ~ShaderExecutable11();
+
+ static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutable *executable);
+
+ ID3D11PixelShader *getPixelShader() const;
+ ID3D11VertexShader *getVertexShader() const;
+ ID3D11GeometryShader *getGeometryShader() const;
+
+ ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11);
+
+ ID3D11PixelShader *mPixelExecutable;
+ ID3D11VertexShader *mVertexExecutable;
+ ID3D11GeometryShader *mGeometryExecutable;
+
+ ID3D11Buffer *mConstantBuffer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp
new file mode 100644
index 0000000000..98868a3fbf
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp
@@ -0,0 +1,60 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader
+// executable implementation details.
+
+#include "libGLESv2/renderer/ShaderExecutable9.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+
+ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable)
+ : ShaderExecutable(function, length)
+{
+ mPixelExecutable = executable;
+ mVertexExecutable = NULL;
+}
+
+ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable)
+ : ShaderExecutable(function, length)
+{
+ mVertexExecutable = executable;
+ mPixelExecutable = NULL;
+}
+
+ShaderExecutable9::~ShaderExecutable9()
+{
+ if (mVertexExecutable)
+ {
+ mVertexExecutable->Release();
+ }
+ if (mPixelExecutable)
+ {
+ mPixelExecutable->Release();
+ }
+}
+
+ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable));
+ return static_cast<ShaderExecutable9*>(executable);
+}
+
+IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const
+{
+ return mVertexExecutable;
+}
+
+IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const
+{
+ return mPixelExecutable;
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h
new file mode 100644
index 0000000000..fa1e6c2844
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h
@@ -0,0 +1,39 @@
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+#define LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+
+#include "libGLESv2/renderer/ShaderExecutable.h"
+
+namespace rx
+{
+
+class ShaderExecutable9 : public ShaderExecutable
+{
+ public:
+ ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable);
+ ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable);
+ virtual ~ShaderExecutable9();
+
+ static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutable *executable);
+
+ IDirect3DPixelShader9 *getPixelShader() const;
+ IDirect3DVertexShader9 *getVertexShader() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ShaderExecutable9);
+
+ IDirect3DPixelShader9 *mPixelExecutable;
+ IDirect3DVertexShader9 *mVertexExecutable;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
new file mode 100644
index 0000000000..14c0515fc8
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h
@@ -0,0 +1,44 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain.h: Defines a back-end specific class that hides the details of the
+// implementation-specific swapchain.
+
+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN_H_
+#define LIBGLESV2_RENDERER_SWAPCHAIN_H_
+
+#include "common/angleutils.h"
+
+namespace rx
+{
+
+class SwapChain
+{
+ public:
+ SwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mWindow(window), mShareHandle(shareHandle), mBackBufferFormat(backBufferFormat), mDepthBufferFormat(depthBufferFormat)
+ {
+ }
+
+ virtual ~SwapChain() {};
+
+ virtual EGLint resize(EGLint backbufferWidth, EGLint backbufferSize) = 0;
+ virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval) = 0;
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height) = 0;
+ virtual void recreate() = 0;
+
+ virtual HANDLE getShareHandle() {return mShareHandle;};
+
+ protected:
+ const HWND mWindow; // Window that the surface is created for.
+ const GLenum mBackBufferFormat;
+ const GLenum mDepthBufferFormat;
+
+ HANDLE mShareHandle;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_SWAPCHAIN_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
new file mode 100644
index 0000000000..98f887587c
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
@@ -0,0 +1,770 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
+
+#include "libGLESv2/renderer/SwapChain11.h"
+
+#include "libGLESv2/renderer/renderer11_utils.h"
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h"
+#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h"
+
+namespace rx
+{
+
+SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+{
+ mSwapChain = NULL;
+ mBackBufferTexture = NULL;
+ mBackBufferRTView = NULL;
+ mOffscreenTexture = NULL;
+ mOffscreenRTView = NULL;
+ mOffscreenSRView = NULL;
+ mDepthStencilTexture = NULL;
+ mDepthStencilDSView = NULL;
+ mQuadVB = NULL;
+ mPassThroughSampler = NULL;
+ mPassThroughIL = NULL;
+ mPassThroughVS = NULL;
+ mPassThroughPS = NULL;
+ mWidth = -1;
+ mHeight = -1;
+ mSwapInterval = 0;
+ mAppCreatedShareHandle = mShareHandle != NULL;
+ mPassThroughResourcesInit = false;
+}
+
+SwapChain11::~SwapChain11()
+{
+ release();
+}
+
+void SwapChain11::release()
+{
+ if (mSwapChain)
+ {
+ mSwapChain->Release();
+ mSwapChain = NULL;
+ }
+
+ if (mBackBufferTexture)
+ {
+ mBackBufferTexture->Release();
+ mBackBufferTexture = NULL;
+ }
+
+ if (mBackBufferRTView)
+ {
+ mBackBufferRTView->Release();
+ mBackBufferRTView = NULL;
+ }
+
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->Release();
+ mOffscreenTexture = NULL;
+ }
+
+ if (mOffscreenRTView)
+ {
+ mOffscreenRTView->Release();
+ mOffscreenRTView = NULL;
+ }
+
+ if (mOffscreenSRView)
+ {
+ mOffscreenSRView->Release();
+ mOffscreenSRView = NULL;
+ }
+
+ if (mDepthStencilTexture)
+ {
+ mDepthStencilTexture->Release();
+ mDepthStencilTexture = NULL;
+ }
+
+ if (mDepthStencilDSView)
+ {
+ mDepthStencilDSView->Release();
+ mDepthStencilDSView = NULL;
+ }
+
+ if (mQuadVB)
+ {
+ mQuadVB->Release();
+ mQuadVB = NULL;
+ }
+
+ if (mPassThroughSampler)
+ {
+ mPassThroughSampler->Release();
+ mPassThroughSampler = NULL;
+ }
+
+ if (mPassThroughIL)
+ {
+ mPassThroughIL->Release();
+ mPassThroughIL = NULL;
+ }
+
+ if (mPassThroughVS)
+ {
+ mPassThroughVS->Release();
+ mPassThroughVS = NULL;
+ }
+
+ if (mPassThroughPS)
+ {
+ mPassThroughPS->Release();
+ mPassThroughPS = NULL;
+ }
+
+ if (!mAppCreatedShareHandle)
+ {
+ mShareHandle = NULL;
+ }
+}
+
+void SwapChain11::releaseOffscreenTexture()
+{
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->Release();
+ mOffscreenTexture = NULL;
+ }
+
+ if (mOffscreenRTView)
+ {
+ mOffscreenRTView->Release();
+ mOffscreenRTView = NULL;
+ }
+
+ if (mOffscreenSRView)
+ {
+ mOffscreenSRView->Release();
+ mOffscreenSRView = NULL;
+ }
+
+ if (mDepthStencilTexture)
+ {
+ mDepthStencilTexture->Release();
+ mDepthStencilTexture = NULL;
+ }
+
+ if (mDepthStencilDSView)
+ {
+ mDepthStencilDSView->Release();
+ mDepthStencilDSView = NULL;
+ }
+}
+
+EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
+{
+ ID3D11Device *device = mRenderer->getDevice();
+
+ ASSERT(device != NULL);
+
+ // D3D11 does not allow zero size textures
+ ASSERT(backbufferWidth >= 1);
+ ASSERT(backbufferHeight >= 1);
+
+ // Preserve the render target content
+ ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
+ if (previousOffscreenTexture)
+ {
+ previousOffscreenTexture->AddRef();
+ }
+ const int previousWidth = mWidth;
+ const int previousHeight = mHeight;
+
+ releaseOffscreenTexture();
+
+ // If the app passed in a share handle, open the resource
+ // See EGL_ANGLE_d3d_share_handle_client_buffer
+ if (mAppCreatedShareHandle)
+ {
+ ID3D11Resource *tempResource11;
+ HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11);
+
+ if (FAILED(result))
+ {
+ ERR("Failed to open the swap chain pbuffer share handle: %08lX", result);
+ release();
+ return EGL_BAD_PARAMETER;
+ }
+
+ result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture);
+ tempResource11->Release();
+
+ if (FAILED(result))
+ {
+ ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result);
+ release();
+ return EGL_BAD_PARAMETER;
+ }
+
+ // Validate offscreen texture parameters
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+ mOffscreenTexture->GetDesc(&offscreenTextureDesc);
+
+ if (offscreenTextureDesc.Width != (UINT)backbufferWidth
+ || offscreenTextureDesc.Height != (UINT)backbufferHeight
+ || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
+ || offscreenTextureDesc.MipLevels != 1
+ || offscreenTextureDesc.ArraySize != 1)
+ {
+ ERR("Invalid texture parameters in the shared offscreen texture pbuffer");
+ release();
+ return EGL_BAD_PARAMETER;
+ }
+ }
+ else
+ {
+ const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport();
+
+ D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+ offscreenTextureDesc.Width = backbufferWidth;
+ offscreenTextureDesc.Height = backbufferHeight;
+ offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ offscreenTextureDesc.MipLevels = 1;
+ offscreenTextureDesc.ArraySize = 1;
+ offscreenTextureDesc.SampleDesc.Count = 1;
+ offscreenTextureDesc.SampleDesc.Quality = 0;
+ offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+ offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+ offscreenTextureDesc.CPUAccessFlags = 0;
+ offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
+
+ HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture);
+
+ if (FAILED(result))
+ {
+ ERR("Could not create offscreen texture: %08lX", result);
+ release();
+
+ if (d3d11::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture");
+
+ // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
+ if (useSharedResource)
+ {
+ IDXGIResource *offscreenTextureResource = NULL;
+ result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource);
+
+ // Fall back to no share handle on failure
+ if (FAILED(result))
+ {
+ ERR("Could not query offscreen texture resource: %08lX", result);
+ }
+ else
+ {
+ result = offscreenTextureResource->GetSharedHandle(&mShareHandle);
+
+ if (FAILED(result))
+ {
+ mShareHandle = NULL;
+ ERR("Could not get offscreen texture shared handle: %08lX", result);
+ }
+ }
+ }
+ }
+
+ HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView);
+
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target");
+
+ result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource");
+
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
+ depthStencilDesc.Width = backbufferWidth;
+ depthStencilDesc.Height = backbufferHeight;
+ depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
+ depthStencilDesc.MipLevels = 1;
+ depthStencilDesc.ArraySize = 1;
+ depthStencilDesc.SampleDesc.Count = 1;
+ depthStencilDesc.SampleDesc.Quality = 0;
+ depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
+ depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ depthStencilDesc.CPUAccessFlags = 0;
+ depthStencilDesc.MiscFlags = 0;
+
+ result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture);
+ if (FAILED(result))
+ {
+ ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
+ release();
+
+ if (d3d11::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+ d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture");
+
+ result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view");
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+
+ if (previousOffscreenTexture != NULL)
+ {
+ D3D11_BOX sourceBox = {0};
+ sourceBox.left = 0;
+ sourceBox.right = std::min(previousWidth, mWidth);
+ sourceBox.top = std::max(previousHeight - mHeight, 0);
+ sourceBox.bottom = previousHeight;
+ sourceBox.front = 0;
+ sourceBox.back = 1;
+
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+ const int yoffset = std::max(mHeight - previousHeight, 0);
+ deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox);
+
+ previousOffscreenTexture->Release();
+
+ if (mSwapChain)
+ {
+ swapRect(0, 0, mWidth, mHeight);
+ }
+ }
+
+ return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+{
+ ID3D11Device *device = mRenderer->getDevice();
+
+ if (device == NULL)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ if (!mSwapChain)
+ reset(backbufferWidth, backbufferHeight, mSwapInterval);
+
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+
+ if (mBackBufferTexture)
+ {
+ mBackBufferTexture->Release();
+ mBackBufferTexture = NULL;
+ }
+
+ if (mBackBufferRTView)
+ {
+ mBackBufferRTView->Release();
+ mBackBufferRTView = NULL;
+ }
+
+ // Resize swap chain
+ DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0);
+
+ if (FAILED(result))
+ {
+ ERR("Error resizing swap chain buffers: 0x%08X", result);
+ release();
+
+ if (d3d11::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
+ }
+
+ result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
+ ASSERT(SUCCEEDED(result));
+ if (SUCCEEDED(result))
+ {
+ d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
+ }
+
+ return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+}
+
+EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+{
+ ID3D11Device *device = mRenderer->getDevice();
+
+ if (device == NULL)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ // Release specific resources to free up memory for the new render target, while the
+ // old render target still exists for the purpose of preserving its contents.
+ if (mSwapChain)
+ {
+ mSwapChain->Release();
+ mSwapChain = NULL;
+ }
+
+ if (mBackBufferTexture)
+ {
+ mBackBufferTexture->Release();
+ mBackBufferTexture = NULL;
+ }
+
+ if (mBackBufferRTView)
+ {
+ mBackBufferRTView->Release();
+ mBackBufferRTView = NULL;
+ }
+
+ mSwapInterval = static_cast<unsigned int>(swapInterval);
+ if (mSwapInterval > 4)
+ {
+ // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
+ return EGL_BAD_PARAMETER;
+ }
+
+ // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+ if (backbufferWidth < 1 || backbufferHeight < 1)
+ {
+ releaseOffscreenTexture();
+ return EGL_SUCCESS;
+ }
+
+ if (mWindow)
+ {
+ // We cannot create a swap chain for an HWND that is owned by a different process
+ DWORD currentProcessId = GetCurrentProcessId();
+ DWORD wndProcessId;
+ GetWindowThreadProcessId(mWindow, &wndProcessId);
+
+ if (currentProcessId != wndProcessId)
+ {
+ ERR("Could not create swap chain, window owned by different process");
+ release();
+ return EGL_BAD_NATIVE_WINDOW;
+ }
+
+ IDXGIFactory *factory = mRenderer->getDxgiFactory();
+
+ DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
+ swapChainDesc.BufferCount = 2;
+ swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+ swapChainDesc.BufferDesc.Width = backbufferWidth;
+ swapChainDesc.BufferDesc.Height = backbufferHeight;
+ 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;
+ swapChainDesc.Flags = 0;
+ swapChainDesc.OutputWindow = mWindow;
+ swapChainDesc.SampleDesc.Count = 1;
+ swapChainDesc.SampleDesc.Quality = 0;
+ swapChainDesc.Windowed = TRUE;
+
+ HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain);
+
+ if (FAILED(result))
+ {
+ ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
+ release();
+
+ if (d3d11::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture");
+
+ result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target");
+ }
+
+ // If we are resizing the swap chain, we don't wish to recreate all the static resources
+ if (!mPassThroughResourcesInit)
+ {
+ mPassThroughResourcesInit = true;
+ initPassThroughResources();
+ }
+
+ return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+}
+
+void SwapChain11::initPassThroughResources()
+{
+ ID3D11Device *device = mRenderer->getDevice();
+
+ ASSERT(device != NULL);
+
+ // Make sure our resources are all not allocated, when we create
+ ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL);
+ ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL);
+
+ D3D11_BUFFER_DESC vbDesc;
+ vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+ vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+ vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ vbDesc.MiscFlags = 0;
+ vbDesc.StructureByteStride = 0;
+
+ HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer");
+
+ D3D11_SAMPLER_DESC samplerDesc;
+ samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+ samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+ samplerDesc.MipLODBias = 0.0f;
+ samplerDesc.MaxAnisotropy = 0;
+ samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+ samplerDesc.BorderColor[0] = 0.0f;
+ samplerDesc.BorderColor[1] = 0.0f;
+ samplerDesc.BorderColor[2] = 0.0f;
+ samplerDesc.BorderColor[3] = 0.0f;
+ samplerDesc.MinLOD = 0;
+ samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+
+ result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler");
+
+ D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout");
+
+ result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader");
+
+ result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS);
+ ASSERT(SUCCEEDED(result));
+ d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader");
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ ID3D11Device *device = mRenderer->getDevice();
+ ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
+
+ // Set vertices
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ d3d11::PositionTexCoordVertex *vertices = static_cast<d3d11::PositionTexCoordVertex*>(mappedResource.pData);
+
+ // Create a quad in homogeneous coordinates
+ float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+ float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+ float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
+ float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
+
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+ float v2 = (y + height) / float(mHeight);
+
+ d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2);
+ d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1);
+ d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2);
+
+ deviceContext->Unmap(mQuadVB, 0);
+
+ static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+ static UINT startIdx = 0;
+ deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx);
+
+ // Apply state
+ deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+
+ static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+ deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
+
+ deviceContext->RSSetState(NULL);
+
+ // Apply shaders
+ deviceContext->IASetInputLayout(mPassThroughIL);
+ deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ deviceContext->VSSetShader(mPassThroughVS, NULL, 0);
+ deviceContext->PSSetShader(mPassThroughPS, NULL, 0);
+ deviceContext->GSSetShader(NULL, NULL, 0);
+
+ // Apply render targets
+ mRenderer->setOneTimeRenderTarget(mBackBufferRTView);
+
+ // Set the viewport
+ D3D11_VIEWPORT viewport;
+ viewport.TopLeftX = 0;
+ viewport.TopLeftY = 0;
+ viewport.Width = mWidth;
+ viewport.Height = mHeight;
+ viewport.MinDepth = 0.0f;
+ viewport.MaxDepth = 1.0f;
+ deviceContext->RSSetViewports(1, &viewport);
+
+ // Apply textures
+ deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView);
+ deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler);
+
+ // Draw
+ deviceContext->Draw(4, 0);
+ result = mSwapChain->Present(mSwapInterval, 0);
+
+ if (result == DXGI_ERROR_DEVICE_REMOVED)
+ {
+ HRESULT removedReason = device->GetDeviceRemovedReason();
+ ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason);
+ return EGL_CONTEXT_LOST;
+ }
+ else if (result == DXGI_ERROR_DEVICE_RESET)
+ {
+ ERR("Present failed: the D3D11 device was reset from a bad command.");
+ return EGL_CONTEXT_LOST;
+ }
+ else if (FAILED(result))
+ {
+ ERR("Present failed with error code 0x%08X", result);
+ }
+
+ // Unbind
+ static ID3D11ShaderResourceView *const nullSRV = NULL;
+ deviceContext->PSSetShaderResources(0, 1, &nullSRV);
+
+ mRenderer->unapplyRenderTargets();
+ mRenderer->markAllStateDirty();
+
+ return EGL_SUCCESS;
+}
+
+// Increments refcount on texture.
+// caller must Release() the returned texture
+ID3D11Texture2D *SwapChain11::getOffscreenTexture()
+{
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->AddRef();
+ }
+
+ return mOffscreenTexture;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11RenderTargetView *SwapChain11::getRenderTarget()
+{
+ if (mOffscreenRTView)
+ {
+ mOffscreenRTView->AddRef();
+ }
+
+ return mOffscreenRTView;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
+{
+ if (mOffscreenSRView)
+ {
+ mOffscreenSRView->AddRef();
+ }
+
+ return mOffscreenSRView;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11DepthStencilView *SwapChain11::getDepthStencil()
+{
+ if (mDepthStencilDSView)
+ {
+ mDepthStencilDSView->AddRef();
+ }
+
+ return mDepthStencilDSView;
+}
+
+ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
+{
+ if (mDepthStencilTexture)
+ {
+ mDepthStencilTexture->AddRef();
+ }
+
+ return mDepthStencilTexture;
+}
+
+SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
+ return static_cast<rx::SwapChain11*>(swapChain);
+}
+
+void SwapChain11::recreate()
+{
+ // possibly should use this method instead of reset
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
new file mode 100644
index 0000000000..800104602e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h
@@ -0,0 +1,78 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain.
+
+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/renderer/SwapChain.h"
+
+namespace rx
+{
+class Renderer11;
+
+class SwapChain11 : public SwapChain
+{
+ public:
+ SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual ~SwapChain11();
+
+ EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
+ virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+ virtual void recreate();
+
+ virtual ID3D11Texture2D *getOffscreenTexture();
+ virtual ID3D11RenderTargetView *getRenderTarget();
+ virtual ID3D11ShaderResourceView *getRenderTargetShaderResource();
+
+ virtual ID3D11Texture2D *getDepthStencilTexture();
+ virtual ID3D11DepthStencilView *getDepthStencil();
+
+ EGLint getWidth() const { return mWidth; }
+ EGLint getHeight() const { return mHeight; }
+
+ static SwapChain11 *makeSwapChain11(SwapChain *swapChain);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SwapChain11);
+
+ void release();
+ void initPassThroughResources();
+ void releaseOffscreenTexture();
+ EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight);
+
+ Renderer11 *mRenderer;
+ EGLint mHeight;
+ EGLint mWidth;
+ bool mAppCreatedShareHandle;
+ unsigned int mSwapInterval;
+ bool mPassThroughResourcesInit;
+
+ IDXGISwapChain *mSwapChain;
+
+ ID3D11Texture2D *mBackBufferTexture;
+ ID3D11RenderTargetView *mBackBufferRTView;
+
+ ID3D11Texture2D *mOffscreenTexture;
+ ID3D11RenderTargetView *mOffscreenRTView;
+ ID3D11ShaderResourceView *mOffscreenSRView;
+
+ ID3D11Texture2D *mDepthStencilTexture;
+ ID3D11DepthStencilView *mDepthStencilDSView;
+
+ ID3D11Buffer *mQuadVB;
+ ID3D11SamplerState *mPassThroughSampler;
+ ID3D11InputLayout *mPassThroughIL;
+ ID3D11VertexShader *mPassThroughVS;
+ ID3D11PixelShader *mPassThroughPS;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp
new file mode 100644
index 0000000000..f57a874688
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp
@@ -0,0 +1,449 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
+
+#include "libGLESv2/renderer/SwapChain9.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+namespace rx
+{
+
+SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat)
+ : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+{
+ mSwapChain = NULL;
+ mBackBuffer = NULL;
+ mDepthStencil = NULL;
+ mRenderTarget = NULL;
+ mOffscreenTexture = NULL;
+ mWidth = -1;
+ mHeight = -1;
+ mSwapInterval = -1;
+}
+
+SwapChain9::~SwapChain9()
+{
+ release();
+}
+
+void SwapChain9::release()
+{
+ if (mSwapChain)
+ {
+ mSwapChain->Release();
+ mSwapChain = NULL;
+ }
+
+ if (mBackBuffer)
+ {
+ mBackBuffer->Release();
+ mBackBuffer = NULL;
+ }
+
+ if (mDepthStencil)
+ {
+ mDepthStencil->Release();
+ mDepthStencil = NULL;
+ }
+
+ if (mRenderTarget)
+ {
+ mRenderTarget->Release();
+ mRenderTarget = NULL;
+ }
+
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->Release();
+ mOffscreenTexture = NULL;
+ }
+
+ if (mWindow)
+ mShareHandle = NULL;
+}
+
+static DWORD convertInterval(EGLint interval)
+{
+ switch(interval)
+ {
+ case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
+ case 1: return D3DPRESENT_INTERVAL_ONE;
+ case 2: return D3DPRESENT_INTERVAL_TWO;
+ case 3: return D3DPRESENT_INTERVAL_THREE;
+ case 4: return D3DPRESENT_INTERVAL_FOUR;
+ default: UNREACHABLE();
+ }
+
+ return D3DPRESENT_INTERVAL_DEFAULT;
+}
+
+EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight)
+{
+ // D3D9 does not support resizing swap chains without recreating them
+ return reset(backbufferWidth, backbufferHeight, mSwapInterval);
+}
+
+EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+{
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ if (device == NULL)
+ {
+ return EGL_BAD_ACCESS;
+ }
+
+ // Evict all non-render target textures to system memory and release all resources
+ // before reallocating them to free up as much video memory as possible.
+ device->EvictManagedResources();
+
+ HRESULT result;
+
+ // Release specific resources to free up memory for the new render target, while the
+ // old render target still exists for the purpose of preserving its contents.
+ if (mSwapChain)
+ {
+ mSwapChain->Release();
+ mSwapChain = NULL;
+ }
+
+ if (mBackBuffer)
+ {
+ mBackBuffer->Release();
+ mBackBuffer = NULL;
+ }
+
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->Release();
+ mOffscreenTexture = NULL;
+ }
+
+ if (mDepthStencil)
+ {
+ mDepthStencil->Release();
+ mDepthStencil = NULL;
+ }
+
+ HANDLE *pShareHandle = NULL;
+ if (!mWindow && mRenderer->getShareHandleSupport())
+ {
+ pShareHandle = &mShareHandle;
+ }
+
+ // CreateTexture will fail on zero dimensions, so just release old target
+ if (!backbufferWidth || !backbufferHeight)
+ {
+ if (mRenderTarget)
+ {
+ mRenderTarget->Release();
+ mRenderTarget = NULL;
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+
+ return EGL_SUCCESS;
+ }
+
+ result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
+ gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT,
+ &mOffscreenTexture, pShareHandle);
+ if (FAILED(result))
+ {
+ ERR("Could not create offscreen texture: %08lX", result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
+
+ result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget);
+ ASSERT(SUCCEEDED(result));
+
+ if (oldRenderTarget)
+ {
+ RECT rect =
+ {
+ 0, 0,
+ mWidth, mHeight
+ };
+
+ if (rect.right > static_cast<LONG>(backbufferWidth))
+ {
+ rect.right = backbufferWidth;
+ }
+
+ if (rect.bottom > static_cast<LONG>(backbufferHeight))
+ {
+ rect.bottom = backbufferHeight;
+ }
+
+ mRenderer->endScene();
+
+ result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE);
+ ASSERT(SUCCEEDED(result));
+
+ oldRenderTarget->Release();
+ }
+
+ if (mWindow)
+ {
+ D3DPRESENT_PARAMETERS presentParameters = {0};
+ presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat);
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat);
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = mWindow;
+ presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.PresentationInterval = convertInterval(swapInterval);
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+ presentParameters.BackBufferWidth = backbufferWidth;
+ presentParameters.BackBufferHeight = backbufferHeight;
+
+ // http://crbug.com/140239
+ // http://crbug.com/143434
+ //
+ // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
+ // when using the integrated Intel. This rounds the width up rather than down.
+ //
+ // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
+ // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
+ if (mRenderer->getAdapterVendor() == VENDOR_ID_INTEL)
+ {
+ presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
+ }
+
+ result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
+
+ ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+
+ result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
+ ASSERT(SUCCEEDED(result));
+ InvalidateRect(mWindow, NULL, FALSE);
+ }
+
+ if (mDepthBufferFormat != GL_NONE)
+ {
+ result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
+ gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat),
+ D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
+
+ ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result);
+ release();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+ else
+ {
+ return EGL_BAD_ALLOC;
+ }
+ }
+ }
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
+ mSwapInterval = swapInterval;
+
+ return EGL_SUCCESS;
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+ if (!mSwapChain)
+ {
+ return EGL_SUCCESS;
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+
+ // Disable all pipeline operations
+ device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+ device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+ device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+ device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ device->SetRenderState(D3DRS_STENCILENABLE, FALSE);
+ device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+ device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
+ device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+ device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+ device->SetPixelShader(NULL);
+ device->SetVertexShader(NULL);
+
+ device->SetRenderTarget(0, mBackBuffer);
+ device->SetDepthStencilSurface(NULL);
+
+ device->SetTexture(0, mOffscreenTexture);
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+ device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
+
+ D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
+ device->SetViewport(&viewport);
+
+ float x1 = x - 0.5f;
+ float y1 = (mHeight - y - height) - 0.5f;
+ float x2 = (x + width) - 0.5f;
+ float y2 = (mHeight - y) - 0.5f;
+
+ float u1 = x / float(mWidth);
+ float v1 = y / float(mHeight);
+ float u2 = (x + width) / float(mWidth);
+ float v2 = (y + height) / float(mHeight);
+
+ float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
+ {x2, y1, 0.0f, 1.0f, u2, v2},
+ {x2, y2, 0.0f, 1.0f, u2, v1},
+ {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v
+
+ mRenderer->startScene();
+ device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
+ mRenderer->endScene();
+
+ device->SetTexture(0, NULL);
+
+ RECT rect =
+ {
+ x, mHeight - y - height,
+ x + width, mHeight - y
+ };
+
+ HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0);
+
+ mRenderer->markAllStateDirty();
+
+ if (d3d9::isDeviceLostError(result))
+ {
+ return EGL_CONTEXT_LOST;
+ }
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
+ {
+ return EGL_BAD_ALLOC;
+ }
+
+ ASSERT(SUCCEEDED(result));
+
+ return EGL_SUCCESS;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *SwapChain9::getRenderTarget()
+{
+ if (mRenderTarget)
+ {
+ mRenderTarget->AddRef();
+ }
+
+ return mRenderTarget;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *SwapChain9::getDepthStencil()
+{
+ if (mDepthStencil)
+ {
+ mDepthStencil->AddRef();
+ }
+
+ return mDepthStencil;
+}
+
+// Increments refcount on texture.
+// caller must Release() the returned texture
+IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
+{
+ if (mOffscreenTexture)
+ {
+ mOffscreenTexture->AddRef();
+ }
+
+ return mOffscreenTexture;
+}
+
+SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain));
+ return static_cast<rx::SwapChain9*>(swapChain);
+}
+
+void SwapChain9::recreate()
+{
+ if (!mSwapChain)
+ {
+ return;
+ }
+
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ if (device == NULL)
+ {
+ return;
+ }
+
+ D3DPRESENT_PARAMETERS presentParameters;
+ HRESULT result = mSwapChain->GetPresentParameters(&presentParameters);
+ ASSERT(SUCCEEDED(result));
+
+ IDirect3DSwapChain9* newSwapChain = NULL;
+ result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain);
+ if (FAILED(result))
+ {
+ return;
+ }
+
+ mSwapChain->Release();
+ mSwapChain = newSwapChain;
+
+ mBackBuffer->Release();
+ result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
+ ASSERT(SUCCEEDED(result));
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h
new file mode 100644
index 0000000000..16a62bd86f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h
@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain.
+
+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+#define LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+
+#include "common/angleutils.h"
+#include "libGLESv2/renderer/SwapChain.h"
+
+namespace rx
+{
+class Renderer9;
+
+class SwapChain9 : public SwapChain
+{
+ public:
+ SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+ GLenum backBufferFormat, GLenum depthBufferFormat);
+ virtual ~SwapChain9();
+
+ EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
+ virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
+ virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+ virtual void recreate();
+
+ virtual IDirect3DSurface9 *getRenderTarget();
+ virtual IDirect3DSurface9 *getDepthStencil();
+ virtual IDirect3DTexture9 *getOffscreenTexture();
+
+ static SwapChain9 *makeSwapChain9(SwapChain *swapChain);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(SwapChain9);
+
+ void release();
+
+ Renderer9 *mRenderer;
+ EGLint mHeight;
+ EGLint mWidth;
+ EGLint mSwapInterval;
+
+ IDirect3DSwapChain9 *mSwapChain;
+ IDirect3DSurface9 *mBackBuffer;
+ IDirect3DSurface9 *mRenderTarget;
+ IDirect3DSurface9 *mDepthStencil;
+ IDirect3DTexture9* mOffscreenTexture;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_SWAPCHAIN9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.cpp
new file mode 100644
index 0000000000..00b316f1cc
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.cpp
@@ -0,0 +1,122 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage.cpp: Implements the abstract rx::TextureStorageInterface class and its concrete derived
+// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
+// GPU-side texture.
+
+#include "libGLESv2/renderer/TextureStorage.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/Texture.h"
+
+#include "common/debug.h"
+
+namespace rx
+{
+unsigned int TextureStorageInterface::mCurrentTextureSerial = 1;
+
+TextureStorageInterface::TextureStorageInterface()
+ : mTextureSerial(issueTextureSerial()),
+ mInstance(NULL)
+{
+}
+
+TextureStorageInterface::~TextureStorageInterface()
+{
+ delete mInstance;
+}
+
+bool TextureStorageInterface::isRenderTarget() const
+{
+ return mInstance->isRenderTarget();
+}
+
+
+bool TextureStorageInterface::isManaged() const
+{
+ return mInstance->isManaged();
+}
+
+unsigned int TextureStorageInterface::getTextureSerial() const
+{
+ return mTextureSerial;
+}
+
+unsigned int TextureStorageInterface::issueTextureSerial()
+{
+ return mCurrentTextureSerial++;
+}
+
+int TextureStorageInterface::getLodOffset() const
+{
+ return mInstance->getLodOffset();
+}
+
+
+int TextureStorageInterface::levelCount()
+{
+ return mInstance->levelCount();
+}
+
+TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain)
+ : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+{
+ mInstance = renderer->createTextureStorage2D(swapchain);
+}
+
+TextureStorageInterface2D::TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+ : mRenderTargetSerial(gl::RenderbufferStorage::issueSerial())
+{
+ mInstance = renderer->createTextureStorage2D(levels, internalformat, usage, forceRenderable, width, height);
+}
+
+TextureStorageInterface2D::~TextureStorageInterface2D()
+{
+}
+
+RenderTarget *TextureStorageInterface2D::getRenderTarget() const
+{
+ return mInstance->getRenderTarget();
+}
+
+void TextureStorageInterface2D::generateMipmap(int level)
+{
+ mInstance->generateMipmap(level);
+}
+
+unsigned int TextureStorageInterface2D::getRenderTargetSerial(GLenum target) const
+{
+ return mRenderTargetSerial;
+}
+
+TextureStorageInterfaceCube::TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+ : mFirstRenderTargetSerial(gl::RenderbufferStorage::issueCubeSerials())
+{
+ mInstance = renderer->createTextureStorageCube(levels, internalformat, usage, forceRenderable, size);
+}
+
+TextureStorageInterfaceCube::~TextureStorageInterfaceCube()
+{
+}
+
+RenderTarget *TextureStorageInterfaceCube::getRenderTarget(GLenum faceTarget) const
+{
+ return mInstance->getRenderTarget(faceTarget);
+}
+
+void TextureStorageInterfaceCube::generateMipmap(int face, int level)
+{
+ mInstance->generateMipmap(face, level);
+}
+
+unsigned int TextureStorageInterfaceCube::getRenderTargetSerial(GLenum target) const
+{
+ return mFirstRenderTargetSerial + gl::TextureCubeMap::faceIndex(target);
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.h
new file mode 100644
index 0000000000..edddb75f3f
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage.h
@@ -0,0 +1,110 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage.h: Defines the abstract rx::TextureStorageInterface class and its concrete derived
+// classes TextureStorageInterface2D and TextureStorageInterfaceCube, which act as the interface to the
+// GPU-side texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+
+#include "common/debug.h"
+
+namespace rx
+{
+class Renderer;
+class SwapChain;
+class RenderTarget;
+class Blit;
+
+class TextureStorage
+{
+ public:
+ TextureStorage() {};
+ virtual ~TextureStorage() {};
+
+ virtual int getLodOffset() const = 0;
+ virtual bool isRenderTarget() const = 0;
+ virtual bool isManaged() const = 0;
+ virtual int levelCount() = 0;
+
+ virtual RenderTarget *getRenderTarget() = 0;
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) = 0;
+ virtual void generateMipmap(int level) = 0;
+ virtual void generateMipmap(int face, int level) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage);
+
+};
+
+class TextureStorageInterface
+{
+ public:
+ TextureStorageInterface();
+ virtual ~TextureStorageInterface();
+
+ TextureStorage *getStorageInstance() { return mInstance; }
+
+ unsigned int getTextureSerial() const;
+ virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
+
+ virtual int getLodOffset() const;
+ virtual bool isRenderTarget() const;
+ virtual bool isManaged() const;
+ virtual int levelCount();
+
+ protected:
+ TextureStorage *mInstance;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface);
+
+ const unsigned int mTextureSerial;
+ static unsigned int issueTextureSerial();
+
+ static unsigned int mCurrentTextureSerial;
+};
+
+class TextureStorageInterface2D : public TextureStorageInterface
+{
+ public:
+ TextureStorageInterface2D(Renderer *renderer, SwapChain *swapchain);
+ TextureStorageInterface2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual ~TextureStorageInterface2D();
+
+ void generateMipmap(int level);
+ RenderTarget *getRenderTarget() const;
+
+ virtual unsigned int getRenderTargetSerial(GLenum target) const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorageInterface2D);
+
+ const unsigned int mRenderTargetSerial;
+};
+
+class TextureStorageInterfaceCube : public TextureStorageInterface
+{
+ public:
+ TextureStorageInterfaceCube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+ virtual ~TextureStorageInterfaceCube();
+
+ void generateMipmap(int face, int level);
+ RenderTarget *getRenderTarget(GLenum faceTarget) const;
+
+ virtual unsigned int getRenderTargetSerial(GLenum target) const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorageInterfaceCube);
+
+ const unsigned int mFirstRenderTargetSerial;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE_H_
+
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
new file mode 100644
index 0000000000..667dbff175
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp
@@ -0,0 +1,676 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
+
+#include "libGLESv2/renderer/TextureStorage11.h"
+
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/renderer/RenderTarget11.h"
+#include "libGLESv2/renderer/SwapChain11.h"
+#include "libGLESv2/renderer/renderer11_utils.h"
+
+#include "libGLESv2/utilities.h"
+#include "libGLESv2/main.h"
+
+namespace rx
+{
+
+TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
+ : mBindFlags(bindFlags),
+ mLodOffset(0),
+ mMipLevels(0),
+ mTexture(NULL),
+ mTextureFormat(DXGI_FORMAT_UNKNOWN),
+ mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
+ mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
+ mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
+ mSRV(NULL),
+ mTextureWidth(0),
+ mTextureHeight(0)
+{
+ mRenderer = Renderer11::makeRenderer11(renderer);
+}
+
+TextureStorage11::~TextureStorage11()
+{
+}
+
+TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
+ return static_cast<TextureStorage11*>(storage);
+}
+
+DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable)
+{
+ UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
+
+ if (d3d11::IsDepthStencilFormat(format))
+ {
+ bindFlags |= D3D11_BIND_DEPTH_STENCIL;
+ }
+ else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+ {
+ bindFlags |= D3D11_BIND_RENDER_TARGET;
+ }
+ return bindFlags;
+}
+
+bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format)
+{
+ switch(format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_A8_UNORM:
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_R8_UNORM:
+ case DXGI_FORMAT_R8G8_UNORM:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ return true;
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC3_UNORM:
+ return false;
+ default:
+ UNREACHABLE();
+ return false;
+ }
+}
+
+UINT TextureStorage11::getBindFlags() const
+{
+ return mBindFlags;
+}
+
+ID3D11Texture2D *TextureStorage11::getBaseTexture() const
+{
+ return mTexture;
+}
+
+int TextureStorage11::getLodOffset() const
+{
+ return mLodOffset;
+}
+
+bool TextureStorage11::isRenderTarget() const
+{
+ return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
+}
+
+bool TextureStorage11::isManaged() const
+{
+ return false;
+}
+
+int TextureStorage11::levelCount()
+{
+ int levels = 0;
+ if (getBaseTexture())
+ {
+ levels = mMipLevels - getLodOffset();
+ }
+ return levels;
+}
+
+UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex)
+{
+ UINT index = 0;
+ if (getBaseTexture())
+ {
+ index = D3D11CalcSubresource(level, faceIndex, mMipLevels);
+ }
+ return index;
+}
+
+bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource,
+ int level, int face, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height)
+{
+ if (srcTexture)
+ {
+ // Round up the width and height to the nearest multiple of dimension alignment
+ unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat);
+ width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment;
+ height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment;
+
+ D3D11_BOX srcBox;
+ srcBox.left = xoffset;
+ srcBox.top = yoffset;
+ srcBox.right = xoffset + width;
+ srcBox.bottom = yoffset + height;
+ srcBox.front = 0;
+ srcBox.back = 1;
+
+ ID3D11DeviceContext *context = mRenderer->getDeviceContext();
+
+ ASSERT(getBaseTexture());
+ context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face),
+ xoffset, yoffset, 0, srcTexture, sourceSubresource, &srcBox);
+ return true;
+ }
+
+ return false;
+}
+
+void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
+{
+ if (source && dest)
+ {
+ ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView();
+ ID3D11RenderTargetView *destRTV = dest->getRenderTargetView();
+
+ if (sourceSRV && destRTV)
+ {
+ gl::Rectangle sourceArea;
+ sourceArea.x = 0;
+ sourceArea.y = 0;
+ sourceArea.width = source->getWidth();
+ sourceArea.height = source->getHeight();
+
+ gl::Rectangle destArea;
+ destArea.x = 0;
+ destArea.y = 0;
+ destArea.width = dest->getWidth();
+ destArea.height = dest->getHeight();
+
+ mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(),
+ destRTV, destArea, dest->getWidth(), dest->getHeight(),
+ GL_RGBA);
+ }
+
+ if (sourceSRV)
+ {
+ sourceSRV->Release();
+ }
+ if (destRTV)
+ {
+ destRTV->Release();
+ }
+ }
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
+ : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
+{
+ mTexture = swapchain->getOffscreenTexture();
+ mSRV = swapchain->getRenderTargetShaderResource();
+
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mRenderTarget[i] = NULL;
+ }
+
+ D3D11_TEXTURE2D_DESC texDesc;
+ mTexture->GetDesc(&texDesc);
+ mMipLevels = texDesc.MipLevels;
+ mTextureFormat = texDesc.Format;
+ mTextureWidth = texDesc.Width;
+ mTextureHeight = texDesc.Height;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ mSRV->GetDesc(&srvDesc);
+ mShaderResourceFormat = srvDesc.Format;
+
+ ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget();
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ offscreenRTV->GetDesc(&rtvDesc);
+ mRenderTargetFormat = rtvDesc.Format;
+ offscreenRTV->Release();
+
+ mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+{
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ mRenderTarget[i] = NULL;
+ }
+
+ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+ mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
+ mDepthStencilFormat = convertedFormat;
+ mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
+ }
+ else
+ {
+ mTextureFormat = convertedFormat;
+ mShaderResourceFormat = convertedFormat;
+ mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+ mRenderTargetFormat = convertedFormat;
+ }
+
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (width > 0 && height > 0)
+ {
+ // adjust size if needed for compressed textures
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = width; // Compressed texture size constraints?
+ desc.Height = height;
+ desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
+ desc.ArraySize = 1;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = 0;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ // this can happen from windows TDR
+ if (d3d11::isDeviceLostError(result))
+ {
+ mRenderer->notifyDeviceLost();
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ else if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ ERR("Creating image failed.");
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ else
+ {
+ mTexture->GetDesc(&desc);
+ mMipLevels = desc.MipLevels;
+ mTextureWidth = desc.Width;
+ mTextureHeight = desc.Height;
+ }
+ }
+}
+
+TextureStorage11_2D::~TextureStorage11_2D()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ }
+
+ if (mSRV)
+ {
+ mSRV->Release();
+ mSRV = NULL;
+ }
+
+ for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+ {
+ delete mRenderTarget[i];
+ mRenderTarget[i] = NULL;
+ }
+}
+
+TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
+ return static_cast<TextureStorage11_2D*>(storage);
+}
+
+RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
+{
+ if (level >= 0 && level < static_cast<int>(mMipLevels))
+ {
+ if (!mRenderTarget[level])
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MostDetailedMip = level;
+ srvDesc.Texture2D.MipLevels = 1;
+
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+ rtvDesc.Texture2D.MipSlice = level;
+
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ srv->Release();
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+ // also needs to keep a reference to the texture.
+ mTexture->AddRef();
+
+ mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
+ std::max(mTextureWidth >> level, 1U),
+ std::max(mTextureHeight >> level, 1U));
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mDepthStencilFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+ dsvDesc.Texture2D.MipSlice = level;
+ dsvDesc.Flags = 0;
+
+ ID3D11DepthStencilView *dsv;
+ result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ srv->Release();
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+ // also needs to keep a reference to the texture.
+ mTexture->AddRef();
+
+ mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
+ std::max(mTextureWidth >> level, 1U),
+ std::max(mTextureHeight >> level, 1U));
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ return mRenderTarget[level];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ID3D11ShaderResourceView *TextureStorage11_2D::getSRV()
+{
+ if (!mSRV)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+ srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+ srvDesc.Texture2D.MostDetailedMip = 0;
+
+ HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+ }
+
+ return mSRV;
+}
+
+void TextureStorage11_2D::generateMipmap(int level)
+{
+ RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
+ RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
+
+ generateMipmapLayer(source, dest);
+}
+
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+ : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+{
+ for (unsigned int i = 0; i < 6; i++)
+ {
+ for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
+ {
+ mRenderTarget[i][j] = NULL;
+ }
+ }
+
+ DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+ if (d3d11::IsDepthStencilFormat(convertedFormat))
+ {
+ mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+ mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
+ mDepthStencilFormat = convertedFormat;
+ mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
+ }
+ else
+ {
+ mTextureFormat = convertedFormat;
+ mShaderResourceFormat = convertedFormat;
+ mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+ mRenderTargetFormat = convertedFormat;
+ }
+
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (size > 0)
+ {
+ // adjust size if needed for compressed textures
+ int height = size;
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
+
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_TEXTURE2D_DESC desc;
+ desc.Width = size;
+ desc.Height = size;
+ desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0;
+ desc.ArraySize = 6;
+ desc.Format = mTextureFormat;
+ desc.SampleDesc.Count = 1;
+ desc.SampleDesc.Quality = 0;
+ desc.Usage = D3D11_USAGE_DEFAULT;
+ desc.BindFlags = getBindFlags();
+ desc.CPUAccessFlags = 0;
+ desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+ HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == E_OUTOFMEMORY);
+ ERR("Creating image failed.");
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ else
+ {
+ mTexture->GetDesc(&desc);
+ mMipLevels = desc.MipLevels;
+ mTextureWidth = desc.Width;
+ mTextureHeight = desc.Height;
+ }
+ }
+}
+
+TextureStorage11_Cube::~TextureStorage11_Cube()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ mTexture = NULL;
+ }
+
+ if (mSRV)
+ {
+ mSRV->Release();
+ mSRV = NULL;
+ }
+
+ for (unsigned int i = 0; i < 6; i++)
+ {
+ for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
+ {
+ delete mRenderTarget[i][j];
+ mRenderTarget[i][j] = NULL;
+ }
+ }
+}
+
+TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
+ return static_cast<TextureStorage11_Cube*>(storage);
+}
+
+RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level)
+{
+ unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget);
+ if (level >= 0 && level < static_cast<int>(mMipLevels))
+ {
+ if (!mRenderTarget[faceIdx][level])
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+ HRESULT result;
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ srvDesc.Texture2DArray.MostDetailedMip = level;
+ srvDesc.Texture2DArray.MipLevels = 1;
+ srvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+ srvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11ShaderResourceView *srv;
+ result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+ rtvDesc.Format = mRenderTargetFormat;
+ rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+ rtvDesc.Texture2DArray.MipSlice = level;
+ rtvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+ rtvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11RenderTargetView *rtv;
+ result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ srv->Release();
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+ // also needs to keep a reference to the texture.
+ mTexture->AddRef();
+
+ mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
+ std::max(mTextureWidth >> level, 1U),
+ std::max(mTextureHeight >> level, 1U));
+ }
+ else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+ {
+ D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+ dsvDesc.Format = mRenderTargetFormat;
+ dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+ dsvDesc.Texture2DArray.MipSlice = level;
+ dsvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+ dsvDesc.Texture2DArray.ArraySize = 1;
+
+ ID3D11DepthStencilView *dsv;
+ result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ srv->Release();
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<RenderTarget*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+
+ // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+ // also needs to keep a reference to the texture.
+ mTexture->AddRef();
+
+ mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
+ std::max(mTextureWidth >> level, 1U),
+ std::max(mTextureHeight >> level, 1U));
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
+
+ return mRenderTarget[faceIdx][level];
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV()
+{
+ if (!mSRV)
+ {
+ ID3D11Device *device = mRenderer->getDevice();
+
+ D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+ srvDesc.Format = mShaderResourceFormat;
+ srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+ srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+ srvDesc.TextureCube.MostDetailedMip = 0;
+
+ HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV);
+
+ if (result == E_OUTOFMEMORY)
+ {
+ return gl::error(GL_OUT_OF_MEMORY, static_cast<ID3D11ShaderResourceView*>(NULL));
+ }
+ ASSERT(SUCCEEDED(result));
+ }
+
+ return mSRV;
+}
+
+void TextureStorage11_Cube::generateMipmap(int face, int level)
+{
+ RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1));
+ RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level));
+
+ generateMipmapLayer(source, dest);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h
new file mode 100644
index 0000000000..3c5ded05b8
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h
@@ -0,0 +1,120 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+
+#include "libGLESv2/Texture.h"
+#include "libGLESv2/renderer/TextureStorage.h"
+
+namespace rx
+{
+class RenderTarget;
+class RenderTarget11;
+class Renderer;
+class Renderer11;
+class SwapChain11;
+
+class TextureStorage11 : public TextureStorage
+{
+ public:
+ TextureStorage11(Renderer *renderer, UINT bindFlags);
+ virtual ~TextureStorage11();
+
+ static TextureStorage11 *makeTextureStorage11(TextureStorage *storage);
+
+ static DWORD GetTextureBindFlags(DXGI_FORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+ static bool IsTextureFormatRenderable(DXGI_FORMAT format);
+
+ UINT getBindFlags() const;
+
+ virtual ID3D11Texture2D *getBaseTexture() const;
+ virtual ID3D11ShaderResourceView *getSRV() = 0;
+ virtual RenderTarget *getRenderTarget() { return getRenderTarget(0); }
+ virtual RenderTarget *getRenderTarget(int level) { return NULL; }
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return getRenderTarget(faceTarget, 0); }
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level) { return NULL; }
+
+ virtual void generateMipmap(int level) {};
+ virtual void generateMipmap(int face, int level) {};
+
+ virtual int getLodOffset() const;
+ virtual bool isRenderTarget() const;
+ virtual bool isManaged() const;
+ virtual int levelCount();
+ UINT getSubresourceIndex(int level, int faceTarget);
+
+ bool updateSubresourceLevel(ID3D11Texture2D *texture, unsigned int sourceSubresource, int level,
+ int faceTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+ protected:
+ void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest);
+
+ Renderer11 *mRenderer;
+ int mLodOffset;
+ unsigned int mMipLevels;
+
+ ID3D11Texture2D *mTexture;
+ DXGI_FORMAT mTextureFormat;
+ DXGI_FORMAT mShaderResourceFormat;
+ DXGI_FORMAT mRenderTargetFormat;
+ DXGI_FORMAT mDepthStencilFormat;
+ unsigned int mTextureWidth;
+ unsigned int mTextureHeight;
+
+ ID3D11ShaderResourceView *mSRV;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
+
+ const UINT mBindFlags;
+};
+
+class TextureStorage11_2D : public TextureStorage11
+{
+ public:
+ TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain);
+ TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual ~TextureStorage11_2D();
+
+ static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
+
+ virtual ID3D11ShaderResourceView *getSRV();
+ virtual RenderTarget *getRenderTarget(int level);
+
+ virtual void generateMipmap(int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
+
+ RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+class TextureStorage11_Cube : public TextureStorage11
+{
+ public:
+ TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+ virtual ~TextureStorage11_Cube();
+
+ static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
+
+ virtual ID3D11ShaderResourceView *getSRV();
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level);
+
+ virtual void generateMipmap(int face, int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
+
+ RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp
new file mode 100644
index 0000000000..8aa74a7cba
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp
@@ -0,0 +1,328 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#include "libGLESv2/main.h"
+#include "libGLESv2/renderer/Renderer9.h"
+#include "libGLESv2/renderer/TextureStorage9.h"
+#include "libGLESv2/renderer/SwapChain9.h"
+#include "libGLESv2/renderer/RenderTarget9.h"
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/Texture.h"
+
+namespace rx
+{
+TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+ : mLodOffset(0),
+ mRenderer(Renderer9::makeRenderer9(renderer)),
+ mD3DUsage(usage),
+ mD3DPool(mRenderer->getTexturePool(usage))
+{
+}
+
+TextureStorage9::~TextureStorage9()
+{
+}
+
+TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9*, storage));
+ return static_cast<TextureStorage9*>(storage);
+}
+
+DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
+{
+ DWORD d3dusage = 0;
+
+ if (d3dfmt == D3DFMT_INTZ)
+ {
+ d3dusage |= D3DUSAGE_DEPTHSTENCIL;
+ }
+ else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+ {
+ d3dusage |= D3DUSAGE_RENDERTARGET;
+ }
+ return d3dusage;
+}
+
+bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format)
+{
+ if (format == D3DFMT_INTZ)
+ {
+ return true;
+ }
+ switch(format)
+ {
+ case D3DFMT_L8:
+ case D3DFMT_A8L8:
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT5:
+ return false;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ return true;
+ default:
+ UNREACHABLE();
+ }
+
+ return false;
+}
+
+bool TextureStorage9::isRenderTarget() const
+{
+ return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+}
+
+bool TextureStorage9::isManaged() const
+{
+ return (mD3DPool == D3DPOOL_MANAGED);
+}
+
+D3DPOOL TextureStorage9::getPool() const
+{
+ return mD3DPool;
+}
+
+DWORD TextureStorage9::getUsage() const
+{
+ return mD3DUsage;
+}
+
+int TextureStorage9::getLodOffset() const
+{
+ return mLodOffset;
+}
+
+int TextureStorage9::levelCount()
+{
+ return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
+{
+ IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
+ mTexture = surfaceTexture;
+ mRenderTarget = NULL;
+
+ initializeRenderTarget();
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+ : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+ mTexture = NULL;
+ mRenderTarget = NULL;
+ // if the width or height is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (width > 0 && height > 0)
+ {
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset);
+ HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
+ mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ initializeRenderTarget();
+}
+
+TextureStorage9_2D::~TextureStorage9_2D()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ }
+
+ delete mRenderTarget;
+}
+
+TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_2D*, storage));
+ return static_cast<TextureStorage9_2D*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty)
+{
+ IDirect3DSurface9 *surface = NULL;
+
+ if (mTexture)
+ {
+ HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface);
+ ASSERT(SUCCEEDED(result));
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level + mLodOffset != 0 && isManaged() && dirty)
+ {
+ mTexture->AddDirtyRect(NULL);
+ }
+ }
+
+ return surface;
+}
+
+RenderTarget *TextureStorage9_2D::getRenderTarget()
+{
+ return mRenderTarget;
+}
+
+void TextureStorage9_2D::generateMipmap(int level)
+{
+ IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
+ IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+
+ if (upper != NULL && lower != NULL)
+ {
+ mRenderer->boxFilter(upper, lower);
+ }
+
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
+{
+ return mTexture;
+}
+
+void TextureStorage9_2D::initializeRenderTarget()
+{
+ ASSERT(mRenderTarget == NULL);
+
+ if (mTexture != NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+
+ mRenderTarget = new RenderTarget9(mRenderer, surface);
+ }
+}
+
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+ : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+ mTexture = NULL;
+ for (int i = 0; i < 6; ++i)
+ {
+ mRenderTarget[i] = NULL;
+ }
+
+ // if the size is not positive this should be treated as an incomplete texture
+ // we handle that here by skipping the d3d texture creation
+ if (size > 0)
+ {
+ IDirect3DDevice9 *device = mRenderer->getDevice();
+ int height = size;
+ gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset);
+ HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
+ mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ gl::error(GL_OUT_OF_MEMORY);
+ }
+ }
+
+ initializeRenderTarget();
+}
+
+TextureStorage9_Cube::~TextureStorage9_Cube()
+{
+ if (mTexture)
+ {
+ mTexture->Release();
+ }
+
+ for (int i = 0; i < 6; ++i)
+ {
+ delete mRenderTarget[i];
+ }
+}
+
+TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStorage *storage)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_Cube*, storage));
+ return static_cast<TextureStorage9_Cube*>(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+{
+ IDirect3DSurface9 *surface = NULL;
+
+ if (mTexture)
+ {
+ D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+ HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface);
+ ASSERT(SUCCEEDED(result));
+
+ // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+ if (level != 0 && isManaged() && dirty)
+ {
+ mTexture->AddDirtyRect(face, NULL);
+ }
+ }
+
+ return surface;
+}
+
+RenderTarget *TextureStorage9_Cube::getRenderTarget(GLenum faceTarget)
+{
+ return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+}
+
+void TextureStorage9_Cube::generateMipmap(int face, int level)
+{
+ IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
+ IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
+
+ if (upper != NULL && lower != NULL)
+ {
+ mRenderer->boxFilter(upper, lower);
+ }
+
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
+{
+ return mTexture;
+}
+
+void TextureStorage9_Cube::initializeRenderTarget()
+{
+ if (mTexture != NULL && isRenderTarget())
+ {
+ IDirect3DSurface9 *surface = NULL;
+
+ for (int i = 0; i < 6; ++i)
+ {
+ ASSERT(mRenderTarget[i] == NULL);
+
+ surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+
+ mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+ }
+ }
+}
+
+} \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h
new file mode 100644
index 0000000000..86f551a131
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h
@@ -0,0 +1,109 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
+#include "libGLESv2/renderer/TextureStorage.h"
+#include "common/debug.h"
+
+namespace rx
+{
+class Renderer9;
+class SwapChain9;
+class RenderTarget;
+class RenderTarget9;
+class Blit;
+
+class TextureStorage9 : public TextureStorage
+{
+ public:
+ TextureStorage9(Renderer *renderer, DWORD usage);
+ virtual ~TextureStorage9();
+
+ static TextureStorage9 *makeTextureStorage9(TextureStorage *storage);
+
+ static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+ static bool IsTextureFormatRenderable(D3DFORMAT format);
+
+ D3DPOOL getPool() const;
+ DWORD getUsage() const;
+
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
+ virtual RenderTarget *getRenderTarget() { return NULL; }
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return NULL; }
+ virtual void generateMipmap(int level) {};
+ virtual void generateMipmap(int face, int level) {};
+
+ virtual int getLodOffset() const;
+ virtual bool isRenderTarget() const;
+ virtual bool isManaged() const;
+ virtual int levelCount();
+
+ protected:
+ int mLodOffset;
+ Renderer9 *mRenderer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
+
+ const DWORD mD3DUsage;
+ const D3DPOOL mD3DPool;
+};
+
+class TextureStorage9_2D : public TextureStorage9
+{
+ public:
+ TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain);
+ TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+ virtual ~TextureStorage9_2D();
+
+ static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
+
+ IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
+ virtual RenderTarget *getRenderTarget();
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+ virtual void generateMipmap(int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
+
+ void initializeRenderTarget();
+
+ IDirect3DTexture9 *mTexture;
+ RenderTarget9 *mRenderTarget;
+};
+
+class TextureStorage9_Cube : public TextureStorage9
+{
+ public:
+ TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+ virtual ~TextureStorage9_Cube();
+
+ static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
+
+ IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
+ virtual RenderTarget *getRenderTarget(GLenum faceTarget);
+ virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+ virtual void generateMipmap(int face, int level);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
+
+ void initializeRenderTarget();
+
+ IDirect3DCubeTexture9 *mTexture;
+ RenderTarget9 *mRenderTarget[6];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp
new file mode 100644
index 0000000000..16e1486511
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -0,0 +1,229 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
+// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
+
+#include "libGLESv2/renderer/VertexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
+#include "libGLESv2/Context.h"
+
+namespace rx
+{
+
+unsigned int VertexBuffer::mNextSerial = 1;
+
+VertexBuffer::VertexBuffer()
+{
+ updateSerial();
+}
+
+VertexBuffer::~VertexBuffer()
+{
+}
+
+void VertexBuffer::updateSerial()
+{
+ mSerial = mNextSerial++;
+}
+
+unsigned int VertexBuffer::getSerial() const
+{
+ return mSerial;
+}
+
+VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
+{
+ mDynamic = dynamic;
+ mWritePosition = 0;
+ mReservedSpace = 0;
+
+ mVertexBuffer = renderer->createVertexBuffer();
+}
+
+VertexBufferInterface::~VertexBufferInterface()
+{
+ delete mVertexBuffer;
+}
+
+unsigned int VertexBufferInterface::getSerial() const
+{
+ return mVertexBuffer->getSerial();
+}
+
+unsigned int VertexBufferInterface::getBufferSize() const
+{
+ return mVertexBuffer->getBufferSize();
+}
+
+bool VertexBufferInterface::setBufferSize(unsigned int size)
+{
+ if (mVertexBuffer->getBufferSize() == 0)
+ {
+ return mVertexBuffer->initialize(size, mDynamic);
+ }
+ else
+ {
+ return mVertexBuffer->setBufferSize(size);
+ }
+}
+
+unsigned int VertexBufferInterface::getWritePosition() const
+{
+ return mWritePosition;
+}
+
+void VertexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+ mWritePosition = writePosition;
+}
+
+bool VertexBufferInterface::discard()
+{
+ return mVertexBuffer->discard();
+}
+
+int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+{
+ if (!reserveSpace(mReservedSpace))
+ {
+ return -1;
+ }
+ mReservedSpace = 0;
+
+ if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
+ {
+ return -1;
+ }
+
+ int oldWritePos = static_cast<int>(mWritePosition);
+ mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances);
+
+ return oldWritePos;
+}
+
+int VertexBufferInterface::storeRawData(const void* data, unsigned int size)
+{
+ if (!reserveSpace(mReservedSpace))
+ {
+ return -1;
+ }
+ mReservedSpace = 0;
+
+ if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
+ {
+ return -1;
+ }
+
+ int oldWritePos = static_cast<int>(mWritePosition);
+ mWritePosition += size;
+
+ return oldWritePos;
+}
+
+void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
+{
+ mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
+}
+
+void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
+{
+ mReservedSpace += size;
+}
+
+VertexBuffer* VertexBufferInterface::getVertexBuffer() const
+{
+ return mVertexBuffer;
+}
+
+
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+{
+ setBufferSize(initialSize);
+}
+
+StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
+{
+}
+
+bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
+{
+ bool result = true;
+ unsigned int curBufferSize = getBufferSize();
+ if (size > curBufferSize)
+ {
+ result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
+ setWritePosition(0);
+ }
+ else if (getWritePosition() + size > curBufferSize)
+ {
+ if (!discard())
+ {
+ return false;
+ }
+ setWritePosition(0);
+ }
+
+ return result;
+}
+
+StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
+{
+}
+
+StaticVertexBufferInterface::~StaticVertexBufferInterface()
+{
+}
+
+int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
+{
+ for (unsigned int element = 0; element < mCache.size(); element++)
+ {
+ if (mCache[element].type == attribute.mType &&
+ mCache[element].size == attribute.mSize &&
+ mCache[element].stride == attribute.stride() &&
+ mCache[element].normalized == attribute.mNormalized)
+ {
+ if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
+ {
+ return mCache[element].streamOffset;
+ }
+ }
+ }
+
+ return -1;
+}
+
+bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
+{
+ unsigned int curSize = getBufferSize();
+ if (curSize == 0)
+ {
+ setBufferSize(size);
+ return true;
+ }
+ else if (curSize >= size)
+ {
+ return true;
+ }
+ else
+ {
+ UNREACHABLE(); // Static vertex buffers can't be resized
+ return false;
+ }
+}
+
+int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+{
+ int attributeOffset = attrib.mOffset % attrib.stride();
+ VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
+ mCache.push_back(element);
+
+ return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h
new file mode 100644
index 0000000000..6ecffd0c0b
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer.h
@@ -0,0 +1,138 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer.h: Defines the abstract VertexBuffer class and VertexBufferInterface
+// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER_H_
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+class VertexAttribute;
+}
+
+namespace rx
+{
+class Renderer;
+
+class VertexBuffer
+{
+ public:
+ VertexBuffer();
+ virtual ~VertexBuffer();
+
+ virtual bool initialize(unsigned int size, bool dynamicUsage) = 0;
+
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
+ GLsizei instances, unsigned int offset) = 0;
+ virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset) = 0;
+
+ virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
+ GLsizei instances) const = 0;
+
+ virtual bool requiresConversion(const gl::VertexAttribute &attrib) const = 0;
+
+ virtual unsigned int getBufferSize() const = 0;
+ virtual bool setBufferSize(unsigned int size) = 0;
+ virtual bool discard() = 0;
+
+ unsigned int getSerial() const;
+
+ protected:
+ void updateSerial();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
+
+ unsigned int mSerial;
+ static unsigned int mNextSerial;
+};
+
+class VertexBufferInterface
+{
+ public:
+ VertexBufferInterface(rx::Renderer *renderer, bool dynamic);
+ virtual ~VertexBufferInterface();
+
+ void reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances);
+ void reserveRawDataSpace(unsigned int size);
+
+ unsigned int getBufferSize() const;
+
+ unsigned int getSerial() const;
+
+ virtual int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
+ virtual int storeRawData(const void* data, unsigned int size);
+
+ VertexBuffer* getVertexBuffer() const;
+
+ protected:
+ virtual bool reserveSpace(unsigned int size) = 0;
+
+ unsigned int getWritePosition() const;
+ void setWritePosition(unsigned int writePosition);
+
+ bool discard();
+
+ bool setBufferSize(unsigned int size);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexBufferInterface);
+
+ rx::Renderer *const mRenderer;
+
+ VertexBuffer* mVertexBuffer;
+
+ unsigned int mWritePosition;
+ unsigned int mReservedSpace;
+ bool mDynamic;
+};
+
+class StreamingVertexBufferInterface : public VertexBufferInterface
+{
+ public:
+ StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize);
+ ~StreamingVertexBufferInterface();
+
+ protected:
+ bool reserveSpace(unsigned int size);
+};
+
+class StaticVertexBufferInterface : public VertexBufferInterface
+{
+ public:
+ explicit StaticVertexBufferInterface(rx::Renderer *renderer);
+ ~StaticVertexBufferInterface();
+
+ int storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances);
+
+ // Returns the offset into the vertex buffer, or -1 if not found
+ int lookupAttribute(const gl::VertexAttribute &attribute);
+
+ protected:
+ bool reserveSpace(unsigned int size);
+
+ private:
+ struct VertexElement
+ {
+ GLenum type;
+ GLint size;
+ GLsizei stride;
+ bool normalized;
+ int attributeOffset;
+
+ unsigned int streamOffset;
+ };
+
+ std::vector<VertexElement> mCache;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp
new file mode 100644
index 0000000000..92c8755e22
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp
@@ -0,0 +1,418 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
+
+#include "libGLESv2/renderer/VertexBuffer11.h"
+#include "libGLESv2/renderer/BufferStorage.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/renderer/Renderer11.h"
+#include "libGLESv2/Context.h"
+
+namespace rx
+{
+
+VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
+{
+ mBuffer = NULL;
+ mBufferSize = 0;
+ mDynamicUsage = false;
+}
+
+VertexBuffer11::~VertexBuffer11()
+{
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ }
+}
+
+bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
+{
+ if (mBuffer)
+ {
+ mBuffer->Release();
+ mBuffer = NULL;
+ }
+
+ updateSerial();
+
+ if (size > 0)
+ {
+ ID3D11Device* dxDevice = mRenderer->getDevice();
+
+ D3D11_BUFFER_DESC bufferDesc;
+ bufferDesc.ByteWidth = size;
+ bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+ bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+ bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+ bufferDesc.MiscFlags = 0;
+ bufferDesc.StructureByteStride = 0;
+
+ HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer);
+ if (FAILED(result))
+ {
+ return false;
+ }
+ }
+
+ mBufferSize = size;
+ mDynamicUsage = dynamicUsage;
+ return true;
+}
+
+VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
+ return static_cast<VertexBuffer11*>(vetexBuffer);
+}
+
+bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
+ GLsizei instances, unsigned int offset)
+{
+ if (mBuffer)
+ {
+ gl::Buffer *buffer = attrib.mBoundBuffer.get();
+
+ int inputStride = attrib.stride();
+ const VertexConverter &converter = getVertexConversion(attrib);
+
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Vertex buffer map failed with error 0x%08x", result);
+ return false;
+ }
+
+ char* output = reinterpret_cast<char*>(mappedResource.pData) + offset;
+
+ const char *input = NULL;
+ if (buffer)
+ {
+ BufferStorage *storage = buffer->getStorage();
+ input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
+ }
+ else
+ {
+ input = static_cast<const char*>(attrib.mPointer);
+ }
+
+ if (instances == 0 || attrib.mDivisor == 0)
+ {
+ input += inputStride * start;
+ }
+
+ converter.conversionFunc(input, inputStride, count, output);
+
+ dxContext->Unmap(mBuffer, 0);
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset)
+{
+ if (mBuffer)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Vertex buffer map failed with error 0x%08x", result);
+ return false;
+ }
+
+ char* bufferData = static_cast<char*>(mappedResource.pData);
+ memcpy(bufferData + offset, data, size);
+
+ dxContext->Unmap(mBuffer, 0);
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+unsigned int VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count,
+ GLsizei instances) const
+{
+ unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
+
+ if (instances == 0 || attrib.mDivisor == 0)
+ {
+ return elementSize * count;
+ }
+ else
+ {
+ return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor);
+ }
+}
+
+bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const
+{
+ return !getVertexConversion(attrib).identity;
+}
+
+unsigned int VertexBuffer11::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+bool VertexBuffer11::setBufferSize(unsigned int size)
+{
+ if (size > mBufferSize)
+ {
+ return initialize(size, mDynamicUsage);
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool VertexBuffer11::discard()
+{
+ if (mBuffer)
+ {
+ ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext();
+
+ D3D11_MAPPED_SUBRESOURCE mappedResource;
+ HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
+ if (FAILED(result))
+ {
+ ERR("Vertex buffer map failed with error 0x%08x", result);
+ return false;
+ }
+
+ dxContext->Unmap(mBuffer, 0);
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const
+{
+ return getVertexConversion(attrib).outputElementSize;
+}
+
+DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const
+{
+ return getVertexConversion(attrib).dxgiFormat;
+}
+
+ID3D11Buffer *VertexBuffer11::getBuffer() const
+{
+ return mBuffer;
+}
+
+template <typename T, unsigned int componentCount, bool widen, bool normalized>
+static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output)
+{
+ unsigned int attribSize = sizeof(T) * componentCount;
+
+ if (attribSize == stride && !widen)
+ {
+ memcpy(output, input, count * attribSize);
+ }
+ else
+ {
+ unsigned int outputStride = widen ? 4 : componentCount;
+ T defaultVal = normalized ? std::numeric_limits<T>::max() : T(1);
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + i * stride);
+ T *offsetOutput = reinterpret_cast<T*>(output) + i * outputStride;
+
+ for (unsigned int j = 0; j < componentCount; j++)
+ {
+ offsetOutput[j] = offsetInput[j];
+ }
+
+ if (widen)
+ {
+ offsetOutput[3] = defaultVal;
+ }
+ }
+ }
+}
+
+template <unsigned int componentCount>
+static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output)
+{
+ static const float divisor = 1.0f / (1 << 16);
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const GLfixed* offsetInput = reinterpret_cast<const GLfixed*>(reinterpret_cast<const char*>(input) + stride * i);
+ float* offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+
+ for (unsigned int j = 0; j < componentCount; j++)
+ {
+ offsetOutput[j] = static_cast<float>(offsetInput[j]) * divisor;
+ }
+ }
+}
+
+template <typename T, unsigned int componentCount, bool normalized>
+static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output)
+{
+ typedef std::numeric_limits<T> NL;
+
+ for (unsigned int i = 0; i < count; i++)
+ {
+ const T *offsetInput = reinterpret_cast<const T*>(reinterpret_cast<const char*>(input) + stride * i);
+ float *offsetOutput = reinterpret_cast<float*>(output) + i * componentCount;
+
+ for (unsigned int j = 0; j < componentCount; j++)
+ {
+ if (normalized)
+ {
+ if (NL::is_signed)
+ {
+ const float divisor = 1.0f / (2 * static_cast<float>(NL::max()) + 1);
+ offsetOutput[j] = (2 * static_cast<float>(offsetInput[j]) + 1) * divisor;
+ }
+ else
+ {
+ offsetOutput[j] = static_cast<float>(offsetInput[j]) / NL::max();
+ }
+ }
+ else
+ {
+ offsetOutput[j] = static_cast<float>(offsetInput[j]);
+ }
+ }
+ }
+}
+
+const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] =
+{
+ { // GL_BYTE
+ { // unnormalized
+ { &copyToFloatVertexData<GLbyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyToFloatVertexData<GLbyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyToFloatVertexData<GLbyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyToFloatVertexData<GLbyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyVertexData<GLbyte, 1, false, true>, true, DXGI_FORMAT_R8_SNORM, 1 },
+ { &copyVertexData<GLbyte, 2, false, true>, true, DXGI_FORMAT_R8G8_SNORM, 2 },
+ { &copyVertexData<GLbyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
+ { &copyVertexData<GLbyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
+ },
+ },
+ { // GL_UNSIGNED_BYTE
+ { // unnormalized
+ { &copyToFloatVertexData<GLubyte, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyToFloatVertexData<GLubyte, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyToFloatVertexData<GLubyte, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyToFloatVertexData<GLubyte, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyVertexData<GLubyte, 1, false, true>, true, DXGI_FORMAT_R8_UNORM, 1 },
+ { &copyVertexData<GLubyte, 2, false, true>, true, DXGI_FORMAT_R8G8_UNORM, 2 },
+ { &copyVertexData<GLubyte, 3, true, true>, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
+ { &copyVertexData<GLubyte, 4, false, true>, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
+ },
+ },
+ { // GL_SHORT
+ { // unnormalized
+ { &copyToFloatVertexData<GLshort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyToFloatVertexData<GLshort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyToFloatVertexData<GLshort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyToFloatVertexData<GLshort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyVertexData<GLshort, 1, false, true>, true, DXGI_FORMAT_R16_SNORM, 2 },
+ { &copyVertexData<GLshort, 2, false, true>, true, DXGI_FORMAT_R16G16_SNORM, 4 },
+ { &copyVertexData<GLshort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
+ { &copyVertexData<GLshort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
+ },
+ },
+ { // GL_UNSIGNED_SHORT
+ { // unnormalized
+ { &copyToFloatVertexData<GLushort, 1, false>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyToFloatVertexData<GLushort, 2, false>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyToFloatVertexData<GLushort, 3, false>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyToFloatVertexData<GLushort, 4, false>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyVertexData<GLushort, 1, false, true>, true, DXGI_FORMAT_R16_UNORM, 2 },
+ { &copyVertexData<GLushort, 2, false, true>, true, DXGI_FORMAT_R16G16_UNORM, 4 },
+ { &copyVertexData<GLushort, 3, true, true>, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
+ { &copyVertexData<GLushort, 4, false, true>, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
+ },
+ },
+ { // GL_FIXED
+ { // unnormalized
+ { &copyFixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyFixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyFixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyFixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyFixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyFixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyFixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyFixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ },
+ { // GL_FLOAT
+ { // unnormalized
+ { &copyVertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyVertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyVertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyVertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ { // normalized
+ { &copyVertexData<GLfloat, 1, false, false>, true, DXGI_FORMAT_R32_FLOAT, 4 },
+ { &copyVertexData<GLfloat, 2, false, false>, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
+ { &copyVertexData<GLfloat, 3, false, false>, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+ { &copyVertexData<GLfloat, 4, false, false>, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+ },
+ },
+};
+
+const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute)
+{
+ unsigned int typeIndex = 0;
+ switch (attribute.mType)
+ {
+ case GL_BYTE: typeIndex = 0; break;
+ case GL_UNSIGNED_BYTE: typeIndex = 1; break;
+ case GL_SHORT: typeIndex = 2; break;
+ case GL_UNSIGNED_SHORT: typeIndex = 3; break;
+ case GL_FIXED: typeIndex = 4; break;
+ case GL_FLOAT: typeIndex = 5; break;
+ default: UNREACHABLE(); break;
+ }
+
+ return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h
new file mode 100644
index 0000000000..75e025075e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h
@@ -0,0 +1,73 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+
+#include "libGLESv2/renderer/VertexBuffer.h"
+
+namespace rx
+{
+class Renderer11;
+
+class VertexBuffer11 : public VertexBuffer
+{
+ public:
+ explicit VertexBuffer11(rx::Renderer11 *const renderer);
+ virtual ~VertexBuffer11();
+
+ virtual bool initialize(unsigned int size, bool dynamicUsage);
+
+ static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
+
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
+ unsigned int offset);
+ virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset);
+
+ virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
+
+ virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
+
+ virtual unsigned int getBufferSize() const;
+ virtual bool setBufferSize(unsigned int size);
+ virtual bool discard();
+
+ unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
+ DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const;
+
+ ID3D11Buffer *getBuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
+
+ rx::Renderer11 *const mRenderer;
+
+ ID3D11Buffer *mBuffer;
+ unsigned int mBufferSize;
+ bool mDynamicUsage;
+
+ typedef void (*VertexConversionFunction)(const void *, unsigned int, unsigned int, void *);
+ struct VertexConverter
+ {
+ VertexConversionFunction conversionFunc;
+ bool identity;
+ DXGI_FORMAT dxgiFormat;
+ unsigned int outputElementSize;
+ };
+
+ enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+ // This table is used to generate mAttributeTypes.
+ static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
+
+ static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ \ No newline at end of file
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp
new file mode 100644
index 0000000000..76dc73e391
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp
@@ -0,0 +1,486 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
+
+#include "libGLESv2/renderer/VertexBuffer9.h"
+#include "libGLESv2/renderer/vertexconversion.h"
+#include "libGLESv2/renderer/BufferStorage.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/Renderer9.h"
+
+#include "libGLESv2/Buffer.h"
+
+namespace rx
+{
+
+bool VertexBuffer9::mTranslationsInitialized = false;
+VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer)
+{
+ mVertexBuffer = NULL;
+ mBufferSize = 0;
+ mDynamicUsage = false;
+
+ if (!mTranslationsInitialized)
+ {
+ initializeTranslations(renderer->getCapsDeclTypes());
+ mTranslationsInitialized = true;
+ }
+}
+
+VertexBuffer9::~VertexBuffer9()
+{
+ if (mVertexBuffer)
+ {
+ mVertexBuffer->Release();
+ mVertexBuffer = NULL;
+ }
+}
+
+bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
+{
+ if (mVertexBuffer)
+ {
+ mVertexBuffer->Release();
+ mVertexBuffer = NULL;
+ }
+
+ updateSerial();
+
+ if (size > 0)
+ {
+ DWORD flags = D3DUSAGE_WRITEONLY;
+ if (dynamicUsage)
+ {
+ flags |= D3DUSAGE_DYNAMIC;
+ }
+
+ HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer);
+
+ if (FAILED(result))
+ {
+ ERR("Out of memory allocating a vertex buffer of size %lu.", size);
+ return false;
+ }
+ }
+
+ mBufferSize = size;
+ mDynamicUsage = dynamicUsage;
+ return true;
+}
+
+VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
+{
+ ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer));
+ return static_cast<VertexBuffer9*>(vertexBuffer);
+}
+
+bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count,
+ GLsizei instances, unsigned int offset)
+{
+ if (mVertexBuffer)
+ {
+ gl::Buffer *buffer = attrib.mBoundBuffer.get();
+
+ int inputStride = attrib.stride();
+ int elementSize = attrib.typeSize();
+ const FormatConverter &converter = formatConverter(attrib);
+
+ DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+ void *mapPtr = NULL;
+ HRESULT result = mVertexBuffer->Lock(offset, spaceRequired(attrib, count, instances), &mapPtr, lockFlags);
+
+ if (FAILED(result))
+ {
+ ERR("Lock failed with error 0x%08x", result);
+ return false;
+ }
+
+ const char *input = NULL;
+ if (buffer)
+ {
+ BufferStorage *storage = buffer->getStorage();
+ input = static_cast<const char*>(storage->getData()) + static_cast<int>(attrib.mOffset);
+ }
+ else
+ {
+ input = static_cast<const char*>(attrib.mPointer);
+ }
+
+ if (instances == 0 || attrib.mDivisor == 0)
+ {
+ input += inputStride * start;
+ }
+
+ if (converter.identity && inputStride == elementSize)
+ {
+ memcpy(mapPtr, input, count * inputStride);
+ }
+ else
+ {
+ converter.convertArray(input, inputStride, count, mapPtr);
+ }
+
+ mVertexBuffer->Unlock();
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset)
+{
+ if (mVertexBuffer)
+ {
+ DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+ void *mapPtr = NULL;
+ HRESULT result = mVertexBuffer->Lock(offset, size, &mapPtr, lockFlags);
+
+ if (FAILED(result))
+ {
+ ERR("Lock failed with error 0x%08x", result);
+ return false;
+ }
+
+ memcpy(mapPtr, data, size);
+
+ mVertexBuffer->Unlock();
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+unsigned int VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const
+{
+ return spaceRequired(attrib, count, instances);
+}
+
+bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const
+{
+ return formatConverter(attrib).identity;
+}
+
+unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const
+{
+ return spaceRequired(attrib, 1, 0);
+}
+
+D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const
+{
+ return formatConverter(attrib).d3dDeclType;
+}
+
+unsigned int VertexBuffer9::getBufferSize() const
+{
+ return mBufferSize;
+}
+
+bool VertexBuffer9::setBufferSize(unsigned int size)
+{
+ if (size > mBufferSize)
+ {
+ return initialize(size, mDynamicUsage);
+ }
+ else
+ {
+ return true;
+ }
+}
+
+bool VertexBuffer9::discard()
+{
+ if (mVertexBuffer)
+ {
+ void *dummy;
+ HRESULT result;
+
+ result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+ if (FAILED(result))
+ {
+ ERR("Discard lock failed with error 0x%08x", result);
+ return false;
+ }
+
+ result = mVertexBuffer->Unlock();
+ if (FAILED(result))
+ {
+ ERR("Discard unlock failed with error 0x%08x", result);
+ return false;
+ }
+
+ return true;
+ }
+ else
+ {
+ ERR("Vertex buffer not initialized.");
+ return false;
+ }
+}
+
+IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
+{
+ return mVertexBuffer;
+}
+
+// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
+//
+// BYTE SHORT (Cast)
+// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
+// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast)
+// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize)
+// SHORT SHORT (Identity)
+// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize)
+// UNSIGNED_SHORT FLOAT (Cast)
+// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize)
+// FIXED (not in WebGL) FLOAT (FixedToFloat)
+// FLOAT FLOAT (Identity)
+
+// GLToCType maps from GL type (as GLenum) to the C typedef.
+template <GLenum GLType> struct GLToCType { };
+
+template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; };
+template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; };
+template <> struct GLToCType<GL_SHORT> { typedef GLshort type; };
+template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; };
+template <> struct GLToCType<GL_FIXED> { typedef GLuint type; };
+template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; };
+
+// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.)
+enum D3DVertexType
+{
+ D3DVT_FLOAT,
+ D3DVT_SHORT,
+ D3DVT_SHORT_NORM,
+ D3DVT_UBYTE,
+ D3DVT_UBYTE_NORM,
+ D3DVT_USHORT_NORM
+};
+
+// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type.
+template <unsigned int D3DType> struct D3DToCType { };
+
+template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; };
+template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; };
+template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; };
+template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; };
+template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; };
+
+// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size.
+template <unsigned int type, int size> struct WidenRule { };
+
+template <int size> struct WidenRule<D3DVT_FLOAT, size> : NoWiden<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT, size> : WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : WidenToEven<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE, size> : WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : WidenToFour<size> { };
+template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : WidenToEven<size> { };
+
+// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination.
+template <unsigned int d3dtype, int size> struct VertexTypeFlags { };
+
+template <unsigned int _capflag, unsigned int _declflag>
+struct VertexTypeFlagsHelper
+{
+ enum { capflag = _capflag };
+ enum { declflag = _declflag };
+};
+
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { };
+template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { };
+template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { };
+template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { };
+
+
+// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
+template <GLenum GLtype, bool normalized> struct VertexTypeMapping { };
+
+template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred>
+struct VertexTypeMappingBase
+{
+ enum { preferred = Preferred };
+ enum { fallback = Fallback };
+};
+
+template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast
+template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize
+template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity
+template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast
+template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize
+template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat
+template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity
+
+
+// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat).
+// The conversion rules themselves are defined in vertexconversion.h.
+
+// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping).
+template <GLenum fromType, bool normalized, unsigned int toType>
+struct ConversionRule : Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> { };
+
+// All conversions from normalized types to float use the Normalize operator.
+template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : Normalize<typename GLToCType<fromType>::type> { };
+
+// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules.
+template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
+template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : FixedToFloat<GLint, 16> { };
+
+// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
+// whether it is normalized or not.
+template <class T, bool normalized> struct DefaultVertexValuesStage2 { };
+
+template <class T> struct DefaultVertexValuesStage2<T, true> : NormalizedDefaultValues<T> { };
+template <class T> struct DefaultVertexValuesStage2<T, false> : SimpleDefaultValues<T> { };
+
+// Work out the default value rule for a D3D type (expressed as the C type) and
+template <class T, bool normalized> struct DefaultVertexValues : DefaultVertexValuesStage2<T, normalized> { };
+template <bool normalized> struct DefaultVertexValues<float, normalized> : SimpleDefaultValues<float> { };
+
+// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion.
+// The fallback conversion produces an output that all D3D9 devices must support.
+template <class T> struct UsePreferred { enum { type = T::preferred }; };
+template <class T> struct UseFallback { enum { type = T::fallback }; };
+
+// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion,
+// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag
+// and the D3DDECLTYPE member needed for the vertex declaration in declflag.
+template <GLenum fromType, bool normalized, int size, template <class T> class PreferenceRule>
+struct Converter
+ : VertexDataConverter<typename GLToCType<fromType>::type,
+ WidenRule<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type, size>,
+ ConversionRule<fromType,
+ normalized,
+ PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>,
+ DefaultVertexValues<typename D3DToCType<PreferenceRule< VertexTypeMapping<fromType, normalized> >::type>::type, normalized > >
+{
+private:
+ enum { d3dtype = PreferenceRule< VertexTypeMapping<fromType, normalized> >::type };
+ enum { d3dsize = WidenRule<d3dtype, size>::finalWidth };
+
+public:
+ enum { capflag = VertexTypeFlags<d3dtype, d3dsize>::capflag };
+ enum { declflag = VertexTypeFlags<d3dtype, d3dsize>::declflag };
+};
+
+// Initialize a TranslationInfo
+#define TRANSLATION(type, norm, size, preferred) \
+ { \
+ Converter<type, norm, size, preferred>::identity, \
+ Converter<type, norm, size, preferred>::finalSize, \
+ Converter<type, norm, size, preferred>::convertArray, \
+ static_cast<D3DDECLTYPE>(Converter<type, norm, size, preferred>::declflag) \
+ }
+
+#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \
+ { \
+ Converter<type, norm, size, UsePreferred>::capflag, \
+ TRANSLATION(type, norm, size, UsePreferred), \
+ TRANSLATION(type, norm, size, UseFallback) \
+ }
+
+#define TRANSLATIONS_FOR_TYPE(type) \
+ { \
+ { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+ { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \
+ }
+
+#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \
+ { \
+ { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+ { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+ }
+
+const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
+{
+ TRANSLATIONS_FOR_TYPE(GL_BYTE),
+ TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
+ TRANSLATIONS_FOR_TYPE(GL_SHORT),
+ TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
+ TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
+ TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
+};
+
+void VertexBuffer9::initializeTranslations(DWORD declTypes)
+{
+ for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++)
+ {
+ for (unsigned int j = 0; j < 2; j++)
+ {
+ for (unsigned int k = 0; k < 4; k++)
+ {
+ if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0)
+ {
+ mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
+ }
+ else
+ {
+ mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
+ }
+ }
+ }
+ }
+}
+
+unsigned int VertexBuffer9::typeIndex(GLenum type)
+{
+ switch (type)
+ {
+ case GL_BYTE: return 0;
+ case GL_UNSIGNED_BYTE: return 1;
+ case GL_SHORT: return 2;
+ case GL_UNSIGNED_SHORT: return 3;
+ case GL_FIXED: return 4;
+ case GL_FLOAT: return 5;
+
+ default: UNREACHABLE(); return 5;
+ }
+}
+
+const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute)
+{
+ return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
+}
+
+unsigned int VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances)
+{
+ unsigned int elementSize = formatConverter(attrib).outputElementSize;
+
+ if (instances == 0 || attrib.mDivisor == 0)
+ {
+ return elementSize * count;
+ }
+ else
+ {
+ return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor);
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h
new file mode 100644
index 0000000000..f771635bda
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+
+#include "libGLESv2/renderer/VertexBuffer.h"
+
+namespace rx
+{
+class Renderer9;
+
+class VertexBuffer9 : public VertexBuffer
+{
+ public:
+ explicit VertexBuffer9(rx::Renderer9 *const renderer);
+ virtual ~VertexBuffer9();
+
+ virtual bool initialize(unsigned int size, bool dynamicUsage);
+
+ static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
+
+ virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
+ unsigned int offset);
+ virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset);
+
+ virtual unsigned int getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances) const;
+
+ virtual bool requiresConversion(const gl::VertexAttribute &attrib) const;
+
+ unsigned int getVertexSize(const gl::VertexAttribute &attrib) const;
+ D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const;
+
+ virtual unsigned int getBufferSize() const;
+ virtual bool setBufferSize(unsigned int size);
+ virtual bool discard();
+
+ IDirect3DVertexBuffer9 *getBuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
+
+ rx::Renderer9 *const mRenderer;
+
+ IDirect3DVertexBuffer9 *mVertexBuffer;
+ unsigned int mBufferSize;
+ bool mDynamicUsage;
+
+ // Attribute format conversion
+ enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+ struct FormatConverter
+ {
+ bool identity;
+ std::size_t outputElementSize;
+ void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
+ D3DDECLTYPE d3dDeclType;
+ };
+
+ static bool mTranslationsInitialized;
+ static void initializeTranslations(DWORD declTypes);
+
+ // [GL types as enumerated by typeIndex()][normalized][size - 1]
+ static FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+ struct TranslationDescription
+ {
+ DWORD capsFlag;
+ FormatConverter preferredConversion;
+ FormatConverter fallbackConversion;
+ };
+
+ // This table is used to generate mFormatConverters.
+ // [GL types as enumerated by typeIndex()][normalized][size - 1]
+ static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+ static unsigned int typeIndex(GLenum type);
+ static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute);
+
+ static unsigned int spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp
new file mode 100644
index 0000000000..ec85857264
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp
@@ -0,0 +1,258 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#include "libGLESv2/renderer/VertexDataManager.h"
+#include "libGLESv2/renderer/BufferStorage.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/VertexBuffer.h"
+
+namespace
+{
+ enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 };
+ // This has to be at least 4k or else it fails on ATI cards.
+ enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 };
+}
+
+namespace rx
+{
+
+static int elementsInBuffer(const gl::VertexAttribute &attribute, int size)
+{
+ int stride = attribute.stride();
+ return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride;
+}
+
+VertexDataManager::VertexDataManager(Renderer *renderer) : mRenderer(renderer)
+{
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mCurrentValue[i][0] = std::numeric_limits<float>::quiet_NaN();
+ mCurrentValue[i][1] = std::numeric_limits<float>::quiet_NaN();
+ mCurrentValue[i][2] = std::numeric_limits<float>::quiet_NaN();
+ mCurrentValue[i][3] = std::numeric_limits<float>::quiet_NaN();
+ mCurrentValueBuffer[i] = NULL;
+ mCurrentValueOffsets[i] = 0;
+ }
+
+ mStreamingBuffer = new StreamingVertexBufferInterface(renderer, INITIAL_STREAM_BUFFER_SIZE);
+
+ if (!mStreamingBuffer)
+ {
+ ERR("Failed to allocate the streaming vertex buffer.");
+ }
+}
+
+VertexDataManager::~VertexDataManager()
+{
+ delete mStreamingBuffer;
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ delete mCurrentValueBuffer[i];
+ }
+}
+
+static bool directStoragePossible(VertexBufferInterface* vb, const gl::VertexAttribute& attrib)
+{
+ gl::Buffer *buffer = attrib.mBoundBuffer.get();
+ BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
+
+ const bool isAligned = (attrib.stride() % 4 == 0) && (attrib.mOffset % 4 == 0);
+
+ return storage && storage->supportsDirectBinding() && !vb->getVertexBuffer()->requiresConversion(attrib) && isAligned;
+}
+
+GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances)
+{
+ if (!mStreamingBuffer)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
+ for (int attributeIndex = 0; attributeIndex < gl::MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ translated[attributeIndex].active = (programBinary->getSemanticIndex(attributeIndex) != -1);
+ }
+
+ // Invalidate static buffers that don't contain matching attributes
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (translated[i].active && attribs[i].mArrayEnabled)
+ {
+ gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+ StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
+
+ if (staticBuffer && staticBuffer->getBufferSize() > 0 && staticBuffer->lookupAttribute(attribs[i]) == -1 &&
+ !directStoragePossible(staticBuffer, attribs[i]))
+ {
+ buffer->invalidateStaticData();
+ }
+ }
+ }
+
+ // Reserve the required space in the buffers
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (translated[i].active && attribs[i].mArrayEnabled)
+ {
+ gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+ StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
+ VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
+
+ if (!directStoragePossible(vertexBuffer, attribs[i]))
+ {
+ if (staticBuffer)
+ {
+ if (staticBuffer->getBufferSize() == 0)
+ {
+ int totalCount = elementsInBuffer(attribs[i], buffer->size());
+ staticBuffer->reserveVertexSpace(attribs[i], totalCount, 0);
+ }
+ }
+ else
+ {
+ mStreamingBuffer->reserveVertexSpace(attribs[i], count, instances);
+ }
+ }
+ }
+ }
+
+ // Perform the vertex data translations
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (translated[i].active)
+ {
+ if (attribs[i].mArrayEnabled)
+ {
+ gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+ if (!buffer && attribs[i].mPointer == NULL)
+ {
+ // This is an application error that would normally result in a crash, but we catch it and return an error
+ ERR("An enabled vertex array has no buffer and no pointer.");
+ return GL_INVALID_OPERATION;
+ }
+
+ StaticVertexBufferInterface *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL;
+ VertexBufferInterface *vertexBuffer = staticBuffer ? staticBuffer : static_cast<VertexBufferInterface*>(mStreamingBuffer);
+
+ BufferStorage *storage = buffer ? buffer->getStorage() : NULL;
+ bool directStorage = directStoragePossible(vertexBuffer, attribs[i]);
+
+ std::size_t streamOffset = -1;
+ unsigned int outputElementSize = 0;
+
+ if (directStorage)
+ {
+ outputElementSize = attribs[i].stride();
+ streamOffset = attribs[i].mOffset + outputElementSize * start;
+ storage->markBufferUsage();
+ }
+ else if (staticBuffer)
+ {
+ streamOffset = staticBuffer->lookupAttribute(attribs[i]);
+ outputElementSize = staticBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
+
+ if (streamOffset == -1)
+ {
+ // Convert the entire buffer
+ int totalCount = elementsInBuffer(attribs[i], storage->getSize());
+ int startIndex = attribs[i].mOffset / attribs[i].stride();
+
+ streamOffset = staticBuffer->storeVertexAttributes(attribs[i], -startIndex, totalCount, 0);
+ }
+
+ if (streamOffset != -1)
+ {
+ streamOffset += (attribs[i].mOffset / attribs[i].stride()) * outputElementSize;
+
+ if (instances == 0 || attribs[i].mDivisor == 0)
+ {
+ streamOffset += start * outputElementSize;
+ }
+ }
+ }
+ else
+ {
+ outputElementSize = mStreamingBuffer->getVertexBuffer()->getSpaceRequired(attribs[i], 1, 0);
+ streamOffset = mStreamingBuffer->storeVertexAttributes(attribs[i], start, count, instances);
+ }
+
+ if (streamOffset == -1)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
+ translated[i].storage = directStorage ? storage : NULL;
+ translated[i].vertexBuffer = vertexBuffer->getVertexBuffer();
+ translated[i].serial = directStorage ? storage->getSerial() : vertexBuffer->getSerial();
+ translated[i].divisor = attribs[i].mDivisor;
+
+ translated[i].attribute = &attribs[i];
+ translated[i].stride = outputElementSize;
+ translated[i].offset = streamOffset;
+ }
+ else
+ {
+ if (!mCurrentValueBuffer[i])
+ {
+ mCurrentValueBuffer[i] = new StreamingVertexBufferInterface(mRenderer, CONSTANT_VERTEX_BUFFER_SIZE);
+ }
+
+ StreamingVertexBufferInterface *buffer = mCurrentValueBuffer[i];
+
+ if (mCurrentValue[i][0] != attribs[i].mCurrentValue[0] ||
+ mCurrentValue[i][1] != attribs[i].mCurrentValue[1] ||
+ mCurrentValue[i][2] != attribs[i].mCurrentValue[2] ||
+ mCurrentValue[i][3] != attribs[i].mCurrentValue[3])
+ {
+ unsigned int requiredSpace = sizeof(float) * 4;
+ buffer->reserveRawDataSpace(requiredSpace);
+ int streamOffset = buffer->storeRawData(attribs[i].mCurrentValue, requiredSpace);
+ if (streamOffset == -1)
+ {
+ return GL_OUT_OF_MEMORY;
+ }
+
+ mCurrentValueOffsets[i] = streamOffset;
+ }
+
+ translated[i].storage = NULL;
+ translated[i].vertexBuffer = mCurrentValueBuffer[i]->getVertexBuffer();
+ translated[i].serial = mCurrentValueBuffer[i]->getSerial();
+ translated[i].divisor = 0;
+
+ translated[i].attribute = &attribs[i];
+ translated[i].stride = 0;
+ translated[i].offset = mCurrentValueOffsets[i];
+ }
+ }
+ }
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (translated[i].active && attribs[i].mArrayEnabled)
+ {
+ gl::Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+ if (buffer)
+ {
+ buffer->promoteStaticUsage(count * attribs[i].typeSize());
+ }
+ }
+ }
+
+ return GL_NO_ERROR;
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h
new file mode 100644
index 0000000000..28387e6baf
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.h
@@ -0,0 +1,65 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDataManager.h: Defines the VertexDataManager, a class that
+// runs the Buffer translation process.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+#define LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
+
+#include "libGLESv2/Constants.h"
+#include "common/angleutils.h"
+
+namespace gl
+{
+class VertexAttribute;
+class ProgramBinary;
+}
+
+namespace rx
+{
+class BufferStorage;
+class StreamingVertexBufferInterface;
+class VertexBuffer;
+class Renderer;
+
+struct TranslatedAttribute
+{
+ bool active;
+
+ const gl::VertexAttribute *attribute;
+ UINT offset;
+ UINT stride; // 0 means not to advance the read pointer at all
+
+ VertexBuffer *vertexBuffer;
+ BufferStorage *storage;
+ unsigned int serial;
+ unsigned int divisor;
+};
+
+class VertexDataManager
+{
+ public:
+ VertexDataManager(rx::Renderer *renderer);
+ virtual ~VertexDataManager();
+
+ GLenum prepareVertexData(const gl::VertexAttribute attribs[], gl::ProgramBinary *programBinary, GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
+
+ rx::Renderer *const mRenderer;
+
+ StreamingVertexBufferInterface *mStreamingBuffer;
+
+ float mCurrentValue[gl::MAX_VERTEX_ATTRIBS][4];
+ StreamingVertexBufferInterface *mCurrentValueBuffer[gl::MAX_VERTEX_ATTRIBS];
+ std::size_t mCurrentValueOffsets[gl::MAX_VERTEX_ATTRIBS];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXDATAMANAGER_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp
new file mode 100644
index 0000000000..9b83a6476e
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp
@@ -0,0 +1,217 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
+
+#include "libGLESv2/ProgramBinary.h"
+#include "libGLESv2/Context.h"
+#include "libGLESv2/renderer/VertexBuffer9.h"
+#include "libGLESv2/renderer/VertexDeclarationCache.h"
+
+namespace rx
+{
+
+VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
+{
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ mVertexDeclCache[i].vertexDeclaration = NULL;
+ mVertexDeclCache[i].lruCount = 0;
+ }
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAppliedVBs[i].serial = 0;
+ }
+
+ mLastSetVDecl = NULL;
+ mInstancingEnabled = true;
+}
+
+VertexDeclarationCache::~VertexDeclarationCache()
+{
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ if (mVertexDeclCache[i].vertexDeclaration)
+ {
+ mVertexDeclCache[i].vertexDeclaration->Release();
+ }
+ }
+}
+
+GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
+{
+ *repeatDraw = 1;
+
+ int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
+ int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
+
+ if (instances > 0)
+ {
+ // Find an indexed attribute to be mapped to D3D stream 0
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (attributes[i].active)
+ {
+ if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0)
+ {
+ indexedAttribute = i;
+ }
+ else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0)
+ {
+ instancedAttribute = i;
+ }
+ if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS)
+ break; // Found both an indexed and instanced attribute
+ }
+ }
+
+ if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
+ {
+ return GL_INVALID_OPERATION;
+ }
+ }
+
+ D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
+ D3DVERTEXELEMENT9 *element = &elements[0];
+
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (attributes[i].active)
+ {
+ // Directly binding the storage buffer is not supported for d3d9
+ ASSERT(attributes[i].storage == NULL);
+
+ int stream = i;
+
+ if (instances > 0)
+ {
+ // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
+ if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
+ {
+ *repeatDraw = instances;
+ }
+ else
+ {
+ if (i == indexedAttribute)
+ {
+ stream = 0;
+ }
+ else if (i == 0)
+ {
+ stream = indexedAttribute;
+ }
+
+ UINT frequency = 1;
+
+ if (attributes[i].divisor == 0)
+ {
+ frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
+ }
+ else
+ {
+ frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
+ }
+
+ device->SetStreamSourceFreq(stream, frequency);
+ mInstancingEnabled = true;
+ }
+ }
+
+ VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer);
+
+ if (mAppliedVBs[stream].serial != attributes[i].serial ||
+ mAppliedVBs[stream].stride != attributes[i].stride ||
+ mAppliedVBs[stream].offset != attributes[i].offset)
+ {
+ device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride);
+ mAppliedVBs[stream].serial = attributes[i].serial;
+ mAppliedVBs[stream].stride = attributes[i].stride;
+ mAppliedVBs[stream].offset = attributes[i].offset;
+ }
+
+ element->Stream = stream;
+ element->Offset = 0;
+ element->Type = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDeclType(*attributes[i].attribute) : D3DDECLTYPE_FLOAT4;
+ element->Method = D3DDECLMETHOD_DEFAULT;
+ element->Usage = D3DDECLUSAGE_TEXCOORD;
+ element->UsageIndex = programBinary->getSemanticIndex(i);
+ element++;
+ }
+ }
+
+ if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
+ {
+ if (mInstancingEnabled)
+ {
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ device->SetStreamSourceFreq(i, 1);
+ }
+
+ mInstancingEnabled = false;
+ }
+ }
+
+ static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+ *(element++) = end;
+
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ VertexDeclCacheEntry *entry = &mVertexDeclCache[i];
+ if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration)
+ {
+ entry->lruCount = ++mMaxLru;
+ if(entry->vertexDeclaration != mLastSetVDecl)
+ {
+ device->SetVertexDeclaration(entry->vertexDeclaration);
+ mLastSetVDecl = entry->vertexDeclaration;
+ }
+
+ return GL_NO_ERROR;
+ }
+ }
+
+ VertexDeclCacheEntry *lastCache = mVertexDeclCache;
+
+ for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+ {
+ if (mVertexDeclCache[i].lruCount < lastCache->lruCount)
+ {
+ lastCache = &mVertexDeclCache[i];
+ }
+ }
+
+ if (lastCache->vertexDeclaration != NULL)
+ {
+ lastCache->vertexDeclaration->Release();
+ lastCache->vertexDeclaration = NULL;
+ // mLastSetVDecl is set to the replacement, so we don't have to worry
+ // about it.
+ }
+
+ memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
+ device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration);
+ device->SetVertexDeclaration(lastCache->vertexDeclaration);
+ mLastSetVDecl = lastCache->vertexDeclaration;
+ lastCache->lruCount = ++mMaxLru;
+
+ return GL_NO_ERROR;
+}
+
+void VertexDeclarationCache::markStateDirty()
+{
+ for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++)
+ {
+ mAppliedVBs[i].serial = 0;
+ }
+
+ mLastSetVDecl = NULL;
+ mInstancingEnabled = true; // Forces it to be disabled when not used
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h
new file mode 100644
index 0000000000..3fc024a9ba
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h
@@ -0,0 +1,58 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+
+#include "libGLESv2/renderer/VertexDataManager.h"
+
+namespace gl
+{
+class VertexDataManager;
+}
+
+namespace rx
+{
+
+class VertexDeclarationCache
+{
+ public:
+ VertexDeclarationCache();
+ ~VertexDeclarationCache();
+
+ GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
+
+ void markStateDirty();
+
+ private:
+ UINT mMaxLru;
+
+ enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
+
+ struct VBData
+ {
+ unsigned int serial;
+ unsigned int stride;
+ unsigned int offset;
+ };
+
+ VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS];
+ IDirect3DVertexDeclaration9 *mLastSetVDecl;
+ bool mInstancingEnabled;
+
+ struct VertexDeclCacheEntry
+ {
+ D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1];
+ UINT lruCount;
+ IDirect3DVertexDeclaration9 *vertexDeclaration;
+ } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h b/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h
new file mode 100644
index 0000000000..8e1973605b
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/generatemip.h
@@ -0,0 +1,203 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// generatemip.h: Defines the GenerateMip function, templated on the format
+// type of the image for which mip levels are being generated.
+
+#ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_
+#define LIBGLESV2_RENDERER_GENERATEMIP_H_
+
+#include "libGLESv2/mathutil.h"
+
+namespace rx
+{
+struct L8
+{
+ unsigned char L;
+
+ static void average(L8 *dst, const L8 *src1, const L8 *src2)
+ {
+ dst->L = ((src1->L ^ src2->L) >> 1) + (src1->L & src2->L);
+ }
+};
+
+typedef L8 R8; // R8 type is functionally equivalent for mip purposes
+typedef L8 A8; // A8 type is functionally equivalent for mip purposes
+
+struct A8L8
+{
+ unsigned char L;
+ unsigned char A;
+
+ static void average(A8L8 *dst, const A8L8 *src1, const A8L8 *src2)
+ {
+ *(unsigned short*)dst = (((*(unsigned short*)src1 ^ *(unsigned short*)src2) & 0xFEFE) >> 1) + (*(unsigned short*)src1 & *(unsigned short*)src2);
+ }
+};
+
+typedef A8L8 R8G8; // R8G8 type is functionally equivalent for mip purposes
+
+struct A8R8G8B8
+{
+ unsigned char B;
+ unsigned char G;
+ unsigned char R;
+ unsigned char A;
+
+ static void average(A8R8G8B8 *dst, const A8R8G8B8 *src1, const A8R8G8B8 *src2)
+ {
+ *(unsigned int*)dst = (((*(unsigned int*)src1 ^ *(unsigned int*)src2) & 0xFEFEFEFE) >> 1) + (*(unsigned int*)src1 & *(unsigned int*)src2);
+ }
+};
+
+typedef A8R8G8B8 R8G8B8A8; // R8G8B8A8 type is functionally equivalent for mip purposes
+
+struct A16B16G16R16F
+{
+ unsigned short R;
+ unsigned short G;
+ unsigned short B;
+ unsigned short A;
+
+ static void average(A16B16G16R16F *dst, const A16B16G16R16F *src1, const A16B16G16R16F *src2)
+ {
+ dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f);
+ dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f);
+ dst->B = gl::float32ToFloat16((gl::float16ToFloat32(src1->B) + gl::float16ToFloat32(src2->B)) * 0.5f);
+ dst->A = gl::float32ToFloat16((gl::float16ToFloat32(src1->A) + gl::float16ToFloat32(src2->A)) * 0.5f);
+ }
+};
+
+struct R16F
+{
+ unsigned short R;
+
+ static void average(R16F *dst, const R16F *src1, const R16F *src2)
+ {
+ dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f);
+ }
+};
+
+struct R16G16F
+{
+ unsigned short R;
+ unsigned short G;
+
+ static void average(R16G16F *dst, const R16G16F *src1, const R16G16F *src2)
+ {
+ dst->R = gl::float32ToFloat16((gl::float16ToFloat32(src1->R) + gl::float16ToFloat32(src2->R)) * 0.5f);
+ dst->G = gl::float32ToFloat16((gl::float16ToFloat32(src1->G) + gl::float16ToFloat32(src2->G)) * 0.5f);
+ }
+};
+
+struct A32B32G32R32F
+{
+ float R;
+ float G;
+ float B;
+ float A;
+
+ static void average(A32B32G32R32F *dst, const A32B32G32R32F *src1, const A32B32G32R32F *src2)
+ {
+ dst->R = (src1->R + src2->R) * 0.5f;
+ dst->G = (src1->G + src2->G) * 0.5f;
+ dst->B = (src1->B + src2->B) * 0.5f;
+ dst->A = (src1->A + src2->A) * 0.5f;
+ }
+};
+
+struct R32F
+{
+ float R;
+
+ static void average(R32F *dst, const R32F *src1, const R32F *src2)
+ {
+ dst->R = (src1->R + src2->R) * 0.5f;
+ }
+};
+
+struct R32G32F
+{
+ float R;
+ float G;
+
+ static void average(R32G32F *dst, const R32G32F *src1, const R32G32F *src2)
+ {
+ dst->R = (src1->R + src2->R) * 0.5f;
+ dst->G = (src1->G + src2->G) * 0.5f;
+ }
+};
+
+struct R32G32B32F
+{
+ float R;
+ float G;
+ float B;
+
+ static void average(R32G32B32F *dst, const R32G32B32F *src1, const R32G32B32F *src2)
+ {
+ dst->R = (src1->R + src2->R) * 0.5f;
+ dst->G = (src1->G + src2->G) * 0.5f;
+ dst->B = (src1->B + src2->B) * 0.5f;
+ }
+};
+
+template <typename T>
+static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight,
+ const unsigned char *sourceData, int sourcePitch,
+ unsigned char *destData, int destPitch)
+{
+ unsigned int mipWidth = std::max(1U, sourceWidth >> 1);
+ unsigned int mipHeight = std::max(1U, sourceHeight >> 1);
+
+ if (sourceHeight == 1)
+ {
+ ASSERT(sourceWidth != 1);
+
+ const T *src = (const T*)sourceData;
+ T *dst = (T*)destData;
+
+ for (unsigned int x = 0; x < mipWidth; x++)
+ {
+ T::average(&dst[x], &src[x * 2], &src[x * 2 + 1]);
+ }
+ }
+ else if (sourceWidth == 1)
+ {
+ ASSERT(sourceHeight != 1);
+
+ for (unsigned int y = 0; y < mipHeight; y++)
+ {
+ const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch);
+ const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch);
+ T *dst = (T*)(destData + y * destPitch);
+
+ T::average(dst, src0, src1);
+ }
+ }
+ else
+ {
+ for (unsigned int y = 0; y < mipHeight; y++)
+ {
+ const T *src0 = (const T*)(sourceData + y * 2 * sourcePitch);
+ const T *src1 = (const T*)(sourceData + y * 2 * sourcePitch + sourcePitch);
+ T *dst = (T*)(destData + y * destPitch);
+
+ for (unsigned int x = 0; x < mipWidth; x++)
+ {
+ T tmp0;
+ T tmp1;
+
+ T::average(&tmp0, &src0[x * 2], &src0[x * 2 + 1]);
+ T::average(&tmp1, &src1[x * 2], &src1[x * 2 + 1]);
+ T::average(&dst[x], &tmp0, &tmp1);
+ }
+ }
+ }
+}
+}
+
+#endif // LIBGLESV2_RENDERER_GENERATEMIP_H_
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
new file mode 100644
index 0000000000..5f01dc12ed
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp
@@ -0,0 +1,688 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer11_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#include "libGLESv2/renderer/renderer11_utils.h"
+
+#include "common/debug.h"
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
+{
+ D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
+
+ switch (glBlend)
+ {
+ case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break;
+ case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break;
+ case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break;
+ case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break;
+ case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break;
+ case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
+ case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break;
+ case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break;
+ case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break;
+ case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break;
+ case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break;
+ case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dBlend;
+}
+
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
+{
+ D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
+
+ switch (glBlendOp)
+ {
+ case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break;
+ case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break;
+ case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dBlendOp;
+}
+
+UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ UINT8 mask = 0;
+ if (red)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_RED;
+ }
+ if (green)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
+ }
+ if (blue)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
+ }
+ if (alpha)
+ {
+ mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
+ }
+ return mask;
+}
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
+{
+ D3D11_CULL_MODE cull = D3D11_CULL_NONE;
+
+ if (cullEnabled)
+ {
+ switch (cullMode)
+ {
+ case GL_FRONT: cull = D3D11_CULL_FRONT; break;
+ case GL_BACK: cull = D3D11_CULL_BACK; break;
+ case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break;
+ default: UNREACHABLE();
+ }
+ }
+ else
+ {
+ cull = D3D11_CULL_NONE;
+ }
+
+ return cull;
+}
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
+{
+ D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
+ switch (comparison)
+ {
+ case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break;
+ case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break;
+ case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break;
+ case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break;
+ case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break;
+ case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break;
+ case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break;
+ case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dComp;
+}
+
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
+{
+ return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+}
+
+UINT8 ConvertStencilMask(GLuint stencilmask)
+{
+ return static_cast<UINT8>(stencilmask);
+}
+
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
+{
+ D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
+
+ switch (stencilOp)
+ {
+ case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break;
+ case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break;
+ case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break;
+ case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break;
+ case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break;
+ case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break;
+ case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break;
+ case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dStencilOp;
+}
+
+D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
+{
+ if (maxAnisotropy > 1.0f)
+ {
+ return D3D11_ENCODE_ANISOTROPIC_FILTER(false);
+ }
+ else
+ {
+ D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
+ D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
+ switch (minFilter)
+ {
+ case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break;
+ case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break;
+ case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break;
+ case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break;
+ case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+ case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+ default: UNREACHABLE();
+ }
+
+ D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
+ switch (magFilter)
+ {
+ case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break;
+ case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break;
+ default: UNREACHABLE();
+ }
+
+ return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false);
+ }
+}
+
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
+{
+ switch (wrap)
+ {
+ case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP;
+ case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP;
+ case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
+ default: UNREACHABLE();
+ }
+
+ return D3D11_TEXTURE_ADDRESS_WRAP;
+}
+
+FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset)
+{
+ return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : -FLT_MAX;
+}
+
+FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
+{
+ return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast<float>(lodOffset) : FLT_MAX;
+}
+
+}
+
+namespace d3d11_gl
+{
+
+GLenum ConvertBackBufferFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES;
+ case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_RGBA8_OES;
+}
+
+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_UNKNOWN: return GL_NONE;
+ case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_DEPTH24_STENCIL8_OES;
+}
+
+GLenum ConvertRenderbufferFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ return GL_BGRA8_EXT;
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ return GL_RGBA8_OES;
+ case DXGI_FORMAT_D16_UNORM:
+ return GL_DEPTH_COMPONENT16;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ return GL_DEPTH24_STENCIL8_OES;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_RGBA8_OES;
+}
+
+GLenum ConvertTextureInternalFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ return GL_RGBA8_OES;
+ case DXGI_FORMAT_A8_UNORM:
+ return GL_ALPHA8_EXT;
+ case DXGI_FORMAT_BC1_UNORM:
+ return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case DXGI_FORMAT_BC2_UNORM:
+ return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
+ case DXGI_FORMAT_BC3_UNORM:
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ return GL_RGBA32F_EXT;
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ return GL_RGB32F_EXT;
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ return GL_RGBA16F_EXT;
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ return GL_BGRA8_EXT;
+ case DXGI_FORMAT_R8_UNORM:
+ return GL_R8_EXT;
+ case DXGI_FORMAT_R8G8_UNORM:
+ return GL_RG8_EXT;
+ case DXGI_FORMAT_R16_FLOAT:
+ return GL_R16F_EXT;
+ case DXGI_FORMAT_R16G16_FLOAT:
+ return GL_RG16F_EXT;
+ case DXGI_FORMAT_D16_UNORM:
+ return GL_DEPTH_COMPONENT16;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ return GL_DEPTH24_STENCIL8_OES;
+ case DXGI_FORMAT_UNKNOWN:
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_RGBA8_OES;
+}
+
+}
+
+namespace gl_d3d11
+{
+
+DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
+{
+ switch (format)
+ {
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8_OES:
+ case GL_RGB565:
+ case GL_RGB8_OES:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case GL_BGRA8_EXT:
+ return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case GL_DEPTH_COMPONENT16:
+ return DXGI_FORMAT_D16_UNORM;
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ return DXGI_FORMAT_D24_UNORM_S8_UINT;
+ default:
+ UNREACHABLE();
+ }
+
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+}
+
+DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
+{
+ switch (internalformat)
+ {
+ case GL_RGB565:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ case GL_LUMINANCE8_EXT:
+ case GL_LUMINANCE8_ALPHA8_EXT:
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+ case GL_ALPHA8_EXT:
+ return DXGI_FORMAT_A8_UNORM;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return DXGI_FORMAT_BC1_UNORM;
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+ return DXGI_FORMAT_BC2_UNORM;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+ return DXGI_FORMAT_BC3_UNORM;
+ case GL_RGBA32F_EXT:
+ case GL_ALPHA32F_EXT:
+ case GL_LUMINANCE_ALPHA32F_EXT:
+ return DXGI_FORMAT_R32G32B32A32_FLOAT;
+ case GL_RGB32F_EXT:
+ case GL_LUMINANCE32F_EXT:
+ return DXGI_FORMAT_R32G32B32_FLOAT;
+ case GL_RGBA16F_EXT:
+ case GL_ALPHA16F_EXT:
+ case GL_LUMINANCE_ALPHA16F_EXT:
+ case GL_RGB16F_EXT:
+ case GL_LUMINANCE16F_EXT:
+ return DXGI_FORMAT_R16G16B16A16_FLOAT;
+ case GL_BGRA8_EXT:
+ return DXGI_FORMAT_B8G8R8A8_UNORM;
+ case GL_R8_EXT:
+ return DXGI_FORMAT_R8_UNORM;
+ case GL_RG8_EXT:
+ return DXGI_FORMAT_R8G8_UNORM;
+ case GL_R16F_EXT:
+ return DXGI_FORMAT_R16_FLOAT;
+ case GL_RG16F_EXT:
+ return DXGI_FORMAT_R16G16_FLOAT;
+ case GL_DEPTH_COMPONENT16:
+ return DXGI_FORMAT_D16_UNORM;
+ case GL_DEPTH_COMPONENT32_OES:
+ case GL_DEPTH24_STENCIL8_OES:
+ return DXGI_FORMAT_D24_UNORM_S8_UINT;
+ case GL_NONE:
+ return DXGI_FORMAT_UNKNOWN;
+ default:
+ UNREACHABLE();
+ }
+
+ return DXGI_FORMAT_R8G8B8A8_UNORM;
+}
+
+}
+
+namespace d3d11
+{
+
+void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
+{
+ vertex->x = x;
+ vertex->y = y;
+ vertex->u = u;
+ vertex->v = v;
+}
+
+void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z,
+ const gl::Color &color)
+{
+ vertex->x = x;
+ vertex->y = y;
+ vertex->z = z;
+ vertex->r = color.red;
+ vertex->g = color.green;
+ vertex->b = color.blue;
+ vertex->a = color.alpha;
+}
+
+size_t ComputePixelSizeBits(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_R1_UNORM:
+ return 1;
+
+ case DXGI_FORMAT_A8_UNORM:
+ case DXGI_FORMAT_R8_SINT:
+ case DXGI_FORMAT_R8_SNORM:
+ case DXGI_FORMAT_R8_TYPELESS:
+ case DXGI_FORMAT_R8_UINT:
+ case DXGI_FORMAT_R8_UNORM:
+ return 8;
+
+ case DXGI_FORMAT_B5G5R5A1_UNORM:
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ case DXGI_FORMAT_D16_UNORM:
+ case DXGI_FORMAT_R16_FLOAT:
+ case DXGI_FORMAT_R16_SINT:
+ case DXGI_FORMAT_R16_SNORM:
+ case DXGI_FORMAT_R16_TYPELESS:
+ case DXGI_FORMAT_R16_UINT:
+ case DXGI_FORMAT_R16_UNORM:
+ case DXGI_FORMAT_R8G8_SINT:
+ case DXGI_FORMAT_R8G8_SNORM:
+ case DXGI_FORMAT_R8G8_TYPELESS:
+ case DXGI_FORMAT_R8G8_UINT:
+ case DXGI_FORMAT_R8G8_UNORM:
+ return 16;
+
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_G8R8_G8B8_UNORM:
+ case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+ case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+ case DXGI_FORMAT_R10G10B10A2_UINT:
+ case DXGI_FORMAT_R10G10B10A2_UNORM:
+ case DXGI_FORMAT_R11G11B10_FLOAT:
+ case DXGI_FORMAT_R16G16_FLOAT:
+ case DXGI_FORMAT_R16G16_SINT:
+ case DXGI_FORMAT_R16G16_SNORM:
+ case DXGI_FORMAT_R16G16_TYPELESS:
+ case DXGI_FORMAT_R16G16_UINT:
+ case DXGI_FORMAT_R16G16_UNORM:
+ case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+ case DXGI_FORMAT_R24G8_TYPELESS:
+ case DXGI_FORMAT_R32_FLOAT:
+ case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+ case DXGI_FORMAT_R32_SINT:
+ case DXGI_FORMAT_R32_TYPELESS:
+ case DXGI_FORMAT_R32_UINT:
+ case DXGI_FORMAT_R8G8_B8G8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+ case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+ case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+ return 32;
+
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R32G32_FLOAT:
+ case DXGI_FORMAT_R32G32_SINT:
+ case DXGI_FORMAT_R32G32_TYPELESS:
+ case DXGI_FORMAT_R32G32_UINT:
+ case DXGI_FORMAT_R32G8X24_TYPELESS:
+ return 64;
+
+ case DXGI_FORMAT_R32G32B32_FLOAT:
+ case DXGI_FORMAT_R32G32B32_SINT:
+ case DXGI_FORMAT_R32G32B32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32_UINT:
+ return 96;
+
+ case DXGI_FORMAT_R32G32B32A32_FLOAT:
+ case DXGI_FORMAT_R32G32B32A32_SINT:
+ case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+ case DXGI_FORMAT_R32G32B32A32_UINT:
+ return 128;
+
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_SNORM:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ return 4;
+
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return 8;
+
+ default:
+ return 0;
+ }
+}
+
+size_t ComputeBlockSizeBits(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_SNORM:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return ComputePixelSizeBits(format) * 16;
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+bool IsCompressed(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_SNORM:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return true;
+ case DXGI_FORMAT_UNKNOWN:
+ UNREACHABLE();
+ return false;
+ default:
+ return false;
+ }
+}
+
+unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ case DXGI_FORMAT_BC4_SNORM:
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ case DXGI_FORMAT_BC5_SNORM:
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ case DXGI_FORMAT_BC6H_SF16:
+ case DXGI_FORMAT_BC6H_TYPELESS:
+ case DXGI_FORMAT_BC6H_UF16:
+ case DXGI_FORMAT_BC7_TYPELESS:
+ case DXGI_FORMAT_BC7_UNORM:
+ case DXGI_FORMAT_BC7_UNORM_SRGB:
+ return 4;
+ case DXGI_FORMAT_UNKNOWN:
+ UNREACHABLE();
+ return 1;
+ default:
+ return 1;
+ }
+}
+
+bool IsDepthStencilFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+ case DXGI_FORMAT_D32_FLOAT:
+ case DXGI_FORMAT_D24_UNORM_S8_UINT:
+ case DXGI_FORMAT_D16_UNORM:
+ return true;
+ default:
+ return false;
+ }
+}
+
+DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS;
+ case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24G8_TYPELESS;
+ case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS;
+ default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format)
+{
+ switch (format)
+ {
+ case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+ case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_UINT;
+ case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+ case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_UNORM;
+ default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN;
+ }
+}
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
+{
+#if defined(_DEBUG)
+ return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
+#else
+ return S_OK;
+#endif
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
new file mode 100644
index 0000000000..1bc48c1a13
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h
@@ -0,0 +1,95 @@
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer11_utils.h: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+
+#include "libGLESv2/angletypes.h"
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
+UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode);
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
+UINT8 ConvertStencilMask(GLuint stencilmask);
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
+
+D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
+FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
+FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
+
+DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
+DXGI_FORMAT ConvertTextureFormat(GLenum format);
+}
+
+namespace d3d11_gl
+{
+
+GLenum ConvertBackBufferFormat(DXGI_FORMAT format);
+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format);
+GLenum ConvertRenderbufferFormat(DXGI_FORMAT format);
+GLenum ConvertTextureInternalFormat(DXGI_FORMAT format);
+
+}
+
+namespace d3d11
+{
+
+struct PositionTexCoordVertex
+{
+ float x, y;
+ float u, v;
+};
+void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v);
+
+struct PositionDepthColorVertex
+{
+ float x, y, z;
+ float r, g, b, a;
+};
+void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z,
+ const gl::Color &color);
+
+size_t ComputePixelSizeBits(DXGI_FORMAT format);
+size_t ComputeBlockSizeBits(DXGI_FORMAT format);
+
+bool IsCompressed(DXGI_FORMAT format);
+unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format);
+
+bool IsDepthStencilFormat(DXGI_FORMAT format);
+DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format);
+DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format);
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name);
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+ switch (errorCode)
+ {
+ case DXGI_ERROR_DEVICE_HUNG:
+ case DXGI_ERROR_DEVICE_REMOVED:
+ case DXGI_ERROR_DEVICE_RESET:
+ case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+ case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp
new file mode 100644
index 0000000000..da75d465e3
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp
@@ -0,0 +1,500 @@
+#include "precompiled.h"
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer9_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D9 renderer.
+
+#include "libGLESv2/renderer/renderer9_utils.h"
+#include "libGLESv2/mathutil.h"
+#include "libGLESv2/Context.h"
+
+#include "common/debug.h"
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison)
+{
+ D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
+ switch (comparison)
+ {
+ case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
+ case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
+ case GL_LESS: d3dComp = D3DCMP_LESS; break;
+ case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
+ case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
+ case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
+ case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
+ case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dComp;
+}
+
+D3DCOLOR ConvertColor(gl::Color color)
+{
+ return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
+ gl::unorm<8>(color.green),
+ gl::unorm<8>(color.blue),
+ gl::unorm<8>(color.alpha));
+}
+
+D3DBLEND ConvertBlendFunc(GLenum blend)
+{
+ D3DBLEND d3dBlend = D3DBLEND_ZERO;
+
+ switch (blend)
+ {
+ case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
+ case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
+ case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
+ case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
+ case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
+ case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
+ case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
+ case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
+ case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
+ case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
+ case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
+ case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+ case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
+ case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+ case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dBlend;
+}
+
+D3DBLENDOP ConvertBlendOp(GLenum blendOp)
+{
+ D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
+
+ switch (blendOp)
+ {
+ case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
+ case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
+ case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dBlendOp;
+}
+
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
+{
+ D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
+
+ switch (stencilOp)
+ {
+ case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
+ case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
+ case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
+ case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
+ case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
+ case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
+ case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
+ case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dStencilOp;
+}
+
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
+{
+ D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
+
+ switch (wrap)
+ {
+ case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
+ case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
+ case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dWrap;
+}
+
+D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
+{
+ D3DCULL cull = D3DCULL_CCW;
+ switch (cullFace)
+ {
+ case GL_FRONT:
+ cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+ break;
+ case GL_BACK:
+ cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+ break;
+ case GL_FRONT_AND_BACK:
+ cull = D3DCULL_NONE; // culling will be handled during draw
+ break;
+ default: UNREACHABLE();
+ }
+
+ return cull;
+}
+
+D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
+{
+ D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
+
+ switch (cubeFace)
+ {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ face = D3DCUBEMAP_FACE_POSITIVE_X;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ face = D3DCUBEMAP_FACE_NEGATIVE_X;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ face = D3DCUBEMAP_FACE_POSITIVE_Y;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ face = D3DCUBEMAP_FACE_NEGATIVE_Y;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ face = D3DCUBEMAP_FACE_POSITIVE_Z;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ face = D3DCUBEMAP_FACE_NEGATIVE_Z;
+ break;
+ default: UNREACHABLE();
+ }
+
+ return face;
+}
+
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+ return (red ? D3DCOLORWRITEENABLE_RED : 0) |
+ (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
+ (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
+ (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
+}
+
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
+{
+ if (maxAnisotropy > 1.0f)
+ {
+ return D3DTEXF_ANISOTROPIC;
+ }
+
+ D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
+ switch (magFilter)
+ {
+ case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
+ case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
+ default: UNREACHABLE();
+ }
+
+ return d3dMagFilter;
+}
+
+void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
+{
+ switch (minFilter)
+ {
+ case GL_NEAREST:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_NONE;
+ break;
+ case GL_LINEAR:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_NONE;
+ break;
+ case GL_NEAREST_MIPMAP_NEAREST:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_POINT;
+ break;
+ case GL_LINEAR_MIPMAP_NEAREST:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_POINT;
+ break;
+ case GL_NEAREST_MIPMAP_LINEAR:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_LINEAR;
+ break;
+ case GL_LINEAR_MIPMAP_LINEAR:
+ *d3dMinFilter = D3DTEXF_LINEAR;
+ *d3dMipFilter = D3DTEXF_LINEAR;
+ break;
+ default:
+ *d3dMinFilter = D3DTEXF_POINT;
+ *d3dMipFilter = D3DTEXF_NONE;
+ UNREACHABLE();
+ }
+
+ if (maxAnisotropy > 1.0f)
+ {
+ *d3dMinFilter = D3DTEXF_ANISOTROPIC;
+ }
+}
+
+D3DFORMAT ConvertRenderbufferFormat(GLenum format)
+{
+ switch (format)
+ {
+ case GL_NONE: return D3DFMT_NULL;
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
+ case GL_RGB565: return D3DFMT_R5G6B5;
+ case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
+ case GL_DEPTH_COMPONENT16:
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
+ default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
+ }
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
+{
+ if (samples <= 1)
+ return D3DMULTISAMPLE_NONE;
+ else
+ return (D3DMULTISAMPLE_TYPE)samples;
+}
+
+}
+
+namespace d3d9_gl
+{
+
+unsigned int GetStencilSize(D3DFORMAT stencilFormat)
+{
+ if (stencilFormat == D3DFMT_INTZ)
+ {
+ return 8;
+ }
+ switch(stencilFormat)
+ {
+ case D3DFMT_D24FS8:
+ case D3DFMT_D24S8:
+ return 8;
+ case D3DFMT_D24X4S4:
+ return 4;
+ case D3DFMT_D15S1:
+ return 1;
+ case D3DFMT_D16_LOCKABLE:
+ case D3DFMT_D32:
+ case D3DFMT_D24X8:
+ case D3DFMT_D32F_LOCKABLE:
+ case D3DFMT_D16:
+ return 0;
+ //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
+ //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
+ default:
+ return 0;
+ }
+}
+
+unsigned int GetAlphaSize(D3DFORMAT colorFormat)
+{
+ switch (colorFormat)
+ {
+ case D3DFMT_A16B16G16R16F:
+ return 16;
+ case D3DFMT_A32B32G32R32F:
+ return 32;
+ case D3DFMT_A2R10G10B10:
+ return 2;
+ case D3DFMT_A8R8G8B8:
+ return 8;
+ case D3DFMT_A1R5G5B5:
+ return 1;
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_R5G6B5:
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
+{
+ if (type == D3DMULTISAMPLE_NONMASKABLE)
+ return 0;
+ else
+ return type;
+}
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
+{
+ switch (d3dformat)
+ {
+ case D3DFMT_L8:
+ return (format == GL_LUMINANCE);
+ case D3DFMT_A8L8:
+ return (format == GL_LUMINANCE_ALPHA);
+ case D3DFMT_DXT1:
+ return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+ case D3DFMT_DXT3:
+ return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+ case D3DFMT_DXT5:
+ return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ return (format == GL_RGBA || format == GL_BGRA_EXT);
+ case D3DFMT_X8R8G8B8:
+ return (format == GL_RGB);
+ default:
+ if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format))
+ return true;
+ return false;
+ }
+}
+
+GLenum ConvertBackBufferFormat(D3DFORMAT format)
+{
+ switch (format)
+ {
+ case D3DFMT_A4R4G4B4: return GL_RGBA4;
+ case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+ case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+ case D3DFMT_R5G6B5: return GL_RGB565;
+ case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_RGBA4;
+}
+
+GLenum ConvertDepthStencilFormat(D3DFORMAT format)
+{
+ if (format == D3DFMT_INTZ)
+ {
+ return GL_DEPTH24_STENCIL8_OES;
+ }
+ switch (format)
+ {
+ case D3DFMT_D16:
+ case D3DFMT_D24X8:
+ return GL_DEPTH_COMPONENT16;
+ case D3DFMT_D24S8:
+ return GL_DEPTH24_STENCIL8_OES;
+ case D3DFMT_UNKNOWN:
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_DEPTH24_STENCIL8_OES;
+}
+
+GLenum ConvertRenderTargetFormat(D3DFORMAT format)
+{
+ if (format == D3DFMT_INTZ)
+ {
+ return GL_DEPTH24_STENCIL8_OES;
+ }
+
+ switch (format)
+ {
+ case D3DFMT_A4R4G4B4: return GL_RGBA4;
+ case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+ case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+ case D3DFMT_R5G6B5: return GL_RGB565;
+ case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+ case D3DFMT_D16:
+ case D3DFMT_D24X8:
+ return GL_DEPTH_COMPONENT16;
+ case D3DFMT_D24S8:
+ return GL_DEPTH24_STENCIL8_OES;
+ case D3DFMT_UNKNOWN:
+ return GL_NONE;
+ default:
+ UNREACHABLE();
+ }
+
+ return GL_RGBA4;
+}
+
+GLenum GetEquivalentFormat(D3DFORMAT format)
+{
+ if (format == D3DFMT_INTZ)
+ return GL_DEPTH24_STENCIL8_OES;
+ if (format == D3DFMT_NULL)
+ return GL_NONE;
+
+ switch (format)
+ {
+ case D3DFMT_A4R4G4B4: return GL_RGBA4;
+ case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+ case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+ case D3DFMT_R5G6B5: return GL_RGB565;
+ case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+ case D3DFMT_D16: return GL_DEPTH_COMPONENT16;
+ case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES;
+ case D3DFMT_UNKNOWN: return GL_NONE;
+ case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
+ case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
+ case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT;
+ case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT;
+ case D3DFMT_L8: return GL_LUMINANCE8_EXT;
+ case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT;
+ default: UNREACHABLE();
+ return GL_NONE;
+ }
+}
+
+}
+
+namespace d3d9
+{
+
+bool IsCompressedFormat(D3DFORMAT surfaceFormat)
+{
+ switch(surfaceFormat)
+ {
+ case D3DFMT_DXT1:
+ case D3DFMT_DXT2:
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT4:
+ case D3DFMT_DXT5:
+ return true;
+ default:
+ return false;
+ }
+}
+
+size_t ComputeRowSize(D3DFORMAT format, unsigned int width)
+{
+ if (format == D3DFMT_INTZ)
+ {
+ return 4 * width;
+ }
+ switch (format)
+ {
+ case D3DFMT_L8:
+ return 1 * width;
+ case D3DFMT_A8L8:
+ return 2 * width;
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A8R8G8B8:
+ return 4 * width;
+ case D3DFMT_A16B16G16R16F:
+ return 8 * width;
+ case D3DFMT_A32B32G32R32F:
+ return 16 * width;
+ case D3DFMT_DXT1:
+ return 8 * ((width + 3) / 4);
+ case D3DFMT_DXT3:
+ case D3DFMT_DXT5:
+ return 16 * ((width + 3) / 4);
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+}
+
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h
new file mode 100644
index 0000000000..bf6cdf1ea6
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h
@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer9_utils.h: Conversion functions and other utility routines
+// specific to the D3D9 renderer
+
+#ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+#define LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+
+#include "libGLESv2/utilities.h"
+
+const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
+const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison);
+D3DCOLOR ConvertColor(gl::Color color);
+D3DBLEND ConvertBlendFunc(GLenum blend);
+D3DBLENDOP ConvertBlendOp(GLenum blendOp);
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
+D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
+D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
+void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
+D3DFORMAT ConvertRenderbufferFormat(GLenum format);
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
+
+}
+
+namespace d3d9_gl
+{
+
+GLuint GetAlphaSize(D3DFORMAT colorFormat);
+GLuint GetStencilSize(D3DFORMAT stencilFormat);
+
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
+GLenum ConvertBackBufferFormat(D3DFORMAT format);
+GLenum ConvertDepthStencilFormat(D3DFORMAT format);
+GLenum ConvertRenderTargetFormat(D3DFORMAT format);
+GLenum GetEquivalentFormat(D3DFORMAT format);
+
+}
+
+namespace d3d9
+{
+bool IsCompressedFormat(D3DFORMAT format);
+size_t ComputeRowSize(D3DFORMAT format, unsigned int width);
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+ switch (errorCode)
+ {
+ case D3DERR_DRIVERINTERNALERROR:
+ case D3DERR_DEVICELOST:
+ case D3DERR_DEVICEHUNG:
+ case D3DERR_DEVICEREMOVED:
+ return true;
+ default:
+ return false;
+ }
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H
diff --git a/src/3rdparty/angle/src/libGLESv2/shaders/Blit.ps b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps
index dcb3bd0e76..dcb3bd0e76 100644
--- a/src/3rdparty/angle/src/libGLESv2/shaders/Blit.ps
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps
diff --git a/src/3rdparty/angle/src/libGLESv2/shaders/Blit.vs b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs
index 3a36980b93..3a36980b93 100644
--- a/src/3rdparty/angle/src/libGLESv2/shaders/Blit.vs
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
new file mode 100644
index 0000000000..d2752601e9
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl
@@ -0,0 +1,33 @@
+void VS_Clear( in float3 inPosition : POSITION, in float4 inColor : COLOR,
+ out float4 outPosition : SV_POSITION, out float4 outColor : COLOR)
+{
+ outPosition = float4(inPosition, 1.0f);
+ outColor = inColor;
+}
+
+// Assume we are in SM4+, which has 8 color outputs
+struct PS_Output
+{
+ float4 color0 : SV_TARGET0;
+ float4 color1 : SV_TARGET1;
+ float4 color2 : SV_TARGET2;
+ float4 color3 : SV_TARGET3;
+ float4 color4 : SV_TARGET4;
+ float4 color5 : SV_TARGET5;
+ float4 color6 : SV_TARGET6;
+ float4 color7 : SV_TARGET7;
+};
+
+PS_Output PS_Clear(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
+{
+ PS_Output outColor;
+ outColor.color0 = inColor;
+ outColor.color1 = inColor;
+ outColor.color2 = inColor;
+ outColor.color3 = inColor;
+ outColor.color4 = inColor;
+ outColor.color5 = inColor;
+ outColor.color6 = inColor;
+ outColor.color7 = inColor;
+ return outColor;
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
new file mode 100644
index 0000000000..43b7801efc
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
@@ -0,0 +1,29 @@
+Texture2D Texture : register(t0);
+SamplerState Sampler : register(s0);
+
+void VS_Passthrough( in float2 inPosition : POSITION, in float2 inTexCoord : TEXCOORD0,
+ out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0)
+{
+ outPosition = float4(inPosition, 0.0f, 1.0f);
+ outTexCoord = inTexCoord;
+}
+
+float4 PS_PassthroughRGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+ return Texture.Sample(Sampler, inTexCoord).rgba;
+}
+
+float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+ return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f);
+}
+
+float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+ return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f);
+}
+
+float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+ return Texture.Sample(Sampler, inTexCoord).rrra;
+}
diff --git a/src/3rdparty/angle/src/libGLESv2/vertexconversion.h b/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h
index 5bb8b8995e..590b9d48a3 100644
--- a/src/3rdparty/angle/src/libGLESv2/vertexconversion.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h
@@ -10,12 +10,7 @@
#ifndef LIBGLESV2_VERTEXCONVERSION_H_
#define LIBGLESV2_VERTEXCONVERSION_H_
-#include <cstddef>
-#include <limits>
-
-#include "libGLESv2/Context.h" // Defines Index
-
-namespace gl
+namespace rx
{
// Conversion types:
diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
index a3eb27d392..9809b9d8e8 100644
--- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp
@@ -1,5 +1,6 @@
+#include "precompiled.h"
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -7,21 +8,12 @@
// utilities.cpp: Conversion functions and other utility routines.
#include "libGLESv2/utilities.h"
-
-#include <limits>
-#include <stdio.h>
-#include <windows.h>
-
-#include "common/debug.h"
-
#include "libGLESv2/mathutil.h"
-#include "libGLESv2/Context.h"
namespace gl
{
-// This is how much data the application expects for a uniform
-int UniformExternalComponentCount(GLenum type)
+int UniformComponentCount(GLenum type)
{
switch (type)
{
@@ -55,42 +47,6 @@ int UniformExternalComponentCount(GLenum type)
return 0;
}
-// This is how much data we actually store for a uniform
-int UniformInternalComponentCount(GLenum type)
-{
- switch (type)
- {
- case GL_BOOL:
- case GL_INT:
- case GL_SAMPLER_2D:
- case GL_SAMPLER_CUBE:
- return 1;
- case GL_BOOL_VEC2:
- case GL_INT_VEC2:
- return 2;
- case GL_INT_VEC3:
- case GL_BOOL_VEC3:
- return 3;
- case GL_FLOAT:
- case GL_FLOAT_VEC2:
- case GL_FLOAT_VEC3:
- case GL_BOOL_VEC4:
- case GL_FLOAT_VEC4:
- case GL_INT_VEC4:
- return 4;
- case GL_FLOAT_MAT2:
- return 8;
- case GL_FLOAT_MAT3:
- return 12;
- case GL_FLOAT_MAT4:
- return 16;
- default:
- UNREACHABLE();
- }
-
- return 0;
-}
-
GLenum UniformComponentType(GLenum type)
{
switch(type)
@@ -137,12 +93,13 @@ size_t UniformComponentSize(GLenum type)
size_t UniformInternalSize(GLenum type)
{
- return UniformComponentSize(UniformComponentType(type)) * UniformInternalComponentCount(type);
+ // Expanded to 4-element vectors
+ return UniformComponentSize(UniformComponentType(type)) * VariableRowCount(type) * 4;
}
size_t UniformExternalSize(GLenum type)
{
- return UniformComponentSize(UniformComponentType(type)) * UniformExternalComponentCount(type);
+ return UniformComponentSize(UniformComponentType(type)) * UniformComponentCount(type);
}
int VariableRowCount(GLenum type)
@@ -163,6 +120,8 @@ int VariableRowCount(GLenum type)
case GL_BOOL_VEC4:
case GL_FLOAT_VEC4:
case GL_INT_VEC4:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
return 1;
case GL_FLOAT_MAT2:
return 2;
@@ -186,6 +145,8 @@ int VariableColumnCount(GLenum type)
case GL_BOOL:
case GL_FLOAT:
case GL_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
return 1;
case GL_BOOL_VEC2:
case GL_FLOAT_VEC2:
@@ -297,6 +258,27 @@ bool IsStencilTexture(GLenum format)
return false;
}
+void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset)
+{
+ int upsampleCount = 0;
+
+ if (isCompressed)
+ {
+ // Don't expand the size of full textures that are at least 4x4
+ // already.
+ if (isImage || *requestWidth < 4 || *requestHeight < 4)
+ {
+ while (*requestWidth % 4 != 0 || *requestHeight % 4 != 0)
+ {
+ *requestWidth <<= 1;
+ *requestHeight <<= 1;
+ upsampleCount++;
+ }
+ }
+ }
+ *levelOffset = upsampleCount;
+}
+
// Returns the size, in bytes, of a single texel in an Image
int ComputePixelSize(GLint internalformat)
{
@@ -510,6 +492,8 @@ bool IsColorRenderable(GLenum internalformat)
case GL_STENCIL_INDEX8:
case GL_DEPTH24_STENCIL8_OES:
return false;
+ case GL_BGRA8_EXT:
+ return true;
default:
UNIMPLEMENTED();
}
@@ -589,597 +573,141 @@ bool IsFloat16Format(GLint internalformat)
}
}
-}
-
-namespace es2dx
-{
-
-D3DCMPFUNC ConvertComparison(GLenum comparison)
-{
- D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
- switch (comparison)
- {
- case GL_NEVER: d3dComp = D3DCMP_NEVER; break;
- case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break;
- case GL_LESS: d3dComp = D3DCMP_LESS; break;
- case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break;
- case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break;
- case GL_GREATER: d3dComp = D3DCMP_GREATER; break;
- case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break;
- case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break;
- default: UNREACHABLE();
- }
-
- return d3dComp;
-}
-
-D3DCOLOR ConvertColor(gl::Color color)
-{
- return D3DCOLOR_RGBA(gl::unorm<8>(color.red),
- gl::unorm<8>(color.green),
- gl::unorm<8>(color.blue),
- gl::unorm<8>(color.alpha));
-}
-
-D3DBLEND ConvertBlendFunc(GLenum blend)
-{
- D3DBLEND d3dBlend = D3DBLEND_ZERO;
-
- switch (blend)
- {
- case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break;
- case GL_ONE: d3dBlend = D3DBLEND_ONE; break;
- case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break;
- case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break;
- case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break;
- case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break;
- case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break;
- case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break;
- case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break;
- case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break;
- case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break;
- case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
- case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break;
- case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
- case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break;
- default: UNREACHABLE();
- }
-
- return d3dBlend;
-}
-
-D3DBLENDOP ConvertBlendOp(GLenum blendOp)
-{
- D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
-
- switch (blendOp)
- {
- case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break;
- case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break;
- case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
- default: UNREACHABLE();
- }
-
- return d3dBlendOp;
-}
-
-D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
-{
- D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
-
- switch (stencilOp)
- {
- case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break;
- case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break;
- case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break;
- case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
- case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
- case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break;
- case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break;
- case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break;
- default: UNREACHABLE();
- }
-
- return d3dStencilOp;
-}
-
-D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
-{
- D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
-
- switch (wrap)
- {
- case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break;
- case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break;
- case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break;
- default: UNREACHABLE();
- }
-
- return d3dWrap;
-}
-
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
-{
- D3DCULL cull = D3DCULL_CCW;
- switch (cullFace)
- {
- case GL_FRONT:
- cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
- break;
- case GL_BACK:
- cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
- break;
- case GL_FRONT_AND_BACK:
- cull = D3DCULL_NONE; // culling will be handled during draw
- break;
- default: UNREACHABLE();
- }
-
- return cull;
-}
-
-D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
-{
- D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
-
- switch (cubeFace)
- {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- face = D3DCUBEMAP_FACE_POSITIVE_X;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- face = D3DCUBEMAP_FACE_NEGATIVE_X;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- face = D3DCUBEMAP_FACE_POSITIVE_Y;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- face = D3DCUBEMAP_FACE_NEGATIVE_Y;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- face = D3DCUBEMAP_FACE_POSITIVE_Z;
- break;
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- face = D3DCUBEMAP_FACE_NEGATIVE_Z;
- break;
- default: UNREACHABLE();
- }
-
- return face;
-}
-
-DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
-{
- return (red ? D3DCOLORWRITEENABLE_RED : 0) |
- (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
- (blue ? D3DCOLORWRITEENABLE_BLUE : 0) |
- (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
-}
-
-D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
-{
- if (maxAnisotropy > 1.0f)
- {
- return D3DTEXF_ANISOTROPIC;
- }
-
- D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
- switch (magFilter)
- {
- case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break;
- case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break;
- default: UNREACHABLE();
- }
-
- return d3dMagFilter;
-}
-
-void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
-{
- switch (minFilter)
- {
- case GL_NEAREST:
- *d3dMinFilter = D3DTEXF_POINT;
- *d3dMipFilter = D3DTEXF_NONE;
- break;
- case GL_LINEAR:
- *d3dMinFilter = D3DTEXF_LINEAR;
- *d3dMipFilter = D3DTEXF_NONE;
- break;
- case GL_NEAREST_MIPMAP_NEAREST:
- *d3dMinFilter = D3DTEXF_POINT;
- *d3dMipFilter = D3DTEXF_POINT;
- break;
- case GL_LINEAR_MIPMAP_NEAREST:
- *d3dMinFilter = D3DTEXF_LINEAR;
- *d3dMipFilter = D3DTEXF_POINT;
- break;
- case GL_NEAREST_MIPMAP_LINEAR:
- *d3dMinFilter = D3DTEXF_POINT;
- *d3dMipFilter = D3DTEXF_LINEAR;
- break;
- case GL_LINEAR_MIPMAP_LINEAR:
- *d3dMinFilter = D3DTEXF_LINEAR;
- *d3dMipFilter = D3DTEXF_LINEAR;
- break;
- default:
- *d3dMinFilter = D3DTEXF_POINT;
- *d3dMipFilter = D3DTEXF_NONE;
- UNREACHABLE();
- }
-
- if (maxAnisotropy > 1.0f)
- {
- *d3dMinFilter = D3DTEXF_ANISOTROPIC;
- }
-}
-
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
- D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
-{
- switch (primitiveType)
- {
- case GL_POINTS:
- *d3dPrimitiveType = D3DPT_POINTLIST;
- *d3dPrimitiveCount = elementCount;
- break;
- case GL_LINES:
- *d3dPrimitiveType = D3DPT_LINELIST;
- *d3dPrimitiveCount = elementCount / 2;
- break;
- case GL_LINE_LOOP:
- *d3dPrimitiveType = D3DPT_LINESTRIP;
- *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately
- break;
- case GL_LINE_STRIP:
- *d3dPrimitiveType = D3DPT_LINESTRIP;
- *d3dPrimitiveCount = elementCount - 1;
- break;
- case GL_TRIANGLES:
- *d3dPrimitiveType = D3DPT_TRIANGLELIST;
- *d3dPrimitiveCount = elementCount / 3;
- break;
- case GL_TRIANGLE_STRIP:
- *d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
- *d3dPrimitiveCount = elementCount - 2;
- break;
- case GL_TRIANGLE_FAN:
- *d3dPrimitiveType = D3DPT_TRIANGLEFAN;
- *d3dPrimitiveCount = elementCount - 2;
- break;
- default:
- return false;
- }
-
- return true;
-}
-
-D3DFORMAT ConvertRenderbufferFormat(GLenum format)
-{
- switch (format)
- {
- case GL_NONE: return D3DFMT_NULL;
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
- case GL_RGB565: return D3DFMT_R5G6B5;
- case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
- case GL_DEPTH_COMPONENT16:
- case GL_STENCIL_INDEX8:
- case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
- default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
- }
-}
-
-D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
-{
- if (samples <= 1)
- return D3DMULTISAMPLE_NONE;
- else
- return (D3DMULTISAMPLE_TYPE)samples;
-}
-
-}
-
-namespace dx2es
-{
-
-unsigned int GetStencilSize(D3DFORMAT stencilFormat)
-{
- if (stencilFormat == D3DFMT_INTZ)
- {
- return 8;
- }
- switch(stencilFormat)
- {
- case D3DFMT_D24FS8:
- case D3DFMT_D24S8:
- return 8;
- case D3DFMT_D24X4S4:
- return 4;
- case D3DFMT_D15S1:
- return 1;
- case D3DFMT_D16_LOCKABLE:
- case D3DFMT_D32:
- case D3DFMT_D24X8:
- case D3DFMT_D32F_LOCKABLE:
- case D3DFMT_D16:
- return 0;
- //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only
- //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only
- default:
- return 0;
- }
-}
-
-unsigned int GetAlphaSize(D3DFORMAT colorFormat)
+unsigned int GetAlphaSize(GLenum colorFormat)
{
switch (colorFormat)
{
- case D3DFMT_A16B16G16R16F:
+ case GL_RGBA16F_EXT:
return 16;
- case D3DFMT_A32B32G32R32F:
+ case GL_RGBA32F_EXT:
return 32;
- case D3DFMT_A2R10G10B10:
- return 2;
- case D3DFMT_A8R8G8B8:
+ case GL_RGBA4:
+ return 4;
+ case GL_RGBA8_OES:
+ case GL_BGRA8_EXT:
return 8;
- case D3DFMT_A1R5G5B5:
+ case GL_RGB5_A1:
return 1;
- case D3DFMT_X8R8G8B8:
- case D3DFMT_R5G6B5:
+ case GL_RGB8_OES:
+ case GL_RGB565:
+ case GL_RGB32F_EXT:
+ case GL_RGB16F_EXT:
return 0;
default:
return 0;
}
}
-unsigned int GetRedSize(D3DFORMAT colorFormat)
+unsigned int GetRedSize(GLenum colorFormat)
{
switch (colorFormat)
{
- case D3DFMT_A16B16G16R16F:
+ case GL_RGBA16F_EXT:
+ case GL_RGB16F_EXT:
return 16;
- case D3DFMT_A32B32G32R32F:
+ case GL_RGBA32F_EXT:
+ case GL_RGB32F_EXT:
return 32;
- case D3DFMT_A2R10G10B10:
- return 10;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
+ case GL_RGBA4:
+ return 4;
+ case GL_RGBA8_OES:
+ case GL_BGRA8_EXT:
+ case GL_RGB8_OES:
return 8;
- case D3DFMT_A1R5G5B5:
- case D3DFMT_R5G6B5:
+ case GL_RGB5_A1:
+ case GL_RGB565:
return 5;
default:
return 0;
}
}
-unsigned int GetGreenSize(D3DFORMAT colorFormat)
+unsigned int GetGreenSize(GLenum colorFormat)
{
switch (colorFormat)
{
- case D3DFMT_A16B16G16R16F:
+ case GL_RGBA16F_EXT:
+ case GL_RGB16F_EXT:
return 16;
- case D3DFMT_A32B32G32R32F:
+ case GL_RGBA32F_EXT:
+ case GL_RGB32F_EXT:
return 32;
- case D3DFMT_A2R10G10B10:
- return 10;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
+ case GL_RGBA4:
+ return 4;
+ case GL_RGBA8_OES:
+ case GL_BGRA8_EXT:
+ case GL_RGB8_OES:
return 8;
- case D3DFMT_A1R5G5B5:
+ case GL_RGB5_A1:
return 5;
- case D3DFMT_R5G6B5:
+ case GL_RGB565:
return 6;
default:
return 0;
}
}
-unsigned int GetBlueSize(D3DFORMAT colorFormat)
+unsigned int GetBlueSize(GLenum colorFormat)
{
switch (colorFormat)
{
- case D3DFMT_A16B16G16R16F:
+ case GL_RGBA16F_EXT:
+ case GL_RGB16F_EXT:
return 16;
- case D3DFMT_A32B32G32R32F:
+ case GL_RGBA32F_EXT:
+ case GL_RGB32F_EXT:
return 32;
- case D3DFMT_A2R10G10B10:
- return 10;
- case D3DFMT_A8R8G8B8:
- case D3DFMT_X8R8G8B8:
+ case GL_RGBA4:
+ return 4;
+ case GL_RGBA8_OES:
+ case GL_BGRA8_EXT:
+ case GL_RGB8_OES:
return 8;
- case D3DFMT_A1R5G5B5:
- case D3DFMT_R5G6B5:
+ case GL_RGB5_A1:
+ case GL_RGB565:
return 5;
default:
return 0;
}
}
-unsigned int GetDepthSize(D3DFORMAT depthFormat)
+unsigned int GetDepthSize(GLenum depthFormat)
{
- if (depthFormat == D3DFMT_INTZ)
- {
- return 24;
- }
switch (depthFormat)
{
- case D3DFMT_D16_LOCKABLE: return 16;
- case D3DFMT_D32: return 32;
- case D3DFMT_D15S1: return 15;
- case D3DFMT_D24S8: return 24;
- case D3DFMT_D24X8: return 24;
- case D3DFMT_D24X4S4: return 24;
- case D3DFMT_D16: return 16;
- case D3DFMT_D32F_LOCKABLE: return 32;
- case D3DFMT_D24FS8: return 24;
- //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
- //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
- default: return 0;
- }
-}
-
-GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
-{
- if (type == D3DMULTISAMPLE_NONMASKABLE)
- return 0;
- else
- return type;
-}
-
-bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
-{
- switch (d3dformat)
- {
- case D3DFMT_L8:
- return (format == GL_LUMINANCE);
- case D3DFMT_A8L8:
- return (format == GL_LUMINANCE_ALPHA);
- case D3DFMT_DXT1:
- return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
- case D3DFMT_DXT3:
- return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
- case D3DFMT_DXT5:
- return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
- case D3DFMT_A8R8G8B8:
- case D3DFMT_A16B16G16R16F:
- case D3DFMT_A32B32G32R32F:
- return (format == GL_RGBA || format == GL_BGRA_EXT);
- case D3DFMT_X8R8G8B8:
- return (format == GL_RGB);
- default:
- if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format))
- return true;
- return false;
- }
-}
-
-bool ConvertReadBufferFormat(D3DFORMAT d3dformat, GLenum *format, GLenum *type)
-{
- switch (d3dformat)
- {
- case D3DFMT_A8R8G8B8:
- *type = GL_UNSIGNED_BYTE;
- *format = GL_BGRA_EXT;
- break;
- case D3DFMT_X8R8G8B8:
- *type = GL_UNSIGNED_BYTE;
- *format = GL_RGB;
- break;
- case D3DFMT_R5G6B5:
- *type = GL_UNSIGNED_SHORT_5_6_5;
- *format = GL_RGB;
- break;
- case D3DFMT_A16B16G16R16F:
- *type = GL_HALF_FLOAT_OES;
- *format = GL_RGBA;
- break;
- case D3DFMT_A32B32G32R32F:
- *type = GL_FLOAT;
- *format = GL_RGBA;
- break;
- case D3DFMT_A4R4G4B4:
- *type = GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT;
- *format = GL_BGRA_EXT;
- break;
- case D3DFMT_A1R5G5B5:
- *type = GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT;
- *format = GL_BGRA_EXT;
- break;
- default:
- *type = GL_NONE;
- *format = GL_NONE;
- return false;
- }
- return true;
-}
-
-GLenum ConvertBackBufferFormat(D3DFORMAT format)
-{
- switch (format)
- {
- case D3DFMT_A4R4G4B4: return GL_RGBA4;
- case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
- case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
- case D3DFMT_R5G6B5: return GL_RGB565;
- case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
- default:
- UNREACHABLE();
+ case GL_DEPTH_COMPONENT16: return 16;
+ case GL_DEPTH_COMPONENT32_OES: return 32;
+ case GL_DEPTH24_STENCIL8_OES: return 24;
+ default: return 0;
}
-
- return GL_RGBA4;
}
-GLenum ConvertDepthStencilFormat(D3DFORMAT format)
+unsigned int GetStencilSize(GLenum stencilFormat)
{
- if (format == D3DFMT_INTZ)
+ switch (stencilFormat)
{
- return GL_DEPTH24_STENCIL8_OES;
+ case GL_DEPTH24_STENCIL8_OES: return 8;
+ default: return 0;
}
- switch (format)
- {
- case D3DFMT_D16:
- case D3DFMT_D24X8:
- return GL_DEPTH_COMPONENT16;
- case D3DFMT_D24S8:
- return GL_DEPTH24_STENCIL8_OES;
- default:
- UNREACHABLE();
- }
-
- return GL_DEPTH24_STENCIL8_OES;
}
-}
-
-namespace dx
-{
-
-bool IsCompressedFormat(D3DFORMAT surfaceFormat)
+bool IsTriangleMode(GLenum drawMode)
{
- switch(surfaceFormat)
+ switch (drawMode)
{
- case D3DFMT_DXT1:
- case D3DFMT_DXT2:
- case D3DFMT_DXT3:
- case D3DFMT_DXT4:
- case D3DFMT_DXT5:
+ case GL_TRIANGLES:
+ case GL_TRIANGLE_FAN:
+ case GL_TRIANGLE_STRIP:
return true;
- default:
+ case GL_POINTS:
+ case GL_LINES:
+ case GL_LINE_LOOP:
+ case GL_LINE_STRIP:
return false;
+ default: UNREACHABLE();
}
-}
-size_t ComputeRowSize(D3DFORMAT format, unsigned int width)
-{
- if (format == D3DFMT_INTZ)
- {
- return 4 * width;
- }
- switch (format)
- {
- case D3DFMT_L8:
- return 1 * width;
- case D3DFMT_A8L8:
- return 2 * width;
- case D3DFMT_X8R8G8B8:
- case D3DFMT_A8R8G8B8:
- return 4 * width;
- case D3DFMT_A16B16G16R16F:
- return 8 * width;
- case D3DFMT_A32B32G32R32F:
- return 16 * width;
- case D3DFMT_DXT1:
- return 8 * ((width + 3) / 4);
- case D3DFMT_DXT3:
- case D3DFMT_DXT5:
- return 16 * ((width + 3) / 4);
- default:
- UNREACHABLE();
- return 0;
- }
+ return false;
}
}
diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.h b/src/3rdparty/angle/src/libGLESv2/utilities.h
index 29ad207313..7a10767086 100644
--- a/src/3rdparty/angle/src/libGLESv2/utilities.h
+++ b/src/3rdparty/angle/src/libGLESv2/utilities.h
@@ -1,5 +1,5 @@
//
-// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
@@ -12,20 +12,15 @@
#define GL_APICALL
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
-#include <d3d9.h>
#include <string>
-const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
-const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
-
namespace gl
{
struct Color;
-int UniformExternalComponentCount(GLenum type);
-int UniformInternalComponentCount(GLenum type);
+int UniformComponentCount(GLenum type);
GLenum UniformComponentType(GLenum type);
size_t UniformInternalSize(GLenum type);
size_t UniformExternalSize(GLenum type);
@@ -34,6 +29,7 @@ int VariableColumnCount(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
+void MakeValidSize(bool isImage, bool isCompressed, GLsizei *requestWidth, GLsizei *requestHeight, int *levelOffset);
int ComputePixelSize(GLint internalformat);
GLsizei ComputePitch(GLsizei width, GLint internalformat, GLint alignment);
GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
@@ -53,69 +49,18 @@ bool IsStencilRenderable(GLenum internalformat);
bool IsFloat32Format(GLint internalformat);
bool IsFloat16Format(GLint internalformat);
-}
-
-namespace es2dx
-{
-
-D3DCMPFUNC ConvertComparison(GLenum comparison);
-D3DCOLOR ConvertColor(gl::Color color);
-D3DBLEND ConvertBlendFunc(GLenum blend);
-D3DBLENDOP ConvertBlendOp(GLenum blendOp);
-D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
-D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
-D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
-D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
-DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
-D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
-void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
- D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
-D3DFORMAT ConvertRenderbufferFormat(GLenum format);
-D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
-
-}
-
-namespace dx2es
-{
-
-GLuint GetAlphaSize(D3DFORMAT colorFormat);
-GLuint GetRedSize(D3DFORMAT colorFormat);
-GLuint GetGreenSize(D3DFORMAT colorFormat);
-GLuint GetBlueSize(D3DFORMAT colorFormat);
-GLuint GetDepthSize(D3DFORMAT depthFormat);
-GLuint GetStencilSize(D3DFORMAT stencilFormat);
-
-GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
-
-bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
-bool ConvertReadBufferFormat(D3DFORMAT d3dformat, GLenum *format, GLenum *type);
-GLenum ConvertBackBufferFormat(D3DFORMAT format);
-GLenum ConvertDepthStencilFormat(D3DFORMAT format);
-}
+GLuint GetAlphaSize(GLenum colorFormat);
+GLuint GetRedSize(GLenum colorFormat);
+GLuint GetGreenSize(GLenum colorFormat);
+GLuint GetBlueSize(GLenum colorFormat);
+GLuint GetDepthSize(GLenum depthFormat);
+GLuint GetStencilSize(GLenum stencilFormat);
+bool IsTriangleMode(GLenum drawMode);
-namespace dx
-{
-bool IsCompressedFormat(D3DFORMAT format);
-size_t ComputeRowSize(D3DFORMAT format, unsigned int width);
}
std::string getTempPath();
void writeFile(const char* path, const void* data, size_t size);
-inline bool isDeviceLostError(HRESULT errorCode)
-{
- switch (errorCode)
- {
- case D3DERR_DRIVERINTERNALERROR:
- case D3DERR_DEVICELOST:
- case D3DERR_DEVICEHUNG:
- case D3DERR_DEVICEREMOVED:
- return true;
- default:
- return false;
- }
-};
-
#endif // LIBGLESV2_UTILITIES_H
diff --git a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp
new file mode 100644
index 0000000000..288f5529ad
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "third_party/compiler/ArrayBoundsClamper.h"
+
+// The built-in 'clamp' instruction only accepts floats and returns a float. I
+// iterated a few times with our driver team who examined the output from our
+// compiler - they said the multiple casts generates more code than a single
+// function call. An inline ternary operator might have been better, but since
+// the index value might be an expression itself, we'd have to make temporary
+// variables to avoid evaluating the expression multiple times. And making
+// temporary variables was difficult because ANGLE would then need to make more
+// brutal changes to the expression tree.
+
+const char* kIntClampBegin = "// BEGIN: Generated code for array bounds clamping\n\n";
+const char* kIntClampEnd = "// END: Generated code for array bounds clamping\n\n";
+const char* kIntClampDefinition = "int webgl_int_clamp(int value, int minValue, int maxValue) { return ((value < minValue) ? minValue : ((value > maxValue) ? maxValue : value)); }\n\n";
+
+namespace {
+
+class ArrayBoundsClamperMarker : public TIntermTraverser {
+public:
+ ArrayBoundsClamperMarker()
+ : mNeedsClamp(false)
+ {
+ }
+
+ virtual bool visitBinary(Visit visit, TIntermBinary* node)
+ {
+ if (node->getOp() == EOpIndexIndirect)
+ {
+ TIntermTyped* left = node->getLeft();
+ if (left->isArray() || left->isVector() || left->isMatrix())
+ {
+ node->setAddIndexClamp();
+ mNeedsClamp = true;
+ }
+ }
+ return true;
+ }
+
+ bool GetNeedsClamp() { return mNeedsClamp; }
+
+private:
+ bool mNeedsClamp;
+};
+
+} // anonymous namespace
+
+ArrayBoundsClamper::ArrayBoundsClamper()
+ : mClampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC)
+ , mArrayBoundsClampDefinitionNeeded(false)
+{
+}
+
+void ArrayBoundsClamper::SetClampingStrategy(ShArrayIndexClampingStrategy clampingStrategy)
+{
+ mClampingStrategy = clampingStrategy;
+}
+
+void ArrayBoundsClamper::MarkIndirectArrayBoundsForClamping(TIntermNode* root)
+{
+ ASSERT(root);
+
+ ArrayBoundsClamperMarker clamper;
+ root->traverse(&clamper);
+ if (clamper.GetNeedsClamp())
+ {
+ SetArrayBoundsClampDefinitionNeeded();
+ }
+}
+
+void ArrayBoundsClamper::OutputClampingFunctionDefinition(TInfoSinkBase& out) const
+{
+ if (!mArrayBoundsClampDefinitionNeeded)
+ {
+ return;
+ }
+ if (mClampingStrategy != SH_CLAMP_WITH_USER_DEFINED_INT_CLAMP_FUNCTION)
+ {
+ return;
+ }
+ out << kIntClampBegin << kIntClampDefinition << kIntClampEnd;
+}
diff --git a/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h
new file mode 100644
index 0000000000..0d4e1a374c
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/compiler/ArrayBoundsClamper.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
+#define THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include "compiler/InfoSink.h"
+#include "compiler/intermediate.h"
+
+class ArrayBoundsClamper {
+public:
+ ArrayBoundsClamper();
+
+ // Must be set before compiling any shaders to ensure consistency
+ // between the translated shaders and any necessary prequel.
+ void SetClampingStrategy(ShArrayIndexClampingStrategy clampingStrategy);
+
+ // Marks nodes in the tree that index arrays indirectly as
+ // requiring clamping.
+ void MarkIndirectArrayBoundsForClamping(TIntermNode* root);
+
+ // If necessary, output array clamp function source into the shader source.
+ void OutputClampingFunctionDefinition(TInfoSinkBase& out) const;
+
+ void Cleanup()
+ {
+ mArrayBoundsClampDefinitionNeeded = false;
+ }
+
+private:
+ bool GetArrayBoundsClampDefinitionNeeded() const { return mArrayBoundsClampDefinitionNeeded; }
+ void SetArrayBoundsClampDefinitionNeeded() { mArrayBoundsClampDefinitionNeeded = true; }
+
+ ShArrayIndexClampingStrategy mClampingStrategy;
+ bool mArrayBoundsClampDefinitionNeeded;
+};
+
+#endif // THIRD_PARTY_COMPILER_ARRAY_BOUNDS_CLAMPER_H_
diff --git a/src/3rdparty/angle/src/third_party/compiler/LICENSE b/src/3rdparty/angle/src/third_party/compiler/LICENSE
new file mode 100644
index 0000000000..c2cb2125e9
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/compiler/LICENSE
@@ -0,0 +1,22 @@
+Copyright (C) 2012 Apple Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY APPLE, INC. ``AS IS'' AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, INC. OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/3rdparty/angle/src/third_party/compiler/README.angle b/src/3rdparty/angle/src/third_party/compiler/README.angle
new file mode 100644
index 0000000000..4fdf757ef4
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/compiler/README.angle
@@ -0,0 +1,12 @@
+Name: ANGLE array bounds clamper from WebKit
+Short Name: WebKit
+URL: http://webkit.org
+Version: 0
+License: BSD
+Security Critical: yes
+
+Description:
+Implements clamping of array indexing expressions during shader translation.
+
+Local Modifications:
+None
diff --git a/src/3rdparty/angle/src/third_party/murmurhash/LICENSE b/src/3rdparty/angle/src/third_party/murmurhash/LICENSE
new file mode 100644
index 0000000000..6a385f0f07
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/murmurhash/LICENSE
@@ -0,0 +1,2 @@
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code. \ No newline at end of file
diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp
new file mode 100644
index 0000000000..dd86292649
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.cpp
@@ -0,0 +1,334 @@
+//-----------------------------------------------------------------------------
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+// Note - The x86 and x64 versions do _not_ produce the same results, as the
+// algorithms are optimized for their respective platforms. You can still
+// compile and run any of them on any platform, but your performance with the
+// non-native version will be less than optimal.
+
+#include "MurmurHash3.h"
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER)
+
+#define FORCE_INLINE __forceinline
+
+#include <stdlib.h>
+
+#define ROTL32(x,y) _rotl(x,y)
+#define ROTL64(x,y) _rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x)
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#define FORCE_INLINE __attribute__((always_inline))
+
+inline uint32_t rotl32 ( uint32_t x, int8_t r )
+{
+ return (x << r) | (x >> (32 - r));
+}
+
+inline uint64_t rotl64 ( uint64_t x, int8_t r )
+{
+ return (x << r) | (x >> (64 - r));
+}
+
+#define ROTL32(x,y) rotl32(x,y)
+#define ROTL64(x,y) rotl64(x,y)
+
+#define BIG_CONSTANT(x) (x##LLU)
+
+#endif // !defined(_MSC_VER)
+
+//-----------------------------------------------------------------------------
+// Block read - if your platform needs to do endian-swapping or can only
+// handle aligned reads, do the conversion here
+
+FORCE_INLINE uint32_t getblock ( const uint32_t * p, int i )
+{
+ return p[i];
+}
+
+FORCE_INLINE uint64_t getblock ( const uint64_t * p, int i )
+{
+ return p[i];
+}
+
+//-----------------------------------------------------------------------------
+// Finalization mix - force all bits of a hash block to avalanche
+
+FORCE_INLINE uint32_t fmix ( uint32_t h )
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+
+ return h;
+}
+
+//----------
+
+FORCE_INLINE uint64_t fmix ( uint64_t k )
+{
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xff51afd7ed558ccd);
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
+ k ^= k >> 33;
+
+ return k;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_32 ( const void * key, int len,
+ uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 4;
+
+ uint32_t h1 = seed;
+
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
+
+ //----------
+ // body
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
+
+ for(int i = -nblocks; i; i++)
+ {
+ uint32_t k1 = getblock(blocks,i);
+
+ k1 *= c1;
+ k1 = ROTL32(k1,15);
+ k1 *= c2;
+
+ h1 ^= k1;
+ h1 = ROTL32(h1,13);
+ h1 = h1*5+0xe6546b64;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*4);
+
+ uint32_t k1 = 0;
+
+ switch(len & 3)
+ {
+ case 3: k1 ^= tail[2] << 16;
+ case 2: k1 ^= tail[1] << 8;
+ case 1: k1 ^= tail[0];
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len;
+
+ h1 = fmix(h1);
+
+ *(uint32_t*)out = h1;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_128 ( const void * key, const int len,
+ uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 16;
+
+ uint32_t h1 = seed;
+ uint32_t h2 = seed;
+ uint32_t h3 = seed;
+ uint32_t h4 = seed;
+
+ const uint32_t c1 = 0x239b961b;
+ const uint32_t c2 = 0xab0e9789;
+ const uint32_t c3 = 0x38b34ae5;
+ const uint32_t c4 = 0xa1e38b93;
+
+ //----------
+ // body
+
+ const uint32_t * blocks = (const uint32_t *)(data + nblocks*16);
+
+ for(int i = -nblocks; i; i++)
+ {
+ uint32_t k1 = getblock(blocks,i*4+0);
+ uint32_t k2 = getblock(blocks,i*4+1);
+ uint32_t k3 = getblock(blocks,i*4+2);
+ uint32_t k4 = getblock(blocks,i*4+3);
+
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+
+ h1 = ROTL32(h1,19); h1 += h2; h1 = h1*5+0x561ccd1b;
+
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
+
+ h2 = ROTL32(h2,17); h2 += h3; h2 = h2*5+0x0bcaa747;
+
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
+
+ h3 = ROTL32(h3,15); h3 += h4; h3 = h3*5+0x96cd1c35;
+
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
+
+ h4 = ROTL32(h4,13); h4 += h1; h4 = h4*5+0x32ac3b17;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
+
+ uint32_t k1 = 0;
+ uint32_t k2 = 0;
+ uint32_t k3 = 0;
+ uint32_t k4 = 0;
+
+ switch(len & 15)
+ {
+ case 15: k4 ^= tail[14] << 16;
+ case 14: k4 ^= tail[13] << 8;
+ case 13: k4 ^= tail[12] << 0;
+ k4 *= c4; k4 = ROTL32(k4,18); k4 *= c1; h4 ^= k4;
+
+ case 12: k3 ^= tail[11] << 24;
+ case 11: k3 ^= tail[10] << 16;
+ case 10: k3 ^= tail[ 9] << 8;
+ case 9: k3 ^= tail[ 8] << 0;
+ k3 *= c3; k3 = ROTL32(k3,17); k3 *= c4; h3 ^= k3;
+
+ case 8: k2 ^= tail[ 7] << 24;
+ case 7: k2 ^= tail[ 6] << 16;
+ case 6: k2 ^= tail[ 5] << 8;
+ case 5: k2 ^= tail[ 4] << 0;
+ k2 *= c2; k2 = ROTL32(k2,16); k2 *= c3; h2 ^= k2;
+
+ case 4: k1 ^= tail[ 3] << 24;
+ case 3: k1 ^= tail[ 2] << 16;
+ case 2: k1 ^= tail[ 1] << 8;
+ case 1: k1 ^= tail[ 0] << 0;
+ k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
+
+ h1 += h2; h1 += h3; h1 += h4;
+ h2 += h1; h3 += h1; h4 += h1;
+
+ h1 = fmix(h1);
+ h2 = fmix(h2);
+ h3 = fmix(h3);
+ h4 = fmix(h4);
+
+ h1 += h2; h1 += h3; h1 += h4;
+ h2 += h1; h3 += h1; h4 += h1;
+
+ ((uint32_t*)out)[0] = h1;
+ ((uint32_t*)out)[1] = h2;
+ ((uint32_t*)out)[2] = h3;
+ ((uint32_t*)out)[3] = h4;
+}
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x64_128 ( const void * key, const int len,
+ const uint32_t seed, void * out )
+{
+ const uint8_t * data = (const uint8_t*)key;
+ const int nblocks = len / 16;
+
+ uint64_t h1 = seed;
+ uint64_t h2 = seed;
+
+ const uint64_t c1 = BIG_CONSTANT(0x87c37b91114253d5);
+ const uint64_t c2 = BIG_CONSTANT(0x4cf5ad432745937f);
+
+ //----------
+ // body
+
+ const uint64_t * blocks = (const uint64_t *)(data);
+
+ for(int i = 0; i < nblocks; i++)
+ {
+ uint64_t k1 = getblock(blocks,i*2+0);
+ uint64_t k2 = getblock(blocks,i*2+1);
+
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
+
+ h1 = ROTL64(h1,27); h1 += h2; h1 = h1*5+0x52dce729;
+
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
+
+ h2 = ROTL64(h2,31); h2 += h1; h2 = h2*5+0x38495ab5;
+ }
+
+ //----------
+ // tail
+
+ const uint8_t * tail = (const uint8_t*)(data + nblocks*16);
+
+ uint64_t k1 = 0;
+ uint64_t k2 = 0;
+
+ switch(len & 15)
+ {
+ case 15: k2 ^= uint64_t(tail[14]) << 48;
+ case 14: k2 ^= uint64_t(tail[13]) << 40;
+ case 13: k2 ^= uint64_t(tail[12]) << 32;
+ case 12: k2 ^= uint64_t(tail[11]) << 24;
+ case 11: k2 ^= uint64_t(tail[10]) << 16;
+ case 10: k2 ^= uint64_t(tail[ 9]) << 8;
+ case 9: k2 ^= uint64_t(tail[ 8]) << 0;
+ k2 *= c2; k2 = ROTL64(k2,33); k2 *= c1; h2 ^= k2;
+
+ case 8: k1 ^= uint64_t(tail[ 7]) << 56;
+ case 7: k1 ^= uint64_t(tail[ 6]) << 48;
+ case 6: k1 ^= uint64_t(tail[ 5]) << 40;
+ case 5: k1 ^= uint64_t(tail[ 4]) << 32;
+ case 4: k1 ^= uint64_t(tail[ 3]) << 24;
+ case 3: k1 ^= uint64_t(tail[ 2]) << 16;
+ case 2: k1 ^= uint64_t(tail[ 1]) << 8;
+ case 1: k1 ^= uint64_t(tail[ 0]) << 0;
+ k1 *= c1; k1 = ROTL64(k1,31); k1 *= c2; h1 ^= k1;
+ };
+
+ //----------
+ // finalization
+
+ h1 ^= len; h2 ^= len;
+
+ h1 += h2;
+ h2 += h1;
+
+ h1 = fmix(h1);
+ h2 = fmix(h2);
+
+ h1 += h2;
+ h2 += h1;
+
+ ((uint64_t*)out)[0] = h1;
+ ((uint64_t*)out)[1] = h2;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h
new file mode 100644
index 0000000000..c08f4f2585
--- /dev/null
+++ b/src/3rdparty/angle/src/third_party/murmurhash/MurmurHash3.h
@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// MurmurHash3 was written by Austin Appleby, and is placed in the public
+// domain. The author hereby disclaims copyright to this source code.
+
+#ifndef _MURMURHASH3_H_
+#define _MURMURHASH3_H_
+
+//-----------------------------------------------------------------------------
+// Platform-specific functions and macros
+
+// Microsoft Visual Studio
+
+#if defined(_MSC_VER)
+
+typedef unsigned char uint8_t;
+typedef unsigned long uint32_t;
+typedef unsigned __int64 uint64_t;
+
+// Other compilers
+
+#else // defined(_MSC_VER)
+
+#include <stdint.h>
+
+#endif // !defined(_MSC_VER)
+
+//-----------------------------------------------------------------------------
+
+void MurmurHash3_x86_32 ( const void * key, int len, uint32_t seed, void * out );
+
+void MurmurHash3_x86_128 ( const void * key, int len, uint32_t seed, void * out );
+
+void MurmurHash3_x64_128 ( const void * key, int len, uint32_t seed, void * out );
+
+//-----------------------------------------------------------------------------
+
+#endif // _MURMURHASH3_H_ \ No newline at end of file
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index b6e6e3397e..dedfc9d417 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -43,6 +43,7 @@
package org.qtproject.qt5.android;
import java.io.File;
+import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@@ -368,6 +369,11 @@ public class QtActivityDelegate
return true;
}
+ public void debugLog(String msg)
+ {
+ Log.i(QtNative.QtTAG, "DEBUGGER: " + msg);
+ }
+
public boolean startApplication()
{
// start application
@@ -414,25 +420,111 @@ public class QtActivityDelegate
&&*/ extras != null
&& extras.containsKey("debug_ping")
&& extras.getString("debug_ping").equals("true")) {
- String packagePath =
- m_activity.getPackageManager().getApplicationInfo(m_activity.getPackageName(),
- PackageManager.GET_CONFIGURATIONS).dataDir + "/";
- String debugPing = packagePath + "debug_ping";
- int i = 0;
- while (true) {
- ++i;
- Log.i(QtNative.QtTAG, "DEBUGGER: WAITING FOR PING AT " + debugPing + ", ATTEMPT " + i);
- File file = new File(debugPing);
- if (file.exists()) {
- file.delete();
- break;
+ try {
+ debugLog("extra parameters: " + extras);
+ String packageName = m_activity.getPackageName();
+ String pingFile = extras.getString("ping_file");
+ String pongFile = extras.getString("pong_file");
+ String gdbserverSocket = extras.getString("gdbserver_socket");
+ String gdbserverCommand = extras.getString("gdbserver_command");
+ boolean usePing = pingFile != null;
+ boolean usePong = pongFile != null;
+ boolean useSocket = gdbserverSocket != null;
+ int napTime = 200; // milliseconds between file accesses
+ int timeOut = 30000; // ms until we give up on ping and pong
+ int maxAttempts = timeOut / napTime;
+
+ if (usePing) {
+ debugLog("removing ping file " + pingFile);
+ File ping = new File(pingFile);
+ if (ping.exists()) {
+ if (!ping.delete())
+ debugLog("ping file cannot be deleted");
}
- Thread.sleep(1000);
}
- Log.i(QtNative.QtTAG, "DEBUGGER: GOT PING " + debugPing);
- }
+ if (usePong) {
+ debugLog("removing pong file " + pongFile);
+ File pong = new File(pongFile);
+ if (pong.exists()) {
+ if (!pong.delete())
+ debugLog("pong file cannot be deleted");
+ }
+ }
+
+ debugLog("starting " + gdbserverCommand);
+ m_debuggerProcess = Runtime.getRuntime().exec(gdbserverCommand);
+ debugLog("gdbserver started");
+
+ if (useSocket) {
+ int i;
+ for (i = 0; i < maxAttempts; ++i) {
+ debugLog("waiting for socket at " + gdbserverSocket + ", attempt " + i);
+ File file = new File(gdbserverSocket);
+ if (file.exists()) {
+ file.setReadable(true, false);
+ file.setWritable(true, false);
+ file.setExecutable(true, false);
+ break;
+ }
+ Thread.sleep(napTime);
+ }
+
+ if (i == maxAttempts) {
+ debugLog("time out when waiting for socket");
+ return false;
+ }
+
+ debugLog("socket ok");
+ } else {
+ debugLog("socket not used");
+ }
+
+ if (usePing) {
+ // Tell we are ready.
+ debugLog("writing ping at " + pingFile);
+ FileWriter writer = new FileWriter(pingFile);
+ writer.write("" + android.os.Process.myPid());
+ writer.close();
+ File file = new File(pingFile);
+ file.setReadable(true, false);
+ file.setWritable(true, false);
+ file.setExecutable(true, false);
+ debugLog("wrote ping");
+ } else {
+ debugLog("ping not requested");
+ }
+
+ // Wait until other side is ready.
+ if (usePong) {
+ int i;
+ for (i = 0; i < maxAttempts; ++i) {
+ debugLog("waiting for pong at " + pongFile + ", attempt " + i);
+ File file = new File(pongFile);
+ if (file.exists()) {
+ file.delete();
+ break;
+ }
+ debugLog("go to sleep");
+ Thread.sleep(napTime);
+ }
+
+ if (i == maxAttempts) {
+ debugLog("time out when waiting for pong file");
+ return false;
+ }
+ debugLog("got pong " + pongFile);
+ } else {
+ debugLog("pong not requested");
+ }
+
+ } catch (IOException ioe) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + ioe.getMessage());
+ } catch (SecurityException se) {
+ Log.e(QtNative.QtTAG,"Can't start debugger" + se.getMessage());
+ }
+ }
if (/*(ai.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0
&&*/ extras != null
@@ -476,7 +568,7 @@ public class QtActivityDelegate
m_activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels, metrics.heightPixels,
metrics.widthPixels, metrics.heightPixels,
- metrics.xdpi, metrics.ydpi);
+ metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
}
m_layout = new QtLayout(m_activity);
m_surface = new QtSurface(m_activity, 0);
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
index 7cb3fdff45..4586ae2002 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
@@ -72,6 +72,7 @@ public class QtNative
private static int m_displayMetricsDesktopHeightPixels = 0;
private static double m_displayMetricsXDpi = .0;
private static double m_displayMetricsYDpi = .0;
+ private static double m_displayMetricsScaledDensity = 1.0;
private static int m_oldx, m_oldy;
private static final int m_moveThreshold = 0;
private static ClipboardManager m_clipboardManager = null;
@@ -195,7 +196,8 @@ public class QtNative
m_displayMetricsDesktopWidthPixels,
m_displayMetricsDesktopHeightPixels,
m_displayMetricsXDpi,
- m_displayMetricsYDpi);
+ m_displayMetricsYDpi,
+ m_displayMetricsScaledDensity);
if (params.length() > 0)
params = "\t" + params;
startQtApplication(f.getAbsolutePath() + "\t" + params, environment);
@@ -209,7 +211,8 @@ public class QtNative
int desktopWidthPixels,
int desktopHeightPixels,
double XDpi,
- double YDpi)
+ double YDpi,
+ double scaledDensity)
{
/* Fix buggy dpi report */
if (XDpi < android.util.DisplayMetrics.DENSITY_LOW)
@@ -224,7 +227,8 @@ public class QtNative
desktopWidthPixels,
desktopHeightPixels,
XDpi,
- YDpi);
+ YDpi,
+ scaledDensity);
} else {
m_displayMetricsScreenWidthPixels = screenWidthPixels;
m_displayMetricsScreenHeightPixels = screenHeightPixels;
@@ -232,6 +236,7 @@ public class QtNative
m_displayMetricsDesktopHeightPixels = desktopHeightPixels;
m_displayMetricsXDpi = XDpi;
m_displayMetricsYDpi = YDpi;
+ m_displayMetricsScaledDensity = scaledDensity;
}
}
}
@@ -535,7 +540,8 @@ public class QtNative
int desktopWidthPixels,
int desktopHeightPixels,
double XDpi,
- double YDpi);
+ double YDpi,
+ double scaledDensity);
public static native void handleOrientationChanged(int newOrientation);
// screen methods
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index 77126ec1c8..b994a43ac4 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -103,7 +103,7 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
DisplayMetrics metrics = new DisplayMetrics();
((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(metrics);
QtNative.setApplicationDisplayMetrics(metrics.widthPixels,
- metrics.heightPixels, getWidth(), getHeight(), metrics.xdpi, metrics.ydpi);
+ metrics.heightPixels, getWidth(), getHeight(), metrics.xdpi, metrics.ydpi, metrics.scaledDensity);
if (m_usesGL)
holder.setFormat(PixelFormat.RGBA_8888);
@@ -136,7 +136,8 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
width,
height,
metrics.xdpi,
- metrics.ydpi);
+ metrics.ydpi,
+ metrics.scaledDensity);
if (!m_started)
return;
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 1161b15e8d..6a407dcb6e 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -6,6 +6,8 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
+ <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
+ <meta-data android:name="android.app.repository" android:value="@string/repository"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<meta-data android:name="android.app.lib_name" android:value=""/>
diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml
index 92ce09b7c0..f47174e3d3 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/java/res/values/libs.xml
@@ -1,8 +1,11 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
+ <array name="qt_sources">
+ <item>https://files.kde.org/necessitas/ministro/android/necessitas/qt5/latest</item>
+ </array>
+ <string name="repository">default</string>
<array name="qt_libs">
- <item>QtCore</item>
- <item>QtGui</item>
+ <item>Qt5Core</item>
</array>
<array name="bundled_libs"/>
</resources>
diff --git a/src/android/java/src/org/kde/necessitas/ministro/IMinistro.aidl b/src/android/java/src/org/kde/necessitas/ministro/IMinistro.aidl
index 1c33a77fdb..236a62f63e 100644
--- a/src/android/java/src/org/kde/necessitas/ministro/IMinistro.aidl
+++ b/src/android/java/src/org/kde/necessitas/ministro/IMinistro.aidl
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2011-2013, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt-project.org/legal
Redistribution and use in source and binary forms, with or without
@@ -24,6 +24,7 @@
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
package org.kde.necessitas.ministro;
import org.kde.necessitas.ministro.IMinistroCallback;
@@ -37,13 +38,13 @@ interface IMinistro
* param parameters
* parameters fields:
* * Key Name Key type Explanations
+* "sources" StringArray Sources list from where Ministro will download the libs. Make sure you are using ONLY secure locations.
+* "repository" String Overwrites the default Ministro repository. Possible values: default, stable, testing and unstable
* "required.modules" StringArray Required modules by your application
* "application.title" String Application name, used to show more informations to user
* "qt.provider" String Qt libs provider, currently only "necessitas" is supported.
-* "minimum.ministro.api" Integer Minimum Ministro API level, used to check if Ministro service compatible with your application. Current API Level is 1 !
-* "minimum.qt.version" Integer Minimim Qt version (e.g. 0x040800, which means Qt 4.8.0, check http://doc.trolltech.com/4.8/qtglobal.html#QT_VERSION)!
-* "3rd.party.repositories" StringArray 3rd party repositories, which should be downloaded by ministro, needs minimum.ministro.api >= 2
-* Check http://community.kde.org/Necessitas/Ministro for more details.
+* "minimum.ministro.api" Integer Minimum Ministro API level, used to check if Ministro service compatible with your application. Current API Level is 3 !
+* "minimum.qt.version" Integer Minimim Qt version (e.g. 0x040800, which means Qt 4.8.0, check http://qt-project.org/doc/qt-4.8/qtglobal.html#QT_VERSION)!
*/
void requestLoader(in IMinistroCallback callback, in Bundle parameters);
}
diff --git a/src/android/java/src/org/kde/necessitas/ministro/IMinistroCallback.aidl b/src/android/java/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
index eec270aec1..0bcb5285b8 100644
--- a/src/android/java/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
+++ b/src/android/java/src/org/kde/necessitas/ministro/IMinistroCallback.aidl
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2011-2013, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt-project.org/legal
Redistribution and use in source and binary forms, with or without
@@ -45,8 +45,10 @@ oneway interface IMinistroCallback {
* - 1 incompatible Ministro version. Ministro needs to be upgraded.
* - 2 not all modules could be satisfy.
* - 3 invalid parameters
+* - 4 invalid qt version
+* - 5 download canceled
*
-* This parameter will contain additional fields which are used by the loader to start your application, so it must be passed to loader.
+* The parameter contains additional fields which are used by the loader to start your application, so it must be passed to the loader.
*/
void loaderReady(in Bundle loaderParams);
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index 4b01d29143..dfb638fbb0 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2012-2013, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt-project.org/legal
Redistribution and use in source and binary forms, with or without
@@ -76,9 +76,8 @@ import android.view.ActionMode.Callback;
public class QtActivity extends Activity
{
private final static int MINISTRO_INSTALL_REQUEST_CODE = 0xf3ee; // request code used to know when Ministro instalation is finished
- private static final int MINISTRO_API_LEVEL = 2; // Ministro api level (check IMinistro.aidl file)
+ private static final int MINISTRO_API_LEVEL = 3; // Ministro api level (check IMinistro.aidl file)
private static final int NECESSITAS_API_LEVEL = 2; // Necessitas api level used by platform plugin
- private static final String QT_PROVIDER = "necessitas";
private static final int QT_VERSION = 0x050100; // This app requires at least Qt version 5.1.0
private static final String ERROR_CODE_KEY = "error.code";
@@ -97,30 +96,44 @@ public class QtActivity extends Activity
/// Ministro server parameter keys
private static final String REQUIRED_MODULES_KEY = "required.modules";
private static final String APPLICATION_TITLE_KEY = "application.title";
- private static final String QT_PROVIDER_KEY = "qt.provider";
private static final String MINIMUM_MINISTRO_API_KEY = "minimum.ministro.api";
private static final String MINIMUM_QT_VERSION_KEY = "minimum.qt.version";
-// private static final String REPOSITORIES="3rd.party.repositories"; // needs MINISTRO_API_LEVEL >=2 !!!
- // Use this key to specify any 3rd party repositories urls
- // Ministro will download these repositories into thier
+ private static final String SOURCES_KEY = "sources"; // needs MINISTRO_API_LEVEL >=3 !!!
+ // Use this key to specify any 3rd party sources urls
+ // Ministro will download these repositories into their
// own folders, check http://community.kde.org/Necessitas/Ministro
// for more details.
+ private static final String REPOSITORY_KEY = "repository"; // use this key to overwrite the default ministro repsitory
+
private static final String APPLICATION_PARAMETERS = null; // use this variable to pass any parameters to your application,
// the parameters must not contain any white spaces
// and must be separated with "\t"
// e.g "-param1\t-param2=value2\t-param3\tvalue3"
- private static final String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_STYLE=1\t";
+ private static final String ENVIRONMENT_VARIABLES = "QT_USE_ANDROID_NATIVE_STYLE=0\t";
// use this variable to add any environment variables to your application.
// the env vars must be separated with "\t"
// e.g. "ENV_VAR1=1\tENV_VAR2=2\t"
// Currently the following vars are used by the android plugin:
- // * QT_USE_ANDROID_NATIVE_STYLE - 0 if you don't want to use android style plugin, it will save a few ms at startup.
+ // * QT_USE_ANDROID_NATIVE_STYLE - 1 to use the android widget style if available,
+ // note that the android style plugin in Qt 5.1 is not fully functional.
private static final int INCOMPATIBLE_MINISTRO_VERSION = 1; // Incompatible Ministro version. Ministro needs to be upgraded.
private ActivityInfo m_activityInfo = null; // activity info object, used to access the libs and the strings
private DexClassLoader m_classLoader = null; // loader object
+ private String[] m_sources = {"https://files.kde.org/necessitas/ministro/android/necessitas/qt5/latest"}; // Make sure you are using ONLY secure locations
+ private String m_repository = "default"; // Overwrites the default Ministro repository
+ // Possible values:
+ // * default - Ministro default repository set with "Ministro configuration tool".
+ // By default the stable version is used. Only this or stable repositories should
+ // be used in production.
+ // * stable - stable repository, only this and default repositories should be used
+ // in production.
+ // * testing - testing repository, DO NOT use this repository in production,
+ // this repository is used to push a new release, and should be used to test your application.
+ // * unstable - unstable repository, DO NOT use this repository in production,
+ // this repository is used to push Qt snapshots.
private String[] m_qtLibs = null; // required qt libs
// this function is used to load and start the loader
@@ -190,7 +203,7 @@ public class QtActivity extends Activity
} catch (Exception e) {
e.printStackTrace();
AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create();
- if (m_activityInfo != null && m_activityInfo.metaData.containsKey("android.app.fatal_error_msg"))
+ if (m_activityInfo.metaData.containsKey("android.app.fatal_error_msg"))
errorDialog.setMessage(m_activityInfo.metaData.getString("android.app.fatal_error_msg"));
else
errorDialog.setMessage("Fatal error, your application can't be started.");
@@ -217,12 +230,12 @@ public class QtActivity extends Activity
parameters.putStringArray(REQUIRED_MODULES_KEY, m_qtLibs);
parameters.putString(APPLICATION_TITLE_KEY, (String)QtActivity.this.getTitle());
parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL);
- parameters.putString(QT_PROVIDER_KEY, QT_PROVIDER);
parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION);
parameters.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES);
if (null!=APPLICATION_PARAMETERS)
parameters.putString(APPLICATION_PARAMETERS_KEY, APPLICATION_PARAMETERS);
- // parameters.putStringArray(REPOSITORIES, null);
+ parameters.putStringArray(SOURCES_KEY, m_sources);
+ parameters.putString(REPOSITORY_KEY, m_repository);
m_service.requestLoader(m_ministroCallback, parameters);
}
} catch (RemoteException e) {
@@ -281,7 +294,7 @@ public class QtActivity extends Activity
{
AlertDialog errorDialog = new AlertDialog.Builder(QtActivity.this).create();
- if (m_activityInfo != null && m_activityInfo.metaData.containsKey("android.app.ministro_not_found_msg"))
+ if (m_activityInfo.metaData.containsKey("android.app.ministro_not_found_msg"))
errorDialog.setMessage(m_activityInfo.metaData.getString("android.app.ministro_not_found_msg"));
else
errorDialog.setMessage("Can't find Ministro service.\nThe application can't start.");
@@ -298,27 +311,34 @@ public class QtActivity extends Activity
private void startApp(final boolean firstStart)
{
try {
- ActivityInfo ai=getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA);
- if (ai.metaData.containsKey("android.app.qt_libs_resource_id")) {
- int resourceId = ai.metaData.getInt("android.app.qt_libs_resource_id");
+ if (m_activityInfo.metaData.containsKey("android.app.qt_sources_resource_id")) {
+ int resourceId = m_activityInfo.metaData.getInt("android.app.qt_sources_resource_id");
+ m_sources = getResources().getStringArray(resourceId);
+ }
+
+ if (m_activityInfo.metaData.containsKey("android.app.repository"))
+ m_repository = m_activityInfo.metaData.getString("android.app.repository");
+
+ if (m_activityInfo.metaData.containsKey("android.app.qt_libs_resource_id")) {
+ int resourceId = m_activityInfo.metaData.getInt("android.app.qt_libs_resource_id");
m_qtLibs = getResources().getStringArray(resourceId);
}
- if (ai.metaData.containsKey("android.app.use_local_qt_libs")
- && ai.metaData.getInt("android.app.use_local_qt_libs") == 1) {
+ if (m_activityInfo.metaData.containsKey("android.app.use_local_qt_libs")
+ && m_activityInfo.metaData.getInt("android.app.use_local_qt_libs") == 1) {
ArrayList<String> libraryList = new ArrayList<String>();
String localPrefix = "/data/local/tmp/qt/";
- if (ai.metaData.containsKey("android.app.libs_prefix"))
- localPrefix = ai.metaData.getString("android.app.libs_prefix");
+ if (m_activityInfo.metaData.containsKey("android.app.libs_prefix"))
+ localPrefix = m_activityInfo.metaData.getString("android.app.libs_prefix");
if (m_qtLibs != null) {
for (int i=0;i<m_qtLibs.length;i++)
libraryList.add(localPrefix+"lib/lib"+m_qtLibs[i]+".so");
}
- if (ai.metaData.containsKey("android.app.load_local_libs")) {
- String[] extraLibs = ai.metaData.getString("android.app.load_local_libs").split(":");
+ if (m_activityInfo.metaData.containsKey("android.app.load_local_libs")) {
+ String[] extraLibs = m_activityInfo.metaData.getString("android.app.load_local_libs").split(":");
for (String lib : extraLibs) {
if (lib.length() > 0)
libraryList.add(localPrefix + lib);
@@ -327,8 +347,8 @@ public class QtActivity extends Activity
String dexPaths = new String();
String pathSeparator = System.getProperty("path.separator", ":");
- if (ai.metaData.containsKey("android.app.load_local_jars")) {
- String[] jarFiles = ai.metaData.getString("android.app.load_local_jars").split(":");
+ if (m_activityInfo.metaData.containsKey("android.app.load_local_jars")) {
+ String[] jarFiles = m_activityInfo.metaData.getString("android.app.load_local_jars").split(":");
for (String jar:jarFiles) {
if (jar.length() > 0) {
if (dexPaths.length() > 0)
@@ -342,9 +362,9 @@ public class QtActivity extends Activity
loaderParams.putInt(ERROR_CODE_KEY, 0);
loaderParams.putString(DEX_PATH_KEY, dexPaths);
loaderParams.putString(LOADER_CLASS_NAME_KEY, "org.qtproject.qt5.android.QtActivityDelegate");
- if (ai.metaData.containsKey("android.app.static_init_classes")) {
+ if (m_activityInfo.metaData.containsKey("android.app.static_init_classes")) {
loaderParams.putStringArray(STATIC_INIT_CLASSES_KEY,
- ai.metaData.getString("android.app.static_init_classes").split(":"));
+ m_activityInfo.metaData.getString("android.app.static_init_classes").split(":"));
}
loaderParams.putStringArrayList(NATIVE_LIBRARIES_KEY, libraryList);
loaderParams.putString(ENVIRONMENT_VARIABLES_KEY, ENVIRONMENT_VARIABLES
@@ -365,7 +385,7 @@ public class QtActivity extends Activity
} catch (Exception e) {
if (firstStart) {
String msg = "This application requires Ministro service. Would you like to install it?";
- if (m_activityInfo != null && m_activityInfo.metaData.containsKey("android.app.ministro_needed_msg"))
+ if (m_activityInfo.metaData.containsKey("android.app.ministro_needed_msg"))
msg = m_activityInfo.metaData.getString("android.app.ministro_needed_msg");
downloadUpgradeMinistro(msg);
} else {
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java
index a23c3afb4d..4de1c833f5 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtApplication.java
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2012, BogDan Vatra <bogdan@kde.org>
+ Copyright (c) 2012-2013, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt-project.org/legal
Redistribution and use in source and binary forms, with or without
diff --git a/src/android/java/version.xml b/src/android/java/version.xml
index 1cd8eb31fe..e709357ba6 100644
--- a/src/android/java/version.xml
+++ b/src/android/java/version.xml
@@ -1,4 +1,4 @@
-<version value="3">
+<version value="5">
<ignore>
<file>AndroidManifest.xml</file>
<file>libs.xml</file>
diff --git a/src/angle/patches/0001-Dynamically-resolve-functions-of-dwmapi.dll.patch b/src/angle/patches/0001-Dynamically-resolve-functions-of-dwmapi.dll.patch
index f58cfe2d03..b259aa3f80 100644
--- a/src/angle/patches/0001-Dynamically-resolve-functions-of-dwmapi.dll.patch
+++ b/src/angle/patches/0001-Dynamically-resolve-functions-of-dwmapi.dll.patch
@@ -1,7 +1,7 @@
-From a5ed22f7c9aa51eebbd3ec48904a4c0999dcced6 Mon Sep 17 00:00:00 2001
-From: Friedemann Kleint <Friedemann.Kleint@digia.com>
-Date: Tue, 6 Nov 2012 09:22:18 +0100
-Subject: [PATCH] Dynamically resolve functions of dwmapi.dll.
+From 211954dffc6a0ee52db130017ae4bea00e80748f Mon Sep 17 00:00:00 2001
+From: Friedemann Kleint <Friedemann.Klient@digia.com>
+Date: Mon, 18 Mar 2013 15:35:13 +0200
+Subject: [PATCH 1/6] Dynamically resolve functions of dwmapi.dll.
The library is not present on Windows XP, for which /DELAYLOAD
is used in ANGLE. However, as this causes problems with MinGW,
@@ -10,24 +10,24 @@ use dynamic resolution.
Task-number: QTBUG-27741
Change-Id: I16214d6f98a184d89858c50ee5306371ea25469e
---
- src/3rdparty/angle/src/libEGL/Surface.cpp | 39 +++++++++++++++++++++--------
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 39 ++++++++++++++++++++++++++++-----------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
-index 732c404..34df14c 100644
+index 78203b0..5ece724 100644
--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
-@@ -73,6 +73,9 @@ Surface::~Surface()
+@@ -71,6 +71,9 @@ Surface::~Surface()
bool Surface::initialize()
{
+ typedef HRESULT (STDAPICALLTYPE *PtrDwmIsCompositionEnabled)(BOOL*);
+ typedef HRESULT (STDAPICALLTYPE *PtrDwmSetPresentParameters)(HWND, DWM_PRESENT_PARAMETERS *);
+
- ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil);
-
if (!resetSwapChain())
-@@ -82,17 +85,31 @@ bool Surface::initialize()
+ return false;
+
+@@ -78,17 +81,31 @@ bool Surface::initialize()
// to minimize the amount of queuing done by DWM between our calls to
// present and the actual screen.
if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) {
@@ -71,5 +71,5 @@ index 732c404..34df14c 100644
}
--
-1.7.10.msysgit.1
+1.8.1.msysgit.1
diff --git a/src/angle/patches/0003-Fix-Float16ToFloat32.py.patch b/src/angle/patches/0003-Fix-Float16ToFloat32.py.patch
deleted file mode 100644
index c37ab43fb9..0000000000
--- a/src/angle/patches/0003-Fix-Float16ToFloat32.py.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From e4f894847ebefe54f9a9f9911c38dc3efe77c260 Mon Sep 17 00:00:00 2001
-From: Jason Barron <jason.barron@digia.com>
-Date: Tue, 16 Oct 2012 10:34:32 +0200
-Subject: [PATCH 3/3] Fix Float16ToFloat32.py.
-
-To ensure generation of compilable code, the script should
-be using the alternate form of the hex string formatter to
-be sure it gets prefixed by '0x'.
-
-Also remove an extra '=' character.
-
-This issue has been reported upstream to the ANGLE team:
-
- http://code.google.com/p/angleproject/issues/detail?id=376
-
-Change-Id: I8ccf017afcfbd2c2f52ed291b89f29ba597c9c41
----
- src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
-index ae646ff..fb2964e 100644
---- a/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
-+++ b/src/3rdparty/angle/src/libGLESv2/Float16ToFloat32.py
-@@ -56,22 +56,22 @@ namespace gl
-
- print "const static unsigned g_mantissa[2048] = {"
- for i in range(0, 2048):
-- print " %08x," % convertMantissa(i)
-+ print " %#10x," % convertMantissa(i)
- print "};\n"
-
- print "const static unsigned g_exponent[64] = {"
- for i in range(0, 64):
-- print " %08x," % convertExponent(i)
-+ print " %#10x," % convertExponent(i)
- print "};\n"
-
- print "const static unsigned g_offset[64] = {"
- for i in range(0, 64):
-- print " %08x," % convertOffset(i)
-+ print " %#10x," % convertOffset(i)
- print "};\n"
-
- print """float float16ToFloat32(unsigned short h)
- {
-- unsigned i32 = =g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
-+ unsigned i32 = g_mantissa[g_offset[h >> 10] + (h & 0x3ff)] + g_exponent[h >> 10];
- return *(float*) &i32;
- }
- }
---
-1.7.11.msysgit.1
-
diff --git a/src/angle/patches/0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch b/src/angle/patches/0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch
index 372b9238af..29852c57fa 100644
--- a/src/angle/patches/0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch
+++ b/src/angle/patches/0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch
@@ -1,7 +1,8 @@
-From 85e9ba49580e307e1213c87cdbfdc301848f497f Mon Sep 17 00:00:00 2001
+From 0b8f4889511d7aa8f9f07b16dbf204f378e127a6 Mon Sep 17 00:00:00 2001
From: Miikka Heikkinen <miikka.heikkinen@digia.com>
-Date: Tue, 20 Nov 2012 13:23:27 +0200
-Subject: [PATCH] Fix black screen after minimizing OpenGL window with ANGLE
+Date: Mon, 18 Mar 2013 16:27:07 +0200
+Subject: [PATCH 3/6] Fix black screen after minimizing OpenGL window with
+ ANGLE
CreateTexture will fail on zero dimensions, so just release old target
and reset dimensions when resetSwapChain is called with zero size area.
@@ -10,14 +11,14 @@ Task-number: QTBUG-27994
Change-Id: I1e500c4fd4b92f7d9ea2a49a44f3fb930b575cd1
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
---
- src/3rdparty/angle/src/libEGL/Surface.cpp | 16 ++++++++++++++++
- 1 files changed, 16 insertions(+), 0 deletions(-)
+ src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
-diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
-index 8e920ab..174b403 100644
---- a/src/3rdparty/angle/src/libEGL/Surface.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
-@@ -224,6 +224,22 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp
+index 0324d01..f57a874 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp
+@@ -137,6 +137,21 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI
pShareHandle = &mShareHandle;
}
@@ -32,14 +33,13 @@ index 8e920ab..174b403 100644
+
+ mWidth = backbufferWidth;
+ mHeight = backbufferHeight;
-+ mPresentIntervalDirty = false;
+
-+ return true;
++ return EGL_SUCCESS;
+ }
+
result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
- mConfig->mRenderTargetFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
- if (FAILED(result))
+ gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT,
+ &mOffscreenTexture, pShareHandle);
--
-1.7.4.msysgit.0
+1.8.1.msysgit.1
diff --git a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch b/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch
index 7519e3ba63..72211aeee0 100644
--- a/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch
+++ b/src/angle/patches/0005-Fix-build-when-SSE2-is-not-available.patch
@@ -1,7 +1,7 @@
-From 45a06cc846dbe451bf42c5b3f617729f208743b1 Mon Sep 17 00:00:00 2001
+From 61abac6f8da2ed1ca3ab74c8c65e5fd1be3d85ad Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@digia.com>
-Date: Wed, 28 Nov 2012 15:38:58 +0100
-Subject: [PATCH] Fix build when SSE2 is not available.
+Date: Mon, 18 Mar 2013 16:36:40 +0200
+Subject: [PATCH 4/6] Fix build when SSE2 is not available.
Although SSE2 support is detected at runtime it still may not be
available at build time, so we have to ensure it only uses SSE2
@@ -9,41 +9,41 @@ when it is available at build time too.
Change-Id: I86c45a6466ab4cec79aa0f62b0d5230a78ad825a
---
- src/3rdparty/angle/src/libGLESv2/Texture.cpp | 4 ++++
- 1 files changed, 4 insertions(+), 0 deletions(-)
+ src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp | 4 ++++
+ 1 file changed, 4 insertions(+)
-diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
-index af430bf..0ea475d 100644
---- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
-+++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
-@@ -378,11 +378,13 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp
+index b3dcc59..53030b7 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp
+@@ -373,11 +373,13 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heigh
switch (mInternalFormat)
{
case GL_ALPHA8_EXT:
+#if defined(__SSE2__)
- if (supportsSSE2())
+ if (gl::supportsSSE2())
{
- loadAlphaDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
else
+#endif
{
- loadAlphaData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
-@@ -418,11 +420,13 @@ void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height
- loadRGB565Data(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+@@ -413,11 +415,13 @@ void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heigh
+ loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
break;
case GL_RGBA8_OES:
+#if defined(__SSE2__)
- if (supportsSSE2())
+ if (gl::supportsSSE2())
{
- loadRGBAUByteDataSSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
else
+#endif
{
- loadRGBAUByteData(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+ loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
}
---
-1.7.9.msysgit.0
+--
+1.8.1.msysgit.1
diff --git a/src/angle/patches/0006-ANGLE-Do-not-reset-the-share-handle-when-resetting-t.patch b/src/angle/patches/0006-ANGLE-Do-not-reset-the-share-handle-when-resetting-t.patch
deleted file mode 100644
index 7d4c7af3f8..0000000000
--- a/src/angle/patches/0006-ANGLE-Do-not-reset-the-share-handle-when-resetting-t.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From 7a2483c26eebf1c06924143108186eae59d85d98 Mon Sep 17 00:00:00 2001
-From: Zeno Albisser <zeno@webkit.org>
-Date: Fri, 30 Nov 2012 13:20:44 +0100
-Subject: [PATCH] ANGLE: Do not reset the share handle when resetting the swap
- chain.
-
-This change only affects the ANGLE_surface_d3d_texture_2d_share_handle
-extension. The patch is necessary to have WebGL running in Qt/WebKit2.
-
-If the share handle is reset, we are loosing the reference to the
-EGLSurface and cannot actually reuse it in a different context anymore.
-
-Change-Id: I0138432dd8ff60ea57e7e591cfa2f8db1d324f53
----
- src/3rdparty/angle/src/libEGL/Surface.cpp | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
-index 174b403..d9e1887 100644
---- a/src/3rdparty/angle/src/libEGL/Surface.cpp
-+++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
-@@ -217,7 +217,6 @@ bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
- mDepthStencil = NULL;
- }
-
-- mShareHandle = NULL;
- HANDLE *pShareHandle = NULL;
- if (!mWindow && mDisplay->shareHandleSupported())
- {
---
-1.7.9.5
-
diff --git a/src/angle/patches/0006-Make-DX9-DX11-mutually-exclusive.patch b/src/angle/patches/0006-Make-DX9-DX11-mutually-exclusive.patch
new file mode 100644
index 0000000000..1e7ab82771
--- /dev/null
+++ b/src/angle/patches/0006-Make-DX9-DX11-mutually-exclusive.patch
@@ -0,0 +1,140 @@
+From a5c113dda327ad3015312c2836b794929d4771ff Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Thu, 21 Mar 2013 17:12:02 +0200
+Subject: [PATCH 5/6] Make DX9/DX11 mutually exclusive
+
+ANGLE dx11proto supports DX9 fallback when DX11 is unavailable. This
+patch removes the fallback mechanism and requires that the library be
+chosen at build time (by defining ANGLE_ENABLE_D3D11). This is required
+for WinRT, because d3d9 is not a support library on that platform.
+---
+ src/3rdparty/angle/src/common/RefCountObject.cpp | 1 -
+ src/3rdparty/angle/src/common/debug.cpp | 4 ++++
+ src/3rdparty/angle/src/libGLESv2/Texture.cpp | 6 +++++-
+ src/3rdparty/angle/src/libGLESv2/precompiled.h | 9 ++++++---
+ src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp | 37 +++++++++++--------------------------
+ 5 files changed, 26 insertions(+), 31 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/common/RefCountObject.cpp b/src/3rdparty/angle/src/common/RefCountObject.cpp
+index 0364adf..c1ef90c 100644
+--- a/src/3rdparty/angle/src/common/RefCountObject.cpp
++++ b/src/3rdparty/angle/src/common/RefCountObject.cpp
+@@ -1,4 +1,3 @@
+-#include "precompiled.h"
+ //
+ // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+ // Use of this source code is governed by a BSD-style license that can be
+diff --git a/src/3rdparty/angle/src/common/debug.cpp b/src/3rdparty/angle/src/common/debug.cpp
+index 2333740..438d397 100644
+--- a/src/3rdparty/angle/src/common/debug.cpp
++++ b/src/3rdparty/angle/src/common/debug.cpp
+@@ -8,7 +8,11 @@
+
+ #include "common/debug.h"
+ #include "common/system.h"
++#ifdef ANGLE_ENABLE_D3D11
++typedef DWORD D3DCOLOR;
++#else
+ #include <d3d9.h>
++#endif
+
+ namespace gl
+ {
+diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+index ae83037..461357a 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp
+@@ -14,7 +14,11 @@
+ #include "libGLESv2/main.h"
+ #include "libGLESv2/mathutil.h"
+ #include "libGLESv2/utilities.h"
+-#include "libGLESv2/renderer/Blit.h"
++#if defined(ANGLE_ENABLE_D3D11)
++# define D3DFMT_UNKNOWN DXGI_FORMAT_UNKNOWN
++#else
++# include "libGLESv2/renderer/Blit.h"
++#endif
+ #include "libGLESv2/Renderbuffer.h"
+ #include "libGLESv2/renderer/Image.h"
+ #include "libGLESv2/renderer/Renderer.h"
+diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+index a850d57..b8b043c 100644
+--- a/src/3rdparty/angle/src/libGLESv2/precompiled.h
++++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h
+@@ -32,9 +32,12 @@
+ #include <unordered_map>
+ #include <vector>
+
+-#include <d3d9.h>
+-#include <D3D11.h>
+-#include <dxgi.h>
++#if defined(ANGLE_ENABLE_D3D11)
++# include <D3D11.h>
++# include <dxgi.h>
++#else
++# include <d3d9.h>
++#endif
+ #include <D3Dcompiler.h>
+
+ #ifdef _MSC_VER
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+index 8fd3425..64e52c1 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp
+@@ -10,14 +10,13 @@
+ #include "libGLESv2/main.h"
+ #include "libGLESv2/Program.h"
+ #include "libGLESv2/renderer/Renderer.h"
+-#include "libGLESv2/renderer/Renderer9.h"
+-#include "libGLESv2/renderer/Renderer11.h"
+-#include "libGLESv2/utilities.h"
+-
+-#if !defined(ANGLE_ENABLE_D3D11)
+-// Enables use of the Direct3D 11 API, when available
+-#define ANGLE_ENABLE_D3D11 0
++#if defined(ANGLE_ENABLE_D3D11)
++# include "libGLESv2/renderer/Renderer11.h"
++# define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT( 1, 0x876, 380 )
++#else
++# include "libGLESv2/renderer/Renderer9.h"
+ #endif
++#include "libGLESv2/utilities.h"
+
+ #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL)
+ #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3
+@@ -174,27 +173,13 @@ rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, bool softwareDevi
+ {
+ rx::Renderer *renderer = NULL;
+ EGLint status = EGL_BAD_ALLOC;
+-
+- if (ANGLE_ENABLE_D3D11)
+- {
+- renderer = new rx::Renderer11(display, hDc);
+-
+- if (renderer)
+- {
+- status = renderer->initialize();
+- }
+-
+- if (status == EGL_SUCCESS)
+- {
+- return renderer;
+- }
+-
+- // Failed to create a D3D11 renderer, try creating a D3D9 renderer
+- delete renderer;
+- }
+
++#if defined(ANGLE_ENABLE_D3D11)
++ renderer = new rx::Renderer11(display, hDc);
++#else
+ renderer = new rx::Renderer9(display, hDc, softwareDevice);
+-
++#endif
++
+ if (renderer)
+ {
+ status = renderer->initialize();
+--
+1.8.1.msysgit.1
+
diff --git a/src/angle/patches/0007-ANGLE-Fix-typedefs-for-Win64.patch b/src/angle/patches/0007-ANGLE-Fix-typedefs-for-Win64.patch
index ed744bbbd9..63e5bd635b 100644
--- a/src/angle/patches/0007-ANGLE-Fix-typedefs-for-Win64.patch
+++ b/src/angle/patches/0007-ANGLE-Fix-typedefs-for-Win64.patch
@@ -1,21 +1,19 @@
-From cf01d1953de652910734d0e01b032da99194590d Mon Sep 17 00:00:00 2001
+From a8f8f0858f59e6b8e344dfb0bb87e264aac0a13f Mon Sep 17 00:00:00 2001
From: Jonathan Liu <net147@gmail.com>
-Date: Tue, 18 Dec 2012 00:37:11 +1100
-Subject: [PATCH] ANGLE: Fix typedefs for Win64
+Date: Thu, 21 Mar 2013 17:28:54 +0200
+Subject: [PATCH 6/6] ANGLE: Fix typedefs for Win64
The long int type is incorrect for Windows 64-bit as LLP64 is used
there.
-
-Change-Id: If4ccf49d6bb0cd7ba4ff2997cebfdbe5e7e9711c
---
src/3rdparty/angle/include/KHR/khrplatform.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/3rdparty/angle/include/KHR/khrplatform.h b/src/3rdparty/angle/include/KHR/khrplatform.h
-index 8ec0d19..56c676c 100644
+index b169773..18a104e 100644
--- a/src/3rdparty/angle/include/KHR/khrplatform.h
+++ b/src/3rdparty/angle/include/KHR/khrplatform.h
-@@ -221,10 +221,17 @@ typedef signed char khronos_int8_t;
+@@ -222,10 +222,17 @@ typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
@@ -34,5 +32,5 @@ index 8ec0d19..56c676c 100644
#if KHRONOS_SUPPORT_FLOAT
/*
--
-1.8.0.1
+1.8.1.msysgit.1
diff --git a/src/angle/patches/0008-ANGLE-DX11-Prevent-assert-when-view-is-minimized-or-.patch b/src/angle/patches/0008-ANGLE-DX11-Prevent-assert-when-view-is-minimized-or-.patch
new file mode 100644
index 0000000000..47ecc25f0c
--- /dev/null
+++ b/src/angle/patches/0008-ANGLE-DX11-Prevent-assert-when-view-is-minimized-or-.patch
@@ -0,0 +1,58 @@
+From 654677720bd856b59387cfd034f441eba8c0e97f Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Thu, 4 Apr 2013 14:21:58 +0300
+Subject: [PATCH] ANGLE DX11: Prevent assert when view is minimized or size
+ goes to 0x0
+
+This allows the Direct3D 11 version of ANGLE to gracefully allow
+surfaces with dimensions of 0. This is important because Qt may resize
+the surface to 0x0 because of window minimization or other user
+action (window resize). As EGL specifies that empty (0x0) surfaces are
+valid, this makes sure an assert doesn't occur in the case that a valid
+surface is resized to an empty one.
+
+Change-Id: Ia60c4c694090d03c1da7f43c56e90b925c8eab6d
+---
+ src/3rdparty/angle/src/libEGL/Surface.cpp | 9 ++++++++-
+ src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp | 3 +++
+ 2 files changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/angle/src/libEGL/Surface.cpp b/src/3rdparty/angle/src/libEGL/Surface.cpp
+index 5ece724..8387443 100644
+--- a/src/3rdparty/angle/src/libEGL/Surface.cpp
++++ b/src/3rdparty/angle/src/libEGL/Surface.cpp
+@@ -172,9 +172,16 @@ bool Surface::resetSwapChain()
+
+ bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+ {
+- ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
+
++ // Prevent bad swap chain resize by calling reset if size is invalid
++ if (backbufferWidth < 1 || backbufferHeight < 1)
++ {
++ mWidth = backbufferWidth;
++ mHeight = backbufferHeight;
++ return mSwapChain->reset(0, 0, mSwapInterval) == EGL_SUCCESS;
++ }
++
+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
+
+ if (status == EGL_CONTEXT_LOST)
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+index 87422be..98f8875 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
+@@ -368,6 +368,9 @@ EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+ return EGL_BAD_ACCESS;
+ }
+
++ if (!mSwapChain)
++ reset(backbufferWidth, backbufferHeight, mSwapInterval);
++
+ // Can only call resize if we have already created our swap buffer and resources
+ ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView);
+
+--
+1.8.1.msysgit.1
+
diff --git a/src/angle/patches/0009-ANGLE-Avoid-memory-copies-on-buffers-when-data-is-nu.patch b/src/angle/patches/0009-ANGLE-Avoid-memory-copies-on-buffers-when-data-is-nu.patch
new file mode 100644
index 0000000000..cecff5c0e8
--- /dev/null
+++ b/src/angle/patches/0009-ANGLE-Avoid-memory-copies-on-buffers-when-data-is-nu.patch
@@ -0,0 +1,72 @@
+From cde4cd6155791355872f635491630c21c791e7f4 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Fri, 5 Apr 2013 15:11:59 +0300
+Subject: [PATCH] ANGLE: Avoid memory copies on buffers when data is null
+
+With data=0, ANGLE can crash when setting the buffer data. As this
+should be a legal operation, don't perform a memcpy when data is null.
+
+Change-Id: I3fa1260482549b1da50d7a68001a65decb98f258
+---
+ src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp | 22 ++++++++++++++++------
+ src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp | 3 ++-
+ 2 files changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+index 4c37bdb..7fe9e6b 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
+@@ -182,7 +182,8 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
+ return gl::error(GL_OUT_OF_MEMORY);
+ }
+
+- memcpy(mappedResource.pData, data, size);
++ if (data)
++ memcpy(mappedResource.pData, data, size);
+
+ context->Unmap(mStagingBuffer, 0);
+ }
+@@ -211,12 +212,21 @@ void BufferStorage11::setData(const void* data, unsigned int size, unsigned int
+ mBufferSize = 0;
+ }
+
+- D3D11_SUBRESOURCE_DATA initialData;
+- initialData.pSysMem = data;
+- initialData.SysMemPitch = size;
+- initialData.SysMemSlicePitch = 0;
+
+- result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
++ if (data)
++ {
++ D3D11_SUBRESOURCE_DATA initialData;
++ initialData.pSysMem = data;
++ initialData.SysMemPitch = size;
++ initialData.SysMemSlicePitch = 0;
++
++ result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer);
++ }
++ else
++ {
++ result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer);
++ }
++
+ if (FAILED(result))
+ {
+ return gl::error(GL_OUT_OF_MEMORY);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+index 7fc14fc..4468461 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
+@@ -54,7 +54,8 @@ void BufferStorage9::setData(const void* data, unsigned int size, unsigned int o
+ }
+
+ mSize = std::max(mSize, offset + size);
+- memcpy(reinterpret_cast<char*>(mMemory) + offset, data, size);
++ if (data)
++ memcpy(reinterpret_cast<char*>(mMemory) + offset, data, size);
+ }
+
+ void BufferStorage9::clear()
+--
+1.8.1.msysgit.1
+
diff --git a/src/angle/src/compiler/preprocessor/preprocessor.pro b/src/angle/src/compiler/preprocessor/preprocessor.pro
index 62476008b3..432c8dcf32 100644
--- a/src/angle/src/compiler/preprocessor/preprocessor.pro
+++ b/src/angle/src/compiler/preprocessor/preprocessor.pro
@@ -4,43 +4,43 @@ TARGET = $$qtLibraryTarget(preprocessor)
include(../../config.pri)
-INCLUDEPATH = $$ANGLE_DIR/src/compiler/preprocessor/new
+INCLUDEPATH = $$ANGLE_DIR/src/compiler/preprocessor
DEFINES += _SECURE_SCL=0
FLEX_SOURCES = \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Tokenizer.l
+ $$ANGLE_DIR/src/compiler/preprocessor/Tokenizer.l
BISON_SOURCES = \
- $$ANGLE_DIR/src/compiler/preprocessor/new/ExpressionParser.y
+ $$ANGLE_DIR/src/compiler/preprocessor/ExpressionParser.y
HEADERS += \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Diagnostics.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveHandler.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveParser.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/ExpressionParser.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Input.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Lexer.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Macro.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/MacroExpander.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/numeric_lex.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/pp_utils.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Preprocessor.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/SourceLocation.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Token.h \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Tokenizer.h
+ $$ANGLE_DIR/src/compiler/preprocessor/DiagnosticsBase.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/DirectiveHandlerBase.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/DirectiveParser.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/ExpressionParser.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Input.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Lexer.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Macro.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/MacroExpander.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/numeric_lex.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/pp_utils.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Preprocessor.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/SourceLocation.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Token.h \
+ $$ANGLE_DIR/src/compiler/preprocessor/Tokenizer.h
SOURCES += \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Diagnostics.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveHandler.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/DirectiveParser.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Input.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Lexer.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Macro.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/MacroExpander.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Preprocessor.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/new/Token.cpp
+ $$ANGLE_DIR/src/compiler/preprocessor/DiagnosticsBase.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/DirectiveHandlerBase.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/DirectiveParser.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/Input.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/Lexer.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/Macro.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/MacroExpander.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/Preprocessor.cpp \
+ $$ANGLE_DIR/src/compiler/preprocessor/Token.cpp
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}.cpp ${QMAKE_FILE_NAME}
diff --git a/src/angle/src/compiler/translator_common.pro b/src/angle/src/compiler/translator_common.pro
index 2d867a921e..cafbb1595d 100644
--- a/src/angle/src/compiler/translator_common.pro
+++ b/src/angle/src/compiler/translator_common.pro
@@ -48,22 +48,12 @@ HEADERS += \
$$ANGLE_DIR/src/compiler/ValidateLimitations.h \
$$ANGLE_DIR/src/compiler/VariableInfo.h \
$$ANGLE_DIR/src/compiler/VariablePacker.h \
- $$ANGLE_DIR/src/compiler/preprocessor/atom.h \
- $$ANGLE_DIR/src/compiler/preprocessor/compile.h \
- $$ANGLE_DIR/src/compiler/preprocessor/cpp.h \
- $$ANGLE_DIR/src/compiler/preprocessor/length_limits.h \
- $$ANGLE_DIR/src/compiler/preprocessor/memory.h \
- $$ANGLE_DIR/src/compiler/preprocessor/parser.h \
- $$ANGLE_DIR/src/compiler/preprocessor/preprocess.h \
- $$ANGLE_DIR/src/compiler/preprocessor/scanner.h \
- $$ANGLE_DIR/src/compiler/preprocessor/slglobals.h \
- $$ANGLE_DIR/src/compiler/preprocessor/symbols.h \
- $$ANGLE_DIR/src/compiler/preprocessor/tokens.h \
$$ANGLE_DIR/src/compiler/timing/RestrictFragmentShaderTiming.h \
$$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.h \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraph.h \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraphBuilder.h \
- $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphOutput.h
+ $$ANGLE_DIR/src/compiler/depgraph/DependencyGraphOutput.h \
+ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.h
SOURCES += \
$$ANGLE_DIR/src/compiler/BuiltInFunctionEmulator.cpp \
@@ -93,19 +83,13 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/ValidateLimitations.cpp \
$$ANGLE_DIR/src/compiler/VariableInfo.cpp \
$$ANGLE_DIR/src/compiler/VariablePacker.cpp \
- $$ANGLE_DIR/src/compiler/preprocessor/atom.c \
- $$ANGLE_DIR/src/compiler/preprocessor/cpp.c \
- $$ANGLE_DIR/src/compiler/preprocessor/cppstruct.c \
- $$ANGLE_DIR/src/compiler/preprocessor/memory.c \
- $$ANGLE_DIR/src/compiler/preprocessor/scanner.c \
- $$ANGLE_DIR/src/compiler/preprocessor/symbols.c \
- $$ANGLE_DIR/src/compiler/preprocessor/tokens.c \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraph.cpp \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraphBuilder.cpp \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraphOutput.cpp \
$$ANGLE_DIR/src/compiler/depgraph/DependencyGraphTraverse.cpp \
$$ANGLE_DIR/src/compiler/timing/RestrictFragmentShaderTiming.cpp \
- $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp
+ $$ANGLE_DIR/src/compiler/timing/RestrictVertexShaderTiming.cpp \
+ $$ANGLE_DIR/src/third_party/compiler/ArrayBoundsClamper.cpp
# NOTE: 'win_flex' and 'bison' can be found in qt5/gnuwin32/bin
flex.commands = $$addGnuPath(win_flex) --noline --nounistd --outfile=${QMAKE_FILE_BASE}_lex.cpp ${QMAKE_FILE_NAME}
diff --git a/src/angle/src/compiler/translator_hlsl.pro b/src/angle/src/compiler/translator_hlsl.pro
index 048e2a48fd..6b17f14d2e 100644
--- a/src/angle/src/compiler/translator_hlsl.pro
+++ b/src/angle/src/compiler/translator_hlsl.pro
@@ -14,7 +14,8 @@ HEADERS += \
$$ANGLE_DIR/src/compiler/OutputHLSL.h \
$$ANGLE_DIR/src/compiler/SearchSymbol.h \
$$ANGLE_DIR/src/compiler/TranslatorHLSL.h \
- $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.h
+ $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.h \
+ $$ANGLE_DIR/src/compiler/Uniform.h
SOURCES += \
$$ANGLE_DIR/src/compiler/CodeGenHLSL.cpp \
@@ -22,4 +23,5 @@ SOURCES += \
$$ANGLE_DIR/src/compiler/OutputHLSL.cpp \
$$ANGLE_DIR/src/compiler/SearchSymbol.cpp \
$$ANGLE_DIR/src/compiler/TranslatorHLSL.cpp \
- $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.cpp
+ $$ANGLE_DIR/src/compiler/UnfoldShortCircuit.cpp \
+ $$ANGLE_DIR/src/compiler/Uniform.cpp
diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri
index 73fbc2e13b..923a40597e 100644
--- a/src/angle/src/config.pri
+++ b/src/angle/src/config.pri
@@ -46,6 +46,11 @@ DEFINES += ANGLE_DISABLE_TRACE \
ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0 \
ANGLE_USE_NEW_PREPROCESSOR=1
+angle_d3d11 {
+ DEFINES += ANGLE_ENABLE_D3D11
+ !build_pass: message("Enabling D3D11 mode for ANGLE")
+}
+
CONFIG(debug, debug|release) {
DEFINES += _DEBUG
} else {
diff --git a/src/angle/src/libEGL/libEGL.pro b/src/angle/src/libEGL/libEGL.pro
index 6f3bc25cfb..c0d021ccab 100644
--- a/src/angle/src/libEGL/libEGL.pro
+++ b/src/angle/src/libEGL/libEGL.pro
@@ -6,8 +6,13 @@ include(../common/common.pri)
# Note: ANGLE is patched to dynamically resolve DwmIsCompositionEnabled DwmSetPresentParameters
# in Surface.cpp, which would otherwise require -ldwmapi, which does not exist on Windows XP
# (QTBUG-27741).
-LIBS += -ld3d9 -ldxguid \
- -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget(libGLESv2)
+
+angle_d3d11 {
+ LIBS += -ld3d11
+} else {
+ LIBS += -ld3d9
+}
+LIBS += -ldxguid -L$$QT_BUILD_TREE/lib -l$$qtLibraryTarget(libGLESv2)
HEADERS += \
$$ANGLE_DIR/src/libEGL/Config.h \
diff --git a/src/angle/src/libGLESv2/libGLESv2.pro b/src/angle/src/libGLESv2/libGLESv2.pro
index 2412a01b82..681cd1be19 100644
--- a/src/angle/src/libGLESv2/libGLESv2.pro
+++ b/src/angle/src/libGLESv2/libGLESv2.pro
@@ -4,10 +4,15 @@ CONFIG += simd
include(../common/common.pri)
-INCLUDEPATH += $$OUT_PWD/..
+INCLUDEPATH += $$OUT_PWD/.. $$ANGLE_DIR/src/libGLESv2
# Remember to adapt tools/configure/configureapp.cpp if the Direct X version changes.
-LIBS += -ld3d9 -ld3dcompiler
+angle_d3d11 {
+ LIBS += -ldxgi -ld3d11
+} else {
+ LIBS += -ld3d9
+}
+LIBS += -ldxguid -ld3dcompiler
STATICLIBS = translator_common translator_hlsl preprocessor
for(libname, STATICLIBS) {
@@ -19,15 +24,13 @@ for(libname, STATICLIBS) {
}
HEADERS += \
+ $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.h \
$$ANGLE_DIR/src/libGLESv2/BinaryStream.h \
- $$ANGLE_DIR/src/libGLESv2/Blit.h \
$$ANGLE_DIR/src/libGLESv2/Buffer.h \
$$ANGLE_DIR/src/libGLESv2/Context.h \
- $$ANGLE_DIR/src/libGLESv2/D3DConstantTable.h \
$$ANGLE_DIR/src/libGLESv2/Fence.h \
$$ANGLE_DIR/src/libGLESv2/Framebuffer.h \
$$ANGLE_DIR/src/libGLESv2/HandleAllocator.h \
- $$ANGLE_DIR/src/libGLESv2/IndexDataManager.h \
$$ANGLE_DIR/src/libGLESv2/main.h \
$$ANGLE_DIR/src/libGLESv2/mathutil.h \
$$ANGLE_DIR/src/libGLESv2/Program.h \
@@ -38,20 +41,31 @@ HEADERS += \
$$ANGLE_DIR/src/libGLESv2/ResourceManager.h \
$$ANGLE_DIR/src/libGLESv2/Shader.h \
$$ANGLE_DIR/src/libGLESv2/Texture.h \
+ $$ANGLE_DIR/src/libGLESv2/Uniform.h \
$$ANGLE_DIR/src/libGLESv2/utilities.h \
$$ANGLE_DIR/src/libGLESv2/vertexconversion.h \
- $$ANGLE_DIR/src/libGLESv2/VertexDataManager.h
+ $$ANGLE_DIR/src/libGLESv2/precompiled.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexDataManager.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDataManager.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDeclarationCache.h
SOURCES += \
- $$ANGLE_DIR/src/libGLESv2/Blit.cpp \
+ $$ANGLE_DIR/src/third_party/murmurhash/MurmurHash3.cpp \
$$ANGLE_DIR/src/libGLESv2/Buffer.cpp \
$$ANGLE_DIR/src/libGLESv2/Context.cpp \
- $$ANGLE_DIR/src/libGLESv2/D3DConstantTable.cpp \
$$ANGLE_DIR/src/libGLESv2/Fence.cpp \
- $$ANGLE_DIR/src/libGLESv2/Framebuffer.cpp \
$$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.cpp \
+ $$ANGLE_DIR/src/libGLESv2/Framebuffer.cpp \
$$ANGLE_DIR/src/libGLESv2/HandleAllocator.cpp \
- $$ANGLE_DIR/src/libGLESv2/IndexDataManager.cpp \
$$ANGLE_DIR/src/libGLESv2/libGLESv2.cpp \
$$ANGLE_DIR/src/libGLESv2/main.cpp \
$$ANGLE_DIR/src/libGLESv2/Program.cpp \
@@ -61,10 +75,84 @@ SOURCES += \
$$ANGLE_DIR/src/libGLESv2/ResourceManager.cpp \
$$ANGLE_DIR/src/libGLESv2/Shader.cpp \
$$ANGLE_DIR/src/libGLESv2/Texture.cpp \
+ $$ANGLE_DIR/src/libGLESv2/Uniform.cpp \
$$ANGLE_DIR/src/libGLESv2/utilities.cpp \
- $$ANGLE_DIR/src/libGLESv2/VertexDataManager.cpp
+ $$ANGLE_DIR/src/libGLESv2/precompiled.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexDataManager.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDataManager.cpp
-SSE2_SOURCES += $$ANGLE_DIR/src/libGLESv2/TextureSSE2.cpp
+sse2:SOURCES += $$ANGLE_DIR/src/libGLESv2/renderer/ImageSSE2.cpp
+
+angle_d3d11 {
+ HEADERS += \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Fence11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/InputLayoutCache.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Query11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/renderer11_utils.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderStateCache.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage11.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer11.h
+
+ SOURCES += \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Fence11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/InputLayoutCache.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Query11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/renderer11_utils.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderStateCache.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage11.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer11.cpp
+} else {
+ HEADERS += \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Blit.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Fence9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Query9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/renderer9_utils.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage9.h \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer9.h
+
+ SOURCES += \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Blit.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/BufferStorage9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Fence9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Image9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/IndexBuffer9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Query9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/Renderer9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/renderer9_utils.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/RenderTarget9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/ShaderExecutable9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/SwapChain9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/TextureStorage9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexBuffer9.cpp \
+ $$ANGLE_DIR/src/libGLESv2/renderer/VertexDeclarationCache.cpp
+}
!static {
DEF_FILE = $$ANGLE_DIR/src/libGLESv2/$${TARGET}.def
@@ -77,27 +165,71 @@ float_converter.commands = python $$ANGLE_DIR/src/libGLESv2/Float16ToFloat32.py
QMAKE_EXTRA_TARGETS += float_converter
# Generate the shader header files.
-PS_INPUT = $$ANGLE_DIR/src/libGLESv2/shaders/Blit.ps
-VS_INPUT = $$ANGLE_DIR/src/libGLESv2/shaders/Blit.vs
+PS_INPUT = $$ANGLE_DIR/src/libGLESv2/renderer/shaders/Blit.ps
+VS_INPUT = $$ANGLE_DIR/src/libGLESv2/renderer/shaders/Blit.vs
+PASSTHROUGH_INPUT = $$ANGLE_DIR/src/libGLESv2/renderer/shaders/Passthrough11.hlsl
+CLEAR_INPUT = $$ANGLE_DIR/src/libGLESv2/renderer/shaders/Clear11.hlsl
PIXEL_SHADERS = passthroughps luminanceps componentmaskps
+PIXEL_SHADERS_PASSTHROUGH = PassthroughRGBA PassthroughRGB \
+ PassthroughLum PassthroughLumAlpha
VERTEX_SHADERS = standardvs flipyvs
-SHADER_DIR = $$OUT_PWD/shaders
+VERTEX_SHADERS_PASSTHROUGH = Passthrough
+CLEAR_SHADERS = Clear
+SHADER_DIR = $$OUT_PWD/renderer/shaders/compiled
for (ps, PIXEL_SHADERS) {
- fxc_$${ps}.commands = $$FXC /nologo /E $$ps /T ps_2_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
- fxc_$${ps}.output = $$SHADER_DIR/$${ps}.h
- fxc_$${ps}.input = PS_INPUT
- fxc_$${ps}.dependency_type = TYPE_C
- fxc_$${ps}.variable_out = HEADERS
- QMAKE_EXTRA_COMPILERS += fxc_$${ps}
+ fxc_ps_$${ps}.commands = $$FXC /nologo /E $$ps /T ps_2_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}.h
+ fxc_ps_$${ps}.input = PS_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+ fxc_ps_$${ps}.variable_out = HEADERS
+ fxc_ps_$${ps}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+}
+for (ps, PIXEL_SHADERS_PASSTHROUGH) {
+ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = PASSTHROUGH_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+ fxc_ps_$${ps}.variable_out = HEADERS
+ fxc_ps_$${ps}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
+}
+for (ps, CLEAR_SHADERS) {
+ fxc_ps_$${ps}.commands = $$FXC /nologo /E PS_$$ps /T ps_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_ps_$${ps}.output = $$SHADER_DIR/$${ps}11ps.h
+ fxc_ps_$${ps}.input = CLEAR_INPUT
+ fxc_ps_$${ps}.dependency_type = TYPE_C
+ fxc_ps_$${ps}.variable_out = HEADERS
+ fxc_ps_$${ps}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_ps_$${ps}
}
for (vs, VERTEX_SHADERS) {
- fxc_$${vs}.commands = $$FXC /nologo /E $$vs /T vs_2_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
- fxc_$${vs}.output = $$SHADER_DIR/$${vs}.h
- fxc_$${vs}.input = VS_INPUT
- fxc_$${vs}.dependency_type = TYPE_C
- fxc_$${vs}.variable_out = HEADERS
- QMAKE_EXTRA_COMPILERS += fxc_$${vs}
+ fxc_vs_$${vs}.commands = $$FXC /nologo /E $$vs /T vs_2_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}.h
+ fxc_vs_$${vs}.input = VS_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+ fxc_vs_$${vs}.variable_out = HEADERS
+ fxc_vs_$${vs}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+}
+for (vs, VERTEX_SHADERS_PASSTHROUGH) {
+ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = PASSTHROUGH_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+ fxc_vs_$${vs}.variable_out = HEADERS
+ fxc_vs_$${vs}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
+}
+for (vs, CLEAR_SHADERS) {
+ fxc_vs_$${vs}.commands = $$FXC /nologo /E VS_$$vs /T vs_4_0 /Fh ${QMAKE_FILE_OUT} ${QMAKE_FILE_NAME}
+ fxc_vs_$${vs}.output = $$SHADER_DIR/$${vs}11vs.h
+ fxc_vs_$${vs}.input = CLEAR_INPUT
+ fxc_vs_$${vs}.dependency_type = TYPE_C
+ fxc_vs_$${vs}.variable_out = HEADERS
+ fxc_vs_$${vs}.CONFIG += target_predeps
+ QMAKE_EXTRA_COMPILERS += fxc_vs_$${vs}
}
load(qt_installs)
diff --git a/src/corelib/Qt5CTestMacros.cmake b/src/corelib/Qt5CTestMacros.cmake
index 32af44a79d..e507c8009e 100644
--- a/src/corelib/Qt5CTestMacros.cmake
+++ b/src/corelib/Qt5CTestMacros.cmake
@@ -26,6 +26,14 @@ if (NO_DBUS)
list(APPEND BUILD_OPTIONS_LIST "-DNO_DBUS=True")
endif()
+foreach(module ${CMAKE_MODULES_UNDER_TEST})
+ list(APPEND BUILD_OPTIONS_LIST
+ "-DCMAKE_${module}_MODULE_MAJOR_VERSION=${CMAKE_${module}_MODULE_MAJOR_VERSION}"
+ "-DCMAKE_${module}_MODULE_MINOR_VERSION=${CMAKE_${module}_MODULE_MINOR_VERSION}"
+ "-DCMAKE_${module}_MODULE_PATCH_VERSION=${CMAKE_${module}_MODULE_PATCH_VERSION}"
+ )
+endforeach()
+
macro(expect_pass _dir)
string(REPLACE "(" "_" testname "${_dir}")
string(REPLACE ")" "_" testname "${testname}")
@@ -95,11 +103,30 @@ function(test_module_includes)
while(all_args)
list(GET all_args 0 qtmodule)
list(REMOVE_AT all_args 0 1)
+
+ set(CMAKE_MODULE_VERSION ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION}.${CMAKE_${qtmodule}_MODULE_MINOR_VERSION}.${CMAKE_${qtmodule}_MODULE_PATCH_VERSION} )
+
set(packages_string
"${packages_string}
find_package(Qt5${qtmodule} 5.0.0 REQUIRED)
include_directories(\${Qt5${qtmodule}_INCLUDE_DIRS})
- add_definitions(\${Qt5${qtmodule}_DEFINITIONS})\n"
+ add_definitions(\${Qt5${qtmodule}_DEFINITIONS})
+
+ if(NOT \"\${Qt5${qtmodule}_VERSION}\" VERSION_EQUAL ${CMAKE_MODULE_VERSION})
+ message(SEND_ERROR \"Qt5${qtmodule}_VERSION variable was not ${CMAKE_MODULE_VERSION}. Got \${Qt5${qtmodule}_VERSION} instead.\")
+ endif()
+ if(NOT \"\${Qt5${qtmodule}_VERSION_MAJOR}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION})
+ message(SEND_ERROR \"Qt5${qtmodule}_VERSION_MAJOR variable was not ${CMAKE_${qtmodule}_MODULE_MAJOR_VERSION}. Got \${Qt5${qtmodule}_VERSION_MAJOR} instead.\")
+ endif()
+ if(NOT \"\${Qt5${qtmodule}_VERSION_MINOR}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_MINOR_VERSION})
+ message(SEND_ERROR \"Qt5${qtmodule}_VERSION_MINOR variable was not ${CMAKE_${qtmodule}_MODULE_MINOR_VERSION}. Got \${Qt5${qtmodule}_VERSION_MINOR} instead.\")
+ endif()
+ if(NOT \"\${Qt5${qtmodule}_VERSION_PATCH}\" VERSION_EQUAL ${CMAKE_${qtmodule}_MODULE_PATCH_VERSION})
+ message(SEND_ERROR \"Qt5${qtmodule}_VERSION_PATCH variable was not ${CMAKE_${qtmodule}_MODULE_PATCH_VERSION}. Got \${Qt5${qtmodule}_VERSION_PATCH} instead.\")
+ endif()
+ if(NOT \"\${Qt5${qtmodule}_VERSION_STRING}\" VERSION_EQUAL ${CMAKE_MODULE_VERSION})
+ message(SEND_ERROR \"Qt5${qtmodule}_VERSION_STRING variable was not ${CMAKE_MODULE_VERSION}. Got \${Qt5${qtmodule}_VERSION_STRING} instead.\")
+ endif()\n"
)
set(libraries_string "${libraries_string} Qt5::${qtmodule}")
endwhile()
diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in
index bdafc85796..379fb5d10e 100644
--- a/src/corelib/Qt5CoreConfigExtras.cmake.in
+++ b/src/corelib/Qt5CoreConfigExtras.cmake.in
@@ -46,10 +46,10 @@ set_property(TARGET Qt5::Core APPEND PROPERTY
COMPATIBLE_INTERFACE_STRING QT_MAJOR_VERSION
)
-!!IF isEmpty(CMAKE_ARCHDATA_DIR_IS_ABSOLUTE)
-set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_ARCHDATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
+!!IF isEmpty(CMAKE_HOST_DATA_DIR_IS_ABSOLUTE)
+set(_qt5_corelib_extra_includes \"${_qt5Core_install_prefix}/$${CMAKE_HOST_DATA_DIR}/mkspecs/$${CMAKE_MKSPEC}\")
!!ELSE
-set(_qt5_corelib_extra_includes \"$${CMAKE_ARCHDATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
+set(_qt5_corelib_extra_includes \"$${CMAKE_HOST_DATA_DIR}mkspecs/$${CMAKE_MKSPEC}\")
!!ENDIF
list(APPEND Qt5Core_INCLUDE_DIRS ${_qt5_corelib_extra_includes})
diff --git a/src/corelib/doc/src/objectmodel/properties.qdoc b/src/corelib/doc/src/objectmodel/properties.qdoc
index 65e23d9dc7..d1690c5908 100644
--- a/src/corelib/doc/src/objectmodel/properties.qdoc
+++ b/src/corelib/doc/src/objectmodel/properties.qdoc
@@ -195,7 +195,7 @@
Suppose we have a class MyClass, which is derived from QObject and
which uses the Q_OBJECT macro in its private section. We want to
- declare a property in MyClass to keep track of a priorty
+ declare a property in MyClass to keep track of a priority
value. The name of the property will be \e priority, and its type
will be an enumeration type named \e Priority, which is defined in
MyClass.
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 747fd87207..5fb9640b19 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -273,7 +273,11 @@ static const struct {
{ "Documentation", "doc" }, // should be ${Data}/doc
{ "Headers", "include" },
{ "Libraries", "lib" },
+#ifdef Q_OS_WIN
+ { "LibraryExecutables", "bin" },
+#else
{ "LibraryExecutables", "libexec" }, // should be ${ArchData}/libexec
+#endif
{ "Binaries", "bin" },
{ "Plugins", "plugins" }, // should be ${ArchData}/plugins
{ "Imports", "imports" }, // should be ${ArchData}/imports
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 42b263be77..484dcbf22e 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -572,6 +572,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\table
\header \li Qt Version \li QDataStream Version
+ \row \li Qt 5.0 \li 13
\row \li Qt 4.6 \li 12
\row \li Qt 4.5 \li 11
\row \li Qt 4.4 \li 10
diff --git a/src/corelib/io/qlockfile.h b/src/corelib/io/qlockfile.h
index 4c8b6bf31a..d46f07ab7b 100644
--- a/src/corelib/io/qlockfile.h
+++ b/src/corelib/io/qlockfile.h
@@ -45,8 +45,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qscopedpointer.h>
-QT_BEGIN_HEADER
-
QT_BEGIN_NAMESPACE
class QLockFilePrivate;
@@ -86,6 +84,4 @@ private:
QT_END_NAMESPACE
-QT_END_HEADER
-
#endif // QLOCKFILE_H
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index fee6a4c4d8..f8b5ebcabd 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -48,11 +48,16 @@
#include "qtemporaryfile.h"
#include "private/qiodevice_p.h"
#include "private/qtemporaryfile_p.h"
+#ifdef Q_OS_UNIX
+#include <errno.h>
+#endif
QT_BEGIN_NAMESPACE
QSaveFilePrivate::QSaveFilePrivate()
- : writeError(QFileDevice::NoError)
+ : writeError(QFileDevice::NoError),
+ useTemporaryFile(true),
+ directWriteFallback(false)
{
}
@@ -201,6 +206,18 @@ bool QSaveFile::open(OpenMode mode)
// Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine.
if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) {
QFileDevice::FileError err = d->fileEngine->error();
+#ifdef Q_OS_UNIX
+ if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) {
+ delete d->fileEngine;
+ d->fileEngine = QAbstractFileEngine::create(d->fileName);
+ if (d->fileEngine->open(mode | QIODevice::Unbuffered)) {
+ d->useTemporaryFile = false;
+ QFileDevice::open(mode);
+ return true;
+ }
+ err = d->fileEngine->error();
+ }
+#endif
if (err == QFileDevice::UnspecifiedError)
err = QFileDevice::OpenError;
d->setError(err, d->fileEngine->errorString());
@@ -209,6 +226,7 @@ bool QSaveFile::open(OpenMode mode)
return false;
}
+ d->useTemporaryFile = true;
QFileDevice::open(mode);
if (existingFile.exists())
setPermissions(existingFile.permissions());
@@ -253,22 +271,24 @@ bool QSaveFile::commit()
// Sync to disk if possible. Ignore errors (e.g. not supported).
d->fileEngine->syncToDisk();
- if (d->writeError != QFileDevice::NoError) {
- d->fileEngine->remove();
- d->writeError = QFileDevice::NoError;
- delete d->fileEngine;
- d->fileEngine = 0;
- return false;
- }
- // atomically replace old file with new file
- // Can't use QFile::rename for that, must use the file engine directly
- Q_ASSERT(d->fileEngine);
- if (!d->fileEngine->renameOverwrite(d->fileName)) {
- d->setError(d->fileEngine->error(), d->fileEngine->errorString());
- d->fileEngine->remove();
- delete d->fileEngine;
- d->fileEngine = 0;
- return false;
+ if (d->useTemporaryFile) {
+ if (d->writeError != QFileDevice::NoError) {
+ d->fileEngine->remove();
+ d->writeError = QFileDevice::NoError;
+ delete d->fileEngine;
+ d->fileEngine = 0;
+ return false;
+ }
+ // atomically replace old file with new file
+ // Can't use QFile::rename for that, must use the file engine directly
+ Q_ASSERT(d->fileEngine);
+ if (!d->fileEngine->renameOverwrite(d->fileName)) {
+ d->setError(d->fileEngine->error(), d->fileEngine->errorString());
+ d->fileEngine->remove();
+ delete d->fileEngine;
+ d->fileEngine = 0;
+ return false;
+ }
}
delete d->fileEngine;
d->fileEngine = 0;
@@ -286,6 +306,11 @@ bool QSaveFile::commit()
Further write operations are possible after calling this method, but none
of it will have any effect, the written file will be discarded.
+ This method has no effect when direct write fallback is used. This is the case
+ when saving over an existing file in a readonly directory: no temporary file can
+ be created, so the existing file is overwritten no matter what, and cancelWriting()
+ cannot do anything about that, the contents of the existing file will be lost.
+
\sa commit()
*/
void QSaveFile::cancelWriting()
@@ -313,4 +338,46 @@ qint64 QSaveFile::writeData(const char *data, qint64 len)
return ret;
}
+/*!
+ Allows writing over the existing file if necessary.
+
+ QSaveFile creates a temporary file in the same directory as the final
+ file and atomically renames it. However this is not possible if the
+ directory permissions do not allow creating new files.
+ In order to preserve atomicity guarantees, open() fails when it
+ cannot create the temporary file.
+
+ In order to allow users to edit files with write permissions in a
+ directory with restricted permissions, call setDirectWriteFallback() with
+ \a enabled set to true, and the following calls to open() will fallback to
+ opening the existing file directly and writing into it, without the use of
+ a temporary file.
+ This does not have atomicity guarantees, i.e. an application crash or
+ for instance a power failure could lead to a partially-written file on disk.
+ It also means cancelWriting() has no effect, in such a case.
+
+ Typically, to save documents edited by the user, call setDirectWriteFallback(true),
+ and to save application internal files (configuration files, data files, ...), keep
+ the default setting which ensures atomicity.
+
+ \sa directWriteFallback()
+*/
+void QSaveFile::setDirectWriteFallback(bool enabled)
+{
+ Q_D(QSaveFile);
+ d->directWriteFallback = enabled;
+}
+
+/*!
+ Returns true if the fallback solution for saving files in read-only
+ directories is enabled.
+
+ \sa setDirectWriteFallback()
+*/
+bool QSaveFile::directWriteFallback() const
+{
+ Q_D(const QSaveFile);
+ return d->directWriteFallback;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h
index 32af4a708e..6d81f58d42 100644
--- a/src/corelib/io/qsavefile.h
+++ b/src/corelib/io/qsavefile.h
@@ -75,6 +75,9 @@ public:
void cancelWriting();
+ void setDirectWriteFallback(bool enabled);
+ bool directWriteFallback() const;
+
protected:
qint64 writeData(const char *data, qint64 len) Q_DECL_OVERRIDE;
diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h
index 27e687835b..53a8b5eb34 100644
--- a/src/corelib/io/qsavefile_p.h
+++ b/src/corelib/io/qsavefile_p.h
@@ -68,6 +68,9 @@ protected:
QString fileName;
QFileDevice::FileError writeError;
+
+ bool useTemporaryFile;
+ bool directWriteFallback;
};
QT_END_NAMESPACE
diff --git a/src/corelib/itemmodels/qabstractproxymodel.cpp b/src/corelib/itemmodels/qabstractproxymodel.cpp
index d5887a52d5..d435c4bcf5 100644
--- a/src/corelib/itemmodels/qabstractproxymodel.cpp
+++ b/src/corelib/itemmodels/qabstractproxymodel.cpp
@@ -91,6 +91,7 @@ QT_BEGIN_NAMESPACE
//detects the deletion of the source model
void QAbstractProxyModelPrivate::_q_sourceModelDestroyed()
{
+ invalidatePersistentIndexes();
model = QAbstractItemModelPrivate::staticEmptyModel();
}
@@ -271,8 +272,7 @@ QVariant QAbstractProxyModel::headerData(int section, Qt::Orientation orientatio
*/
QMap<int, QVariant> QAbstractProxyModel::itemData(const QModelIndex &proxyIndex) const
{
- Q_D(const QAbstractProxyModel);
- return d->model->itemData(mapToSource(proxyIndex));
+ return QAbstractItemModel::itemData(proxyIndex);
}
/*!
@@ -298,8 +298,7 @@ bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &valu
*/
bool QAbstractProxyModel::setItemData(const QModelIndex &index, const QMap< int, QVariant >& roles)
{
- Q_D(QAbstractProxyModel);
- return d->model->setItemData(mapToSource(index), roles);
+ return QAbstractItemModel::setItemData(index, roles);
}
/*!
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index e5bdd83dc3..67b0d98402 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -295,7 +295,8 @@ typedef QHash<QModelIndex, QSortFilterProxyModelPrivate::Mapping *> IndexMap;
void QSortFilterProxyModelPrivate::_q_sourceModelDestroyed()
{
QAbstractProxyModelPrivate::_q_sourceModelDestroyed();
- _q_clearMapping();
+ qDeleteAll(source_index_mapping);
+ source_index_mapping.clear();
}
void QSortFilterProxyModelPrivate::remove_from_mapping(const QModelIndex &source_parent)
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 189116ddc1..4add02f805 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -689,7 +689,7 @@ struct QMetaTypeIdQObject<T*, /* isPointerToTypeDerivedFromQObject */ true>
return id;
const char * const cName = T::staticMetaObject.className();
QByteArray typeName;
- typeName.reserve(strlen(cName) + 1);
+ typeName.reserve(int(strlen(cName)) + 1);
typeName.append(cName).append('*');
const int newId = qRegisterNormalizedMetaType<T*>(
typeName,
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 7b80e5c1da..bae4a837a0 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -971,7 +971,7 @@ Q_CORE_EXPORT void QVariantPrivate::registerHandler(const int /* Modules::Names
QVariant to convert between types given suitable data; it is still
possible to supply data which cannot actually be converted.
- For example, canConvert(int) would return true when called on a variant
+ For example, canConvert(Int) would return true when called on a variant
containing a string because, in principle, QVariant is able to convert
strings of numbers to integers.
However, if the string contains non-numeric characters, it cannot be
diff --git a/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp b/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
index 35fe0a5a3f..4511dcb346 100644
--- a/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
+++ b/src/dbus/doc/snippets/code/doc_src_qdbusadaptors.cpp
@@ -146,7 +146,7 @@ int main(int argc, char **argv)
new MainApplicationAdaptor(app);
// connect to D-Bus and register as an object:
- QDBusConnection::sessionBus().registerObject("/MainApplication", app);
+ QDBusConnection::sessionBus().registerObject("/MainApplication", &app);
// add main window, etc.
[...]
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index e007c9967e..7487aabde5 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -46,6 +46,8 @@
#include "qaccessibleplugin.h"
#include "qaccessibleobject.h"
#include "qaccessiblebridge.h"
+#include <QtCore/qtextboundaryfinder.h>
+#include <QtGui/qtextcursor.h>
#include <QtGui/QGuiApplication>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformaccessibility.h>
@@ -790,6 +792,77 @@ void QAccessible::updateAccessibility(QAccessibleEvent *event)
#endif
/*!
+ \internal
+ \brief getBoundaries is a helper function to find the accessible text boundaries for QTextCursor based documents.
+ \param documentCursor a valid cursor bound to the document (not null). It needs to ba at the position to look for the boundary
+ \param boundaryType the type of boundary to find
+ \return the boundaries as pair
+*/
+QPair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCursor &offsetCursor, TextBoundaryType boundaryType)
+{
+ Q_ASSERT(!offsetCursor.isNull());
+
+ QTextCursor endCursor = offsetCursor;
+ endCursor.movePosition(QTextCursor::End);
+ int characterCount = endCursor.position();
+
+ QPair<int, int> result;
+ QTextCursor cursor = offsetCursor;
+ switch (boundaryType) {
+ case CharBoundary:
+ result.first = cursor.position();
+ cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ break;
+ case WordBoundary:
+ cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
+ result.first = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ break;
+ case SentenceBoundary: {
+ // QCursor does not provide functionality to move to next sentence.
+ // We therefore find the current block, then go through the block using
+ // QTextBoundaryFinder and find the sentence the \offset represents
+ cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
+ result.first = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ QString blockText = cursor.selectedText();
+ const int offsetWithinBlockText = offsetCursor.position() - result.first;
+ QTextBoundaryFinder sentenceFinder(QTextBoundaryFinder::Sentence, blockText);
+ sentenceFinder.setPosition(offsetWithinBlockText);
+ int prevBoundary = offsetWithinBlockText;
+ int nextBoundary = offsetWithinBlockText;
+ if (!(sentenceFinder.boundaryReasons() & QTextBoundaryFinder::StartOfItem))
+ prevBoundary = sentenceFinder.toPreviousBoundary();
+ nextBoundary = sentenceFinder.toNextBoundary();
+ if (nextBoundary != -1)
+ result.second = result.first + nextBoundary;
+ if (prevBoundary != -1)
+ result.first += prevBoundary;
+ break; }
+ case LineBoundary:
+ cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
+ result.first = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ break;
+ case ParagraphBoundary:
+ cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
+ result.first = cursor.position();
+ cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ break;
+ case NoBoundary:
+ result.first = 0;
+ result.second = characterCount;
+ break;
+ }
+ return result;
+}
+
+/*!
\class QAccessibleInterface
\brief The QAccessibleInterface class defines an interface that exposes information
about accessible objects.
diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h
index 8447f34154..339e3fbcd6 100644
--- a/src/gui/accessible/qaccessible.h
+++ b/src/gui/accessible/qaccessible.h
@@ -62,6 +62,7 @@ QT_BEGIN_NAMESPACE
class QAccessibleInterface;
class QAccessibleEvent;
class QWindow;
+class QTextCursor;
// We need to inherit QObject to expose the enums to QML.
class Q_GUI_EXPORT QAccessible
@@ -331,6 +332,15 @@ public:
TableCellInterface
};
+ enum TextBoundaryType {
+ CharBoundary,
+ WordBoundary,
+ SentenceBoundary,
+ ParagraphBoundary,
+ LineBoundary,
+ NoBoundary
+ };
+
typedef QAccessibleInterface*(*InterfaceFactory)(const QString &key, QObject*);
typedef void(*UpdateHandler)(QAccessibleEvent *event);
typedef void(*RootObjectHandler)(QObject*);
@@ -359,6 +369,8 @@ public:
static void cleanup();
+ static QPair< int, int > qAccessibleTextBoundaryHelper(const QTextCursor &cursor, TextBoundaryType boundaryType);
+
private:
static UpdateHandler updateHandler;
static RootObjectHandler rootObjectHandler;
diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp
index bd9ecde260..d790fac071 100644
--- a/src/gui/accessible/qaccessible2.cpp
+++ b/src/gui/accessible/qaccessible2.cpp
@@ -49,17 +49,6 @@
QT_BEGIN_NAMESPACE
/*!
- \namespace QAccessible2
- \ingroup accessibility
- \internal
-
- \brief The QAccessible2 namespace defines constants relating to
- IAccessible2-based interfaces
-
- \l{IAccessible2 Specification}
-*/
-
-/*!
\class QAccessibleTextInterface
\internal
\inmodule QtGui
@@ -139,7 +128,7 @@ QT_BEGIN_NAMESPACE
of that item; returns an empty string if there is no such an item.
Sets \a startOffset and \a endOffset values to -1 on error.
*/
-QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
+QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
const QString txt = text(0, characterCount());
@@ -155,13 +144,13 @@ QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible2::Bou
QTextBoundaryFinder::BoundaryType type;
switch (boundaryType) {
- case QAccessible2::CharBoundary:
+ case QAccessible::CharBoundary:
type = QTextBoundaryFinder::Grapheme;
break;
- case QAccessible2::WordBoundary:
+ case QAccessible::WordBoundary:
type = QTextBoundaryFinder::Word;
break;
- case QAccessible2::SentenceBoundary:
+ case QAccessible::SentenceBoundary:
type = QTextBoundaryFinder::Sentence;
break;
default:
@@ -199,7 +188,7 @@ QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible2::Bou
of that item; returns an empty string if there is no such an item.
Sets \a startOffset and \a endOffset values to -1 on error.
*/
-QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
const QString txt = text(0, characterCount());
@@ -215,13 +204,13 @@ QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::Boun
QTextBoundaryFinder::BoundaryType type;
switch (boundaryType) {
- case QAccessible2::CharBoundary:
+ case QAccessible::CharBoundary:
type = QTextBoundaryFinder::Grapheme;
break;
- case QAccessible2::WordBoundary:
+ case QAccessible::WordBoundary:
type = QTextBoundaryFinder::Word;
break;
- case QAccessible2::SentenceBoundary:
+ case QAccessible::SentenceBoundary:
type = QTextBoundaryFinder::Sentence;
break;
default:
@@ -259,7 +248,7 @@ QString QAccessibleTextInterface::textAfterOffset(int offset, QAccessible2::Boun
of that item; returns an empty string if there is no such an item.
Sets \a startOffset and \a endOffset values to -1 on error.
*/
-QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
const QString txt = text(0, characterCount());
@@ -275,13 +264,13 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible2::Boundar
QTextBoundaryFinder::BoundaryType type;
switch (boundaryType) {
- case QAccessible2::CharBoundary:
+ case QAccessible::CharBoundary:
type = QTextBoundaryFinder::Grapheme;
break;
- case QAccessible2::WordBoundary:
+ case QAccessible::WordBoundary:
type = QTextBoundaryFinder::Word;
break;
- case QAccessible2::SentenceBoundary:
+ case QAccessible::SentenceBoundary:
type = QTextBoundaryFinder::Sentence;
break;
default:
diff --git a/src/gui/accessible/qaccessible2_p.h b/src/gui/accessible/qaccessible2_p.h
index 1a1eeea4ba..95f93e2431 100644
--- a/src/gui/accessible/qaccessible2_p.h
+++ b/src/gui/accessible/qaccessible2_p.h
@@ -50,18 +50,6 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
-namespace QAccessible2
-{
- enum BoundaryType {
- CharBoundary,
- WordBoundary,
- SentenceBoundary,
- ParagraphBoundary,
- LineBoundary,
- NoBoundary
- };
-}
-
class Q_GUI_EXPORT QAccessibleTextInterface
{
public:
@@ -79,11 +67,11 @@ public:
// text
virtual QString text(int startOffset, int endOffset) const = 0;
- virtual QString textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ virtual QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- virtual QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ virtual QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- virtual QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ virtual QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
virtual int characterCount() const = 0;
diff --git a/src/gui/doc/qtgui.qdocconf b/src/gui/doc/qtgui.qdocconf
index fcf6cdf57c..74596d8a50 100644
--- a/src/gui/doc/qtgui.qdocconf
+++ b/src/gui/doc/qtgui.qdocconf
@@ -21,7 +21,7 @@ qhp.QtGui.customFilters.Qt.filterAttributes = qtgui $QT_VERSION
qhp.QtGui.subprojects = classes
qhp.QtGui.subprojects.classes.title = C++ Classes
-qhp.QtGui.subprojects.classes.indexTitle = Qt GUI C++ API
+qhp.QtGui.subprojects.classes.indexTitle = Qt GUI C++ Classes
qhp.QtGui.subprojects.classes.selectors = class fake:headerfile
qhp.QtGui.subprojects.classes.sortPages = true
diff --git a/src/gui/doc/src/qtgui.qdoc b/src/gui/doc/src/qtgui.qdoc
index 201bb03a14..6c3e9a4938 100644
--- a/src/gui/doc/src/qtgui.qdoc
+++ b/src/gui/doc/src/qtgui.qdoc
@@ -27,7 +27,7 @@
/*!
\module QtGui
- \title Qt GUI C++ API
+ \title Qt GUI C++ Classes
\ingroup modules
\brief The Qt GUI module provides the basic enablers for graphical
@@ -164,7 +164,7 @@
\section1 Reference
\list
- \li \l{Qt GUI C++ API}
+ \li \l{Qt GUI C++ Classes}
\list
\li \l{Event Classes}
\li \l{Painting Classes}
diff --git a/src/gui/opengl/qopenglfunctions_1_2.h b/src/gui/opengl/qopenglfunctions_1_2.h
index b0b06da76e..e646fea703 100644
--- a/src/gui/opengl/qopenglfunctions_1_2.h
+++ b/src/gui/opengl/qopenglfunctions_1_2.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -452,7 +453,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
private:
friend class QOpenGLContext;
@@ -803,6 +803,11 @@ inline void QOpenGLFunctions_1_2::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_1_2::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_1_2::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -2344,11 +2349,6 @@ inline void QOpenGLFunctions_1_2::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_1_2::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglfunctions_1_3.h b/src/gui/opengl/qopenglfunctions_1_3.h
index 362a60649b..44728a2d18 100644
--- a/src/gui/opengl/qopenglfunctions_1_3.h
+++ b/src/gui/opengl/qopenglfunctions_1_3.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -463,7 +464,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -855,6 +855,11 @@ inline void QOpenGLFunctions_1_3::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_1_3::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_1_3::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -2443,11 +2448,6 @@ inline void QOpenGLFunctions_1_3::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_1_3::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_1_3::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_1_4.h b/src/gui/opengl/qopenglfunctions_1_4.h
index fbb5b2e86c..463927fdaf 100644
--- a/src/gui/opengl/qopenglfunctions_1_4.h
+++ b/src/gui/opengl/qopenglfunctions_1_4.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -472,7 +473,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -906,6 +906,11 @@ inline void QOpenGLFunctions_1_4::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_1_4::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_1_4::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -2531,11 +2536,6 @@ inline void QOpenGLFunctions_1_4::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_1_4::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_1_4::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_1_5.h b/src/gui/opengl/qopenglfunctions_1_5.h
index cdb2140a5c..c50dcabb90 100644
--- a/src/gui/opengl/qopenglfunctions_1_5.h
+++ b/src/gui/opengl/qopenglfunctions_1_5.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -493,7 +494,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -930,6 +930,11 @@ inline void QOpenGLFunctions_1_5::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_1_5::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_1_5::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -2652,11 +2657,6 @@ inline void QOpenGLFunctions_1_5::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_1_5::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_1_5::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_2_0.h b/src/gui/opengl/qopenglfunctions_2_0.h
index afc5eabb38..ee610793ad 100644
--- a/src/gui/opengl/qopenglfunctions_2_0.h
+++ b/src/gui/opengl/qopenglfunctions_2_0.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -552,7 +553,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1029,6 +1029,11 @@ inline void QOpenGLFunctions_2_0::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_2_0::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_2_0::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -3038,11 +3043,6 @@ inline void QOpenGLFunctions_2_0::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_2_0::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_2_0::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_2_1.h b/src/gui/opengl/qopenglfunctions_2_1.h
index c1d291fba4..2dc77cd165 100644
--- a/src/gui/opengl/qopenglfunctions_2_1.h
+++ b/src/gui/opengl/qopenglfunctions_2_1.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -560,7 +561,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1040,6 +1040,11 @@ inline void QOpenGLFunctions_2_1::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_2_1::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_2_1::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -3081,11 +3086,6 @@ inline void QOpenGLFunctions_2_1::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_2_1::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_2_1::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_3_0.h b/src/gui/opengl/qopenglfunctions_3_0.h
index f586bdec58..d6448a08d6 100644
--- a/src/gui/opengl/qopenglfunctions_3_0.h
+++ b/src/gui/opengl/qopenglfunctions_3_0.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -626,7 +627,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1130,6 +1130,11 @@ inline void QOpenGLFunctions_3_0::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_0::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_0::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -3493,11 +3498,6 @@ inline void QOpenGLFunctions_3_0::glColorTable(GLenum target, GLenum internalfor
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_3_0::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_3_0::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_3_1.h b/src/gui/opengl/qopenglfunctions_3_1.h
index 46beec85e0..b483ac21ad 100644
--- a/src/gui/opengl/qopenglfunctions_3_1.h
+++ b/src/gui/opengl/qopenglfunctions_3_1.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -684,6 +685,11 @@ inline void QOpenGLFunctions_3_1::glTexSubImage3D(GLenum target, GLint level, GL
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_1::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_1::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_3_2_compatibility.h b/src/gui/opengl/qopenglfunctions_3_2_compatibility.h
index f279f1037a..599f493104 100644
--- a/src/gui/opengl/qopenglfunctions_3_2_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_3_2_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -661,7 +662,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1171,6 +1171,11 @@ inline void QOpenGLFunctions_3_2_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_2_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_2_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -3693,11 +3698,6 @@ inline void QOpenGLFunctions_3_2_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_3_2_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_3_2_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_3_2_core.h b/src/gui/opengl/qopenglfunctions_3_2_core.h
index b3d9a5040c..8445384b60 100644
--- a/src/gui/opengl/qopenglfunctions_3_2_core.h
+++ b/src/gui/opengl/qopenglfunctions_3_2_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -706,6 +707,11 @@ inline void QOpenGLFunctions_3_2_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_2_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_2_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_3_3_compatibility.h b/src/gui/opengl/qopenglfunctions_3_3_compatibility.h
index 95e000f88d..6230ebccec 100644
--- a/src/gui/opengl/qopenglfunctions_3_3_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_3_3_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -721,7 +722,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1234,6 +1234,11 @@ inline void QOpenGLFunctions_3_3_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_3_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_3_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -4048,11 +4053,6 @@ inline void QOpenGLFunctions_3_3_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_3_3_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_3_3_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_3_3_core.h b/src/gui/opengl/qopenglfunctions_3_3_core.h
index 0ffb156831..e24c678b9b 100644
--- a/src/gui/opengl/qopenglfunctions_3_3_core.h
+++ b/src/gui/opengl/qopenglfunctions_3_3_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -767,6 +768,11 @@ inline void QOpenGLFunctions_3_3_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_3_3_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_3_3_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_4_0_compatibility.h b/src/gui/opengl/qopenglfunctions_4_0_compatibility.h
index a77a2951b1..72e270a1c8 100644
--- a/src/gui/opengl/qopenglfunctions_4_0_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_4_0_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -769,7 +770,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1285,6 +1285,11 @@ inline void QOpenGLFunctions_4_0_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_0_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_0_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -4331,11 +4336,6 @@ inline void QOpenGLFunctions_4_0_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_4_0_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_4_0_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_4_0_core.h b/src/gui/opengl/qopenglfunctions_4_0_core.h
index 64b75a7374..7d4e468399 100644
--- a/src/gui/opengl/qopenglfunctions_4_0_core.h
+++ b/src/gui/opengl/qopenglfunctions_4_0_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -816,6 +817,11 @@ inline void QOpenGLFunctions_4_0_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_0_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_0_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_4_1_compatibility.h b/src/gui/opengl/qopenglfunctions_4_1_compatibility.h
index 3d7f703b8d..e343d2cba9 100644
--- a/src/gui/opengl/qopenglfunctions_4_1_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_4_1_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -859,7 +860,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1378,6 +1378,11 @@ inline void QOpenGLFunctions_4_1_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_1_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_1_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -4866,11 +4871,6 @@ inline void QOpenGLFunctions_4_1_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_4_1_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_4_1_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_4_1_core.h b/src/gui/opengl/qopenglfunctions_4_1_core.h
index 90ec87568e..851d80bf36 100644
--- a/src/gui/opengl/qopenglfunctions_4_1_core.h
+++ b/src/gui/opengl/qopenglfunctions_4_1_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -907,6 +908,11 @@ inline void QOpenGLFunctions_4_1_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_1_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_1_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_4_2_compatibility.h b/src/gui/opengl/qopenglfunctions_4_2_compatibility.h
index 65bb26767a..1819c79702 100644
--- a/src/gui/opengl/qopenglfunctions_4_2_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_4_2_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -873,7 +874,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1395,6 +1395,11 @@ inline void QOpenGLFunctions_4_2_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_2_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_2_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -4945,11 +4950,6 @@ inline void QOpenGLFunctions_4_2_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_4_2_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_4_2_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_4_2_core.h b/src/gui/opengl/qopenglfunctions_4_2_core.h
index 2abe9cb033..dbdaa2996f 100644
--- a/src/gui/opengl/qopenglfunctions_4_2_core.h
+++ b/src/gui/opengl/qopenglfunctions_4_2_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -922,6 +923,11 @@ inline void QOpenGLFunctions_4_2_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_2_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_2_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglfunctions_4_3_compatibility.h b/src/gui/opengl/qopenglfunctions_4_3_compatibility.h
index 124685d0c0..60be506e6a 100644
--- a/src/gui/opengl/qopenglfunctions_4_3_compatibility.h
+++ b/src/gui/opengl/qopenglfunctions_4_3_compatibility.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -908,7 +909,6 @@ public:
void glColorTableParameteriv(GLenum target, GLenum pname, const GLint *params);
void glColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params);
void glColorTable(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
// OpenGL 1.3 deprecated functions
void glMultTransposeMatrixd(const GLdouble *m);
@@ -1433,6 +1433,11 @@ inline void QOpenGLFunctions_4_3_Compatibility::glTexSubImage3D(GLenum target, G
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_3_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_3_Compatibility::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
@@ -5150,11 +5155,6 @@ inline void QOpenGLFunctions_4_3_Compatibility::glColorTable(GLenum target, GLen
d_1_2_Deprecated->ColorTable(target, internalformat, width, format, type, table);
}
-inline void QOpenGLFunctions_4_3_Compatibility::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
-{
- d_1_2_Deprecated->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
-}
-
// OpenGL 1.3 deprecated functions
inline void QOpenGLFunctions_4_3_Compatibility::glMultTransposeMatrixd(const GLdouble *m)
diff --git a/src/gui/opengl/qopenglfunctions_4_3_core.h b/src/gui/opengl/qopenglfunctions_4_3_core.h
index c004594eb8..f7823cd6aa 100644
--- a/src/gui/opengl/qopenglfunctions_4_3_core.h
+++ b/src/gui/opengl/qopenglfunctions_4_3_core.h
@@ -139,6 +139,7 @@ public:
// OpenGL 1.2 core functions
void glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void glBlendEquation(GLenum mode);
void glBlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -958,6 +959,11 @@ inline void QOpenGLFunctions_4_3_Core::glTexSubImage3D(GLenum target, GLint leve
d_1_2_Core->TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
}
+inline void QOpenGLFunctions_4_3_Core::glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+{
+ d_1_2_Core->TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
+}
+
inline void QOpenGLFunctions_4_3_Core::glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
{
d_1_2_Core->DrawRangeElements(mode, start, end, count, type, indices);
diff --git a/src/gui/opengl/qopenglversionfunctions.cpp b/src/gui/opengl/qopenglversionfunctions.cpp
index d39ecd9d4c..0b1b6834e3 100644
--- a/src/gui/opengl/qopenglversionfunctions.cpp
+++ b/src/gui/opengl/qopenglversionfunctions.cpp
@@ -384,6 +384,7 @@ QOpenGLFunctions_1_2_CoreBackend::QOpenGLFunctions_1_2_CoreBackend(QOpenGLContex
// OpenGL 1.2 core functions
CopyTexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLint , GLint , GLsizei , GLsizei )>(context->getProcAddress("glCopyTexSubImage3D"));
TexSubImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLint , GLint , GLsizei , GLsizei , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexSubImage3D"));
+ TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexImage3D"));
DrawRangeElements = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLuint , GLuint , GLsizei , GLenum , const GLvoid *)>(context->getProcAddress("glDrawRangeElements"));
BlendEquation = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum )>(context->getProcAddress("glBlendEquation"));
BlendColor = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLfloat , GLfloat , GLfloat , GLfloat )>(context->getProcAddress("glBlendColor"));
@@ -1593,7 +1594,6 @@ QOpenGLFunctions_1_2_DeprecatedBackend::QOpenGLFunctions_1_2_DeprecatedBackend(Q
ColorTableParameteriv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLenum , const GLint *)>(context->getProcAddress("glColorTableParameteriv"));
ColorTableParameterfv = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLenum , const GLfloat *)>(context->getProcAddress("glColorTableParameterfv"));
ColorTable = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLenum , GLsizei , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glColorTable"));
- TexImage3D = reinterpret_cast<void (QOPENGLF_APIENTRYP)(GLenum , GLint , GLint , GLsizei , GLsizei , GLsizei , GLint , GLenum , GLenum , const GLvoid *)>(context->getProcAddress("glTexImage3D"));
}
diff --git a/src/gui/opengl/qopenglversionfunctions.h b/src/gui/opengl/qopenglversionfunctions.h
index b58a7186d1..833c5adf9f 100644
--- a/src/gui/opengl/qopenglversionfunctions.h
+++ b/src/gui/opengl/qopenglversionfunctions.h
@@ -258,6 +258,7 @@ public:
// OpenGL 1.2 core functions
void (QOPENGLF_APIENTRYP CopyTexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
void (QOPENGLF_APIENTRYP TexSubImage3D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
+ void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
void (QOPENGLF_APIENTRYP DrawRangeElements)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
void (QOPENGLF_APIENTRYP BlendEquation)(GLenum mode);
void (QOPENGLF_APIENTRYP BlendColor)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
@@ -1171,7 +1172,6 @@ public:
void (QOPENGLF_APIENTRYP ColorTableParameteriv)(GLenum target, GLenum pname, const GLint *params);
void (QOPENGLF_APIENTRYP ColorTableParameterfv)(GLenum target, GLenum pname, const GLfloat *params);
void (QOPENGLF_APIENTRYP ColorTable)(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table);
- void (QOPENGLF_APIENTRYP TexImage3D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
};
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 8532a040a4..651949192b 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -40,12 +40,17 @@
****************************************************************************/
#if defined(__OPTIMIZE__) && !defined(__INTEL_COMPILER) && defined(__GNUC__) \
- && (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)
+ && (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ >= 440)
// GCC 4.4 supports #pragma GCC optimize and #pragma GCC target
-# pragma GCC optimize "O3"
-# if defined(__i386__) && defined(__SSE2__) && !defined(__SSE2_MATH__)
-# pragma GCC target "fpmath=sse"
-# endif
+
+# if (__GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ < 473)
+// From GCC 4.7.3 onwards, GCC optimize can result in gcc bailing out with OOM
+# pragma GCC optimize "O3"
+# endif
+
+# if defined(__i386__) && defined(__SSE2__) && !defined(__SSE2_MATH__)
+# pragma GCC target "fpmath=sse"
+# endif
#endif
#include <qstylehints.h>
diff --git a/src/network/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp
index 49d6babb10..4f74936ac7 100644
--- a/src/network/bearer/qnetworkconfigmanager.cpp
+++ b/src/network/bearer/qnetworkconfigmanager.cpp
@@ -55,10 +55,13 @@
QT_BEGIN_NAMESPACE
static QBasicAtomicPointer<QNetworkConfigurationManagerPrivate> connManager_ptr;
+static QBasicAtomicInt appShutdown;
static void connManager_cleanup()
{
// this is not atomic or thread-safe!
+ int shutdown = appShutdown.fetchAndStoreAcquire(1);
+ Q_ASSERT(shutdown == 0);
QNetworkConfigurationManagerPrivate *cmp = connManager_ptr.fetchAndStoreAcquire(0);
if (cmp)
cmp->cleanup();
@@ -72,7 +75,8 @@ void QNetworkConfigurationManagerPrivate::addPostRoutine()
QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate()
{
QNetworkConfigurationManagerPrivate *ptr = connManager_ptr.loadAcquire();
- if (!ptr) {
+ int shutdown = appShutdown.loadAcquire();
+ if (!ptr && !shutdown) {
static QBasicMutex connManager_mutex;
QMutexLocker locker(&connManager_mutex);
if (!(ptr = connManager_ptr.loadAcquire())) {
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
index e4702e8497..6efd5085ac 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor.cpp
@@ -1791,7 +1791,7 @@ bool AtSpiAdaptor::textInterface(QAccessibleInterface *interface, const QString
int offset = message.arguments().at(0).toInt();
int start;
int end;
- QString result = interface->textInterface()->textAtOffset(offset, QAccessible2::CharBoundary, &start, &end);
+ QString result = interface->textInterface()->textAtOffset(offset, QAccessible::CharBoundary, &start, &end);
sendReply(connection, message, (int) *(qPrintable (result)));
} else if (function == QLatin1String("GetCharacterExtents")) {
int offset = message.arguments().at(0).toInt();
@@ -1879,23 +1879,23 @@ bool AtSpiAdaptor::textInterface(QAccessibleInterface *interface, const QString
return true;
}
-QAccessible2::BoundaryType AtSpiAdaptor::qAccessibleBoundaryType(int atspiTextBoundaryType) const
+QAccessible::TextBoundaryType AtSpiAdaptor::qAccessibleBoundaryType(int atspiTextBoundaryType) const
{
switch (atspiTextBoundaryType) {
case ATSPI_TEXT_BOUNDARY_CHAR:
- return QAccessible2::CharBoundary;
+ return QAccessible::CharBoundary;
case ATSPI_TEXT_BOUNDARY_WORD_START:
case ATSPI_TEXT_BOUNDARY_WORD_END:
- return QAccessible2::WordBoundary;
+ return QAccessible::WordBoundary;
case ATSPI_TEXT_BOUNDARY_SENTENCE_START:
case ATSPI_TEXT_BOUNDARY_SENTENCE_END:
- return QAccessible2::SentenceBoundary;
+ return QAccessible::SentenceBoundary;
case ATSPI_TEXT_BOUNDARY_LINE_START:
case ATSPI_TEXT_BOUNDARY_LINE_END:
- return QAccessible2::LineBoundary;
+ return QAccessible::LineBoundary;
}
Q_ASSERT_X(0, "", "Requested invalid boundary type.");
- return QAccessible2::CharBoundary;
+ return QAccessible::CharBoundary;
}
// FIXME all attribute methods below should share code
diff --git a/src/platformsupport/linuxaccessibility/atspiadaptor_p.h b/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
index aafaecfeae..6f005c33ab 100644
--- a/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
+++ b/src/platformsupport/linuxaccessibility/atspiadaptor_p.h
@@ -128,7 +128,7 @@ private:
QVariantList getAttributeValue(QAccessibleInterface *, int offset, const QString &attributeName) const;
QRect getCharacterExtents(QAccessibleInterface *, int offset, uint coordType) const;
QRect getRangeExtents(QAccessibleInterface *, int startOffset, int endOffset, uint coordType) const;
- QAccessible2::BoundaryType qAccessibleBoundaryType(int atspiTextBoundaryType) const;
+ QAccessible::TextBoundaryType qAccessibleBoundaryType(int atspiTextBoundaryType) const;
static bool inheritsQAction(QObject *object);
// private vars
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
index 751a722bb8..f20823f25b 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp
@@ -72,8 +72,6 @@
QT_BEGIN_NAMESPACE
-using namespace QAccessible2;
-
QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
QString Q_GUI_EXPORT qt_accHotKey(const QString &text);
@@ -997,83 +995,18 @@ QPoint QAccessibleTextWidget::scrollBarPosition() const
return QPoint(0, 0);
}
-QPair< int, int > QAccessibleTextWidget::getBoundaries(int offset, BoundaryType boundaryType) const
-{
- if (offset >= characterCount())
- return QPair<int, int>(characterCount(), characterCount());
- if (offset < 0)
- return QPair<int, int>(0, 0);
-
- QTextCursor cursor = textCursor();
- QPair<int, int> result;
-
- cursor.setPosition(offset);
- switch (boundaryType) {
- case CharBoundary:
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
- case WordBoundary:
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
- case SentenceBoundary: {
- // QCursor does not provide functionality to move to next sentence.
- // We therefore find the current block, then go through the block using
- // QTextBoundaryFinder and find the sentence the \offset represents
- cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- QString blockText = cursor.selectedText();
- const int offsetWithinBlockText = offset - result.first;
- QTextBoundaryFinder sentenceFinder(QTextBoundaryFinder::Sentence, blockText);
- sentenceFinder.setPosition(offsetWithinBlockText);
- int prevBoundary = offsetWithinBlockText;
- int nextBoundary = offsetWithinBlockText;
- if (!(sentenceFinder.boundaryReasons() & QTextBoundaryFinder::StartOfItem))
- prevBoundary = sentenceFinder.toPreviousBoundary();
- nextBoundary = sentenceFinder.toNextBoundary();
- if (nextBoundary != -1)
- result.second = result.first + nextBoundary;
- if (prevBoundary != -1)
- result.first += prevBoundary;
- break; }
- case LineBoundary:
- cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
- case ParagraphBoundary:
- cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
- case NoBoundary:
- result.first = 0;
- result.second = characterCount();
- break;
- default:
- qWarning("QAccessibleTextWidget::getBoundaries: Unknown boundary type %d", boundaryType);
- result.first = -1;
- result.second = -1;
- }
- return result;
-}
-QString QAccessibleTextWidget::textBeforeOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
Q_ASSERT(startOffset);
Q_ASSERT(endOffset);
- QPair<int, int> boundaries = getBoundaries(offset, boundaryType);
- boundaries = getBoundaries(boundaries.first - 1, boundaryType);
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ cursor.setPosition(boundaries.first - 1);
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
*startOffset = boundaries.first;
*endOffset = boundaries.second;
@@ -1082,14 +1015,17 @@ QString QAccessibleTextWidget::textBeforeOffset(int offset, BoundaryType boundar
}
-QString QAccessibleTextWidget::textAfterOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
Q_ASSERT(startOffset);
Q_ASSERT(endOffset);
- QPair<int, int> boundaries = getBoundaries(offset, boundaryType);
- boundaries = getBoundaries(boundaries.second, boundaryType);
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ cursor.setPosition(boundaries.second);
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
*startOffset = boundaries.first;
*endOffset = boundaries.second;
@@ -1097,13 +1033,15 @@ QString QAccessibleTextWidget::textAfterOffset(int offset, BoundaryType boundary
return text(boundaries.first, boundaries.second);
}
-QString QAccessibleTextWidget::textAtOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
Q_ASSERT(startOffset);
Q_ASSERT(endOffset);
- QPair<int, int> boundaries = getBoundaries(offset, boundaryType);
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(offset);
+ QPair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
*startOffset = boundaries.first;
*endOffset = boundaries.second;
diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h
index 35ef3ce905..c60a1d893e 100644
--- a/src/plugins/accessible/widgets/qaccessiblewidgets.h
+++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h
@@ -92,11 +92,11 @@ public:
// text
QString text(int startOffset, int endOffset) const;
- QString textBeforeOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ QString textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
int characterCount() const;
@@ -115,8 +115,8 @@ public:
protected:
QTextCursor textCursorForRange(int startOffset, int endOffset) const;
- QPair<int, int> getBoundaries(int offset, QAccessible2::BoundaryType boundaryType) const;
virtual QPoint scrollBarPosition() const;
+ // return the current text cursor at the caret position including a potential selection
virtual QTextCursor textCursor() const = 0;
virtual void setTextCursor(const QTextCursor &) = 0;
virtual QTextDocument *textDocument() const = 0;
diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp
index a9a43a7875..0112182a4b 100644
--- a/src/plugins/accessible/widgets/simplewidgets.cpp
+++ b/src/plugins/accessible/widgets/simplewidgets.cpp
@@ -67,7 +67,6 @@ QT_BEGIN_NAMESPACE
#ifndef QT_NO_ACCESSIBILITY
-using namespace QAccessible2;
extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel = false);
QString Q_GUI_EXPORT qt_accStripAmp(const QString &text);
@@ -724,7 +723,7 @@ QString QAccessibleLineEdit::text(int startOffset, int endOffset) const
return lineEdit()->text().mid(startOffset, endOffset - startOffset);
}
-QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleLineEdit::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
if (lineEdit()->echoMode() != QLineEdit::Normal) {
@@ -734,7 +733,7 @@ QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryT
return QAccessibleTextInterface::textBeforeOffset(offset, boundaryType, startOffset, endOffset);
}
-QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleLineEdit::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
if (lineEdit()->echoMode() != QLineEdit::Normal) {
@@ -744,7 +743,7 @@ QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryTy
return QAccessibleTextInterface::textAfterOffset(offset, boundaryType, startOffset, endOffset);
}
-QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType,
+QString QAccessibleLineEdit::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
if (lineEdit()->echoMode() != QLineEdit::Normal) {
diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h
index 4701634ca0..f1426354f1 100644
--- a/src/plugins/accessible/widgets/simplewidgets.h
+++ b/src/plugins/accessible/widgets/simplewidgets.h
@@ -156,11 +156,11 @@ public:
int offsetAtPoint(const QPoint &point) const;
void selection(int selectionIndex, int *startOffset, int *endOffset) const;
QString text(int startOffset, int endOffset) const;
- QString textBeforeOffset (int offset, QAccessible2::BoundaryType boundaryType,
+ QString textBeforeOffset (int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- QString textAfterOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ QString textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
- QString textAtOffset(int offset, QAccessible2::BoundaryType boundaryType,
+ QString textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const;
void removeSelection(int selectionIndex);
void setCursorPosition(int position);
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index ec44b91111..3c61a69480 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -287,7 +287,8 @@ ushort TableGenerator::keysymToUtf8(uint32_t sym)
uint32_t TableGenerator::stringToKeysym(QString keysymName)
{
uint32_t keysym;
- const char *name = keysymName.toLatin1().constData();
+ QByteArray keysymArray = keysymName.toLatin1();
+ const char *name = keysymArray.constData();
if ((keysym = xkb_keysym_from_name(name, (xkb_keysym_flags)0)) == XKB_KEY_NoSymbol)
qWarning() << QString("Qt Warrning - invalid keysym: %1").arg(keysymName);
diff --git a/src/plugins/platforms/android/src/androidjnimain.cpp b/src/plugins/platforms/android/src/androidjnimain.cpp
index ae94e75e34..36d95b0816 100644
--- a/src/plugins/platforms/android/src/androidjnimain.cpp
+++ b/src/plugins/platforms/android/src/androidjnimain.cpp
@@ -123,6 +123,7 @@ static QAndroidPlatformIntegration *m_androidPlatformIntegration = 0;
static int m_desktopWidthPixels = 0;
static int m_desktopHeightPixels = 0;
+static double m_scaledDensity = 0;
static volatile bool m_pauseApplication;
@@ -287,6 +288,11 @@ namespace QtAndroid
return m_desktopHeightPixels;
}
+ double scaledDensity()
+ {
+ return m_scaledDensity;
+ }
+
JavaVM *javaVM()
{
return m_javaVM;
@@ -623,10 +629,11 @@ static void destroySurface(JNIEnv *env, jobject /*thiz*/)
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
jint /*widthPixels*/, jint /*heightPixels*/,
jint desktopWidthPixels, jint desktopHeightPixels,
- jdouble xdpi, jdouble ydpi)
+ jdouble xdpi, jdouble ydpi, jdouble scaledDensity)
{
m_desktopWidthPixels = desktopWidthPixels;
m_desktopHeightPixels = desktopHeightPixels;
+ m_scaledDensity = scaledDensity;
if (!m_androidPlatformIntegration) {
QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,desktopHeightPixels,
@@ -687,7 +694,7 @@ static JNINativeMethod methods[] = {
{"resumeQtApp", "()V", (void *)resumeQtApp},
{"quitQtAndroidPlugin", "()V", (void *)quitQtAndroidPlugin},
{"terminateQt", "()V", (void *)terminateQt},
- {"setDisplayMetrics", "(IIIIDD)V", (void *)setDisplayMetrics},
+ {"setDisplayMetrics", "(IIIIDDD)V", (void *)setDisplayMetrics},
{"setSurface", "(Ljava/lang/Object;)V", (void *)setSurface},
{"destroySurface", "()V", (void *)destroySurface},
{"lockSurface", "()V", (void *)lockSurface},
diff --git a/src/plugins/platforms/android/src/androidjnimain.h b/src/plugins/platforms/android/src/androidjnimain.h
index 618bd87cdb..f75df55e02 100644
--- a/src/plugins/platforms/android/src/androidjnimain.h
+++ b/src/plugins/platforms/android/src/androidjnimain.h
@@ -81,6 +81,7 @@ namespace QtAndroid
QWindow *topLevelWindowAt(const QPoint &globalPos);
int desktopWidthPixels();
int desktopHeightPixels();
+ double scaledDensity();
JavaVM *javaVM();
jclass findClass(const QString &className, JNIEnv *env);
AAssetManager *assetManager();
diff --git a/src/plugins/platforms/android/src/androidjnimenu.cpp b/src/plugins/platforms/android/src/androidjnimenu.cpp
index e49af0fdac..bb180347c1 100644
--- a/src/plugins/platforms/android/src/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/src/androidjnimenu.cpp
@@ -177,6 +177,20 @@ namespace QtAndroidMenu
resetMenuBar();
}
+ static QString removeAmpersandEscapes(QString s)
+ {
+ int i = 0;
+ while (i < s.size()) {
+ ++i;
+ if (s.at(i-1) != QLatin1Char('&'))
+ continue;
+ if (i < s.size() && s.at(i) == QLatin1Char('&'))
+ ++i;
+ s.remove(i-1,1);
+ }
+ return s.trimmed();
+ }
+
static void fillMenuItem(JNIEnv *env, jobject menuItem, bool checkable, bool checked, bool enabled, bool visible, const QIcon &icon=QIcon())
{
env->CallObjectMethod(menuItem, setCheckableMenuItemMethodID, checkable);
@@ -204,8 +218,9 @@ namespace QtAndroidMenu
foreach (QAndroidPlatformMenuItem *item, platformMenu->menuItems()) {
if (item->isSeparator())
continue;
- jstring jtext = env->NewString(reinterpret_cast<const jchar *>(item->text().data()),
- item->text().length());
+ QString itemText = removeAmpersandEscapes(item->text());
+ jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
+ itemText.length());
jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID,
menuNoneValue,
@@ -239,8 +254,9 @@ namespace QtAndroidMenu
order = addAllMenuItemsToMenu(env, menu, static_cast<QAndroidPlatformMenu *>(menus.front()));
} else {
foreach (QAndroidPlatformMenu *item, menus) {
- jstring jtext = env->NewString(reinterpret_cast<const jchar *>(item->text().data()),
- item->text().length());
+ QString itemText = removeAmpersandEscapes(item->text());
+ jstring jtext = env->NewString(reinterpret_cast<const jchar *>(itemText.data()),
+ itemText.length());
jobject menuItem = env->CallObjectMethod(menu,
addMenuItemMethodID,
menuNoneValue,
@@ -299,8 +315,9 @@ namespace QtAndroidMenu
if (!visibleMenu)
return;
- jstring jtext = env->NewString(reinterpret_cast<const jchar*>(visibleMenu->text().data()),
- visibleMenu->text().length());
+ QString menuText = removeAmpersandEscapes(visibleMenu->text());
+ jstring jtext = env->NewString(reinterpret_cast<const jchar*>(menuText.data()),
+ menuText.length());
env->CallObjectMethod(menu, setHeaderTitleContextMenuMethodID, jtext);
env->DeleteLocalRef(jtext);
addAllMenuItemsToMenu(env, menu, visibleMenu);
diff --git a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
index cd415843a7..4734d47eb3 100644
--- a/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
+++ b/src/plugins/platforms/android/src/opengl/qeglfshooks_android.cpp
@@ -56,6 +56,7 @@ public:
EGLNativeDisplayType platformDisplay() const;
QSize screenSize() const;
QSizeF physicalScreenSize() const;
+ QDpi logicalDpi() const;
int screenDepth() const;
QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
EGLNativeWindowType createNativeWindow(const QSize &size, const QSurfaceFormat &format);
@@ -86,6 +87,12 @@ QSizeF QEglFSAndroidHooks::physicalScreenSize() const
return QSizeF(QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth, QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight);
}
+QDpi QEglFSAndroidHooks::logicalDpi() const
+{
+ qreal lDpi = QtAndroid::scaledDensity() * 100;
+ return QDpi(lDpi, lDpi);
+}
+
EGLNativeWindowType QEglFSAndroidHooks::createNativeWindow(const QSize &size, const QSurfaceFormat &format)
{
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
index 2779d7cffd..409c833db3 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.cpp
@@ -69,3 +69,9 @@ QRegion QAndroidPlatformScreen::doRedraw()
QtAndroid::flushImage(mGeometry.topLeft(), *mScreenImage, touched.boundingRect());
return touched;
}
+
+QDpi QAndroidPlatformScreen::logicalDpi() const
+{
+ qreal lDpi = QtAndroid::scaledDensity() * 100;
+ return QDpi(lDpi, lDpi);
+}
diff --git a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
index df08e43af4..cfd503d611 100644
--- a/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/src/raster/qandroidplatformscreen.h
@@ -50,6 +50,7 @@ class QAndroidPlatformScreen: public QFbScreen
public:
QAndroidPlatformScreen();
void topWindowChanged(QWindow *w);
+ QDpi logicalDpi() const;
public slots:
QRegion doRedraw();
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 297d81abab..1e9acd79ed 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -247,7 +247,7 @@ static QString strippedText(QString s)
[mSavePanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())]
: [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : nil];
+ [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
// Call processEvents in case the event dispatcher has been interrupted, and needs to do
// cleanup of modal sessions. Do this before showing the native dialog, otherwise it will
@@ -274,7 +274,7 @@ static QString strippedText(QString s)
[self updateProperties];
[mSavePanel setDirectoryURL:selectable ? [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.filePath())]
: [NSURL fileURLWithPath:QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.path())]];
- [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : nil];
+ [mSavePanel setNameFieldStringValue:selectable ? QT_PREPEND_NAMESPACE(QCFString::toNSString)(info.fileName()) : @""];
NSWindow *nsparent = static_cast<NSWindow *>(qGuiApp->platformNativeInterface()->nativeResourceForWindow("nswindow", parent));
[mSavePanel beginSheetModalForWindow:nsparent completionHandler:^(NSInteger result){
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 5ec2cea362..066b2d9cc1 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -262,7 +262,7 @@ static const KeyPair entries[NumEntries] = {
{ NSF6FunctionKey, Qt::Key_F6 },
{ NSF7FunctionKey, Qt::Key_F7 },
{ NSF8FunctionKey, Qt::Key_F8 },
- { NSF9FunctionKey, Qt::Key_F8 },
+ { NSF9FunctionKey, Qt::Key_F9 },
{ NSF10FunctionKey, Qt::Key_F10 },
{ NSF11FunctionKey, Qt::Key_F11 },
{ NSF12FunctionKey, Qt::Key_F12 },
@@ -764,6 +764,9 @@ CGContextRef qt_mac_cg_context(QPaintDevice *pdev)
return ret;
}
+// qpaintengine_mac.mm
+extern void qt_mac_cgimage_data_free(void *, const void *memoryToFree, size_t);
+
CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
{
int width = qImage.width();
@@ -777,8 +780,7 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
const uchar *imageData = qImage.bits();
if (dataCopy) {
- delete[] *dataCopy;
- *dataCopy = new uchar[qImage.byteCount()];
+ *dataCopy = static_cast<uchar *>(malloc(qImage.byteCount()));
memcpy(*dataCopy, imageData, qImage.byteCount());
}
int bitDepth = qImage.depth();
@@ -789,7 +791,7 @@ CGImageRef qt_mac_toCGImage(const QImage &qImage, bool isMask, uchar **dataCopy)
NULL,
dataCopy ? *dataCopy : imageData,
qImage.byteCount(),
- NULL);
+ dataCopy ? qt_mac_cgimage_data_free : NULL);
CGImageRef cgImage = 0;
if (isMask) {
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index 40cffab3c9..dd99a6f3bc 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -104,9 +104,9 @@ QCocoaMenuItem::~QCocoaMenuItem()
{
if (m_merged) {
[m_native setHidden:YES];
+ } else {
+ [m_native release];
}
-
- [m_native release];
}
void QCocoaMenuItem::setText(const QString &text)
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index da53fe9c26..f0f1f56d90 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -46,6 +46,7 @@
#include "qcocoamenubar.h"
#include "qmacmime.h"
#include "qcocoahelpers.h"
+#include "qcocoaapplication.h"
#include <qbytearray.h>
#include <qwindow.h>
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index beaa50da6d..f8eed0ebf1 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -74,6 +74,8 @@ QCocoaTheme::QCocoaTheme()
QCocoaTheme::~QCocoaTheme()
{
delete m_systemPalette;
+ qDeleteAll(m_palettes);
+ qDeleteAll(m_fonts);
}
bool QCocoaTheme::usePlatformNativeDialog(DialogType dialogType) const
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index e74f9dcfe0..4e567c6c63 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -211,9 +211,8 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
m_qtView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
m_contentView = m_qtView;
setGeometry(tlw->geometry());
-
recreateWindow(parent());
-
+ tlw->setGeometry(geometry());
m_inConstructor = false;
}
@@ -395,8 +394,11 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint;
if (flags == Qt::Window) {
styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
- } else if ((flags & Qt::Dialog) && (window()->modality() != Qt::NonModal)) {
- styleMask = NSResizableWindowMask | NSTitledWindowMask;
+ } else if (flags & Qt::Dialog) {
+ if (window()->modality() == Qt::NonModal)
+ styleMask = NSResizableWindowMask | NSClosableWindowMask | NSTitledWindowMask;
+ else
+ styleMask = NSResizableWindowMask | NSTitledWindowMask;
} else if (!(flags & Qt::FramelessWindowHint)) {
if ((flags & Qt::Dialog) || (flags & Qt::WindowMaximizeButtonHint))
styleMask |= NSResizableWindowMask;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 3046b898df..568cc4bebf 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -102,7 +102,6 @@ static QTouchDevice *touchDevice = 0;
{
CGImageRelease(m_maskImage);
m_maskImage = 0;
- delete[] m_maskData;
m_maskData = 0;
m_window = 0;
if (m_subscribesForGlobalFrameNotifications) {
@@ -322,6 +321,7 @@ static QTouchDevice *touchDevice = 0;
CGImageRelease(m_maskImage);
if (region->isEmpty()) {
m_maskImage = 0;
+ return;
}
const QRect &rect = region->boundingRect();
diff --git a/src/plugins/platforms/eglfs/qeglfshooks.h b/src/plugins/platforms/eglfs/qeglfshooks.h
index c4ac7185fb..c8486b9378 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks.h
+++ b/src/plugins/platforms/eglfs/qeglfshooks.h
@@ -43,6 +43,7 @@
#define QEGLFSHOOKS_H
#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformscreen.h>
#include <QtGui/QSurfaceFormat>
#include <QtGui/QImage>
#include <EGL/egl.h>
@@ -61,6 +62,7 @@ public:
virtual EGLNativeDisplayType platformDisplay() const;
virtual QSizeF physicalScreenSize() const;
virtual QSize screenSize() const;
+ virtual QDpi logicalDpi() const;
virtual int screenDepth() const;
virtual QImage::Format screenFormat() const;
virtual QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const;
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index 8200fa70b2..5c264834b3 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -178,6 +178,15 @@ QSize QEglFSHooks::screenSize() const
return size;
}
+QDpi QEglFSHooks::logicalDpi() const
+{
+ QSizeF ps = physicalScreenSize();
+ QSize s = screenSize();
+
+ return QDpi(25.4 * s.width() / ps.width(),
+ 25.4 * s.height() / ps.height());
+}
+
int QEglFSHooks::screenDepth() const
{
static int depth = qgetenv("QT_QPA_EGLFS_DEPTH").toInt();
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 83f50dd382..e104bd7f2b 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -88,6 +88,12 @@ QSizeF QEglFSScreen::physicalSize() const
return QEglFSHooks::hooks()->physicalScreenSize();
}
+QDpi QEglFSScreen::logicalDpi() const
+{
+ return QEglFSHooks::hooks()->logicalDpi();
+}
+
+
QPlatformCursor *QEglFSScreen::cursor() const
{
return m_cursor;
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 8d3c5dbaec..298a67cd3a 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -64,6 +64,7 @@ public:
QImage::Format format() const;
QSizeF physicalSize() const;
+ QDpi logicalDpi() const;
QPlatformCursor *cursor() const;
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index d3966964e0..e2a6113010 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -44,7 +44,7 @@
#include <dlfcn.h>
-#include <QtGui/QOpenGlContext>
+#include <QtGui/QOpenGLContext>
#import <OpenGLES/EAGL.h>
#import <QuartzCore/CAEAGLLayer.h>
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 3265ed8e37..d86ed5f090 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -142,7 +142,7 @@ QIOSScreen::QIOSScreen(unsigned int screenIndex)
if (isQtApplication()) {
// When in a non-mixed environment, let QScreen follow the current interface orientation:
- setPrimaryOrientation(toQtScreenOrientation(rootViewController().interfaceOrientation));
+ setPrimaryOrientation(toQtScreenOrientation(UIDeviceOrientation(rootViewController().interfaceOrientation)));
}
[pool release];
diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h
index 5ccbcac710..b03f65f556 100644
--- a/src/plugins/platforms/ios/qiostheme.h
+++ b/src/plugins/platforms/ios/qiostheme.h
@@ -42,6 +42,7 @@
#ifndef QIOSTHEME_H
#define QIOSTHEME_H
+#include <QtCore/QHash>
#include <qpa/qplatformtheme.h>
QT_BEGIN_NAMESPACE
@@ -57,6 +58,9 @@ public:
const QFont *font(Font type = SystemFont) const;
static const char *name;
+
+private:
+ mutable QHash<QPlatformTheme::Font, QFont *> m_fonts;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm
index f98781f8a7..e7093185aa 100644
--- a/src/plugins/platforms/ios/qiostheme.mm
+++ b/src/plugins/platforms/ios/qiostheme.mm
@@ -59,6 +59,7 @@ QIOSTheme::QIOSTheme()
QIOSTheme::~QIOSTheme()
{
+ qDeleteAll(m_fonts);
}
QVariant QIOSTheme::themeHint(ThemeHint hint) const
@@ -73,8 +74,7 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const
const QFont *QIOSTheme::font(Font type) const
{
- static QHash<QPlatformTheme::Font, QFont *> fonts;
- if (fonts.isEmpty()) {
+ if (m_fonts.isEmpty()) {
// The real system font on iOS is '.Helvetica Neue UI', as returned by both [UIFont systemFontOfSize]
// and CTFontCreateUIFontForLanguage(kCTFontSystemFontType, ...), but this font is not included when
// populating the available fonts in QCoreTextFontDatabase::populateFontDatabase(), since the font
@@ -84,13 +84,13 @@ const QFont *QIOSTheme::font(Font type) const
// For now we hard-code the font to Helvetica, which should be very close to the actual
// system font.
QLatin1String systemFontFamilyName("Helvetica");
- fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize]));
- fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize]));
- fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize]));
- fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize]));
+ m_fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize]));
+ m_fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize]));
+ m_fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize]));
+ m_fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize]));
}
- return fonts.value(type, 0);
+ return m_fonts.value(type, 0);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosviewcontroller.mm b/src/plugins/platforms/ios/qiosviewcontroller.mm
index c52bfd7345..404b213966 100644
--- a/src/plugins/platforms/ios/qiosviewcontroller.mm
+++ b/src/plugins/platforms/ios/qiosviewcontroller.mm
@@ -78,7 +78,7 @@
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
Q_UNUSED(duration);
- Qt::ScreenOrientation orientation = toQtScreenOrientation(toInterfaceOrientation);
+ Qt::ScreenOrientation orientation = toQtScreenOrientation(UIDeviceOrientation(toInterfaceOrientation));
if (orientation == -1)
return;
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index e4fb5e2e1c..d7a2fa1a75 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -501,7 +501,7 @@ void QIOSWindow::handleContentOrientationChange(Qt::ScreenOrientation orientatio
{
// Keep the status bar in sync with content orientation. This will ensure
// that the task bar (and associated gestures) are aligned correctly:
- UIDeviceOrientation uiOrientation = fromQtScreenOrientation(orientation);
+ UIInterfaceOrientation uiOrientation = UIInterfaceOrientation(fromQtScreenOrientation(orientation));
[[UIApplication sharedApplication] setStatusBarOrientation:uiOrientation animated:NO];
}
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index b1afd7aca3..7a28fd9074 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -1354,7 +1354,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textBeforeOffset(long offse
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
if (QAccessibleTextInterface *textIface = textInterface()) {
- const QString txt = textIface->textBeforeOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ const QString txt = textIface->textBeforeOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
if (!txt.isEmpty()) {
*text = QStringToBSTR(txt);
return S_OK;
@@ -1374,7 +1374,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAfterOffset(
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
if (QAccessibleTextInterface *textIface = textInterface()) {
- const QString txt = textIface->textAfterOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ const QString txt = textIface->textAfterOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
if (!txt.isEmpty()) {
*text = QStringToBSTR(txt);
return S_OK;
@@ -1393,7 +1393,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAtOffset(long offset,
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
if (QAccessibleTextInterface *textIface = textInterface()) {
- const QString txt = textIface->textAtOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ const QString txt = textIface->textAtOffset(offset, (QAccessible::TextBoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
if (!txt.isEmpty()) {
*text = QStringToBSTR(txt);
return S_OK;
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 7e6b55dead..545484de8d 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -172,7 +172,7 @@ QWindowsUser32DLL::QWindowsUser32DLL() :
updateLayeredWindowIndirect(0),
isHungAppWindow(0),
registerTouchWindow(0), unregisterTouchWindow(0),
- getTouchInputInfo(0), closeTouchInputHandle(0)
+ getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0)
{
}
@@ -187,6 +187,7 @@ void QWindowsUser32DLL::init()
updateLayeredWindowIndirect = (UpdateLayeredWindowIndirect)(library.resolve("UpdateLayeredWindowIndirect"));
isHungAppWindow = (IsHungAppWindow)library.resolve("IsHungAppWindow");
+ setProcessDPIAware = (SetProcessDPIAware)library.resolve("SetProcessDPIAware");
}
bool QWindowsUser32DLL::initTouch()
@@ -252,7 +253,7 @@ struct QWindowsContextPrivate {
QSet<QString> m_registeredWindowClassNames;
HandleBaseWindowHash m_windows;
HDC m_displayContext;
- const int m_defaultDPI;
+ int m_defaultDPI;
QWindowsKeyMapper m_keyMapper;
QWindowsMouseHandler m_mouseHandler;
QWindowsMimeConverter m_mimeConverter;
@@ -266,8 +267,6 @@ struct QWindowsContextPrivate {
QWindowsContextPrivate::QWindowsContextPrivate() :
m_systemInfo(0),
- m_displayContext(GetDC(0)),
- m_defaultDPI(GetDeviceCaps(m_displayContext,LOGPIXELSY)),
m_oleInitializeResult(OleInitialize(NULL)),
m_eventType(QByteArrayLiteral("windows_generic_MSG")),
m_lastActiveWindow(0), m_asyncExpose(0)
@@ -276,6 +275,11 @@ QWindowsContextPrivate::QWindowsContextPrivate() :
QWindowsContext::user32dll.init();
QWindowsContext::shell32dll.init();
#endif
+ // Ensure metrics functions report correct data, QTBUG-30063.
+ if (QWindowsContext::user32dll.setProcessDPIAware)
+ QWindowsContext::user32dll.setProcessDPIAware();
+ m_displayContext = GetDC(0);
+ m_defaultDPI = GetDeviceCaps(m_displayContext, LOGPIXELSY);
const QSysInfo::WinVersion ver = QSysInfo::windowsVersion();
#ifndef Q_OS_WINCE
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 1fe71e3aff..d60b632beb 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -80,6 +80,7 @@ struct QWindowsUser32DLL
const BLENDFUNCTION *, DWORD);
typedef BOOL (WINAPI *UpdateLayeredWindowIndirect)(HWND, const UPDATELAYEREDWINDOWINFO *);
typedef BOOL (WINAPI *IsHungAppWindow)(HWND);
+ typedef BOOL (WINAPI *SetProcessDPIAware)();
// Functions missing in Q_CC_GNU stub libraries.
SetLayeredWindowAttributes setLayeredWindowAttributes;
@@ -94,6 +95,9 @@ struct QWindowsUser32DLL
UnregisterTouchWindow unregisterTouchWindow;
GetTouchInputInfo getTouchInputInfo;
CloseTouchInputHandle closeTouchInputHandle;
+
+ // Windows Vista onwards
+ SetProcessDPIAware setProcessDPIAware;
};
struct QWindowsShell32DLL
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 8565bf0204..5b84725edf 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -1457,9 +1457,7 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDi
{
public:
QWindowsFileDialogHelper() {}
- // For Qt 4 compatibility, do not create native non-modal dialogs on widgets,
- // but only on QQuickWindows, which do not have a fallback.
- virtual bool supportsNonModalDialog(const QWindow *parent = 0) const { return isQQuickWindow(parent); }
+ virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
virtual void setDirectory(const QString &directory);
@@ -1853,7 +1851,7 @@ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFile
{
public:
QWindowsXpFileDialogHelper() {}
- virtual bool supportsNonModalDialog(const QWindow *parent = 0) const { return isQQuickWindow(parent); }
+ virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return false; }
virtual bool defaultNameFilterDisables() const
{ return true; }
virtual void setDirectory(const QString &directory);
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index 6f59b33e62..da3e2a6a6a 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -279,7 +279,7 @@ static PIXELFORMATDESCRIPTOR
if (format.stereo())
pfd.dwFlags |= PFD_STEREO;
- if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer && !isPixmap)
+ if (format.swapBehavior() != QSurfaceFormat::SingleBuffer && !isPixmap)
pfd.dwFlags |= PFD_DOUBLEBUFFER;
pfd.cDepthBits =
format.depthBufferSize() >= 0 ? format.depthBufferSize() : 32;
@@ -389,12 +389,11 @@ static int choosePixelFormat(HDC hdc,
iAttributes[i++] = WGL_COLOR_BITS_ARB;
iAttributes[i++] = 24;
switch (format.swapBehavior()) {
- case QSurfaceFormat::DefaultSwapBehavior:
- break;
case QSurfaceFormat::SingleBuffer:
iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
iAttributes[i++] = FALSE;
break;
+ case QSurfaceFormat::DefaultSwapBehavior:
case QSurfaceFormat::DoubleBuffer:
case QSurfaceFormat::TripleBuffer:
iAttributes[i++] = WGL_DOUBLE_BUFFER_ARB;
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 30e0478e64..03e4925c3b 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -541,7 +541,6 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
case QPlatformIntegration::ShowIsFullScreen:
case QPlatformIntegration::PasswordMaskDelay:
case QPlatformIntegration::StartDragVelocity:
- case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
break; // Not implemented
case QPlatformIntegration::FontSmoothingGamma:
return QVariant(QWindowsFontDatabase::fontSmoothingGamma());
@@ -551,6 +550,11 @@ QVariant QWindowsIntegration::styleHint(QPlatformIntegration::StyleHint hint) co
break;
case QPlatformIntegration::UseRtlExtensions:
return QVariant(d->m_context.useRTLExtensions());
+ case QPlatformIntegration::SynthesizeMouseFromTouchEvents:
+ // We do not want Qt to synthesize mouse events as Windows also does that.
+ // Alternatively, Windows-generated touch mouse events can be identified and
+ // ignored by checking GetMessageExtraInfo() for MI_WP_SIGNATURE (0xFF515700).
+ return false;
}
return QPlatformIntegration::styleHint(hint);
}
diff --git a/src/printsupport/doc/src/qtprintsupport-module.qdoc b/src/printsupport/doc/src/qtprintsupport-module.qdoc
index 47420368e5..477b9a7097 100644
--- a/src/printsupport/doc/src/qtprintsupport-module.qdoc
+++ b/src/printsupport/doc/src/qtprintsupport-module.qdoc
@@ -27,7 +27,7 @@
/*!
\module QtPrintSupport
- \title Qt Print Support Module
+ \title Qt Print Support C++ Classes
\brief The Qt PrintSupport module provides classes to make printing easier and portable.
\ingroup modules
@@ -43,4 +43,3 @@
\snippet code/doc_src_qtprintsupport.pro 0
*/
-
diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index 25da004db8..e58710e0f5 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -1132,15 +1132,14 @@ void QDB2Result::detachFromResultSet()
/************************************/
QDB2Driver::QDB2Driver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QDB2DriverPrivate, parent)
{
- d = new QDB2DriverPrivate;
}
QDB2Driver::QDB2Driver(Qt::HANDLE env, Qt::HANDLE con, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QDB2DriverPrivate, parent)
{
- d = new QDB2DriverPrivate;
+ Q_D(QDB2Driver);
d->hEnv = (SQLHANDLE)env;
d->hDbc = (SQLHANDLE)con;
if (env && con) {
@@ -1157,6 +1156,7 @@ QDB2Driver::~QDB2Driver()
bool QDB2Driver::open(const QString& db, const QString& user, const QString& password, const QString& host, int port,
const QString& connOpts)
{
+ Q_D(QDB2Driver);
if (isOpen())
close();
SQLRETURN r;
@@ -1259,6 +1259,7 @@ bool QDB2Driver::open(const QString& db, const QString& user, const QString& pas
void QDB2Driver::close()
{
+ Q_D(QDB2Driver);
SQLRETURN r;
if (d->hDbc) {
// Open statements/descriptors handles are automatically cleaned up by SQLDisconnect
@@ -1285,11 +1286,13 @@ void QDB2Driver::close()
QSqlResult *QDB2Driver::createResult() const
{
+ Q_D(const QDB2Driver);
return new QDB2Result(this, d);
}
QSqlRecord QDB2Driver::record(const QString& tableName) const
{
+ Q_D(const QDB2Driver);
QSqlRecord fil;
if (!isOpen())
return fil;
@@ -1363,6 +1366,7 @@ QSqlRecord QDB2Driver::record(const QString& tableName) const
QStringList QDB2Driver::tables(QSql::TableType type) const
{
+ Q_D(const QDB2Driver);
QStringList tl;
if (!isOpen())
return tl;
@@ -1434,6 +1438,7 @@ QStringList QDB2Driver::tables(QSql::TableType type) const
QSqlIndex QDB2Driver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QDB2Driver);
QSqlIndex index(tablename);
if (!isOpen())
return index;
@@ -1535,6 +1540,7 @@ bool QDB2Driver::beginTransaction()
bool QDB2Driver::commitTransaction()
{
+ Q_D(QDB2Driver);
if (!isOpen()) {
qWarning("QDB2Driver::commitTransaction: Database not open");
return false;
@@ -1552,6 +1558,7 @@ bool QDB2Driver::commitTransaction()
bool QDB2Driver::rollbackTransaction()
{
+ Q_D(QDB2Driver);
if (!isOpen()) {
qWarning("QDB2Driver::rollbackTransaction: Database not open");
return false;
@@ -1569,6 +1576,7 @@ bool QDB2Driver::rollbackTransaction()
bool QDB2Driver::setAutoCommit(bool autoCommit)
{
+ Q_D(QDB2Driver);
SQLUINTEGER ac = autoCommit ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF;
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
@@ -1627,6 +1635,7 @@ QString QDB2Driver::formatValue(const QSqlField &field, bool trimStrings) const
QVariant QDB2Driver::handle() const
{
+ Q_D(const QDB2Driver);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
}
diff --git a/src/sql/drivers/db2/qsql_db2_p.h b/src/sql/drivers/db2/qsql_db2_p.h
index 68563448ed..89b07c9c83 100644
--- a/src/sql/drivers/db2/qsql_db2_p.h
+++ b/src/sql/drivers/db2/qsql_db2_p.h
@@ -101,6 +101,7 @@ private:
class Q_EXPORT_SQLDRIVER_DB2 QDB2Driver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QDB2Driver)
Q_OBJECT
public:
explicit QDB2Driver(QObject* parent = 0);
@@ -127,7 +128,6 @@ public:
private:
bool setAutoCommit(bool autoCommit);
- QDB2DriverPrivate* d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index 2137514679..bd97db189c 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -312,11 +312,13 @@ struct QIBaseEventBuffer {
class QIBaseDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QIBaseDriver)
public:
- QIBaseDriverPrivate(QIBaseDriver *d) : QSqlDriverPrivate(), q(d), ibase(0), trans(0), tc(0) { dbmsType = Interbase; }
+ QIBaseDriverPrivate() : QSqlDriverPrivate(), ibase(0), trans(0), tc(0) { dbmsType = Interbase; }
bool isError(const char *msg, QSqlError::ErrorType typ = QSqlError::UnknownError)
{
+ Q_Q(QIBaseDriver);
QString imsg;
ISC_LONG sqlcode;
if (!getIBaseError(imsg, status, sqlcode, tc))
@@ -328,7 +330,6 @@ public:
}
public:
- QIBaseDriver* q;
isc_db_handle ibase;
isc_tr_handle trans;
QTextCodec *tc;
@@ -418,9 +419,9 @@ public:
QIBaseResultPrivate::QIBaseResultPrivate(QIBaseResult *d, const QIBaseDriver *ddb):
- q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d->tc)
+ q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d_func()->ibase), sqlda(0), inda(0), queryType(-1), tc(ddb->d_func()->tc)
{
- localTransaction = (ddb->d->ibase == 0);
+ localTransaction = (ddb->d_func()->ibase == 0);
}
void QIBaseResultPrivate::cleanup()
@@ -861,9 +862,9 @@ bool QIBaseResultPrivate::transaction()
{
if (trans)
return true;
- if (db->d->trans) {
+ if (db->d_func()->trans) {
localTransaction = false;
- trans = db->d->trans;
+ trans = db->d_func()->trans;
return true;
}
localTransaction = true;
@@ -1396,15 +1397,14 @@ QVariant QIBaseResult::handle() const
/*********************************/
QIBaseDriver::QIBaseDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QIBaseDriverPrivate, parent)
{
- d = new QIBaseDriverPrivate(this);
}
QIBaseDriver::QIBaseDriver(isc_db_handle connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QIBaseDriverPrivate, parent)
{
- d = new QIBaseDriverPrivate(this);
+ Q_D(QIBaseDriver);
d->ibase = connection;
setOpen(true);
setOpenError(false);
@@ -1444,6 +1444,7 @@ bool QIBaseDriver::open(const QString & db,
int /*port*/,
const QString & connOpts)
{
+ Q_D(QIBaseDriver);
if (isOpen())
close();
@@ -1526,6 +1527,7 @@ bool QIBaseDriver::open(const QString & db,
void QIBaseDriver::close()
{
+ Q_D(QIBaseDriver);
if (isOpen()) {
if (d->eventBuffers.size()) {
@@ -1562,6 +1564,7 @@ QSqlResult *QIBaseDriver::createResult() const
bool QIBaseDriver::beginTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (d->trans)
@@ -1574,6 +1577,7 @@ bool QIBaseDriver::beginTransaction()
bool QIBaseDriver::commitTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (!d->trans)
@@ -1587,6 +1591,7 @@ bool QIBaseDriver::commitTransaction()
bool QIBaseDriver::rollbackTransaction()
{
+ Q_D(QIBaseDriver);
if (!isOpen() || isOpenError())
return false;
if (!d->trans)
@@ -1749,6 +1754,7 @@ QString QIBaseDriver::formatValue(const QSqlField &field, bool trimStrings) cons
QVariant QIBaseDriver::handle() const
{
+ Q_D(const QIBaseDriver);
return QVariant(qRegisterMetaType<isc_db_handle>("isc_db_handle"), &d->ibase);
}
@@ -1777,6 +1783,7 @@ static isc_callback qEventCallback(char *result, short length, char *updated)
bool QIBaseDriver::subscribeToNotification(const QString &name)
{
+ Q_D(QIBaseDriver);
if (!isOpen()) {
qWarning("QIBaseDriver::subscribeFromNotificationImplementation: database not open.");
return false;
@@ -1826,6 +1833,7 @@ bool QIBaseDriver::subscribeToNotification(const QString &name)
bool QIBaseDriver::unsubscribeFromNotification(const QString &name)
{
+ Q_D(QIBaseDriver);
if (!isOpen()) {
qWarning("QIBaseDriver::unsubscribeFromNotificationImplementation: database not open.");
return false;
@@ -1855,11 +1863,13 @@ bool QIBaseDriver::unsubscribeFromNotification(const QString &name)
QStringList QIBaseDriver::subscribedToNotifications() const
{
+ Q_D(const QIBaseDriver);
return QStringList(d->eventBuffers.keys());
}
void QIBaseDriver::qHandleEventNotification(void *updatedResultBuffer)
{
+ Q_D(QIBaseDriver);
QMap<QString, QIBaseEventBuffer *>::const_iterator i;
for (i = d->eventBuffers.constBegin(); i != d->eventBuffers.constEnd(); ++i) {
QIBaseEventBuffer* eBuffer = i.value();
diff --git a/src/sql/drivers/ibase/qsql_ibase_p.h b/src/sql/drivers/ibase/qsql_ibase_p.h
index b2560ca17c..ab9edfd1a5 100644
--- a/src/sql/drivers/ibase/qsql_ibase_p.h
+++ b/src/sql/drivers/ibase/qsql_ibase_p.h
@@ -64,9 +64,9 @@ class QIBaseDriver;
class QIBaseDriver : public QSqlDriver
{
- Q_OBJECT
- friend class QIBaseDriverPrivate;
friend class QIBaseResultPrivate;
+ Q_DECLARE_PRIVATE(QIBaseDriver)
+ Q_OBJECT
public:
explicit QIBaseDriver(QObject *parent = 0);
explicit QIBaseDriver(isc_db_handle connection, QObject *parent = 0);
@@ -104,9 +104,6 @@ public:
private Q_SLOTS:
void qHandleEventNotification(void* updatedResultBuffer);
-
-private:
- QIBaseDriverPrivate* d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 871b13182f..0e20cf539e 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -435,8 +435,8 @@ void QMYSQLResult::cleanup()
// must iterate trough leftover result sets from multi-selects or stored procedures
// if this isn't done subsequent queries will fail with "Commands out of sync"
#if MYSQL_VERSION_ID >= 40100
- while (d->driver && d->driver->d->mysql && mysql_next_result(d->driver->d->mysql) == 0) {
- MYSQL_RES *res = mysql_store_result(d->driver->d->mysql);
+ while (d->driver && d->driver->d_func()->mysql && mysql_next_result(d->driver->d_func()->mysql) == 0) {
+ MYSQL_RES *res = mysql_store_result(d->driver->d_func()->mysql);
if (res)
mysql_free_result(res);
}
@@ -606,7 +606,7 @@ QVariant QMYSQLResult::data(int field)
return QVariant(f.type);
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d->tc, f.outField, f.bufLength);
+ val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength);
} else {
if (d->row[field] == NULL) {
// NULL value
@@ -614,7 +614,7 @@ QVariant QMYSQLResult::data(int field)
}
fieldLength = mysql_fetch_lengths(d->result)[field];
if (f.type != QVariant::ByteArray)
- val = toUnicode(d->driver->d->tc, d->row[field], fieldLength);
+ val = toUnicode(d->driver->d_func()->tc, d->row[field], fieldLength);
}
switch(f.type) {
@@ -693,22 +693,22 @@ bool QMYSQLResult::reset (const QString& query)
cleanup();
- const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
- if (mysql_real_query(d->driver->d->mysql, encQuery.data(), encQuery.length())) {
+ const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
+ if (mysql_real_query(d->driver->d_func()->mysql, encQuery.data(), encQuery.length())) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute query"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- d->result = mysql_store_result(d->driver->d->mysql);
- if (!d->result && mysql_field_count(d->driver->d->mysql) > 0) {
+ d->result = mysql_store_result(d->driver->d_func()->mysql);
+ if (!d->result && mysql_field_count(d->driver->d_func()->mysql) > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store result"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- int numFields = mysql_field_count(d->driver->d->mysql);
+ int numFields = mysql_field_count(d->driver->d_func()->mysql);
setSelect(numFields != 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
+ d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
if (isSelect()) {
for(int i = 0; i < numFields; i++) {
@@ -753,7 +753,7 @@ QVariant QMYSQLResult::lastInsertId() const
return QVariant(id);
#endif
} else {
- quint64 id = mysql_insert_id(d->driver->d->mysql);
+ quint64 id = mysql_insert_id(d->driver->d_func()->mysql);
if (id)
return QVariant(id);
}
@@ -773,11 +773,11 @@ QSqlRecord QMYSQLResult::record() const
res = d->result;
#endif
- if (!mysql_errno(d->driver->d->mysql)) {
+ if (!mysql_errno(d->driver->d_func()->mysql)) {
mysql_field_seek(res, 0);
MYSQL_FIELD* field = mysql_fetch_field(res);
while(field) {
- info.append(qToField(field, d->driver->d->tc));
+ info.append(qToField(field, d->driver->d_func()->tc));
field = mysql_fetch_field(res);
}
}
@@ -802,26 +802,26 @@ bool QMYSQLResult::nextResult()
delete[] d->fields[i].outField;
d->fields.clear();
- int status = mysql_next_result(d->driver->d->mysql);
+ int status = mysql_next_result(d->driver->d_func()->mysql);
if (status > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to execute next query"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
} else if (status == -1) {
return false; // No more result sets
}
- d->result = mysql_store_result(d->driver->d->mysql);
- int numFields = mysql_field_count(d->driver->d->mysql);
+ d->result = mysql_store_result(d->driver->d_func()->mysql);
+ int numFields = mysql_field_count(d->driver->d_func()->mysql);
if (!d->result && numFields > 0) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to store next result"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
setSelect(numFields > 0);
d->fields.resize(numFields);
- d->rowsAffected = mysql_affected_rows(d->driver->d->mysql);
+ d->rowsAffected = mysql_affected_rows(d->driver->d_func()->mysql);
if (isSelect()) {
for (int i = 0; i < numFields; i++) {
@@ -874,7 +874,7 @@ bool QMYSQLResult::prepare(const QString& query)
return false;
#if MYSQL_VERSION_ID >= 40108
cleanup();
- if (!d->driver->d->preparedQuerysEnabled)
+ if (!d->driver->d_func()->preparedQuerysEnabled)
return QSqlResult::prepare(query);
int r;
@@ -883,14 +883,14 @@ bool QMYSQLResult::prepare(const QString& query)
return false;
if (!d->stmt)
- d->stmt = mysql_stmt_init(d->driver->d->mysql);
+ d->stmt = mysql_stmt_init(d->driver->d_func()->mysql);
if (!d->stmt) {
setLastError(qMakeError(QCoreApplication::translate("QMYSQLResult", "Unable to prepare statement"),
- QSqlError::StatementError, d->driver->d));
+ QSqlError::StatementError, d->driver->d_func()));
return false;
}
- const QByteArray encQuery(fromUnicode(d->driver->d->tc, query));
+ const QByteArray encQuery(fromUnicode(d->driver->d_func()->tc, query));
r = mysql_stmt_prepare(d->stmt, encQuery.constData(), encQuery.length());
if (r != 0) {
setLastError(qMakeStmtError(QCoreApplication::translate("QMYSQLResult",
@@ -1010,7 +1010,7 @@ bool QMYSQLResult::exec()
break;
case QVariant::String:
default: {
- QByteArray ba = fromUnicode(d->driver->d->tc, val.toString());
+ QByteArray ba = fromUnicode(d->driver->d_func()->tc, val.toString());
stringVector.append(ba);
currBind->buffer_type = MYSQL_TYPE_STRING;
currBind->buffer = const_cast<char *>(ba.constData());
@@ -1115,7 +1115,7 @@ static void qLibraryEnd()
}
QMYSQLDriver::QMYSQLDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QMYSQLDriverPrivate, parent)
{
init();
qLibraryInit();
@@ -1127,8 +1127,9 @@ QMYSQLDriver::QMYSQLDriver(QObject * parent)
*/
QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QMYSQLDriverPrivate, parent)
{
+ Q_D(QMYSQLDriver);
init();
if (con) {
d->mysql = (MYSQL *) con;
@@ -1146,7 +1147,7 @@ QMYSQLDriver::QMYSQLDriver(MYSQL * con, QObject * parent)
void QMYSQLDriver::init()
{
- d = new QMYSQLDriverPrivate();
+ Q_D(QMYSQLDriver);
d->mysql = 0;
qMySqlConnectionCount++;
}
@@ -1160,6 +1161,7 @@ QMYSQLDriver::~QMYSQLDriver()
bool QMYSQLDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QMYSQLDriver);
switch (f) {
case Transactions:
// CLIENT_TRANSACTION should be defined in all recent mysql client libs > 3.23.34
@@ -1227,6 +1229,7 @@ bool QMYSQLDriver::open(const QString& db,
int port,
const QString& connOpts)
{
+ Q_D(QMYSQLDriver);
if (isOpen())
close();
@@ -1328,6 +1331,7 @@ bool QMYSQLDriver::open(const QString& db,
void QMYSQLDriver::close()
{
+ Q_D(QMYSQLDriver);
if (isOpen()) {
#ifndef QT_NO_THREAD
mysql_thread_end();
@@ -1346,6 +1350,7 @@ QSqlResult *QMYSQLDriver::createResult() const
QStringList QMYSQLDriver::tables(QSql::TableType type) const
{
+ Q_D(const QMYSQLDriver);
QStringList tl;
#if MYSQL_VERSION_ID >= 40100
if( mysql_get_server_version(d->mysql) < 50000)
@@ -1413,6 +1418,7 @@ QSqlIndex QMYSQLDriver::primaryIndex(const QString& tablename) const
QSqlRecord QMYSQLDriver::record(const QString& tablename) const
{
+ Q_D(const QMYSQLDriver);
QString table=tablename;
if(isIdentifierEscaped(table, QSqlDriver::TableName))
table = stripDelimiters(table, QSqlDriver::TableName);
@@ -1434,11 +1440,13 @@ QSqlRecord QMYSQLDriver::record(const QString& tablename) const
QVariant QMYSQLDriver::handle() const
{
+ Q_D(const QMYSQLDriver);
return QVariant::fromValue(d->mysql);
}
bool QMYSQLDriver::beginTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1456,6 +1464,7 @@ bool QMYSQLDriver::beginTransaction()
bool QMYSQLDriver::commitTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1473,6 +1482,7 @@ bool QMYSQLDriver::commitTransaction()
bool QMYSQLDriver::rollbackTransaction()
{
+ Q_D(QMYSQLDriver);
#ifndef CLIENT_TRANSACTIONS
return false;
#endif
@@ -1490,6 +1500,7 @@ bool QMYSQLDriver::rollbackTransaction()
QString QMYSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
{
+ Q_D(const QMYSQLDriver);
QString r;
if (field.isNull()) {
r = QLatin1String("NULL");
diff --git a/src/sql/drivers/mysql/qsql_mysql_p.h b/src/sql/drivers/mysql/qsql_mysql_p.h
index c23bcd92d7..a1be139b2a 100644
--- a/src/sql/drivers/mysql/qsql_mysql_p.h
+++ b/src/sql/drivers/mysql/qsql_mysql_p.h
@@ -110,8 +110,9 @@ private:
class Q_EXPORT_SQLDRIVER_MYSQL QMYSQLDriver : public QSqlDriver
{
- Q_OBJECT
friend class QMYSQLResult;
+ Q_DECLARE_PRIVATE(QMYSQLDriver)
+ Q_OBJECT
public:
explicit QMYSQLDriver(QObject *parent=0);
explicit QMYSQLDriver(MYSQL *con, QObject * parent=0);
@@ -141,7 +142,6 @@ protected:
bool rollbackTransaction();
private:
void init();
- QMYSQLDriverPrivate* d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index 6eb6703ebf..fe9ae42e6f 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -2088,10 +2088,9 @@ void QOCIResult::virtual_hook(int id, void *data)
QOCIDriver::QOCIDriver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QOCIDriverPrivate, parent)
{
- d = new QOCIDriverPrivate();
-
+ Q_D(QOCIDriver);
#ifdef QOCI_THREADED
const ub4 mode = OCI_UTF16 | OCI_OBJECT | OCI_THREADED;
#else
@@ -2116,9 +2115,9 @@ QOCIDriver::QOCIDriver(QObject* parent)
}
QOCIDriver::QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QOCIDriverPrivate, parent)
{
- d = new QOCIDriverPrivate();
+ Q_D(QOCIDriver);
d->env = env;
d->svc = ctx;
@@ -2132,6 +2131,7 @@ QOCIDriver::QOCIDriver(OCIEnv* env, OCISvcCtx* ctx, QObject* parent)
QOCIDriver::~QOCIDriver()
{
+ Q_D(QOCIDriver);
if (isOpen())
close();
int r = OCIHandleFree(d->err, OCI_HTYPE_ERROR);
@@ -2144,6 +2144,7 @@ QOCIDriver::~QOCIDriver()
bool QOCIDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QOCIDriver);
switch (f) {
case Transactions:
case LastInsertId:
@@ -2202,6 +2203,7 @@ bool QOCIDriver::open(const QString & db,
int port,
const QString &opts)
{
+ Q_D(QOCIDriver);
int r;
if (isOpen())
@@ -2288,6 +2290,7 @@ bool QOCIDriver::open(const QString & db,
void QOCIDriver::close()
{
+ Q_D(QOCIDriver);
if (!isOpen())
return;
@@ -2305,11 +2308,13 @@ void QOCIDriver::close()
QSqlResult *QOCIDriver::createResult() const
{
+ Q_D(const QOCIDriver);
return new QOCIResult(this, d);
}
bool QOCIDriver::beginTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::beginTransaction: Database not open");
return false;
@@ -2330,6 +2335,7 @@ bool QOCIDriver::beginTransaction()
bool QOCIDriver::commitTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::commitTransaction: Database not open");
return false;
@@ -2349,6 +2355,7 @@ bool QOCIDriver::commitTransaction()
bool QOCIDriver::rollbackTransaction()
{
+ Q_D(QOCIDriver);
if (!isOpen()) {
qWarning("QOCIDriver::rollbackTransaction: Database not open");
return false;
@@ -2368,6 +2375,7 @@ bool QOCIDriver::rollbackTransaction()
QStringList QOCIDriver::tables(QSql::TableType type) const
{
+ Q_D(const QOCIDriver);
QStringList tl;
QStringList sysUsers = QStringList() << QLatin1String("MDSYS")
<< QLatin1String("LBACSYS")
@@ -2473,6 +2481,7 @@ void qSplitTableAndOwner(const QString & tname, QString * tbl,
QSqlRecord QOCIDriver::record(const QString& tablename) const
{
+ Q_D(const QOCIDriver);
QSqlRecord fil;
if (!isOpen())
return fil;
@@ -2546,6 +2555,7 @@ QSqlRecord QOCIDriver::record(const QString& tablename) const
QSqlIndex QOCIDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QOCIDriver);
QSqlIndex idx(tablename);
if (!isOpen())
return idx;
@@ -2666,6 +2676,7 @@ QString QOCIDriver::formatValue(const QSqlField &field, bool trimStrings) const
QVariant QOCIDriver::handle() const
{
+ Q_D(const QOCIDriver);
return QVariant::fromValue(d->env);
}
diff --git a/src/sql/drivers/oci/qsql_oci_p.h b/src/sql/drivers/oci/qsql_oci_p.h
index 0b874e6be3..c55a4209fa 100644
--- a/src/sql/drivers/oci/qsql_oci_p.h
+++ b/src/sql/drivers/oci/qsql_oci_p.h
@@ -73,6 +73,7 @@ class QOCIDriverPrivate;
class Q_EXPORT_SQLDRIVER_OCI QOCIDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QOCIDriver)
Q_OBJECT
friend struct QOCIResultPrivate;
friend class QOCIPrivate;
@@ -101,8 +102,6 @@ protected:
bool beginTransaction();
bool commitTransaction();
bool rollbackTransaction();
-private:
- QOCIDriverPrivate *d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index f92cda8c25..d36a224d8e 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -188,13 +188,13 @@ public:
bool QODBCPrivate::isStmtHandleValid(const QSqlDriver *driver)
{
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- return disconnectCount == odbcdriver->d->disconnectCount;
+ return disconnectCount == odbcdriver->d_func()->disconnectCount;
}
void QODBCPrivate::updateStmtHandleState(const QSqlDriver *driver)
{
const QODBCDriver *odbcdriver = static_cast<const QODBCDriver*> (driver);
- disconnectCount = odbcdriver->d->disconnectCount;
+ disconnectCount = odbcdriver->d_func()->disconnectCount;
}
static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode = 0)
@@ -1767,15 +1767,14 @@ void QODBCResult::setForwardOnly(bool forward)
QODBCDriver::QODBCDriver(QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QODBCDriverPrivate, parent)
{
- init();
}
-QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent)
- : QSqlDriver(parent)
+QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject *parent)
+ : QSqlDriver(*new QODBCDriverPrivate, parent)
{
- init();
+ Q_D(QODBCDriver);
d->hEnv = env;
d->hDbc = con;
if (env && con) {
@@ -1784,11 +1783,6 @@ QODBCDriver::QODBCDriver(SQLHANDLE env, SQLHANDLE con, QObject * parent)
}
}
-void QODBCDriver::init()
-{
- d = new QODBCDriverPrivate();
-}
-
QODBCDriver::~QODBCDriver()
{
cleanup();
@@ -1796,6 +1790,7 @@ QODBCDriver::~QODBCDriver()
bool QODBCDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QODBCDriver);
switch (f) {
case Transactions: {
if (!d->hDbc)
@@ -1850,6 +1845,7 @@ bool QODBCDriver::open(const QString & db,
int,
const QString& connOpts)
{
+ Q_D(QODBCDriver);
if (isOpen())
close();
SQLRETURN r;
@@ -1946,9 +1942,8 @@ void QODBCDriver::close()
void QODBCDriver::cleanup()
{
+ Q_D(QODBCDriver);
SQLRETURN r;
- if (!d)
- return;
if(d->hDbc) {
// Open statements/descriptors handles are automatically cleaned up by SQLDisconnect
@@ -2196,11 +2191,13 @@ void QODBCDriverPrivate::checkDateTimePrecision()
QSqlResult *QODBCDriver::createResult() const
{
- return new QODBCResult(this, d);
+ Q_D(const QODBCDriver);
+ return new QODBCResult(this, const_cast<QODBCDriverPrivate*>(d));
}
bool QODBCDriver::beginTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::beginTransaction: Database not open";
return false;
@@ -2220,6 +2217,7 @@ bool QODBCDriver::beginTransaction()
bool QODBCDriver::commitTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::commitTransaction: Database not open";
return false;
@@ -2237,6 +2235,7 @@ bool QODBCDriver::commitTransaction()
bool QODBCDriver::rollbackTransaction()
{
+ Q_D(QODBCDriver);
if (!isOpen()) {
qWarning() << "QODBCDriver::rollbackTransaction: Database not open";
return false;
@@ -2254,6 +2253,7 @@ bool QODBCDriver::rollbackTransaction()
bool QODBCDriver::endTrans()
{
+ Q_D(QODBCDriver);
SQLUINTEGER ac(SQL_AUTOCOMMIT_ON);
SQLRETURN r = SQLSetConnectAttr(d->hDbc,
SQL_ATTR_AUTOCOMMIT,
@@ -2268,6 +2268,7 @@ bool QODBCDriver::endTrans()
QStringList QODBCDriver::tables(QSql::TableType type) const
{
+ Q_D(const QODBCDriver);
QStringList tl;
if (!isOpen())
return tl;
@@ -2345,6 +2346,7 @@ QStringList QODBCDriver::tables(QSql::TableType type) const
QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QODBCDriver);
QSqlIndex index(tablename);
if (!isOpen())
return index;
@@ -2360,7 +2362,7 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
return index;
}
QString catalog, schema, table;
- d->splitTableQualifier(tablename, catalog, schema, table);
+ const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@@ -2472,13 +2474,14 @@ QSqlIndex QODBCDriver::primaryIndex(const QString& tablename) const
QSqlRecord QODBCDriver::record(const QString& tablename) const
{
+ Q_D(const QODBCDriver);
QSqlRecord fil;
if (!isOpen())
return fil;
SQLHANDLE hStmt;
QString catalog, schema, table;
- d->splitTableQualifier(tablename, catalog, schema, table);
+ const_cast<QODBCDriverPrivate*>(d)->splitTableQualifier(tablename, catalog, schema, table);
if (isIdentifierEscaped(catalog, QSqlDriver::TableName))
catalog = stripDelimiters(catalog, QSqlDriver::TableName);
@@ -2597,12 +2600,14 @@ QString QODBCDriver::formatValue(const QSqlField &field,
QVariant QODBCDriver::handle() const
{
+ Q_D(const QODBCDriver);
return QVariant(qRegisterMetaType<SQLHANDLE>("SQLHANDLE"), &d->hDbc);
}
QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType) const
{
- QChar quote = d->quoteChar();
+ Q_D(const QODBCDriver);
+ QChar quote = const_cast<QODBCDriverPrivate*>(d)->quoteChar();
QString res = identifier;
if(!identifier.isEmpty() && !identifier.startsWith(quote) && !identifier.endsWith(quote) ) {
res.replace(quote, QString(quote)+QString(quote));
@@ -2614,7 +2619,8 @@ QString QODBCDriver::escapeIdentifier(const QString &identifier, IdentifierType)
bool QODBCDriver::isIdentifierEscaped(const QString &identifier, IdentifierType) const
{
- QChar quote = d->quoteChar();
+ Q_D(const QODBCDriver);
+ QChar quote = const_cast<QODBCDriverPrivate*>(d)->quoteChar();
return identifier.size() > 2
&& identifier.startsWith(quote) //left delimited
&& identifier.endsWith(quote); //right delimited
diff --git a/src/sql/drivers/odbc/qsql_odbc_p.h b/src/sql/drivers/odbc/qsql_odbc_p.h
index 191f64f072..b18768a5a2 100644
--- a/src/sql/drivers/odbc/qsql_odbc_p.h
+++ b/src/sql/drivers/odbc/qsql_odbc_p.h
@@ -123,6 +123,7 @@ private:
class Q_EXPORT_SQLDRIVER_ODBC QODBCDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QODBCDriver)
Q_OBJECT
public:
explicit QODBCDriver(QObject *parent=0);
@@ -154,10 +155,8 @@ protected:
bool rollbackTransaction();
private:
- void init();
bool endTrans();
void cleanup();
- QODBCDriverPrivate* d;
friend class QODBCPrivate;
};
diff --git a/src/sql/drivers/psql/qsql_psql.cpp b/src/sql/drivers/psql/qsql_psql.cpp
index aed0a11218..9331f5c371 100644
--- a/src/sql/drivers/psql/qsql_psql.cpp
+++ b/src/sql/drivers/psql/qsql_psql.cpp
@@ -124,9 +124,9 @@ inline void qPQfreemem(void *buffer)
class QPSQLDriverPrivate : public QSqlDriverPrivate
{
+ Q_DECLARE_PUBLIC(QPSQLDriver)
public:
- QPSQLDriverPrivate(QPSQLDriver *qq) : QSqlDriverPrivate(),
- q(qq),
+ QPSQLDriverPrivate() : QSqlDriverPrivate(),
connection(0),
isUtf8(false),
pro(QPSQLDriver::Version6),
@@ -135,7 +135,6 @@ public:
hasBackslashEscape(false)
{ dbmsType = PostgreSQL; }
- QPSQLDriver *q;
PGconn *connection;
bool isUtf8;
QPSQLDriver::Protocol pro;
@@ -179,10 +178,11 @@ void QPSQLDriverPrivate::appendTables(QStringList &tl, QSqlQuery &t, QChar type)
PGresult * QPSQLDriverPrivate::exec(const char * stmt) const
{
+ Q_Q(const QPSQLDriver);
PGresult *result = PQexec(connection, stmt);
if (seid.size() && !pendingNotifyCheck) {
pendingNotifyCheck = true;
- QMetaObject::invokeMethod(q, "_q_handleNotification", Qt::QueuedConnection, Q_ARG(int,0));
+ QMetaObject::invokeMethod(const_cast<QPSQLDriver*>(q), "_q_handleNotification", Qt::QueuedConnection, Q_ARG(int,0));
}
return result;
}
@@ -205,7 +205,11 @@ public:
QString fieldSerial(int i) const { return QLatin1Char('$') + QString::number(i + 1); }
void deallocatePreparedStmt();
- const QPSQLDriverPrivate * privDriver() const {Q_Q(const QPSQLResult); return reinterpret_cast<const QPSQLDriver *>(q->driver())->d; }
+ const QPSQLDriverPrivate * privDriver() const
+ {
+ Q_Q(const QPSQLResult);
+ return reinterpret_cast<const QPSQLDriver *>(q->driver())->d_func();
+ }
PGresult *result;
int currentSize;
@@ -767,15 +771,14 @@ QPSQLDriver::Protocol QPSQLDriverPrivate::getPSQLVersion()
}
QPSQLDriver::QPSQLDriver(QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QPSQLDriverPrivate, parent)
{
- init();
}
QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QPSQLDriverPrivate, parent)
{
- init();
+ Q_D(QPSQLDriver);
d->connection = conn;
if (conn) {
d->pro = d->getPSQLVersion();
@@ -785,24 +788,22 @@ QPSQLDriver::QPSQLDriver(PGconn *conn, QObject *parent)
}
}
-void QPSQLDriver::init()
-{
- d = new QPSQLDriverPrivate(this);
-}
-
QPSQLDriver::~QPSQLDriver()
{
+ Q_D(QPSQLDriver);
if (d->connection)
PQfinish(d->connection);
}
QVariant QPSQLDriver::handle() const
{
+ Q_D(const QPSQLDriver);
return QVariant::fromValue(d->connection);
}
bool QPSQLDriver::hasFeature(DriverFeature f) const
{
+ Q_D(const QPSQLDriver);
switch (f) {
case Transactions:
case QuerySize:
@@ -849,6 +850,7 @@ bool QPSQLDriver::open(const QString & db,
int port,
const QString& connOpts)
{
+ Q_D(QPSQLDriver);
if (isOpen())
close();
QString connectString;
@@ -891,6 +893,7 @@ bool QPSQLDriver::open(const QString & db,
void QPSQLDriver::close()
{
+ Q_D(QPSQLDriver);
if (isOpen()) {
d->seid.clear();
@@ -915,6 +918,7 @@ QSqlResult *QPSQLDriver::createResult() const
bool QPSQLDriver::beginTransaction()
{
+ Q_D(const QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::beginTransaction: Database not open");
return false;
@@ -932,6 +936,7 @@ bool QPSQLDriver::beginTransaction()
bool QPSQLDriver::commitTransaction()
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::commitTransaction: Database not open");
return false;
@@ -965,6 +970,7 @@ bool QPSQLDriver::commitTransaction()
bool QPSQLDriver::rollbackTransaction()
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::rollbackTransaction: Database not open");
return false;
@@ -982,6 +988,7 @@ bool QPSQLDriver::rollbackTransaction()
QStringList QPSQLDriver::tables(QSql::TableType type) const
{
+ Q_D(const QPSQLDriver);
QStringList tl;
if (!isOpen())
return tl;
@@ -989,9 +996,9 @@ QStringList QPSQLDriver::tables(QSql::TableType type) const
t.setForwardOnly(true);
if (type & QSql::Tables)
- d->appendTables(tl, t, QLatin1Char('r'));
+ const_cast<QPSQLDriverPrivate*>(d)->appendTables(tl, t, QLatin1Char('r'));
if (type & QSql::Views)
- d->appendTables(tl, t, QLatin1Char('v'));
+ const_cast<QPSQLDriverPrivate*>(d)->appendTables(tl, t, QLatin1Char('v'));
if (type & QSql::SystemTables) {
t.exec(QLatin1String("select relname from pg_class where (relkind = 'r') "
"and (relname like 'pg_%') "));
@@ -1013,6 +1020,7 @@ static void qSplitTableName(QString &tablename, QString &schema)
QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
{
+ Q_D(const QPSQLDriver);
QSqlIndex idx(tablename);
if (!isOpen())
return idx;
@@ -1094,6 +1102,7 @@ QSqlIndex QPSQLDriver::primaryIndex(const QString& tablename) const
QSqlRecord QPSQLDriver::record(const QString& tablename) const
{
+ Q_D(const QPSQLDriver);
QSqlRecord info;
if (!isOpen())
return info;
@@ -1231,6 +1240,7 @@ QSqlRecord QPSQLDriver::record(const QString& tablename) const
QString QPSQLDriver::formatValue(const QSqlField &field, bool trimStrings) const
{
+ Q_D(const QPSQLDriver);
QString r;
if (field.isNull()) {
r = QLatin1String("NULL");
@@ -1326,16 +1336,19 @@ QString QPSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType)
bool QPSQLDriver::isOpen() const
{
+ Q_D(const QPSQLDriver);
return PQstatus(d->connection) == CONNECTION_OK;
}
QPSQLDriver::Protocol QPSQLDriver::protocol() const
{
+ Q_D(const QPSQLDriver);
return d->pro;
}
bool QPSQLDriver::subscribeToNotification(const QString &name)
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::subscribeToNotificationImplementation: database not open.");
return false;
@@ -1373,6 +1386,7 @@ bool QPSQLDriver::subscribeToNotification(const QString &name)
bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
{
+ Q_D(QPSQLDriver);
if (!isOpen()) {
qWarning("QPSQLDriver::unsubscribeFromNotificationImplementation: database not open.");
return false;
@@ -1404,11 +1418,13 @@ bool QPSQLDriver::unsubscribeFromNotification(const QString &name)
QStringList QPSQLDriver::subscribedToNotifications() const
{
+ Q_D(const QPSQLDriver);
return d->seid;
}
void QPSQLDriver::_q_handleNotification(int)
{
+ Q_D(QPSQLDriver);
d->pendingNotifyCheck = false;
PQconsumeInput(d->connection);
diff --git a/src/sql/drivers/psql/qsql_psql_p.h b/src/sql/drivers/psql/qsql_psql_p.h
index a20b9de3ef..5f4aa68b9e 100644
--- a/src/sql/drivers/psql/qsql_psql_p.h
+++ b/src/sql/drivers/psql/qsql_psql_p.h
@@ -103,6 +103,7 @@ class QPSQLDriverPrivate;
class Q_EXPORT_SQLDRIVER_PSQL QPSQLDriver : public QSqlDriver
{
friend class QPSQLResultPrivate;
+ Q_DECLARE_PRIVATE(QPSQLDriver)
Q_OBJECT
public:
@@ -155,10 +156,6 @@ protected:
private Q_SLOTS:
void _q_handleNotification(int);
-
-private:
- void init();
- QPSQLDriverPrivate *d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index c78f0b6882..ffeb7921b3 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -346,15 +346,15 @@ QSQLiteResult::QSQLiteResult(const QSQLiteDriver* db)
: QSqlCachedResult(db)
{
d = new QSQLiteResultPrivate(this);
- d->access = db->d->access;
- db->d->results.append(this);
+ d->access = db->d_func()->access;
+ const_cast<QSQLiteDriverPrivate*>(db->d_func())->results.append(this);
}
QSQLiteResult::~QSQLiteResult()
{
const QSqlDriver *sqlDriver = driver();
if (sqlDriver)
- qobject_cast<const QSQLiteDriver *>(sqlDriver)->d->results.removeOne(this);
+ const_cast<QSQLiteDriverPrivate*>(qobject_cast<const QSQLiteDriver *>(sqlDriver)->d_func())->results.removeOne(this);
d->cleanup();
delete d;
}
@@ -530,15 +530,14 @@ QVariant QSQLiteResult::handle() const
/////////////////////////////////////////////////////////
QSQLiteDriver::QSQLiteDriver(QObject * parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLiteDriverPrivate, parent)
{
- d = new QSQLiteDriverPrivate();
}
QSQLiteDriver::QSQLiteDriver(sqlite3 *connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLiteDriverPrivate, parent)
{
- d = new QSQLiteDriverPrivate();
+ Q_D(QSQLiteDriver);
d->access = connection;
setOpen(true);
setOpenError(false);
@@ -579,6 +578,7 @@ bool QSQLiteDriver::hasFeature(DriverFeature f) const
*/
bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &conOpts)
{
+ Q_D(QSQLiteDriver);
if (isOpen())
close();
@@ -622,6 +622,7 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c
void QSQLiteDriver::close()
{
+ Q_D(QSQLiteDriver);
if (isOpen()) {
foreach (QSQLiteResult *result, d->results) {
result->d->finalize();
@@ -778,6 +779,7 @@ QSqlRecord QSQLiteDriver::record(const QString &tbl) const
QVariant QSQLiteDriver::handle() const
{
+ Q_D(const QSQLiteDriver);
return QVariant::fromValue(d->access);
}
diff --git a/src/sql/drivers/sqlite/qsql_sqlite_p.h b/src/sql/drivers/sqlite/qsql_sqlite_p.h
index 548d1da97c..526dd9a22a 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite_p.h
+++ b/src/sql/drivers/sqlite/qsql_sqlite_p.h
@@ -71,6 +71,7 @@ class QSQLiteDriver;
class Q_EXPORT_SQLDRIVER_SQLITE QSQLiteDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QSQLiteDriver)
Q_OBJECT
friend class QSQLiteResult;
public:
@@ -95,9 +96,6 @@ public:
QSqlIndex primaryIndex(const QString &table) const;
QVariant handle() const;
QString escapeIdentifier(const QString &identifier, IdentifierType) const;
-
-private:
- QSQLiteDriverPrivate* d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index 39ad122822..7e56d5cc17 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -281,8 +281,8 @@ QSQLite2Result::QSQLite2Result(const QSQLite2Driver* db)
: QSqlCachedResult(db)
{
d = new QSQLite2ResultPrivate(this);
- d->access = db->d->access;
- d->utf8 = db->d->utf8;
+ d->access = db->d_func()->access;
+ d->utf8 = db->d_func()->utf8;
}
QSQLite2Result::~QSQLite2Result()
@@ -376,16 +376,15 @@ QVariant QSQLite2Result::handle() const
/////////////////////////////////////////////////////////
-QSQLite2Driver::QSQLite2Driver(QObject * parent)
- : QSqlDriver(parent)
+QSQLite2Driver::QSQLite2Driver(QObject *parent)
+ : QSqlDriver(*new QSQLite2DriverPrivate, parent)
{
- d = new QSQLite2DriverPrivate();
}
QSQLite2Driver::QSQLite2Driver(sqlite *connection, QObject *parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QSQLite2DriverPrivate, parent)
{
- d = new QSQLite2DriverPrivate();
+ Q_D(QSQLite2Driver);
d->access = connection;
setOpen(true);
setOpenError(false);
@@ -398,6 +397,7 @@ QSQLite2Driver::~QSQLite2Driver()
bool QSQLite2Driver::hasFeature(DriverFeature f) const
{
+ Q_D(const QSQLite2Driver);
switch (f) {
case Transactions:
case SimpleLocking:
@@ -415,6 +415,7 @@ bool QSQLite2Driver::hasFeature(DriverFeature f) const
*/
bool QSQLite2Driver::open(const QString & db, const QString &, const QString &, const QString &, int, const QString &)
{
+ Q_D(QSQLite2Driver);
if (isOpen())
close();
@@ -441,6 +442,7 @@ bool QSQLite2Driver::open(const QString & db, const QString &, const QString &,
void QSQLite2Driver::close()
{
+ Q_D(QSQLite2Driver);
if (isOpen()) {
sqlite_close(d->access);
d->access = 0;
@@ -456,6 +458,7 @@ QSqlResult *QSQLite2Driver::createResult() const
bool QSQLite2Driver::beginTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -473,6 +476,7 @@ bool QSQLite2Driver::beginTransaction()
bool QSQLite2Driver::commitTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -490,6 +494,7 @@ bool QSQLite2Driver::commitTransaction()
bool QSQLite2Driver::rollbackTransaction()
{
+ Q_D(QSQLite2Driver);
if (!isOpen() || isOpenError())
return false;
@@ -586,6 +591,7 @@ QSqlRecord QSQLite2Driver::record(const QString &tbl) const
QVariant QSQLite2Driver::handle() const
{
+ Q_D(const QSQLite2Driver);
return QVariant::fromValue(d->access);
}
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
index 7a075210ae..ae38a662ac 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2_p.h
@@ -71,8 +71,9 @@ class QSQLite2Driver;
class QSQLite2Driver : public QSqlDriver
{
- Q_OBJECT
friend class QSQLite2Result;
+ Q_DECLARE_PRIVATE(QSQLite2Driver)
+ Q_OBJECT
public:
explicit QSQLite2Driver(QObject *parent = 0);
explicit QSQLite2Driver(sqlite *connection, QObject *parent = 0);
@@ -100,9 +101,6 @@ public:
QSqlIndex primaryIndex(const QString &table) const;
QVariant handle() const;
QString escapeIdentifier(const QString &identifier, IdentifierType) const;
-
-private:
- QSQLite2DriverPrivate* d;
};
QT_END_NAMESPACE
diff --git a/src/sql/drivers/tds/qsql_tds.cpp b/src/sql/drivers/tds/qsql_tds.cpp
index fe59fa8822..69534fe380 100644
--- a/src/sql/drivers/tds/qsql_tds.cpp
+++ b/src/sql/drivers/tds/qsql_tds.cpp
@@ -327,12 +327,12 @@ QTDSResult::QTDSResult(const QTDSDriver* db)
: QSqlCachedResult(db)
{
d = new QTDSResultPrivate();
- d->login = db->d->login;
+ d->login = db->d_func()->login;
- d->dbproc = dbopen(d->login, const_cast<char*>(db->d->hostName.toLatin1().constData()));
+ d->dbproc = dbopen(d->login, const_cast<char*>(db->d_func()->hostName.toLatin1().constData()));
if (!d->dbproc)
return;
- if (dbuse(d->dbproc, const_cast<char*>(db->d->db.toLatin1().constData())) == FAIL)
+ if (dbuse(d->dbproc, const_cast<char*>(db->d_func()->db.toLatin1().constData())) == FAIL)
return;
// insert d in error handler dict
@@ -355,7 +355,7 @@ void QTDSResult::cleanup()
d->clearErrorMsgs();
d->rec.clear();
for (int i = 0; i < d->buffer.size(); ++i)
- free(d->buffer.at(i * 2).data);
+ free(d->buffer.at(i).data);
d->buffer.clear();
// "can" stands for "cancel"... very clever.
dbcanquery(d->dbproc);
@@ -541,14 +541,15 @@ QSqlRecord QTDSResult::record() const
///////////////////////////////////////////////////////////////////
QTDSDriver::QTDSDriver(QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QTDSDriverPrivate, parent)
{
init();
}
QTDSDriver::QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QObject* parent)
- : QSqlDriver(parent)
+ : QSqlDriver(*new QTDSDriverPrivate, parent)
{
+ Q_D(QTDSDriver);
init();
d->login = rec;
d->hostName = host;
@@ -561,12 +562,13 @@ QTDSDriver::QTDSDriver(LOGINREC* rec, const QString& host, const QString &db, QO
QVariant QTDSDriver::handle() const
{
+ Q_D(const QTDSDriver);
return QVariant(qRegisterMetaType<LOGINREC *>("LOGINREC*"), &d->login);
}
void QTDSDriver::init()
{
- d = new QTDSDriverPrivate();
+ Q_D(QTDSDriver);
d->initialized = (dbinit() == SUCCEED);
// the following two code-lines will fail compilation on some FreeTDS versions
// just comment them out if you have FreeTDS (you won't get any errors and warnings then)
@@ -606,6 +608,7 @@ bool QTDSDriver::open(const QString & db,
int /*port*/,
const QString& /*connOpts*/)
{
+ Q_D(QTDSDriver);
if (isOpen())
close();
if (!d->initialized) {
@@ -645,6 +648,7 @@ bool QTDSDriver::open(const QString & db,
void QTDSDriver::close()
{
+ Q_D(QTDSDriver);
if (isOpen()) {
#ifdef Q_USE_SYBASE
dbloginfree(d->login);
diff --git a/src/sql/drivers/tds/qsql_tds_p.h b/src/sql/drivers/tds/qsql_tds_p.h
index 5336f183ef..dd7088a167 100644
--- a/src/sql/drivers/tds/qsql_tds_p.h
+++ b/src/sql/drivers/tds/qsql_tds_p.h
@@ -84,6 +84,7 @@ class QTDSDriver;
class Q_EXPORT_SQLDRIVER_TDS QTDSDriver : public QSqlDriver
{
+ Q_DECLARE_PRIVATE(QTDSDriver)
Q_OBJECT
friend class QTDSResult;
public:
@@ -115,7 +116,6 @@ protected:
bool rollbackTransaction();
private:
void init();
- QTDSDriverPrivate *d;
};
QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 97f95e6280..63b90f27c6 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -88,6 +88,13 @@ QSqlDriver::QSqlDriver(QObject *parent)
{
}
+/*! \internal
+*/
+QSqlDriver::QSqlDriver(QSqlDriverPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
/*!
Destroys the object and frees any allocated resources.
*/
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 5e0950e57b..017ffd4e4a 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -126,6 +126,7 @@ Q_SIGNALS:
void notification(const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload);
protected:
+ QSqlDriver(QSqlDriverPrivate &dd, QObject *parent = 0);
virtual void setOpen(bool o);
virtual void setOpenError(bool e);
virtual void setLastError(const QSqlError& e);
diff --git a/src/sql/kernel/qsqldriver_p.h b/src/sql/kernel/qsqldriver_p.h
index 1e7e3cc7a0..05570e584c 100644
--- a/src/sql/kernel/qsqldriver_p.h
+++ b/src/sql/kernel/qsqldriver_p.h
@@ -61,31 +61,26 @@ QT_BEGIN_NAMESPACE
class QSqlDriverPrivate : public QObjectPrivate
{
+ Q_DECLARE_PUBLIC(QSqlDriver)
+
public:
enum DBMSType {UnknownDB, MSSqlServer, MySqlServer, PostgreSQL, Oracle, Sybase, SQLite, Interbase, DB2};
- QSqlDriverPrivate();
- virtual ~QSqlDriverPrivate();
-public:
- // @CHECK: this member is never used. It was named q, which expanded to q_func().
- QSqlDriver *q_func();
- uint isOpen : 1;
- uint isOpenError : 1;
+ QSqlDriverPrivate()
+ : QObjectPrivate(),
+ isOpen(false),
+ isOpenError(false),
+ precisionPolicy(QSql::LowPrecisionDouble),
+ dbmsType(UnknownDB)
+ { }
+
+ uint isOpen;
+ uint isOpenError;
QSqlError error;
QSql::NumericalPrecisionPolicy precisionPolicy;
DBMSType dbmsType;
};
-inline QSqlDriverPrivate::QSqlDriverPrivate()
- : QObjectPrivate(), isOpen(false), isOpenError(false), precisionPolicy(QSql::LowPrecisionDouble),
- dbmsType(UnknownDB)
-{
-}
-
-QSqlDriverPrivate::~QSqlDriverPrivate()
-{
-}
-
QT_END_NAMESPACE
#endif // QSQLDRIVER_P_H
diff --git a/src/tools/qdoc/doc/config/qdoc.qdocconf b/src/tools/qdoc/doc/config/qdoc.qdocconf
index 6bbe934749..84e9689f50 100644
--- a/src/tools/qdoc/doc/config/qdoc.qdocconf
+++ b/src/tools/qdoc/doc/config/qdoc.qdocconf
@@ -20,7 +20,7 @@ tagfile = ../html/qdoc.tags
qhp.projects = QDoc
qhp.QDoc.file = qdoc.qhp
-qhp.QDoc.namespace = qdoc.$QT_VERSION_TAG
+qhp.QDoc.namespace = org.qt-project.qdoc.$QT_VERSION_TAG
qhp.QDoc.virtualFolder = qdoc
qhp.QDoc.indexTitle = QDoc Manual
qhp.QDoc.indexRoot =
diff --git a/src/tools/qdoc/node.cpp b/src/tools/qdoc/node.cpp
index c293d48673..028c0a0b2a 100644
--- a/src/tools/qdoc/node.cpp
+++ b/src/tools/qdoc/node.cpp
@@ -1440,7 +1440,6 @@ NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
ClassNode::ClassNode(InnerNode *parent, const QString& name)
: InnerNode(Class, parent, name)
{
- hidden = false;
abstract_ = false;
qmlelement = 0;
setPageType(ApiPage);
diff --git a/src/tools/qdoc/node.h b/src/tools/qdoc/node.h
index 4802b6de54..642bcec06a 100644
--- a/src/tools/qdoc/node.h
+++ b/src/tools/qdoc/node.h
@@ -440,9 +440,6 @@ public:
const QList<RelatedClass> &derivedClasses() const { return derived; }
const QList<RelatedClass> &ignoredBaseClasses() const { return ignoredBases; }
- bool hideFromMainList() const { return hidden; }
- void setHideFromMainList(bool value) { hidden = value; }
-
QString serviceName() const { return sname; }
void setServiceName(const QString& value) { sname = value; }
QmlClassNode* qmlElement() { return qmlelement; }
@@ -456,7 +453,6 @@ private:
QList<RelatedClass> bases;
QList<RelatedClass> derived;
QList<RelatedClass> ignoredBases;
- bool hidden;
bool abstract_;
QString sname;
QmlClassNode* qmlelement;
diff --git a/src/tools/qdoc/qdocdatabase.cpp b/src/tools/qdoc/qdocdatabase.cpp
index 191da5caf8..30a9efaada 100644
--- a/src/tools/qdoc/qdocdatabase.cpp
+++ b/src/tools/qdoc/qdocdatabase.cpp
@@ -448,18 +448,16 @@ void QDocDatabase::findAllClasses(const InnerNode* node)
!(*c)->parent()->name().isEmpty())
className = (*c)->parent()->name()+"::"+className;
- if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
- if ((*c)->status() == Node::Compat) {
- compatClasses_.insert(className, *c);
- }
- else if ((*c)->status() == Node::Obsolete) {
- obsoleteClasses_.insert(className, *c);
- }
- else {
- nonCompatClasses_.insert(className, *c);
- if ((*c)->status() == Node::Main)
- mainClasses_.insert(className, *c);
- }
+ if ((*c)->status() == Node::Compat) {
+ compatClasses_.insert(className, *c);
+ }
+ else if ((*c)->status() == Node::Obsolete) {
+ obsoleteClasses_.insert(className, *c);
+ }
+ else {
+ nonCompatClasses_.insert(className, *c);
+ if ((*c)->status() == Node::Main)
+ mainClasses_.insert(className, *c);
}
QString serviceName = (static_cast<const ClassNode *>(*c))->serviceName();
diff --git a/src/tools/uic/qclass_lib_map.h b/src/tools/uic/qclass_lib_map.h
index 075b2d52e8..6859cd0cd4 100644
--- a/src/tools/uic/qclass_lib_map.h
+++ b/src/tools/uic/qclass_lib_map.h
@@ -313,7 +313,7 @@ QT_CLASS_LIB(QDeclarativePropertyValueInterceptor, QtDeclarative, qdeclarativepr
QT_CLASS_LIB(QDeclarativePropertyValueSource, QtDeclarative, qdeclarativepropertyvaluesource.h)
QT_CLASS_LIB(QDeclarativeScriptString, QtDeclarative, qdeclarativescriptstring.h)
QT_CLASS_LIB(QDeclarativePropertyMap, QtDeclarative, qdeclarativepropertymap.h)
-QT_CLASS_LIB(QDeclarativeView, QtQuick1, qdeclarativeview.h)
+QT_CLASS_LIB(QDeclarativeView, QtDeclarative, qdeclarativeview.h)
QT_CLASS_LIB(QMacGLCompatTypes, QtOpenGL, qgl.h)
QT_CLASS_LIB(QMacGLCompatTypes, QtOpenGL, qgl.h)
QT_CLASS_LIB(QMacCompatGLint, QtOpenGL, qgl.h)
diff --git a/src/widgets/dialogs/qwizard.cpp b/src/widgets/dialogs/qwizard.cpp
index 72283451d7..3f214809b4 100644
--- a/src/widgets/dialogs/qwizard.cpp
+++ b/src/widgets/dialogs/qwizard.cpp
@@ -1936,7 +1936,7 @@ void QWizardAntiFlickerWidget::paintEvent(QPaintEvent *)
Here, we call QWizardPage::field() to access the contents of the
\c className field (which was defined in the \c ClassInfoPage)
- and use it to initialize the \c OuputFilePage. The field's
+ and use it to initialize the \c OutputFilePage. The field's
contents is returned as a QVariant.
When we create a field using QWizardPage::registerField(), we
@@ -3131,6 +3131,16 @@ bool QWizard::event(QEvent *event)
d->handleAeroStyleChange();
}
else if (d->isVistaThemeEnabled()) {
+ if (event->type() == QEvent::Resize
+ || event->type() == QEvent::LayoutDirectionChange) {
+ const int buttonLeft = (layoutDirection() == Qt::RightToLeft
+ ? width() - d->vistaHelper->backButton()->sizeHint().width()
+ : 0);
+
+ d->vistaHelper->backButton()->move(buttonLeft,
+ d->vistaHelper->backButton()->y());
+ }
+
d->vistaHelper->mouseEvent(event);
}
#endif
diff --git a/src/widgets/dialogs/qwizard_win.cpp b/src/widgets/dialogs/qwizard_win.cpp
index 001c21da61..b57614c018 100644
--- a/src/widgets/dialogs/qwizard_win.cpp
+++ b/src/widgets/dialogs/qwizard_win.cpp
@@ -240,7 +240,11 @@ void QVistaBackButton::paintEvent(QPaintEvent *)
else if (underMouse())
state = WIZ_NAV_BB_HOT;
- pDrawThemeBackground(theme, hdc, WIZ_NAV_BACKBUTTON, state, &clipRect, &clipRect);
+ WIZ_NAVIGATIONPARTS buttonType = (layoutDirection() == Qt::LeftToRight
+ ? WIZ_NAV_BACKBUTTON
+ : WIZ_NAV_FORWARDBUTTON);
+
+ pDrawThemeBackground(theme, hdc, buttonType, state, &clipRect, &clipRect);
}
/******************************************************************************
@@ -385,7 +389,11 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
glowOffset = glowSize();
}
- const QRect textRectangle(titleOffset() - glowOffset, verticalCenter - textHeight / 2, textWidth, textHeight);
+ const int titleLeft = (wizard->layoutDirection() == Qt::LeftToRight
+ ? titleOffset() - glowOffset
+ : wizard->width() - titleOffset() - textWidth + glowOffset);
+
+ const QRect textRectangle(titleLeft, verticalCenter - textHeight / 2, textWidth, textHeight);
if (isWindow) {
drawTitleText(painter, text, textRectangle, hdc);
} else {
@@ -397,7 +405,11 @@ void QVistaHelper::drawTitleBar(QPainter *painter)
const QIcon windowIcon = wizard->windowIcon();
if (!windowIcon.isNull()) {
- const QRect rect(origin.x() + leftMargin(),
+ const int iconLeft = (wizard->layoutDirection() == Qt::LeftToRight
+ ? leftMargin()
+ : wizard->width() - leftMargin() - iconSize());
+
+ const QRect rect(origin.x() + iconLeft,
origin.y() + verticalCenter - iconSize() / 2, iconSize(), iconSize());
const HICON hIcon = qt_pixmapToWinHICON(windowIcon.pixmap(iconSize()));
DrawIconEx(hdc, rect.left(), rect.top(), hIcon, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index c2308b780f..edd2329df8 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -9517,6 +9517,9 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f)
bool wasCreated = testAttribute(Qt::WA_WState_Created);
QWidget *oldtlw = window();
+ if (f & Qt::Window) // Frame geometry likely changes, refresh.
+ d->data.fstrut_dirty = true;
+
QWidget *desktopWidget = 0;
if (parent && parent->windowType() == Qt::Desktop)
desktopWidget = parent;
diff --git a/src/widgets/styles/qgtkstyle_p.cpp b/src/widgets/styles/qgtkstyle_p.cpp
index f29f250de0..a53a961a89 100644
--- a/src/widgets/styles/qgtkstyle_p.cpp
+++ b/src/widgets/styles/qgtkstyle_p.cpp
@@ -529,18 +529,6 @@ void QGtkStylePrivate::initGtkWidgets() const
return;
}
- static QString themeName;
- if (!gtkWidgetMap()->contains("GtkWindow") && themeName.isEmpty()) {
- themeName = getThemeName();
-
- if (themeName == QLS("Qt") || themeName == QLS("Qt4")) {
- // Due to namespace conflicts with Qt3 and obvious recursion with Qt4,
- // we cannot support the GTK_Qt Gtk engine
- qWarning("QGtkStyle cannot be used together with the GTK_Qt engine.");
- return;
- }
- }
-
if (QGtkStylePrivate::gtk_init) {
#ifndef Q_OS_MAC
// Gtk will set the Qt error handler so we have to reset it afterwards
@@ -688,38 +676,12 @@ bool QGtkStylePrivate::getGConfBool(const QString &key, bool fallback)
QString QGtkStylePrivate::getThemeName()
{
QString themeName;
- // We try to parse the gtkrc file first
- // primarily to avoid resolving Gtk functions if
- // the KDE 3 "Qt" style is currently in use
- QString rcPaths = QString::fromLocal8Bit(qgetenv("GTK2_RC_FILES"));
- if (!rcPaths.isEmpty()) {
- QStringList paths = rcPaths.split(QLS(":"));
- foreach (const QString &rcPath, paths) {
- if (!rcPath.isEmpty()) {
- QFile rcFile(rcPath);
- if (rcFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
- QTextStream in(&rcFile);
- while(!in.atEnd()) {
- QString line = in.readLine();
- if (line.contains(QLS("gtk-theme-name"))) {
- line = line.right(line.length() - line.indexOf(QLatin1Char('=')) - 1);
- line.remove(QLatin1Char('\"'));
- line = line.trimmed();
- themeName = line;
- break;
- }
- }
- }
- }
- if (!themeName.isEmpty())
- break;
- }
- }
-
- // Fall back to gconf
- if (themeName.isEmpty() && resolveGConf())
- themeName = getGConfString(QLS("/desktop/gnome/interface/gtk_theme"));
-
+ // Read the theme name from GtkSettings
+ GtkSettings *settings = QGtkStylePrivate::gtk_settings_get_default();
+ gchararray value;
+ g_object_get(settings, "gtk-theme-name", &value, NULL);
+ themeName = QString::fromUtf8(value);
+ g_free(value);
return themeName;
}
diff --git a/src/xml/doc/src/qtxml-index.qdoc b/src/xml/doc/src/qtxml-index.qdoc
index 2247ce5ace..ded8f3de3c 100644
--- a/src/xml/doc/src/qtxml-index.qdoc
+++ b/src/xml/doc/src/qtxml-index.qdoc
@@ -31,7 +31,7 @@
\brief The Qt XML module provides C++ implementations of the SAX and DOM standards for XML.
The module is not actively maintained anymore. Please use
- the QXmlStreamReader and QXmlStreamwriter classes in Qt Core instead.
+ the QXmlStreamReader and QXmlStreamWriter classes in Qt Core instead.
To include the definitions of the module's classes, use the
following directive:
diff --git a/tests/auto/cmake/cmake.pro b/tests/auto/cmake/cmake.pro
index bf2dbcb772..715e710490 100644
--- a/tests/auto/cmake/cmake.pro
+++ b/tests/auto/cmake/cmake.pro
@@ -2,4 +2,14 @@
# Cause make to do nothing.
TEMPLATE = subdirs
+CMAKE_QT_MODULES_UNDER_TEST = core network xml sql testlib
+
+qtHaveModule(dbus): CMAKE_QT_MODULES_UNDER_TEST += dbus
+qtHaveModule(gui): CMAKE_QT_MODULES_UNDER_TEST += gui
+qtHaveModule(openglextensions): CMAKE_QT_MODULES_UNDER_TEST += openglextensions
+qtHaveModule(widgets): CMAKE_QT_MODULES_UNDER_TEST += widgets
+qtHaveModule(printsupport): CMAKE_QT_MODULES_UNDER_TEST += printsupport
+qtHaveModule(opengl): CMAKE_QT_MODULES_UNDER_TEST += opengl
+qtHaveModule(concurrent): CMAKE_QT_MODULES_UNDER_TEST += concurrent
+
CONFIG += ctest_testcase
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 5ef4b11e8a..d9292b8460 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -66,6 +66,7 @@ private slots:
void textStreamManualFlush();
void textStreamAutoFlush();
void saveTwice();
+ void transactionalWriteNoPermissionsOnDir_data();
void transactionalWriteNoPermissionsOnDir();
void transactionalWriteNoPermissionsOnFile();
void transactionalWriteCanceled();
@@ -153,20 +154,86 @@ void tst_QSaveFile::textStreamAutoFlush()
QFile::remove(targetFile);
}
+void tst_QSaveFile::transactionalWriteNoPermissionsOnDir_data()
+{
+ QTest::addColumn<bool>("directWriteFallback");
+
+ QTest::newRow("default") << false;
+ QTest::newRow("directWriteFallback") << true;
+}
+
void tst_QSaveFile::transactionalWriteNoPermissionsOnDir()
{
#ifdef Q_OS_UNIX
- if (::geteuid() == 0)
- QSKIP("not valid running this test as root");
+ QFETCH(bool, directWriteFallback);
+ // Restore permissions so that the QTemporaryDir cleanup can happen
+ class PermissionRestorer
+ {
+ QString m_path;
+ public:
+ PermissionRestorer(const QString& path)
+ : m_path(path)
+ {}
- // You can write into /dev/zero, but you can't create a /dev/zero.XXXXXX temp file.
- QSaveFile file("/dev/zero");
- if (!QDir("/dev").exists())
- QSKIP("/dev doesn't exist on this system");
+ ~PermissionRestorer()
+ {
+ restore();
+ }
+ void restore()
+ {
+ QFile file(m_path);
+ file.setPermissions(QFile::Permissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner));
+ }
+ };
- QVERIFY(!file.open(QIODevice::WriteOnly));
- QCOMPARE((int)file.error(), (int)QFile::OpenError);
- QVERIFY(!file.commit());
+
+ QTemporaryDir dir;
+ QVERIFY(QFile(dir.path()).setPermissions(QFile::ReadOwner | QFile::ExeOwner));
+ PermissionRestorer permissionRestorer(dir.path());
+
+ const QString targetFile = dir.path() + QString::fromLatin1("/outfile");
+ QSaveFile firstTry(targetFile);
+ QVERIFY(!firstTry.open(QIODevice::WriteOnly));
+ QCOMPARE((int)firstTry.error(), (int)QFile::OpenError);
+ QVERIFY(!firstTry.commit());
+
+ // Now make an existing writable file
+ permissionRestorer.restore();
+ QFile f(targetFile);
+ QVERIFY(f.open(QIODevice::WriteOnly));
+ QCOMPARE(f.write("Hello"), Q_INT64_C(5));
+ f.close();
+
+ // Make the directory non-writable again
+ QVERIFY(QFile(dir.path()).setPermissions(QFile::ReadOwner | QFile::ExeOwner));
+
+ // And write to it again using QSaveFile; only works if directWriteFallback is enabled
+ QSaveFile file(targetFile);
+ file.setDirectWriteFallback(directWriteFallback);
+ QCOMPARE(file.directWriteFallback(), directWriteFallback);
+ if (directWriteFallback) {
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::NoError);
+ QCOMPARE(file.write("World"), Q_INT64_C(5));
+ QVERIFY(file.commit());
+
+ QFile reader(targetFile);
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("World"));
+ reader.close();
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::NoError);
+ QCOMPARE(file.write("W"), Q_INT64_C(1));
+ file.cancelWriting(); // no effect, as per the documentation
+ QVERIFY(file.commit());
+
+ QVERIFY(reader.open(QIODevice::ReadOnly));
+ QCOMPARE(QString::fromLatin1(reader.readAll()), QString::fromLatin1("W"));
+ } else {
+ QVERIFY(!file.open(QIODevice::WriteOnly));
+ QCOMPARE((int)file.error(), (int)QFile::OpenError);
+ }
#endif
}
diff --git a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
index f750b7a9d4..ea0a14c18c 100644
--- a/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qidentityproxymodel/tst_qidentityproxymodel.cpp
@@ -79,6 +79,8 @@ private slots:
void reset();
void dataChanged();
+ void itemData();
+
protected:
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
@@ -364,5 +366,29 @@ void tst_QIdentityProxyModel::dataChanged()
m_proxy->setSourceModel(0);
}
+class AppendStringProxy : public QIdentityProxyModel
+{
+public:
+ QVariant data(const QModelIndex &index, int role) const
+ {
+ const QVariant result = sourceModel()->data(index, role);
+ if (role != Qt::DisplayRole)
+ return result;
+ return result.toString() + "_appended";
+ }
+};
+
+void tst_QIdentityProxyModel::itemData()
+{
+ QStringListModel model(QStringList() << "Monday" << "Tuesday" << "Wednesday");
+ AppendStringProxy proxy;
+ proxy.setSourceModel(&model);
+
+ const QModelIndex topIndex = proxy.index(0, 0);
+ QCOMPARE(topIndex.data(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+ QCOMPARE(proxy.data(topIndex, Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+ QCOMPARE(proxy.itemData(topIndex).value(Qt::DisplayRole).toString(), QStringLiteral("Monday_appended"));
+}
+
QTEST_MAIN(tst_QIdentityProxyModel)
#include "tst_qidentityproxymodel.moc"
diff --git a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
index 4578bcdab6..923b9a3a07 100644
--- a/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
+++ b/tests/auto/corelib/itemmodels/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp
@@ -148,6 +148,7 @@ private slots:
void chainedProxyModelRoleNames();
+ void noMapAfterSourceDelete();
protected:
void buildHierarchy(const QStringList &data, QAbstractItemModel *model);
void checkHierarchy(const QStringList &data, const QAbstractItemModel *model);
@@ -3809,5 +3810,39 @@ void tst_QSortFilterProxyModel::chainedProxyModelRoleNames()
QVERIFY(proxy2.roleNames().value(Qt::UserRole + 1) == "custom");
}
+class SourceAssertion : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ explicit SourceAssertion(QObject *parent = 0)
+ : QSortFilterProxyModel(parent)
+ {
+
+ }
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const
+ {
+ Q_ASSERT(sourceModel());
+ return QSortFilterProxyModel::mapToSource(proxyIndex);
+ }
+};
+
+void tst_QSortFilterProxyModel::noMapAfterSourceDelete()
+{
+ SourceAssertion proxy;
+ QStringListModel *model = new QStringListModel(QStringList() << "Foo" << "Bar");
+
+ proxy.setSourceModel(model);
+
+ // Create mappings
+ QPersistentModelIndex persistent = proxy.index(0, 0);
+
+ QVERIFY(persistent.isValid());
+
+ delete model;
+
+ QVERIFY(!persistent.isValid());
+}
+
QTEST_MAIN(tst_QSortFilterProxyModel)
#include "tst_qsortfilterproxymodel.moc"
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index 670beff40b..4e0b3298fc 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1644,10 +1644,10 @@ void tst_QAccessibility::textEditTest()
QTest::qWaitForWindowShown(&edit);
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
QCOMPARE(iface->text(QAccessible::Value), edit.toPlainText());
- QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
+ QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible::WordBoundary, &startOffset, &endOffset), QString("world"));
QCOMPARE(startOffset, 6);
QCOMPARE(endOffset, 11);
- QCOMPARE(iface->textInterface()->textAtOffset(15, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("How are you today?"));
+ QCOMPARE(iface->textInterface()->textAtOffset(15, QAccessible::LineBoundary, &startOffset, &endOffset), QString("How are you today?"));
QCOMPARE(startOffset, 13);
QCOMPARE(endOffset, 31);
QCOMPARE(iface->textInterface()->characterCount(), 48);
@@ -1705,10 +1705,10 @@ void tst_QAccessibility::textBrowserTest()
QCOMPARE(iface->text(QAccessible::Value), text);
int startOffset;
int endOffset;
- QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
+ QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible::WordBoundary, &startOffset, &endOffset), QString("world"));
QCOMPARE(startOffset, 6);
QCOMPARE(endOffset, 11);
- QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
+ QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
QCOMPARE(startOffset, 12);
QCOMPARE(endOffset, 30);
QCOMPARE(iface->textInterface()->characterCount(), 31);
@@ -1931,45 +1931,45 @@ void tst_QAccessibility::lineEditTest()
int start, end;
QCOMPARE(textIface->text(0, 8), QString::fromLatin1("I always"));
- QCOMPARE(textIface->textAtOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("I"));
+ QCOMPARE(textIface->textAtOffset(0, QAccessible::CharBoundary,&start,&end), QString::fromLatin1("I"));
QCOMPARE(start, 0);
QCOMPARE(end, 1);
- QCOMPARE(textIface->textBeforeOffset(0, QAccessible2::CharBoundary,&start,&end), QString());
- QCOMPARE(textIface->textAfterOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1(" "));
+ QCOMPARE(textIface->textBeforeOffset(0, QAccessible::CharBoundary,&start,&end), QString());
+ QCOMPARE(textIface->textAfterOffset(0, QAccessible::CharBoundary,&start,&end), QString::fromLatin1(" "));
QCOMPARE(start, 1);
QCOMPARE(end, 2);
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("a"));
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::CharBoundary,&start,&end), QString::fromLatin1("a"));
QCOMPARE(start, 5);
QCOMPARE(end, 6);
- QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("w"));
- QCOMPARE(textIface->textAfterOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("y"));
+ QCOMPARE(textIface->textBeforeOffset(5, QAccessible::CharBoundary,&start,&end), QString::fromLatin1("w"));
+ QCOMPARE(textIface->textAfterOffset(5, QAccessible::CharBoundary,&start,&end), QString::fromLatin1("y"));
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::WordBoundary,&start,&end), QString::fromLatin1("always"));
QCOMPARE(start, 2);
QCOMPARE(end, 8);
- QCOMPARE(textIface->textAtOffset(2, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
- QCOMPARE(textIface->textAtOffset(7, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always"));
- QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
- QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice"));
- QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
- QCOMPARE(textIface->textAtOffset(101, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(". --"));
+ QCOMPARE(textIface->textAtOffset(2, QAccessible::WordBoundary,&start,&end), QString::fromLatin1("always"));
+ QCOMPARE(textIface->textAtOffset(7, QAccessible::WordBoundary,&start,&end), QString::fromLatin1("always"));
+ QCOMPARE(textIface->textAtOffset(8, QAccessible::WordBoundary,&start,&end), QString::fromLatin1(" "));
+ QCOMPARE(textIface->textAtOffset(25, QAccessible::WordBoundary,&start,&end), QString::fromLatin1("advice"));
+ QCOMPARE(textIface->textAtOffset(92, QAccessible::WordBoundary,&start,&end), QString::fromLatin1("oneself"));
+ QCOMPARE(textIface->textAtOffset(101, QAccessible::WordBoundary,&start,&end), QString::fromLatin1(". --"));
- QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
- QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" "));
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
+ QCOMPARE(textIface->textBeforeOffset(5, QAccessible::WordBoundary,&start,&end), QString::fromLatin1(" "));
+ QCOMPARE(textIface->textAfterOffset(5, QAccessible::WordBoundary,&start,&end), QString::fromLatin1(" "));
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
QCOMPARE(start, 0);
QCOMPARE(end, 30);
- QCOMPARE(textIface->textBeforeOffset(40, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
- QCOMPARE(textIface->textAfterOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("It is the only thing to do with it. "));
+ QCOMPARE(textIface->textBeforeOffset(40, QAccessible::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. "));
+ QCOMPARE(textIface->textAfterOffset(5, QAccessible::SentenceBoundary,&start,&end), QString::fromLatin1("It is the only thing to do with it. "));
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::ParagraphBoundary,&start,&end), cite);
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::ParagraphBoundary,&start,&end), cite);
QCOMPARE(start, 0);
QCOMPARE(end, cite.length());
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::LineBoundary,&start,&end), cite);
- QCOMPARE(textIface->textAtOffset(5, QAccessible2::NoBoundary,&start,&end), cite);
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::LineBoundary,&start,&end), cite);
+ QCOMPARE(textIface->textAtOffset(5, QAccessible::NoBoundary,&start,&end), cite);
QTestAccessibility::clearEvents();
}
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
index 0eb3ba8c22..e47140b61b 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_databases.h
@@ -96,14 +96,26 @@ static QString qGetHostName()
// to prevent nameclashes on our database server, each machine
// will use its own set of table names. Call this function to get
// "tablename_hostname"
-inline static QString qTableName( const QString& prefix, const char *sourceFileName )
+inline QString fixupTableName(const QString &tableName, QSqlDatabase db)
{
- return QLatin1String("dbtst")+QString::number(qHash(QLatin1String(sourceFileName) + "_" + qGetHostName().replace( "-", "_" )), 16)+"_"+prefix;
+ QString tbName = tableName;
+ // On Oracle we are limited to 30 character tablenames
+ QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
+ if (d && d->dbmsType == QSqlDriverPrivate::Oracle)
+ tbName.truncate(30);
+ return tbName;
}
-inline static QString qTableName( const QString& prefix, QSqlDriver* driver )
+inline static QString qTableName(const QString& prefix, const char *sourceFileName, QSqlDatabase db)
{
- return driver->escapeIdentifier( prefix + "_" + qGetHostName(), QSqlDriver::TableName );
+ return fixupTableName(QString(QLatin1String("dbtst") + QString::number(qHash(QLatin1String(sourceFileName) +
+ "_" + qGetHostName().replace( "-", "_" )), 16) + "_" + prefix), db);
+}
+
+inline static QString qTableName(const QString& prefix, QSqlDatabase db)
+{
+ return fixupTableName(QString(db.driver()->escapeIdentifier(prefix + "_" + qGetHostName(), QSqlDriver::TableName)),
+ db);
}
inline static bool testWhiteSpaceNames( const QString &name )
@@ -467,6 +479,8 @@ public:
{
if (db.driverName().startsWith("QPSQL"))
return QLatin1String("timestamp");
+ if (db.driverName().startsWith("QOCI") && getOraVersion(db) >= 9)
+ return QLatin1String("timestamp(0)");
return QLatin1String("datetime");
}
diff --git a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
index b294570df8..b958a30108 100644
--- a/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
+++ b/tests/auto/sql/kernel/qsqldatabase/tst_qsqldatabase.cpp
@@ -242,10 +242,10 @@ struct FieldDef {
// excluding the primary key field
static int createFieldTable(const FieldDef fieldDefs[], QSqlDatabase db)
{
- tst_Databases::safeDropTable(db, qTableName("qtestfields", __FILE__));
+ tst_Databases::safeDropTable(db, qTableName("qtestfields", __FILE__, db));
QSqlQuery q(db);
// construct a create table statement consisting of all fieldtypes
- QString qs = "create table " + qTableName("qtestfields", __FILE__);
+ QString qs = "create table " + qTableName("qtestfields", __FILE__, db);
QString autoName = tst_Databases::autoFieldName(db);
if (tst_Databases::isMSAccess(db))
qs.append(" (id int not null");
@@ -299,18 +299,18 @@ void tst_QSqlDatabase::createTestTables(QSqlDatabase db)
// please never ever change this table; otherwise fix all tests ;)
if (tst_Databases::isMSAccess(db)) {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__) +
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__, db) +
" (id int not null, t_varchar varchar(40) not null, t_char char(40), "
"t_numeric number, primary key (id, t_varchar))"));
} else {
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__) +
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest", __FILE__, db) +
" (id integer not null, t_varchar varchar(40) not null, "
"t_char char(40), t_numeric numeric(6, 3), primary key (id, t_varchar))"));
}
if (testWhiteSpaceNames(db.driverName())) {
QString qry = "create table "
- + db.driver()->escapeIdentifier(qTableName("qtest", __FILE__) + " test", QSqlDriver::TableName)
+ + db.driver()->escapeIdentifier(qTableName("qtest", __FILE__, db) + " test", QSqlDriver::TableName)
+ '('
+ db.driver()->escapeIdentifier(QLatin1String("test test"), QSqlDriver::FieldName)
+ " int not null primary key)";
@@ -329,45 +329,45 @@ void tst_QSqlDatabase::dropTestTables(QSqlDatabase db)
}
// drop the view first, otherwise we'll get dependency problems
- tst_Databases::safeDropViews(db, QStringList() << qTableName("qtest_view", __FILE__) << qTableName("qtest_view2", __FILE__));
+ tst_Databases::safeDropViews(db, QStringList() << qTableName("qtest_view", __FILE__, db) << qTableName("qtest_view2", __FILE__, db));
QStringList tableNames;
- tableNames << qTableName("qtest", __FILE__)
- << qTableName("qtestfields", __FILE__)
- << qTableName("qtestalter", __FILE__)
- << qTableName("qtest_temp", __FILE__)
- << qTableName("qtest_bigint", __FILE__)
- << qTableName("qtest_xmltype", __FILE__)
- << qTableName("latin1table", __FILE__)
- << qTableName("qtest_sqlguid", __FILE__)
- << qTableName("batable", __FILE__)
- << qTableName("qtest_prec", __FILE__)
- << qTableName("uint", __FILE__)
- << qTableName("strings", __FILE__)
- << qTableName("numericfields", __FILE__)
- << qTableName("qtest_ibaseblobs", __FILE__)
- << qTableName("qtestBindBool", __FILE__)
- << qTableName("testqGetString", __FILE__)
- << qTableName("qtest_sqlguid", __FILE__)
- << qTableName("uint_table", __FILE__)
- << qTableName("uint_test", __FILE__)
- << qTableName("bug_249059", __FILE__);
+ tableNames << qTableName("qtest", __FILE__, db)
+ << qTableName("qtestfields", __FILE__, db)
+ << qTableName("qtestalter", __FILE__, db)
+ << qTableName("qtest_temp", __FILE__, db)
+ << qTableName("qtest_bigint", __FILE__, db)
+ << qTableName("qtest_xmltype", __FILE__, db)
+ << qTableName("latin1table", __FILE__, db)
+ << qTableName("qtest_sqlguid", __FILE__, db)
+ << qTableName("batable", __FILE__, db)
+ << qTableName("qtest_prec", __FILE__, db)
+ << qTableName("uint", __FILE__, db)
+ << qTableName("strings", __FILE__, db)
+ << qTableName("numericfields", __FILE__, db)
+ << qTableName("qtest_ibaseblobs", __FILE__, db)
+ << qTableName("qtestBindBool", __FILE__, db)
+ << qTableName("testqGetString", __FILE__, db)
+ << qTableName("qtest_sqlguid", __FILE__, db)
+ << qTableName("uint_table", __FILE__, db)
+ << qTableName("uint_test", __FILE__, db)
+ << qTableName("bug_249059", __FILE__, db);
QSqlQuery q(0, db);
if (db.driverName().startsWith("QPSQL")) {
- q.exec("drop schema " + qTableName("qtestschema", __FILE__) + " cascade");
- q.exec("drop schema " + qTableName("qtestScHeMa", __FILE__) + " cascade");
+ q.exec("drop schema " + qTableName("qtestschema", __FILE__, db) + " cascade");
+ q.exec("drop schema " + qTableName("qtestScHeMa", __FILE__, db) + " cascade");
}
if (testWhiteSpaceNames(db.driverName()))
- tableNames << db.driver()->escapeIdentifier(qTableName("qtest", __FILE__) + " test", QSqlDriver::TableName);
+ tableNames << db.driver()->escapeIdentifier(qTableName("qtest", __FILE__, db) + " test", QSqlDriver::TableName);
tst_Databases::safeDropTables(db, tableNames);
if (db.driverName().startsWith("QOCI")) {
- q.exec("drop user "+qTableName("CREATOR", __FILE__)+" cascade");
- q.exec("drop user "+qTableName("APPUSER", __FILE__)+" cascade");
- q.exec("DROP TABLE system."+qTableName("mypassword", __FILE__));
+ q.exec("drop user "+qTableName("CREATOR", __FILE__, db)+ " cascade");
+ q.exec("drop user "+qTableName("APPUSER", __FILE__, db) + " cascade");
+ q.exec("DROP TABLE sys."+qTableName("mypassword", __FILE__, db));
}
}
@@ -377,7 +377,7 @@ void tst_QSqlDatabase::populateTestTables(QSqlDatabase db)
if (!db.isValid())
return;
QSqlQuery q(db);
- const QString qtest(qTableName("qtest", __FILE__));
+ const QString qtest(qTableName("qtest", __FILE__, db));
q.exec("delete from " + qtest); //non-fatal
QVERIFY_SQL(q, exec("insert into " + qtest + " (id, t_varchar, t_char, t_numeric) values (0, 'VarChar0', 'Char0', 1.1)"));
@@ -502,7 +502,7 @@ void tst_QSqlDatabase::tables()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest(qTableName("qtest", __FILE__)), qtest_view(qTableName("qtest_view", __FILE__)), temp_tab(qTableName("test_tab", __FILE__));
+ const QString qtest(qTableName("qtest", __FILE__, db)), qtest_view(qTableName("qtest_view", __FILE__, db)), temp_tab(qTableName("test_tab", __FILE__, db));
bool views = true;
bool tempTables = false;
@@ -567,7 +567,7 @@ void tst_QSqlDatabase::whitespaceInIdentifiers()
CHECK_DATABASE(db);
if (testWhiteSpaceNames(db.driverName())) {
- const QString tableName(qTableName("qtest", __FILE__) + " test");
+ const QString tableName(qTableName("qtest", __FILE__, db) + " test");
QVERIFY(db.tables().contains(tableName, Qt::CaseInsensitive));
QSqlRecord rec = db.record(db.driver()->escapeIdentifier(tableName, QSqlDriver::TableName));
@@ -595,7 +595,7 @@ void tst_QSqlDatabase::alterTable()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtestalter(qTableName("qtestalter", __FILE__));
+ const QString qtestalter(qTableName("qtestalter", __FILE__, db));
QSqlQuery q(db);
@@ -671,12 +671,12 @@ void tst_QSqlDatabase::commonFieldTest(const FieldDef fieldDefs[], QSqlDatabase
{
CHECK_DATABASE(db);
- QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__));
+ QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__, db));
QCOMPARE((int)rec.count(), fieldCount+1);
testRecord(fieldDefs, rec, db);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("select * from " + qTableName("qtestfields", __FILE__)));
+ QVERIFY_SQL(q, exec("select * from " + qTableName("qtestfields", __FILE__, db)));
}
void tst_QSqlDatabase::recordTDS()
@@ -772,12 +772,12 @@ void tst_QSqlDatabase::recordOCI()
commonFieldTest(fieldDefs, db, fieldCount);
// some additional tests
- QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__));
+ QSqlRecord rec = db.record(qTableName("qtestfields", __FILE__, db));
QCOMPARE(rec.field("T_NUMBER").length(), 10);
QCOMPARE(rec.field("T_NUMBER").precision(), 5);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("SELECT * FROM " + qTableName("qtestfields", __FILE__)));
+ QVERIFY_SQL(q, exec("SELECT * FROM " + qTableName("qtestfields", __FILE__, db)));
rec = q.record();
QCOMPARE(rec.field("T_NUMBER").length(), 10);
QCOMPARE(rec.field("T_NUMBER").precision(), 5);
@@ -834,11 +834,11 @@ void tst_QSqlDatabase::recordPSQL()
if(tst_Databases::isPostgreSQL(db))
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- q.exec("drop sequence " + qTableName("qtestfields", __FILE__) + "_t_bigserial_seq");
- q.exec("drop sequence " + qTableName("qtestfields", __FILE__) + "_t_serial_seq");
+ q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db) + "_t_bigserial_seq");
+ q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db) + "_t_serial_seq");
// older psql cut off the table name
- q.exec("drop sequence " + qTableName("qtestfields", __FILE__).left(15) + "_t_bigserial_seq");
- q.exec("drop sequence " + qTableName("qtestfields", __FILE__).left(18) + "_t_serial_seq");
+ q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db).left(15) + "_t_bigserial_seq");
+ q.exec("drop sequence " + qTableName("qtestfields", __FILE__, db).left(18) + "_t_serial_seq");
const int fieldCount = createFieldTable(fieldDefs, db);
QVERIFY(fieldCount > 0);
@@ -1075,7 +1075,7 @@ void tst_QSqlDatabase::transaction()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest(qTableName("qtest", __FILE__));
+ const QString qtest(qTableName("qtest", __FILE__, db));
if (!db.driver()->hasFeature(QSqlDriver::Transactions))
QSKIP("DBMS not transaction capable");
@@ -1125,7 +1125,7 @@ void tst_QSqlDatabase::bigIntField()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QString drvName = db.driverName();
- const QString qtest_bigint(qTableName("qtest_bigint", __FILE__));
+ const QString qtest_bigint(qTableName("qtest_bigint", __FILE__, db));
QSqlQuery q(db);
q.setForwardOnly(true);
@@ -1196,21 +1196,21 @@ void tst_QSqlDatabase::caseSensivity()
|| db.driverName().startsWith("QODBC"))
cs = true;
- QSqlRecord rec = db.record(qTableName("qtest", __FILE__));
+ QSqlRecord rec = db.record(qTableName("qtest", __FILE__, db));
QVERIFY((int)rec.count() > 0);
if (!cs) {
- rec = db.record(qTableName("QTEST", __FILE__).toUpper());
+ rec = db.record(qTableName("QTEST", __FILE__, db).toUpper());
QVERIFY((int)rec.count() > 0);
- rec = db.record(qTableName("qTesT", __FILE__));
+ rec = db.record(qTableName("qTesT", __FILE__, db));
QVERIFY((int)rec.count() > 0);
}
- rec = db.primaryIndex(qTableName("qtest", __FILE__));
+ rec = db.primaryIndex(qTableName("qtest", __FILE__, db));
QVERIFY((int)rec.count() > 0);
if (!cs) {
- rec = db.primaryIndex(qTableName("QTEST", __FILE__).toUpper());
+ rec = db.primaryIndex(qTableName("QTEST", __FILE__, db).toUpper());
QVERIFY((int)rec.count() > 0);
- rec = db.primaryIndex(qTableName("qTesT", __FILE__));
+ rec = db.primaryIndex(qTableName("qTesT", __FILE__, db));
QVERIFY((int)rec.count() > 0);
}
}
@@ -1226,7 +1226,7 @@ void tst_QSqlDatabase::noEscapedFieldNamesInRecord()
fieldname = fieldname.toUpper();
QSqlQuery q(db);
- QString query = "SELECT " + db.driver()->escapeIdentifier(fieldname, QSqlDriver::FieldName) + " FROM " + qTableName("qtest", __FILE__);
+ QString query = "SELECT " + db.driver()->escapeIdentifier(fieldname, QSqlDriver::FieldName) + " FROM " + qTableName("qtest", __FILE__, db);
QVERIFY_SQL(q, exec(query));
QCOMPARE(q.record().fieldName(0), fieldname);
}
@@ -1246,9 +1246,9 @@ void tst_QSqlDatabase::psql_schemas()
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
}
- QVERIFY_SQL(q, exec("CREATE SCHEMA " + qTableName("qtestschema", __FILE__)));
+ QVERIFY_SQL(q, exec("CREATE SCHEMA " + qTableName("qtestschema", __FILE__, db)));
- QString table = qTableName("qtestschema", __FILE__) + '.' + qTableName("qtesttable", __FILE__);
+ QString table = qTableName("qtestschema", __FILE__, db) + '.' + qTableName("qtesttable", __FILE__, db);
QVERIFY_SQL(q, exec("CREATE TABLE " + table + " (id int primary key, name varchar(20))"));
QVERIFY(db.tables().contains(table));
@@ -1278,8 +1278,8 @@ void tst_QSqlDatabase::psql_escapedIdentifiers()
if(tst_Databases::isPostgreSQL(db))
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- const QString schemaName(qTableName("qtestScHeMa", __FILE__)),
- tableName(qTableName("qtest", __FILE__)),
+ const QString schemaName(qTableName("qtestScHeMa", __FILE__, db)),
+ tableName(qTableName("qtest", __FILE__, db)),
field1Name(QLatin1String("fIeLdNaMe")),
field2Name(QLatin1String("ZuLu"));
@@ -1318,7 +1318,7 @@ void tst_QSqlDatabase::psql_escapeBytea()
QByteArray ba(dta, 4);
QSqlQuery q(db);
- const QString tableName(qTableName("batable", __FILE__));
+ const QString tableName(qTableName("batable", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (ba bytea)").arg(tableName)));
QSqlQuery iq(db);
@@ -1351,7 +1351,7 @@ void tst_QSqlDatabase::bug_249059()
QSKIP("Test requires PostgreSQL >= 7.3");
QSqlQuery q(db);
- const QString tableName(qTableName("bug_249059", __FILE__));
+ const QString tableName(qTableName("bug_249059", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (dt timestamp, t time)").arg(tableName)));
QSqlQuery iq(db);
@@ -1386,7 +1386,7 @@ void tst_QSqlDatabase::precisionPolicy()
// DBMS_SPECIFIC(db, "QPSQL");
QSqlQuery q(db);
- const QString tableName(qTableName("qtest_prec", __FILE__));
+ const QString tableName(qTableName("qtest_prec", __FILE__, db));
if(!db.driver()->hasFeature(QSqlDriver::LowPrecisionNumbers))
QSKIP("Driver or database doesn't support setting precision policy");
@@ -1422,8 +1422,6 @@ void tst_QSqlDatabase::precisionPolicy()
q.setNumericalPrecisionPolicy(QSql::LowPrecisionInt32);
QVERIFY_SQL(q, exec(query));
- if(db.driverName().startsWith("QOCI"))
- QEXPECT_FAIL("", "Oracle fails to move to next when data columns are oversize", Abort);
QVERIFY_SQL(q, next());
if(db.driverName().startsWith("QSQLITE"))
QEXPECT_FAIL("", "SQLite returns this value as determined by contents of the field, not the declaration", Continue);
@@ -1481,7 +1479,7 @@ void tst_QSqlDatabase::mysqlOdbc_unsignedIntegers()
QSKIP("MySQL through ODBC-driver specific test");
QSqlQuery q(db);
- const QString tableName(qTableName("uint", __FILE__));
+ const QString tableName(qTableName("uint", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (foo integer(10) unsigned, bar integer(10))").arg(tableName)));
QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (-4000000000, -4000000000)").arg(tableName)));
QVERIFY_SQL(q, exec(QString("INSERT INTO %1 VALUES (4000000000, 4000000000)").arg(tableName)));
@@ -1505,7 +1503,7 @@ void tst_QSqlDatabase::accessOdbc_strings()
QSKIP("MS Access specific test");
QSqlQuery q(db);
- const QString tableName(qTableName("strings", __FILE__));
+ const QString tableName(qTableName("strings", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (aStr memo, bStr memo, cStr memo, dStr memo"
", eStr memo, fStr memo, gStr memo, hStr memo)").arg(tableName)));
@@ -1543,7 +1541,7 @@ void tst_QSqlDatabase::ibase_numericFields()
CHECK_DATABASE(db);
QSqlQuery q(db);
- const QString tableName(qTableName("numericfields", __FILE__));
+ const QString tableName(qTableName("numericfields", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (id int not null, num1 NUMERIC(2,1), "
"num2 NUMERIC(5,2), num3 NUMERIC(10,3), "
"num4 NUMERIC(18,4))").arg(tableName)));
@@ -1615,7 +1613,7 @@ void tst_QSqlDatabase::ibase_fetchBlobs()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("qtest_ibaseblobs", __FILE__));
+ const QString tableName(qTableName("qtest_ibaseblobs", __FILE__, db));
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1 (blob1 BLOB segment size 256)").arg(tableName)));
@@ -1648,7 +1646,7 @@ void tst_QSqlDatabase::ibase_procWithoutReturnValues()
CHECK_DATABASE(db);
QSqlQuery q(db);
- const QString procName(qTableName("qtest_proc1", __FILE__));
+ const QString procName(qTableName("qtest_proc1", __FILE__, db));
q.exec(QString("drop procedure %1").arg(procName));
QVERIFY_SQL(q, exec("CREATE PROCEDURE " + procName + " (str VARCHAR(10))\nAS BEGIN\nstr='test';\nEND;"));
QVERIFY_SQL(q, exec(QString("execute procedure %1('qtest')").arg(procName)));
@@ -1664,7 +1662,7 @@ void tst_QSqlDatabase::ibase_procWithReturnValues()
if (!db.driverName().startsWith("QIBASE"))
QSKIP("InterBase specific test");
- const QString procName(qTableName("qtest_proc2", __FILE__));
+ const QString procName(qTableName("qtest_proc2", __FILE__, db));
QSqlQuery q(db);
q.exec(QString("drop procedure %1").arg(procName));
@@ -1706,11 +1704,11 @@ void tst_QSqlDatabase::formatValueTrimStrings()
QSqlQuery q(db);
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (50, 'Trim Test ', 'Trim Test 2 ')").arg(qTableName("qtest", __FILE__))));
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (51, 'TrimTest', 'Trim Test 2')").arg(qTableName("qtest", __FILE__))));
- QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (52, ' ', ' ')").arg(qTableName("qtest", __FILE__))));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (50, 'Trim Test ', 'Trim Test 2 ')").arg(qTableName("qtest", __FILE__, db))));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (51, 'TrimTest', 'Trim Test 2')").arg(qTableName("qtest", __FILE__, db))));
+ QVERIFY_SQL(q, exec(QString("INSERT INTO %1 (id, t_varchar, t_char) values (52, ' ', ' ')").arg(qTableName("qtest", __FILE__, db))));
- QVERIFY_SQL(q, exec(QString("SELECT t_varchar, t_char FROM %1 WHERE id >= 50 AND id <= 52 ORDER BY id").arg(qTableName("qtest", __FILE__))));
+ QVERIFY_SQL(q, exec(QString("SELECT t_varchar, t_char FROM %1 WHERE id >= 50 AND id <= 52 ORDER BY id").arg(qTableName("qtest", __FILE__, db))));
QVERIFY_SQL(q, next());
@@ -1734,10 +1732,10 @@ void tst_QSqlDatabase::odbc_reopenDatabase()
CHECK_DATABASE(db);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__)));
+ QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__, db)));
QVERIFY_SQL(q, next());
db.open();
- QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__)));
+ QVERIFY_SQL(q, exec("SELECT * from " + qTableName("qtest", __FILE__, db)));
QVERIFY_SQL(q, next());
db.open();
}
@@ -1752,10 +1750,10 @@ void tst_QSqlDatabase::odbc_bindBoolean()
QSKIP("MySql has inconsistent behaviour of bit field type across versions.");
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtestBindBool", __FILE__) + "(id int, boolvalue bit)"));
+ QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtestBindBool", __FILE__, db) + "(id int, boolvalue bit)"));
// Bind and insert
- QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("qtestBindBool", __FILE__) + " VALUES(?, ?)"));
+ QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("qtestBindBool", __FILE__, db) + " VALUES(?, ?)"));
q.bindValue(0, 1);
q.bindValue(1, true);
QVERIFY_SQL(q, exec());
@@ -1764,7 +1762,7 @@ void tst_QSqlDatabase::odbc_bindBoolean()
QVERIFY_SQL(q, exec());
// Retrive
- QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + qTableName("qtestBindBool", __FILE__) + " ORDER BY id"));
+ QVERIFY_SQL(q, exec("SELECT id, boolvalue FROM " + qTableName("qtestBindBool", __FILE__, db) + " ORDER BY id"));
QVERIFY_SQL(q, next());
QCOMPARE(q.value(0).toInt(), 1);
QCOMPARE(q.value(1).toBool(), true);
@@ -1778,7 +1776,7 @@ void tst_QSqlDatabase::odbc_testqGetString()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString testqGetString(qTableName("testqGetString", __FILE__));
+ const QString testqGetString(qTableName("testqGetString", __FILE__, db));
QSqlQuery q(db);
if (tst_Databases::isSqlServer(db))
@@ -1822,7 +1820,7 @@ void tst_QSqlDatabase::mysql_multiselect()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString qtest(qTableName("qtest", __FILE__));
+ const QString qtest(qTableName("qtest", __FILE__, db));
QSqlQuery q(db);
QString version=tst_Databases::getMySqlVersion( db );
@@ -1848,7 +1846,7 @@ void tst_QSqlDatabase::ibase_useCustomCharset()
db.setConnectOptions("ISC_DPB_LC_CTYPE=Latin1");
db.open();
- const QString tableName(qTableName("latin1table", __FILE__));
+ const QString tableName(qTableName("latin1table", __FILE__, db));
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(text VARCHAR(6) CHARACTER SET Latin1)").arg(tableName)));
@@ -1886,8 +1884,8 @@ void tst_QSqlDatabase::oci_xmltypeSupport()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("qtest_xmltype", __FILE__));
- QString xml("<?xml version=\"1.0\"?><TABLE_NAME>MY_TABLE</TABLE_NAME>");
+ const QString tableName(qTableName("qtest_xmltype", __FILE__, db));
+ QString xml("<?xml version=\"1.0\"?>\n<TABLE_NAME>MY_TABLE</TABLE_NAME>\n");
QSqlQuery q(db);
// Embedding the XML in the statement
@@ -1914,7 +1912,7 @@ void tst_QSqlDatabase::oci_fieldLength()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("qtest", __FILE__));
+ const QString tableName(qTableName("qtest", __FILE__, db));
QSqlQuery q(db);
QVERIFY_SQL(q, exec(QString("SELECT t_varchar, t_char FROM %1").arg(tableName)));
@@ -1930,7 +1928,7 @@ void tst_QSqlDatabase::oci_synonymstest()
CHECK_DATABASE(db);
QSqlQuery q(db);
- const QString creator(qTableName("CREATOR", __FILE__)), appuser(qTableName("APPUSER", __FILE__)), table1(qTableName("TABLE1", __FILE__));
+ const QString creator(qTableName("CREATOR", __FILE__, db)), appuser(qTableName("APPUSER", __FILE__, db)), table1(qTableName("TABLE1", __FILE__, db));
// QVERIFY_SQL(q, exec("drop public synonym "+table1));
QVERIFY_SQL(q, exec(QString("create user %1 identified by %2 default tablespace users temporary tablespace temp").arg(creator).arg(creator)));
QVERIFY_SQL(q, exec(QString("grant CONNECT to %1").arg(creator)));
@@ -1948,8 +1946,8 @@ void tst_QSqlDatabase::oci_synonymstest()
db3.close();
QVERIFY_SQL(db3, open(appuser,appuser));
QSqlQuery q3(db3);
- QVERIFY_SQL(q3, exec("create synonym "+appuser+'.'+qTableName("synonyms", __FILE__)+" for "+creator+'.'+table1));
- QVERIFY_SQL(db3, tables().filter(qTableName("synonyms", __FILE__), Qt::CaseInsensitive).count() >= 1);
+ QVERIFY_SQL(q3, exec("create synonym " + appuser + '.' + qTableName("synonyms", __FILE__, db) + " for " + creator + '.' + table1));
+ QVERIFY_SQL(db3, tables().filter(qTableName("synonyms", __FILE__, db), Qt::CaseInsensitive).count() >= 1);
}
@@ -1963,7 +1961,7 @@ void tst_QSqlDatabase::odbc_uniqueidentifier()
if (!tst_Databases::isSqlServer(db))
QSKIP("SQL Server (ODBC) specific test");
- const QString tableName(qTableName("qtest_sqlguid", __FILE__));
+ const QString tableName(qTableName("qtest_sqlguid", __FILE__, db));
QString guid = QString("AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
QString invalidGuid = QString("GAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE");
@@ -2006,7 +2004,7 @@ void tst_QSqlDatabase::odbc_uintfield()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("uint_table", __FILE__));
+ const QString tableName(qTableName("uint_table", __FILE__, db));
unsigned int val = 4294967295U;
QSqlQuery q(db);
@@ -2070,7 +2068,7 @@ void tst_QSqlDatabase::eventNotificationIBase()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString procedureName(qTableName("posteventProc", __FILE__));
+ const QString procedureName(qTableName("posteventProc", __FILE__, db));
QSqlDriver *driver=db.driver();
QVERIFY_SQL(*driver, subscribeToNotification(procedureName));
QTest::qWait(300); // Interbase needs some time to call the driver callback.
@@ -2100,7 +2098,7 @@ void tst_QSqlDatabase::eventNotificationPSQL()
CHECK_DATABASE(db);
QSqlQuery query(db);
- QString procedureName = qTableName("posteventProc", __FILE__);
+ QString procedureName = qTableName("posteventProc", __FILE__, db);
QString payload = "payload";
QSqlDriver &driver=*(db.driver());
QVERIFY_SQL(driver, subscribeToNotification(procedureName));
@@ -2124,7 +2122,7 @@ void tst_QSqlDatabase::sqlite_bindAndFetchUInt()
QSKIP("SQLite3 specific test");
QSqlQuery q(db);
- const QString tableName(qTableName("uint_test", __FILE__));
+ const QString tableName(qTableName("uint_test", __FILE__, db));
QVERIFY_SQL(q, exec(QString("CREATE TABLE %1(uint_field UNSIGNED INTEGER)").arg(tableName)));
QVERIFY_SQL(q, prepare(QString("INSERT INTO %1 VALUES(?)").arg(tableName)));
q.addBindValue(4000000000U);
@@ -2144,7 +2142,7 @@ void tst_QSqlDatabase::db2_valueCacheUpdate()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("qtest", __FILE__));
+ const QString tableName(qTableName("qtest", __FILE__, db));
QSqlQuery q(db);
q.exec(QString("SELECT id, t_varchar, t_char, t_numeric FROM %1").arg(tableName));
q.next();
@@ -2167,7 +2165,7 @@ void tst_QSqlDatabase::sqlStatementUseIsNull_189093()
// select a record with NULL value
QSqlQuery q(QString::null, db);
- QVERIFY_SQL(q, exec("select * from " + qTableName("qtest", __FILE__) + " where id = 4"));
+ QVERIFY_SQL(q, exec("select * from " + qTableName("qtest", __FILE__, db) + " where id = 4"));
QVERIFY_SQL(q, next());
QSqlDriver *driver = db.driver();
@@ -2190,17 +2188,18 @@ void tst_QSqlDatabase::mysql_savepointtest()
QSqlQuery q(db);
QVERIFY_SQL(q, exec("begin"));
- QVERIFY_SQL(q, exec("insert into "+qTableName("qtest", __FILE__)+" VALUES (54, 'foo', 'foo', 54.54)"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("qtest", __FILE__, db) + " VALUES (54, 'foo', 'foo', 54.54)"));
QVERIFY_SQL(q, exec("savepoint foo"));
}
void tst_QSqlDatabase::oci_tables()
{
+ QSKIP("Requires specific permissions to create a system table");
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
QSqlQuery q(db);
- const QString systemTableName("system."+qTableName("mypassword", __FILE__));
+ const QString systemTableName("sys." + qTableName("mypassword", __FILE__, db).toUpper());
QVERIFY_SQL(q, exec("CREATE TABLE "+systemTableName+"(name VARCHAR(20))"));
QVERIFY(!db.tables().contains(systemTableName.toUpper()));
QVERIFY(db.tables(QSql::SystemTables).contains(systemTableName.toUpper()));
@@ -2220,8 +2219,8 @@ void tst_QSqlDatabase::sqlite_enable_cache_mode()
db2.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE");
QVERIFY_SQL(db2, open());
QSqlQuery q(db), q2(db2);
- QVERIFY_SQL(q, exec("select * from "+qTableName("qtest", __FILE__)));
- QVERIFY_SQL(q2, exec("select * from "+qTableName("qtest", __FILE__)));
+ QVERIFY_SQL(q, exec("select * from " + qTableName("qtest", __FILE__, db)));
+ QVERIFY_SQL(q2, exec("select * from " + qTableName("qtest", __FILE__, db)));
}
QTEST_MAIN(tst_QSqlDatabase)
diff --git a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
index 852cb8f41e..3500e26f5e 100644
--- a/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
+++ b/tests/auto/sql/kernel/qsqldriver/tst_qsqldriver.cpp
@@ -77,7 +77,7 @@ void tst_QSqlDriver::initTestCase_data()
void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
{
QSqlQuery q(db);
- const QString relTEST1(qTableName("relTEST1", __FILE__));
+ const QString relTEST1(qTableName("relTEST1", __FILE__, db));
if(tst_Databases::isPostgreSQL(db))
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
@@ -102,7 +102,7 @@ void tst_QSqlDriver::cleanupTestCase()
{
foreach (const QString &dbName, dbs.dbNames) {
QSqlDatabase db = QSqlDatabase::database(dbName);
- tst_Databases::safeDropTable( db, qTableName( "relTEST1", __FILE__ ) );
+ tst_Databases::safeDropTable(db, qTableName("relTEST1", __FILE__, db));
}
dbs.close();
}
@@ -121,7 +121,7 @@ void tst_QSqlDriver::record()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tablename(qTableName("relTEST1", __FILE__));
+ QString tablename(qTableName("relTEST1", __FILE__, db));
QStringList fields;
fields << "id" << "name" << "title_key" << "another_title_key";
@@ -178,7 +178,7 @@ void tst_QSqlDriver::primaryIndex()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tablename(qTableName("relTEST1", __FILE__));
+ QString tablename(qTableName("relTEST1", __FILE__, db));
//check that we can get primary index using unquoted mixed case table name
QSqlIndex index = db.driver()->primaryIndex(tablename);
QCOMPARE(index.count(), 1);
diff --git a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
index 1fbdd31a8f..ff458d6f2b 100644
--- a/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
+++ b/tests/auto/sql/kernel/qsqlquery/tst_qsqlquery.cpp
@@ -44,7 +44,7 @@
#include "../qsqldatabase/tst_databases.h"
-const QString qtest(qTableName( "qtest", __FILE__ ));
+const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
class tst_QSqlQuery : public QObject
{
@@ -318,59 +318,59 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
QStringList tablenames;
// drop all the table in case a testcase failed
tablenames << qtest
- << qTableName( "qtest_null", __FILE__ )
- << qTableName( "qtest_blob", __FILE__ )
- << qTableName( "qtest_bittest", __FILE__ )
- << qTableName( "qtest_nullblob", __FILE__ )
- << qTableName( "qtest_rawtest", __FILE__ )
- << qTableName( "qtest_precision", __FILE__ )
- << qTableName( "qtest_prepare", __FILE__ )
- << qTableName( "qtestj1", __FILE__ )
- << qTableName( "qtestj2", __FILE__ )
- << qTableName( "char1Select", __FILE__ )
- << qTableName( "char1SU", __FILE__ )
- << qTableName( "qxmltest", __FILE__ )
- << qTableName( "qtest_exerr", __FILE__ )
- << qTableName( "qtest_empty", __FILE__ )
- << qTableName( "clobby", __FILE__ )
- << qTableName( "bindtest", __FILE__ )
- << qTableName( "more_results", __FILE__ )
- << qTableName( "blobstest", __FILE__ )
- << qTableName( "oraRowId", __FILE__ )
- << qTableName( "qtest_batch", __FILE__ )
- << qTableName("bug6421", __FILE__).toUpper()
- << qTableName("bug5765", __FILE__)
- << qTableName("bug6852", __FILE__)
- << qTableName("bug21884", __FILE__)
- << qTableName("bug23895", __FILE__)
- << qTableName( "qtest_lockedtable", __FILE__ )
- << qTableName( "Planet", __FILE__ )
- << qTableName( "task_250026", __FILE__ )
- << qTableName( "task_234422", __FILE__ )
- << qTableName("test141895", __FILE__)
- << qTableName("qtest_oraOCINumber", __FILE__)
- << qTableName( "bug2192", __FILE__);
+ << qTableName("qtest_null", __FILE__, db)
+ << qTableName("qtest_blob", __FILE__, db)
+ << qTableName("qtest_bittest", __FILE__, db)
+ << qTableName("qtest_nullblob", __FILE__, db)
+ << qTableName("qtest_rawtest", __FILE__, db)
+ << qTableName("qtest_precision", __FILE__, db)
+ << qTableName("qtest_prepare", __FILE__, db)
+ << qTableName("qtestj1", __FILE__, db)
+ << qTableName("qtestj2", __FILE__, db)
+ << qTableName("char1Select", __FILE__, db)
+ << qTableName("char1SU", __FILE__, db)
+ << qTableName("qxmltest", __FILE__, db)
+ << qTableName("qtest_exerr", __FILE__, db)
+ << qTableName("qtest_empty", __FILE__, db)
+ << qTableName("clobby", __FILE__, db)
+ << qTableName("bindtest", __FILE__, db)
+ << qTableName("more_results", __FILE__, db)
+ << qTableName("blobstest", __FILE__, db)
+ << qTableName("oraRowId", __FILE__, db)
+ << qTableName("qtest_batch", __FILE__, db)
+ << qTableName("bug6421", __FILE__, db).toUpper()
+ << qTableName("bug5765", __FILE__, db)
+ << qTableName("bug6852", __FILE__, db)
+ << qTableName("bug21884", __FILE__, db)
+ << qTableName("bug23895", __FILE__, db)
+ << qTableName("qtest_lockedtable", __FILE__, db)
+ << qTableName("Planet", __FILE__, db)
+ << qTableName("task_250026", __FILE__, db)
+ << qTableName("task_234422", __FILE__, db)
+ << qTableName("test141895", __FILE__, db)
+ << qTableName("qtest_oraOCINumber", __FILE__, db)
+ << qTableName("bug2192", __FILE__, db);
if ( db.driverName().startsWith("QPSQL") )
- tablenames << qTableName("task_233829", __FILE__);
+ tablenames << qTableName("task_233829", __FILE__, db);
if ( db.driverName().startsWith("QSQLITE") )
- tablenames << qTableName( "record_sqlite", __FILE__ );
+ tablenames << qTableName("record_sqlite", __FILE__, db);
if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QOCI" ) )
- tablenames << qTableName( "qtest_longstr", __FILE__ );
+ tablenames << qTableName("qtest_longstr", __FILE__, db);
if (tst_Databases::isSqlServer( db ))
- db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__));
+ db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__, db));
if (tst_Databases::isMySQL( db ))
- db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__));
+ db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__, db));
tst_Databases::safeDropTables( db, tablenames );
if ( db.driverName().startsWith( "QOCI" ) ) {
QSqlQuery q( db );
- q.exec( "DROP PACKAGE " + qTableName("pkg", __FILE__) );
+ q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db));
}
}
@@ -391,15 +391,15 @@ void tst_QSqlQuery::createTestTables( QSqlDatabase db )
QVERIFY_SQL( q, exec( "create table " + qtest + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) );
if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) )
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null", __FILE__ ) + " (id int null, t_varchar varchar(20) null)" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int null, t_varchar varchar(20) null)"));
else
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null", __FILE__ ) + " (id int, t_varchar varchar(20))" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int, t_varchar varchar(20))"));
}
void tst_QSqlQuery::populateTestTables( QSqlDatabase db )
{
QSqlQuery q( db );
- const QString qtest_null(qTableName( "qtest_null", __FILE__ ));
+ const QString qtest_null(qTableName( "qtest_null", __FILE__, db));
q.exec( "delete from " + qtest );
QVERIFY_SQL( q, exec( "insert into " + qtest + " values (1, 'VarChar1', 'Char1')" ) );
QVERIFY_SQL( q, exec( "insert into " + qtest + " values (2, 'VarChar2', 'Char2')" ) );
@@ -423,7 +423,7 @@ void tst_QSqlQuery::char1Select()
{
QSqlQuery q( db );
- const QString tbl = qTableName("char1Select", __FILE__);
+ const QString tbl = qTableName("char1Select", __FILE__, db);
q.exec( "drop table " + tbl);
QVERIFY_SQL(q, exec("create table " + tbl + " (id char(1))"));
QVERIFY_SQL(q, exec("insert into " + tbl + " values ('a')"));
@@ -456,7 +456,7 @@ void tst_QSqlQuery::char1SelectUnicode()
QSKIP( "Test requires MySQL >= 5.0");
QString createQuery;
- const QString char1SelectUnicode(qTableName( "char1SU", __FILE__ ));
+ const QString char1SelectUnicode(qTableName("char1SU", __FILE__, db));
if ( tst_Databases::isSqlServer( db ) )
createQuery = "create table " + char1SelectUnicode + "(id nchar(1))";
@@ -501,7 +501,7 @@ void tst_QSqlQuery::oraRowId()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString oraRowId(qTableName("oraRowId", __FILE__));
+ const QString oraRowId(qTableName("oraRowId", __FILE__, db));
QSqlQuery q( db );
QVERIFY_SQL( q, exec( "select rowid from " + qtest ) );
@@ -536,7 +536,7 @@ void tst_QSqlQuery::mysqlOutValues()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString hello(qTableName( "hello", __FILE__ )), qtestproc(qTableName( "qtestproc", __FILE__ ));
+ const QString hello(qTableName("hello", __FILE__, db)), qtestproc(qTableName("qtestproc", __FILE__, db));
QSqlQuery q( db );
@@ -594,7 +594,7 @@ void tst_QSqlQuery::bindBool()
CHECK_DATABASE( db );
QSqlQuery q(db);
- const QString tableName(qTableName( "bindBool", __FILE__ ));
+ const QString tableName(qTableName("bindBool", __FILE__, db));
q.exec("DROP TABLE " + tableName);
QString colType = db.driverName().startsWith("QPSQL") ? QLatin1String("BOOLEAN") : QLatin1String("INT");
QVERIFY_SQL(q, exec("CREATE TABLE " + tableName + " (id INT, flag " + colType + " NOT NULL, PRIMARY KEY(id))"));
@@ -622,7 +622,7 @@ void tst_QSqlQuery::oraOutValues()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString tst_outValues(qTableName("tst_outValues", __FILE__));
+ const QString tst_outValues(qTableName("tst_outValues", __FILE__, db));
if ( !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
QSKIP( "Test requires prepared query support");
@@ -718,7 +718,7 @@ void tst_QSqlQuery::oraClob()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString clobby(qTableName("clobby", __FILE__));
+ const QString clobby(qTableName("clobby", __FILE__, db));
QSqlQuery q( db );
@@ -771,16 +771,16 @@ void tst_QSqlQuery::storedProceduresIBase()
CHECK_DATABASE( db );
QSqlQuery q( db );
- q.exec( "drop procedure " + qTableName( "TESTPROC", __FILE__ ) );
+ q.exec("drop procedure " + qTableName("TESTPROC", __FILE__, db));
- QVERIFY_SQL( q, exec( "create procedure " + qTableName( "TESTPROC", __FILE__ ) +
+ QVERIFY_SQL(q, exec("create procedure " + qTableName("TESTPROC", __FILE__, db) +
" RETURNS (x integer, y varchar(20)) "
"AS BEGIN "
" x = 42; "
" y = 'Hello Anders'; "
"END" ) );
- QVERIFY_SQL( q, prepare( "execute procedure " + qTableName( "TestProc", __FILE__ ) ) );
+ QVERIFY_SQL(q, prepare("execute procedure " + qTableName("TestProc", __FILE__, db)));
QVERIFY_SQL( q, exec() );
// check for a valid result set
@@ -797,7 +797,7 @@ void tst_QSqlQuery::storedProceduresIBase()
// the second next shall fail
QVERIFY( !q.next() );
- q.exec( "drop procedure " + qTableName( "TestProc", __FILE__ ) );
+ q.exec("drop procedure " + qTableName("TestProc", __FILE__, db));
}
void tst_QSqlQuery::outValuesDB2()
@@ -813,8 +813,8 @@ void tst_QSqlQuery::outValuesDB2()
q.setForwardOnly( true );
- q.exec( "drop procedure " + qTableName( "tst_outValues", __FILE__ ) ); //non-fatal
- QVERIFY_SQL( q, exec( "CREATE PROCEDURE " + qTableName( "tst_outValues", __FILE__ ) +
+ q.exec("drop procedure " + qTableName("tst_outValues", __FILE__, db)); //non-fatal
+ QVERIFY_SQL( q, exec( "CREATE PROCEDURE " + qTableName("tst_outValues", __FILE__, db) +
" (OUT x int, OUT x2 double, OUT x3 char(20))\n"
"LANGUAGE SQL\n"
"P1: BEGIN\n"
@@ -823,7 +823,7 @@ void tst_QSqlQuery::outValuesDB2()
" SET x3 = 'Homer';\n"
"END P1" ) );
- QVERIFY_SQL( q, prepare( "call " + qTableName( "tst_outValues", __FILE__ ) + "(?, ?, ?)" ) );
+ QVERIFY_SQL(q, prepare("call " + qTableName("tst_outValues", __FILE__, db) + "(?, ?, ?)"));
q.addBindValue( 0, QSql::Out );
q.addBindValue( 0.0, QSql::Out );
@@ -841,7 +841,7 @@ void tst_QSqlQuery::outValues()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString tst_outValues(qTableName("tst_outValues", __FILE__));
+ const QString tst_outValues(qTableName("tst_outValues", __FILE__, db));
if ( !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
QSKIP( "Test requires prepared query support");
@@ -905,11 +905,11 @@ void tst_QSqlQuery::blob()
q.setForwardOnly( true );
- QString queryString = QString( "create table " + qTableName( "qtest_blob", __FILE__ ) +
+ QString queryString = QString("create table " + qTableName("qtest_blob", __FILE__, db) +
" (id int not null primary key, t_blob %1)" ).arg( tst_Databases::blobTypeName( db, BLOBSIZE ) );
QVERIFY_SQL( q, exec( queryString ) );
- QVERIFY_SQL( q, prepare( "insert into " + qTableName( "qtest_blob", __FILE__ ) + " (id, t_blob) values (?, ?)" ) );
+ QVERIFY_SQL(q, prepare("insert into " + qTableName("qtest_blob", __FILE__, db) + " (id, t_blob) values (?, ?)"));
for ( i = 0; i < BLOBCOUNT; ++i ) {
q.addBindValue( i );
@@ -917,7 +917,7 @@ void tst_QSqlQuery::blob()
QVERIFY_SQL( q, exec() );
}
- QVERIFY_SQL( q, exec( "select * from " + qTableName( "qtest_blob", __FILE__ ) ) );
+ QVERIFY_SQL(q, exec("select * from " + qTableName("qtest_blob", __FILE__, db)));
for ( i = 0; i < BLOBCOUNT; ++i ) {
QVERIFY( q.next() );
@@ -1382,7 +1382,7 @@ void tst_QSqlQuery::isNull()
CHECK_DATABASE( db );
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "select id, t_varchar from " + qTableName( "qtest_null", __FILE__ ) + " order by id" ) );
+ QVERIFY_SQL(q, exec("select id, t_varchar from " + qTableName("qtest_null", __FILE__, db) + " order by id"));
QVERIFY( q.next() );
QVERIFY( !q.isNull( 0 ) );
QVERIFY( q.isNull( 1 ) );
@@ -1408,13 +1408,13 @@ void tst_QSqlQuery::bitField()
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_bittest", __FILE__ ) + " (bitty bit)" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_bittest", __FILE__, db) + " (bitty bit)"));
- QVERIFY_SQL( q, exec( "insert into " + qTableName( "qtest_bittest", __FILE__ ) + " values (0)" ) );
+ QVERIFY_SQL(q, exec("insert into " + qTableName("qtest_bittest", __FILE__, db) + " values (0)"));
- QVERIFY_SQL( q, exec( "insert into " + qTableName( "qtest_bittest", __FILE__ ) + " values (1)" ) );
+ QVERIFY_SQL(q, exec("insert into " + qTableName("qtest_bittest", __FILE__, db) + " values (1)"));
- QVERIFY_SQL( q, exec( "select bitty from " + qTableName( "qtest_bittest", __FILE__ ) ) );
+ QVERIFY_SQL(q, exec("select bitty from " + qTableName("qtest_bittest", __FILE__, db)));
QVERIFY( q.next() );
@@ -1432,7 +1432,7 @@ void tst_QSqlQuery::nullBlob()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtest_nullblob(qTableName("qtest_nullblob", __FILE__));
+ const QString qtest_nullblob(qTableName("qtest_nullblob", __FILE__, db));
QSqlQuery q( db );
QVERIFY_SQL( q, exec( "create table " + qtest_nullblob + " (id int primary key, bb blob)" ) );
@@ -1462,7 +1462,7 @@ void tst_QSqlQuery::rawField()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtest_rawtest(qTableName("qtest_rawtest", __FILE__));
+ const QString qtest_rawtest(qTableName("qtest_rawtest", __FILE__, db));
QSqlQuery q( db );
q.setForwardOnly( true );
@@ -1487,7 +1487,7 @@ void tst_QSqlQuery::precision()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtest_precision(qTableName( "qtest_precision", __FILE__ ));
+ const QString qtest_precision(qTableName("qtest_precision", __FILE__, db));
static const char* precStr = "1.2345678901234567891";
@@ -1646,7 +1646,7 @@ void tst_QSqlQuery::joins()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtestj1(qTableName("qtestj1", __FILE__)), qtestj2(qTableName("qtestj2", __FILE__));
+ const QString qtestj1(qTableName("qtestj1", __FILE__, db)), qtestj2(qTableName("qtestj2", __FILE__, db));
if ( db.driverName().startsWith( "QOCI" )
|| db.driverName().startsWith( "QTDS" )
@@ -1731,7 +1731,7 @@ void tst_QSqlQuery::prepare_bind_exec()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtest_prepare(qTableName("qtest_prepare", __FILE__));
+ const QString qtest_prepare(qTableName("qtest_prepare", __FILE__, db));
if(db.driverName().startsWith("QIBASE") && (db.databaseName() == "silence.nokia.troll.no:c:\\ibase\\testdb_ascii" || db.databaseName() == "/opt/interbase/qttest.gdb"))
QSKIP("Can't transliterate extended unicode to ascii");
@@ -2031,9 +2031,9 @@ void tst_QSqlQuery::sqlServerLongStrings()
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "CREATE TABLE " + qTableName( "qtest_longstr", __FILE__ ) + " (id int primary key, longstring ntext)" ) );
+ QVERIFY_SQL(q, exec("CREATE TABLE " + qTableName("qtest_longstr", __FILE__, db) + " (id int primary key, longstring ntext)"));
- QVERIFY_SQL( q, prepare( "INSERT INTO " + qTableName( "qtest_longstr", __FILE__ ) + " VALUES (?, ?)" ) );
+ QVERIFY_SQL(q, prepare("INSERT INTO " + qTableName("qtest_longstr", __FILE__, db) + " VALUES (?, ?)"));
q.addBindValue( 0 );
@@ -2051,7 +2051,7 @@ void tst_QSqlQuery::sqlServerLongStrings()
QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, exec( "select * from " + qTableName( "qtest_longstr", __FILE__ ) ) );
+ QVERIFY_SQL(q, exec("select * from " + qTableName( "qtest_longstr", __FILE__, db)));
QVERIFY_SQL( q, next() );
@@ -2103,7 +2103,7 @@ void tst_QSqlQuery::batchExec()
QSKIP( "Database can't do BatchOperations");
QSqlQuery q( db );
- const QString tableName = qTableName( "qtest_batch", __FILE__ );
+ const QString tableName = qTableName("qtest_batch", __FILE__, db);
QVERIFY_SQL( q, exec( "create table " + tableName + " (id int, name varchar(20), dt date, num numeric(8, 4))" ) );
QVERIFY_SQL( q, prepare( "insert into " + tableName + " (id, name, dt, num) values (?, ?, ?, ?)" ) );
@@ -2247,9 +2247,9 @@ void tst_QSqlQuery::record_sqlite()
QSqlQuery q( db );
- QVERIFY_SQL( q, exec( "create table "+qTableName( "record_sqlite", __FILE__ )+"(id integer primary key, name varchar, title int)" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("record_sqlite", __FILE__, db) + "(id integer primary key, name varchar, title int)"));
- QSqlRecord rec = db.record( qTableName( "record_sqlite", __FILE__ ) );
+ QSqlRecord rec = db.record(qTableName("record_sqlite", __FILE__, db));
QCOMPARE( rec.count(), 3 );
QCOMPARE( rec.field( 0 ).type(), QVariant::Int );
@@ -2257,7 +2257,7 @@ void tst_QSqlQuery::record_sqlite()
QCOMPARE( rec.field( 2 ).type(), QVariant::Int );
/* important - select from an empty table */
- QVERIFY_SQL( q, exec( "select id, name, title from "+qTableName( "record_sqlite", __FILE__ ) ) );
+ QVERIFY_SQL(q, exec("select id, name, title from " + qTableName("record_sqlite", __FILE__, db)));
rec = q.record();
QCOMPARE( rec.count(), 3 );
@@ -2276,13 +2276,13 @@ void tst_QSqlQuery::oraLong()
QString aLotOfText( 127000, QLatin1Char( 'H' ) );
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_longstr", __FILE__ ) + " (id int primary key, astr long)" ) );
- QVERIFY_SQL( q, prepare( "insert into " + qTableName( "qtest_longstr", __FILE__ ) + " (id, astr) values (?, ?)" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_longstr", __FILE__, db) + " (id int primary key, astr long)"));
+ QVERIFY_SQL(q, prepare("insert into " + qTableName("qtest_longstr", __FILE__, db) + " (id, astr) values (?, ?)"));
q.addBindValue( 1 );
q.addBindValue( aLotOfText );
QVERIFY_SQL( q, exec() );
- QVERIFY_SQL( q, exec( "select id,astr from " + qTableName( "qtest_longstr", __FILE__ ) ) );
+ QVERIFY_SQL(q, exec("select id,astr from " + qTableName("qtest_longstr", __FILE__, db)));
QVERIFY( q.next() );
QCOMPARE( q.value( 0 ).toInt(), 1 );
@@ -2297,7 +2297,7 @@ void tst_QSqlQuery::execErrorRecovery()
QSqlQuery q( db );
- const QString tbl = qTableName("qtest_exerr", __FILE__);
+ const QString tbl = qTableName("qtest_exerr", __FILE__, db);
q.exec("drop table " + tbl);
QVERIFY_SQL(q, exec("create table " + tbl + " (id int not null primary key)"));
QVERIFY_SQL(q, prepare("insert into " + tbl + " values (?)" ));
@@ -2354,7 +2354,7 @@ void tst_QSqlQuery::bindWithDoubleColonCastOperator()
if ( !db.driverName().startsWith( "QPSQL" ) )
QSKIP( "Test requires PostgreSQL");
- const QString tablename(qTableName( "bindtest", __FILE__ ));
+ const QString tablename(qTableName("bindtest", __FILE__, db));
QSqlQuery q( db );
@@ -2516,7 +2516,7 @@ void tst_QSqlQuery::sqlite_finish()
db2.setDatabaseName( db.databaseName() );
QVERIFY_SQL( db2, open() );
- const QString tableName(qTableName( "qtest_lockedtable", __FILE__ ));
+ const QString tableName(qTableName("qtest_lockedtable", __FILE__, db));
QSqlQuery q( db );
tst_Databases::safeDropTable( db, tableName );
@@ -2566,7 +2566,7 @@ void tst_QSqlQuery::nextResult()
else if ( db.driverName().startsWith( "QDB2" ) )
driverType = DB2;
- const QString tableName(qTableName( "more_results", __FILE__ ));
+ const QString tableName(qTableName("more_results", __FILE__, db));
QVERIFY_SQL( q, exec( "CREATE TABLE " + tableName + " (id integer, text varchar(20), num numeric(6, 3), empty varchar(10));" ) );
@@ -2670,7 +2670,7 @@ void tst_QSqlQuery::nextResult()
}
// Stored procedure with multiple result sets
- const QString procName(qTableName( "proc_more_res", __FILE__ ));
+ const QString procName(qTableName("proc_more_res", __FILE__, db));
q.exec( QString( "DROP PROCEDURE %1;" ).arg( procName ) );
@@ -2748,7 +2748,7 @@ void tst_QSqlQuery::blobsPreparedQuery()
if ( !db.driver()->hasFeature( QSqlDriver::BLOB ) || !db.driver()->hasFeature( QSqlDriver::PreparedQueries ) )
QSKIP( "DBMS does not support BLOBs or prepared queries");
- const QString tableName(qTableName( "blobstest", __FILE__ ));
+ const QString tableName(qTableName("blobstest", __FILE__, db));
QSqlQuery q( db );
q.setForwardOnly( true ); // This is needed to make the test work with DB2.
@@ -2803,10 +2803,10 @@ void tst_QSqlQuery::emptyTableNavigate()
{
QSqlQuery q( db );
- const QString tbl = qTableName("qtest_empty", __FILE__);
+ const QString tbl = qTableName("qtest_empty", __FILE__, db);
q.exec("drop table " + tbl);
QVERIFY_SQL(q, exec("create table " + tbl + " (id char(10))"));
- QVERIFY_SQL(q, prepare("select * from " + qTableName("qtest_empty", __FILE__ )));
+ QVERIFY_SQL(q, prepare("select * from " + tbl));
QVERIFY_SQL( q, exec() );
QVERIFY( !q.next() );
QCOMPARE( q.lastError().isValid(), false );
@@ -2819,7 +2819,7 @@ void tst_QSqlQuery::task_217003()
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
QSqlQuery q( db );
- const QString Planet(qTableName( "Planet", __FILE__));
+ const QString Planet(qTableName( "Planet", __FILE__, db));
q.exec("drop table " + Planet);
QVERIFY_SQL( q, exec( "create table " + Planet + " (Name varchar(20))" ) );
@@ -2850,7 +2850,7 @@ void tst_QSqlQuery::task_250026()
CHECK_DATABASE( db );
QSqlQuery q( db );
- const QString tableName(qTableName( "task_250026", __FILE__ ));
+ const QString tableName(qTableName("task_250026", __FILE__, db));
if ( !q.exec( "create table " + tableName + " (longfield varchar(1100))" ) ) {
qDebug() << "Error" << q.lastError();
@@ -2898,7 +2898,7 @@ void tst_QSqlQuery::task_229811()
QSqlQuery q( db );
- const QString tableName(qTableName( "task_229811", __FILE__ ));
+ const QString tableName(qTableName("task_229811", __FILE__, db));
if ( !q.exec( "CREATE TABLE " + tableName + " (Word varchar(20))" ) ) {
qDebug() << "Warning" << q.lastError();
@@ -2945,7 +2945,7 @@ void tst_QSqlQuery::task_234422()
m_airlines << "Lufthansa" << "SAS" << "United" << "KLM" << "Aeroflot";
m_countries << "DE" << "SE" << "US" << "NL" << "RU";
- const QString tableName(qTableName( "task_234422", __FILE__ ));
+ const QString tableName(qTableName("task_234422", __FILE__, db));
QVERIFY_SQL(query,exec("CREATE TABLE " + tableName + " (id int primary key, "
"name varchar(20), homecountry varchar(2))"));
@@ -2977,7 +2977,7 @@ void tst_QSqlQuery::task_233829()
CHECK_DATABASE( db );
QSqlQuery q( db );
- const QString tableName(qTableName("task_233829", __FILE__));
+ const QString tableName(qTableName("task_233829", __FILE__, db));
QVERIFY_SQL(q,exec("CREATE TABLE " + tableName + "(dbl1 double precision,dbl2 double precision) without oids;"));
QString queryString("INSERT INTO " + tableName +"(dbl1, dbl2) VALUES(?,?)");
@@ -2997,7 +2997,7 @@ void tst_QSqlQuery::sqlServerReturn0()
if (!tst_Databases::isSqlServer( db ))
QSKIP("SQL Server specific test");
- const QString tableName(qTableName("test141895", __FILE__)), procName(qTableName("test141895_proc", __FILE__));
+ const QString tableName(qTableName("test141895", __FILE__, db)), procName(qTableName("test141895_proc", __FILE__, db));
QSqlQuery q( db );
q.exec("DROP TABLE " + tableName);
q.exec("DROP PROCEDURE " + procName);
@@ -3023,7 +3023,7 @@ void tst_QSqlQuery::QTBUG_551()
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
QSqlQuery q(db);
- const QString pkgname(qTableName("pkg", __FILE__));
+ const QString pkgname(qTableName("pkg", __FILE__, db));
QVERIFY_SQL(q, exec("CREATE OR REPLACE PACKAGE "+pkgname+" IS \n\
\n\
TYPE IntType IS TABLE OF INTEGER INDEX BY BINARY_INTEGER;\n\
@@ -3070,7 +3070,7 @@ void tst_QSqlQuery::QTBUG_14132()
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
QSqlQuery q(db);
- const QString procedureName(qTableName("procedure", __FILE__));
+ const QString procedureName(qTableName("procedure", __FILE__, db));
QVERIFY_SQL(q, exec("CREATE OR REPLACE PROCEDURE "+ procedureName + " (outStr OUT varchar2) \n\
is \n\
begin \n\
@@ -3093,7 +3093,7 @@ void tst_QSqlQuery::QTBUG_18435()
return;
QSqlQuery q(db);
- QString procName(qTableName("qtbug_18435_proc", __FILE__));
+ QString procName(qTableName("qtbug_18435_proc", __FILE__, db));
q.exec("DROP PROCEDURE " + procName);
const QString stmt =
@@ -3118,7 +3118,7 @@ void tst_QSqlQuery::QTBUG_5251()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString timetest(qTableName("timetest", __FILE__));
+ const QString timetest(qTableName("timetest", __FILE__, db));
if (!db.driverName().startsWith( "QPSQL" )) return;
@@ -3151,7 +3151,7 @@ void tst_QSqlQuery::QTBUG_6421()
CHECK_DATABASE( db );
QSqlQuery q(db);
- const QString tableName(qTableName("bug6421", __FILE__).toUpper());
+ const QString tableName(qTableName("bug6421", __FILE__, db).toUpper());
QVERIFY_SQL(q, exec("create table "+tableName+"(COL1 char(10), COL2 char(10), COL3 char(10))"));
QVERIFY_SQL(q, exec("create index INDEX1 on "+tableName+" (COL1 desc)"));
@@ -3176,16 +3176,16 @@ void tst_QSqlQuery::QTBUG_6618()
QSKIP("SQL Server specific test");
QSqlQuery q(db);
- q.exec( "drop procedure " + qTableName( "tst_raiseError", __FILE__ ) ); //non-fatal
+ q.exec("drop procedure " + qTableName("tst_raiseError", __FILE__, db)); //non-fatal
QString errorString;
for (int i=0;i<110;i++)
errorString+="reallylong";
errorString+=" error";
- QVERIFY_SQL( q, exec("create procedure " + qTableName( "tst_raiseError", __FILE__ ) + " as\n"
+ QVERIFY_SQL(q, exec("create procedure " + qTableName("tst_raiseError", __FILE__, db) + " as\n"
"begin\n"
" raiserror('" + errorString + "', 16, 1)\n"
"end\n" ));
- q.exec( "{call " + qTableName( "tst_raiseError", __FILE__ ) + "}" );
+ q.exec("{call " + qTableName("tst_raiseError", __FILE__, db) + "}");
QVERIFY(q.lastError().text().contains(errorString));
}
@@ -3198,7 +3198,7 @@ void tst_QSqlQuery::QTBUG_6852()
QSKIP( "Test requires MySQL >= 5.0");
QSqlQuery q(db);
- const QString tableName(qTableName("bug6852", __FILE__)), procName(qTableName("bug6852_proc", __FILE__));
+ const QString tableName(qTableName("bug6852", __FILE__, db)), procName(qTableName("bug6852_proc", __FILE__, db));
QVERIFY_SQL(q, exec("DROP PROCEDURE IF EXISTS "+procName));
QVERIFY_SQL(q, exec("CREATE TABLE "+tableName+"(\n"
@@ -3232,7 +3232,7 @@ void tst_QSqlQuery::QTBUG_5765()
QSKIP( "Test requires MySQL >= 4.1");
QSqlQuery q(db);
- const QString tableName(qTableName("bug5765", __FILE__));
+ const QString tableName(qTableName("bug5765", __FILE__, db));
QVERIFY_SQL(q, exec("CREATE TABLE "+tableName+"(testval TINYINT(1) DEFAULT 0)"));
q.prepare("INSERT INTO "+tableName+" SET testval = :VALUE");
@@ -3275,7 +3275,7 @@ void tst_QSqlQuery::QTBUG_21884()
QSqlQuery q(db);
QStringList stList;
- QString tableName(qTableName("bug21884", __FILE__ ));
+ QString tableName(qTableName("bug21884", __FILE__, db));
stList << "create table " + tableName + "(id integer primary key, note string)";
stList << "select * from " + tableName + ";";
stList << "select * from " + tableName + "; \t\n\r";
@@ -3370,7 +3370,7 @@ void tst_QSqlQuery::QTBUG_23895()
QSqlQuery q(db);
- QString tableName(qTableName("bug23895", __FILE__ ));
+ QString tableName(qTableName("bug23895", __FILE__, db));
q.prepare("create table " + tableName + "(id integer primary key, val1 bool, val2 boolean)");
QVERIFY_SQL(q, exec());
q.prepare("insert into " + tableName + "(id, val1, val2) values(?, ?, ?);");
@@ -3425,7 +3425,7 @@ void tst_QSqlQuery::QTBUG_14904()
QSqlQuery q(db);
- QString tableName(qTableName("bug14904", __FILE__ ));
+ QString tableName(qTableName("bug14904", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
q.prepare("create table " + tableName + "(val1 bool)");
@@ -3456,7 +3456,7 @@ void tst_QSqlQuery::QTBUG_2192()
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
{
- const QString tableName(qTableName("bug2192", __FILE__));
+ const QString tableName(qTableName("bug2192", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
QSqlQuery q(db);
@@ -3483,7 +3483,7 @@ void tst_QSqlQuery::oraOCINumber()
QFETCH( QString, dbName );
QSqlDatabase db = QSqlDatabase::database( dbName );
CHECK_DATABASE( db );
- const QString qtest_oraOCINumber(qTableName("qtest_oraOCINumber", __FILE__));
+ const QString qtest_oraOCINumber(qTableName("qtest_oraOCINumber", __FILE__, db));
QSqlQuery q( db );
q.setForwardOnly( true );
@@ -3592,7 +3592,7 @@ void tst_QSqlQuery::sqlite_constraint()
QSKIP("Sqlite3 specific test");
QSqlQuery q(db);
- const QString trigger(qTableName("test_constraint", __FILE__));
+ const QString trigger(qTableName("test_constraint", __FILE__, db));
QVERIFY_SQL(q, exec("CREATE TEMP TRIGGER "+trigger+" BEFORE DELETE ON "+qtest+
"\nFOR EACH ROW "
@@ -3610,7 +3610,7 @@ void tst_QSqlQuery::sqlite_real()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString tableName(qTableName("sqliterealtype", __FILE__));
+ const QString tableName(qTableName("sqliterealtype", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
QSqlQuery q(db);
@@ -3641,8 +3641,10 @@ void tst_QSqlQuery::aggregateFunctionTypes()
// QPSQL uses LongLong for manipulation of integers
if (db.driverName().startsWith("QPSQL") || db.driverName().startsWith("QMYSQL"))
intType = QVariant::LongLong;
+ else if (db.driverName().startsWith("QOCI"))
+ intType = QVariant::Double;
{
- const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__));
+ const QString tableName(qTableName("numericFunctionsWithIntValues", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
QSqlQuery q(db);
@@ -3672,7 +3674,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT AVG(id) FROM " + tableName));
QVERIFY(q.next());
if (db.driverName().startsWith("QSQLITE") || db.driverName().startsWith("QPSQL")
- || (db.driverName().startsWith("QMYSQL"))) {
+ || db.driverName().startsWith("QMYSQL") || db.driverName().startsWith("QOCI")) {
QCOMPARE(q.value(0).toDouble(), 1.5);
QCOMPARE(q.record().field(0).type(), QVariant::Double);
} else {
@@ -3688,15 +3690,15 @@ void tst_QSqlQuery::aggregateFunctionTypes()
QVERIFY_SQL(q, exec("SELECT MIN(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 1);
- QCOMPARE(q.record().field(0).type(), QVariant::Int);
+ QCOMPARE(q.record().field(0).type(), intType);
QVERIFY_SQL(q, exec("SELECT MAX(id) FROM " + tableName));
QVERIFY(q.next());
QCOMPARE(q.value(0).toInt(), 2);
- QCOMPARE(q.record().field(0).type(), QVariant::Int);
+ QCOMPARE(q.record().field(0).type(), intType);
}
{
- const QString tableName(qTableName("numericFunctionsWithDoubleValues", __FILE__));
+ const QString tableName(qTableName("numericFunctionsWithDoubleValues", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
QSqlQuery q(db);
@@ -3755,7 +3757,7 @@ void tst_QSqlQuery::aggregateFunctionTypes()
}
}
{
- const QString tableName(qTableName("stringFunctions", __FILE__));
+ const QString tableName(qTableName("stringFunctions", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
QSqlQuery q(db);
diff --git a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
index a3fe47be69..1be74dc5fa 100644
--- a/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
+++ b/tests/auto/sql/kernel/qsqlthread/tst_qsqlthread.cpp
@@ -53,7 +53,7 @@
#include <pthread.h>
#endif
-const QString qtest(qTableName("qtest", __FILE__));
+const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
// set this define if Oracle is built with threading support
//#define QOCI_THREADED
@@ -303,7 +303,7 @@ void tst_QSqlThread::dropTestTables()
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
QSqlQuery q(db);
- tst_Databases::safeDropTables(db, QStringList() << qtest << qTableName("qtest2", __FILE__) << qTableName("emptytable", __FILE__));
+ tst_Databases::safeDropTables(db, QStringList() << qtest << qTableName("qtest2", __FILE__, db) << qTableName("emptytable", __FILE__, db));
}
}
@@ -316,10 +316,10 @@ void tst_QSqlThread::createTestTables()
QVERIFY_SQL(q, exec("create table " + qtest
+ "(id int NOT NULL primary key, name varchar(20), title int)"));
- QVERIFY_SQL(q, exec("create table " + qTableName("qtest2", __FILE__)
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest2", __FILE__, db)
+ "(id int NOT NULL primary key, title varchar(20))"));
- QVERIFY_SQL(q, exec("create table " + qTableName("emptytable", __FILE__)
+ QVERIFY_SQL(q, exec("create table " + qTableName("emptytable", __FILE__, db)
+ "(id int NOT NULL primary key)"));
}
}
@@ -335,9 +335,9 @@ void tst_QSqlThread::repopulateTestTables()
QVERIFY_SQL(q, exec("insert into " + qtest + " values(2, 'trond', 2)"));
QVERIFY_SQL(q, exec("insert into " + qtest + " values(3, 'vohi', 3)"));
- QVERIFY_SQL(q, exec("delete from " + qTableName("qtest2", __FILE__)));
- QVERIFY_SQL(q, exec("insert into " + qTableName("qtest2", __FILE__) + " values(1, 'herr')"));
- QVERIFY_SQL(q, exec("insert into " + qTableName("qtest2", __FILE__) + " values(2, 'mister')"));
+ QVERIFY_SQL(q, exec("delete from " + qTableName("qtest2", __FILE__, db)));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("qtest2", __FILE__, db) + " values(1, 'herr')"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("qtest2", __FILE__, db) + " values(2, 'mister')"));
}
}
diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
index 774620b366..cb9b4a5c1f 100644
--- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
@@ -147,10 +147,10 @@ void tst_QSqlQueryModel::cleanupTestCase()
void tst_QSqlQueryModel::dropTestTables(QSqlDatabase db)
{
QStringList tableNames;
- tableNames << qTableName("test", __FILE__)
- << qTableName("test2", __FILE__)
- << qTableName("test3", __FILE__)
- << qTableName("many", __FILE__);
+ tableNames << qTableName("test", __FILE__, db)
+ << qTableName("test2", __FILE__, db)
+ << qTableName("test3", __FILE__, db)
+ << qTableName("many", __FILE__, db);
tst_Databases::safeDropTables(db, tableNames);
}
@@ -160,10 +160,10 @@ void tst_QSqlQueryModel::createTestTables(QSqlDatabase db)
QSqlQuery q(db);
if(tst_Databases::isPostgreSQL(db))
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- QVERIFY_SQL( q, exec("create table " + qTableName("test", __FILE__) + "(id integer not null, name varchar(20), title integer, primary key (id))"));
- QVERIFY_SQL( q, exec("create table " + qTableName("test2", __FILE__) + "(id integer not null, title varchar(20), primary key (id))"));
- QVERIFY_SQL( q, exec("create table " + qTableName("test3", __FILE__) + "(id integer not null, primary key (id))"));
- QVERIFY_SQL( q, exec("create table " + qTableName("many", __FILE__) + "(id integer not null, name varchar(20), primary key (id))"));
+ QVERIFY_SQL( q, exec("create table " + qTableName("test", __FILE__, db) + "(id integer not null, name varchar(20), title integer, primary key (id))"));
+ QVERIFY_SQL( q, exec("create table " + qTableName("test2", __FILE__, db) + "(id integer not null, title varchar(20), primary key (id))"));
+ QVERIFY_SQL( q, exec("create table " + qTableName("test3", __FILE__, db) + "(id integer not null, primary key (id))"));
+ QVERIFY_SQL( q, exec("create table " + qTableName("many", __FILE__, db) + "(id integer not null, name varchar(20), primary key (id))"));
}
void tst_QSqlQueryModel::populateTestTables(QSqlDatabase db)
@@ -173,38 +173,38 @@ void tst_QSqlQueryModel::populateTestTables(QSqlDatabase db)
QSqlQuery q(db), q2(db);
- tst_Databases::safeDropTables(db, QStringList() << qTableName("manytmp", __FILE__) << qTableName("test3tmp", __FILE__));
- QVERIFY_SQL(q, exec("create table " + qTableName("manytmp", __FILE__) + "(id integer not null, name varchar(20), primary key (id))"));
- QVERIFY_SQL(q, exec("create table " + qTableName("test3tmp", __FILE__) + "(id integer not null, primary key (id))"));
+ tst_Databases::safeDropTables(db, QStringList() << qTableName("manytmp", __FILE__, db) << qTableName("test3tmp", __FILE__, db));
+ QVERIFY_SQL(q, exec("create table " + qTableName("manytmp", __FILE__, db) + "(id integer not null, name varchar(20), primary key (id))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("test3tmp", __FILE__, db) + "(id integer not null, primary key (id))"));
if (hasTransactions) QVERIFY_SQL(db, transaction());
- QVERIFY_SQL(q, exec("insert into " + qTableName("test", __FILE__) + " values(1, 'harry', 1)"));
- QVERIFY_SQL(q, exec("insert into " + qTableName("test", __FILE__) + " values(2, 'trond', 2)"));
- QVERIFY_SQL(q, exec("insert into " + qTableName("test2", __FILE__) + " values(1, 'herr')"));
- QVERIFY_SQL(q, exec("insert into " + qTableName("test2", __FILE__) + " values(2, 'mister')"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("test", __FILE__, db) + " values(1, 'harry', 1)"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("test", __FILE__, db) + " values(2, 'trond', 2)"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("test2", __FILE__, db) + " values(1, 'herr')"));
+ QVERIFY_SQL(q, exec("insert into " + qTableName("test2", __FILE__, db) + " values(2, 'mister')"));
- QVERIFY_SQL(q, exec(QString("insert into " + qTableName("test3", __FILE__) + " values(0)")));
- QVERIFY_SQL(q, prepare("insert into "+qTableName("test3", __FILE__)+"(id) select id + ? from "+qTableName("test3tmp", __FILE__)));
+ QVERIFY_SQL(q, exec(QString("insert into " + qTableName("test3", __FILE__, db) + " values(0)")));
+ QVERIFY_SQL(q, prepare("insert into "+ qTableName("test3", __FILE__, db) + "(id) select id + ? from " + qTableName("test3tmp", __FILE__, db)));
for (int i=1; i<260; i*=2) {
- q2.exec("delete from "+qTableName("test3tmp", __FILE__));
- QVERIFY_SQL(q2, exec("insert into "+qTableName("test3tmp", __FILE__)+"(id) select id from "+qTableName("test3", __FILE__)));
+ q2.exec("delete from " + qTableName("test3tmp", __FILE__, db));
+ QVERIFY_SQL(q2, exec("insert into " + qTableName("test3tmp", __FILE__, db) + "(id) select id from " + qTableName("test3", __FILE__, db)));
q.bindValue(0, i);
QVERIFY_SQL(q, exec());
}
- QVERIFY_SQL(q, exec(QString("insert into " + qTableName("many", __FILE__) + "(id, name) values (0, \'harry\')")));
- QVERIFY_SQL(q, prepare("insert into "+qTableName("many", __FILE__)+"(id, name) select id + ?, name from "+qTableName("manytmp", __FILE__)));
+ QVERIFY_SQL(q, exec(QString("insert into " + qTableName("many", __FILE__, db) + "(id, name) values (0, \'harry\')")));
+ QVERIFY_SQL(q, prepare("insert into " + qTableName("many", __FILE__, db) + "(id, name) select id + ?, name from " + qTableName("manytmp", __FILE__, db)));
for (int i=1; i < 2048; i*=2) {
- q2.exec("delete from "+qTableName("manytmp", __FILE__));
- QVERIFY_SQL(q2, exec("insert into "+qTableName("manytmp", __FILE__)+"(id, name) select id, name from "+qTableName("many", __FILE__)));
+ q2.exec("delete from " + qTableName("manytmp", __FILE__, db));
+ QVERIFY_SQL(q2, exec("insert into " + qTableName("manytmp", __FILE__, db) + "(id, name) select id, name from " + qTableName("many", __FILE__, db)));
q.bindValue(0, i);
QVERIFY_SQL(q, exec());
}
if (hasTransactions) QVERIFY_SQL(db, commit());
- tst_Databases::safeDropTables(db, QStringList() << qTableName("manytmp", __FILE__) << qTableName("test3tmp", __FILE__));
+ tst_Databases::safeDropTables(db, QStringList() << qTableName("manytmp", __FILE__, db) << qTableName("test3tmp", __FILE__, db));
}
void tst_QSqlQueryModel::generic_data(const QString& engine)
@@ -232,7 +232,7 @@ void tst_QSqlQueryModel::removeColumn()
CHECK_DATABASE(db);
DBTestModel model;
- model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db));
model.fetchMore();
QSignalSpy spy(&model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)));
@@ -314,7 +314,7 @@ void tst_QSqlQueryModel::insertColumn()
CHECK_DATABASE(db);
DBTestModel model;
- model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db));
model.fetchMore(); // necessary???
bool isToUpper = db.driverName().startsWith("QIBASE") || db.driverName().startsWith("QOCI") || db.driverName().startsWith("QDB2");
@@ -417,7 +417,7 @@ void tst_QSqlQueryModel::record()
CHECK_DATABASE(db);
QSqlQueryModel model;
- model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db));
QSqlRecord rec = model.record();
@@ -451,7 +451,7 @@ void tst_QSqlQueryModel::setHeaderData()
QVERIFY(!model.setHeaderData(5, Qt::Vertical, "foo"));
QVERIFY(model.headerData(5, Qt::Vertical).isValid());
- model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("select * from " + qTableName("test", __FILE__, db), db));
qRegisterMetaType<Qt::Orientation>("Qt::Orientation");
QSignalSpy spy(&model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)));
@@ -482,7 +482,7 @@ void tst_QSqlQueryModel::fetchMore()
QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset()));
QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
- model.setQuery(QSqlQuery("select * from " + qTableName("many", __FILE__), db));
+ model.setQuery(QSqlQuery("select * from " + qTableName("many", __FILE__, db), db));
int rowCount = model.rowCount();
QCOMPARE(modelAboutToBeResetSpy.count(), 1);
@@ -514,7 +514,7 @@ void tst_QSqlQueryModel::withSortFilterProxyModel()
QSKIP("Test applies only for drivers not reporting the query size.");
QSqlQueryModel model;
- model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test3", __FILE__), db));
+ model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test3", __FILE__, db), db));
QSortFilterProxyModel proxy;
proxy.setSourceModel(&model);
@@ -524,7 +524,7 @@ void tst_QSqlQueryModel::withSortFilterProxyModel()
QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset()));
QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
QSignalSpy modelRowsInsertedSpy(&model, SIGNAL(rowsInserted(QModelIndex,int,int)));
- model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test3", __FILE__), db));
+ model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test3", __FILE__, db), db));
view.scrollToBottom();
QTestEventLoop::instance().enterLoop(1);
@@ -555,13 +555,13 @@ void tst_QSqlQueryModel::setQuerySignalEmission()
QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
// First select, the model was empty and no rows had to be removed, but model resets anyway.
- model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__, db), db));
QCOMPARE(modelAboutToBeResetSpy.count(), 1);
QCOMPARE(modelResetSpy.count(), 1);
// Second select, the model wasn't empty and two rows had to be removed!
// setQuery() resets the model accompanied by begin and end signals
- model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__), db));
+ model.setQuery(QSqlQuery("SELECT * FROM " + qTableName("test", __FILE__, db), db));
QCOMPARE(modelAboutToBeResetSpy.count(), 2);
QCOMPARE(modelResetSpy.count(), 2);
}
@@ -580,7 +580,7 @@ void tst_QSqlQueryModel::setQueryWithNoRowsInResultSet()
// The query's result set will be empty so no signals should be emitted!
QSqlQuery query(db);
- QVERIFY_SQL(query, exec("SELECT * FROM " + qTableName("test", __FILE__) + " where 0 = 1"));
+ QVERIFY_SQL(query, exec("SELECT * FROM " + qTableName("test", __FILE__, db) + " where 0 = 1"));
model.setQuery(query);
QCOMPARE(modelRowsAboutToBeInsertedSpy.count(), 0);
QCOMPARE(modelRowsInsertedSpy.count(), 0);
@@ -649,7 +649,7 @@ void tst_QSqlQueryModel::task_180617()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString test3(qTableName("test3", __FILE__));
+ const QString test3(qTableName("test3", __FILE__, db));
QTableView view;
QCOMPARE(view.columnAt(0), -1);
diff --git a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
index 58ad995245..b218a0c4f7 100644
--- a/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
+++ b/tests/auto/sql/models/qsqlrelationaltablemodel/tst_qsqlrelationaltablemodel.cpp
@@ -45,11 +45,11 @@
#include "../../kernel/qsqldatabase/tst_databases.h"
-const QString reltest1(qTableName("reltest1", __FILE__)),
- reltest2(qTableName("reltest2", __FILE__)),
- reltest3(qTableName("reltest3", __FILE__)),
- reltest4(qTableName("reltest4", __FILE__)),
- reltest5(qTableName("reltest5", __FILE__));
+const QString reltest1(qTableName("reltest1", __FILE__, QSqlDatabase())),
+ reltest2(qTableName("reltest2", __FILE__, QSqlDatabase())),
+ reltest3(qTableName("reltest3", __FILE__, QSqlDatabase())),
+ reltest4(qTableName("reltest4", __FILE__, QSqlDatabase())),
+ reltest5(qTableName("reltest5", __FILE__, QSqlDatabase()));
class tst_QSqlRelationalTableModel : public QObject
{
@@ -134,13 +134,13 @@ void tst_QSqlRelationalTableModel::recreateTestTables(QSqlDatabase db)
QVERIFY_SQL( q, exec("insert into " + reltest5 + " values('mister', 'Mr')"));
if (testWhiteSpaceNames(db.driverName())) {
- QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test6", QSqlDriver::TableName);
+ QString reltest6 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test6", QSqlDriver::TableName);
QVERIFY_SQL( q, exec("create table " + reltest6 + " (id int not null primary key, " + db.driver()->escapeIdentifier("city key", QSqlDriver::FieldName) +
" int, " + db.driver()->escapeIdentifier("extra field", QSqlDriver::FieldName) + " int)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(1, 1,9)"));
QVERIFY_SQL( q, exec("insert into " + reltest6 + " values(2, 2,8)"));
- QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test7", QSqlDriver::TableName);
+ QString reltest7 = db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test7", QSqlDriver::TableName);
QVERIFY_SQL( q, exec("create table " + reltest7 + " (" + db.driver()->escapeIdentifier("city id", QSqlDriver::TableName) + " int not null primary key, " + db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName) + " varchar(20))"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(1, 'New York')"));
QVERIFY_SQL( q, exec("insert into " + reltest7 + " values(2, 'Washington')"));
@@ -181,14 +181,14 @@ void tst_QSqlRelationalTableModel::dropTestTables( QSqlDatabase db )
<< reltest3
<< reltest4
<< reltest5
- << (qTableName( "rel", __FILE__)+" test6")
- << (qTableName( "rel", __FILE__)+" test7")
- << qTableName("CASETEST1", db.driver() )
- << qTableName("casetest1", db.driver() );
+ << (qTableName("rel", __FILE__, db) + " test6")
+ << (qTableName( "rel", __FILE__, db) + " test7")
+ << qTableName("CASETEST1", db)
+ << qTableName("casetest1", db);
tst_Databases::safeDropTables( db, tableNames );
- db.exec("DROP SCHEMA "+qTableName("QTBUG_5373", __FILE__)+" CASCADE");
- db.exec("DROP SCHEMA "+qTableName("QTBUG_5373_s2", __FILE__)+" CASCADE");
+ db.exec("DROP SCHEMA " + qTableName("QTBUG_5373", __FILE__, db) + " CASCADE");
+ db.exec("DROP SCHEMA " + qTableName("QTBUG_5373_s2", __FILE__, db) + " CASCADE");
}
void tst_QSqlRelationalTableModel::init()
@@ -1095,54 +1095,54 @@ void tst_QSqlRelationalTableModel::casing()
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities");
QSqlQuery q(db);
- QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db.driver()).toUpper() +
+ QVERIFY_SQL( q, exec("create table " + qTableName("CASETEST1", db).toUpper() +
" (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
- if( !q.exec("create table " + qTableName("casetest1", db.driver()) +
+ if (!q.exec("create table " + qTableName("casetest1", db) +
" (ident int not null primary key, name varchar(20), title_key int)"))
QSKIP("The casing test for this database is irrelevant since this database does not treat different cases as separate entities");
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(1, 'harry', 1, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(2, 'trond', 2, 1)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(3, 'vohi', 1, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db.driver()).toUpper() + " values(4, 'boris', 2, 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(1, 'jerry', 1)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(2, 'george', 2)"));
- QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db.driver()) + " values(4, 'kramer', 2)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(1, 'harry', 1, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(2, 'trond', 2, 1)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(3, 'vohi', 1, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("CASETEST1", db).toUpper() + " values(4, 'boris', 2, 2)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(1, 'jerry', 1)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(2, 'george', 2)"));
+ QVERIFY_SQL( q, exec("insert into " + qTableName("casetest1", db) + " values(4, 'kramer', 2)"));
if (db.driverName().startsWith("QOCI")) {
//try an owner that doesn't exist
- QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db.driver()).toUpper());
+ QSqlRecord rec = db.driver()->record("doug." + qTableName("CASETEST1", db).toUpper());
QCOMPARE( rec.count(), 0);
//try an owner that does exist
- rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db.driver()).toUpper());
+ rec = db.driver()->record(db.userName() + "." + qTableName("CASETEST1", db).toUpper());
QCOMPARE( rec.count(), 4);
}
- QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db.driver()).toUpper());
+ QSqlRecord rec = db.driver()->record(qTableName("CASETEST1", db).toUpper());
QCOMPARE( rec.count(), 4);
- rec = db.driver()->record(qTableName("casetest1", db.driver()));
+ rec = db.driver()->record(qTableName("casetest1", db));
QCOMPARE( rec.count(), 3);
QSqlTableModel upperCaseModel(0, db);
- upperCaseModel.setTable(qTableName("CASETEST1", db.driver()).toUpper());
+ upperCaseModel.setTable(qTableName("CASETEST1", db).toUpper());
- QCOMPARE(upperCaseModel.tableName(),qTableName("CASETEST1",db.driver()).toUpper());
+ QCOMPARE(upperCaseModel.tableName(), qTableName("CASETEST1", db).toUpper());
QVERIFY_SQL(upperCaseModel, select());
QCOMPARE(upperCaseModel.rowCount(), 4);
QSqlTableModel lowerCaseModel(0, db);
- lowerCaseModel.setTable(qTableName("casetest1", db.driver()));
- QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1",db.driver()));
+ lowerCaseModel.setTable(qTableName("casetest1", db));
+ QCOMPARE(lowerCaseModel.tableName(), qTableName("casetest1", db));
QVERIFY_SQL(lowerCaseModel, select());
QCOMPARE(lowerCaseModel.rowCount(), 3);
QSqlRelationalTableModel model(0, db);
- model.setTable(qTableName("CASETEST1", db.driver()).toUpper());
+ model.setTable(qTableName("CASETEST1", db).toUpper());
model.setRelation(2, QSqlRelation(reltest2, "tid", "title"));
QVERIFY_SQL(model, select());
@@ -1372,9 +1372,9 @@ void tst_QSqlRelationalTableModel::whiteSpaceInIdentifiers()
if (!testWhiteSpaceNames(db.driverName()))
QSKIP("White space test irrelevant for driver");
QSqlRelationalTableModel model(0, db);
- model.setTable(db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test6", QSqlDriver::TableName));
+ model.setTable(db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test6", QSqlDriver::TableName));
model.setSort(0, Qt::DescendingOrder);
- model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel", __FILE__)+" test7", QSqlDriver::TableName),
+ model.setRelation(1, QSqlRelation(db.driver()->escapeIdentifier(qTableName("rel", __FILE__, db) + " test7", QSqlDriver::TableName),
db.driver()->escapeIdentifier("city id", QSqlDriver::FieldName),
db.driver()->escapeIdentifier("city name", QSqlDriver::FieldName)));
QVERIFY_SQL(model, select());
@@ -1459,13 +1459,15 @@ void tst_QSqlRelationalTableModel::psqlSchemaTest()
QSqlRelationalTableModel model(0, db);
QSqlQuery q(db);
- QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373", __FILE__)));
- QVERIFY_SQL(q, exec("create schema "+qTableName("QTBUG_5373_s2", __FILE__)));
- QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373", __FILE__)+"."+qTableName("document", __FILE__)+"(document_id int primary key, relatingid int, userid int)"));
- QVERIFY_SQL(q, exec("create table "+qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__)+"(userid int primary key, username char(40))"));
- model.setTable(qTableName("QTBUG_5373", __FILE__)+"."+qTableName("document", __FILE__));
- model.setRelation(1, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__), "userid", "username"));
- model.setRelation(2, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__)+"."+qTableName("user", __FILE__), "userid", "username"));
+ QVERIFY_SQL(q, exec("create schema " + qTableName("QTBUG_5373", __FILE__, db)));
+ QVERIFY_SQL(q, exec("create schema " + qTableName("QTBUG_5373_s2", __FILE__, db)));
+ QVERIFY_SQL(q, exec("create table " + qTableName("QTBUG_5373", __FILE__, db) + "." + qTableName("document", __FILE__, db) +
+ "(document_id int primary key, relatingid int, userid int)"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("QTBUG_5373_s2", __FILE__, db) + "." + qTableName("user", __FILE__, db) +
+ "(userid int primary key, username char(40))"));
+ model.setTable(qTableName("QTBUG_5373", __FILE__, db) + "." + qTableName("document", __FILE__, db));
+ model.setRelation(1, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__, db) + "." + qTableName("user", __FILE__, db), "userid", "username"));
+ model.setRelation(2, QSqlRelation(qTableName("QTBUG_5373_s2", __FILE__, db) + "." + qTableName("user", __FILE__, db), "userid", "username"));
QVERIFY_SQL(model, select());
model.setJoinMode(QSqlRelationalTableModel::LeftJoin);
@@ -1503,8 +1505,8 @@ void tst_QSqlRelationalTableModel::relationOnFirstColumn()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString testTable1 = qTableName("QTBUG_20038_test1", __FILE__);
- QString testTable2 = qTableName("QTBUG_20038_test2", __FILE__);
+ QString testTable1 = qTableName("QTBUG_20038_test1", __FILE__, db);
+ QString testTable2 = qTableName("QTBUG_20038_test2", __FILE__, db);
tst_Databases::safeDropTables(db, QStringList() << testTable1 << testTable2);
//prepare test1 table
diff --git a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
index df89ba3cf8..771c224963 100644
--- a/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
+++ b/tests/auto/sql/models/qsqltablemodel/tst_qsqltablemodel.cpp
@@ -45,9 +45,9 @@
#include <QtSql>
#include <QtSql/private/qsqltablemodel_p.h>
-const QString test(qTableName("test", __FILE__)),
- test2(qTableName("test2", __FILE__)),
- test3(qTableName("test3", __FILE__));
+const QString test(qTableName("test", __FILE__, QSqlDatabase())),
+ test2(qTableName("test2", __FILE__, QSqlDatabase())),
+ test3(qTableName("test3", __FILE__, QSqlDatabase()));
class tst_QSqlTableModel : public QObject
@@ -176,18 +176,18 @@ void tst_QSqlTableModel::dropTestTables()
tableNames << test
<< test2
<< test3
- << qTableName("test4", __FILE__)
- << qTableName("emptytable", __FILE__)
- << qTableName("bigtable", __FILE__)
- << qTableName("foo", __FILE__)
- << qTableName("pktest", __FILE__);
+ << qTableName("test4", __FILE__, db)
+ << qTableName("emptytable", __FILE__, db)
+ << qTableName("bigtable", __FILE__, db)
+ << qTableName("foo", __FILE__, db)
+ << qTableName("pktest", __FILE__, db);
if (testWhiteSpaceNames(db.driverName()))
- tableNames << qTableName("qtestw hitespace", db.driver());
+ tableNames << qTableName("qtestw hitespace", db);
tst_Databases::safeDropTables(db, tableNames);
if (db.driverName().startsWith("QPSQL")) {
- q.exec("DROP SCHEMA " + qTableName("testschema", __FILE__) + " CASCADE");
+ q.exec("DROP SCHEMA " + qTableName("testschema", __FILE__, db) + " CASCADE");
}
}
}
@@ -205,19 +205,19 @@ void tst_QSqlTableModel::createTestTables()
QVERIFY_SQL( q, exec("create table " + test3 + "(id int, random varchar(20), randomtwo varchar(20))"));
if(!tst_Databases::isSqlServer(db))
- QVERIFY_SQL( q, exec("create table " + qTableName("test4", __FILE__) + "(column1 varchar(50), column2 varchar(50), column3 varchar(50))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("test4", __FILE__, db) + "(column1 varchar(50), column2 varchar(50), column3 varchar(50))"));
else
- QVERIFY_SQL( q, exec("create table " + qTableName("test4", __FILE__) + "(column1 varchar(50), column2 varchar(50) NULL, column3 varchar(50))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("test4", __FILE__, db) + "(column1 varchar(50), column2 varchar(50) NULL, column3 varchar(50))"));
- QVERIFY_SQL( q, exec("create table " + qTableName("emptytable", __FILE__) + "(id int)"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("emptytable", __FILE__, db) + "(id int)"));
if (testWhiteSpaceNames(db.driverName())) {
- QString qry = "create table " + qTableName("qtestw hitespace", db.driver()) + " ("+ db.driver()->escapeIdentifier("a field", QSqlDriver::FieldName) + " int)";
+ QString qry = "create table " + qTableName("qtestw hitespace", db) + " ("+ db.driver()->escapeIdentifier("a field", QSqlDriver::FieldName) + " int)";
QVERIFY_SQL( q, exec(qry));
}
- QVERIFY_SQL( q, exec("create table "+qTableName("pktest", __FILE__)+"(id int not null primary key, a varchar(20))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("pktest", __FILE__, db) + "(id int not null primary key, a varchar(20))"));
}
}
@@ -343,7 +343,7 @@ void tst_QSqlTableModel::selectRow()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tbl = qTableName("pktest", __FILE__);
+ QString tbl = qTableName("pktest", __FILE__, db);
QSqlQuery q(db);
q.exec("DELETE FROM " + tbl);
q.exec("INSERT INTO " + tbl + " (id, a) VALUES (0, 'a')");
@@ -403,7 +403,7 @@ void tst_QSqlTableModel::selectRowOverride()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tbl = qTableName("pktest", __FILE__);
+ QString tbl = qTableName("pktest", __FILE__, db);
QSqlQuery q(db);
q.exec("DELETE FROM " + tbl);
q.exec("INSERT INTO " + tbl + " (id, a) VALUES (0, 'a')");
@@ -827,7 +827,7 @@ void tst_QSqlTableModel::insertRowFailure()
CHECK_DATABASE(db);
QSqlTableModel model(0, db);
- model.setTable(qTableName("pktest", __FILE__));
+ model.setTable(qTableName("pktest", __FILE__, db));
model.setEditStrategy(submitpolicy);
QSqlRecord values = model.record();
@@ -975,7 +975,7 @@ void tst_QSqlTableModel::insertWithAutoColumn()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tbl = qTableName("autoColumnTest", __FILE__);
+ QString tbl = qTableName("autoColumnTest", __FILE__, db);
QSqlQuery q(db);
q.exec("DROP TABLE " + tbl);
QVERIFY_SQL(q, exec("CREATE TABLE " + tbl + "(id INTEGER PRIMARY KEY AUTOINCREMENT, val TEXT)"));
@@ -1378,8 +1378,8 @@ void tst_QSqlTableModel::revert()
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- QString tblA = qTableName("revertATest", __FILE__);
- QString tblB = qTableName("revertBTest", __FILE__);
+ QString tblA = qTableName("revertATest", __FILE__, db);
+ QString tblB = qTableName("revertBTest", __FILE__, db);
QSqlQuery q(db);
q.exec("PRAGMA foreign_keys = ON;");
q.exec("DROP TABLE " + tblB);
@@ -1646,7 +1646,7 @@ void tst_QSqlTableModel::emptyTable()
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 0);
- model.setTable(qTableName("emptytable", __FILE__));
+ model.setTable(qTableName("emptytable", __FILE__, db));
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.columnCount(), 1);
@@ -1670,9 +1670,9 @@ void tst_QSqlTableModel::tablesAndSchemas()
CHECK_DATABASE(db);
QSqlQuery q(db);
- q.exec("DROP SCHEMA " + qTableName("testschema", __FILE__) + " CASCADE");
- QVERIFY_SQL( q, exec("create schema " + qTableName("testschema", __FILE__)));
- QString tableName = qTableName("testschema", __FILE__) + '.' + qTableName("testtable", __FILE__);
+ q.exec("DROP SCHEMA " + qTableName("testschema", __FILE__, db) + " CASCADE");
+ QVERIFY_SQL( q, exec("create schema " + qTableName("testschema", __FILE__, db)));
+ QString tableName = qTableName("testschema", __FILE__, db) + '.' + qTableName("testtable", __FILE__, db);
QVERIFY_SQL( q, exec("create table " + tableName + "(id int)"));
QVERIFY_SQL( q, exec("insert into " + tableName + " values(1)"));
QVERIFY_SQL( q, exec("insert into " + tableName + " values(2)"));
@@ -1693,7 +1693,7 @@ void tst_QSqlTableModel::whitespaceInIdentifiers()
if (!testWhiteSpaceNames(db.driverName()))
QSKIP("DBMS doesn't support whitespaces in identifiers");
- QString tableName = qTableName("qtestw hitespace", db.driver());
+ QString tableName = qTableName("qtestw hitespace", db);
QSqlTableModel model(0, db);
model.setTable(tableName);
@@ -1711,10 +1711,10 @@ void tst_QSqlTableModel::primaryKeyOrder()
if(tst_Databases::isPostgreSQL(db))
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
- QVERIFY_SQL( q, exec("create table "+qTableName("foo", __FILE__)+"(a varchar(20), id int not null primary key, b varchar(20))"));
+ QVERIFY_SQL(q, exec("create table " + qTableName("foo", __FILE__, db) + "(a varchar(20), id int not null primary key, b varchar(20))"));
QSqlTableModel model(0, db);
- model.setTable(qTableName("foo", __FILE__));
+ model.setTable(qTableName("foo", __FILE__, db));
QSqlIndex pk = model.primaryKey();
QCOMPARE(pk.count(), 1);
@@ -1783,7 +1783,7 @@ void tst_QSqlTableModel::sqlite_bigTable()
QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db);
- const QString bigtable(qTableName("bigtable", __FILE__));
+ const QString bigtable(qTableName("bigtable", __FILE__, db));
bool hasTransactions = db.driver()->hasFeature(QSqlDriver::Transactions);
if (hasTransactions) QVERIFY(db.transaction());
@@ -1865,7 +1865,7 @@ void tst_QSqlTableModel::submitAllOnInvalidTable()
// setTable returns a void, so the error can only be caught by
// manually checking lastError(). ### Qt5: This should be changed!
- model.setTable(qTableName("invalidTable", __FILE__));
+ model.setTable(qTableName("invalidTable", __FILE__, db));
QCOMPARE(model.lastError().type(), QSqlError::StatementError);
// This will give us an empty record which is expected behavior
@@ -1975,7 +1975,7 @@ void tst_QSqlTableModel::tableModifyWithBlank()
CHECK_DATABASE(db);
QSqlTableModel model(0, db);
- model.setTable(qTableName("test4", __FILE__));
+ model.setTable(qTableName("test4", __FILE__, db));
model.select();
//generate a time stamp for the test. Add one second to the current time to make sure
diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
index d0b9b0a14a..d7050033f3 100644
--- a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
+++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
@@ -178,6 +178,7 @@ private:
tst_QCompleter::tst_QCompleter() : completer(0), completionColumn(0), columnCount(3)
{
treeWidget = new QTreeWidget;
+ treeWidget->move(100, 100);
treeWidget->setColumnCount(columnCount);
}
@@ -1065,12 +1066,13 @@ void tst_QCompleter::modelDeletion()
completer->setCompletionPrefix("i");
completer->setModel(listModel);
QVERIFY(completer->completionCount() == 3);
- QListView *view = new QListView;
+ QScopedPointer<QListView> view(new QListView);
view->setModel(completer->completionModel());
delete listModel;
+ view->move(200, 200);
view->show();
qApp->processEvents();
- delete view;
+ view.reset();
QVERIFY(completer->completionCount() == 0);
QVERIFY(completer->currentRow() == -1);
}
@@ -1083,10 +1085,10 @@ void tst_QCompleter::multipleWidgets()
completer.setCompletionMode(QCompleter::InlineCompletion);
QWidget window;
+ window.move(200, 200);
window.show();
QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
- QVERIFY(qApp->activeWindow() == &window);
QFocusEvent focusIn(QEvent::FocusIn);
QFocusEvent focusOut(QEvent::FocusOut);
@@ -1128,13 +1130,11 @@ void tst_QCompleter::focusIn()
QCompleter completer(list);
QWidget window;
+ window.move(200, 200);
window.show();
- QTest::qWait(100);
window.activateWindow();
QApplication::setActiveWindow(&window);
- QTest::qWait(100);
-
- QTRY_COMPARE(qApp->activeWindow(), &window);
+ QVERIFY(QTest::qWaitForWindowActive(&window));
QComboBox *comboBox = new QComboBox(&window);
comboBox->setEditable(true);
@@ -1194,7 +1194,9 @@ void tst_QCompleter::disabledItems()
QCompleter *completer = new QCompleter(model, &lineEdit);
QSignalSpy spy(completer, SIGNAL(activated(QString)));
lineEdit.setCompleter(completer);
+ lineEdit.move(200, 200);
lineEdit.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&lineEdit));
QTest::keyPress(&lineEdit, Qt::Key_S);
QTest::keyPress(&lineEdit, Qt::Key_U);
@@ -1212,15 +1214,19 @@ void tst_QCompleter::task178797_activatedOnReturn()
{
QStringList words;
words << "foobar1" << "foobar2";
- QLineEdit *ledit = new QLineEdit;
+ QLineEdit ledit;
+ setFrameless(&ledit);
QCompleter *completer = new QCompleter(words);
- ledit->setCompleter(completer);
+ ledit.setCompleter(completer);
QSignalSpy spy(completer, SIGNAL(activated(QString)));
QCOMPARE(spy.count(), 0);
- ledit->show();
- QTest::keyClick(ledit, Qt::Key_F);
+ ledit.move(200, 200);
+ ledit.show();
+ qApp->setActiveWindow(&ledit);
+ QVERIFY(QTest::qWaitForWindowActive(&ledit));
+ QTest::keyClick(&ledit, Qt::Key_F);
qApp->processEvents();
- QVERIFY(qApp->activePopupWidget());
+ QTRY_VERIFY(qApp->activePopupWidget());
QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Down);
qApp->processEvents();
QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Return);
@@ -1289,19 +1295,20 @@ private slots:
void tst_QCompleter::task246056_setCompletionPrefix()
{
- task246056_ComboBox *comboBox = new task246056_ComboBox;
- setFrameless(comboBox);
- QVERIFY(comboBox->completer());
- comboBox->addItem("");
- comboBox->addItem("a1");
- comboBox->addItem("a2");
- comboBox->show();
- comboBox->setFocus();
- QTest::qWait(100);
- QTest::keyPress(comboBox, 'a');
- QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Down);
- QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Down);
- QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Enter); // don't crash!
+ task246056_ComboBox comboBox;
+ setFrameless(&comboBox);
+ QVERIFY(comboBox.completer());
+ comboBox.addItem("");
+ comboBox.addItem("a1");
+ comboBox.addItem("a2");
+ comboBox.move(200, 200);
+ comboBox.show();
+ QApplication::setActiveWindow(&comboBox);
+ QVERIFY(QTest::qWaitForWindowActive(&comboBox));
+ QTest::keyPress(&comboBox, 'a');
+ QTest::keyPress(comboBox.completer()->popup(), Qt::Key_Down);
+ QTest::keyPress(comboBox.completer()->popup(), Qt::Key_Down);
+ QTest::keyPress(comboBox.completer()->popup(), Qt::Key_Enter); // don't crash!
}
class task250064_TextEdit : public QTextEdit
@@ -1326,39 +1333,41 @@ class task250064_Widget : public QWidget
{
Q_OBJECT
public:
- task250064_TextEdit *textEdit;
-
- task250064_Widget(task250064_TextEdit *textEdit)
- : textEdit(textEdit)
+ task250064_Widget() : m_textEdit(new task250064_TextEdit)
{
QTabWidget *tabWidget = new QTabWidget;
tabWidget->setFocusPolicy(Qt::ClickFocus);
- tabWidget->addTab(textEdit, "untitled");
+ tabWidget->addTab(m_textEdit, "untitled");
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(tabWidget);
- textEdit->setPlainText("bla bla bla");
- textEdit->setFocus();
+ m_textEdit->setPlainText("bla bla bla");
+ m_textEdit->setFocus();
}
void setCompletionModel()
{
- textEdit->completer->setModel(0);
+ m_textEdit->completer->setModel(0);
}
+
+ QTextEdit *textEdit() const { return m_textEdit; }
+
+private:
+ task250064_TextEdit *m_textEdit;
};
void tst_QCompleter::task250064_lostFocus()
{
- task250064_TextEdit *textEdit = new task250064_TextEdit;
- task250064_Widget *widget = new task250064_Widget(textEdit);
- widget->show();
- QTest::qWait(100);
- QTest::keyPress(textEdit, 'a');
- Qt::FocusPolicy origPolicy = textEdit->focusPolicy();
+ task250064_Widget widget;
+ widget.show();
+ QApplication::setActiveWindow(&widget);
+ QVERIFY(QTest::qWaitForWindowActive(&widget));
+ QTest::keyPress(widget.textEdit(), 'a');
+ Qt::FocusPolicy origPolicy = widget.textEdit()->focusPolicy();
QVERIFY(origPolicy != Qt::NoFocus);
- widget->setCompletionModel();
- QCOMPARE(textEdit->focusPolicy(), origPolicy);
+ widget.setCompletionModel();
+ QCOMPARE(widget.textEdit()->focusPolicy(), origPolicy);
}
void tst_QCompleter::task253125_lineEditCompletion_data()
@@ -1391,6 +1400,7 @@ void tst_QCompleter::task253125_lineEditCompletion()
QLineEdit edit;
edit.setCompleter(completer);
+ edit.move(200, 200);
edit.show();
edit.setFocus();
QApplication::setActiveWindow(&edit);
@@ -1423,6 +1433,7 @@ void tst_QCompleter::task247560_keyboardNavigation()
QLineEdit edit;
edit.setCompleter(&completer);
+ edit.move(200, 200);
edit.show();
edit.setFocus();
QApplication::setActiveWindow(&edit);
@@ -1543,6 +1554,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
comp.setModel(&model);
edit.setCompleter(&comp);
+ edit.move(200, 200);
edit.show();
QApplication::setActiveWindow(&edit);
QVERIFY(QTest::qWaitForWindowActive(&edit));
@@ -1583,6 +1595,7 @@ void tst_QCompleter::QTBUG_14292_filesystem()
QTRY_VERIFY(!comp.popup()->isVisible());
QWidget w;
+ w.move(400, 200);
w.show();
QApplication::setActiveWindow(&w);
QVERIFY(QTest::qWaitForWindowActive(&w));
diff --git a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
index d7ef32e520..2bce545f90 100644
--- a/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
+++ b/tests/benchmarks/sql/kernel/qsqlquery/main.cpp
@@ -44,7 +44,7 @@
#include "../../../../auto/sql/kernel/qsqldatabase/tst_databases.h"
-const QString qtest(qTableName( "qtest", __FILE__ ));
+const QString qtest(qTableName("qtest", __FILE__, QSqlDatabase()));
class tst_QSqlQuery : public QObject
{
@@ -149,56 +149,56 @@ void tst_QSqlQuery::dropTestTables( QSqlDatabase db )
QStringList tablenames;
// drop all the table in case a testcase failed
tablenames << qtest
- << qTableName( "qtest_null", __FILE__ )
- << qTableName( "qtest_blob", __FILE__ )
- << qTableName( "qtest_bittest", __FILE__ )
- << qTableName( "qtest_nullblob", __FILE__ )
- << qTableName( "qtest_rawtest", __FILE__ )
- << qTableName( "qtest_precision", __FILE__ )
- << qTableName( "qtest_prepare", __FILE__ )
- << qTableName( "qtestj1", __FILE__ )
- << qTableName( "qtestj2", __FILE__ )
- << qTableName( "char1Select", __FILE__ )
- << qTableName( "char1SU", __FILE__ )
- << qTableName( "qxmltest", __FILE__ )
- << qTableName( "qtest_exerr", __FILE__ )
- << qTableName( "qtest_empty", __FILE__ )
- << qTableName( "clobby", __FILE__ )
- << qTableName( "bindtest", __FILE__ )
- << qTableName( "more_results", __FILE__ )
- << qTableName( "blobstest", __FILE__ )
- << qTableName( "oraRowId", __FILE__ )
- << qTableName( "qtest_batch", __FILE__ )
- << qTableName("bug6421", __FILE__).toUpper()
- << qTableName("bug5765", __FILE__)
- << qTableName("bug6852", __FILE__)
- << qTableName( "qtest_lockedtable", __FILE__ )
- << qTableName( "Planet", __FILE__ )
- << qTableName( "task_250026", __FILE__ )
- << qTableName( "task_234422", __FILE__ )
- << qTableName("test141895", __FILE__)
- << qTableName("qtest_oraOCINumber", __FILE__);
+ << qTableName("qtest_null", __FILE__, db)
+ << qTableName("qtest_blob", __FILE__, db)
+ << qTableName("qtest_bittest", __FILE__, db)
+ << qTableName("qtest_nullblob", __FILE__, db)
+ << qTableName("qtest_rawtest", __FILE__, db)
+ << qTableName("qtest_precision", __FILE__, db)
+ << qTableName("qtest_prepare", __FILE__, db)
+ << qTableName("qtestj1", __FILE__, db)
+ << qTableName("qtestj2", __FILE__, db)
+ << qTableName("char1Select", __FILE__, db)
+ << qTableName("char1SU", __FILE__, db)
+ << qTableName("qxmltest", __FILE__, db)
+ << qTableName("qtest_exerr", __FILE__, db)
+ << qTableName("qtest_empty", __FILE__, db)
+ << qTableName("clobby", __FILE__, db)
+ << qTableName("bindtest", __FILE__, db)
+ << qTableName("more_results", __FILE__, db)
+ << qTableName("blobstest", __FILE__, db)
+ << qTableName("oraRowId", __FILE__, db)
+ << qTableName("qtest_batch", __FILE__, db)
+ << qTableName("bug6421", __FILE__, db).toUpper()
+ << qTableName("bug5765", __FILE__, db)
+ << qTableName("bug6852", __FILE__, db)
+ << qTableName("qtest_lockedtable", __FILE__, db)
+ << qTableName("Planet", __FILE__, db)
+ << qTableName("task_250026", __FILE__, db)
+ << qTableName("task_234422", __FILE__, db)
+ << qTableName("test141895", __FILE__, db)
+ << qTableName("qtest_oraOCINumber", __FILE__, db);
if ( db.driverName().startsWith("QPSQL") )
- tablenames << qTableName("task_233829", __FILE__);
+ tablenames << qTableName("task_233829", __FILE__, db);
if ( db.driverName().startsWith("QSQLITE") )
- tablenames << qTableName( "record_sqlite", __FILE__ );
+ tablenames << qTableName("record_sqlite", __FILE__, db);
if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QOCI" ) )
- tablenames << qTableName( "qtest_longstr", __FILE__ );
+ tablenames << qTableName("qtest_longstr", __FILE__, db);
if (tst_Databases::isSqlServer( db ))
- db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__));
+ db.exec("DROP PROCEDURE " + qTableName("test141895_proc", __FILE__, db));
if (tst_Databases::isMySQL( db ))
- db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__));
+ db.exec("DROP PROCEDURE IF EXISTS "+qTableName("bug6852_proc", __FILE__, db));
tst_Databases::safeDropTables( db, tablenames );
if ( db.driverName().startsWith( "QOCI" ) ) {
QSqlQuery q( db );
- q.exec( "DROP PACKAGE " + qTableName("pkg", __FILE__) );
+ q.exec("DROP PACKAGE " + qTableName("pkg", __FILE__, db));
}
}
@@ -219,15 +219,15 @@ void tst_QSqlQuery::createTestTables( QSqlDatabase db )
QVERIFY_SQL( q, exec( "create table " + qtest + " (id int "+tst_Databases::autoFieldName(db) +" NOT NULL, t_varchar varchar(20), t_char char(20), primary key(id))" ) );
if ( tst_Databases::isSqlServer( db ) || db.driverName().startsWith( "QTDS" ) )
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null", __FILE__ ) + " (id int null, t_varchar varchar(20) null)" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int null, t_varchar varchar(20) null)" ) );
else
- QVERIFY_SQL( q, exec( "create table " + qTableName( "qtest_null", __FILE__ ) + " (id int, t_varchar varchar(20))" ) );
+ QVERIFY_SQL(q, exec("create table " + qTableName("qtest_null", __FILE__, db) + " (id int, t_varchar varchar(20))" ) );
}
void tst_QSqlQuery::populateTestTables( QSqlDatabase db )
{
QSqlQuery q( db );
- const QString qtest_null(qTableName( "qtest_null", __FILE__ ));
+ const QString qtest_null(qTableName("qtest_null", __FILE__, db));
q.exec( "delete from " + qtest );
QVERIFY_SQL( q, exec( "insert into " + qtest + " values (1, 'VarChar1', 'Char1')" ) );
QVERIFY_SQL( q, exec( "insert into " + qtest + " values (2, 'VarChar2', 'Char2')" ) );
@@ -251,7 +251,7 @@ void tst_QSqlQuery::benchmark()
QSKIP( "Test requires MySQL >= 5.0");
QSqlQuery q(db);
- const QString tableName(qTableName("benchmark", __FILE__));
+ const QString tableName(qTableName("benchmark", __FILE__, db));
tst_Databases::safeDropTable( db, tableName );
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index a1ad081d97..dc11c0d0a2 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -566,6 +566,9 @@ void Configure::parseCmdLine()
else if (configCmdLine.at(i) == "-angle") {
dictionary[ "ANGLE" ] = "yes";
dictionary[ "ANGLE_FROM" ] = "commandline";
+ } else if (configCmdLine.at(i) == "-angle-d3d11") {
+ dictionary[ "ANGLE" ] = "d3d11";
+ dictionary[ "ANGLE_FROM" ] = "commandline";
} else if (configCmdLine.at(i) == "-no-angle") {
dictionary[ "ANGLE" ] = "no";
dictionary[ "ANGLE_FROM" ] = "commandline";
@@ -1673,7 +1676,7 @@ bool Configure::displayHelp()
desc( "-libdir <dir>", "Libraries will be installed to <dir>\n(default PREFIX/lib)");
desc( "-headerdir <dir>", "Headers will be installed to <dir>\n(default PREFIX/include)");
desc( "-archdatadir <dir>", "Architecture-dependent data used by Qt will be installed to <dir>\n(default PREFIX)");
- desc( "-libexecdir <dir>", "Program executables will be installed to <dir>\n(default ARCHDATADIR/lib)");
+ desc( "-libexecdir <dir>", "Program executables will be installed to <dir>\n(default ARCHDATADIR/bin)");
desc( "-plugindir <dir>", "Plugins will be installed to <dir>\n(default ARCHDATADIR/plugins)");
desc( "-importdir <dir>", "Imports for QML1 will be installed to <dir>\n(default ARCHDATADIR/imports)");
desc( "-qmldir <dir>", "Imports for QML2 will be installed to <dir>\n(default ARCHDATADIR/qml)");
@@ -1838,6 +1841,7 @@ bool Configure::displayHelp()
}
desc("ANGLE", "yes", "-angle", "Use the ANGLE implementation of OpenGL ES 2.0.");
+ desc("ANGLE", "d3d11", "-angle-d3d11", "Use the Direct3D 11-based ANGLE implementation of OpenGL ES 2.0.");
desc("ANGLE", "no", "-no-angle", "Do not use ANGLE.\nSee http://code.google.com/p/angleproject/\n");
#endif
// Qt\Windows only options go below here --------------------------------------------------------------------------------
@@ -2038,7 +2042,7 @@ bool Configure::checkAngleAvailability(QString *errorMessage /* = 0 */) const
}
}
- const QString directXLibrary = QStringLiteral("d3d9.lib");
+ const QString directXLibrary = dictionary["ANGLE"] == "d3d11" ? QStringLiteral("d3d11.lib") : QStringLiteral("d3d9.lib");
if (!findFile(directXLibrary)) {
if (errorMessage)
*errorMessage = QString::fromLatin1("The library '%1' could not be found.").arg(directXLibrary);
@@ -2368,7 +2372,7 @@ bool Configure::verifyConfiguration()
}
// -angle given on command line, but Direct X cannot be found.
- if (dictionary["ANGLE"] == "yes") {
+ if (dictionary["ANGLE"] != "no") {
QString errorMessage;
if (!checkAngleAvailability(&errorMessage)) {
cout << "WARNING: ANGLE specified, but the DirectX SDK could not be detected:" << endl
@@ -2505,8 +2509,11 @@ void Configure::generateOutputVars()
qtConfig += "icu";
// ANGLE --------------------------------------------------------
- if (dictionary[ "ANGLE" ] == "yes")
+ if (dictionary[ "ANGLE" ] != "no") {
qtConfig += "angle";
+ if (dictionary[ "ANGLE" ] == "d3d11")
+ qmakeConfig += "angle_d3d11";
+ }
// Image formates -----------------------------------------------
if (dictionary[ "GIF" ] == "no")
@@ -3685,7 +3692,7 @@ void Configure::generateQConfigCpp()
dictionary["QT_INSTALL_ARCHDATA"] = qipempty ? "" : dictionary["QT_INSTALL_PREFIX"];
if (!dictionary["QT_INSTALL_LIBEXECS"].size()) {
if (dictionary["QT_INSTALL_ARCHDATA"] == dictionary["QT_INSTALL_PREFIX"])
- dictionary["QT_INSTALL_LIBEXECS"] = qipempty ? "" : dictionary["QT_INSTALL_ARCHDATA"] + "/lib";
+ dictionary["QT_INSTALL_LIBEXECS"] = qipempty ? "" : dictionary["QT_INSTALL_ARCHDATA"] + "/bin";
else
dictionary["QT_INSTALL_LIBEXECS"] = qipempty ? "" : dictionary["QT_INSTALL_ARCHDATA"] + "/libexec";
}
diff --git a/util/glgen/qopenglextensions.h.footer b/util/glgen/qopenglextensions.h.footer
index b8a8e6f267..465b241c33 100644
--- a/util/glgen/qopenglextensions.h.footer
+++ b/util/glgen/qopenglextensions.h.footer
@@ -8,7 +8,7 @@ public:
void (QOPENGLF_APIENTRYP EGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image);
};
-class Q_GUI_EXPORT QOpenGLExtension_OES_EGL_image : public QAbstractOpenGLExtension
+class QOpenGLExtension_OES_EGL_image : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_OES_EGL_image();
@@ -41,7 +41,7 @@ public:
void (QOPENGLF_APIENTRYP ProgramBinaryOES)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
};
-class Q_GUI_EXPORT QOpenGLExtension_OES_get_program_binary : public QAbstractOpenGLExtension
+class QOpenGLExtension_OES_get_program_binary : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_OES_get_program_binary();
@@ -75,7 +75,7 @@ public:
void (QOPENGLF_APIENTRYP GetBufferPointervOES)(GLenum target, GLenum pname, GLvoid** params);
};
-class Q_GUI_EXPORT QOpenGLExtension_OES_mapbuffer : public QAbstractOpenGLExtension
+class QOpenGLExtension_OES_mapbuffer : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_OES_mapbuffer();
@@ -119,7 +119,7 @@ public:
void (QOPENGLF_APIENTRYP FramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
};
-class Q_GUI_EXPORT QOpenGLExtension_OES_texture_3D : public QAbstractOpenGLExtension
+class QOpenGLExtension_OES_texture_3D : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_OES_texture_3D();
@@ -182,7 +182,7 @@ public:
GLboolean (QOPENGLF_APIENTRYP IsVertexArrayOES)(GLuint array);
};
-class Q_GUI_EXPORT QOpenGLExtension_OES_vertex_array_object : public QAbstractOpenGLExtension
+class QOpenGLExtension_OES_vertex_array_object : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_OES_vertex_array_object();
@@ -238,7 +238,7 @@ public:
void (QOPENGLF_APIENTRYP GetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
};
-class Q_GUI_EXPORT QOpenGLExtension_AMD_performance_monitor : public QAbstractOpenGLExtension
+class QOpenGLExtension_AMD_performance_monitor : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_AMD_performance_monitor();
@@ -333,7 +333,7 @@ public:
void (QOPENGLF_APIENTRYP BlitFramebufferANGLE)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
};
-class Q_GUI_EXPORT QOpenGLExtension_ANGLE_framebuffer_blit : public QAbstractOpenGLExtension
+class QOpenGLExtension_ANGLE_framebuffer_blit : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_ANGLE_framebuffer_blit();
@@ -358,7 +358,7 @@ public:
void (QOPENGLF_APIENTRYP RenderbufferStorageMultisampleANGLE)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
};
-class Q_GUI_EXPORT QOpenGLExtension_ANGLE_framebuffer_multisample : public QAbstractOpenGLExtension
+class QOpenGLExtension_ANGLE_framebuffer_multisample : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_ANGLE_framebuffer_multisample();
@@ -385,7 +385,7 @@ public:
void (QOPENGLF_APIENTRYP VertexAttribDivisorANGLE)(GLuint index, GLuint divisor);
};
-class Q_GUI_EXPORT QOpenGLExtension_ANGLE_instanced_arrays : public QAbstractOpenGLExtension
+class QOpenGLExtension_ANGLE_instanced_arrays : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_ANGLE_instanced_arrays();
@@ -424,7 +424,7 @@ public:
void (QOPENGLF_APIENTRYP GetTranslatedShaderSourceANGLE)(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source);
};
-class Q_GUI_EXPORT QOpenGLExtension_ANGLE_translated_shader_source : public QAbstractOpenGLExtension
+class QOpenGLExtension_ANGLE_translated_shader_source : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_ANGLE_translated_shader_source();
@@ -450,7 +450,7 @@ public:
void (QOPENGLF_APIENTRYP ResolveMultisampleFramebufferAPPLE)(void);
};
-class Q_GUI_EXPORT QOpenGLExtension_APPLE_framebuffer_multisample : public QAbstractOpenGLExtension
+class QOpenGLExtension_APPLE_framebuffer_multisample : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_APPLE_framebuffer_multisample();
@@ -483,7 +483,7 @@ public:
void (QOPENGLF_APIENTRYP GetObjectLabelEXT)(GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_debug_label : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_debug_label : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_debug_label();
@@ -517,7 +517,7 @@ public:
void (QOPENGLF_APIENTRYP PopGroupMarkerEXT)(void);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_debug_marker : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_debug_marker : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_debug_marker();
@@ -556,7 +556,7 @@ public:
void (QOPENGLF_APIENTRYP DiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_discard_framebuffer : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_discard_framebuffer : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_discard_framebuffer();
@@ -582,7 +582,7 @@ public:
void (QOPENGLF_APIENTRYP FramebufferTexture2DMultisampleEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_multisampled_render_to_texture : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_multisampled_render_to_texture : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_multisampled_render_to_texture();
@@ -615,7 +615,7 @@ public:
void (QOPENGLF_APIENTRYP MultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_multi_draw_arrays : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_multi_draw_arrays : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_multi_draw_arrays();
@@ -653,7 +653,7 @@ public:
void (QOPENGLF_APIENTRYP GetQueryObjectuivEXT)(GLuint id, GLenum pname, GLuint *params);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_occlusion_query_boolean : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_occlusion_query_boolean : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_occlusion_query_boolean();
@@ -723,7 +723,7 @@ public:
void (QOPENGLF_APIENTRYP GetnUniformivEXT)(GLuint program, GLint location, GLsizei bufSize, GLint *params);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_robustness : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_robustness : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_robustness();
@@ -798,7 +798,7 @@ public:
void (QOPENGLF_APIENTRYP GetProgramPipelineInfoLogEXT)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_separate_shader_objects : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_separate_shader_objects : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_separate_shader_objects();
@@ -1031,7 +1031,7 @@ public:
void (QOPENGLF_APIENTRYP TextureStorage3DEXT)(GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
};
-class Q_GUI_EXPORT QOpenGLExtension_EXT_texture_storage : public QAbstractOpenGLExtension
+class QOpenGLExtension_EXT_texture_storage : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_EXT_texture_storage();
@@ -1092,7 +1092,7 @@ public:
void (QOPENGLF_APIENTRYP FramebufferTexture2DMultisampleIMG)(GLenum, GLenum, GLenum, GLuint, GLint, GLsizei);
};
-class Q_GUI_EXPORT QOpenGLExtension_IMG_multisampled_render_to_texture : public QAbstractOpenGLExtension
+class QOpenGLExtension_IMG_multisampled_render_to_texture : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_IMG_multisampled_render_to_texture();
@@ -1125,7 +1125,7 @@ public:
void (QOPENGLF_APIENTRYP CoverageOperationNV)(GLenum operation);
};
-class Q_GUI_EXPORT QOpenGLExtension_NV_coverage_sample : public QAbstractOpenGLExtension
+class QOpenGLExtension_NV_coverage_sample : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_NV_coverage_sample();
@@ -1157,7 +1157,7 @@ public:
void (QOPENGLF_APIENTRYP DrawBuffersNV)(GLsizei n, const GLenum *bufs);
};
-class Q_GUI_EXPORT QOpenGLExtension_NV_draw_buffers : public QAbstractOpenGLExtension
+class QOpenGLExtension_NV_draw_buffers : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_NV_draw_buffers();
@@ -1188,7 +1188,7 @@ public:
void (QOPENGLF_APIENTRYP SetFenceNV)(GLuint fence, GLenum condition);
};
-class Q_GUI_EXPORT QOpenGLExtension_NV_fence : public QAbstractOpenGLExtension
+class QOpenGLExtension_NV_fence : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_NV_fence();
@@ -1255,7 +1255,7 @@ public:
void (QOPENGLF_APIENTRYP ReadBufferNV)(GLenum mode);
};
-class Q_GUI_EXPORT QOpenGLExtension_NV_read_buffer : public QAbstractOpenGLExtension
+class QOpenGLExtension_NV_read_buffer : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_NV_read_buffer();
@@ -1280,7 +1280,7 @@ public:
void (QOPENGLF_APIENTRYP AlphaFuncQCOM)(GLenum func, GLclampf ref);
};
-class Q_GUI_EXPORT QOpenGLExtension_QCOM_alpha_test : public QAbstractOpenGLExtension
+class QOpenGLExtension_QCOM_alpha_test : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_QCOM_alpha_test();
@@ -1308,7 +1308,7 @@ public:
void (QOPENGLF_APIENTRYP DisableDriverControlQCOM)(GLuint driverControl);
};
-class Q_GUI_EXPORT QOpenGLExtension_QCOM_driver_control : public QAbstractOpenGLExtension
+class QOpenGLExtension_QCOM_driver_control : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_QCOM_driver_control();
@@ -1361,7 +1361,7 @@ public:
void (QOPENGLF_APIENTRYP ExtGetBufferPointervQCOM)(GLenum target, GLvoid **params);
};
-class Q_GUI_EXPORT QOpenGLExtension_QCOM_extended_get : public QAbstractOpenGLExtension
+class QOpenGLExtension_QCOM_extended_get : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_QCOM_extended_get();
@@ -1438,7 +1438,7 @@ public:
void (QOPENGLF_APIENTRYP ExtGetProgramBinarySourceQCOM)(GLuint program, GLenum shadertype, GLchar *source, GLint *length);
};
-class Q_GUI_EXPORT QOpenGLExtension_QCOM_extended_get2 : public QAbstractOpenGLExtension
+class QOpenGLExtension_QCOM_extended_get2 : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_QCOM_extended_get2();
@@ -1485,7 +1485,7 @@ public:
void (QOPENGLF_APIENTRYP EndTilingQCOM)(GLbitfield preserveMask);
};
-class Q_GUI_EXPORT QOpenGLExtension_QCOM_tiled_rendering : public QAbstractOpenGLExtension
+class QOpenGLExtension_QCOM_tiled_rendering : public QAbstractOpenGLExtension
{
public:
QOpenGLExtension_QCOM_tiled_rendering();
diff --git a/util/glgen/qopenglextensions.h.header b/util/glgen/qopenglextensions.h.header
index 89e248fc33..b83b081166 100644
--- a/util/glgen/qopenglextensions.h.header
+++ b/util/glgen/qopenglextensions.h.header
@@ -51,9 +51,10 @@
#ifndef QOPENGLEXTENSIONS_H
#define QOPENGLEXTENSIONS_H
+#include <QtCore/qglobal.h>
+
#ifndef QT_NO_OPENGL
-#include <QtCore/QtGlobal>
#include <QtGui/qopengl.h>
class QOpenGLContext;
@@ -66,119 +67,6 @@ QT_BEGIN_NAMESPACE
#pragma qt_sync_stop_processing
#endif
-#if !defined(QT_OPENGL_ES_2)
-// This block is copied from glext.h and defines the types needed by
-// a few extension classes. This may need updating in glgen when a new
-// OpenGL release is made and this file is regenerated.
-
-#include <stddef.h>
-#ifndef GL_VERSION_2_0
-/* GL type for program/shader text */
-typedef char GLchar;
-#endif
-
-#ifndef GL_VERSION_1_5
-/* GL types for handling large vertex buffer objects */
-typedef ptrdiff_t GLintptr;
-typedef ptrdiff_t GLsizeiptr;
-#endif
-
-#ifndef GL_ARB_vertex_buffer_object
-/* GL types for handling large vertex buffer objects */
-typedef ptrdiff_t GLintptrARB;
-typedef ptrdiff_t GLsizeiptrARB;
-#endif
-
-#ifndef GL_ARB_shader_objects
-/* GL types for program/shader text and shader object handles */
-typedef char GLcharARB;
-typedef unsigned int GLhandleARB;
-#endif
-
-/* GL type for "half" precision (s10e5) float data in host memory */
-#ifndef GL_ARB_half_float_pixel
-typedef unsigned short GLhalfARB;
-#endif
-
-#ifndef GL_NV_half_float
-typedef unsigned short GLhalfNV;
-#endif
-
-#ifndef GLEXT_64_TYPES_DEFINED
-/* This code block is duplicated in glxext.h, so must be protected */
-#define GLEXT_64_TYPES_DEFINED
-/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
-/* (as used in the GL_EXT_timer_query extension). */
-#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
-#include <inttypes.h>
-#elif defined(__sun__) || defined(__digital__)
-#include <inttypes.h>
-#if defined(__STDC__)
-#if defined(__arch64__) || defined(_LP64)
-typedef long int int64_t;
-typedef unsigned long int uint64_t;
-#else
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#endif /* __arch64__ */
-#endif /* __STDC__ */
-#elif defined( __VMS ) || defined(__sgi)
-#include <inttypes.h>
-#elif defined(__SCO__) || defined(__USLC__)
-#include <stdint.h>
-#elif defined(__UNIXOS2__) || defined(__SOL64__)
-typedef long int int32_t;
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#elif defined(_WIN32) && defined(__GNUC__)
-#include <stdint.h>
-#elif defined(_WIN32)
-typedef __int32 int32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#else
-/* Fallback if nothing above works */
-#include <inttypes.h>
-#endif
-#endif
-
-#ifndef GL_EXT_timer_query
-typedef int64_t GLint64EXT;
-typedef uint64_t GLuint64EXT;
-#endif
-
-#ifndef GL_ARB_sync
-typedef int64_t GLint64;
-typedef uint64_t GLuint64;
-typedef struct __GLsync *GLsync;
-#endif
-
-#ifndef GL_ARB_cl_event
-/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */
-struct _cl_context;
-struct _cl_event;
-#endif
-
-#ifndef GL_ARB_debug_output
-typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
-#endif
-
-#ifndef GL_AMD_debug_output
-typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
-#endif
-
-#ifndef GL_KHR_debug
-typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
-#endif
-
-#ifndef GL_NV_vdpau_interop
-typedef GLintptr GLvdpauSurfaceNV;
-#endif
-
-// End of block copied from glext.h
-#endif
-
-struct QOpenGLFunctionsPrivate;
class QAbstractOpenGLExtensionPrivate
{
diff --git a/util/glgen/qopenglversionfunctions.h.header b/util/glgen/qopenglversionfunctions.h.header
index 3bd28fc52d..69cdaf3728 100644
--- a/util/glgen/qopenglversionfunctions.h.header
+++ b/util/glgen/qopenglversionfunctions.h.header
@@ -51,17 +51,18 @@
#ifndef QOPENGLVERSIONFUNCTIONS_H
#define QOPENGLVERSIONFUNCTIONS_H
+#include <QtCore/qglobal.h>
+
#ifndef QT_NO_OPENGL
-#include <QtCore/QtGlobal>
#include <QtCore/qhash.h>
#include <QtCore/qpair.h>
#include <QtGui/qopengl.h>
-class QOpenGLContext;
-
QT_BEGIN_NAMESPACE
+class QOpenGLContext;
+
#if 0
// silence syncqt warnings
#pragma qt_class(QOpenGLVersionFunctions)
diff --git a/util/glgen/qopenglversionfunctions__VERSION__.h.footer b/util/glgen/qopenglversionfunctions__VERSION__.h.footer
index 02db4d3a13..b81155c102 100644
--- a/util/glgen/qopenglversionfunctions__VERSION__.h.footer
+++ b/util/glgen/qopenglversionfunctions__VERSION__.h.footer
@@ -1,6 +1,6 @@
QT_END_NAMESPACE
-#endif // QT_NO_OPENGL
+#endif // QT_NO_OPENGL && !QT_OPENGL_ES_2
#endif
diff --git a/util/glgen/qopenglversionfunctions__VERSION__.h.header b/util/glgen/qopenglversionfunctions__VERSION__.h.header
index b3d097c2f9..4b30dc1b65 100644
--- a/util/glgen/qopenglversionfunctions__VERSION__.h.header
+++ b/util/glgen/qopenglversionfunctions__VERSION__.h.header
@@ -51,7 +51,9 @@
#ifndef QOPENGLVERSIONFUNCTIONS__VERSION___H
#define QOPENGLVERSIONFUNCTIONS__VERSION___H
-#ifndef QT_NO_OPENGL
+#include <QtCore/qglobal.h>
+
+#if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2)
#include <QtGui/QOpenGLVersionFunctions>
#include <QtGui/qopenglcontext.h>
diff --git a/util/glgen/specparser.cpp b/util/glgen/specparser.cpp
index 514a700644..91a906bca9 100644
--- a/util/glgen/specparser.cpp
+++ b/util/glgen/specparser.cpp
@@ -253,7 +253,7 @@ void SpecParser::parseFunctions(QTextStream &stream)
// Extract the OpenGL version in which this function was deprecated.
// If it is OpenGL 3.1 then it must be a compatibility profile function
QString deprecatedVersion = deprecatedRegExp.cap(1).simplified();
- if (deprecatedVersion == QStringLiteral("3.1"))
+ if (deprecatedVersion == QStringLiteral("3.1") && !inDeprecationException(currentFunction.name))
currentVersionProfile.profile = VersionProfile::CompatibilityProfile;
} else if (categoryRegExp.indexIn(line) != -1) {
@@ -305,3 +305,8 @@ void SpecParser::parseFunctions(QTextStream &stream)
m_versions = versions.toList();
qSort(m_versions);
}
+
+bool SpecParser::inDeprecationException(const QString &functionName) const
+{
+ return (functionName == QStringLiteral("TexImage3D"));
+}
diff --git a/util/glgen/specparser.h b/util/glgen/specparser.h
index e455f6579c..19357841ca 100644
--- a/util/glgen/specparser.h
+++ b/util/glgen/specparser.h
@@ -192,6 +192,7 @@ protected:
bool parseTypeMap();
void parseEnums();
void parseFunctions(QTextStream &stream);
+ bool inDeprecationException(const QString &functionName) const;
private:
QString m_specFileName;