summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle')
-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.cpp432
-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.cpp342
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h56
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp75
-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.cpp767
-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
246 files changed, 27329 insertions, 16397 deletions
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..5a62142b45 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,106 @@ 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();
-
- HRESULT result;
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(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;
- }
+ ERR("Could not retrieve the window dimensions");
+ return error(EGL_BAD_SURFACE, false);
+ }
- if (mBackBuffer)
- {
- mBackBuffer->Release();
- mBackBuffer = NULL;
+ width = windowRect.right - windowRect.left;
+ height = windowRect.bottom - windowRect.top;
}
-
- if (mOffscreenTexture)
+ else
{
- mOffscreenTexture->Release();
- mOffscreenTexture = NULL;
+ // non-window surface - size is determined at creation
+ width = mWidth;
+ height = mHeight;
}
- if (mDepthStencil)
+ mSwapChain = mRenderer->createSwapChain(mWindow, mShareHandle,
+ mConfig->mRenderTargetFormat,
+ mConfig->mDepthStencilFormat);
+ if (!mSwapChain)
{
- mDepthStencil->Release();
- mDepthStencil = NULL;
+ return error(EGL_BAD_ALLOC, false);
}
- HANDLE *pShareHandle = NULL;
- if (!mWindow && mDisplay->shareHandleSupported())
+ if (!resetSwapChain(width, height))
{
- pShareHandle = &mShareHandle;
+ delete mSwapChain;
+ mSwapChain = NULL;
+ return false;
}
- // CreateTexture will fail on zero dimensions, so just release old target
- if (!backbufferWidth || !backbufferHeight)
- {
- if (mRenderTarget)
- {
- mRenderTarget->Release();
- mRenderTarget = NULL;
- }
+ return true;
+}
- mWidth = backbufferWidth;
- mHeight = backbufferHeight;
- mPresentIntervalDirty = false;
+bool Surface::resizeSwapChain(int backbufferWidth, int backbufferHeight)
+{
+ ASSERT(backbufferWidth >= 0 && backbufferHeight >= 0);
+ ASSERT(mSwapChain);
- return true;
- }
+ EGLint status = mSwapChain->resize(backbufferWidth, backbufferHeight);
- result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
- mConfig->mRenderTargetFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle);
- if (FAILED(result))
+ if (status == EGL_CONTEXT_LOST)
{
- ERR("Could not create offscreen texture: %08lX", result);
- release();
-
- if(isDeviceLostError(result))
- {
- mDisplay->notifyDeviceLost();
- return false;
- }
- else
- {
- return error(EGL_BAD_ALLOC, false);
- }
+ 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 +239,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);
-
- gl::Context *context = static_cast<gl::Context*>(glGetCurrentContext());
- if (context)
- {
- context->markAllStateDirty();
- }
+ EGLint status = mSwapChain->swapRect(x, y, width, height);
- if (isDeviceLostError(result))
+ if (status == EGL_CONTEXT_LOST)
{
- 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 +346,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 +364,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 +399,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 +412,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 +438,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..4c37bdbf60
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp
@@ -0,0 +1,342 @@
+#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);
+ }
+
+ 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;
+ }
+
+ D3D11_SUBRESOURCE_DATA initialData;
+ initialData.pSysMem = data;
+ initialData.SysMemPitch = size;
+ initialData.SysMemSlicePitch = 0;
+
+ result = device->CreateBuffer(&bufferDesc, &initialData, &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..7fc14fc073
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp
@@ -0,0 +1,75 @@
+#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);
+ 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..87422be727
--- /dev/null
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp
@@ -0,0 +1,767 @@
+#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;
+ }
+
+ // 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