summaryrefslogtreecommitdiffstats
path: root/Source/ThirdParty
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-05-16 16:25:10 +0100
committerBen Murdoch <benm@google.com>2011-05-23 18:54:14 +0100
commitab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb (patch)
treedb769fadd053248f85db67434a5b275224defef7 /Source/ThirdParty
parent52e2557aeb8477967e97fd24f20f8f407a10fa15 (diff)
downloadexternal_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.zip
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.gz
external_webkit-ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb.tar.bz2
Merge WebKit at r76408: Initial merge by git.
Change-Id: I5b91decbd693ccbf5c1b8354b37cd68cc9a1ea53
Diffstat (limited to 'Source/ThirdParty')
-rw-r--r--Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj137
-rw-r--r--Source/ThirdParty/ANGLE/ChangeLog610
-rw-r--r--Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h228
-rw-r--r--Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj35
-rw-r--r--Source/ThirdParty/ANGLE/src/common/debug.cpp8
-rw-r--r--Source/ThirdParty/ANGLE/src/common/debug.h2
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Common.h21
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp189
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h21
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/InfoSink.h1
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp122
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Initialize.h10
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp16
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp172
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp29
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp86
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h2
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp137
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h39
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp46
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h10
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp38
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h33
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ShHandle.h64
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp281
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp16
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h29
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp29
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h6
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp8
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h6
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Types.h6
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h2
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp468
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h62
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp210
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h38
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp108
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h50
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh11
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh12
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang.h16
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang.l734
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang.y1108
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp3186
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp4710
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h274
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp396
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/intermediate.h54
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/localintermediate.h4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/osinclude.h24
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp43
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h8
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c59
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h4
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c328
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h9
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c17
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/unistd.h1
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/util.cpp33
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/util.h21
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/Config.cpp7
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/Display.cpp301
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/Display.h19
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp266
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/Surface.h19
-rw-r--r--Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp35
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp19
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp50
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h9
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp633
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Context.h135
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp134
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h43
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp54
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp184
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Program.h10
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp1
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp48
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h5
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp35
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp1054
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h74
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp383
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h107
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp766
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h154
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp38
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h110
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp613
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h137
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp690
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def9
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj24
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp181
-rw-r--r--Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h14
100 files changed, 16498 insertions, 4306 deletions
diff --git a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
index 066a930..aa91bdb 100644
--- a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
+++ b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj
@@ -7,6 +7,22 @@
objects = {
/* Begin PBXBuildFile section */
+ 90D9B10212E11DCB002D4255 /* Compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0F912E11DCB002D4255 /* Compiler.cpp */; };
+ 90D9B10312E11DCB002D4255 /* ExtensionBehavior.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */; };
+ 90D9B10412E11DCB002D4255 /* glslang_lex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */; };
+ 90D9B10512E11DCB002D4255 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */; };
+ 90D9B10612E11DCB002D4255 /* glslang_tab.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FD12E11DCB002D4255 /* glslang_tab.h */; };
+ 90D9B10712E11DCB002D4255 /* glslang.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B0FE12E11DCB002D4255 /* glslang.h */; };
+ 90D9B10912E11DCB002D4255 /* SearchSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */; };
+ 90D9B10A12E11DCB002D4255 /* SearchSymbol.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10112E11DCB002D4255 /* SearchSymbol.h */; };
+ 90D9B11312E11DD6002D4255 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10B12E11DD6002D4255 /* util.cpp */; };
+ 90D9B11412E11DD6002D4255 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10C12E11DD6002D4255 /* util.h */; };
+ 90D9B11512E11DD6002D4255 /* ValidateLimitations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */; };
+ 90D9B11612E11DD6002D4255 /* ValidateLimitations.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */; };
+ 90D9B11712E11DD6002D4255 /* VariableInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */; };
+ 90D9B11812E11DD6002D4255 /* VariableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B11012E11DD6002D4255 /* VariableInfo.h */; };
+ 90D9B11912E11DD6002D4255 /* VersionGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */; };
+ 90D9B11A12E11DD6002D4255 /* VersionGLSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 90D9B11212E11DD6002D4255 /* VersionGLSL.h */; };
FB39D2711200F35A00088E69 /* CodeGenGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */; };
FB39D2751200F35A00088E69 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2261200F35A00088E69 /* debug.cpp */; };
FB39D2791200F35A00088E69 /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D22A1200F35A00088E69 /* InfoSink.cpp */; };
@@ -33,8 +49,6 @@
FB39D2AA1200F35A00088E69 /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D25C1200F35A00088E69 /* SymbolTable.cpp */; };
FB39D2AC1200F35A00088E69 /* TranslatorGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D2681200F35A00088E69 /* TranslatorGLSL.cpp */; };
FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */; };
- FB39D7231201032000088E69 /* glslang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7201201032000088E69 /* glslang.cpp */; };
- FB39D7241201032000088E69 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7221201032000088E69 /* glslang_tab.cpp */; };
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BF1200F3E600088E69 /* ShaderLang.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
@@ -42,6 +56,23 @@
5D7C59C51208C68B001C873E /* ANGLE.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ANGLE.xcconfig; sourceTree = "<group>"; };
5D7C59C61208C68B001C873E /* Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Base.xcconfig; sourceTree = "<group>"; };
5D7C59C71208C68B001C873E /* DebugRelease.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugRelease.xcconfig; sourceTree = "<group>"; };
+ 90D9B0F912E11DCB002D4255 /* Compiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Compiler.cpp; sourceTree = "<group>"; };
+ 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtensionBehavior.h; sourceTree = "<group>"; };
+ 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_lex.cpp; sourceTree = "<group>"; };
+ 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = "<group>"; };
+ 90D9B0FD12E11DCB002D4255 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang_tab.h; sourceTree = "<group>"; };
+ 90D9B0FE12E11DCB002D4255 /* glslang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang.h; sourceTree = "<group>"; };
+ 90D9B0FF12E11DCB002D4255 /* ossource_nspr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossource_nspr.cpp; sourceTree = "<group>"; };
+ 90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SearchSymbol.cpp; sourceTree = "<group>"; };
+ 90D9B10112E11DCB002D4255 /* SearchSymbol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SearchSymbol.h; sourceTree = "<group>"; };
+ 90D9B10B12E11DD6002D4255 /* util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; };
+ 90D9B10C12E11DD6002D4255 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
+ 90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateLimitations.cpp; sourceTree = "<group>"; };
+ 90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ValidateLimitations.h; sourceTree = "<group>"; };
+ 90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableInfo.cpp; sourceTree = "<group>"; };
+ 90D9B11012E11DD6002D4255 /* VariableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableInfo.h; sourceTree = "<group>"; };
+ 90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VersionGLSL.cpp; sourceTree = "<group>"; };
+ 90D9B11212E11DD6002D4255 /* VersionGLSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VersionGLSL.h; sourceTree = "<group>"; };
FB39D0D11200F0E300088E69 /* libANGLE.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libANGLE.a; sourceTree = BUILT_PRODUCTS_DIR; };
FB39D1861200F26200088E69 /* BaseTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = "<group>"; };
FB39D1871200F26200088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; };
@@ -50,8 +81,6 @@
FB39D18A1200F26200088E69 /* ConstantUnion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConstantUnion.h; sourceTree = "<group>"; };
FB39D18B1200F26200088E69 /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
FB39D18C1200F26200088E69 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- FB39D18D1200F26200088E69 /* glslang.l */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lex; path = glslang.l; sourceTree = "<group>"; };
- FB39D18E1200F26200088E69 /* glslang.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = glslang.y; sourceTree = "<group>"; };
FB39D18F1200F26200088E69 /* InfoSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = InfoSink.cpp; sourceTree = "<group>"; };
FB39D1901200F26200088E69 /* InfoSink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoSink.h; sourceTree = "<group>"; };
FB39D1911200F26200088E69 /* Initialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = Initialize.cpp; sourceTree = "<group>"; };
@@ -112,15 +141,12 @@
FB39D1D11200F26200088E69 /* Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; };
FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
FB39D1D31200F26200088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnfoldSelect.h; sourceTree = "<group>"; };
- FB39D1D41200F26200088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
FB39D2211200F35A00088E69 /* BaseTypes.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = BaseTypes.h; sourceTree = "<group>"; };
FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; };
FB39D2241200F35A00088E69 /* Common.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Common.h; sourceTree = "<group>"; };
FB39D2251200F35A00088E69 /* ConstantUnion.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ConstantUnion.h; sourceTree = "<group>"; };
FB39D2261200F35A00088E69 /* debug.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; };
FB39D2271200F35A00088E69 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
- FB39D2281200F35A00088E69 /* glslang.l */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.lex; path = glslang.l; sourceTree = "<group>"; };
- FB39D2291200F35A00088E69 /* glslang.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = glslang.y; sourceTree = "<group>"; };
FB39D22A1200F35A00088E69 /* InfoSink.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InfoSink.cpp; sourceTree = "<group>"; };
FB39D22B1200F35A00088E69 /* InfoSink.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = InfoSink.h; sourceTree = "<group>"; };
FB39D22C1200F35A00088E69 /* Initialize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Initialize.cpp; sourceTree = "<group>"; };
@@ -175,11 +201,7 @@
FB39D26C1200F35A00088E69 /* Types.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = Types.h; sourceTree = "<group>"; };
FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
FB39D26E1200F35A00088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = UnfoldSelect.h; sourceTree = "<group>"; };
- FB39D26F1200F35A00088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
FB39D2BF1200F3E600088E69 /* ShaderLang.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ShaderLang.h; sourceTree = "<group>"; };
- FB39D7201201032000088E69 /* glslang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = glslang.cpp; path = DerivedSources/ANGLE/glslang.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
- FB39D7211201032000088E69 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glslang_tab.h; path = DerivedSources/ANGLE/glslang_tab.h; sourceTree = BUILT_PRODUCTS_DIR; };
- FB39D7221201032000088E69 /* glslang_tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = glslang_tab.cpp; path = DerivedSources/ANGLE/glslang_tab.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -208,7 +230,6 @@
children = (
FB39D2201200F35A00088E69 /* compiler */,
FB39D0841200EDEB00088E69 /* Source */,
- FB39D0CB1200EF9400088E69 /* Intermediates */,
5D7C59C41208C68B001C873E /* Configurations */,
FB39D0CC1200EF9B00088E69 /* Products */,
);
@@ -223,16 +244,6 @@
name = Source;
sourceTree = "<group>";
};
- FB39D0CB1200EF9400088E69 /* Intermediates */ = {
- isa = PBXGroup;
- children = (
- FB39D7201201032000088E69 /* glslang.cpp */,
- FB39D7211201032000088E69 /* glslang_tab.h */,
- FB39D7221201032000088E69 /* glslang_tab.cpp */,
- );
- name = Intermediates;
- sourceTree = "<group>";
- };
FB39D0CC1200EF9B00088E69 /* Products */ = {
isa = PBXGroup;
children = (
@@ -251,8 +262,6 @@
FB39D18A1200F26200088E69 /* ConstantUnion.h */,
FB39D18B1200F26200088E69 /* debug.cpp */,
FB39D18C1200F26200088E69 /* debug.h */,
- FB39D18D1200F26200088E69 /* glslang.l */,
- FB39D18E1200F26200088E69 /* glslang.y */,
FB39D18F1200F26200088E69 /* InfoSink.cpp */,
FB39D1901200F26200088E69 /* InfoSink.h */,
FB39D1911200F26200088E69 /* Initialize.cpp */,
@@ -297,7 +306,6 @@
FB39D1D11200F26200088E69 /* Types.h */,
FB39D1D21200F26200088E69 /* UnfoldSelect.cpp */,
FB39D1D31200F26200088E69 /* UnfoldSelect.h */,
- FB39D1D41200F26200088E69 /* unistd.h */,
);
includeInIndex = 0;
name = compiler;
@@ -332,14 +340,19 @@
FB39D2201200F35A00088E69 /* compiler */ = {
isa = PBXGroup;
children = (
+ FB39D2441200F35A00088E69 /* preprocessor */,
FB39D2211200F35A00088E69 /* BaseTypes.h */,
FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */,
FB39D2241200F35A00088E69 /* Common.h */,
+ 90D9B0F912E11DCB002D4255 /* Compiler.cpp */,
FB39D2251200F35A00088E69 /* ConstantUnion.h */,
FB39D2261200F35A00088E69 /* debug.cpp */,
FB39D2271200F35A00088E69 /* debug.h */,
- FB39D2281200F35A00088E69 /* glslang.l */,
- FB39D2291200F35A00088E69 /* glslang.y */,
+ 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */,
+ 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */,
+ 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */,
+ 90D9B0FD12E11DCB002D4255 /* glslang_tab.h */,
+ 90D9B0FE12E11DCB002D4255 /* glslang.h */,
FB39D22A1200F35A00088E69 /* InfoSink.cpp */,
FB39D22B1200F35A00088E69 /* InfoSink.h */,
FB39D22C1200F35A00088E69 /* Initialize.cpp */,
@@ -355,6 +368,7 @@
FB39D2361200F35A00088E69 /* localintermediate.h */,
FB39D2371200F35A00088E69 /* MMap.h */,
FB39D2381200F35A00088E69 /* osinclude.h */,
+ 90D9B0FF12E11DCB002D4255 /* ossource_nspr.cpp */,
FB39D2391200F35A00088E69 /* ossource_posix.cpp */,
FB39D23A1200F35A00088E69 /* ossource_win.cpp */,
FB39D23B1200F35A00088E69 /* OutputGLSL.cpp */,
@@ -364,11 +378,12 @@
FB39D2411200F35A00088E69 /* ParseHelper.h */,
FB39D2421200F35A00088E69 /* PoolAlloc.cpp */,
FB39D2431200F35A00088E69 /* PoolAlloc.h */,
- FB39D2441200F35A00088E69 /* preprocessor */,
FB39D2561200F35A00088E69 /* QualifierAlive.cpp */,
FB39D2571200F35A00088E69 /* QualifierAlive.h */,
FB39D2581200F35A00088E69 /* RemoveTree.cpp */,
FB39D2591200F35A00088E69 /* RemoveTree.h */,
+ 90D9B10012E11DCB002D4255 /* SearchSymbol.cpp */,
+ 90D9B10112E11DCB002D4255 /* SearchSymbol.h */,
FB39D25A1200F35A00088E69 /* ShaderLang.cpp */,
FB39D25B1200F35A00088E69 /* ShHandle.h */,
FB39D25C1200F35A00088E69 /* SymbolTable.cpp */,
@@ -378,7 +393,14 @@
FB39D26C1200F35A00088E69 /* Types.h */,
FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */,
FB39D26E1200F35A00088E69 /* UnfoldSelect.h */,
- FB39D26F1200F35A00088E69 /* unistd.h */,
+ 90D9B10B12E11DD6002D4255 /* util.cpp */,
+ 90D9B10C12E11DD6002D4255 /* util.h */,
+ 90D9B10D12E11DD6002D4255 /* ValidateLimitations.cpp */,
+ 90D9B10E12E11DD6002D4255 /* ValidateLimitations.h */,
+ 90D9B10F12E11DD6002D4255 /* VariableInfo.cpp */,
+ 90D9B11012E11DD6002D4255 /* VariableInfo.h */,
+ 90D9B11112E11DD6002D4255 /* VersionGLSL.cpp */,
+ 90D9B11212E11DD6002D4255 /* VersionGLSL.h */,
);
name = compiler;
path = src/compiler;
@@ -425,6 +447,14 @@
buildActionMask = 2147483647;
files = (
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */,
+ 90D9B10312E11DCB002D4255 /* ExtensionBehavior.h in Headers */,
+ 90D9B10612E11DCB002D4255 /* glslang_tab.h in Headers */,
+ 90D9B10712E11DCB002D4255 /* glslang.h in Headers */,
+ 90D9B10A12E11DCB002D4255 /* SearchSymbol.h in Headers */,
+ 90D9B11412E11DD6002D4255 /* util.h in Headers */,
+ 90D9B11612E11DD6002D4255 /* ValidateLimitations.h in Headers */,
+ 90D9B11812E11DD6002D4255 /* VariableInfo.h in Headers */,
+ 90D9B11A12E11DD6002D4255 /* VersionGLSL.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -436,8 +466,6 @@
buildConfigurationList = FB39D0D61200F11E00088E69 /* Build configuration list for PBXNativeTarget "ANGLE" */;
buildPhases = (
FB39D77B1201110C00088E69 /* Headers */,
- FB39D0DE1200F19100088E69 /* Generate glslang lexer */,
- FB39D31C1200F69200088E69 /* Generate glslang parser */,
FB39D0CE1200F0E300088E69 /* Sources */,
FB39D0CF1200F0E300088E69 /* Frameworks */,
);
@@ -457,7 +485,6 @@
isa = PBXProject;
buildConfigurationList = FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "ANGLE" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
@@ -474,49 +501,11 @@
};
/* End PBXProject section */
-/* Begin PBXShellScriptBuildPhase section */
- FB39D0DE1200F19100088E69 /* Generate glslang lexer */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 12;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/src/compiler/glslang.l",
- );
- name = "Generate glslang lexer";
- outputPaths = (
- "$(BUILT_PRODUCTS_DIR)/DerivedSources/$(PROJECT_NAME)/glslang.cpp",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}\"\nflex --noline --nounistd \"--outfile=${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}/glslang.cpp\" \"${SRCROOT}/src/compiler/glslang.l\"\n";
- };
- FB39D31C1200F69200088E69 /* Generate glslang parser */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/src/compiler/glslang.y",
- );
- name = "Generate glslang parser";
- outputPaths = (
- "$(BUILT_PRODUCTS_DIR)/DerivedSources/$(PROJECT_NAME)/glslang_tab.cpp",
- "$(BUILT_PRODUCTS_DIR)/DerivedSources/$(PROJECT_NAME)/glslang_tab.h",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "mkdir -p \"${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}\"\nbison --no-lines \"--defines=${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}/glslang_tab.h\" \"--skeleton=yacc.c\" \"--output=${BUILT_PRODUCTS_DIR}/DerivedSources/${PROJECT_NAME}/glslang_tab.cpp\" \"${SRCROOT}/src/compiler/glslang.y\"\n";
- };
-/* End PBXShellScriptBuildPhase section */
-
/* Begin PBXSourcesBuildPhase section */
FB39D0CE1200F0E300088E69 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- FB39D7231201032000088E69 /* glslang.cpp in Sources */,
- FB39D7241201032000088E69 /* glslang_tab.cpp in Sources */,
FB39D2711200F35A00088E69 /* CodeGenGLSL.cpp in Sources */,
FB39D2751200F35A00088E69 /* debug.cpp in Sources */,
FB39D2791200F35A00088E69 /* InfoSink.cpp in Sources */,
@@ -543,6 +532,14 @@
FB39D2AA1200F35A00088E69 /* SymbolTable.cpp in Sources */,
FB39D2AC1200F35A00088E69 /* TranslatorGLSL.cpp in Sources */,
FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */,
+ 90D9B10212E11DCB002D4255 /* Compiler.cpp in Sources */,
+ 90D9B10412E11DCB002D4255 /* glslang_lex.cpp in Sources */,
+ 90D9B10512E11DCB002D4255 /* glslang_tab.cpp in Sources */,
+ 90D9B10912E11DCB002D4255 /* SearchSymbol.cpp in Sources */,
+ 90D9B11312E11DD6002D4255 /* util.cpp in Sources */,
+ 90D9B11512E11DD6002D4255 /* ValidateLimitations.cpp in Sources */,
+ 90D9B11712E11DD6002D4255 /* VariableInfo.cpp in Sources */,
+ 90D9B11912E11DD6002D4255 /* VersionGLSL.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/ThirdParty/ANGLE/ChangeLog b/Source/ThirdParty/ANGLE/ChangeLog
index bd993b7..604df51 100644
--- a/Source/ThirdParty/ANGLE/ChangeLog
+++ b/Source/ThirdParty/ANGLE/ChangeLog
@@ -1,3 +1,613 @@
+2011-01-18 Kenneth Russell <kbr@google.com>
+
+ Unreviewed, Leopard build fix. Remove flex/bison targets for GLSL
+ grammar because the generated sources are already checked in.
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * src/build_angle.xcodeproj/project.pbxproj:
+
+2011-01-18 Kenneth Russell <kbr@google.com>
+
+ Unreviewed, release build fix. Explicitly cast away const.
+
+ * src/compiler/preprocessor/scanner.c:
+ (ScanFromString):
+
+2011-01-18 Ben Vanik <ben.vanik@gmail.com>
+
+ Reviewed by Kenneth Russell.
+
+ Updating ANGLE in WebKit to r533.
+ https://bugs.webkit.org/show_bug.cgi?id=47194
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * include/GLSLANG/ShaderLang.h:
+ * src/common/debug.cpp:
+ (gl::trace):
+ * src/common/debug.h:
+ * src/compiler/CodeGenGLSL.cpp:
+ (ConstructCompiler):
+ * src/compiler/CodeGenHLSL.cpp:
+ (ConstructCompiler):
+ * src/compiler/Common.h:
+ (EncodeSourceLoc):
+ (DecodeSourceLoc):
+ * src/compiler/Compiler.cpp: Added.
+ (TShHandleBase::TShHandleBase):
+ (TShHandleBase::~TShHandleBase):
+ (TCompiler::TCompiler):
+ (TCompiler::~TCompiler):
+ (TCompiler::Init):
+ (TCompiler::compile):
+ (TCompiler::InitBuiltInSymbolTable):
+ (TCompiler::clearResults):
+ (TCompiler::validateLimitations):
+ (TCompiler::collectAttribsUniforms):
+ * src/compiler/ExtensionBehavior.h: Added.
+ * src/compiler/InfoSink.cpp:
+ (TInfoSinkBase::location):
+ * src/compiler/InfoSink.h:
+ (TInfoSinkBase::size):
+ * src/compiler/Initialize.cpp:
+ (BuiltInFunctionsCommon):
+ (BuiltInFunctionsVertex):
+ (BuiltInFunctionsFragment):
+ (StandardUniforms):
+ (DefaultPrecisionVertex):
+ (DefaultPrecisionFragment):
+ (BuiltInConstants):
+ (TBuiltIns::initialize):
+ (IdentifyBuiltIns):
+ (InitExtensionBehavior):
+ * src/compiler/Initialize.h:
+ * src/compiler/IntermTraverse.cpp:
+ (TIntermLoop::traverse):
+ * src/compiler/Intermediate.cpp:
+ (getOperatorString):
+ (TIntermediate::addBinaryMath):
+ (TIntermediate::addLoop):
+ (TIntermediate::postProcess):
+ (TIntermBinary::promote):
+ * src/compiler/OutputGLSL.cpp:
+ (TOutputGLSL::visitUnary):
+ (TOutputGLSL::visitLoop):
+ * src/compiler/OutputHLSL.cpp:
+ (sh::OutputHLSL::OutputHLSL):
+ (sh::OutputHLSL::header):
+ (sh::OutputHLSL::visitBinary):
+ (sh::OutputHLSL::visitUnary):
+ (sh::OutputHLSL::visitAggregate):
+ (sh::OutputHLSL::visitLoop):
+ (sh::OutputHLSL::handleExcessiveLoop):
+ (sh::OutputHLSL::argumentString):
+ * src/compiler/OutputHLSL.h:
+ * src/compiler/ParseHelper.cpp:
+ (ReportInfo):
+ (DefineExtensionMacros):
+ (TParseContext::error):
+ (TParseContext::warning):
+ (TParseContext::reservedErrorCheck):
+ (TParseContext::constructorErrorCheck):
+ (TParseContext::arrayQualifierErrorCheck):
+ (TParseContext::extensionErrorCheck):
+ (TParseContext::areAllChildConst):
+ (PaParseStrings):
+ * src/compiler/ParseHelper.h:
+ (TParseContext::TParseContext):
+ * src/compiler/PoolAlloc.cpp:
+ (InitializeGlobalPools):
+ (FreeGlobalPools):
+ (SetGlobalPoolAllocator):
+ (TPoolAllocator::TPoolAllocator):
+ (TPoolAllocator::~TPoolAllocator):
+ (TAllocation::checkAllocList):
+ * src/compiler/PoolAlloc.h:
+ * src/compiler/SearchSymbol.cpp: Added.
+ (sh::SearchSymbol::SearchSymbol):
+ (sh::SearchSymbol::traverse):
+ (sh::SearchSymbol::visitSymbol):
+ (sh::SearchSymbol::foundMatch):
+ * src/compiler/SearchSymbol.h: Added.
+ * src/compiler/ShHandle.h:
+ (TCompiler::getAsCompiler):
+ (TCompiler::getInfoSink):
+ (TCompiler::getAttribs):
+ (TCompiler::getUniforms):
+ (TCompiler::getShaderType):
+ (TCompiler::getShaderSpec):
+ * src/compiler/ShaderLang.cpp:
+ (getVariableMaxLength):
+ (getVariableInfo):
+ (ShInitBuiltInResources):
+ (ShConstructCompiler):
+ (ShCompile):
+ (ShGetInfo):
+ (ShGetInfoLog):
+ (ShGetObjectCode):
+ (ShGetActiveAttrib):
+ (ShGetActiveUniform):
+ * src/compiler/SymbolTable.cpp:
+ (TSymbolTableLevel::relateToExtension):
+ * src/compiler/SymbolTable.h:
+ (TVariable::shareConstPointer):
+ (TFunction::relateToExtension):
+ (TFunction::getExtension):
+ (TFunction::getParamCount):
+ (TFunction::getParam):
+ (TSymbolTable::getGlobalLevel):
+ (TSymbolTable::relateToOperator):
+ (TSymbolTable::relateToExtension):
+ * src/compiler/TranslatorGLSL.cpp:
+ (writeVersion):
+ (TranslatorGLSL::TranslatorGLSL):
+ (TranslatorGLSL::translate):
+ * src/compiler/TranslatorGLSL.h:
+ * src/compiler/TranslatorHLSL.cpp:
+ (TranslatorHLSL::TranslatorHLSL):
+ (TranslatorHLSL::translate):
+ * src/compiler/TranslatorHLSL.h:
+ * src/compiler/Types.h:
+ (TType::TType):
+ * src/compiler/UnfoldSelect.cpp:
+ (sh::UnfoldSelect::visitSelection):
+ * src/compiler/UnfoldSelect.h:
+ * src/compiler/ValidateLimitations.cpp: Added.
+ (ValidateLimitations::ValidateLimitations):
+ (ValidateLimitations::visitSymbol):
+ (ValidateLimitations::visitConstantUnion):
+ (ValidateLimitations::visitBinary):
+ (ValidateLimitations::visitUnary):
+ (ValidateLimitations::visitSelection):
+ (ValidateLimitations::visitAggregate):
+ (ValidateLimitations::visitLoop):
+ (ValidateLimitations::visitBranch):
+ (ValidateLimitations::error):
+ (ValidateLimitations::withinLoopBody):
+ (ValidateLimitations::isLoopIndex):
+ (ValidateLimitations::validateLoopType):
+ (ValidateLimitations::validateForLoopHeader):
+ (ValidateLimitations::validateForLoopInit):
+ (ValidateLimitations::validateForLoopCond):
+ (ValidateLimitations::validateForLoopExpr):
+ (ValidateLimitations::validateFunctionCall):
+ (ValidateLimitations::validateOperation):
+ (ValidateLimitations::isConstExpr):
+ (ValidateLimitations::isConstIndexExpr):
+ (ValidateLimitations::validateIndexing):
+ * src/compiler/ValidateLimitations.h: Added.
+ (ValidateLimitations::numErrors):
+ * src/compiler/VariableInfo.cpp: Added.
+ (arrayBrackets):
+ (getVariableDataType):
+ (getVariableInfo):
+ (getBuiltInVariableInfo):
+ (getUserDefinedVariableInfo):
+ (CollectAttribsUniforms::CollectAttribsUniforms):
+ (CollectAttribsUniforms::visitSymbol):
+ (CollectAttribsUniforms::visitConstantUnion):
+ (CollectAttribsUniforms::visitBinary):
+ (CollectAttribsUniforms::visitUnary):
+ (CollectAttribsUniforms::visitSelection):
+ (CollectAttribsUniforms::visitAggregate):
+ (CollectAttribsUniforms::visitLoop):
+ (CollectAttribsUniforms::visitBranch):
+ * src/compiler/VariableInfo.h: Added.
+ * src/compiler/VersionGLSL.cpp: Added.
+ (TVersionGLSL::TVersionGLSL):
+ (TVersionGLSL::visitSymbol):
+ (TVersionGLSL::visitConstantUnion):
+ (TVersionGLSL::visitBinary):
+ (TVersionGLSL::visitUnary):
+ (TVersionGLSL::visitSelection):
+ (TVersionGLSL::visitAggregate):
+ (TVersionGLSL::visitLoop):
+ (TVersionGLSL::visitBranch):
+ (TVersionGLSL::updateVersion):
+ * src/compiler/VersionGLSL.h: Added.
+ (TVersionGLSL::getVersion):
+ * src/compiler/generate_glslang_lexer.sh: Added.
+ * src/compiler/generate_glslang_parser.sh: Added.
+ * src/compiler/glslang.h: Added.
+ * src/compiler/glslang.l:
+ * src/compiler/glslang.y:
+ * src/compiler/glslang_lex.cpp: Added.
+ (yy_get_next_buffer):
+ (yy_get_previous_state):
+ (yy_try_NUL_trans):
+ (input):
+ (yyrestart):
+ (yy_switch_to_buffer):
+ (yy_load_buffer_state):
+ (yy_create_buffer):
+ (yy_delete_buffer):
+ (yy_init_buffer):
+ (yy_flush_buffer):
+ (yypush_buffer_state):
+ (yypop_buffer_state):
+ (yyensure_buffer_stack):
+ (yy_scan_buffer):
+ (yy_scan_string):
+ (yy_scan_bytes):
+ (yy_push_state):
+ (yy_pop_state):
+ (yy_top_state):
+ (yy_fatal_error):
+ (yyget_extra):
+ (yyget_lineno):
+ (yyget_column):
+ (yyget_in):
+ (yyget_out):
+ (yyget_leng):
+ (yyget_text):
+ (yyset_extra):
+ (yyset_lineno):
+ (yyset_column):
+ (yyset_in):
+ (yyset_out):
+ (yyget_debug):
+ (yyset_debug):
+ (yyget_lval):
+ (yyset_lval):
+ (yylex_init):
+ (yylex_init_extra):
+ (yy_init_globals):
+ (yylex_destroy):
+ (yy_flex_strncpy):
+ (yy_flex_strlen):
+ (yyalloc):
+ (yyrealloc):
+ (yyfree):
+ (string_input):
+ (check_type):
+ (reserved_word):
+ (yyerror):
+ (glslang_initialize):
+ (glslang_finalize):
+ (glslang_scan):
+ * src/compiler/glslang_tab.cpp: Added.
+ (yytnamerr):
+ (yysyntax_error):
+ (glslang_parse):
+ * src/compiler/glslang_tab.h: Added.
+ * src/compiler/intermOut.cpp:
+ (TOutputTraverser::TOutputTraverser):
+ (OutputTreeText):
+ (TOutputTraverser::visitSymbol):
+ (TOutputTraverser::visitBinary):
+ (TOutputTraverser::visitUnary):
+ (TOutputTraverser::visitAggregate):
+ (TOutputTraverser::visitSelection):
+ (TOutputTraverser::visitConstantUnion):
+ (TOutputTraverser::visitLoop):
+ (TOutputTraverser::visitBranch):
+ (TIntermediate::outputTree):
+ * src/compiler/intermediate.h:
+ (TIntermLoop::TIntermLoop):
+ (TIntermLoop::getType):
+ (TIntermLoop::getInit):
+ (TIntermLoop::getCondition):
+ (TIntermLoop::getExpression):
+ (TIntermLoop::getBody):
+ * src/compiler/localintermediate.h:
+ * src/compiler/osinclude.h:
+ (OS_GetTLSValue):
+ * src/compiler/ossource_nspr.cpp: Added.
+ (OS_AllocTLSIndex):
+ (OS_SetTLSValue):
+ (OS_FreeTLSIndex):
+ * src/compiler/preprocessor/compile.h:
+ * src/compiler/preprocessor/cpp.c:
+ (CPPdefine):
+ (CPPelse):
+ (CPPif):
+ (CPPifdef):
+ (CPPerror):
+ (CPPextension):
+ (readCPPline):
+ * src/compiler/preprocessor/preprocess.h:
+ * src/compiler/preprocessor/scanner.c:
+ (str_getch):
+ (str_ungetch):
+ (ScanFromString):
+ (lFloatConst):
+ (byte_scan):
+ (yylex_CPP):
+ (check_EOF):
+ * src/compiler/preprocessor/scanner.h:
+ * src/compiler/preprocessor/tokens.c:
+ (RecordToken):
+ (ReadToken):
+ * src/compiler/tools: Removed.
+ * src/compiler/unistd.h: Removed.
+ * src/compiler/util.cpp: Added.
+ (atof_dot):
+ * src/compiler/util.h: Added.
+ * src/libEGL/Config.cpp:
+ (egl::Config::set):
+ * src/libEGL/Display.cpp:
+ (egl::Display::Display):
+ (egl::Display::initialize):
+ (egl::Display::terminate):
+ (egl::Display::createDevice):
+ (egl::Display::resetDevice):
+ (egl::Display::createContext):
+ (egl::Display::destroyContext):
+ (egl::Display::getMinSwapInterval):
+ (egl::Display::getMaxSwapInterval):
+ (egl::Display::getDevice):
+ (egl::Display::getFloatTextureSupport):
+ (egl::Display::getHalfFloatTextureSupport):
+ (egl::Display::getLuminanceTextureSupport):
+ (egl::Display::getLuminanceAlphaTextureSupport):
+ (egl::Display::getBufferPool):
+ (egl::Display::getEventQuerySupport):
+ (egl::Display::getDefaultPresentParameters):
+ * src/libEGL/Display.h:
+ * src/libEGL/Surface.cpp:
+ (egl::Surface::Surface):
+ (egl::Surface::~Surface):
+ (egl::Surface::release):
+ (egl::Surface::resetSwapChain):
+ (egl::Surface::writeRecordableFlipState):
+ (egl::Surface::restoreState):
+ (egl::SurfaceWindowProc):
+ (egl::Surface::subclassWindow):
+ (egl::Surface::unsubclassWindow):
+ (egl::Surface::checkForOutOfDateSwapChain):
+ (egl::Surface::convertInterval):
+ (egl::Surface::swap):
+ (egl::Surface::getRenderTarget):
+ (egl::Surface::setSwapInterval):
+ * src/libEGL/Surface.h:
+ * src/libEGL/libEGL.cpp:
+ * src/libGLESv2/Blit.cpp:
+ (gl::Blit::copySurfaceToTexture):
+ (gl::Blit::setCommonBlitState):
+ * src/libGLESv2/Buffer.cpp:
+ (gl::Buffer::Buffer):
+ (gl::Buffer::~Buffer):
+ (gl::Buffer::bufferData):
+ (gl::Buffer::bufferSubData):
+ (gl::Buffer::getVertexBuffer):
+ (gl::Buffer::getIndexBuffer):
+ (gl::Buffer::invalidateStaticData):
+ * src/libGLESv2/Buffer.h:
+ * src/libGLESv2/Context.cpp:
+ (gl::Context::Context):
+ (gl::Context::~Context):
+ (gl::Context::makeCurrent):
+ (gl::Context::markAllStateDirty):
+ (gl::Context::setFragmentShaderDerivativeHint):
+ (gl::Context::setEnableVertexAttribArray):
+ (gl::Context::getVertexAttribState):
+ (gl::Context::getVertexAttributes):
+ (gl::Context::createFence):
+ (gl::Context::deleteFence):
+ (gl::Context::bindTexture2D):
+ (gl::Context::bindTextureCubeMap):
+ (gl::Context::getFence):
+ (gl::Context::getTexture2D):
+ (gl::Context::getTextureCubeMap):
+ (gl::Context::getSamplerTexture):
+ (gl::Context::getBooleanv):
+ (gl::Context::getIntegerv):
+ (gl::Context::getQueryParameterInfo):
+ (gl::Context::applyRenderTarget):
+ (gl::Context::applyState):
+ (gl::Context::lookupAttributeMapping):
+ (gl::Context::applyVertexBuffer):
+ (gl::Context::applyIndexBuffer):
+ (gl::Context::readPixels):
+ (gl::Context::clear):
+ (gl::Context::drawArrays):
+ (gl::Context::drawElements):
+ (gl::Context::finish):
+ (gl::Context::drawClosingLine):
+ (gl::Context::getMaximumVaryingVectors):
+ (gl::Context::getMaximumFragmentUniformVectors):
+ (gl::Context::supportsEventQueries):
+ (gl::Context::supportsFloatTextures):
+ (gl::Context::supportsFloatLinearFilter):
+ (gl::Context::supportsFloatRenderableTextures):
+ (gl::Context::supportsHalfFloatTextures):
+ (gl::Context::supportsHalfFloatLinearFilter):
+ (gl::Context::supportsHalfFloatRenderableTextures):
+ (gl::Context::getMaximumRenderbufferDimension):
+ (gl::Context::getMaximumTextureDimension):
+ (gl::Context::getMaximumCubeTextureDimension):
+ (gl::Context::getMaximumTextureLevel):
+ (gl::Context::supportsLuminanceTextures):
+ (gl::Context::supportsLuminanceAlphaTextures):
+ (gl::Context::supports32bitIndices):
+ (gl::Context::getIncompleteTexture):
+ (gl::Context::setVertexAttrib):
+ (gl::Context::initExtensionString):
+ (gl::Context::blitFramebuffer):
+ * src/libGLESv2/Context.h:
+ (gl::VertexAttribute::VertexAttribute):
+ (gl::VertexAttribute::typeSize):
+ (gl::VertexAttribute::stride):
+ * src/libGLESv2/Fence.cpp: Added.
+ (gl::Fence::Fence):
+ (gl::Fence::~Fence):
+ (gl::Fence::isFence):
+ (gl::Fence::setFence):
+ (gl::Fence::testFence):
+ (gl::Fence::finishFence):
+ (gl::Fence::getFenceiv):
+ * src/libGLESv2/Fence.h: Added.
+ * src/libGLESv2/Framebuffer.cpp:
+ (gl::Framebuffer::completeness):
+ (gl::DefaultFramebuffer::DefaultFramebuffer):
+ (gl::DefaultFramebuffer::completeness):
+ * src/libGLESv2/Program.cpp:
+ (gl::Program::Program):
+ (gl::Program::getSamplerMapping):
+ (gl::Program::getUniformLocation):
+ (gl::Program::setUniform1iv):
+ (gl::Program::applyUniforms):
+ (gl::Program::packVaryings):
+ (gl::Program::linkVaryings):
+ (gl::Program::link):
+ (gl::Program::defineUniform):
+ (gl::Program::createUniform):
+ (gl::Program::applyUniform1iv):
+ (gl::Program::resetInfoLog):
+ (gl::Program::unlink):
+ (gl::Program::getActiveAttribute):
+ (gl::Program::getActiveUniform):
+ (gl::Program::getDxDepthRangeLocation):
+ * src/libGLESv2/Program.h:
+ * src/libGLESv2/RefCountObject.cpp:
+ (gl::RefCountObject::~RefCountObject):
+ * src/libGLESv2/Renderbuffer.cpp:
+ (gl::RenderbufferStorage::RenderbufferStorage):
+ (gl::RenderbufferStorage::isFloatingPoint):
+ (gl::Colorbuffer::Colorbuffer):
+ (gl::DepthStencilbuffer::DepthStencilbuffer):
+ * src/libGLESv2/Renderbuffer.h:
+ * src/libGLESv2/Shader.cpp:
+ (gl::Shader::Shader):
+ (gl::Shader::parseVaryings):
+ (gl::Shader::compileToHLSL):
+ (gl::VertexShader::parseAttributes):
+ * src/libGLESv2/Texture.cpp:
+ (gl::Texture::Texture):
+ (gl::Texture::isFloatingPoint):
+ (gl::Texture::isRenderableFormat):
+ (gl::Texture::selectFormat):
+ (gl::Texture::loadImageData):
+ (gl::Texture::loadAlphaFloatImageData):
+ (gl::Texture::loadAlphaHalfFloatImageData):
+ (gl::Texture::loadLuminanceImageData):
+ (gl::Texture::loadLuminanceFloatImageData):
+ (gl::Texture::loadLuminanceHalfFloatImageData):
+ (gl::Texture::loadLuminanceAlphaImageData):
+ (gl::Texture::loadLuminanceAlphaFloatImageData):
+ (gl::Texture::loadLuminanceAlphaHalfFloatImageData):
+ (gl::Texture::loadRGBFloatImageData):
+ (gl::Texture::loadRGBHalfFloatImageData):
+ (gl::Texture::loadRGBAFloatImageData):
+ (gl::Texture::loadRGBAHalfFloatImageData):
+ (gl::Texture::createSurface):
+ (gl::Texture::setImage):
+ (gl::Texture::setCompressedImage):
+ (gl::Texture::subImage):
+ (gl::Texture::subImageCompressed):
+ (gl::Texture::copyNonRenderable):
+ (gl::Texture::getD3DFormat):
+ (gl::Texture::isRenderable):
+ (gl::Texture2D::Texture2D):
+ (gl::Texture2D::~Texture2D):
+ (gl::Texture2D::redefineTexture):
+ (gl::Texture2D::setImage):
+ (gl::Texture2D::setCompressedImage):
+ (gl::Texture2D::copyImage):
+ (gl::Texture2D::copySubImage):
+ (gl::Texture2D::isComplete):
+ (gl::Texture2D::createTexture):
+ (gl::Texture2D::convertToRenderTarget):
+ (gl::Texture2D::generateMipmaps):
+ (gl::Texture2D::getColorbuffer):
+ (gl::Texture2D::getRenderTarget):
+ (gl::TextureCubeMap::TextureCubeMap):
+ (gl::TextureCubeMap::~TextureCubeMap):
+ (gl::TextureCubeMap::subImage):
+ (gl::TextureCubeMap::subImageCompressed):
+ (gl::TextureCubeMap::isComplete):
+ (gl::TextureCubeMap::createTexture):
+ (gl::TextureCubeMap::convertToRenderTarget):
+ (gl::TextureCubeMap::redefineTexture):
+ (gl::TextureCubeMap::copyImage):
+ (gl::TextureCubeMap::copySubImage):
+ (gl::TextureCubeMap::generateMipmaps):
+ (gl::TextureCubeMap::getColorbuffer):
+ (gl::TextureCubeMap::getRenderTarget):
+ (gl::Texture::TextureColorbufferProxy::TextureColorbufferProxy):
+ (gl::Texture::TextureColorbufferProxy::isFloatingPoint):
+ * src/libGLESv2/Texture.h:
+ * src/libGLESv2/geometry/IndexDataManager.cpp:
+ (gl::IndexDataManager::IndexDataManager):
+ (gl::IndexDataManager::~IndexDataManager):
+ (gl::convertIndices):
+ (gl::computeRange):
+ (gl::IndexDataManager::prepareIndexData):
+ (gl::IndexDataManager::indexSize):
+ (gl::IndexDataManager::typeSize):
+ (gl::IndexBuffer::IndexBuffer):
+ (gl::IndexBuffer::~IndexBuffer):
+ (gl::IndexBuffer::getBuffer):
+ (gl::IndexBuffer::unmap):
+ (gl::StreamingIndexBuffer::StreamingIndexBuffer):
+ (gl::StreamingIndexBuffer::~StreamingIndexBuffer):
+ (gl::StreamingIndexBuffer::map):
+ (gl::StreamingIndexBuffer::reserveSpace):
+ (gl::StaticIndexBuffer::StaticIndexBuffer):
+ (gl::StaticIndexBuffer::~StaticIndexBuffer):
+ (gl::StaticIndexBuffer::map):
+ (gl::StaticIndexBuffer::reserveSpace):
+ (gl::StaticIndexBuffer::lookupType):
+ (gl::StaticIndexBuffer::lookupRange):
+ (gl::StaticIndexBuffer::addRange):
+ * src/libGLESv2/geometry/IndexDataManager.h:
+ (gl::IndexBuffer::size):
+ * src/libGLESv2/geometry/VertexDataManager.cpp:
+ (gl::VertexDataManager::VertexDataManager):
+ (gl::VertexDataManager::~VertexDataManager):
+ (gl::VertexDataManager::writeAttributeData):
+ (gl::VertexDataManager::prepareVertexData):
+ (gl::VertexDataManager::spaceRequired):
+ (gl::VertexDataManager::checkVertexCaps):
+ (gl::VertexDataManager::typeIndex):
+ (gl::VertexDataManager::setupAttributes):
+ (gl::VertexBuffer::VertexBuffer):
+ (gl::VertexBuffer::~VertexBuffer):
+ (gl::VertexBuffer::unmap):
+ (gl::VertexBuffer::getBuffer):
+ (gl::ConstantVertexBuffer::ConstantVertexBuffer):
+ (gl::ConstantVertexBuffer::~ConstantVertexBuffer):
+ (gl::ArrayVertexBuffer::ArrayVertexBuffer):
+ (gl::ArrayVertexBuffer::~ArrayVertexBuffer):
+ (gl::ArrayVertexBuffer::addRequiredSpace):
+ (gl::ArrayVertexBuffer::addRequiredSpaceFor):
+ (gl::StreamingVertexBuffer::StreamingVertexBuffer):
+ (gl::StreamingVertexBuffer::~StreamingVertexBuffer):
+ (gl::StreamingVertexBuffer::map):
+ (gl::StreamingVertexBuffer::reserveRequiredSpace):
+ (gl::StaticVertexBuffer::StaticVertexBuffer):
+ (gl::StaticVertexBuffer::~StaticVertexBuffer):
+ (gl::StaticVertexBuffer::map):
+ (gl::StaticVertexBuffer::reserveRequiredSpace):
+ (gl::StaticVertexBuffer::lookupAttribute):
+ (gl::VertexDataManager::formatConverter):
+ * src/libGLESv2/geometry/VertexDataManager.h:
+ (gl::ArrayVertexBuffer::size):
+ (gl::VertexDataManager::dirtyCurrentValue):
+ * src/libGLESv2/geometry/backend.cpp: Removed.
+ * src/libGLESv2/geometry/backend.h: Removed.
+ * src/libGLESv2/geometry/dx9.cpp: Removed.
+ * src/libGLESv2/geometry/dx9.h: Removed.
+ * src/libGLESv2/libGLESv2.cpp:
+ * src/libGLESv2/libGLESv2.def:
+ * src/libGLESv2/libGLESv2.vcproj:
+ * src/libGLESv2/utilities.cpp:
+ (gl::UniformComponentCount):
+ (gl::UniformComponentType):
+ (gl::ComputePixelSize):
+ (gl::CheckTextureFormatType):
+ (gl::IsColorRenderable):
+ (gl::IsDepthRenderable):
+ (gl::IsStencilRenderable):
+ (es2dx::GetAlphaSize):
+ (es2dx::GetRedSize):
+ (es2dx::GetGreenSize):
+ (es2dx::GetBlueSize):
+ (es2dx::GetDepthSize):
+ (es2dx::ConvertPrimitiveType):
+ (dx2es::ConvertBackBufferFormat):
+ (dx2es::ConvertDepthStencilFormat):
+ * src/libGLESv2/utilities.h:
+
2011-01-17 Dan Bernstein <mitz@apple.com>
Rubber-stamped by Mark Rowe.
diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
index e0a5cc8..d0664e4 100644
--- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
+++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h
@@ -14,6 +14,66 @@
#ifdef __cplusplus
extern "C" {
#endif
+
+// Version number for shader translation API.
+// It is incremented everytime the API changes.
+#define SH_VERSION 103
+
+//
+// The names of the following enums have been derived by replacing GL prefix
+// with SH. For example, SH_INFO_LOG_LENGTH is equivalent to GL_INFO_LOG_LENGTH.
+// The enum values are also equal to the values of their GL counterpart. This
+// is done to make it easier for applications to use the shader library.
+//
+typedef enum {
+ SH_FRAGMENT_SHADER = 0x8B30,
+ SH_VERTEX_SHADER = 0x8B31
+} ShShaderType;
+
+typedef enum {
+ SH_GLES2_SPEC = 0x8B40,
+ SH_WEBGL_SPEC = 0x8B41
+} ShShaderSpec;
+
+typedef enum {
+ SH_NONE = 0,
+ SH_INT = 0x1404,
+ SH_FLOAT = 0x1406,
+ SH_FLOAT_VEC2 = 0x8B50,
+ SH_FLOAT_VEC3 = 0x8B51,
+ SH_FLOAT_VEC4 = 0x8B52,
+ SH_INT_VEC2 = 0x8B53,
+ SH_INT_VEC3 = 0x8B54,
+ SH_INT_VEC4 = 0x8B55,
+ SH_BOOL = 0x8B56,
+ SH_BOOL_VEC2 = 0x8B57,
+ SH_BOOL_VEC3 = 0x8B58,
+ SH_BOOL_VEC4 = 0x8B59,
+ SH_FLOAT_MAT2 = 0x8B5A,
+ SH_FLOAT_MAT3 = 0x8B5B,
+ SH_FLOAT_MAT4 = 0x8B5C,
+ SH_SAMPLER_2D = 0x8B5E,
+ SH_SAMPLER_CUBE = 0x8B60
+} ShDataType;
+
+typedef enum {
+ SH_INFO_LOG_LENGTH = 0x8B84,
+ SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
+ SH_ACTIVE_UNIFORMS = 0x8B86,
+ SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
+ SH_ACTIVE_ATTRIBUTES = 0x8B89,
+ SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A
+} ShShaderInfo;
+
+// Compile options.
+typedef enum {
+ SH_VALIDATE = 0,
+ SH_VALIDATE_LOOP_INDEXING = 0x0001,
+ SH_INTERMEDIATE_TREE = 0x0002,
+ SH_OBJECT_CODE = 0x0004,
+ SH_ATTRIBUTES_UNIFORMS = 0x0008
+} ShCompileOptions;
+
//
// Driver must call this first, once, before doing any other
// compiler operations.
@@ -25,23 +85,6 @@ int ShInitialize();
// If the function succeeds, the return value is nonzero, else zero.
//
int ShFinalize();
-//
-// Types of languages the compiler can consume.
-//
-typedef enum {
- EShLangVertex,
- EShLangFragment,
- EShLangCount,
-} EShLanguage;
-
-//
-// The language specification compiler conforms to.
-// It currently supports OpenGL ES and WebGL specifications.
-//
-typedef enum {
- EShSpecGLES2,
- EShSpecWebGL,
-} EShSpec;
//
// Implementation dependent built-in resources (constants and extensions).
@@ -62,27 +105,12 @@ typedef struct
// Extensions.
// Set to 1 to enable the extension, else 0.
int OES_standard_derivatives;
-} TBuiltInResource;
+} ShBuiltInResources;
//
// Initialize built-in resources with minimum expected values.
//
-void ShInitBuiltInResource(TBuiltInResource* resources);
-
-//
-// Optimization level for the compiler.
-//
-typedef enum {
- EShOptNoGeneration,
- EShOptNone,
- EShOptSimple, // Optimizations that can be done quickly
- EShOptFull, // Optimizations that will take more time
-} EShOptimizationLevel;
-
-enum TDebugOptions {
- EDebugOpNone = 0x000,
- EDebugOpIntermediate = 0x001, // Writes intermediate tree into info-log.
-};
+void ShInitBuiltInResources(ShBuiltInResources* resources);
//
// ShHandle held by but opaque to the driver. It is allocated,
@@ -96,30 +124,130 @@ typedef void* ShHandle;
//
// Driver calls these to create and destroy compiler objects.
//
-ShHandle ShConstructCompiler(EShLanguage, EShSpec, const TBuiltInResource*);
-void ShDestruct(ShHandle);
+// Returns the handle of constructed compiler.
+// Parameters:
+// type: Specifies the type of shader - SH_FRAGMENT_SHADER or SH_VERTEX_SHADER.
+// spec: Specifies the language spec the compiler must conform to -
+// SH_GLES2_SPEC or SH_WEBGL_SPEC.
+// resources: Specifies the built-in resources.
+ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources* resources);
+void ShDestruct(ShHandle handle);
//
-// The return value of ShCompile is boolean, indicating
-// success or failure.
-//
-// The info-log should be written by ShCompile into
-// ShHandle, so it can answer future queries.
+// Compiles the given shader source.
+// If the function succeeds, the return value is nonzero, else zero.
+// Parameters:
+// handle: Specifies the handle of compiler to be used.
+// shaderStrings: Specifies an array of pointers to null-terminated strings
+// containing the shader source code.
+// numStrings: Specifies the number of elements in shaderStrings array.
+// compileOptions: A mask containing the following parameters:
+// SH_VALIDATE: Validates shader to ensure that it conforms to the spec
+// specified during compiler construction.
+// SH_VALIDATE_LOOP_INDEXING: Validates loop and indexing in the shader to
+// ensure that they do not exceed the minimum
+// functionality mandated in GLSL 1.0 spec,
+// Appendix A, Section 4 and 5.
+// There is no need to specify this parameter when
+// compiling for WebGL - it is implied.
+// SH_INTERMEDIATE_TREE: Writes intermediate tree to info log.
+// Can be queried by calling ShGetInfoLog().
+// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
+// Can be queried by calling ShGetObjectCode().
+// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
+// Can be queried by calling ShGetActiveAttrib() and
+// ShGetActiveUniform().
//
int ShCompile(
- const ShHandle,
+ const ShHandle handle,
const char* const shaderStrings[],
const int numStrings,
- const EShOptimizationLevel,
- int debugOptions
+ int compileOptions
);
-//
-// All the following return 0 if the information is not
-// available in the object passed down, or the object is bad.
-//
-const char* ShGetInfoLog(const ShHandle);
-const char* ShGetObjectCode(const ShHandle);
+// Returns a parameter from a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// pname: Specifies the parameter to query.
+// The following parameters are defined:
+// SH_INFO_LOG_LENGTH: the number of characters in the information log
+// including the null termination character.
+// SH_OBJECT_CODE_LENGTH: the number of characters in the object code
+// including the null termination character.
+// SH_ACTIVE_ATTRIBUTES: the number of active attribute variables.
+// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: the length of the longest active attribute
+// variable name including the null
+// termination character.
+// SH_ACTIVE_UNIFORMS: the number of active uniform variables.
+// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
+// variable name including the null
+// termination character.
+//
+// params: Requested parameter
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params);
+
+// Returns nul-terminated information log for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// infoLog: Specifies an array of characters that is used to return
+// the information log. It is assumed that infoLog has enough memory
+// to accomodate the information log. The size of the buffer required
+// to store the returned information log can be obtained by calling
+// ShGetInfo with SH_INFO_LOG_LENGTH.
+void ShGetInfoLog(const ShHandle handle, char* infoLog);
+
+// Returns null-terminated object code for a compiled shader.
+// Parameters:
+// handle: Specifies the compiler
+// infoLog: Specifies an array of characters that is used to return
+// the object code. It is assumed that infoLog has enough memory to
+// accomodate the object code. The size of the buffer required to
+// store the returned object code can be obtained by calling
+// ShGetInfo with SH_OBJECT_CODE_LENGTH.
+void ShGetObjectCode(const ShHandle handle, char* objCode);
+
+// Returns information about an active attribute variable.
+// Parameters:
+// handle: Specifies the compiler
+// index: Specifies the index of the attribute variable to be queried.
+// length: Returns the number of characters actually written in the string
+// indicated by name (excluding the null terminator) if a value other
+// than NULL is passed.
+// size: Returns the size of the attribute variable.
+// type: Returns the data type of the attribute variable.
+// name: Returns a null terminated string containing the name of the
+// attribute variable. It is assumed that name has enough memory to
+// accomodate the attribute variable name. The size of the buffer
+// required to store the attribute variable name can be obtained by
+// calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
+void ShGetActiveAttrib(const ShHandle handle,
+ int index,
+ int* length,
+ int* size,
+ ShDataType* type,
+ char* name);
+
+// Returns information about an active uniform variable.
+// Parameters:
+// handle: Specifies the compiler
+// index: Specifies the index of the uniform variable to be queried.
+// length: Returns the number of characters actually written in the string
+// indicated by name (excluding the null terminator) if a value
+// other than NULL is passed.
+// size: Returns the size of the uniform variable.
+// type: Returns the data type of the uniform variable.
+// name: Returns a null terminated string containing the name of the
+// uniform variable. It is assumed that name has enough memory to
+// accomodate the uniform variable name. The size of the buffer required
+// to store the uniform variable name can be obtained by calling
+// ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
+void ShGetActiveUniform(const ShHandle handle,
+ int index,
+ int* length,
+ int* size,
+ ShDataType* type,
+ char* name);
#ifdef __cplusplus
}
diff --git a/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj
index f118435..67f7e29 100644
--- a/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj
+++ b/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj
@@ -35,7 +35,6 @@
/* Begin PBXBuildFile section */
05563ADFEA15116D7233332F /* QualifierAlive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4857E18799D332C30EF460C7 /* QualifierAlive.cpp */; };
0A216949103E1E228F9C12F0 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */; };
- 0D4064167398A6892809A09E /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53D169CB849B861E15DF99A /* glslang_tab.cpp */; };
3065D29E97FAC6E127388D15 /* Initialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */; };
32B1DBCD6B83F2146D787A62 /* atom.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C9B4616A65A5ABEF91FD6DC /* atom.c */; };
35BE1BBEE6135A1CB0608EA8 /* cppstruct.c in Sources */ = {isa = PBXBuildFile; fileRef = 8058A0A2A0A02386867517EA /* cppstruct.c */; };
@@ -45,7 +44,6 @@
6F9F875017A68ABE5D39FF19 /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 976C831A75EBE009A9861796 /* ParseHelper.cpp */; };
888F1382498E2D74AF2801C8 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ABA230FEA3654B030E4C4FB /* debug.cpp */; };
9E8DFE1CCEF038BF2B65428C /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */; };
- ABA5C61B1B78B9A8D69F6AEC /* glslang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB1F91D3D8CC446F35B00D1B /* glslang.cpp */; };
AC23F58FDD3C55F5CA18EED7 /* RemoveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */; };
AD85517F086FDCEF3947C403 /* symbols.c in Sources */ = {isa = PBXBuildFile; fileRef = F013A7240BDAE8A61413D8C0 /* symbols.c */; };
B4858417E54365BE8CDE3919 /* ossource_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE258486005F6696CC031622 /* ossource_posix.cpp */; };
@@ -60,8 +58,6 @@
FB3C505711F7924A0081F5BA /* CodeGenGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B7B1127C75B576FC00D74AED /* CodeGenGLSL.cpp */; };
FB3C505811F7924A0081F5BA /* OutputGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 48B7402CC07A059FEF5EC351 /* OutputGLSL.cpp */; };
FB3C505911F7924A0081F5BA /* TranslatorGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6FB70DC74A21FBCD665ABDF9 /* TranslatorGLSL.cpp */; };
- FB3C508E11F7949E0081F5BA /* glslang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB1F91D3D8CC446F35B00D1B /* glslang.cpp */; };
- FB3C508F11F7949E0081F5BA /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A53D169CB849B861E15DF99A /* glslang_tab.cpp */; };
FB3C509211F794CE0081F5BA /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ABA230FEA3654B030E4C4FB /* debug.cpp */; };
FB3C509311F794CE0081F5BA /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E6927BE5D3C2C82F86111DF /* InfoSink.cpp */; };
FB3C509411F794CE0081F5BA /* Initialize.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */; };
@@ -133,6 +129,10 @@
5A21599C59BC1A75A7FABA34 /* OutputHLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputHLSL.h; sourceTree = "<group>"; };
60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = "<group>"; };
6BBC8224B9D8E234D117FA0C /* preprocess.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = preprocess.h; sourceTree = "<group>"; };
+ 6E02565112E6934D00B3431F /* glslang_lex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_lex.cpp; sourceTree = "<group>"; };
+ 6E02565212E6934D00B3431F /* glslang_tab.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = "<group>"; };
+ 6E02565312E6934D00B3431F /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang_tab.h; sourceTree = "<group>"; };
+ 6E02565412E6934D00B3431F /* glslang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = glslang.h; sourceTree = "<group>"; };
6E6927BE5D3C2C82F86111DF /* InfoSink.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InfoSink.cpp; sourceTree = "<group>"; };
6FB70DC74A21FBCD665ABDF9 /* TranslatorGLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorGLSL.cpp; sourceTree = "<group>"; };
799DC9611EE2EA3BA7CF5477 /* intermediate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = intermediate.h; sourceTree = "<group>"; };
@@ -143,7 +143,6 @@
8513FAC699DB1558D1D49A48 /* Initialize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Initialize.h; sourceTree = "<group>"; };
85845FFF5A8E63364308236D /* InitializeParseContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeParseContext.h; sourceTree = "<group>"; };
89A6F7B1AD3918E64DF76EB1 /* slglobals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = slglobals.h; sourceTree = "<group>"; };
- 8C3225C2F8C3573CD9725E66 /* glslang.y */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.yacc; path = glslang.y; sourceTree = "<group>"; };
93D61CB0BCE54E069D71F920 /* OutputGLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputGLSL.h; sourceTree = "<group>"; };
95276AA6B36FC1B1D913FCE4 /* debug.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = "<group>"; };
976C831A75EBE009A9861796 /* ParseHelper.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ParseHelper.cpp; sourceTree = "<group>"; };
@@ -151,8 +150,6 @@
9CED3AFF1E61B45EE1005656 /* atom.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = atom.h; sourceTree = "<group>"; };
9D47B1AC82E4EE859AC54243 /* QualifierAlive.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = QualifierAlive.h; sourceTree = "<group>"; };
A0CE43631849276A31187C7B /* InitializeDll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = "<group>"; };
- A3153D58F4BBBD98A84E4210 /* glslang.l */ = {isa = PBXFileReference; lastKnownFileType = text; path = glslang.l; sourceTree = "<group>"; };
- A53D169CB849B861E15DF99A /* glslang_tab.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = "<group>"; };
A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Initialize.cpp; sourceTree = "<group>"; };
AA53B6632C76F905DF08E564 /* Types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; };
AE65E139AE10DE9EFAD8D5B1 /* ShHandle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ShHandle.h; sourceTree = "<group>"; };
@@ -163,13 +160,11 @@
B75707B393B7EAB7DD9999CB /* cpp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cpp.c; sourceTree = "<group>"; };
B7B1127C75B576FC00D74AED /* CodeGenGLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenGLSL.cpp; sourceTree = "<group>"; };
B7E5B0F04635E6090F0DE8EF /* SymbolTable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolTable.cpp; sourceTree = "<group>"; };
- BC66D6B47D9AF3286644BBE1 /* glslang_tab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glslang_tab.h; sourceTree = "<group>"; };
BE258486005F6696CC031622 /* ossource_posix.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ossource_posix.cpp; sourceTree = "<group>"; };
C3DAFF6BF12BB7F4784D6C7E /* TranslatorHLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorHLSL.cpp; sourceTree = "<group>"; };
C49549DCCAF450EB761520E1 /* CodeGenHLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGenHLSL.cpp; sourceTree = "<group>"; };
C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IntermTraverse.cpp; sourceTree = "<group>"; };
C8BD59BD7056FFC21373C50A /* osinclude.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = osinclude.h; sourceTree = "<group>"; };
- CB1F91D3D8CC446F35B00D1B /* glslang.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = glslang.cpp; sourceTree = "<group>"; };
CEE0C90DF6D504D1F3629711 /* ParseHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ParseHelper.h; sourceTree = "<group>"; };
CF2B62E0820C831AF812D000 /* build_angle.gyp */ = {isa = PBXFileReference; lastKnownFileType = text; path = build_angle.gyp; sourceTree = "<group>"; };
CFD12C6E46EBE0839BBE52B5 /* parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
@@ -233,6 +228,10 @@
196DB6AB006BB83503C7D786 /* Source */ = {
isa = PBXGroup;
children = (
+ 6E02565112E6934D00B3431F /* glslang_lex.cpp */,
+ 6E02565212E6934D00B3431F /* glslang_tab.cpp */,
+ 6E02565312E6934D00B3431F /* glslang_tab.h */,
+ 6E02565412E6934D00B3431F /* glslang.h */,
0E8D65F584FDB84DAABD3969 /* preprocessor */,
27E4C7ED0B82E18DCBEDF1C9 /* BaseTypes.h */,
B7B1127C75B576FC00D74AED /* CodeGenGLSL.cpp */,
@@ -275,8 +274,6 @@
2A765B86CBAF0D4A3E69DCA7 /* UnfoldSelect.h */,
4ABA230FEA3654B030E4C4FB /* debug.cpp */,
95276AA6B36FC1B1D913FCE4 /* debug.h */,
- A3153D58F4BBBD98A84E4210 /* glslang.l */,
- 8C3225C2F8C3573CD9725E66 /* glslang.y */,
DEAF6F3126C2EC4397785C3F /* intermOut.cpp */,
799DC9611EE2EA3BA7CF5477 /* intermediate.h */,
153BF06BF12C6F50496C6156 /* localintermediate.h */,
@@ -289,21 +286,10 @@
path = compiler;
sourceTree = "<group>";
};
- 466E1D0531A79B5813E8A7F8 /* Intermediates */ = {
- isa = PBXGroup;
- children = (
- CB1F91D3D8CC446F35B00D1B /* glslang.cpp */,
- A53D169CB849B861E15DF99A /* glslang_tab.cpp */,
- BC66D6B47D9AF3286644BBE1 /* glslang_tab.h */,
- );
- name = Intermediates;
- sourceTree = INTERMEDIATE_DIR;
- };
5BBEFF9B91738297B95C568D = {
isa = PBXGroup;
children = (
196DB6AB006BB83503C7D786 /* Source */,
- 466E1D0531A79B5813E8A7F8 /* Intermediates */,
E0EDC4130E7D374318CE72BE /* Products */,
B2C184C3543198BA51592EA4 /* Build */,
);
@@ -373,7 +359,6 @@
};
buildConfigurationList = 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */;
compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
@@ -457,8 +442,6 @@
F098F463EDABCF0769007678 /* scanner.c in Sources */,
AD85517F086FDCEF3947C403 /* symbols.c in Sources */,
E8C727AA8E9DC5E7B58857DF /* tokens.c in Sources */,
- ABA5C61B1B78B9A8D69F6AEC /* glslang.cpp in Sources */,
- 0D4064167398A6892809A09E /* glslang_tab.cpp in Sources */,
B4858417E54365BE8CDE3919 /* ossource_posix.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -476,7 +459,6 @@
FB3C50A811F794FF0081F5BA /* scanner.c in Sources */,
FB3C50A911F794FF0081F5BA /* symbols.c in Sources */,
FB3C50AA11F794FF0081F5BA /* tokens.c in Sources */,
- FB3C508E11F7949E0081F5BA /* glslang.cpp in Sources */,
FB3C505711F7924A0081F5BA /* CodeGenGLSL.cpp in Sources */,
FB3C509211F794CE0081F5BA /* debug.cpp in Sources */,
FB3C509311F794CE0081F5BA /* InfoSink.cpp in Sources */,
@@ -495,7 +477,6 @@
FB3C50A011F794CE0081F5BA /* ShaderLang.cpp in Sources */,
FB3C50A111F794CE0081F5BA /* SymbolTable.cpp in Sources */,
FB3C505911F7924A0081F5BA /* TranslatorGLSL.cpp in Sources */,
- FB3C508F11F7949E0081F5BA /* glslang_tab.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Source/ThirdParty/ANGLE/src/common/debug.cpp b/Source/ThirdParty/ANGLE/src/common/debug.cpp
index d8d6ab8..3de5d4e 100644
--- a/Source/ThirdParty/ANGLE/src/common/debug.cpp
+++ b/Source/ThirdParty/ANGLE/src/common/debug.cpp
@@ -11,17 +11,22 @@
#include <stdio.h>
#include <stdarg.h>
+#ifndef TRACE_OUTPUT_FILE
+#define TRACE_OUTPUT_FILE "debug.txt"
+#endif
+
static bool trace_on = true;
namespace gl
{
void trace(const char *format, ...)
{
+#if !defined(ANGLE_DISABLE_TRACE)
if (trace_on)
{
if (format)
{
- FILE *file = fopen("debug.txt", "a");
+ FILE *file = fopen(TRACE_OUTPUT_FILE, "a");
if (file)
{
@@ -34,5 +39,6 @@ void trace(const char *format, ...)
}
}
}
+#endif // !defined(ANGLE_DISABLE_TRACE)
}
}
diff --git a/Source/ThirdParty/ANGLE/src/common/debug.h b/Source/ThirdParty/ANGLE/src/common/debug.h
index 9a5135b..2c4ec70 100644
--- a/Source/ThirdParty/ANGLE/src/common/debug.h
+++ b/Source/ThirdParty/ANGLE/src/common/debug.h
@@ -19,7 +19,7 @@ namespace gl
}
// A macro to output a trace of a function call and its arguments to the debugging log
-#ifndef NDEBUG
+#if !defined(NDEBUG) && !defined(ANGLE_DISABLE_TRACE)
#define TRACE(message, ...) gl::trace("trace: %s"message"\n", __FUNCTION__, __VA_ARGS__)
#else
#define TRACE(...) ((void)0)
diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
index 855b092..d140b37 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp
@@ -11,9 +11,9 @@
// compile object used by higher level code. It returns
// a subclass of TCompiler.
//
-TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
{
- return new TranslatorGLSL(language, spec);
+ return new TranslatorGLSL(type, spec);
}
//
diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
index 4db771d..e04e789 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp
@@ -11,9 +11,9 @@
// compile object used by higher level code. It returns
// a subclass of TCompiler.
//
-TCompiler* ConstructCompiler(EShLanguage language, EShSpec spec)
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec)
{
- return new TranslatorHLSL(language, spec);
+ return new TranslatorHLSL(type, spec);
}
//
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Common.h b/Source/ThirdParty/ANGLE/src/compiler/Common.h
index 65d0a51..27a5598 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Common.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Common.h
@@ -14,9 +14,24 @@
#include "compiler/PoolAlloc.h"
+// We need two pieces of information to report errors/warnings - string and
+// line number. We encode these into a single int so that it can be easily
+// incremented/decremented by lexer. The right SOURCE_LOC_LINE_SIZE bits store
+// line number while the rest store the string number. Since the shaders are
+// usually small, we should not run out of memory. SOURCE_LOC_LINE_SIZE
+// can be increased to alleviate this issue.
typedef int TSourceLoc;
-const unsigned int SourceLocLineMask = 0xffff;
-const unsigned int SourceLocStringShift = 16;
+const unsigned int SOURCE_LOC_LINE_SIZE = 16; // in bits.
+const unsigned int SOURCE_LOC_LINE_MASK = (1 << SOURCE_LOC_LINE_SIZE) - 1;
+
+inline TSourceLoc EncodeSourceLoc(int string, int line) {
+ return (string << SOURCE_LOC_LINE_SIZE) | (line & SOURCE_LOC_LINE_MASK);
+}
+
+inline void DecodeSourceLoc(TSourceLoc loc, int* string, int* line) {
+ if (string) *string = loc >> SOURCE_LOC_LINE_SIZE;
+ if (line) *line = loc & SOURCE_LOC_LINE_MASK;
+}
//
// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
@@ -71,6 +86,4 @@ public:
TMap(const tAllocator& a) : std::map<K, D, CMP, tAllocator>(std::map<K, D, CMP, tAllocator>::key_compare(), a) {}
};
-typedef TMap<TString, TString> TPragmaTable;
-
#endif // _COMMON_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
new file mode 100644
index 0000000..649b457
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
@@ -0,0 +1,189 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/Initialize.h"
+#include "compiler/ParseHelper.h"
+#include "compiler/ShHandle.h"
+#include "compiler/ValidateLimitations.h"
+
+namespace {
+bool InitializeSymbolTable(
+ const TBuiltInStrings& builtInStrings,
+ ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
+ TInfoSink& infoSink, TSymbolTable& symbolTable)
+{
+ TIntermediate intermediate(infoSink);
+ TExtensionBehavior extBehavior;
+ TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
+
+ GlobalParseContext = &parseContext;
+
+ assert(symbolTable.isEmpty());
+ //
+ // Parse the built-ins. This should only happen once per
+ // language symbol table.
+ //
+ // Push the symbol table to give it an initial scope. This
+ // push should not have a corresponding pop, so that built-ins
+ // are preserved, and the test for an empty table fails.
+ //
+ symbolTable.push();
+
+ for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
+ {
+ const char* builtInShaders = i->c_str();
+ int builtInLengths = static_cast<int>(i->size());
+ if (builtInLengths <= 0)
+ continue;
+
+ if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
+ {
+ infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
+ return false;
+ }
+ }
+
+ IdentifyBuiltIns(type, spec, resources, symbolTable);
+
+ return true;
+}
+
+class TScopedPoolAllocator {
+public:
+ TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
+ : mAllocator(allocator), mPushPopAllocator(pushPop) {
+ if (mPushPopAllocator) mAllocator->push();
+ SetGlobalPoolAllocator(mAllocator);
+ }
+ ~TScopedPoolAllocator() {
+ SetGlobalPoolAllocator(NULL);
+ if (mPushPopAllocator) mAllocator->pop();
+ }
+
+private:
+ TPoolAllocator* mAllocator;
+ bool mPushPopAllocator;
+};
+} // namespace
+
+TShHandleBase::TShHandleBase() {
+ allocator.push();
+ SetGlobalPoolAllocator(&allocator);
+}
+
+TShHandleBase::~TShHandleBase() {
+ SetGlobalPoolAllocator(NULL);
+ allocator.popAll();
+}
+
+TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
+ : shaderType(type),
+ shaderSpec(spec)
+{
+}
+
+TCompiler::~TCompiler()
+{
+}
+
+bool TCompiler::Init(const ShBuiltInResources& resources)
+{
+ TScopedPoolAllocator scopedAlloc(&allocator, false);
+
+ // Generate built-in symbol table.
+ if (!InitBuiltInSymbolTable(resources))
+ return false;
+ InitExtensionBehavior(resources, extensionBehavior);
+
+ return true;
+}
+
+bool TCompiler::compile(const char* const shaderStrings[],
+ const int numStrings,
+ int compileOptions)
+{
+ TScopedPoolAllocator scopedAlloc(&allocator, true);
+ clearResults();
+
+ if (numStrings == 0)
+ return true;
+
+ // If compiling for WebGL, validate loop and indexing as well.
+ if (shaderSpec == SH_WEBGL_SPEC)
+ compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+
+ TIntermediate intermediate(infoSink);
+ TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
+ shaderType, shaderSpec, infoSink);
+ GlobalParseContext = &parseContext;
+
+ // We preserve symbols at the built-in level from compile-to-compile.
+ // Start pushing the user-defined symbols at global level.
+ symbolTable.push();
+ if (!symbolTable.atGlobalLevel())
+ infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
+
+ // Parse shader.
+ bool success =
+ (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) &&
+ (parseContext.treeRoot != NULL);
+ if (success) {
+ TIntermNode* root = parseContext.treeRoot;
+ success = intermediate.postProcess(root);
+
+ if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
+ success = validateLimitations(root);
+
+ if (success && (compileOptions & SH_INTERMEDIATE_TREE))
+ intermediate.outputTree(root);
+
+ if (success && (compileOptions & SH_OBJECT_CODE))
+ translate(root);
+
+ if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
+ collectAttribsUniforms(root);
+ }
+
+ // Cleanup memory.
+ intermediate.remove(parseContext.treeRoot);
+ // Ensure symbol table is returned to the built-in level,
+ // throwing away all but the built-ins.
+ while (!symbolTable.atBuiltInLevel())
+ symbolTable.pop();
+
+ return success;
+}
+
+bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
+{
+ TBuiltIns builtIns;
+
+ builtIns.initialize(shaderType, shaderSpec, resources);
+ return InitializeSymbolTable(builtIns.getBuiltInStrings(),
+ shaderType, shaderSpec, resources, infoSink, symbolTable);
+}
+
+void TCompiler::clearResults()
+{
+ infoSink.info.erase();
+ infoSink.obj.erase();
+ infoSink.debug.erase();
+
+ attribs.clear();
+ uniforms.clear();
+}
+
+bool TCompiler::validateLimitations(TIntermNode* root) {
+ ValidateLimitations validate(shaderType, infoSink.info);
+ root->traverse(&validate);
+ return validate.numErrors() == 0;
+}
+
+void TCompiler::collectAttribsUniforms(TIntermNode* root)
+{
+ CollectAttribsUniforms collect(attribs, uniforms);
+ root->traverse(&collect);
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h
new file mode 100644
index 0000000..da96c24
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
+#define _EXTENSION_BEHAVIOR_INCLUDED_
+
+#include "compiler/Common.h"
+
+typedef enum {
+ EBhRequire,
+ EBhEnable,
+ EBhWarn,
+ EBhDisable
+} TBehavior;
+
+typedef TMap<TString, TBehavior> TExtensionBehavior;
+
+#endif // _EXTENSION_TABLE_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
index 317a88f..ba32f78 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.cpp
@@ -32,8 +32,8 @@ void TInfoSinkBase::prefix(TPrefixType message) {
}
void TInfoSinkBase::location(TSourceLoc loc) {
- int string = loc >> SourceLocStringShift;
- int line = loc & SourceLocLineMask;
+ int string = 0, line = 0;
+ DecodeSourceLoc(loc, &string, &line);
TPersistStringStream stream;
if (line)
diff --git a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
index 4762778..e2224e9 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/InfoSink.h
@@ -91,6 +91,7 @@ public:
}
void erase() { sink.clear(); }
+ int size() { return static_cast<int>(sink.size()); }
const TPersistString& str() const { return sink; }
const char* c_str() const { return sink.c_str(); }
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
index 6bfcf4f..12b53fe 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp
@@ -311,15 +311,6 @@ static TString BuiltInFunctionsCommon()
s.append(TString("bvec4 not(bvec4 x);"));
//
- // Texture Functions.
- //
- s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
- s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
-
- s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
-
- //
// Noise functions.
//
//s.append(TString("float noise1(float x);"));
@@ -342,7 +333,6 @@ static TString BuiltInFunctionsCommon()
//s.append(TString("vec4 noise4(vec3 x);"));
//s.append(TString("vec4 noise4(vec4 x);"));
- s.append(TString("\n"));
return s;
}
@@ -351,7 +341,7 @@ static TString BuiltInFunctionsCommon()
// Prototypes for built-in functions seen by vertex shaders only.
//
//============================================================================
-static TString BuiltInFunctionsVertex()
+static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources)
{
TString s;
@@ -363,12 +353,18 @@ static TString BuiltInFunctionsVertex()
//
// Texture Functions.
//
- s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
- s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
- s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+ if (resources.MaxVertexTextureImageUnits > 0) {
+ s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+ s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
+
+ s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);"));
+ s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);"));
+ s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);"));
+ s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);"));
+ }
- s.append(TString("\n"));
return s;
}
@@ -377,34 +373,40 @@ static TString BuiltInFunctionsVertex()
// Prototypes for built-in functions seen by fragment shaders only.
//
//============================================================================
-static TString BuiltInFunctionsFragment()
+static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources)
{
TString s;
//
// Texture Functions.
//
+ s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);"));
+ s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);"));
+ s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);"));
+
s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);"));
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);"));
s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);"));
s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);"));
- //s.append(TString("float dFdx(float p);"));
- //s.append(TString("vec2 dFdx(vec2 p);"));
- //s.append(TString("vec3 dFdx(vec3 p);"));
- //s.append(TString("vec4 dFdx(vec4 p);"));
-
- //s.append(TString("float dFdy(float p);"));
- //s.append(TString("vec2 dFdy(vec2 p);"));
- //s.append(TString("vec3 dFdy(vec3 p);"));
- //s.append(TString("vec4 dFdy(vec4 p);"));
-
- s.append(TString("float fwidth(float p);"));
- s.append(TString("vec2 fwidth(vec2 p);"));
- s.append(TString("vec3 fwidth(vec3 p);"));
- s.append(TString("vec4 fwidth(vec4 p);"));
+ if (resources.OES_standard_derivatives) {
+ s.append(TString("float dFdx(float p);"));
+ s.append(TString("vec2 dFdx(vec2 p);"));
+ s.append(TString("vec3 dFdx(vec3 p);"));
+ s.append(TString("vec4 dFdx(vec4 p);"));
+
+ s.append(TString("float dFdy(float p);"));
+ s.append(TString("vec2 dFdy(vec2 p);"));
+ s.append(TString("vec3 dFdy(vec3 p);"));
+ s.append(TString("vec4 dFdy(vec4 p);"));
+
+ s.append(TString("float fwidth(float p);"));
+ s.append(TString("vec2 fwidth(vec2 p);"));
+ s.append(TString("vec3 fwidth(vec3 p);"));
+ s.append(TString("vec4 fwidth(vec4 p);"));
+ }
- s.append(TString("\n"));
return s;
}
@@ -427,7 +429,6 @@ static TString StandardUniforms()
s.append(TString("};"));
s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;"));
- s.append(TString("\n"));
return s;
}
@@ -443,7 +444,6 @@ static TString DefaultPrecisionVertex()
s.append(TString("precision highp int;"));
s.append(TString("precision highp float;"));
- s.append(TString("\n"));
return s;
}
@@ -459,7 +459,6 @@ static TString DefaultPrecisionFragment()
s.append(TString("precision mediump int;"));
// No default precision for float in fragment shaders
- s.append(TString("\n"));
return s;
}
@@ -468,7 +467,7 @@ static TString DefaultPrecisionFragment()
// Implementation dependent built-in constants.
//
//============================================================================
-static TString BuiltInConstants(const TBuiltInResource &resources)
+static TString BuiltInConstants(const ShBuiltInResources &resources)
{
TStringStream s;
@@ -485,20 +484,21 @@ static TString BuiltInConstants(const TBuiltInResource &resources)
return s.str();
}
-void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources)
+void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources& resources)
{
- switch (language) {
- case EShLangFragment:
+ switch (type) {
+ case SH_FRAGMENT_SHADER:
builtInStrings.push_back(DefaultPrecisionFragment());
builtInStrings.push_back(BuiltInFunctionsCommon());
- builtInStrings.push_back(BuiltInFunctionsFragment());
+ builtInStrings.push_back(BuiltInFunctionsFragment(resources));
builtInStrings.push_back(StandardUniforms());
break;
- case EShLangVertex:
+ case SH_VERTEX_SHADER:
builtInStrings.push_back(DefaultPrecisionVertex());
builtInStrings.push_back(BuiltInFunctionsCommon());
- builtInStrings.push_back(BuiltInFunctionsVertex());
+ builtInStrings.push_back(BuiltInFunctionsVertex(resources));
builtInStrings.push_back(StandardUniforms());
break;
@@ -508,14 +508,16 @@ void TBuiltIns::initialize(EShLanguage language, EShSpec spec, const TBuiltInRes
builtInStrings.push_back(BuiltInConstants(resources));
}
-void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources, TSymbolTable& symbolTable)
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources& resources,
+ TSymbolTable& symbolTable)
{
//
// First, insert some special built-in variables that are not in
// the built-in header files.
//
- switch(language) {
- case EShLangFragment:
+ switch(type) {
+ case SH_FRAGMENT_SHADER:
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
@@ -523,7 +525,7 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
break;
- case EShLangVertex:
+ case SH_VERTEX_SHADER:
symbolTable.insert(*new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
symbolTable.insert(*new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
break;
@@ -591,20 +593,26 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
symbolTable.relateToOperator("all", EOpAll);
// Map language-specific operators.
- switch(language) {
- case EShLangVertex:
+ switch(type) {
+ case SH_VERTEX_SHADER:
break;
- case EShLangFragment:
- //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
+ case SH_FRAGMENT_SHADER:
+ if (resources.OES_standard_derivatives) {
+ symbolTable.relateToOperator("dFdx", EOpDFdx);
+ symbolTable.relateToOperator("dFdy", EOpDFdy);
+ symbolTable.relateToOperator("fwidth", EOpFwidth);
+
+ symbolTable.relateToExtension("dFdx", "GL_OES_standard_derivatives");
+ symbolTable.relateToExtension("dFdy", "GL_OES_standard_derivatives");
+ symbolTable.relateToExtension("fwidth", "GL_OES_standard_derivatives");
+ }
break;
default: break;
}
// Finally add resource-specific variables.
- switch(language) {
- case EShLangFragment: {
+ switch(type) {
+ case SH_FRAGMENT_SHADER: {
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
fragData.setArraySize(resources.MaxDrawBuffers);
@@ -615,3 +623,9 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
}
}
+void InitExtensionBehavior(const ShBuiltInResources& resources,
+ TExtensionBehavior& extBehavior)
+{
+ if (resources.OES_standard_derivatives)
+ extBehavior["GL_OES_standard_derivatives"] = EBhDisable;
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.h b/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
index c078659..8b0adc6 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.h
@@ -17,17 +17,19 @@ class TBuiltIns {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- void initialize(EShLanguage language, EShSpec spec, const TBuiltInResource& resources);
+ void initialize(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources& resources);
const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; }
protected:
TBuiltInStrings builtInStrings;
};
-void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources& resources,
TSymbolTable& symbolTable);
-extern "C" int InitPreprocessor(void);
-extern "C" int FinalizePreprocessor(void);
+void InitExtensionBehavior(const ShBuiltInResources& resources,
+ TExtensionBehavior& extensionBehavior);
#endif // _INITIALIZE_INCLUDED_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp b/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
index 34a6f3c..a13877f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/IntermTraverse.cpp
@@ -229,9 +229,9 @@ void TIntermLoop::traverse(TIntermTraverser* it)
if(it->rightToLeft)
{
- if(terminal)
+ if(expr)
{
- terminal->traverse(it);
+ expr->traverse(it);
}
if(body)
@@ -239,16 +239,16 @@ void TIntermLoop::traverse(TIntermTraverser* it)
body->traverse(it);
}
- if(test)
+ if(cond)
{
- test->traverse(it);
+ cond->traverse(it);
}
}
else
{
- if(test)
+ if(cond)
{
- test->traverse(it);
+ cond->traverse(it);
}
if(body)
@@ -256,9 +256,9 @@ void TIntermLoop::traverse(TIntermTraverser* it)
body->traverse(it);
}
- if(terminal)
+ if(expr)
{
- terminal->traverse(it);
+ expr->traverse(it);
}
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
index 5ebd919..ea71234 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp
@@ -22,6 +22,101 @@ static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
return left > right ? left : right;
}
+const char* getOperatorString(TOperator op) {
+ switch (op) {
+ case EOpInitialize: return "=";
+ case EOpAssign: return "=";
+ case EOpAddAssign: return "+=";
+ case EOpSubAssign: return "-=";
+ case EOpDivAssign: return "/=";
+
+ // Fall-through.
+ case EOpMulAssign:
+ case EOpVectorTimesMatrixAssign:
+ case EOpVectorTimesScalarAssign:
+ case EOpMatrixTimesScalarAssign:
+ case EOpMatrixTimesMatrixAssign: return "*=";
+
+ // Fall-through.
+ case EOpIndexDirect:
+ case EOpIndexIndirect: return "[]";
+
+ case EOpIndexDirectStruct: return ".";
+ case EOpVectorSwizzle: return ".";
+ case EOpAdd: return "+";
+ case EOpSub: return "-";
+ case EOpMul: return "*";
+ case EOpDiv: return "/";
+ case EOpMod: UNIMPLEMENTED(); break;
+ case EOpEqual: return "==";
+ case EOpNotEqual: return "!=";
+ case EOpLessThan: return "<";
+ case EOpGreaterThan: return ">";
+ case EOpLessThanEqual: return "<=";
+ case EOpGreaterThanEqual: return ">=";
+
+ // Fall-through.
+ case EOpVectorTimesScalar:
+ case EOpVectorTimesMatrix:
+ case EOpMatrixTimesVector:
+ case EOpMatrixTimesScalar:
+ case EOpMatrixTimesMatrix: return "*";
+
+ case EOpLogicalOr: return "||";
+ case EOpLogicalXor: return "^^";
+ case EOpLogicalAnd: return "&&";
+ case EOpNegative: return "-";
+ case EOpVectorLogicalNot: return "not";
+ case EOpLogicalNot: return "!";
+ case EOpPostIncrement: return "++";
+ case EOpPostDecrement: return "--";
+ case EOpPreIncrement: return "++";
+ case EOpPreDecrement: return "--";
+
+ // Fall-through.
+ case EOpConvIntToBool:
+ case EOpConvFloatToBool: return "bool";
+
+ // Fall-through.
+ case EOpConvBoolToFloat:
+ case EOpConvIntToFloat: return "float";
+
+ // Fall-through.
+ case EOpConvFloatToInt:
+ case EOpConvBoolToInt: return "int";
+
+ case EOpRadians: return "radians";
+ case EOpDegrees: return "degrees";
+ case EOpSin: return "sin";
+ case EOpCos: return "cos";
+ case EOpTan: return "tan";
+ case EOpAsin: return "asin";
+ case EOpAcos: return "acos";
+ case EOpAtan: return "atan";
+ case EOpExp: return "exp";
+ case EOpLog: return "log";
+ case EOpExp2: return "exp2";
+ case EOpLog2: return "log2";
+ case EOpSqrt: return "sqrt";
+ case EOpInverseSqrt: return "inversesqrt";
+ case EOpAbs: return "abs";
+ case EOpSign: return "sign";
+ case EOpFloor: return "floor";
+ case EOpCeil: return "ceil";
+ case EOpFract: return "fract";
+ case EOpLength: return "length";
+ case EOpNormalize: return "normalize";
+ case EOpDFdx: return "dFdx";
+ case EOpDFdy: return "dFdy";
+ case EOpFwidth: return "fwidth";
+ case EOpAny: return "any";
+ case EOpAll: return "all";
+
+ default: break;
+ }
+ return "";
+}
+
////////////////////////////////////////////////////////////////////////////
//
// First set of functions are to help build the intermediate representation.
@@ -51,18 +146,23 @@ TIntermSymbol* TIntermediate::addSymbol(int id, const TString& name, const TType
TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable)
{
switch (op) {
+ case EOpEqual:
+ case EOpNotEqual:
+ if (left->isArray())
+ return 0;
+ break;
case EOpLessThan:
case EOpGreaterThan:
case EOpLessThanEqual:
case EOpGreaterThanEqual:
- if (left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector() || left->getType().getBasicType() == EbtStruct) {
+ if (left->isMatrix() || left->isArray() || left->isVector() || left->getBasicType() == EbtStruct) {
return 0;
}
break;
case EOpLogicalOr:
case EOpLogicalXor:
case EOpLogicalAnd:
- if (left->getType().getBasicType() != EbtBool || left->getType().isMatrix() || left->getType().isArray() || left->getType().isVector()) {
+ if (left->getBasicType() != EbtBool || left->isMatrix() || left->isArray() || left->isVector()) {
return 0;
}
break;
@@ -70,7 +170,7 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
case EOpSub:
case EOpDiv:
case EOpMul:
- if (left->getType().getBasicType() == EbtStruct || left->getType().getBasicType() == EbtBool)
+ if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
return 0;
default: break;
}
@@ -78,8 +178,10 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
//
// First try converting the children to compatible types.
//
-
- if (!(left->getType().getStruct() && right->getType().getStruct())) {
+ if (left->getType().getStruct() && right->getType().getStruct()) {
+ if (left->getType() != right->getType())
+ return 0;
+ } else {
TIntermTyped* child = addConversion(op, left->getType(), right);
if (child)
right = child;
@@ -90,12 +192,8 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
else
return 0;
}
- } else {
- if (left->getType() != right->getType())
- return 0;
}
-
//
// Need a new node holding things together then. Make
// one and promote it to the right type.
@@ -107,18 +205,16 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
node->setLeft(left);
node->setRight(right);
- if (! node->promote(infoSink))
+ if (!node->promote(infoSink))
return 0;
- TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
- TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
-
//
// See if we can fold constants.
//
-
TIntermTyped* typedReturnNode = 0;
- if ( leftTempConstant && rightTempConstant) {
+ TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
+ TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
+ if (leftTempConstant && rightTempConstant) {
typedReturnNode = leftTempConstant->fold(node->getOp(), rightTempConstant, infoSink);
if (typedReturnNode)
@@ -602,9 +698,9 @@ TIntermTyped* TIntermediate::addSwizzle(TVectorFields& fields, TSourceLoc line)
//
// Create loop nodes.
//
-TIntermNode* TIntermediate::addLoop(TIntermNode *init, TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
{
- TIntermNode* node = new TIntermLoop(init, body, test, terminal, testFirst);
+ TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
node->setLine(line);
return node;
@@ -630,7 +726,7 @@ TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expres
// This is to be executed once the final root is put on top by the parsing
// process.
//
-bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
+bool TIntermediate::postProcess(TIntermNode* root)
{
if (root == 0)
return true;
@@ -760,6 +856,12 @@ bool TIntermUnary::promote(TInfoSink&)
//
bool TIntermBinary::promote(TInfoSink& infoSink)
{
+ // This function only handles scalars, vectors, and matrices.
+ if (left->isArray() || right->isArray()) {
+ infoSink.info.message(EPrefixInternalError, "Invalid operation for arrays", getLine());
+ return false;
+ }
+
// GLSL ES 2.0 does not support implicit type casting.
// So the basic type should always match.
if (left->getBasicType() != right->getBasicType())
@@ -781,40 +883,6 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
getTypePointer()->setQualifier(EvqTemporary);
}
- //
- // Array operations.
- //
- if (left->isArray() || right->isArray()) {
- //
- // Arrays types have to be exact matches.
- //
- if (left->getType() != right->getType())
- return false;
-
- switch (op) {
- //
- // Promote to conditional
- //
- case EOpEqual:
- case EOpNotEqual:
- setType(TType(EbtBool, EbpUndefined));
- break;
-
- //
- // Set array information.
- //
- case EOpAssign:
- case EOpInitialize:
- getTypePointer()->setArraySize(left->getType().getArraySize());
- getTypePointer()->setArrayInformationType(left->getType().getArrayInformationType());
- break;
-
- default:
- return false;
- }
- return true;
- }
-
int size = std::max(left->getNominalSize(), right->getNominalSize());
//
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
index fd263b6..23476f2 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp
@@ -374,6 +374,10 @@ bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
case EOpLength: writeTriplet(visit, "length(", NULL, ")"); break;
case EOpNormalize: writeTriplet(visit, "normalize(", NULL, ")"); break;
+ case EOpDFdx: writeTriplet(visit, "dFdx(", NULL, ")"); break;
+ case EOpDFdy: writeTriplet(visit, "dFdy(", NULL, ")"); break;
+ case EOpFwidth: writeTriplet(visit, "fwidth(", NULL, ")"); break;
+
case EOpAny: writeTriplet(visit, "any(", NULL, ")"); break;
case EOpAll: writeTriplet(visit, "all(", NULL, ")"); break;
@@ -608,23 +612,32 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
incrementDepth();
// Loop header.
- if (node->testFirst()) // for loop
+ TLoopType loopType = node->getType();
+ if (loopType == ELoopFor) // for loop
{
out << "for (";
if (node->getInit())
node->getInit()->traverse(this);
out << "; ";
- ASSERT(node->getTest() != NULL);
- node->getTest()->traverse(this);
+ if (node->getCondition())
+ node->getCondition()->traverse(this);
out << "; ";
- if (node->getTerminal())
- node->getTerminal()->traverse(this);
+ if (node->getExpression())
+ node->getExpression()->traverse(this);
+ out << ")\n";
+ }
+ else if (loopType == ELoopWhile) // while loop
+ {
+ out << "while (";
+ ASSERT(node->getCondition() != NULL);
+ node->getCondition()->traverse(this);
out << ")\n";
}
else // do-while loop
{
+ ASSERT(loopType == ELoopDoWhile);
out << "do\n";
}
@@ -632,11 +645,11 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
visitCodeBlock(node->getBody());
// Loop footer.
- if (!node->testFirst()) // while loop
+ if (loopType == ELoopDoWhile) // do-while loop
{
out << "while (";
- ASSERT(node->getTest() != NULL);
- node->getTest()->traverse(this);
+ ASSERT(node->getCondition() != NULL);
+ node->getCondition()->traverse(this);
out << ");\n";
}
decrementDepth();
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
index 8b8a4e6..57e99d2 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp
@@ -9,6 +9,7 @@
#include "compiler/debug.h"
#include "compiler/InfoSink.h"
#include "compiler/UnfoldSelect.h"
+#include "compiler/SearchSymbol.h"
#include <stdio.h>
#include <algorithm>
@@ -64,7 +65,7 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr
mScopeDepth = 0;
- mArgumentIndex = 0;
+ mUniqueIndex = 0;
}
OutputHLSL::~OutputHLSL()
@@ -96,7 +97,7 @@ int OutputHLSL::vectorSize(const TType &type) const
void OutputHLSL::header()
{
- EShLanguage language = mContext.language;
+ ShShaderType shaderType = mContext.shaderType;
TInfoSinkBase &out = mHeader;
for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
@@ -109,7 +110,7 @@ void OutputHLSL::header()
out << *constructor;
}
- if (language == EShLangFragment)
+ if (shaderType == SH_FRAGMENT_SHADER)
{
TString uniforms;
TString varyings;
@@ -361,7 +362,8 @@ void OutputHLSL::header()
" float diff;\n"
"};\n"
"\n"
- "uniform gl_DepthRangeParameters gl_DepthRange;\n"
+ "uniform float3 dx_DepthRange;"
+ "static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n"
"\n";
}
@@ -653,7 +655,39 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getOp())
{
case EOpAssign: outputTriplet(visit, "(", " = ", ")"); break;
- case EOpInitialize: outputTriplet(visit, "", " = ", ""); break;
+ case EOpInitialize:
+ if (visit == PreVisit)
+ {
+ // GLSL allows to write things like "float x = x;" where a new variable x is defined
+ // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+ // new variable is created before the assignment is evaluated), so we need to convert
+ // this to "float t = x, x = t;".
+
+ TIntermSymbol *symbolNode = node->getLeft()->getAsSymbolNode();
+ TIntermTyped *expression = node->getRight();
+
+ sh::SearchSymbol searchSymbol(symbolNode->getSymbol());
+ expression->traverse(&searchSymbol);
+ bool sameSymbol = searchSymbol.foundMatch();
+
+ if (sameSymbol)
+ {
+ // Type already printed
+ out << "t" + str(mUniqueIndex) + " = ";
+ expression->traverse(this);
+ out << ", ";
+ symbolNode->traverse(this);
+ out << " = t" + str(mUniqueIndex);
+
+ mUniqueIndex++;
+ return false;
+ }
+ }
+ else if (visit == InVisit)
+ {
+ out << " = ";
+ }
+ break;
case EOpAddAssign: outputTriplet(visit, "(", " += ", ")"); break;
case EOpSubAssign: outputTriplet(visit, "(", " -= ", ")"); break;
case EOpMulAssign: outputTriplet(visit, "(", " *= ", ")"); break;
@@ -933,9 +967,9 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
case EOpFract: outputTriplet(visit, "frac(", "", ")"); break;
case EOpLength: outputTriplet(visit, "length(", "", ")"); break;
case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break;
-// case EOpDPdx: outputTriplet(visit, "ddx(", "", ")"); break;
-// case EOpDPdy: outputTriplet(visit, "ddy(", "", ")"); break;
-// case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break;
+ case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break;
+ case EOpDFdy: outputTriplet(visit, "ddy(", "", ")"); break;
+ case EOpFwidth: outputTriplet(visit, "fwidth(", "", ")"); break;
case EOpAny: outputTriplet(visit, "any(", "", ")"); break;
case EOpAll: outputTriplet(visit, "all(", "", ")"); break;
default: UNREACHABLE();
@@ -946,7 +980,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
{
- EShLanguage language = mContext.language;
+ ShShaderType shaderType = mContext.shaderType;
TInfoSinkBase &out = mBody;
switch (node->getOp())
@@ -1392,7 +1426,7 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
TInfoSinkBase &out = mBody;
- if (!node->testFirst())
+ if (node->getType() == ELoopDoWhile)
{
out << "do\n"
"{\n";
@@ -1404,14 +1438,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
mUnfoldSelect->traverse(node->getInit());
}
- if (node->getTest())
+ if (node->getCondition())
{
- mUnfoldSelect->traverse(node->getTest());
+ mUnfoldSelect->traverse(node->getCondition());
}
- if (node->getTerminal())
+ if (node->getExpression())
{
- mUnfoldSelect->traverse(node->getTerminal());
+ mUnfoldSelect->traverse(node->getExpression());
}
out << "for(";
@@ -1423,16 +1457,16 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << "; ";
- if (node->getTest())
+ if (node->getCondition())
{
- node->getTest()->traverse(this);
+ node->getCondition()->traverse(this);
}
out << "; ";
- if (node->getTerminal())
+ if (node->getExpression())
{
- node->getTerminal()->traverse(this);
+ node->getExpression()->traverse(this);
}
out << ")\n"
@@ -1446,11 +1480,11 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
out << "}\n";
- if (!node->testFirst())
+ if (node->getType() == ELoopDoWhile)
{
out << "while(\n";
- node->getTest()->traverse(this);
+ node->getCondition()->traverse(this);
out << ")";
}
@@ -1565,9 +1599,9 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
}
// Parse comparator and limit value
- if (index != NULL && node->getTest())
+ if (index != NULL && node->getCondition())
{
- TIntermBinary *test = node->getTest()->getAsBinaryNode();
+ TIntermBinary *test = node->getCondition()->getAsBinaryNode();
if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
{
@@ -1585,10 +1619,10 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
}
// Parse increment
- if (index != NULL && comparator != EOpNull && node->getTerminal())
+ if (index != NULL && comparator != EOpNull && node->getExpression())
{
- TIntermBinary *binaryTerminal = node->getTerminal()->getAsBinaryNode();
- TIntermUnary *unaryTerminal = node->getTerminal()->getAsUnaryNode();
+ TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+ TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
if (binaryTerminal)
{
@@ -1711,7 +1745,7 @@ TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
if (name.empty()) // HLSL demands named arguments, also for prototypes
{
- name = "x" + str(mArgumentIndex++);
+ name = "x" + str(mUniqueIndex++);
}
else
{
diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
index dc3c482..ddbd077 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h
@@ -120,7 +120,7 @@ class OutputHLSL : public TIntermTraverser
ScopeBracket mScopeBracket;
unsigned int mScopeDepth;
- int mArgumentIndex; // For creating unique argument names
+ int mUniqueIndex; // For creating unique names
};
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
index 407226b..53f3fa8 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp
@@ -9,9 +9,35 @@
#include <stdarg.h>
#include <stdio.h>
+#include "compiler/glslang.h"
#include "compiler/osinclude.h"
#include "compiler/InitializeParseContext.h"
+extern "C" {
+extern int InitPreprocessor();
+extern int FinalizePreprocessor();
+extern void PredefineIntMacro(const char *name, int value);
+}
+
+static void ReportInfo(TInfoSinkBase& sink,
+ TPrefixType type, TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfo)
+{
+ /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+ sink.prefix(type);
+ sink.location(loc);
+ sink << "'" << token << "' : " << reason << " " << extraInfo << "\n";
+}
+
+static void DefineExtensionMacros(const TExtensionBehavior& extBehavior)
+{
+ for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+ iter != extBehavior.end(); ++iter) {
+ PredefineIntMacro(iter->first.c_str(), 1);
+ }
+}
+
///////////////////////////////////////////////////////////////////////
//
// Sub- vector and matrix fields
@@ -176,24 +202,32 @@ void TParseContext::recover()
//
// Used by flex/bison to output all syntax and parsing errors.
//
-void TParseContext::error(TSourceLoc nLine, const char *szReason, const char *szToken,
- const char *szExtraInfoFormat, ...)
+void TParseContext::error(TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfoFormat, ...)
{
- char szExtraInfo[400];
+ char extraInfo[512];
va_list marker;
+ va_start(marker, extraInfoFormat);
+ vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
- va_start(marker, szExtraInfoFormat);
+ ReportInfo(infoSink.info, EPrefixError, loc, reason, token, extraInfo);
- vsnprintf(szExtraInfo, sizeof(szExtraInfo), szExtraInfoFormat, marker);
+ va_end(marker);
+ ++numErrors;
+}
- /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
- infoSink.info.prefix(EPrefixError);
- infoSink.info.location(nLine);
- infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
+void TParseContext::warning(TSourceLoc loc,
+ const char* reason, const char* token,
+ const char* extraInfoFormat, ...) {
+ char extraInfo[512];
+ va_list marker;
+ va_start(marker, extraInfoFormat);
+ vsnprintf(extraInfo, sizeof(extraInfo), extraInfoFormat, marker);
- va_end(marker);
+ ReportInfo(infoSink.info, EPrefixWarning, loc, reason, token, extraInfo);
- ++numErrors;
+ va_end(marker);
}
//
@@ -415,7 +449,7 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier)
error(line, reservedErrMsg, "gl_", "");
return true;
}
- if (spec == EShSpecWebGL) {
+ if (shaderSpec == SH_WEBGL_SPEC) {
if (identifier.substr(0, 6) == TString("webgl_")) {
error(line, reservedErrMsg, "webgl_", "");
return true;
@@ -471,17 +505,18 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
bool matrixInMatrix = false;
bool arrayArg = false;
for (int i = 0; i < function.getParamCount(); ++i) {
- size += function[i].type->getObjectSize();
+ const TParameter& param = function.getParam(i);
+ size += param.type->getObjectSize();
- if (constructingMatrix && function[i].type->isMatrix())
+ if (constructingMatrix && param.type->isMatrix())
matrixInMatrix = true;
if (full)
overFull = true;
if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
full = true;
- if (function[i].type->getQualifier() != EvqConst)
+ if (param.type->getQualifier() != EvqConst)
constType = false;
- if (function[i].type->isArray())
+ if (param.type->isArray())
arrayArg = true;
}
@@ -510,7 +545,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
return true;
}
- if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->size() != function.getParamCount()) {
+ if (op == EOpConstructStruct && !type->isArray() && int(type->getStruct()->size()) != function.getParamCount()) {
error(line, "Number of constructor parameters does not match the number of structure fields", "constructor", "");
return true;
}
@@ -674,14 +709,11 @@ bool TParseContext::arraySizeErrorCheck(int line, TIntermTyped* expr, int& size)
//
bool TParseContext::arrayQualifierErrorCheck(int line, TPublicType type)
{
- if (type.qualifier == EvqAttribute) {
+ if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str(), "");
return true;
}
- if (type.qualifier == EvqConst && extensionErrorCheck(line, "GL_3DL_array_objects"))
- return true;
-
return false;
}
@@ -886,16 +918,22 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
return false;
}
-bool TParseContext::extensionErrorCheck(int line, const char* extension)
-{
- if (extensionBehavior[extension] == EBhWarn) {
- infoSink.info.message(EPrefixWarning, ("extension " + TString(extension) + " is being used").c_str(), line);
- return false;
+bool TParseContext::extensionErrorCheck(int line, const TString& extension)
+{
+ TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension);
+ if (iter == extensionBehavior.end()) {
+ error(line, "extension", extension.c_str(), "is not supported");
+ return true;
}
- if (extensionBehavior[extension] == EBhDisable) {
- error(line, "extension", extension, "is disabled");
+ if (iter->second == EBhDisable) {
+ error(line, "extension", extension.c_str(), "is disabled");
return true;
}
+ if (iter->second == EBhWarn) {
+ TString msg = "extension " + extension + " is being used";
+ infoSink.info.message(EPrefixWarning, msg.c_str(), line);
+ return false;
+ }
return false;
}
@@ -1021,6 +1059,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
{
+ ASSERT(aggrNode != NULL);
if (!aggrNode->isConstructor())
return false;
@@ -1028,13 +1067,10 @@ bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
// check if all the child nodes are constants so that they can be inserted into
// the parent node
- if (aggrNode) {
- TIntermSequence &childSequenceVector = aggrNode->getSequence() ;
- for (TIntermSequence::iterator p = childSequenceVector.begin();
- p != childSequenceVector.end(); p++) {
- if (!(*p)->getAsTyped()->getAsConstantUnion())
- return false;
- }
+ TIntermSequence &sequence = aggrNode->getSequence() ;
+ for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
+ if (!(*p)->getAsTyped()->getAsConstantUnion())
+ return false;
}
return allConstant;
@@ -1379,16 +1415,29 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n
}
//
-// Initialize all supported extensions to disable
+// Parse an array of strings using yyparse.
//
-void TParseContext::initializeExtensionBehavior()
-{
- //
- // example code: extensionBehavior["test"] = EBhDisable; // where "test" is the name of
- // supported extension
- //
- extensionBehavior["GL_ARB_texture_rectangle"] = EBhRequire;
- extensionBehavior["GL_3DL_array_objects"] = EBhDisable;
+// Returns 0 for success.
+//
+int PaParseStrings(int count, const char* const string[], const int length[],
+ TParseContext* context) {
+ if ((count == 0) || (string == NULL))
+ return 1;
+
+ // setup preprocessor.
+ if (InitPreprocessor())
+ return 1;
+ DefineExtensionMacros(context->extensionBehavior);
+
+ if (glslang_initialize(context))
+ return 1;
+
+ glslang_scan(count, string, length, context);
+ int error = glslang_parse(context);
+
+ glslang_finalize(context);
+ FinalizePreprocessor();
+ return (error == 0) && (context->numErrors == 0) ? 0 : 1;
}
OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
index 792333f..cb6e0d0 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h
@@ -6,9 +6,10 @@
#ifndef _PARSER_HELPER_INCLUDED_
#define _PARSER_HELPER_INCLUDED_
+#include "compiler/ExtensionBehavior.h"
+#include "compiler/localintermediate.h"
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
-#include "compiler/localintermediate.h"
struct TMatrixFields {
bool wholeRow;
@@ -17,13 +18,6 @@ struct TMatrixFields {
int col;
};
-typedef enum {
- EBhRequire,
- EBhEnable,
- EBhWarn,
- EBhDisable
-} TBehavior;
-
struct TPragma {
TPragma(bool o, bool d) : optimize(o), debug(d) { }
bool optimize;
@@ -36,15 +30,16 @@ struct TPragma {
// they can be passed to the parser without needing a global.
//
struct TParseContext {
- TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage l, EShSpec s, TInfoSink& is) :
- intermediate(interm), symbolTable(symt), infoSink(is), language(l), spec(s), treeRoot(0),
+ TParseContext(TSymbolTable& symt, const TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, TInfoSink& is) :
+ intermediate(interm), symbolTable(symt), extensionBehavior(ext), infoSink(is), shaderType(type), shaderSpec(spec), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
- inTypeParen(false), contextPragma(true, false) { }
+ inTypeParen(false), scanner(NULL), contextPragma(true, false) { }
TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
+ TExtensionBehavior extensionBehavior; // mapping between supported extensions and current behavior.
TInfoSink& infoSink;
- EShLanguage language; // vertex or fragment language (future: pack or unpack)
- EShSpec spec; // The language specification compiler conforms to - GLES2 or WebGL.
+ ShShaderType shaderType; // vertex or fragment language (future: pack or unpack)
+ ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL.
TIntermNode* treeRoot; // root of parse tree being created
bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
int numErrors;
@@ -53,11 +48,11 @@ struct TParseContext {
bool inTypeParen; // true if in parentheses, looking only for an identifier
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
- TMap<TString, TBehavior> extensionBehavior;
- void initializeExtensionBehavior();
- void error(TSourceLoc, const char *szReason, const char *szToken,
- const char *szExtraInfoFormat, ...);
+ void error(TSourceLoc loc, const char *reason, const char* token,
+ const char* extraInfoFormat, ...);
+ void warning(TSourceLoc loc, const char* reason, const char* token,
+ const char* extraInfoFormat, ...);
bool reservedErrorCheck(int line, const TString& identifier);
void recover();
@@ -86,7 +81,7 @@ struct TParseContext {
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
- bool extensionErrorCheck(int line, const char*);
+ bool extensionErrorCheck(int line, const TString&);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
@@ -100,16 +95,14 @@ struct TParseContext {
TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, TSourceLoc line);
TIntermTyped* addConstStruct(TString& , TIntermTyped*, TSourceLoc);
bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc);
+ void* scanner;
struct TPragma contextPragma;
TString HashErrMsg;
bool AfterEOF;
};
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext&);
-void PaReservedWord();
-int PaIdentOrType(TString& id, TParseContext&, TSymbol*&);
-int PaParseComment(int &lineno, TParseContext&);
-void setInitialState();
+int PaParseStrings(int count, const char* const string[], const int length[],
+ TParseContext* context);
typedef TParseContext* TParseContextPointer;
extern TParseContextPointer& GetGlobalParseContext();
diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
index 7e348ca..93e21e4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp
@@ -22,14 +22,10 @@ void InitializeGlobalPools()
if (globalPools)
return;
- TPoolAllocator *globalPoolAllocator = new TPoolAllocator(true);
-
TThreadGlobalPools* threadData = new TThreadGlobalPools();
-
- threadData->globalPoolAllocator = globalPoolAllocator;
-
- OS_SetTLSValue(PoolIndex, threadData);
- globalPoolAllocator->push();
+ threadData->globalPoolAllocator = 0;
+
+ OS_SetTLSValue(PoolIndex, threadData);
}
void FreeGlobalPools()
@@ -38,9 +34,7 @@ void FreeGlobalPools()
TThreadGlobalPools* globalPools= static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
if (!globalPools)
return;
-
- GlobalPoolAllocator.popAll();
- delete &GlobalPoolAllocator;
+
delete globalPools;
}
@@ -66,7 +60,7 @@ TPoolAllocator& GetGlobalPoolAllocator()
return *threadData->globalPoolAllocator;
}
-void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
+void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
{
TThreadGlobalPools* threadData = static_cast<TThreadGlobalPools*>(OS_GetTLSValue(PoolIndex));
@@ -77,13 +71,13 @@ void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator)
// Implement the functionality of the TPoolAllocator class, which
// is documented in PoolAlloc.h.
//
-TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignment) :
- global(g),
+TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) :
pageSize(growthIncrement),
alignment(allocationAlignment),
freeList(0),
inUseList(0),
- numCalls(0)
+ numCalls(0),
+ totalBytes(0)
{
//
// Don't allow page sizes we know are smaller than all common
@@ -123,24 +117,14 @@ TPoolAllocator::TPoolAllocator(bool g, int growthIncrement, int allocationAlignm
TPoolAllocator::~TPoolAllocator()
{
- if (!global) {
- //
- // Then we know that this object is not being
- // allocated after other, globally scoped objects
- // that depend on it. So we can delete the "in use" memory.
- //
- while (inUseList) {
- tHeader* next = inUseList->nextPage;
- inUseList->~tHeader();
- delete [] reinterpret_cast<char*>(inUseList);
- inUseList = next;
- }
+ while (inUseList) {
+ tHeader* next = inUseList->nextPage;
+ inUseList->~tHeader();
+ delete [] reinterpret_cast<char*>(inUseList);
+ inUseList = next;
}
- //
- // Always delete the free list memory - it can't be being
- // (correctly) referenced, whether the pool allocator was
- // global or not. We should not check the guard blocks
+ // We should not check the guard blocks
// here, because we did it already when the block was
// placed into the free list.
//
@@ -315,4 +299,4 @@ void TAllocation::checkAllocList() const
{
for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc)
alloc->check();
-}
+} \ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
index 645db78..051dc00 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h
@@ -115,7 +115,7 @@ private:
//
class TPoolAllocator {
public:
- TPoolAllocator(bool global = false, int growthIncrement = 8*1024, int allocationAlignment = 16);
+ TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
//
// Don't call the destructor just to free up the memory, call pop()
@@ -194,7 +194,6 @@ protected:
return TAllocation::offsetAllocation(memory);
}
- bool global; // should be true if this object is globally scoped
size_t pageSize; // granularity of allocation from the OS
size_t alignment; // all returned allocations will be aligned at
// this granularity, which will be a power of 2
@@ -220,18 +219,15 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
-typedef TPoolAllocator* PoolAllocatorPointer;
extern TPoolAllocator& GetGlobalPoolAllocator();
+extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
#define GlobalPoolAllocator GetGlobalPoolAllocator()
-
struct TThreadGlobalPools
{
TPoolAllocator* globalPoolAllocator;
};
-void SetGlobalPoolAllocatorPtr(TPoolAllocator* poolAllocator);
-
//
// This STL compatible allocator is intended to be used as the allocator
// parameter to templatized STL containers, like vector and map.
@@ -301,4 +297,4 @@ protected:
TPoolAllocator& allocator;
};
-#endif // _POOLALLOC_INCLUDED_
+#endif // _POOLALLOC_INCLUDED_ \ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp
new file mode 100644
index 0000000..9368f1a
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.cpp
@@ -0,0 +1,38 @@
+//
+// 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.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#include "compiler/SearchSymbol.h"
+
+#include "compiler/InfoSink.h"
+#include "compiler/OutputHLSL.h"
+
+namespace sh
+{
+SearchSymbol::SearchSymbol(const TString &symbol) : mSymbol(symbol)
+{
+ match = false;
+}
+
+void SearchSymbol::traverse(TIntermNode *node)
+{
+ node->traverse(this);
+}
+
+void SearchSymbol::visitSymbol(TIntermSymbol *symbolNode)
+{
+ if (symbolNode->getSymbol() == mSymbol)
+ {
+ match = true;
+ }
+}
+
+bool SearchSymbol::foundMatch() const
+{
+ return match;
+}
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h
new file mode 100644
index 0000000..6bc0b90
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/SearchSymbol.h
@@ -0,0 +1,33 @@
+//
+// 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.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#ifndef COMPILER_SEARCHSYMBOL_H_
+#define COMPILER_SEARCHSYMBOL_H_
+
+#include "compiler/intermediate.h"
+#include "compiler/ParseHelper.h"
+
+namespace sh
+{
+class SearchSymbol : public TIntermTraverser
+{
+ public:
+ SearchSymbol(const TString &symbol);
+
+ void traverse(TIntermNode *node);
+ void visitSymbol(TIntermSymbol *symbolNode);
+
+ bool foundMatch() const;
+
+ protected:
+ const TString &mSymbol;
+ bool match;
+};
+}
+
+#endif // COMPILER_SEARCHSYMBOL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
index 5ef5d30..e65c1ee 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h
@@ -16,20 +16,26 @@
#include "GLSLANG/ShaderLang.h"
+#include "compiler/ExtensionBehavior.h"
#include "compiler/InfoSink.h"
#include "compiler/SymbolTable.h"
+#include "compiler/VariableInfo.h"
class TCompiler;
-class TIntermNode;
//
// The base class used to back handles returned to the driver.
//
class TShHandleBase {
public:
- TShHandleBase() { }
- virtual ~TShHandleBase() { }
+ TShHandleBase();
+ virtual ~TShHandleBase();
virtual TCompiler* getAsCompiler() { return 0; }
+
+protected:
+ // Memory allocator. Allocates and tracks memory required by the compiler.
+ // Deallocates all memory when compiler is destructed.
+ TPoolAllocator allocator;
};
//
@@ -38,27 +44,49 @@ public:
//
class TCompiler : public TShHandleBase {
public:
- TCompiler(EShLanguage l, EShSpec s) : language(l), spec(s) { }
- virtual ~TCompiler() { }
-
- EShLanguage getLanguage() const { return language; }
- EShSpec getSpec() const { return spec; }
- TSymbolTable& getSymbolTable() { return symbolTable; }
- TInfoSink& getInfoSink() { return infoSink; }
+ TCompiler(ShShaderType type, ShShaderSpec spec);
+ virtual ~TCompiler();
+ virtual TCompiler* getAsCompiler() { return this; }
- virtual bool compile(TIntermNode* root) = 0;
+ bool Init(const ShBuiltInResources& resources);
+ bool compile(const char* const shaderStrings[],
+ const int numStrings,
+ int compileOptions);
- virtual TCompiler* getAsCompiler() { return this; }
+ // Get results of the last compilation.
+ TInfoSink& getInfoSink() { return infoSink; }
+ const TVariableInfoList& getAttribs() const { return attribs; }
+ const TVariableInfoList& getUniforms() const { return uniforms; }
protected:
- EShLanguage language;
- EShSpec spec;
+ ShShaderType getShaderType() const { return shaderType; }
+ ShShaderSpec getShaderSpec() const { return shaderSpec; }
+ // Initialize symbol-table with built-in symbols.
+ bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
+ // Clears the results from the previous compilation.
+ void clearResults();
+ // Returns true if the given shader does not exceed the minimum
+ // functionality mandated in GLSL 1.0 spec Appendix A.
+ bool validateLimitations(TIntermNode* root);
+ // Collect info for all attribs and uniforms.
+ void collectAttribsUniforms(TIntermNode* root);
+ // Translate to object code.
+ virtual void translate(TIntermNode* root) = 0;
+
+private:
+ ShShaderType shaderType;
+ ShShaderSpec shaderSpec;
// Built-in symbol table for the given language, spec, and resources.
// It is preserved from compile-to-compile.
TSymbolTable symbolTable;
- // Output sink.
- TInfoSink infoSink;
+ // Built-in extensions with default behavior.
+ TExtensionBehavior extensionBehavior;
+
+ // Results of compilation.
+ TInfoSink infoSink; // Output sink.
+ TVariableInfoList attribs; // Active attributes in the compiled shader.
+ TVariableInfoList uniforms; // Active uniforms in the compiled shader.
};
//
@@ -70,7 +98,7 @@ protected:
// destroy the machine dependent objects, which contain the
// above machine independent information.
//
-TCompiler* ConstructCompiler(EShLanguage, EShSpec);
+TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec);
void DeleteCompiler(TCompiler*);
-#endif // _SHHANDLE_INCLUDED_
+#endif // _SHHANDLE_INCLUDED_ \ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
index e0c646a..6cac61d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp
@@ -11,78 +11,55 @@
#include "GLSLANG/ShaderLang.h"
-#include "compiler/Initialize.h"
#include "compiler/InitializeDll.h"
-#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
-#include "compiler/SymbolTable.h"
-static bool InitializeSymbolTable(
- const TBuiltInStrings& builtInStrings,
- EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
- TInfoSink& infoSink, TSymbolTable& symbolTable)
-{
- TIntermediate intermediate(infoSink);
- TParseContext parseContext(symbolTable, intermediate, language, spec, infoSink);
-
- GlobalParseContext = &parseContext;
-
- setInitialState();
-
- assert(symbolTable.isEmpty());
- //
- // Parse the built-ins. This should only happen once per
- // language symbol table.
- //
- // Push the symbol table to give it an initial scope. This
- // push should not have a corresponding pop, so that built-ins
- // are preserved, and the test for an empty table fails.
- //
- symbolTable.push();
-
- //Initialize the Preprocessor
- if (InitPreprocessor())
- {
- infoSink.info.message(EPrefixInternalError, "Unable to intialize the Preprocessor");
- return false;
- }
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler.
+//
- for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
+static int getVariableMaxLength(const TVariableInfoList& varList)
+{
+ TString::size_type maxLen = 0;
+ for (TVariableInfoList::const_iterator i = varList.begin();
+ i != varList.end(); ++i)
{
- const char* builtInShaders[1];
- int builtInLengths[1];
-
- builtInShaders[0] = (*i).c_str();
- builtInLengths[0] = (int) (*i).size();
-
- if (PaParseStrings(const_cast<char**>(builtInShaders), builtInLengths, 1, parseContext) != 0)
- {
- infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
- return false;
- }
+ maxLen = std::max(maxLen, i->name.size());
}
-
- IdentifyBuiltIns(language, spec, resources, symbolTable);
-
- FinalizePreprocessor();
-
- return true;
+ // Add 1 to include null-termination character.
+ return static_cast<int>(maxLen) + 1;
}
-static bool GenerateBuiltInSymbolTable(
- EShLanguage language, EShSpec spec, const TBuiltInResource& resources,
- TInfoSink& infoSink, TSymbolTable& symbolTable)
+static void getVariableInfo(ShShaderInfo varType,
+ const ShHandle handle,
+ int index,
+ int* length,
+ int* size,
+ ShDataType* type,
+ char* name)
{
- TBuiltIns builtIns;
+ if (!handle || !size || !type || !name)
+ return;
+ ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
+ (varType == SH_ACTIVE_UNIFORMS));
- builtIns.initialize(language, spec, resources);
- return InitializeSymbolTable(builtIns.getBuiltInStrings(), language, spec, resources, infoSink, symbolTable);
-}
+ TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
+ TCompiler* compiler = base->getAsCompiler();
+ if (compiler == 0)
+ return;
-//
-// This is the platform independent interface between an OGL driver
-// and the shading language compiler.
-//
+ const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
+ compiler->getAttribs() : compiler->getUniforms();
+ if (index < 0 || index >= static_cast<int>(varList.size()))
+ return;
+
+ const TVariableInfo& varInfo = varList[index];
+ if (length) *length = varInfo.name.size();
+ *size = varInfo.size;
+ *type = varInfo.type;
+ strcpy(name, varInfo.name.c_str());
+}
//
// Driver must call this first, once, before doing any other
@@ -110,7 +87,7 @@ int ShFinalize()
//
// Initialize built-in resources with minimum expected values.
//
-void ShInitBuiltInResource(TBuiltInResource* resources)
+void ShInitBuiltInResources(ShBuiltInResources* resources)
{
// Constants.
resources->MaxVertexAttribs = 8;
@@ -129,18 +106,19 @@ void ShInitBuiltInResource(TBuiltInResource* resources)
//
// Driver calls these to create and destroy compiler objects.
//
-ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
+ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+ const ShBuiltInResources* resources)
{
if (!InitThread())
return 0;
- TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, spec));
+ TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec));
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return 0;
// Generate built-in symbol table.
- if (!GenerateBuiltInSymbolTable(language, spec, *resources, compiler->getInfoSink(), compiler->getSymbolTable())) {
+ if (!compiler->Init(*resources)) {
ShDestruct(base);
return 0;
}
@@ -170,9 +148,7 @@ int ShCompile(
const ShHandle handle,
const char* const shaderStrings[],
const int numStrings,
- const EShOptimizationLevel optLevel,
- int debugOptions
- )
+ int compileOptions)
{
if (!InitThread())
return 0;
@@ -184,128 +160,95 @@ int ShCompile(
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return 0;
-
- GlobalPoolAllocator.push();
- TInfoSink& infoSink = compiler->getInfoSink();
- infoSink.info.erase();
- infoSink.debug.erase();
- infoSink.obj.erase();
-
- if (numStrings == 0)
- return 1;
-
- TIntermediate intermediate(infoSink);
- TSymbolTable& symbolTable = compiler->getSymbolTable();
-
- TParseContext parseContext(symbolTable, intermediate, compiler->getLanguage(), compiler->getSpec(), infoSink);
- parseContext.initializeExtensionBehavior();
- GlobalParseContext = &parseContext;
-
- setInitialState();
-
- InitPreprocessor();
- //
- // Parse the application's shaders. All the following symbol table
- // work will be throw-away, so push a new allocation scope that can
- // be thrown away, then push a scope for the current shader's globals.
- //
- bool success = true;
-
- symbolTable.push();
- if (!symbolTable.atGlobalLevel())
- parseContext.infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
-
- int ret = PaParseStrings(const_cast<char**>(shaderStrings), 0, numStrings, parseContext);
- if (ret)
- success = false;
-
- if (success && parseContext.treeRoot) {
- if (optLevel == EShOptNoGeneration)
- parseContext.infoSink.info.message(EPrefixNone, "No errors. No code generation was requested.");
- else {
- success = intermediate.postProcess(parseContext.treeRoot, parseContext.language);
-
- if (success) {
-
- if (debugOptions & EDebugOpIntermediate)
- intermediate.outputTree(parseContext.treeRoot);
-
- //
- // Call the machine dependent compiler
- //
- if (!compiler->compile(parseContext.treeRoot))
- success = false;
- }
- }
- } else if (!success) {
- parseContext.infoSink.info.prefix(EPrefixError);
- parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
- success = false;
- if (debugOptions & EDebugOpIntermediate)
- intermediate.outputTree(parseContext.treeRoot);
- } else if (!parseContext.treeRoot) {
- parseContext.error(1, "Unexpected end of file.", "", "");
- parseContext.infoSink.info << parseContext.numErrors << " compilation errors. No code generated.\n\n";
- success = false;
- if (debugOptions & EDebugOpIntermediate)
- intermediate.outputTree(parseContext.treeRoot);
- }
- intermediate.remove(parseContext.treeRoot);
+ bool success = compiler->compile(shaderStrings, numStrings, compileOptions);
+ return success ? 1 : 0;
+}
- //
- // Ensure symbol table is returned to the built-in level,
- // throwing away all but the built-ins.
- //
- while (!symbolTable.atBuiltInLevel())
- symbolTable.pop();
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params)
+{
+ if (!handle || !params)
+ return;
- FinalizePreprocessor();
- //
- // Throw away all the temporary memory used by the compilation process.
- //
- GlobalPoolAllocator.pop();
+ TShHandleBase* base = static_cast<TShHandleBase*>(handle);
+ TCompiler* compiler = base->getAsCompiler();
+ if (!compiler) return;
- return success ? 1 : 0;
+ switch(pname)
+ {
+ case SH_INFO_LOG_LENGTH:
+ *params = compiler->getInfoSink().info.size() + 1;
+ break;
+ case SH_OBJECT_CODE_LENGTH:
+ *params = compiler->getInfoSink().obj.size() + 1;
+ break;
+ case SH_ACTIVE_UNIFORMS:
+ *params = compiler->getUniforms().size();
+ break;
+ case SH_ACTIVE_UNIFORM_MAX_LENGTH:
+ *params = getVariableMaxLength(compiler->getUniforms());
+ break;
+ case SH_ACTIVE_ATTRIBUTES:
+ *params = compiler->getAttribs().size();
+ break;
+ case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+ *params = getVariableMaxLength(compiler->getAttribs());
+ break;
+
+ default: UNREACHABLE();
+ }
}
//
// Return any compiler log of messages for the application.
//
-const char* ShGetInfoLog(const ShHandle handle)
+void ShGetInfoLog(const ShHandle handle, char* infoLog)
{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
+ if (!handle || !infoLog)
+ return;
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TInfoSink* infoSink = 0;
-
- if (base->getAsCompiler())
- infoSink = &(base->getAsCompiler()->getInfoSink());
+ TCompiler* compiler = base->getAsCompiler();
+ if (!compiler) return;
- infoSink->info << infoSink->debug.c_str();
- return infoSink->info.c_str();
+ TInfoSink& infoSink = compiler->getInfoSink();
+ strcpy(infoLog, infoSink.info.c_str());
}
//
// Return any object code.
//
-const char* ShGetObjectCode(const ShHandle handle)
+void ShGetObjectCode(const ShHandle handle, char* objCode)
{
- if (!InitThread())
- return 0;
-
- if (handle == 0)
- return 0;
+ if (!handle || !objCode)
+ return;
TShHandleBase* base = static_cast<TShHandleBase*>(handle);
- TInfoSink* infoSink;
+ TCompiler* compiler = base->getAsCompiler();
+ if (!compiler) return;
- if (base->getAsCompiler())
- infoSink = &(base->getAsCompiler()->getInfoSink());
+ TInfoSink& infoSink = compiler->getInfoSink();
+ strcpy(objCode, infoSink.obj.c_str());
+}
- return infoSink->obj.c_str();
+void ShGetActiveAttrib(const ShHandle handle,
+ int index,
+ int* length,
+ int* size,
+ ShDataType* type,
+ char* name)
+{
+ getVariableInfo(SH_ACTIVE_ATTRIBUTES,
+ handle, index, length, size, type, name);
+}
+
+void ShGetActiveUniform(const ShHandle handle,
+ int index,
+ int* length,
+ int* size,
+ ShDataType* type,
+ char* name)
+{
+ getVariableInfo(SH_ACTIVE_UNIFORMS,
+ handle, index, length, size, type, name);
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
index 1b08667..02817d4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp
@@ -140,6 +140,22 @@ void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
}
}
+//
+// Change all function entries in the table with the non-mangled name
+// to be related to the provided built-in extension. This is a low
+// performance operation, and only intended for symbol tables that
+// live across a large number of compiles.
+//
+void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
+{
+ for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+ if (it->second->isFunction()) {
+ TFunction* function = static_cast<TFunction*>(it->second);
+ if (function->getName() == name)
+ function->relateToExtension(ext);
+ }
+ }
+}
TSymbol::TSymbol(const TSymbol& copyOf)
{
diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
index b1a80b5..38bc657 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h
@@ -94,7 +94,10 @@ public:
void shareConstPointer( ConstantUnion *constArray)
{
- delete unionArray;
+ if (unionArray == constArray)
+ return;
+
+ delete[] unionArray;
unionArray = constArray;
}
TVariable(const TVariable&, TStructureMap& remapper); // copy constructor
@@ -156,14 +159,18 @@ public:
const TString& getMangledName() const { return mangledName; }
const TType& getReturnType() const { return returnType; }
+
void relateToOperator(TOperator o) { op = o; }
TOperator getBuiltInOp() const { return op; }
+
+ void relateToExtension(const TString& ext) { extension = ext; }
+ const TString& getExtension() const { return extension; }
+
void setDefined() { defined = true; }
bool isDefined() { return defined; }
- int getParamCount() const { return static_cast<int>(parameters.size()); }
- TParameter& operator [](int i) { return parameters[i]; }
- const TParameter& operator [](int i) const { return parameters[i]; }
+ int getParamCount() const { return static_cast<int>(parameters.size()); }
+ const TParameter& getParam(int i) const { return parameters[i]; }
virtual void dump(TInfoSink &infoSink) const;
TFunction(const TFunction&, TStructureMap& remapper);
@@ -175,6 +182,7 @@ protected:
TType returnType;
TString mangledName;
TOperator op;
+ TString extension;
bool defined;
};
@@ -221,6 +229,7 @@ public:
}
void relateToOperator(const char* name, TOperator op);
+ void relateToExtension(const char* name, const TString& ext);
void dump(TInfoSink &infoSink) const;
TSymbolTableLevel* clone(TStructureMap& remapper);
@@ -289,8 +298,16 @@ public:
return symbol;
}
- TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 2); return table[1]; }
- void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); }
+ TSymbolTableLevel* getGlobalLevel() {
+ assert(table.size() >= 2);
+ return table[1];
+ }
+ void relateToOperator(const char* name, TOperator op) {
+ table[0]->relateToOperator(name, op);
+ }
+ void relateToExtension(const char* name, const TString& ext) {
+ table[0]->relateToExtension(name, ext);
+ }
int getMaxSymbolId() { return uniqueId; }
void dump(TInfoSink &infoSink) const;
void copyTable(const TSymbolTable& copyOf);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
index 7b8d903..7a63ae1 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp
@@ -7,14 +7,31 @@
#include "compiler/TranslatorGLSL.h"
#include "compiler/OutputGLSL.h"
+#include "compiler/VersionGLSL.h"
-TranslatorGLSL::TranslatorGLSL(EShLanguage lang, EShSpec spec)
- : TCompiler(lang, spec) {
+static void writeVersion(ShShaderType type, TIntermNode* root,
+ TInfoSinkBase& sink) {
+ TVersionGLSL versionGLSL(type);
+ root->traverse(&versionGLSL);
+ int version = versionGLSL.getVersion();
+ // We need to write version directive only if it is greater than 110.
+ // If there is no version directive in the shader, 110 is implied.
+ if (version > 110) {
+ sink << "#version " << version << "\n";
+ }
}
-bool TranslatorGLSL::compile(TIntermNode* root) {
- TOutputGLSL outputGLSL(infoSink.obj);
- root->traverse(&outputGLSL);
+TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
+ : TCompiler(type, spec) {
+}
+
+void TranslatorGLSL::translate(TIntermNode* root) {
+ TInfoSinkBase& sink = getInfoSink().obj;
- return true;
+ // Write GLSL version.
+ writeVersion(getShaderType(), root, sink);
+
+ // Write translated shader.
+ TOutputGLSL outputGLSL(sink);
+ root->traverse(&outputGLSL);
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
index 973e39a..c2ce06d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.h
@@ -11,8 +11,10 @@
class TranslatorGLSL : public TCompiler {
public:
- TranslatorGLSL(EShLanguage lang, EShSpec spec);
- virtual bool compile(TIntermNode* root);
+ TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+ virtual void translate(TIntermNode* root);
};
#endif // COMPILER_TRANSLATORGLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
index 3a1e52d..96d7f10 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.cpp
@@ -8,17 +8,15 @@
#include "compiler/OutputHLSL.h"
-TranslatorHLSL::TranslatorHLSL(EShLanguage lang, EShSpec spec)
- : TCompiler(lang, spec)
+TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec)
+ : TCompiler(type, spec)
{
}
-bool TranslatorHLSL::compile(TIntermNode *root)
+void TranslatorHLSL::translate(TIntermNode *root)
{
TParseContext& parseContext = *GetGlobalParseContext();
sh::OutputHLSL outputHLSL(parseContext);
outputHLSL.output();
-
- return true;
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
index 38a5f0c..c3f672b 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorHLSL.h
@@ -11,8 +11,10 @@
class TranslatorHLSL : public TCompiler {
public:
- TranslatorHLSL(EShLanguage lang, EShSpec spec);
- virtual bool compile(TIntermNode* root);
+ TranslatorHLSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+ virtual void translate(TIntermNode* root);
};
#endif // COMPILER_TRANSLATORHLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Types.h b/Source/ThirdParty/ANGLE/src/compiler/Types.h
index 897b28f..d0fcc08 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Types.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/Types.h
@@ -85,12 +85,12 @@ public:
TType() {}
TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
{
}
explicit TType(const TPublicType &p) :
type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0)
{
if (p.userDef) {
structure = p.userDef->getStruct();
@@ -99,7 +99,7 @@ public:
}
TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
- structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
+ maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), fieldName(0), mangled(0)
{
typeName = NewPoolTString(n.c_str());
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
index 20035fe..a36c393 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp
@@ -3,6 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
+// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements
+//
#include "compiler/UnfoldSelect.h"
@@ -44,7 +46,7 @@ bool UnfoldSelect::visitSelection(Visit visit, TIntermSelection *node)
"}\n"
"else\n"
"{\n";
- node->getCondition()->traverse(this);
+ node->getFalseBlock()->traverse(this);
out << " t" << i << " = ";
node->getFalseBlock()->traverse(mOutputHLSL);
out << ";\n"
diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
index 68b2e8a..de296e4 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h
@@ -3,6 +3,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
+// UnfoldSelect is an AST traverser to output the select operator ?: as if-else statements
+//
#ifndef COMPILER_UNFOLDSELECT_H_
#define COMPILER_UNFOLDSELECT_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
new file mode 100644
index 0000000..886f693
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp
@@ -0,0 +1,468 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/ValidateLimitations.h"
+#include "compiler/InfoSink.h"
+#include "compiler/ParseHelper.h"
+
+namespace {
+bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) {
+ for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
+ if (i->index.id == symbol->getId())
+ return true;
+ }
+ return false;
+}
+
+// Traverses a node to check if it represents a constant index expression.
+// Definition:
+// constant-index-expressions are a superset of constant-expressions.
+// Constant-index-expressions can include loop indices as defined in
+// GLSL ES 1.0 spec, Appendix A, section 4.
+// The following are constant-index-expressions:
+// - Constant expressions
+// - Loop indices as defined in section 4
+// - Expressions composed of both of the above
+class ValidateConstIndexExpr : public TIntermTraverser {
+public:
+ ValidateConstIndexExpr(const TLoopStack& stack)
+ : mValid(true), mLoopStack(stack) {}
+
+ // Returns true if the parsed node represents a constant index expression.
+ bool isValid() const { return mValid; }
+
+ virtual void visitSymbol(TIntermSymbol* symbol) {
+ // Only constants and loop indices are allowed in a
+ // constant index expression.
+ if (mValid) {
+ mValid = (symbol->getQualifier() == EvqConst) ||
+ IsLoopIndex(symbol, mLoopStack);
+ }
+ }
+ virtual void visitConstantUnion(TIntermConstantUnion*) {}
+ virtual bool visitBinary(Visit, TIntermBinary*) { return true; }
+ virtual bool visitUnary(Visit, TIntermUnary*) { return true; }
+ virtual bool visitSelection(Visit, TIntermSelection*) { return true; }
+ virtual bool visitAggregate(Visit, TIntermAggregate*) { return true; }
+ virtual bool visitLoop(Visit, TIntermLoop*) { return true; }
+ virtual bool visitBranch(Visit, TIntermBranch*) { return true; }
+
+private:
+ bool mValid;
+ const TLoopStack& mLoopStack;
+};
+} // namespace
+
+ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
+ TInfoSinkBase& sink)
+ : mShaderType(shaderType),
+ mSink(sink),
+ mNumErrors(0)
+{
+}
+
+void ValidateLimitations::visitSymbol(TIntermSymbol*)
+{
+}
+
+void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
+{
+ // Check if loop index is modified in the loop body.
+ validateOperation(node, node->getLeft());
+
+ // Check indexing.
+ switch (node->getOp()) {
+ case EOpIndexDirect:
+ case EOpIndexIndirect:
+ validateIndexing(node);
+ break;
+ default: break;
+ }
+ return true;
+}
+
+bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
+{
+ // Check if loop index is modified in the loop body.
+ validateOperation(node, node->getOperand());
+
+ return true;
+}
+
+bool ValidateLimitations::visitSelection(Visit, TIntermSelection*)
+{
+ return true;
+}
+
+bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
+{
+ switch (node->getOp()) {
+ case EOpFunctionCall:
+ validateFunctionCall(node);
+ break;
+ default:
+ break;
+ }
+ return true;
+}
+
+bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
+{
+ if (!validateLoopType(node))
+ return false;
+
+ TLoopInfo info;
+ memset(&info, 0, sizeof(TLoopInfo));
+ if (!validateForLoopHeader(node, &info))
+ return false;
+
+ TIntermNode* body = node->getBody();
+ if (body != NULL) {
+ mLoopStack.push_back(info);
+ body->traverse(this);
+ mLoopStack.pop_back();
+ }
+
+ // The loop is fully processed - no need to visit children.
+ return false;
+}
+
+bool ValidateLimitations::visitBranch(Visit, TIntermBranch*)
+{
+ return true;
+}
+
+void ValidateLimitations::error(TSourceLoc loc,
+ const char *reason, const char* token)
+{
+ mSink.prefix(EPrefixError);
+ mSink.location(loc);
+ mSink << "'" << token << "' : " << reason << "\n";
+ ++mNumErrors;
+}
+
+bool ValidateLimitations::withinLoopBody() const
+{
+ return !mLoopStack.empty();
+}
+
+bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const
+{
+ return IsLoopIndex(symbol, mLoopStack);
+}
+
+bool ValidateLimitations::validateLoopType(TIntermLoop* node) {
+ TLoopType type = node->getType();
+ if (type == ELoopFor)
+ return true;
+
+ // Reject while and do-while loops.
+ error(node->getLine(),
+ "This type of loop is not allowed",
+ type == ELoopWhile ? "while" : "do");
+ return false;
+}
+
+bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node,
+ TLoopInfo* info)
+{
+ ASSERT(node->getType() == ELoopFor);
+
+ //
+ // The for statement has the form:
+ // for ( init-declaration ; condition ; expression ) statement
+ //
+ if (!validateForLoopInit(node, info))
+ return false;
+ if (!validateForLoopCond(node, info))
+ return false;
+ if (!validateForLoopExpr(node, info))
+ return false;
+
+ return true;
+}
+
+bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
+ TLoopInfo* info)
+{
+ TIntermNode* init = node->getInit();
+ if (init == NULL) {
+ error(node->getLine(), "Missing init declaration", "for");
+ return false;
+ }
+
+ //
+ // init-declaration has the form:
+ // type-specifier identifier = constant-expression
+ //
+ TIntermAggregate* decl = init->getAsAggregate();
+ if ((decl == NULL) || (decl->getOp() != EOpDeclaration)) {
+ error(init->getLine(), "Invalid init declaration", "for");
+ return false;
+ }
+ // To keep things simple do not allow declaration list.
+ TIntermSequence& declSeq = decl->getSequence();
+ if (declSeq.size() != 1) {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return false;
+ }
+ TIntermBinary* declInit = declSeq[0]->getAsBinaryNode();
+ if ((declInit == NULL) || (declInit->getOp() != EOpInitialize)) {
+ error(decl->getLine(), "Invalid init declaration", "for");
+ return false;
+ }
+ TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode();
+ if (symbol == NULL) {
+ error(declInit->getLine(), "Invalid init declaration", "for");
+ return false;
+ }
+ // The loop index has type int or float.
+ TBasicType type = symbol->getBasicType();
+ if ((type != EbtInt) && (type != EbtFloat)) {
+ error(symbol->getLine(),
+ "Invalid type for loop index", getBasicString(type));
+ return false;
+ }
+ // The loop index is initialized with constant expression.
+ if (!isConstExpr(declInit->getRight())) {
+ error(declInit->getLine(),
+ "Loop index cannot be initialized with non-constant expression",
+ symbol->getSymbol().c_str());
+ return false;
+ }
+
+ info->index.id = symbol->getId();
+ return true;
+}
+
+bool ValidateLimitations::validateForLoopCond(TIntermLoop* node,
+ TLoopInfo* info)
+{
+ TIntermNode* cond = node->getCondition();
+ if (cond == NULL) {
+ error(node->getLine(), "Missing condition", "for");
+ return false;
+ }
+ //
+ // condition has the form:
+ // loop_index relational_operator constant_expression
+ //
+ TIntermBinary* binOp = cond->getAsBinaryNode();
+ if (binOp == NULL) {
+ error(node->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ // Loop index should be to the left of relational operator.
+ TIntermSymbol* symbol = binOp->getLeft()->getAsSymbolNode();
+ if (symbol == NULL) {
+ error(binOp->getLine(), "Invalid condition", "for");
+ return false;
+ }
+ if (symbol->getId() != info->index.id) {
+ error(symbol->getLine(),
+ "Expected loop index", symbol->getSymbol().c_str());
+ return false;
+ }
+ // Relational operator is one of: > >= < <= == or !=.
+ switch (binOp->getOp()) {
+ case EOpEqual:
+ case EOpNotEqual:
+ case EOpLessThan:
+ case EOpGreaterThan:
+ case EOpLessThanEqual:
+ case EOpGreaterThanEqual:
+ break;
+ default:
+ error(binOp->getLine(),
+ "Invalid relational operator",
+ getOperatorString(binOp->getOp()));
+ break;
+ }
+ // Loop index must be compared with a constant.
+ if (!isConstExpr(binOp->getRight())) {
+ error(binOp->getLine(),
+ "Loop index cannot be compared with non-constant expression",
+ symbol->getSymbol().c_str());
+ return false;
+ }
+
+ return true;
+}
+
+bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node,
+ TLoopInfo* info)
+{
+ TIntermNode* expr = node->getExpression();
+ if (expr == NULL) {
+ error(node->getLine(), "Missing expression", "for");
+ return false;
+ }
+
+ // for expression has one of the following forms:
+ // loop_index++
+ // loop_index--
+ // loop_index += constant_expression
+ // loop_index -= constant_expression
+ // ++loop_index
+ // --loop_index
+ // The last two forms are not specified in the spec, but I am assuming
+ // its an oversight.
+ TIntermUnary* unOp = expr->getAsUnaryNode();
+ TIntermBinary* binOp = unOp ? NULL : expr->getAsBinaryNode();
+
+ TOperator op = EOpNull;
+ TIntermSymbol* symbol = NULL;
+ if (unOp != NULL) {
+ op = unOp->getOp();
+ symbol = unOp->getOperand()->getAsSymbolNode();
+ } else if (binOp != NULL) {
+ op = binOp->getOp();
+ symbol = binOp->getLeft()->getAsSymbolNode();
+ }
+
+ // The operand must be loop index.
+ if (symbol == NULL) {
+ error(expr->getLine(), "Invalid expression", "for");
+ return false;
+ }
+ if (symbol->getId() != info->index.id) {
+ error(symbol->getLine(),
+ "Expected loop index", symbol->getSymbol().c_str());
+ return false;
+ }
+
+ // The operator is one of: ++ -- += -=.
+ switch (op) {
+ case EOpPostIncrement:
+ case EOpPostDecrement:
+ case EOpPreIncrement:
+ case EOpPreDecrement:
+ ASSERT((unOp != NULL) && (binOp == NULL));
+ break;
+ case EOpAddAssign:
+ case EOpSubAssign:
+ ASSERT((unOp == NULL) && (binOp != NULL));
+ break;
+ default:
+ error(expr->getLine(), "Invalid operator", getOperatorString(op));
+ return false;
+ }
+
+ // Loop index must be incremented/decremented with a constant.
+ if (binOp != NULL) {
+ if (!isConstExpr(binOp->getRight())) {
+ error(binOp->getLine(),
+ "Loop index cannot be modified by non-constant expression",
+ symbol->getSymbol().c_str());
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
+{
+ ASSERT(node->getOp() == EOpFunctionCall);
+
+ // If not within loop body, there is nothing to check.
+ if (!withinLoopBody())
+ return true;
+
+ // List of param indices for which loop indices are used as argument.
+ typedef std::vector<int> ParamIndex;
+ ParamIndex pIndex;
+ TIntermSequence& params = node->getSequence();
+ for (TIntermSequence::size_type i = 0; i < params.size(); ++i) {
+ TIntermSymbol* symbol = params[i]->getAsSymbolNode();
+ if (symbol && isLoopIndex(symbol))
+ pIndex.push_back(i);
+ }
+ // If none of the loop indices are used as arguments,
+ // there is nothing to check.
+ if (pIndex.empty())
+ return true;
+
+ bool valid = true;
+ TSymbolTable& symbolTable = GlobalParseContext->symbolTable;
+ TSymbol* symbol = symbolTable.find(node->getName());
+ ASSERT(symbol && symbol->isFunction());
+ TFunction* function = static_cast<TFunction*>(symbol);
+ for (ParamIndex::const_iterator i = pIndex.begin();
+ i != pIndex.end(); ++i) {
+ const TParameter& param = function->getParam(*i);
+ TQualifier qual = param.type->getQualifier();
+ if ((qual == EvqOut) || (qual == EvqInOut)) {
+ error(params[*i]->getLine(),
+ "Loop index cannot be used as argument to a function out or inout parameter",
+ params[*i]->getAsSymbolNode()->getSymbol().c_str());
+ valid = false;
+ }
+ }
+
+ return valid;
+}
+
+bool ValidateLimitations::validateOperation(TIntermOperator* node,
+ TIntermNode* operand) {
+ // Check if loop index is modified in the loop body.
+ if (!withinLoopBody() || !node->modifiesState())
+ return true;
+
+ const TIntermSymbol* symbol = operand->getAsSymbolNode();
+ if (symbol && isLoopIndex(symbol)) {
+ error(node->getLine(),
+ "Loop index cannot be statically assigned to within the body of the loop",
+ symbol->getSymbol().c_str());
+ }
+ return true;
+}
+
+bool ValidateLimitations::isConstExpr(TIntermNode* node)
+{
+ ASSERT(node != NULL);
+ return node->getAsConstantUnion() != NULL;
+}
+
+bool ValidateLimitations::isConstIndexExpr(TIntermNode* node)
+{
+ ASSERT(node != NULL);
+
+ ValidateConstIndexExpr validate(mLoopStack);
+ node->traverse(&validate);
+ return validate.isValid();
+}
+
+bool ValidateLimitations::validateIndexing(TIntermBinary* node)
+{
+ ASSERT((node->getOp() == EOpIndexDirect) ||
+ (node->getOp() == EOpIndexIndirect));
+
+ bool valid = true;
+ TIntermTyped* index = node->getRight();
+ // The index expression must have integral type.
+ if (!index->isScalar() || (index->getBasicType() != EbtInt)) {
+ error(index->getLine(),
+ "Index expression must have integral type",
+ index->getCompleteString().c_str());
+ valid = false;
+ }
+ // The index expession must be a constant-index-expression unless
+ // the operand is a uniform in a vertex shader.
+ TIntermTyped* operand = node->getLeft();
+ bool skip = (mShaderType == SH_VERTEX_SHADER) &&
+ (operand->getQualifier() == EvqUniform);
+ if (!skip && !isConstIndexExpr(index)) {
+ error(index->getLine(), "Index expression must be constant", "[]");
+ valid = false;
+ }
+ return valid;
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h
new file mode 100644
index 0000000..a4f5a28
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h
@@ -0,0 +1,62 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+class TInfoSinkBase;
+
+struct TLoopInfo {
+ struct TIndex {
+ int id; // symbol id.
+ } index;
+};
+typedef TVector<TLoopInfo> TLoopStack;
+
+// Traverses intermediate tree to ensure that the shader does not exceed the
+// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
+class ValidateLimitations : public TIntermTraverser {
+public:
+ ValidateLimitations(ShShaderType shaderType, TInfoSinkBase& sink);
+
+ int numErrors() const { return mNumErrors; }
+
+ virtual void visitSymbol(TIntermSymbol*);
+ virtual void visitConstantUnion(TIntermConstantUnion*);
+ virtual bool visitBinary(Visit, TIntermBinary*);
+ virtual bool visitUnary(Visit, TIntermUnary*);
+ virtual bool visitSelection(Visit, TIntermSelection*);
+ virtual bool visitAggregate(Visit, TIntermAggregate*);
+ virtual bool visitLoop(Visit, TIntermLoop*);
+ virtual bool visitBranch(Visit, TIntermBranch*);
+
+private:
+ void error(TSourceLoc loc, const char *reason, const char* token);
+
+ bool withinLoopBody() const;
+ bool isLoopIndex(const TIntermSymbol* symbol) const;
+ bool validateLoopType(TIntermLoop* node);
+ bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
+ bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
+ bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
+ bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
+ // Returns true if none of the loop indices is used as the argument to
+ // the given function out or inout parameter.
+ bool validateFunctionCall(TIntermAggregate* node);
+ bool validateOperation(TIntermOperator* node, TIntermNode* operand);
+
+ // Returns true if indexing does not exceed the minimum functionality
+ // mandated in GLSL 1.0 spec, Appendix A, Section 5.
+ bool isConstExpr(TIntermNode* node);
+ bool isConstIndexExpr(TIntermNode* node);
+ bool validateIndexing(TIntermBinary* node);
+
+ ShShaderType mShaderType;
+ TInfoSinkBase& mSink;
+ int mNumErrors;
+ TLoopStack mLoopStack;
+};
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp
new file mode 100644
index 0000000..ad2e08f
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp
@@ -0,0 +1,210 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/VariableInfo.h"
+
+static TString arrayBrackets(int index)
+{
+ TStringStream stream;
+ stream << "[" << index << "]";
+ return stream.str();
+}
+
+// Returns the data type for an attribute or uniform.
+static ShDataType getVariableDataType(const TType& type)
+{
+ switch (type.getBasicType()) {
+ case EbtFloat:
+ if (type.isMatrix()) {
+ switch (type.getNominalSize()) {
+ case 2: return SH_FLOAT_MAT2;
+ case 3: return SH_FLOAT_MAT3;
+ case 4: return SH_FLOAT_MAT4;
+ default: UNREACHABLE();
+ }
+ } else if (type.isVector()) {
+ switch (type.getNominalSize()) {
+ case 2: return SH_FLOAT_VEC2;
+ case 3: return SH_FLOAT_VEC3;
+ case 4: return SH_FLOAT_VEC4;
+ default: UNREACHABLE();
+ }
+ } else {
+ return SH_FLOAT;
+ }
+ case EbtInt:
+ if (type.isMatrix()) {
+ UNREACHABLE();
+ } else if (type.isVector()) {
+ switch (type.getNominalSize()) {
+ case 2: return SH_INT_VEC2;
+ case 3: return SH_INT_VEC3;
+ case 4: return SH_INT_VEC4;
+ default: UNREACHABLE();
+ }
+ } else {
+ return SH_INT;
+ }
+ case EbtBool:
+ if (type.isMatrix()) {
+ UNREACHABLE();
+ } else if (type.isVector()) {
+ switch (type.getNominalSize()) {
+ case 2: return SH_BOOL_VEC2;
+ case 3: return SH_BOOL_VEC3;
+ case 4: return SH_BOOL_VEC4;
+ default: UNREACHABLE();
+ }
+ } else {
+ return SH_BOOL;
+ }
+ case EbtSampler2D: return SH_SAMPLER_2D;
+ case EbtSamplerCube: return SH_SAMPLER_CUBE;
+ default: UNREACHABLE();
+ }
+ return SH_NONE;
+}
+
+static void getBuiltInVariableInfo(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList);
+static void getUserDefinedVariableInfo(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList);
+
+// Returns info for an attribute or uniform.
+static void getVariableInfo(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList)
+{
+ if (type.getBasicType() == EbtStruct) {
+ if (type.isArray()) {
+ for (int i = 0; i < type.getArraySize(); ++i) {
+ TString lname = name + arrayBrackets(i);
+ getUserDefinedVariableInfo(type, lname, infoList);
+ }
+ } else {
+ getUserDefinedVariableInfo(type, name, infoList);
+ }
+ } else {
+ getBuiltInVariableInfo(type, name, infoList);
+ }
+}
+
+void getBuiltInVariableInfo(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList)
+{
+ ASSERT(type.getBasicType() != EbtStruct);
+
+ TVariableInfo varInfo;
+ if (type.isArray()) {
+ varInfo.name = (name + "[0]").c_str();
+ varInfo.size = type.getArraySize();
+ } else {
+ varInfo.name = name.c_str();
+ varInfo.size = 1;
+ }
+ varInfo.type = getVariableDataType(type);
+ infoList.push_back(varInfo);
+}
+
+void getUserDefinedVariableInfo(const TType& type,
+ const TString& name,
+ TVariableInfoList& infoList)
+{
+ ASSERT(type.getBasicType() == EbtStruct);
+
+ TString lname = name + ".";
+ const TTypeList* structure = type.getStruct();
+ for (size_t i = 0; i < structure->size(); ++i) {
+ const TType* fieldType = (*structure)[i].type;
+ getVariableInfo(*fieldType,
+ lname + fieldType->getFieldName(),
+ infoList);
+ }
+}
+
+CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
+ TVariableInfoList& uniforms)
+ : mAttribs(attribs),
+ mUniforms(uniforms)
+{
+}
+
+// We are only interested in attribute and uniform variable declaration.
+void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
+{
+}
+
+void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
+{
+ return false;
+}
+
+bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
+{
+ return false;
+}
+
+bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
+{
+ return false;
+}
+
+bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
+{
+ bool visitChildren = false;
+
+ switch (node->getOp())
+ {
+ case EOpSequence:
+ // We need to visit sequence children to get to variable declarations.
+ visitChildren = true;
+ break;
+ case EOpDeclaration: {
+ const TIntermSequence& sequence = node->getSequence();
+ TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
+ if (qualifier == EvqAttribute || qualifier == EvqUniform)
+ {
+ TVariableInfoList& infoList = qualifier == EvqAttribute ?
+ mAttribs : mUniforms;
+ for (TIntermSequence::const_iterator i = sequence.begin();
+ i != sequence.end(); ++i)
+ {
+ const TIntermSymbol* variable = (*i)->getAsSymbolNode();
+ // The only case in which the sequence will not contain a
+ // TIntermSymbol node is initialization. It will contain a
+ // TInterBinary node in that case. Since attributes and unifroms
+ // cannot be initialized in a shader, we must have only
+ // TIntermSymbol nodes in the sequence.
+ ASSERT(variable != NULL);
+ getVariableInfo(variable->getType(), variable->getSymbol(),
+ infoList);
+ }
+ }
+ break;
+ }
+ default: break;
+ }
+
+ return visitChildren;
+}
+
+bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
+{
+ return false;
+}
+
+bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
+{
+ return false;
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h
new file mode 100644
index 0000000..15a5c57
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+// Provides information about a variable.
+// It is currently being used to store info about active attribs and uniforms.
+struct TVariableInfo {
+ TPersistString name;
+ ShDataType type;
+ int size;
+};
+typedef std::vector<TVariableInfo> TVariableInfoList;
+
+// Traverses intermediate tree to collect all attributes and uniforms.
+class CollectAttribsUniforms : public TIntermTraverser {
+public:
+ CollectAttribsUniforms(TVariableInfoList& attribs,
+ TVariableInfoList& uniforms);
+
+ virtual void visitSymbol(TIntermSymbol*);
+ virtual void visitConstantUnion(TIntermConstantUnion*);
+ virtual bool visitBinary(Visit, TIntermBinary*);
+ virtual bool visitUnary(Visit, TIntermUnary*);
+ virtual bool visitSelection(Visit, TIntermSelection*);
+ virtual bool visitAggregate(Visit, TIntermAggregate*);
+ virtual bool visitLoop(Visit, TIntermLoop*);
+ virtual bool visitBranch(Visit, TIntermBranch*);
+
+private:
+ TVariableInfoList& mAttribs;
+ TVariableInfoList& mUniforms;
+};
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp
new file mode 100644
index 0000000..3f87820
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp
@@ -0,0 +1,108 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/VersionGLSL.h"
+
+static const int GLSL_VERSION_110 = 110;
+static const int GLSL_VERSION_120 = 120;
+
+// We need to scan for two things:
+// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
+// but only at the global scope.
+// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
+// but inside any scope.
+// So we need to scan the entire fragment shader but only the global scope
+// of vertex shader.
+//
+// TODO(alokp): The following two cases of invariant decalaration get lost
+// during parsing - they do not get carried over to the intermediate tree.
+// Handle these cases:
+// 1. When a pragma is used to force all output variables to be invariant:
+// - #pragma STDGL invariant(all)
+// 2. When a previously decalared or built-in variable is marked invariant:
+// - invariant gl_Position;
+// - varying vec3 color; invariant color;
+//
+TVersionGLSL::TVersionGLSL(ShShaderType type)
+ : mShaderType(type),
+ mVersion(GLSL_VERSION_110)
+{
+}
+
+void TVersionGLSL::visitSymbol(TIntermSymbol* node)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+
+ if (node->getSymbol() == "gl_PointCoord")
+ updateVersion(GLSL_VERSION_120);
+}
+
+void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+}
+
+bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+ return true;
+}
+
+bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+ return true;
+}
+
+bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+ return true;
+}
+
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
+{
+ // We need to scan the entire fragment shader but only the global scope
+ // of vertex shader.
+ bool visitChildren = mShaderType == SH_FRAGMENT_SHADER ? true : false;
+
+ switch (node->getOp()) {
+ case EOpSequence:
+ // We need to visit sequence children to get to global or inner scope.
+ visitChildren = true;
+ break;
+ case EOpDeclaration: {
+ const TIntermSequence& sequence = node->getSequence();
+ TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
+ if ((qualifier == EvqInvariantVaryingIn) ||
+ (qualifier == EvqInvariantVaryingOut)) {
+ updateVersion(GLSL_VERSION_120);
+ }
+ break;
+ }
+ default: break;
+ }
+
+ return visitChildren;
+}
+
+bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+ return true;
+}
+
+bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
+{
+ ASSERT(mShaderType == SH_FRAGMENT_SHADER);
+ return true;
+}
+
+void TVersionGLSL::updateVersion(int version)
+{
+ mVersion = std::max(version, mVersion);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h
new file mode 100644
index 0000000..64d002b
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h
@@ -0,0 +1,50 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_VERSIONGLSL_H_
+#define COMPILER_VERSIONGLSL_H_
+
+#include "GLSLANG/ShaderLang.h"
+#include "compiler/intermediate.h"
+
+// Traverses the intermediate tree to return the minimum GLSL version
+// required to legally access all built-in features used in the shader.
+// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
+// - #version and #extension to declare version and extensions.
+// - built-in functions refract, exp, and log.
+// - updated step() to compare x < edge instead of x <= edge.
+// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
+// - many changes to reduce differences when compared to the ES specification.
+// - invariant keyword and its support.
+// - c++ style name hiding rules.
+// - built-in variable gl_PointCoord for fragment shaders.
+//
+class TVersionGLSL : public TIntermTraverser {
+public:
+ TVersionGLSL(ShShaderType type);
+
+ // Returns 120 if "invariant" keyword or "gl_PointCoord" is used
+ // in the shader. Else 110 is returned.
+ int getVersion() { return mVersion; }
+
+ virtual void visitSymbol(TIntermSymbol*);
+ virtual void visitConstantUnion(TIntermConstantUnion*);
+ virtual bool visitBinary(Visit, TIntermBinary*);
+ virtual bool visitUnary(Visit, TIntermUnary*);
+ virtual bool visitSelection(Visit, TIntermSelection*);
+ virtual bool visitAggregate(Visit, TIntermAggregate*);
+ virtual bool visitLoop(Visit, TIntermLoop*);
+ virtual bool visitBranch(Visit, TIntermBranch*);
+
+protected:
+ void updateVersion(int version);
+
+private:
+ ShShaderType mShaderType;
+ int mVersion;
+};
+
+#endif // COMPILER_VERSIONGLSL_H_
diff --git a/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh
new file mode 100644
index 0000000..268479d
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_lexer.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+# Copyright (c) 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.
+
+# Generates GLSL ES lexer - glslang_lex.cpp
+
+script_dir=$(dirname $0)
+input_file=$script_dir/glslang.l
+output_file=$script_dir/glslang_lex.cpp
+flex --noline --nounistd --outfile=$output_file $input_file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh
new file mode 100644
index 0000000..889f5c0
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/generate_glslang_parser.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright (c) 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.
+
+# Generates GLSL ES parser - glslang_tab.h and glslang_tab.cpp
+
+script_dir=$(dirname $0)
+input_file=$script_dir/glslang.y
+output_header=$script_dir/glslang_tab.h
+output_source=$script_dir/glslang_tab.cpp
+bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.h b/Source/ThirdParty/ANGLE/src/compiler/glslang.h
new file mode 100644
index 0000000..26f1457
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.h
@@ -0,0 +1,16 @@
+//
+// Copyright (c) 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.
+//
+
+struct TParseContext;
+extern int glslang_initialize(TParseContext* context);
+extern int glslang_finalize(TParseContext* context);
+
+extern void glslang_scan(int count,
+ const char* const string[],
+ const int length[],
+ TParseContext* context);
+extern int glslang_parse(TParseContext* context);
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/glslang.l
index 02c226f..5a7c5d5 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/glslang.l
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.l
@@ -4,34 +4,29 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
-*/
-/* Based on
-ANSI C grammar, Lex specification
-
-In 1985, Jeff Lee published this Lex specification together with a Yacc
-grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted
-both to net.sources in 1987; that original, as mentioned in the answer
-to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net,
-file usenet/net.sources/ansi.c.grammar.Z.
-I intend to keep this version as close to the current C Standard grammar
-as possible; please let me know if you discover discrepancies.
+This file contains the Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
-Jutta Degener, 1995
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
*/
-D [0-9]
-L [a-zA-Z_]
-H [a-fA-F0-9]
-E [Ee][+-]?{D}+
-O [0-7]
+%top{
+//
+// Copyright (c) 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.
+//
-%option nounput
-%{
-#include <stdio.h>
-#include <stdlib.h>
+// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+}
+%{
+#include "compiler/glslang.h"
#include "compiler/ParseHelper.h"
+#include "compiler/util.h"
#include "glslang_tab.h"
/* windows only pragma */
@@ -39,407 +34,304 @@ O [0-7]
#pragma warning(disable : 4102)
#endif
-int yy_input(char* buf, int max_size);
-
-extern int yyparse(void*);
-#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-#define parseContext (*((TParseContext*)(parseContextLocal)))
-
-#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size))
+#define YY_USER_ACTION yylval->lex.line = yylineno;
+#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 int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
%}
-/*
-TODO(alokp): yylineno is only here to support old flex.exe in compiler/tools.
-Remove it when we can exclusively use the newer version.
-*/
-%option yylineno
-
-%option noyywrap
-%option never-interactive
-%x FIELDS
+%option noyywrap nounput never-interactive
+%option yylineno reentrant bison-bridge
+%option stack
+%option extra-type="TParseContext*"
+%x COMMENT FIELDS
+D [0-9]
+L [a-zA-Z_]
+H [a-fA-F0-9]
+E [Ee][+-]?{D}+
+O [0-7]
%%
-<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ };
-
-"invariant" { pyylval->lex.line = yylineno; return(INVARIANT); }
-"highp" { pyylval->lex.line = yylineno; return(HIGH_PRECISION); }
-"mediump" { pyylval->lex.line = yylineno; return(MEDIUM_PRECISION); }
-"lowp" { pyylval->lex.line = yylineno; return(LOW_PRECISION); }
-"precision" { pyylval->lex.line = yylineno; return(PRECISION); }
-
-"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); }
-"const" { pyylval->lex.line = yylineno; return(CONST_QUAL); }
-"uniform" { pyylval->lex.line = yylineno; return(UNIFORM); }
-"varying" { pyylval->lex.line = yylineno; return(VARYING); }
-
-"break" { pyylval->lex.line = yylineno; return(BREAK); }
-"continue" { pyylval->lex.line = yylineno; return(CONTINUE); }
-"do" { pyylval->lex.line = yylineno; return(DO); }
-"for" { pyylval->lex.line = yylineno; return(FOR); }
-"while" { pyylval->lex.line = yylineno; return(WHILE); }
-
-"if" { pyylval->lex.line = yylineno; return(IF); }
-"else" { pyylval->lex.line = yylineno; return(ELSE); }
-
-"in" { pyylval->lex.line = yylineno; return(IN_QUAL); }
-"out" { pyylval->lex.line = yylineno; return(OUT_QUAL); }
-"inout" { pyylval->lex.line = yylineno; return(INOUT_QUAL); }
-
-"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
-"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
-"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
-"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
-"true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
-"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
-
-"discard" { pyylval->lex.line = yylineno; return(DISCARD); }
-"return" { pyylval->lex.line = yylineno; return(RETURN); }
-
-"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
-"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
-"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
-
-"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
-"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
-"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); }
-"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
-"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
-"ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
-"bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
-"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
-"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
-
-"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; }
-"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; }
-
-"struct" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(STRUCT); }
-
-"asm" { PaReservedWord(); return 0; }
-
-"class" { PaReservedWord(); return 0; }
-"union" { PaReservedWord(); return 0; }
-"enum" { PaReservedWord(); return 0; }
-"typedef" { PaReservedWord(); return 0; }
-"template" { PaReservedWord(); return 0; }
-"this" { PaReservedWord(); return 0; }
-"packed" { PaReservedWord(); return 0; }
-
-"goto" { PaReservedWord(); return 0; }
-"switch" { PaReservedWord(); return 0; }
-"default" { PaReservedWord(); return 0; }
-
-"inline" { PaReservedWord(); return 0; }
-"noinline" { PaReservedWord(); return 0; }
-"volatile" { PaReservedWord(); return 0; }
-"public" { PaReservedWord(); return 0; }
-"static" { PaReservedWord(); return 0; }
-"extern" { PaReservedWord(); return 0; }
-"external" { PaReservedWord(); return 0; }
-"interface" { PaReservedWord(); return 0; }
-
-"long" { PaReservedWord(); return 0; }
-"short" { PaReservedWord(); return 0; }
-"double" { PaReservedWord(); return 0; }
-"half" { PaReservedWord(); return 0; }
-"fixed" { PaReservedWord(); return 0; }
-"unsigned" { PaReservedWord(); return 0; }
-
-"input" { PaReservedWord(); return 0; }
-"output" { PaReservedWord(); return 0; }
-
-"hvec2" { PaReservedWord(); return 0; }
-"hvec3" { PaReservedWord(); return 0; }
-"hvec4" { PaReservedWord(); return 0; }
-"fvec2" { PaReservedWord(); return 0; }
-"fvec3" { PaReservedWord(); return 0; }
-"fvec4" { PaReservedWord(); return 0; }
-"dvec2" { PaReservedWord(); return 0; }
-"dvec3" { PaReservedWord(); return 0; }
-"dvec4" { PaReservedWord(); return 0; }
-
-"sizeof" { PaReservedWord(); return 0; }
-"cast" { PaReservedWord(); return 0; }
-
-"namespace" { PaReservedWord(); return 0; }
-"using" { PaReservedWord(); return 0; }
-
-{L}({L}|{D})* {
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol);
+
+%{
+ TParseContext* context = yyextra;
+%}
+
+ /* Single-line comments */
+"//"[^\n]* ;
+
+ /* Multi-line comments */
+"/*" { yy_push_state(COMMENT, yyscanner); }
+<COMMENT>. |
+<COMMENT>\n ;
+<COMMENT>"*/" { yy_pop_state(yyscanner); }
+
+"invariant" { return(INVARIANT); }
+"highp" { return(HIGH_PRECISION); }
+"mediump" { return(MEDIUM_PRECISION); }
+"lowp" { return(LOW_PRECISION); }
+"precision" { return(PRECISION); }
+
+"attribute" { return(ATTRIBUTE); }
+"const" { return(CONST_QUAL); }
+"uniform" { return(UNIFORM); }
+"varying" { return(VARYING); }
+
+"break" { return(BREAK); }
+"continue" { return(CONTINUE); }
+"do" { return(DO); }
+"for" { return(FOR); }
+"while" { return(WHILE); }
+
+"if" { return(IF); }
+"else" { return(ELSE); }
+
+"in" { return(IN_QUAL); }
+"out" { return(OUT_QUAL); }
+"inout" { return(INOUT_QUAL); }
+
+"float" { context->lexAfterType = true; return(FLOAT_TYPE); }
+"int" { context->lexAfterType = true; return(INT_TYPE); }
+"void" { context->lexAfterType = true; return(VOID_TYPE); }
+"bool" { context->lexAfterType = true; return(BOOL_TYPE); }
+"true" { yylval->lex.b = true; return(BOOLCONSTANT); }
+"false" { yylval->lex.b = false; return(BOOLCONSTANT); }
+
+"discard" { return(DISCARD); }
+"return" { return(RETURN); }
+
+"mat2" { context->lexAfterType = true; return(MATRIX2); }
+"mat3" { context->lexAfterType = true; return(MATRIX3); }
+"mat4" { context->lexAfterType = true; return(MATRIX4); }
+
+"vec2" { context->lexAfterType = true; return (VEC2); }
+"vec3" { context->lexAfterType = true; return (VEC3); }
+"vec4" { context->lexAfterType = true; return (VEC4); }
+"ivec2" { context->lexAfterType = true; return (IVEC2); }
+"ivec3" { context->lexAfterType = true; return (IVEC3); }
+"ivec4" { context->lexAfterType = true; return (IVEC4); }
+"bvec2" { context->lexAfterType = true; return (BVEC2); }
+"bvec3" { context->lexAfterType = true; return (BVEC3); }
+"bvec4" { context->lexAfterType = true; return (BVEC4); }
+
+"sampler2D" { context->lexAfterType = true; return SAMPLER2D; }
+"samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; }
+
+"struct" { context->lexAfterType = true; return(STRUCT); }
+
+"asm" { return reserved_word(yyscanner); }
+
+"class" { return reserved_word(yyscanner); }
+"union" { return reserved_word(yyscanner); }
+"enum" { return reserved_word(yyscanner); }
+"typedef" { return reserved_word(yyscanner); }
+"template" { return reserved_word(yyscanner); }
+"this" { return reserved_word(yyscanner); }
+"packed" { return reserved_word(yyscanner); }
+
+"goto" { return reserved_word(yyscanner); }
+"switch" { return reserved_word(yyscanner); }
+"default" { return reserved_word(yyscanner); }
+
+"inline" { return reserved_word(yyscanner); }
+"noinline" { return reserved_word(yyscanner); }
+"volatile" { return reserved_word(yyscanner); }
+"public" { return reserved_word(yyscanner); }
+"static" { return reserved_word(yyscanner); }
+"extern" { return reserved_word(yyscanner); }
+"external" { return reserved_word(yyscanner); }
+"interface" { return reserved_word(yyscanner); }
+
+"long" { return reserved_word(yyscanner); }
+"short" { return reserved_word(yyscanner); }
+"double" { return reserved_word(yyscanner); }
+"half" { return reserved_word(yyscanner); }
+"fixed" { return reserved_word(yyscanner); }
+"unsigned" { return reserved_word(yyscanner); }
+
+"input" { return reserved_word(yyscanner); }
+"output" { return reserved_word(yyscanner); }
+
+"hvec2" { return reserved_word(yyscanner); }
+"hvec3" { return reserved_word(yyscanner); }
+"hvec4" { return reserved_word(yyscanner); }
+"fvec2" { return reserved_word(yyscanner); }
+"fvec3" { return reserved_word(yyscanner); }
+"fvec4" { return reserved_word(yyscanner); }
+"dvec2" { return reserved_word(yyscanner); }
+"dvec3" { return reserved_word(yyscanner); }
+"dvec4" { return reserved_word(yyscanner); }
+
+"sizeof" { return reserved_word(yyscanner); }
+"cast" { return reserved_word(yyscanner); }
+
+"namespace" { return reserved_word(yyscanner); }
+"using" { return reserved_word(yyscanner); }
+
+{L}({L}|{D})* {
+ yylval->lex.string = NewPoolTString(yytext);
+ return check_type(yyscanner);
}
-0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
-{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
-
-{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
-
-"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; }
-
-"+=" { pyylval->lex.line = yylineno; return(ADD_ASSIGN); }
-"-=" { pyylval->lex.line = yylineno; return(SUB_ASSIGN); }
-"*=" { pyylval->lex.line = yylineno; return(MUL_ASSIGN); }
-"/=" { pyylval->lex.line = yylineno; return(DIV_ASSIGN); }
-"%=" { pyylval->lex.line = yylineno; return(MOD_ASSIGN); }
-"<<=" { pyylval->lex.line = yylineno; return(LEFT_ASSIGN); }
-">>=" { pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); }
-"&=" { pyylval->lex.line = yylineno; return(AND_ASSIGN); }
-"^=" { pyylval->lex.line = yylineno; return(XOR_ASSIGN); }
-"|=" { pyylval->lex.line = yylineno; return(OR_ASSIGN); }
-
-"++" { pyylval->lex.line = yylineno; return(INC_OP); }
-"--" { pyylval->lex.line = yylineno; return(DEC_OP); }
-"&&" { pyylval->lex.line = yylineno; return(AND_OP); }
-"||" { pyylval->lex.line = yylineno; return(OR_OP); }
-"^^" { pyylval->lex.line = yylineno; return(XOR_OP); }
-"<=" { pyylval->lex.line = yylineno; return(LE_OP); }
-">=" { pyylval->lex.line = yylineno; return(GE_OP); }
-"==" { pyylval->lex.line = yylineno; return(EQ_OP); }
-"!=" { pyylval->lex.line = yylineno; return(NE_OP); }
-"<<" { pyylval->lex.line = yylineno; return(LEFT_OP); }
-">>" { pyylval->lex.line = yylineno; return(RIGHT_OP); }
-";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); }
-("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); }
-("}"|"%>") { pyylval->lex.line = yylineno; return(RIGHT_BRACE); }
-"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); }
-":" { pyylval->lex.line = yylineno; return(COLON); }
-"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); }
-"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); }
-")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); }
-("["|"<:") { pyylval->lex.line = yylineno; return(LEFT_BRACKET); }
-("]"|":>") { pyylval->lex.line = yylineno; return(RIGHT_BRACKET); }
+0[xX]{H}+ { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+0{O}+ { yylval->lex.i = 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}+{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); }
+"."{D}+({E})? { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+
+"+=" { return(ADD_ASSIGN); }
+"-=" { return(SUB_ASSIGN); }
+"*=" { return(MUL_ASSIGN); }
+"/=" { return(DIV_ASSIGN); }
+"%=" { return(MOD_ASSIGN); }
+"<<=" { return(LEFT_ASSIGN); }
+">>=" { return(RIGHT_ASSIGN); }
+"&=" { return(AND_ASSIGN); }
+"^=" { return(XOR_ASSIGN); }
+"|=" { return(OR_ASSIGN); }
+
+"++" { return(INC_OP); }
+"--" { return(DEC_OP); }
+"&&" { return(AND_OP); }
+"||" { return(OR_OP); }
+"^^" { return(XOR_OP); }
+"<=" { return(LE_OP); }
+">=" { return(GE_OP); }
+"==" { return(EQ_OP); }
+"!=" { return(NE_OP); }
+"<<" { return(LEFT_OP); }
+">>" { return(RIGHT_OP); }
+";" { context->lexAfterType = false; return(SEMICOLON); }
+("{"|"<%") { context->lexAfterType = false; return(LEFT_BRACE); }
+("}"|"%>") { return(RIGHT_BRACE); }
+"," { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
+":" { return(COLON); }
+"=" { context->lexAfterType = false; return(EQUAL); }
+"(" { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
+")" { context->inTypeParen = false; return(RIGHT_PAREN); }
+("["|"<:") { return(LEFT_BRACKET); }
+("]"|":>") { return(RIGHT_BRACKET); }
"." { BEGIN(FIELDS); return(DOT); }
-"!" { pyylval->lex.line = yylineno; return(BANG); }
-"-" { pyylval->lex.line = yylineno; return(DASH); }
-"~" { pyylval->lex.line = yylineno; return(TILDE); }
-"+" { pyylval->lex.line = yylineno; return(PLUS); }
-"*" { pyylval->lex.line = yylineno; return(STAR); }
-"/" { pyylval->lex.line = yylineno; return(SLASH); }
-"%" { pyylval->lex.line = yylineno; return(PERCENT); }
-"<" { pyylval->lex.line = yylineno; return(LEFT_ANGLE); }
-">" { pyylval->lex.line = yylineno; return(RIGHT_ANGLE); }
-"|" { pyylval->lex.line = yylineno; return(VERTICAL_BAR); }
-"^" { pyylval->lex.line = yylineno; return(CARET); }
-"&" { pyylval->lex.line = yylineno; return(AMPERSAND); }
-"?" { pyylval->lex.line = yylineno; return(QUESTION); }
+"!" { return(BANG); }
+"-" { return(DASH); }
+"~" { return(TILDE); }
+"+" { return(PLUS); }
+"*" { return(STAR); }
+"/" { return(SLASH); }
+"%" { return(PERCENT); }
+"<" { return(LEFT_ANGLE); }
+">" { return(RIGHT_ANGLE); }
+"|" { return(VERTICAL_BAR); }
+"^" { return(CARET); }
+"&" { return(AMPERSAND); }
+"?" { return(QUESTION); }
<FIELDS>{L}({L}|{D})* {
-BEGIN(INITIAL);
- pyylval->lex.line = yylineno;
- pyylval->lex.string = NewPoolTString(yytext);
- return FIELD_SELECTION; }
+ BEGIN(INITIAL);
+ yylval->lex.string = NewPoolTString(yytext);
+ return FIELD_SELECTION;
+}
<FIELDS>[ \t\v\f\r] {}
[ \t\v\n\f\r] { }
-<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();}
-<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n";
- return 0; }
+<*><<EOF>> { context->AfterEOF = true; yyterminate(); }
+<*>. { context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
%%
-
-//Including Pre-processor.
extern "C" {
- #include "compiler/preprocessor/preprocess.h"
-}
-
-//
-// The YY_INPUT macro just calls this. Maybe this could be just put into
-// the macro directly.
-//
-
-int yy_input(char* buf, int max_size)
-{
- int len;
-
- if ((len = yylex_CPP(buf, max_size)) == 0)
- return 0;
- if (len >= max_size)
- YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-
- buf[len] = ' ';
- return len+1;
-}
-
-
-//
-// Parse an array of strings using yyparse. We set up globals used by
-// yywrap.
-//
-// Returns 0 for success, as per yyparse().
-//
-int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal)
-{
- int argv0len;
-
- ScanFromString(argv[0]);
-
- //Storing the Current Compiler Parse context into the cpp structure.
- cpp->pC = (void*)&parseContextLocal;
-
- if (!argv || argc == 0)
- return 1;
-
- for (int i = 0; i < argc; ++i) {
- if (!argv[i]) {
- parseContextLocal.error(0, "Null shader source string", "", "");
- parseContextLocal.recover();
- return 1;
- }
- }
-
- if (!strLen) {
- argv0len = (int) strlen(argv[0]);
- strLen = &argv0len;
- }
- yyrestart(0);
- (&parseContextLocal)->AfterEOF = false;
- cpp->PaWhichStr = 0;
- cpp->PaArgv = argv;
- cpp->PaArgc = argc;
- cpp->PaStrLen = strLen;
- cpp->pastFirstStatement = 0;
- yylineno = 1;
-
- if (*cpp->PaStrLen >= 0) {
- int ret = yyparse((void*)(&parseContextLocal));
- if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
- return 1;
- else
- return 0;
- }
- else
- return 0;
-}
-
-void yyerror(const char *s)
-{
- if (((TParseContext *)cpp->pC)->AfterEOF) {
- if (cpp->tokensBeforeEOF == 1) {
- GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, "");
- GlobalParseContext->recover();
- }
- } else {
- GlobalParseContext->error(yylineno, "syntax error", yytext, s, "");
- GlobalParseContext->recover();
- }
-}
+// Preprocessor interface.
+#include "compiler/preprocessor/preprocess.h"
-void PaReservedWord()
-{
- GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", "");
- GlobalParseContext->recover();
-}
-
-int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol)
-{
- symbol = parseContextLocal.symbolTable.find(id);
- if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) {
- TVariable* variable = static_cast<TVariable*>(symbol);
- if (variable->isUserType()) {
- parseContextLocal.lexAfterType = true;
- return TYPE_NAME;
- }
- }
-
- return IDENTIFIER;
-}
-
-int PaParseComment(int &lineno, TParseContext& parseContextLocal)
-{
- int transitionFlag = 0;
- int nextChar;
-
- while (transitionFlag != 2) {
- nextChar = yyinput();
- if (nextChar == '\n')
- lineno++;
- switch (nextChar) {
- case '*' :
- transitionFlag = 1;
- break;
- case '/' : /* if star is the previous character, then it is the end of comment */
- if (transitionFlag == 1) {
- return 1 ;
- }
- break;
- case EOF :
- /* Raise error message here */
- parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", "");
- GlobalParseContext->recover();
- return YY_NULL;
- default : /* Any other character will be a part of the comment */
- transitionFlag = 0;
- }
- }
- return 1;
-}
-
-extern "C" {
+#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)
{
- ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg);
+ SETUP_CONTEXT(cpp);
+ context->infoSink.debug.message(EPrefixNone, msg);
}
void CPPWarningToInfoLog(const char *msg)
{
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno);
+ SETUP_CONTEXT(cpp);
+ context->warning(yylineno, msg, "", "");
}
void CPPShInfoLogMsg(const char *msg)
{
- ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,"");
- GlobalParseContext->recover();
+ SETUP_CONTEXT(cpp);
+ context->error(yylineno, msg, "", "");
+ context->recover();
}
void CPPErrorToInfoLog(char *msg)
{
- ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,"");
- GlobalParseContext->recover();
+ SETUP_CONTEXT(cpp);
+ context->error(yylineno, msg, "", "");
+ context->recover();
}
void SetLineNumber(int line)
{
- yylineno &= ~SourceLocLineMask;
- yylineno |= line;
+ SETUP_CONTEXT(cpp);
+ int string = 0;
+ DecodeSourceLoc(yylineno, &string, NULL);
+ yylineno = EncodeSourceLoc(string, line);
}
void SetStringNumber(int string)
{
- yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask);
+ SETUP_CONTEXT(cpp);
+ int line = 0;
+ DecodeSourceLoc(yylineno, NULL, &line);
+ yylineno = EncodeSourceLoc(string, line);
}
-int GetStringNumber(void)
+int GetStringNumber()
{
- return yylineno >> 16;
+ SETUP_CONTEXT(cpp);
+ int string = 0;
+ DecodeSourceLoc(yylineno, &string, NULL);
+ return string;
}
-int GetLineNumber(void)
+int GetLineNumber()
{
- return yylineno & SourceLocLineMask;
+ SETUP_CONTEXT(cpp);
+ int line = 0;
+ DecodeSourceLoc(yylineno, NULL, &line);
+ return line;
}
-void IncLineNumber(void)
+void IncLineNumber()
{
- if ((yylineno & SourceLocLineMask) <= SourceLocLineMask)
- ++yylineno;
+ SETUP_CONTEXT(cpp);
+ int string = 0, line = 0;
+ DecodeSourceLoc(yylineno, &string, &line);
+ yylineno = EncodeSourceLoc(string, ++line);
}
-void DecLineNumber(void)
+void DecLineNumber()
{
- if ((yylineno & SourceLocLineMask) > 0)
- --yylineno;
+ 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 (!strcmp(tokens[0], "optimize")) {
if (numTokens != 4) {
CPPShInfoLogMsg("optimize pragma syntax is incorrect");
@@ -452,9 +344,9 @@ void HandlePragma(const char **tokens, int numTokens)
}
if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = true;
+ context->contextPragma.optimize = true;
else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.optimize = false;
+ context->contextPragma.optimize = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
return;
@@ -476,9 +368,9 @@ void HandlePragma(const char **tokens, int numTokens)
}
if (!strcmp(tokens[2], "on"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = true;
+ context->contextPragma.debug = true;
else if (!strcmp(tokens[2], "off"))
- ((TParseContext *)cpp->pC)->contextPragma.debug = false;
+ context->contextPragma.debug = false;
else {
CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
return;
@@ -489,7 +381,6 @@ void HandlePragma(const char **tokens, int numTokens)
return;
}
} else {
-
#ifdef PRAGMA_TABLE
//
// implementation specific pragma
@@ -524,21 +415,24 @@ void HandlePragma(const char **tokens, int numTokens)
void StoreStr(char *string)
{
+ SETUP_CONTEXT(cpp);
TString strSrc;
strSrc = TString(string);
- ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc;
+ context->HashErrMsg = context->HashErrMsg + " " + strSrc;
}
const char* GetStrfromTStr(void)
{
- cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str();
+ SETUP_CONTEXT(cpp);
+ cpp->ErrMsg = context->HashErrMsg.c_str();
return cpp->ErrMsg;
}
void ResetTString(void)
{
- ((TParseContext *)cpp->pC)->HashErrMsg = "";
+ SETUP_CONTEXT(cpp);
+ context->HashErrMsg = "";
}
TBehavior GetBehavior(const char* behavior)
@@ -557,8 +451,9 @@ TBehavior GetBehavior(const char* behavior)
}
}
-void updateExtensionBehavior(const char* extName, const char* behavior)
+void updateExtensionBehavior(const char* extName, const char* behavior)
{
+ SETUP_CONTEXT(cpp);
TBehavior behaviorVal = GetBehavior(behavior);
TMap<TString, TBehavior>:: iterator iter;
TString msg;
@@ -569,12 +464,12 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
return;
} else {
- for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter)
+ for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
iter->second = behaviorVal;
}
} else {
- iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName));
- if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) {
+ iter = context->extensionBehavior.find(TString(extName));
+ if (iter == context->extensionBehavior.end()) {
switch (behaviorVal) {
case EBhRequire:
CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
@@ -583,7 +478,7 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
case EBhWarn:
case EBhDisable:
msg = TString("extension '") + extName + "' is not supported";
- ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
+ context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
break;
}
return;
@@ -591,10 +486,85 @@ void updateExtensionBehavior(const char* extName, const char* behavior)
iter->second = behaviorVal;
}
}
-
} // extern "C"
-void setInitialState()
-{
- yy_start = 1;
+int string_input(char* buf, int max_size, yyscan_t yyscanner) {
+ int len;
+
+ if ((len = yylex_CPP(buf, max_size)) == 0)
+ return 0;
+ if (len >= max_size)
+ YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+
+ buf[len] = ' ';
+ return len+1;
+}
+
+int check_type(yyscan_t yyscanner) {
+ struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+ int token = IDENTIFIER;
+ TSymbol* symbol = yyextra->symbolTable.find(yytext);
+ if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
+ TVariable* variable = static_cast<TVariable*>(symbol);
+ if (variable->isUserType()) {
+ yyextra->lexAfterType = true;
+ token = TYPE_NAME;
+ }
+ }
+ yylval->lex.symbol = symbol;
+ return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+ struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+ yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
+ yyextra->recover();
+ return 0;
}
+
+void yyerror(TParseContext* context, const char* reason) {
+ struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
+
+ if (context->AfterEOF) {
+ context->error(yylineno, reason, "unexpected EOF", "");
+ } else {
+ context->error(yylineno, reason, yytext, "");
+ }
+ context->recover();
+}
+
+int glslang_initialize(TParseContext* context) {
+ yyscan_t scanner = NULL;
+ if (yylex_init_extra(context, &scanner))
+ return 1;
+
+ context->scanner = scanner;
+ return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+ yyscan_t scanner = context->scanner;
+ if (scanner == NULL) return 0;
+
+ context->scanner = NULL;
+ return yylex_destroy(scanner);
+}
+
+void glslang_scan(int count, const char* const string[], const int length[],
+ TParseContext* context) {
+ yyrestart(NULL, context->scanner);
+ yyset_lineno(EncodeSourceLoc(0, 1), context->scanner);
+ context->AfterEOF = false;
+
+ // Init preprocessor.
+ cpp->pC = context;
+ cpp->PaWhichStr = 0;
+ cpp->PaArgv = string;
+ cpp->PaArgc = count;
+ cpp->PaStrLen = length;
+ cpp->pastFirstStatement = 0;
+ ScanFromString(string[0]);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.y b/Source/ThirdParty/ANGLE/src/compiler/glslang.y
index d0d29df..5eae4b5 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/glslang.y
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.y
@@ -1,89 +1,38 @@
+/*
//
// 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 is bison grammar and production code for parsing the OpenGL 2.0 shading
- * languages.
- */
-%{
-
-/* Based on:
-ANSI C Yacc grammar
+This file contains the Yacc grammar for GLSL ES.
+Based on ANSI C Yacc grammar:
+http://www.lysator.liu.se/c/ANSI-C-grammar-y.html
-In 1985, Jeff Lee published his Yacc grammar (which is accompanied by a
-matching Lex specification) for the April 30, 1985 draft version of the
-ANSI C standard. Tom Stockfisch reposted it to net.sources in 1987; that
-original, as mentioned in the answer to question 17.25 of the comp.lang.c
-FAQ, can be ftp'ed from ftp.uu.net, file usenet/net.sources/ansi.c.grammar.Z.
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_parser.sh,
+WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
+*/
-I intend to keep this version as close to the current C Standard grammar as
-possible; please let me know if you discover discrepancies.
+%{
+//
+// 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.
+//
-Jutta Degener, 1995
-*/
+// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
#include "compiler/SymbolTable.h"
#include "compiler/ParseHelper.h"
#include "GLSLANG/ShaderLang.h"
-#define YYPARSE_PARAM parseContextLocal
-/*
-TODO(alokp): YYPARSE_PARAM_DECL is only here to support old bison.exe in
-compiler/tools. Remove it when we can exclusively use the newer version.
-*/
-#define YYPARSE_PARAM_DECL void*
-#define parseContext ((TParseContext*)(parseContextLocal))
-#define YYLEX_PARAM parseContextLocal
-#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(const char*);
-
-#define FRAG_VERT_ONLY(S, L) { \
- if (parseContext->language != EShLangFragment && \
- parseContext->language != EShLangVertex) { \
- parseContext->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
-
-#define VERTEX_ONLY(S, L) { \
- if (parseContext->language != EShLangVertex) { \
- parseContext->error(L, " supported in vertex shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
-
-#define FRAG_ONLY(S, L) { \
- if (parseContext->language != EShLangFragment) { \
- parseContext->error(L, " supported in fragment shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
-
-#define PACK_ONLY(S, L) { \
- if (parseContext->language != EShLangPack) { \
- parseContext->error(L, " supported in pack shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
+#define YYLEX_PARAM context->scanner
+%}
-#define UNPACK_ONLY(S, L) { \
- if (parseContext->language != EShLangUnpack) { \
- parseContext->error(L, " supported in unpack shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
+%expect 1 /* One shift reduce conflict because of if | else */
+%pure-parser
+%parse-param {TParseContext* context}
-#define PACK_UNPACK_ONLY(S, L) { \
- if (parseContext->language != EShLangUnpack && \
- parseContext->language != EShLangPack) { \
- parseContext->error(L, " supported in pack/unpack shaders only ", S, "", ""); \
- parseContext->recover(); \
- } \
-}
-%}
%union {
struct {
TSourceLoc line;
@@ -117,11 +66,32 @@ extern void yyerror(const char*);
}
%{
- extern int yylex(YYSTYPE*, void*);
+extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
+extern void yyerror(TParseContext* context, const char* reason);
+
+#define FRAG_VERT_ONLY(S, L) { \
+ if (context->shaderType != SH_FRAGMENT_SHADER && \
+ context->shaderType != SH_VERTEX_SHADER) { \
+ context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
+
+#define VERTEX_ONLY(S, L) { \
+ if (context->shaderType != SH_VERTEX_SHADER) { \
+ context->error(L, " supported in vertex shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
+
+#define FRAG_ONLY(S, L) { \
+ if (context->shaderType != SH_FRAGMENT_SHADER) { \
+ context->error(L, " supported in fragment shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
%}
-%pure_parser /* Just in case is called from multiple threads */
-%expect 1 /* One shift reduce conflict because of if | else */
%token <lex> INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
@@ -185,17 +155,17 @@ variable_identifier
const TSymbol* symbol = $1.symbol;
const TVariable* variable;
if (symbol == 0) {
- parseContext->error($1.line, "undeclared identifier", $1.string->c_str(), "");
- parseContext->recover();
+ context->error($1.line, "undeclared identifier", $1.string->c_str(), "");
+ context->recover();
TType type(EbtFloat, EbpUndefined);
TVariable* fakeVariable = new TVariable($1.string, type);
- parseContext->symbolTable.insert(*fakeVariable);
+ context->symbolTable.insert(*fakeVariable);
variable = fakeVariable;
} else {
// This identifier can only be a variable type symbol
if (! symbol->isVariable()) {
- parseContext->error($1.line, "variable expected", $1.string->c_str(), "");
- parseContext->recover();
+ context->error($1.line, "variable expected", $1.string->c_str(), "");
+ context->recover();
}
variable = static_cast<const TVariable*>(symbol);
}
@@ -206,9 +176,9 @@ variable_identifier
if (variable->getType().getQualifier() == EvqConst ) {
ConstantUnion* constArray = variable->getConstPointer();
TType t(variable->getType());
- $$ = parseContext->intermediate.addConstantUnion(constArray, t, $1.line);
+ $$ = context->intermediate.addConstantUnion(constArray, t, $1.line);
} else
- $$ = parseContext->intermediate.addSymbol(variable->getUniqueId(),
+ $$ = context->intermediate.addSymbol(variable->getUniqueId(),
variable->getName(),
variable->getType(), $1.line);
}
@@ -224,22 +194,22 @@ primary_expression
// check for overflow for constants
//
if (abs($1.i) >= (1 << 16)) {
- parseContext->error($1.line, " integer constant overflow", "", "");
- parseContext->recover();
+ context->error($1.line, " integer constant overflow", "", "");
+ context->recover();
}
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst($1.i);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $1.line);
}
| FLOATCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst($1.f);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
}
| BOOLCONSTANT {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst($1.b);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $1.line);
}
| LEFT_PAREN expression RIGHT_PAREN {
$$ = $2;
@@ -253,57 +223,57 @@ postfix_expression
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
if ($1->getAsSymbolNode())
- parseContext->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
+ context->error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
else
- parseContext->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
- parseContext->recover();
+ context->error($2.line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+ context->recover();
}
if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == EvqConst) {
if ($1->isArray()) { // constant folding for arrays
- $$ = parseContext->addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+ $$ = context->addConstArrayNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $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
- $$ = parseContext->addConstVectorNode(fields, $1, $2.line);
+ $$ = context->addConstVectorNode(fields, $1, $2.line);
} else if ($1->isMatrix()) { // constant folding for matrices
- $$ = parseContext->addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
+ $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), $1, $2.line);
}
} else {
if ($3->getQualifier() == EvqConst) {
if (($1->isVector() || $1->isMatrix()) && $1->getType().getNominalSize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !$1->isArray() ) {
- parseContext->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
- parseContext->recover();
+ context->error($2.line, "", "[", "field selection out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+ context->recover();
} else {
if ($1->isArray()) {
if ($1->getType().getArraySize() == 0) {
if ($1->getType().getMaxArraySize() <= $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
- if (parseContext->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
- parseContext->recover();
+ if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, $2.line))
+ context->recover();
} else {
- if (parseContext->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
- parseContext->recover();
+ if (context->arraySetMaxSize($1->getAsSymbolNode(), $1->getTypePointer(), 0, false, $2.line))
+ context->recover();
}
} else if ( $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= $1->getType().getArraySize()) {
- parseContext->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
- parseContext->recover();
+ context->error($2.line, "", "[", "array index out of range '%d'", $3->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+ context->recover();
}
}
- $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
+ $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, $2.line);
}
} else {
if ($1->isArray() && $1->getType().getArraySize() == 0) {
- parseContext->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
- parseContext->recover();
+ context->error($2.line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+ context->recover();
}
- $$ = parseContext->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
+ $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, $2.line);
}
}
if ($$ == 0) {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), $2.line);
} else if ($1->isArray()) {
if ($1->getType().getStruct())
$$->setType(TType($1->getType().getStruct(), $1->getType().getTypeName()));
@@ -328,22 +298,22 @@ postfix_expression
}
| postfix_expression DOT FIELD_SELECTION {
if ($1->isArray()) {
- parseContext->error($3.line, "cannot apply dot operator to an array", ".", "");
- parseContext->recover();
+ context->error($3.line, "cannot apply dot operator to an array", ".", "");
+ context->recover();
}
if ($1->isVector()) {
TVectorFields fields;
- if (! parseContext->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+ if (! context->parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.num = 1;
fields.offsets[0] = 0;
- parseContext->recover();
+ context->recover();
}
if ($1->getType().getQualifier() == EvqConst) { // constant folding for vector fields
- $$ = parseContext->addConstVectorNode(fields, $1, $3.line);
+ $$ = context->addConstVectorNode(fields, $1, $3.line);
if ($$ == 0) {
- parseContext->recover();
+ context->recover();
$$ = $1;
}
else
@@ -352,47 +322,47 @@ postfix_expression
if (fields.num == 1) {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.offsets[0]);
- TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
- $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+ $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision()));
} else {
TString vectorString = *$3.string;
- TIntermTyped* index = parseContext->intermediate.addSwizzle(fields, $3.line);
- $$ = parseContext->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
+ TIntermTyped* index = context->intermediate.addSwizzle(fields, $3.line);
+ $$ = context->intermediate.addIndex(EOpVectorSwizzle, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, (int) vectorString.size()));
}
}
} else if ($1->isMatrix()) {
TMatrixFields fields;
- if (! parseContext->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
+ if (! context->parseMatrixFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.wholeRow = false;
fields.wholeCol = false;
fields.row = 0;
fields.col = 0;
- parseContext->recover();
+ context->recover();
}
if (fields.wholeRow || fields.wholeCol) {
- parseContext->error($2.line, " non-scalar fields not implemented yet", ".", "");
- parseContext->recover();
+ context->error($2.line, " non-scalar fields not implemented yet", ".", "");
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(0);
- TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
- $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+ $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision(),EvqTemporary, $1->getNominalSize()));
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(fields.col * $1->getNominalSize() + fields.row);
- TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
- $$ = parseContext->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), $3.line);
+ $$ = context->intermediate.addIndex(EOpIndexDirect, $1, index, $2.line);
$$->setType(TType($1->getBasicType(), $1->getPrecision()));
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
- parseContext->error($2.line, "structure has no fields", "Internal Error", "");
- parseContext->recover();
+ context->error($2.line, "structure has no fields", "Internal Error", "");
+ context->recover();
$$ = $1;
} else {
unsigned int i;
@@ -404,9 +374,9 @@ postfix_expression
}
if (fieldFound) {
if ($1->getType().getQualifier() == EvqConst) {
- $$ = parseContext->addConstStruct(*$3.string, $1, $2.line);
+ $$ = context->addConstStruct(*$3.string, $1, $2.line);
if ($$ == 0) {
- parseContext->recover();
+ context->recover();
$$ = $1;
}
else {
@@ -418,40 +388,40 @@ postfix_expression
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setIConst(i);
- TIntermTyped* index = parseContext->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
- $$ = parseContext->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, $3.line);
+ $$ = context->intermediate.addIndex(EOpIndexDirectStruct, $1, index, $2.line);
$$->setType(*(*fields)[i].type);
}
} else {
- parseContext->error($2.line, " no such field in structure", $3.string->c_str(), "");
- parseContext->recover();
+ context->error($2.line, " no such field in structure", $3.string->c_str(), "");
+ context->recover();
$$ = $1;
}
}
} else {
- parseContext->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
- parseContext->recover();
+ context->error($2.line, " field selection requires structure, vector, or matrix on left hand side", $3.string->c_str(), "");
+ context->recover();
$$ = $1;
}
// don't delete $3.string, it's from the pool
}
| postfix_expression INC_OP {
- if (parseContext->lValueErrorCheck($2.line, "++", $1))
- parseContext->recover();
- $$ = parseContext->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext->symbolTable);
+ if (context->lValueErrorCheck($2.line, "++", $1))
+ context->recover();
+ $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->unaryOpError($2.line, "++", $1->getCompleteString());
- parseContext->recover();
+ context->unaryOpError($2.line, "++", $1->getCompleteString());
+ context->recover();
$$ = $1;
}
}
| postfix_expression DEC_OP {
- if (parseContext->lValueErrorCheck($2.line, "--", $1))
- parseContext->recover();
- $$ = parseContext->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext->symbolTable);
+ if (context->lValueErrorCheck($2.line, "--", $1))
+ context->recover();
+ $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->unaryOpError($2.line, "--", $1->getCompleteString());
- parseContext->recover();
+ context->unaryOpError($2.line, "--", $1->getCompleteString());
+ context->recover();
$$ = $1;
}
}
@@ -459,8 +429,8 @@ postfix_expression
integer_expression
: expression {
- if (parseContext->integerErrorCheck($1, "[]"))
- parseContext->recover();
+ if (context->integerErrorCheck($1, "[]"))
+ context->recover();
$$ = $1;
}
;
@@ -478,18 +448,18 @@ function_call
// Their parameters will be verified algorithmically.
//
TType type(EbtVoid, EbpUndefined); // use this to get the type back
- if (parseContext->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
+ if (context->constructorErrorCheck($1.line, $1.intermNode, *fnCall, op, &type)) {
$$ = 0;
} else {
//
// It's a constructor, of type 'type'.
//
- $$ = parseContext->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
+ $$ = context->addConstructor($1.intermNode, &type, op, fnCall, $1.line);
}
if ($$ == 0) {
- parseContext->recover();
- $$ = parseContext->intermediate.setAggregateOperator(0, op, $1.line);
+ context->recover();
+ $$ = context->intermediate.setAggregateOperator(0, op, $1.line);
}
$$->setType(type);
} else {
@@ -498,12 +468,15 @@ function_call
//
const TFunction* fnCandidate;
bool builtIn;
- fnCandidate = parseContext->findFunction($1.line, fnCall, &builtIn);
+ fnCandidate = context->findFunction($1.line, fnCall, &builtIn);
if (fnCandidate) {
//
- // A declared function. But, it might still map to a built-in
- // operation.
+ // A declared function.
//
+ if (builtIn && !fnCandidate->getExtension().empty() &&
+ context->extensionErrorCheck($1.line, fnCandidate->getExtension())) {
+ context->recover();
+ }
op = fnCandidate->getBuiltInOp();
if (builtIn && op != EOpNull) {
//
@@ -513,20 +486,20 @@ function_call
//
// Treat it like a built-in unary operator.
//
- $$ = parseContext->intermediate.addUnaryMath(op, $1.intermNode, 0, parseContext->symbolTable);
+ $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable);
if ($$ == 0) {
- parseContext->error($1.intermNode->getLine(), " wrong operand type", "Internal Error",
+ context->error($1.intermNode->getLine(), " wrong operand type", "Internal Error",
"built in unary operator function. Type: %s",
static_cast<TIntermTyped*>($1.intermNode)->getCompleteString().c_str());
YYERROR;
}
} else {
- $$ = parseContext->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
+ $$ = context->intermediate.setAggregateOperator($1.intermAggregate, op, $1.line);
}
} else {
// This is a real function call
- $$ = parseContext->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
+ $$ = context->intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, $1.line);
$$->setType(fnCandidate->getReturnType());
// this is how we know whether the given function is a builtIn function or a user defined function
@@ -537,16 +510,14 @@ function_call
$$->getAsAggregate()->setName(fnCandidate->getMangledName());
TQualifier qual;
- TQualifierList& qualifierList = $$->getAsAggregate()->getQualifier();
for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
- qual = (*fnCandidate)[i].type->getQualifier();
+ qual = fnCandidate->getParam(i).type->getQualifier();
if (qual == EvqOut || qual == EvqInOut) {
- if (parseContext->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
- parseContext->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
- parseContext->recover();
+ if (context->lValueErrorCheck($$->getLine(), "assign", $$->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+ context->error($1.intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+ context->recover();
}
}
- qualifierList.push_back(qual);
}
}
$$->setType(fnCandidate->getReturnType());
@@ -555,8 +526,8 @@ function_call
// Put on a dummy node for error recovery
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setFConst(0.0f);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
- parseContext->recover();
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), $1.line);
+ context->recover();
}
}
delete fnCall;
@@ -568,8 +539,8 @@ function_call_or_method
$$ = $1;
}
| postfix_expression DOT function_call_generic {
- parseContext->error($3.line, "methods are not supported", "", "");
- parseContext->recover();
+ context->error($3.line, "methods are not supported", "", "");
+ context->recover();
$$ = $3;
}
;
@@ -607,7 +578,7 @@ function_call_header_with_parameters
TParameter param = { 0, new TType($3->getType()) };
$1.function->addParameter(param);
$$.function = $1.function;
- $$.intermNode = parseContext->intermediate.growAggregate($1.intermNode, $3, $2.line);
+ $$.intermNode = context->intermediate.growAggregate($1.intermNode, $3, $2.line);
}
;
@@ -625,19 +596,16 @@ function_identifier
// Constructor
//
if ($1.array) {
- if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
- parseContext->recover();
- $1.setArray(false);
- }
+ // Constructors for arrays are not allowed.
+ context->error($1.line, "cannot construct this type", "array", "");
+ context->recover();
+ $1.setArray(false);
}
+ TOperator op = EOpNull;
if ($1.userDef) {
- TString tempString = "";
- TType type($1);
- TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
- $$ = function;
+ op = EOpConstructStruct;
} else {
- TOperator op = EOpNull;
switch ($1.type) {
case EbtFloat:
if ($1.matrix) {
@@ -671,29 +639,30 @@ function_identifier
case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
}
break;
+ default: break;
}
if (op == EOpNull) {
- parseContext->error($1.line, "cannot construct this type", getBasicString($1.type), "");
- parseContext->recover();
+ context->error($1.line, "cannot construct this type", getBasicString($1.type), "");
+ context->recover();
$1.type = EbtFloat;
op = EOpConstructFloat;
}
- TString tempString = "";
- TType type($1);
- TFunction *function = new TFunction(&tempString, type, op);
- $$ = function;
}
+ TString tempString;
+ TType type($1);
+ TFunction *function = new TFunction(&tempString, type, op);
+ $$ = function;
}
| IDENTIFIER {
- if (parseContext->reservedErrorCheck($1.line, *$1.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($1.line, *$1.string))
+ context->recover();
TType type(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type);
$$ = function;
}
| FIELD_SELECTION {
- if (parseContext->reservedErrorCheck($1.line, *$1.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($1.line, *$1.string))
+ context->recover();
TType type(EbtVoid, EbpUndefined);
TFunction *function = new TFunction($1.string, type);
$$ = function;
@@ -705,28 +674,28 @@ unary_expression
$$ = $1;
}
| INC_OP unary_expression {
- if (parseContext->lValueErrorCheck($1.line, "++", $2))
- parseContext->recover();
- $$ = parseContext->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, parseContext->symbolTable);
+ if (context->lValueErrorCheck($1.line, "++", $2))
+ context->recover();
+ $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable);
if ($$ == 0) {
- parseContext->unaryOpError($1.line, "++", $2->getCompleteString());
- parseContext->recover();
+ context->unaryOpError($1.line, "++", $2->getCompleteString());
+ context->recover();
$$ = $2;
}
}
| DEC_OP unary_expression {
- if (parseContext->lValueErrorCheck($1.line, "--", $2))
- parseContext->recover();
- $$ = parseContext->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, parseContext->symbolTable);
+ if (context->lValueErrorCheck($1.line, "--", $2))
+ context->recover();
+ $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable);
if ($$ == 0) {
- parseContext->unaryOpError($1.line, "--", $2->getCompleteString());
- parseContext->recover();
+ context->unaryOpError($1.line, "--", $2->getCompleteString());
+ context->recover();
$$ = $2;
}
}
| unary_operator unary_expression {
if ($1.op != EOpNull) {
- $$ = parseContext->intermediate.addUnaryMath($1.op, $2, $1.line, parseContext->symbolTable);
+ $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable);
if ($$ == 0) {
const char* errorOp = "";
switch($1.op) {
@@ -734,8 +703,8 @@ unary_expression
case EOpLogicalNot: errorOp = "!"; break;
default: break;
}
- parseContext->unaryOpError($1.line, errorOp, $2->getCompleteString());
- parseContext->recover();
+ context->unaryOpError($1.line, errorOp, $2->getCompleteString());
+ context->recover();
$$ = $2;
}
} else
@@ -755,19 +724,19 @@ multiplicative_expression
: unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression {
FRAG_VERT_ONLY("*", $2.line);
- $$ = parseContext->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $1;
}
}
| multiplicative_expression SLASH unary_expression {
FRAG_VERT_ONLY("/", $2.line);
- $$ = parseContext->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $1;
}
}
@@ -776,18 +745,18 @@ multiplicative_expression
additive_expression
: multiplicative_expression { $$ = $1; }
| additive_expression PLUS multiplicative_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $1;
}
}
| additive_expression DASH multiplicative_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $1;
}
}
@@ -800,43 +769,43 @@ shift_expression
relational_expression
: shift_expression { $$ = $1; }
| relational_expression LEFT_ANGLE shift_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
| relational_expression RIGHT_ANGLE shift_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
| relational_expression LE_OP shift_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
| relational_expression GE_OP shift_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
;
@@ -844,26 +813,24 @@ relational_expression
equality_expression
: relational_expression { $$ = $1; }
| equality_expression EQ_OP relational_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
- } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
- parseContext->recover();
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ }
}
| equality_expression NE_OP relational_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
- } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
- parseContext->recover();
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ }
}
;
@@ -882,13 +849,13 @@ inclusive_or_expression
logical_and_expression
: inclusive_or_expression { $$ = $1; }
| logical_and_expression AND_OP inclusive_or_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
;
@@ -896,13 +863,13 @@ logical_and_expression
logical_xor_expression
: logical_and_expression { $$ = $1; }
| logical_xor_expression XOR_OP logical_and_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
;
@@ -910,13 +877,13 @@ logical_xor_expression
logical_or_expression
: logical_xor_expression { $$ = $1; }
| logical_or_expression OR_OP logical_xor_expression {
- $$ = parseContext->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, parseContext->symbolTable);
+ $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, context->symbolTable);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
ConstantUnion *unionArray = new ConstantUnion[1];
unionArray->setBConst(false);
- $$ = parseContext->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
+ $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), $2.line);
}
}
;
@@ -924,16 +891,16 @@ logical_or_expression
conditional_expression
: logical_or_expression { $$ = $1; }
| logical_or_expression QUESTION expression COLON assignment_expression {
- if (parseContext->boolErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->boolErrorCheck($2.line, $1))
+ context->recover();
- $$ = parseContext->intermediate.addSelection($1, $3, $5, $2.line);
+ $$ = context->intermediate.addSelection($1, $3, $5, $2.line);
if ($3->getType() != $5->getType())
$$ = 0;
if ($$ == 0) {
- parseContext->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, ":", $3->getCompleteString(), $5->getCompleteString());
+ context->recover();
$$ = $5;
}
}
@@ -942,15 +909,14 @@ conditional_expression
assignment_expression
: conditional_expression { $$ = $1; }
| unary_expression assignment_operator assignment_expression {
- if (parseContext->lValueErrorCheck($2.line, "assign", $1))
- parseContext->recover();
- $$ = parseContext->intermediate.addAssign($2.op, $1, $3, $2.line);
+ if (context->lValueErrorCheck($2.line, "assign", $1))
+ context->recover();
+ $$ = context->intermediate.addAssign($2.op, $1, $3, $2.line);
if ($$ == 0) {
- parseContext->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->assignError($2.line, "assign", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $1;
- } else if (($1->isArray() || $3->isArray()) && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects"))
- parseContext->recover();
+ }
}
;
@@ -967,10 +933,10 @@ expression
$$ = $1;
}
| expression COMMA assignment_expression {
- $$ = parseContext->intermediate.addComma($1, $3, $2.line);
+ $$ = context->intermediate.addComma($1, $3, $2.line);
if ($$ == 0) {
- parseContext->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
- parseContext->recover();
+ context->binaryOpError($2.line, ",", $1->getCompleteString(), $3->getCompleteString());
+ context->recover();
$$ = $3;
}
}
@@ -978,8 +944,8 @@ expression
constant_expression
: conditional_expression {
- if (parseContext->constErrorCheck($1))
- parseContext->recover();
+ if (context->constErrorCheck($1))
+ context->recover();
$$ = $1;
}
;
@@ -994,16 +960,16 @@ declaration
for (int i = 0; i < function.getParamCount(); i++)
{
- TParameter &param = function[i];
+ const TParameter &param = function.getParam(i);
if (param.name != 0)
{
TVariable *variable = new TVariable(param.name, *param.type);
- prototype = parseContext->intermediate.growAggregate(prototype, parseContext->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line);
}
else
{
- prototype = parseContext->intermediate.growAggregate(prototype, parseContext->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
}
}
@@ -1016,7 +982,7 @@ declaration
$$ = $1.intermAggregate;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
- parseContext->symbolTable.setDefaultPrecision( $3.type, $2 );
+ context->symbolTable.setDefaultPrecision( $3.type, $2 );
$$ = 0;
}
;
@@ -1031,16 +997,16 @@ function_prototype
//
// Redeclarations are allowed. But, return types and parameter qualifiers must match.
//
- TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find($1->getMangledName()));
+ TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find($1->getMangledName()));
if (prevDec) {
if (prevDec->getReturnType() != $1->getReturnType()) {
- parseContext->error($2.line, "overloaded functions must have the same return type", $1->getReturnType().getBasicString(), "");
- parseContext->recover();
+ 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) {
- if ((*prevDec)[i].type->getQualifier() != (*$1)[i].type->getQualifier()) {
- parseContext->error($2.line, "overloaded functions must have the same parameter qualifiers", (*$1)[i].type->getQualifierString(), "");
- parseContext->recover();
+ 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();
}
}
}
@@ -1053,7 +1019,7 @@ function_prototype
$$.function = $1;
$$.line = $2.line;
- parseContext->symbolTable.insert(*$$.function);
+ context->symbolTable.insert(*$$.function);
}
;
@@ -1085,8 +1051,8 @@ function_header_with_parameters
//
// This parameter > first is void
//
- parseContext->error($2.line, "cannot be an argument type except for '(void)'", "void", "");
- parseContext->recover();
+ context->error($2.line, "cannot be an argument type except for '(void)'", "void", "");
+ context->recover();
delete $3.param.type;
} else {
// Add the parameter
@@ -1099,12 +1065,12 @@ function_header_with_parameters
function_header
: fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) {
- parseContext->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
- parseContext->recover();
+ context->error($2.line, "no qualifiers allowed for function return", getQualifierString($1.qualifier), "");
+ context->recover();
}
// make sure a sampler is not involved as well...
- if (parseContext->structQualifierErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $1))
+ context->recover();
// Add the function as a prototype after parsing it (we do not support recursion)
TFunction *function;
@@ -1118,26 +1084,26 @@ parameter_declarator
// Type + name
: type_specifier IDENTIFIER {
if ($1.type == EbtVoid) {
- parseContext->error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
- parseContext->recover();
+ context->error($2.line, "illegal use of type 'void'", $2.string->c_str(), "");
+ context->recover();
}
- if (parseContext->reservedErrorCheck($2.line, *$2.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($2.line, *$2.string))
+ context->recover();
TParameter param = {$2.string, new TType($1)};
$$.line = $2.line;
$$.param = param;
}
| type_specifier IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
// Check that we can make an array out of this type
- if (parseContext->arrayTypeErrorCheck($3.line, $1))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($3.line, $1))
+ context->recover();
- if (parseContext->reservedErrorCheck($2.line, *$2.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($2.line, *$2.string))
+ context->recover();
int size;
- if (parseContext->arraySizeErrorCheck($3.line, $4, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($3.line, $4, size))
+ context->recover();
$1.setArray(true, size);
TType* type = new TType($1);
@@ -1158,30 +1124,30 @@ parameter_declaration
//
: type_qualifier parameter_qualifier parameter_declarator {
$$ = $3;
- if (parseContext->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
- parseContext->recover();
+ if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+ context->recover();
}
| parameter_qualifier parameter_declarator {
$$ = $2;
- if (parseContext->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
- parseContext->recover();
- if (parseContext->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
- parseContext->recover();
+ if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+ context->recover();
+ if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+ context->recover();
}
//
// Only type
//
| type_qualifier parameter_qualifier parameter_type_specifier {
$$ = $3;
- if (parseContext->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
- parseContext->recover();
+ if (context->paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
+ context->recover();
}
| parameter_qualifier parameter_type_specifier {
$$ = $2;
- if (parseContext->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
- parseContext->recover();
- if (parseContext->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
- parseContext->recover();
+ if (context->parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
+ context->recover();
+ if (context->paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
+ context->recover();
}
;
@@ -1212,152 +1178,83 @@ init_declarator_list
$$ = $1;
if ($$.type.precision == EbpUndefined) {
- $$.type.precision = parseContext->symbolTable.getDefaultPrecision($1.type.type);
- if (parseContext->precisionErrorCheck($1.line, $$.type.precision, $1.type.type)) {
- parseContext->recover();
+ $$.type.precision = context->symbolTable.getDefaultPrecision($1.type.type);
+ if (context->precisionErrorCheck($1.line, $$.type.precision, $1.type.type)) {
+ context->recover();
}
}
}
| init_declarator_list COMMA IDENTIFIER {
- $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, parseContext->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line);
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line);
- if (parseContext->structQualifierErrorCheck($3.line, $$.type))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($3.line, $$.type))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $$.type))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type))
+ context->recover();
- if (parseContext->nonInitErrorCheck($3.line, *$3.string, $$.type))
- parseContext->recover();
+ if (context->nonInitErrorCheck($3.line, *$3.string, $$.type))
+ context->recover();
}
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- if (parseContext->structQualifierErrorCheck($3.line, $1.type))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($3.line, $1.type))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+ context->recover();
$$ = $1;
- if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+ context->recover();
else {
$1.type.setArray(true);
TVariable* variable;
- if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
- parseContext->recover();
+ if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+ context->recover();
}
}
| init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- if (parseContext->structQualifierErrorCheck($3.line, $1.type))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($3.line, $1.type))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($3.line, *$3.string, $1.type))
+ context->recover();
$$ = $1;
- if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($4.line, $1.type) || context->arrayQualifierErrorCheck($4.line, $1.type))
+ context->recover();
else {
int size;
- if (parseContext->arraySizeErrorCheck($4.line, $5, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($4.line, $5, size))
+ context->recover();
$1.type.setArray(true, size);
TVariable* variable;
- if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
- parseContext->recover();
+ if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
+ context->recover();
TType type = TType($1.type);
type.setArraySize(size);
- $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, parseContext->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
- }
- }
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET EQUAL initializer {
- if (parseContext->structQualifierErrorCheck($3.line, $1.type))
- parseContext->recover();
-
- $$ = $1;
-
- TVariable* variable = 0;
- if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
- parseContext->recover();
- else {
- $1.type.setArray(true, $7->getType().getArraySize());
- if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
- parseContext->recover();
- }
-
- if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
- parseContext->recover();
- else {
- TIntermNode* intermNode;
- if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $7, intermNode, variable)) {
- //
- // build the intermediate representation
- //
- if (intermNode)
- $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $6.line);
- else
- $$.intermAggregate = $1.intermAggregate;
- } else {
- parseContext->recover();
- $$.intermAggregate = 0;
- }
- }
- }
- | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET EQUAL initializer {
- if (parseContext->structQualifierErrorCheck($3.line, $1.type))
- parseContext->recover();
-
- $$ = $1;
-
- TVariable* variable = 0;
- if (parseContext->arrayTypeErrorCheck($4.line, $1.type) || parseContext->arrayQualifierErrorCheck($4.line, $1.type))
- parseContext->recover();
- else {
- int size;
- if (parseContext->arraySizeErrorCheck($4.line, $5, size))
- parseContext->recover();
- $1.type.setArray(true, size);
- if (parseContext->arrayErrorCheck($4.line, *$3.string, $1.type, variable))
- parseContext->recover();
- }
-
- if (parseContext->extensionErrorCheck($$.line, "GL_3DL_array_objects"))
- parseContext->recover();
- else {
- TIntermNode* intermNode;
- if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $8, intermNode, variable)) {
- //
- // build the intermediate representation
- //
- if (intermNode)
- $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $7.line);
- else
- $$.intermAggregate = $1.intermAggregate;
- } else {
- parseContext->recover();
- $$.intermAggregate = 0;
- }
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line);
}
}
| init_declarator_list COMMA IDENTIFIER EQUAL initializer {
- if (parseContext->structQualifierErrorCheck($3.line, $1.type))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($3.line, $1.type))
+ context->recover();
$$ = $1;
TIntermNode* intermNode;
- if (!parseContext->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
+ if (!context->executeInitializer($3.line, *$3.string, $1.type, $5, intermNode)) {
//
// build the intermediate representation
//
if (intermNode)
- $$.intermAggregate = parseContext->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
+ $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, intermNode, $4.line);
else
$$.intermAggregate = $1.intermAggregate;
} else {
- parseContext->recover();
+ context->recover();
$$.intermAggregate = 0;
}
}
@@ -1366,88 +1263,88 @@ init_declarator_list
single_declaration
: fully_specified_type {
$$.type = $1;
- $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line);
}
| fully_specified_type IDENTIFIER {
- $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
- if (parseContext->structQualifierErrorCheck($2.line, $$.type))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $$.type))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $$.type))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($2.line, *$2.string, $$.type))
+ context->recover();
$$.type = $1;
- if (parseContext->nonInitErrorCheck($2.line, *$2.string, $$.type))
- parseContext->recover();
+ if (context->nonInitErrorCheck($2.line, *$2.string, $$.type))
+ context->recover();
}
| fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
- $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line);
- if (parseContext->structQualifierErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $1))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $1))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
+ context->recover();
$$.type = $1;
- if (parseContext->arrayTypeErrorCheck($3.line, $1) || parseContext->arrayQualifierErrorCheck($3.line, $1))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+ context->recover();
else {
$1.setArray(true);
TVariable* variable;
- if (parseContext->arrayErrorCheck($3.line, *$2.string, $1, variable))
- parseContext->recover();
+ if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+ context->recover();
}
}
| fully_specified_type IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
TType type = TType($1);
int size;
- if (parseContext->arraySizeErrorCheck($2.line, $4, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($2.line, $4, size))
+ context->recover();
type.setArraySize(size);
- $$.intermAggregate = parseContext->intermediate.makeAggregate(parseContext->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line);
- if (parseContext->structQualifierErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $1))
+ context->recover();
- if (parseContext->nonInitConstErrorCheck($2.line, *$2.string, $1))
- parseContext->recover();
+ if (context->nonInitConstErrorCheck($2.line, *$2.string, $1))
+ context->recover();
$$.type = $1;
- if (parseContext->arrayTypeErrorCheck($3.line, $1) || parseContext->arrayQualifierErrorCheck($3.line, $1))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1))
+ context->recover();
else {
int size;
- if (parseContext->arraySizeErrorCheck($3.line, $4, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($3.line, $4, size))
+ context->recover();
$1.setArray(true, size);
TVariable* variable;
- if (parseContext->arrayErrorCheck($3.line, *$2.string, $1, variable))
- parseContext->recover();
+ if (context->arrayErrorCheck($3.line, *$2.string, $1, variable))
+ context->recover();
}
}
| fully_specified_type IDENTIFIER EQUAL initializer {
- if (parseContext->structQualifierErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $1))
+ context->recover();
$$.type = $1;
TIntermNode* intermNode;
- if (!parseContext->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
+ if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode)) {
//
// Build intermediate representation
//
if(intermNode)
- $$.intermAggregate = parseContext->intermediate.makeAggregate(intermNode, $3.line);
+ $$.intermAggregate = context->intermediate.makeAggregate(intermNode, $3.line);
else
$$.intermAggregate = 0;
} else {
- parseContext->recover();
+ context->recover();
$$.intermAggregate = 0;
}
}
@@ -1479,14 +1376,14 @@ single_declaration
//
//input_or_output
// : INPUT {
-// if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "input"))
-// parseContext->recover();
+// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "input"))
+// context->recover();
// UNPACK_ONLY("input", $1.line);
// $$.qualifier = EvqInput;
// }
// | OUTPUT {
-// if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "output"))
-// parseContext->recover();
+// if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "output"))
+// context->recover();
// PACK_ONLY("output", $1.line);
// $$.qualifier = EvqOutput;
// }
@@ -1515,12 +1412,12 @@ single_declaration
//
//buffer_declaration
// : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
-// if (parseContext->reservedErrorCheck($2.line, *$2.string, parseContext))
-// parseContext->recover();
+// if (context->reservedErrorCheck($2.line, *$2.string, context))
+// context->recover();
// $$.variable = new TVariable($2.string, $1);
-// if (! parseContext->symbolTable.insert(*$$.variable)) {
-// parseContext->error($2.line, "redefinition", $$.variable->getName().c_str(), "");
-// parseContext->recover();
+// if (! context->symbolTable.insert(*$$.variable)) {
+// context->error($2.line, "redefinition", $$.variable->getName().c_str(), "");
+// context->recover();
// // don't have to delete $$.variable, the pool pop will take care of it
// }
// }
@@ -1531,31 +1428,27 @@ fully_specified_type
$$ = $1;
if ($1.array) {
- if (parseContext->extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
- parseContext->recover();
- $1.setArray(false);
- }
+ context->error($1.line, "not supported", "first-class array", "");
+ context->recover();
+ $1.setArray(false);
}
}
| type_qualifier type_specifier {
- if ($2.array && parseContext->extensionErrorCheck($2.line, "GL_3DL_array_objects")) {
- parseContext->recover();
- $2.setArray(false);
- }
- if ($2.array && parseContext->arrayQualifierErrorCheck($2.line, $1)) {
- parseContext->recover();
+ if ($2.array) {
+ context->error($2.line, "not supported", "first-class array", "");
+ context->recover();
$2.setArray(false);
}
if ($1.qualifier == EvqAttribute &&
($2.type == EbtBool || $2.type == EbtInt)) {
- parseContext->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
- parseContext->recover();
+ context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+ context->recover();
}
if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &&
($2.type == EbtBool || $2.type == EbtInt)) {
- parseContext->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
- parseContext->recover();
+ context->error($2.line, "cannot be bool or int", getQualifierString($1.qualifier), "");
+ context->recover();
}
$$ = $2;
$$.qualifier = $1.qualifier;
@@ -1568,29 +1461,29 @@ type_qualifier
}
| ATTRIBUTE {
VERTEX_ONLY("attribute", $1.line);
- if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "attribute"))
- parseContext->recover();
+ if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "attribute"))
+ context->recover();
$$.setBasic(EbtVoid, EvqAttribute, $1.line);
}
| VARYING {
- if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "varying"))
- parseContext->recover();
- if (parseContext->language == EShLangVertex)
+ if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "varying"))
+ context->recover();
+ if (context->shaderType == SH_VERTEX_SHADER)
$$.setBasic(EbtVoid, EvqVaryingOut, $1.line);
else
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
}
| INVARIANT VARYING {
- if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "invariant varying"))
- parseContext->recover();
- if (parseContext->language == EShLangVertex)
+ if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+ context->recover();
+ if (context->shaderType == SH_VERTEX_SHADER)
$$.setBasic(EbtVoid, EvqInvariantVaryingOut, $1.line);
else
$$.setBasic(EbtVoid, EvqInvariantVaryingIn, $1.line);
}
| UNIFORM {
- if (parseContext->globalErrorCheck($1.line, parseContext->symbolTable.atGlobalLevel(), "uniform"))
- parseContext->recover();
+ if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "uniform"))
+ context->recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
;
@@ -1624,12 +1517,12 @@ type_specifier_no_prec
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1;
- if (parseContext->arrayTypeErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($2.line, $1))
+ context->recover();
else {
int size;
- if (parseContext->arraySizeErrorCheck($2.line, $3, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($2.line, $3, size))
+ context->recover();
$$.setArray(true, size);
}
}
@@ -1637,103 +1530,103 @@ type_specifier_no_prec
type_specifier_nonarray
: VOID_TYPE {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line);
}
| FLOAT_TYPE {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
}
| INT_TYPE {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
}
| BOOL_TYPE {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
}
// | UNSIGNED INT_TYPE {
// PACK_UNPACK_ONLY("unsigned", $1.line);
-// TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+// TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// $$.setBasic(EbtInt, qual, $1.line);
// }
| VEC2 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(2);
}
| VEC3 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(3);
}
| VEC4 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4);
}
| BVEC2 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.setAggregate(2);
}
| BVEC3 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.setAggregate(3);
}
| BVEC4 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
$$.setAggregate(4);
}
| IVEC2 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(2);
}
| IVEC3 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(3);
}
| IVEC4 {
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(4);
}
| MATRIX2 {
FRAG_VERT_ONLY("mat2", $1.line);
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(2, true);
}
| MATRIX3 {
FRAG_VERT_ONLY("mat3", $1.line);
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(3, true);
}
| MATRIX4 {
FRAG_VERT_ONLY("mat4", $1.line);
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| SAMPLER2D {
FRAG_VERT_ONLY("sampler2D", $1.line);
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| SAMPLERCUBE {
FRAG_VERT_ONLY("samplerCube", $1.line);
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, $1.line);
}
| struct_specifier {
FRAG_VERT_ONLY("struct", $1.line);
$$ = $1;
- $$.qualifier = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ $$.qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
| TYPE_NAME {
//
@@ -1741,7 +1634,7 @@ type_specifier_nonarray
// type.
//
TType& structure = static_cast<TVariable*>($1.symbol)->getType();
- TQualifier qual = parseContext->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtStruct, qual, $1.line);
$$.userDef = &structure;
}
@@ -1749,14 +1642,14 @@ type_specifier_nonarray
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
- if (parseContext->reservedErrorCheck($2.line, *$2.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($2.line, *$2.string))
+ context->recover();
TType* structure = new TType($4, *$2.string);
TVariable* userTypeDef = new TVariable($2.string, *structure, true);
- if (! parseContext->symbolTable.insert(*userTypeDef)) {
- parseContext->error($2.line, "redefinition", $2.string->c_str(), "struct");
- parseContext->recover();
+ if (! context->symbolTable.insert(*userTypeDef)) {
+ context->error($2.line, "redefinition", $2.string->c_str(), "struct");
+ context->recover();
}
$$.setBasic(EbtStruct, EvqTemporary, $1.line);
$$.userDef = structure;
@@ -1777,8 +1670,8 @@ struct_declaration_list
for (unsigned int i = 0; i < $2->size(); ++i) {
for (unsigned int j = 0; j < $$->size(); ++j) {
if ((*$$)[j].type->getFieldName() == (*$2)[i].type->getFieldName()) {
- parseContext->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
- parseContext->recover();
+ context->error((*$2)[i].line, "duplicate field name in structure:", "struct", (*$2)[i].type->getFieldName().c_str());
+ context->recover();
}
}
$$->push_back((*$2)[i]);
@@ -1790,8 +1683,8 @@ struct_declaration
: type_specifier struct_declarator_list SEMICOLON {
$$ = $2;
- if (parseContext->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
- parseContext->recover();
+ if (context->voidErrorCheck($1.line, (*$2)[0].type->getFieldName(), $1)) {
+ context->recover();
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
@@ -1804,8 +1697,8 @@ struct_declaration
// don't allow arrays of arrays
if (type->isArray()) {
- if (parseContext->arrayTypeErrorCheck($1.line, $1))
- parseContext->recover();
+ if (context->arrayTypeErrorCheck($1.line, $1))
+ context->recover();
}
if ($1.array)
type->setArraySize($1.arraySize);
@@ -1829,24 +1722,24 @@ struct_declarator_list
struct_declarator
: IDENTIFIER {
- if (parseContext->reservedErrorCheck($1.line, *$1.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($1.line, *$1.string))
+ context->recover();
$$.type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
}
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
- if (parseContext->reservedErrorCheck($1.line, *$1.string))
- parseContext->recover();
+ if (context->reservedErrorCheck($1.line, *$1.string))
+ context->recover();
$$.type = new TType(EbtVoid, EbpUndefined);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
int size;
- if (parseContext->arraySizeErrorCheck($2.line, $3, size))
- parseContext->recover();
+ if (context->arraySizeErrorCheck($2.line, $3, size))
+ context->recover();
$$.type->setArraySize(size);
}
;
@@ -1876,7 +1769,7 @@ simple_statement
compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
- | LEFT_BRACE { parseContext->symbolTable.push(); } statement_list { parseContext->symbolTable.pop(); } RIGHT_BRACE {
+ | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0)
$3->setOp(EOpSequence);
$$ = $3;
@@ -1902,10 +1795,10 @@ compound_statement_no_new_scope
statement_list
: statement {
- $$ = parseContext->intermediate.makeAggregate($1, 0);
+ $$ = context->intermediate.makeAggregate($1, 0);
}
| statement_list statement {
- $$ = parseContext->intermediate.growAggregate($1, $2, 0);
+ $$ = context->intermediate.growAggregate($1, $2, 0);
}
;
@@ -1916,9 +1809,9 @@ expression_statement
selection_statement
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
- if (parseContext->boolErrorCheck($1.line, $3))
- parseContext->recover();
- $$ = parseContext->intermediate.addSelection($3, $5, $1.line);
+ if (context->boolErrorCheck($1.line, $3))
+ context->recover();
+ $$ = context->intermediate.addSelection($3, $5, $1.line);
}
;
@@ -1939,42 +1832,42 @@ condition
// In 1996 c++ draft, conditions can include single declarations
: expression {
$$ = $1;
- if (parseContext->boolErrorCheck($1->getLine(), $1))
- parseContext->recover();
+ if (context->boolErrorCheck($1->getLine(), $1))
+ context->recover();
}
| fully_specified_type IDENTIFIER EQUAL initializer {
TIntermNode* intermNode;
- if (parseContext->structQualifierErrorCheck($2.line, $1))
- parseContext->recover();
- if (parseContext->boolErrorCheck($2.line, $1))
- parseContext->recover();
+ if (context->structQualifierErrorCheck($2.line, $1))
+ context->recover();
+ if (context->boolErrorCheck($2.line, $1))
+ context->recover();
- if (!parseContext->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
+ if (!context->executeInitializer($2.line, *$2.string, $1, $4, intermNode))
$$ = $4;
else {
- parseContext->recover();
+ context->recover();
$$ = 0;
}
}
;
iteration_statement
- : WHILE LEFT_PAREN { parseContext->symbolTable.push(); ++parseContext->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
- parseContext->symbolTable.pop();
- $$ = parseContext->intermediate.addLoop(0, $6, $4, 0, true, $1.line);
- --parseContext->loopNestingLevel;
+ : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
+ context->symbolTable.pop();
+ $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
+ --context->loopNestingLevel;
}
- | DO { ++parseContext->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
- if (parseContext->boolErrorCheck($8.line, $6))
- parseContext->recover();
+ | DO { ++context->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
+ if (context->boolErrorCheck($8.line, $6))
+ context->recover();
- $$ = parseContext->intermediate.addLoop(0, $3, $6, 0, false, $4.line);
- --parseContext->loopNestingLevel;
+ $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
+ --context->loopNestingLevel;
}
- | FOR LEFT_PAREN { parseContext->symbolTable.push(); ++parseContext->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
- parseContext->symbolTable.pop();
- $$ = parseContext->intermediate.addLoop($4, $7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line);
- --parseContext->loopNestingLevel;
+ | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
+ context->symbolTable.pop();
+ $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line);
+ --context->loopNestingLevel;
}
;
@@ -2009,40 +1902,40 @@ for_rest_statement
jump_statement
: CONTINUE SEMICOLON {
- if (parseContext->loopNestingLevel <= 0) {
- parseContext->error($1.line, "continue statement only allowed in loops", "", "");
- parseContext->recover();
+ if (context->loopNestingLevel <= 0) {
+ context->error($1.line, "continue statement only allowed in loops", "", "");
+ context->recover();
}
- $$ = parseContext->intermediate.addBranch(EOpContinue, $1.line);
+ $$ = context->intermediate.addBranch(EOpContinue, $1.line);
}
| BREAK SEMICOLON {
- if (parseContext->loopNestingLevel <= 0) {
- parseContext->error($1.line, "break statement only allowed in loops", "", "");
- parseContext->recover();
+ if (context->loopNestingLevel <= 0) {
+ context->error($1.line, "break statement only allowed in loops", "", "");
+ context->recover();
}
- $$ = parseContext->intermediate.addBranch(EOpBreak, $1.line);
+ $$ = context->intermediate.addBranch(EOpBreak, $1.line);
}
| RETURN SEMICOLON {
- $$ = parseContext->intermediate.addBranch(EOpReturn, $1.line);
- if (parseContext->currentFunctionType->getBasicType() != EbtVoid) {
- parseContext->error($1.line, "non-void function must return a value", "return", "");
- parseContext->recover();
+ $$ = context->intermediate.addBranch(EOpReturn, $1.line);
+ if (context->currentFunctionType->getBasicType() != EbtVoid) {
+ context->error($1.line, "non-void function must return a value", "return", "");
+ context->recover();
}
}
| RETURN expression SEMICOLON {
- $$ = parseContext->intermediate.addBranch(EOpReturn, $2, $1.line);
- parseContext->functionReturnsValue = true;
- if (parseContext->currentFunctionType->getBasicType() == EbtVoid) {
- parseContext->error($1.line, "void function cannot return a value", "return", "");
- parseContext->recover();
- } else if (*(parseContext->currentFunctionType) != $2->getType()) {
- parseContext->error($1.line, "function return is not matching type:", "return", "");
- parseContext->recover();
+ $$ = context->intermediate.addBranch(EOpReturn, $2, $1.line);
+ context->functionReturnsValue = true;
+ if (context->currentFunctionType->getBasicType() == EbtVoid) {
+ context->error($1.line, "void function cannot return a value", "return", "");
+ context->recover();
+ } else if (*(context->currentFunctionType) != $2->getType()) {
+ context->error($1.line, "function return is not matching type:", "return", "");
+ context->recover();
}
}
| DISCARD SEMICOLON {
FRAG_ONLY("discard", $1.line);
- $$ = parseContext->intermediate.addBranch(EOpKill, $1.line);
+ $$ = context->intermediate.addBranch(EOpKill, $1.line);
}
;
@@ -2051,11 +1944,11 @@ jump_statement
translation_unit
: external_declaration {
$$ = $1;
- parseContext->treeRoot = $$;
+ context->treeRoot = $$;
}
| translation_unit external_declaration {
- $$ = parseContext->intermediate.growAggregate($1, $2, 0);
- parseContext->treeRoot = $$;
+ $$ = context->intermediate.growAggregate($1, $2, 0);
+ context->treeRoot = $$;
}
;
@@ -2070,8 +1963,8 @@ external_declaration
function_definition
: function_prototype {
- TFunction& function = *($1.function);
- TFunction* prevDec = static_cast<TFunction*>(parseContext->symbolTable.find(function.getMangledName()));
+ TFunction* function = $1.function;
+ TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
//
// Note: 'prevDec' could be 'function' if this is the first time we've seen function
// as it would have just been put in the symbol table. Otherwise, we're looking up
@@ -2081,35 +1974,35 @@ function_definition
//
// Then this function already has a body.
//
- parseContext->error($1.line, "function already has a body", function.getName().c_str(), "");
- parseContext->recover();
+ context->error($1.line, "function already has a body", function->getName().c_str(), "");
+ context->recover();
}
prevDec->setDefined();
//
// Raise error message if main function takes any parameters or return anything other than void
//
- if (function.getName() == "main") {
- if (function.getParamCount() > 0) {
- parseContext->error($1.line, "function cannot take any parameter(s)", function.getName().c_str(), "");
- parseContext->recover();
+ if (function->getName() == "main") {
+ if (function->getParamCount() > 0) {
+ context->error($1.line, "function cannot take any parameter(s)", function->getName().c_str(), "");
+ context->recover();
}
- if (function.getReturnType().getBasicType() != EbtVoid) {
- parseContext->error($1.line, "", function.getReturnType().getBasicString(), "main function cannot return a value");
- parseContext->recover();
+ if (function->getReturnType().getBasicType() != EbtVoid) {
+ context->error($1.line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+ context->recover();
}
}
//
// New symbol table scope for body of function plus its arguments
//
- parseContext->symbolTable.push();
+ context->symbolTable.push();
//
// Remember the return type for later checking for RETURN statements.
//
- parseContext->currentFunctionType = &(prevDec->getReturnType());
- parseContext->functionReturnsValue = false;
+ context->currentFunctionType = &(prevDec->getReturnType());
+ context->functionReturnsValue = false;
//
// Insert parameters into the symbol table.
@@ -2120,59 +2013,60 @@ function_definition
// knows where to find parameters.
//
TIntermAggregate* paramNodes = new TIntermAggregate;
- for (int i = 0; i < function.getParamCount(); i++) {
- TParameter& param = function[i];
+ for (int i = 0; i < function->getParamCount(); i++) {
+ const TParameter& param = function->getParam(i);
if (param.name != 0) {
TVariable *variable = new TVariable(param.name, *param.type);
//
// Insert the parameters with name in the symbol table.
//
- if (! parseContext->symbolTable.insert(*variable)) {
- parseContext->error($1.line, "redefinition", variable->getName().c_str(), "");
- parseContext->recover();
+ if (! context->symbolTable.insert(*variable)) {
+ context->error($1.line, "redefinition", variable->getName().c_str(), "");
+ context->recover();
delete variable;
}
- //
- // Transfer ownership of name pointer to symbol table.
- //
- param.name = 0;
//
// Add the parameter to the HIL
//
- paramNodes = parseContext->intermediate.growAggregate(
+ paramNodes = context->intermediate.growAggregate(
paramNodes,
- parseContext->intermediate.addSymbol(variable->getUniqueId(),
+ context->intermediate.addSymbol(variable->getUniqueId(),
variable->getName(),
variable->getType(), $1.line),
$1.line);
} else {
- paramNodes = parseContext->intermediate.growAggregate(paramNodes, parseContext->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
+ paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, $1.line), $1.line);
}
}
- parseContext->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
+ context->intermediate.setAggregateOperator(paramNodes, EOpParameters, $1.line);
$1.intermAggregate = paramNodes;
- parseContext->loopNestingLevel = 0;
+ context->loopNestingLevel = 0;
}
compound_statement_no_new_scope {
//?? Check that all paths return a value if return type != void ?
// May be best done as post process phase on intermediate code
- if (parseContext->currentFunctionType->getBasicType() != EbtVoid && ! parseContext->functionReturnsValue) {
- parseContext->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
- parseContext->recover();
+ if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
+ context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str());
+ context->recover();
}
- parseContext->symbolTable.pop();
- $$ = parseContext->intermediate.growAggregate($1.intermAggregate, $3, 0);
- parseContext->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
+ context->symbolTable.pop();
+ $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0);
+ context->intermediate.setAggregateOperator($$, EOpFunction, $1.line);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
$$->getAsAggregate()->setType($1.function->getReturnType());
// store the pragma information for debug and optimize and other vendor specific
// information. This information can be queried from the parse tree
- $$->getAsAggregate()->setOptimize(parseContext->contextPragma.optimize);
- $$->getAsAggregate()->setDebug(parseContext->contextPragma.debug);
- $$->getAsAggregate()->addToPragmaTable(parseContext->contextPragma.pragmaTable);
+ $$->getAsAggregate()->setOptimize(context->contextPragma.optimize);
+ $$->getAsAggregate()->setDebug(context->contextPragma.debug);
+ $$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
}
;
%%
+
+int glslang_parse(TParseContext* context) {
+ return yyparse(context);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp
new file mode 100644
index 0000000..9d5f53f
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp
@@ -0,0 +1,3186 @@
+#line 17 "compiler/glslang.l"
+//
+// Copyright (c) 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 is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT!
+
+
+
+#line 13 "compiler/glslang_lex.cpp"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+ * access to the local variable yy_act. Since yyless() is a macro, it would break
+ * existing scanners that call yyless() from OUTSIDE yylex.
+ * One obvious solution it to make yy_act a global. I tried that, and saw
+ * a 5% performance hit in a non-yylineno scanner, because yy_act is
+ * normally declared as a register variable-- so it is not worth it.
+ */
+ #define YY_LESS_LINENO(n) \
+ do { \
+ int yyl;\
+ for ( yyl = n; yyl < yyleng; ++yyl )\
+ if ( yytext[yyl] == '\n' )\
+ --yylineno;\
+ }while(0)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
+
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 145
+#define YY_END_OF_BUFFER 146
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[411] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 146, 144, 143, 143,
+ 128, 134, 139, 123, 124, 132, 131, 120, 129, 127,
+ 133, 92, 92, 121, 117, 135, 122, 136, 140, 88,
+ 125, 126, 138, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 118, 137, 119, 130, 3, 4, 3,
+ 142, 145, 141, 114, 100, 119, 108, 103, 98, 106,
+ 96, 107, 97, 95, 2, 1, 99, 94, 90, 91,
+ 0, 0, 92, 126, 118, 125, 115, 111, 113, 112,
+ 116, 88, 104, 110, 88, 88, 88, 88, 88, 88,
+
+ 88, 88, 88, 88, 17, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 20, 22,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 105, 109, 5, 141,
+ 0, 1, 94, 0, 0, 93, 89, 101, 102, 48,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 18, 88, 88,
+ 88, 88, 88, 88, 88, 88, 26, 88, 88, 88,
+ 88, 88, 88, 88, 88, 23, 88, 88, 88, 88,
+
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 0, 95,
+ 0, 94, 88, 28, 88, 88, 85, 88, 88, 88,
+ 88, 88, 88, 88, 21, 51, 88, 88, 88, 88,
+ 88, 56, 70, 88, 88, 88, 88, 88, 88, 88,
+ 88, 67, 9, 33, 34, 35, 88, 88, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
+ 88, 54, 29, 88, 88, 88, 88, 88, 88, 36,
+ 37, 38, 27, 88, 88, 88, 15, 42, 43, 44,
+ 49, 12, 88, 88, 88, 88, 81, 82, 83, 88,
+
+ 30, 71, 25, 78, 79, 80, 7, 75, 76, 77,
+ 88, 24, 73, 88, 88, 39, 40, 41, 88, 88,
+ 88, 88, 88, 88, 88, 88, 88, 68, 88, 88,
+ 88, 88, 88, 88, 88, 50, 88, 87, 88, 88,
+ 19, 88, 88, 88, 88, 69, 64, 59, 88, 88,
+ 88, 88, 88, 74, 55, 88, 62, 32, 88, 84,
+ 63, 47, 57, 88, 88, 88, 88, 88, 88, 88,
+ 88, 58, 31, 88, 88, 88, 8, 88, 88, 88,
+ 88, 88, 52, 13, 88, 14, 88, 88, 16, 65,
+ 88, 88, 88, 60, 88, 88, 88, 53, 72, 61,
+
+ 11, 66, 6, 86, 10, 45, 88, 88, 46, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 1, 1, 1, 5, 6, 1, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 16, 16, 16, 20, 20, 21, 22, 23,
+ 24, 25, 26, 1, 27, 27, 28, 29, 30, 27,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 32, 31, 31,
+ 33, 1, 34, 35, 31, 1, 36, 37, 38, 39,
+
+ 40, 41, 42, 43, 44, 31, 45, 46, 47, 48,
+ 49, 50, 31, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[64] =
+ { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 1, 1, 1, 1, 1, 1, 3, 3, 3, 3,
+ 4, 4, 1, 1, 1, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 1,
+ 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[416] =
+ { 0,
+ 0, 0, 61, 62, 71, 0, 606, 607, 607, 607,
+ 581, 42, 129, 607, 607, 580, 126, 607, 125, 123,
+ 137, 149, 157, 578, 607, 175, 578, 44, 607, 0,
+ 607, 607, 120, 95, 103, 142, 146, 136, 156, 552,
+ 168, 162, 551, 120, 158, 545, 173, 558, 172, 178,
+ 111, 186, 554, 607, 159, 607, 607, 607, 607, 582,
+ 607, 607, 0, 607, 607, 607, 607, 607, 607, 607,
+ 607, 607, 607, 222, 607, 0, 607, 228, 254, 262,
+ 281, 0, 290, 607, 607, 607, 571, 607, 607, 607,
+ 570, 0, 607, 607, 546, 539, 542, 550, 549, 536,
+
+ 551, 538, 544, 532, 529, 542, 529, 526, 526, 532,
+ 520, 527, 524, 534, 520, 526, 529, 530, 0, 204,
+ 529, 207, 515, 528, 519, 521, 511, 525, 522, 524,
+ 507, 512, 509, 498, 183, 512, 508, 510, 499, 502,
+ 212, 507, 499, 511, 186, 504, 607, 607, 607, 0,
+ 306, 0, 316, 332, 270, 342, 0, 607, 607, 0,
+ 496, 500, 509, 506, 490, 490, 161, 505, 502, 502,
+ 500, 497, 489, 495, 482, 493, 496, 0, 493, 481,
+ 488, 485, 489, 482, 471, 470, 483, 486, 483, 478,
+ 469, 294, 474, 477, 468, 465, 469, 475, 466, 457,
+
+ 460, 458, 468, 454, 452, 452, 454, 451, 462, 461,
+ 278, 456, 451, 440, 320, 458, 460, 449, 348, 354,
+ 360, 366, 450, 0, 448, 336, 0, 440, 438, 446,
+ 435, 452, 441, 370, 0, 0, 435, 445, 445, 430,
+ 373, 0, 0, 432, 376, 433, 427, 426, 427, 426,
+ 379, 0, 0, 0, 0, 0, 422, 423, 428, 419,
+ 432, 427, 426, 418, 422, 414, 417, 421, 426, 425,
+ 416, 0, 0, 422, 411, 411, 416, 415, 412, 0,
+ 0, 0, 0, 402, 414, 416, 0, 0, 0, 0,
+ 0, 0, 404, 405, 399, 409, 0, 0, 0, 400,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 407, 0, 0, 405, 401, 0, 0, 0, 397, 393,
+ 398, 388, 401, 387, 400, 389, 396, 0, 394, 396,
+ 380, 389, 395, 390, 378, 0, 380, 0, 379, 382,
+ 0, 371, 370, 370, 383, 0, 385, 0, 384, 383,
+ 368, 381, 368, 0, 0, 371, 0, 0, 363, 0,
+ 0, 0, 0, 360, 371, 364, 368, 303, 297, 288,
+ 300, 0, 0, 283, 290, 269, 0, 277, 274, 255,
+ 232, 255, 0, 0, 244, 0, 236, 226, 0, 0,
+ 225, 208, 211, 0, 185, 202, 131, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 134, 117, 0, 607,
+ 398, 400, 402, 406, 142
+ } ;
+
+static yyconst flex_int16_t yy_def[416] =
+ { 0,
+ 410, 1, 411, 411, 410, 5, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 412,
+ 410, 410, 410, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 413, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 414, 410, 410, 410, 410,
+ 410, 415, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 412, 410, 410, 412, 412, 412, 412, 412, 412,
+
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 410, 410, 410, 413,
+ 410, 414, 410, 410, 410, 410, 415, 410, 410, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 410, 410,
+ 410, 410, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 412,
+
+ 412, 412, 412, 412, 412, 412, 412, 412, 412, 0,
+ 410, 410, 410, 410, 410
+ } ;
+
+static yyconst flex_int16_t yy_nxt[671] =
+ { 0,
+ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 23, 23, 23, 23,
+ 24, 25, 26, 27, 28, 29, 30, 30, 30, 30,
+ 30, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 30, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 30, 30, 30, 54,
+ 55, 56, 57, 59, 59, 65, 66, 90, 91, 60,
+ 60, 8, 61, 62, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 63, 63, 63,
+
+ 63, 63, 63, 8, 8, 8, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
+ 8, 8, 8, 8, 67, 70, 72, 74, 74, 74,
+ 74, 74, 74, 93, 157, 75, 95, 96, 73, 71,
+ 76, 97, 68, 98, 94, 123, 409, 99, 141, 124,
+ 77, 78, 142, 79, 79, 79, 79, 79, 80, 78,
+ 408, 83, 83, 83, 83, 83, 83, 100, 81, 85,
+ 82, 107, 147, 108, 407, 103, 81, 101, 81, 104,
+ 102, 110, 109, 125, 105, 86, 81, 87, 88, 111,
+
+ 106, 112, 119, 116, 113, 82, 126, 132, 128, 120,
+ 114, 117, 229, 230, 133, 134, 121, 137, 204, 148,
+ 138, 143, 118, 129, 135, 144, 130, 136, 139, 216,
+ 406, 217, 405, 205, 145, 140, 74, 74, 74, 74,
+ 74, 74, 153, 153, 153, 153, 153, 153, 396, 184,
+ 404, 151, 185, 186, 190, 211, 187, 154, 188, 397,
+ 403, 151, 191, 212, 402, 401, 78, 154, 79, 79,
+ 79, 79, 79, 80, 78, 400, 80, 80, 80, 80,
+ 80, 80, 399, 81, 156, 156, 156, 156, 156, 156,
+ 155, 81, 155, 81, 398, 156, 156, 156, 156, 156,
+
+ 156, 81, 78, 395, 83, 83, 83, 83, 83, 83,
+ 254, 255, 256, 394, 393, 219, 392, 219, 275, 81,
+ 220, 220, 220, 220, 220, 220, 276, 391, 390, 81,
+ 153, 153, 153, 153, 153, 153, 280, 281, 282, 389,
+ 388, 221, 387, 221, 386, 154, 222, 222, 222, 222,
+ 222, 222, 288, 289, 290, 154, 156, 156, 156, 156,
+ 156, 156, 220, 220, 220, 220, 220, 220, 220, 220,
+ 220, 220, 220, 220, 222, 222, 222, 222, 222, 222,
+ 222, 222, 222, 222, 222, 222, 297, 298, 299, 304,
+ 305, 306, 308, 309, 310, 316, 317, 318, 58, 58,
+
+ 58, 58, 92, 92, 150, 150, 152, 385, 152, 152,
+ 384, 383, 382, 381, 380, 379, 378, 377, 376, 375,
+ 374, 373, 372, 371, 370, 369, 368, 367, 366, 365,
+ 364, 363, 362, 361, 360, 359, 358, 357, 356, 355,
+ 354, 353, 352, 351, 350, 349, 348, 347, 346, 345,
+ 344, 343, 342, 341, 340, 339, 338, 337, 336, 335,
+ 334, 333, 332, 331, 330, 329, 328, 327, 326, 325,
+ 324, 323, 322, 321, 320, 319, 315, 314, 313, 312,
+ 311, 307, 303, 302, 301, 300, 296, 295, 294, 293,
+ 292, 291, 287, 286, 285, 284, 283, 279, 278, 277,
+
+ 274, 273, 272, 271, 270, 269, 268, 267, 266, 265,
+ 264, 263, 262, 261, 260, 259, 258, 257, 253, 252,
+ 251, 250, 249, 248, 247, 246, 245, 244, 243, 242,
+ 241, 240, 239, 238, 237, 236, 235, 234, 233, 232,
+ 231, 228, 227, 226, 225, 224, 223, 218, 215, 214,
+ 213, 210, 209, 208, 207, 206, 203, 202, 201, 200,
+ 199, 198, 197, 196, 195, 194, 193, 192, 189, 183,
+ 182, 181, 180, 179, 178, 177, 176, 175, 174, 173,
+ 172, 171, 170, 169, 168, 167, 166, 165, 164, 163,
+ 162, 161, 160, 159, 158, 149, 146, 131, 127, 122,
+
+ 115, 89, 84, 69, 64, 410, 7, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410
+ } ;
+
+static yyconst flex_int16_t yy_chk[671] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 4, 12, 12, 28, 28, 3,
+ 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 13, 17, 19, 20, 20, 20,
+ 20, 20, 20, 33, 415, 21, 34, 34, 19, 17,
+ 21, 35, 13, 35, 33, 44, 408, 35, 51, 44,
+ 21, 22, 51, 22, 22, 22, 22, 22, 22, 23,
+ 407, 23, 23, 23, 23, 23, 23, 36, 22, 26,
+ 22, 38, 55, 38, 397, 37, 23, 36, 22, 37,
+ 36, 39, 38, 45, 37, 26, 23, 26, 26, 39,
+
+ 37, 39, 42, 41, 39, 22, 45, 49, 47, 42,
+ 39, 41, 167, 167, 49, 49, 42, 50, 135, 55,
+ 50, 52, 41, 47, 49, 52, 47, 49, 50, 145,
+ 396, 145, 395, 135, 52, 50, 74, 74, 74, 74,
+ 74, 74, 78, 78, 78, 78, 78, 78, 381, 120,
+ 393, 74, 120, 120, 122, 141, 120, 78, 120, 381,
+ 392, 74, 122, 141, 391, 388, 79, 78, 79, 79,
+ 79, 79, 79, 79, 80, 387, 80, 80, 80, 80,
+ 80, 80, 385, 79, 155, 155, 155, 155, 155, 155,
+ 81, 80, 81, 79, 382, 81, 81, 81, 81, 81,
+
+ 81, 80, 83, 380, 83, 83, 83, 83, 83, 83,
+ 192, 192, 192, 379, 378, 151, 376, 151, 211, 83,
+ 151, 151, 151, 151, 151, 151, 211, 375, 374, 83,
+ 153, 153, 153, 153, 153, 153, 215, 215, 215, 371,
+ 370, 154, 369, 154, 368, 153, 154, 154, 154, 154,
+ 154, 154, 226, 226, 226, 153, 156, 156, 156, 156,
+ 156, 156, 219, 219, 219, 219, 219, 219, 220, 220,
+ 220, 220, 220, 220, 221, 221, 221, 221, 221, 221,
+ 222, 222, 222, 222, 222, 222, 234, 234, 234, 241,
+ 241, 241, 245, 245, 245, 251, 251, 251, 411, 411,
+
+ 411, 411, 412, 412, 413, 413, 414, 367, 414, 414,
+ 366, 365, 364, 359, 356, 353, 352, 351, 350, 349,
+ 347, 345, 344, 343, 342, 340, 339, 337, 335, 334,
+ 333, 332, 331, 330, 329, 327, 326, 325, 324, 323,
+ 322, 321, 320, 319, 315, 314, 311, 300, 296, 295,
+ 294, 293, 286, 285, 284, 279, 278, 277, 276, 275,
+ 274, 271, 270, 269, 268, 267, 266, 265, 264, 263,
+ 262, 261, 260, 259, 258, 257, 250, 249, 248, 247,
+ 246, 244, 240, 239, 238, 237, 233, 232, 231, 230,
+ 229, 228, 225, 223, 218, 217, 216, 214, 213, 212,
+
+ 210, 209, 208, 207, 206, 205, 204, 203, 202, 201,
+ 200, 199, 198, 197, 196, 195, 194, 193, 191, 190,
+ 189, 188, 187, 186, 185, 184, 183, 182, 181, 180,
+ 179, 177, 176, 175, 174, 173, 172, 171, 170, 169,
+ 168, 166, 165, 164, 163, 162, 161, 146, 144, 143,
+ 142, 140, 139, 138, 137, 136, 134, 133, 132, 131,
+ 130, 129, 128, 127, 126, 125, 124, 123, 121, 118,
+ 117, 116, 115, 114, 113, 112, 111, 110, 109, 108,
+ 107, 106, 105, 104, 103, 102, 101, 100, 99, 98,
+ 97, 96, 95, 91, 87, 60, 53, 48, 46, 43,
+
+ 40, 27, 24, 16, 11, 7, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410,
+ 410, 410, 410, 410, 410, 410, 410, 410, 410, 410
+ } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[146] =
+ { 0,
+0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, };
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright (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 Lex specification for GLSL ES.
+Based on ANSI C grammar, Lex specification:
+http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
+
+IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_lexer.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
+*/
+
+#include "compiler/glslang.h"
+#include "compiler/ParseHelper.h"
+#include "compiler/util.h"
+#include "glslang_tab.h"
+
+/* windows only pragma */
+#ifdef _MSC_VER
+#pragma warning(disable : 4102)
+#endif
+
+#define YY_USER_ACTION yylval->lex.line = yylineno;
+#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 int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+
+#define INITIAL 0
+#define COMMENT 1
+#define FIELDS 2
+
+#define YY_EXTRA_TYPE TParseContext*
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (yyscan_t yyscanner );
+
+int yyget_debug (yyscan_t yyscanner );
+
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *yyget_in (yyscan_t yyscanner );
+
+void yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *yyget_out (yyscan_t yyscanner );
+
+void yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int yyget_leng (yyscan_t yyscanner );
+
+char *yyget_text (yyscan_t yyscanner );
+
+int yyget_lineno (yyscan_t yyscanner );
+
+void yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
+
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (yyscan_t yyscanner );
+#else
+extern int yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+ static void yy_push_state (int new_state ,yyscan_t yyscanner);
+
+ static void yy_pop_state (yyscan_t yyscanner );
+
+ static int yy_top_state (yyscan_t yyscanner );
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ int n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex \
+ (YYSTYPE * yylval_param ,yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
+ (YYSTYPE * yylval_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ TParseContext* context = yyextra;
+
+ /* Single-line comments */
+
+ yylval = yylval_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ yy_load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 411 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_current_state != 410 );
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+
+ YY_DO_BEFORE_ACTION;
+
+ if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
+ {
+ int yyl;
+ for ( yyl = 0; yyl < yyleng; ++yyl )
+ if ( yytext[yyl] == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+ }
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+;
+ YY_BREAK
+/* Multi-line comments */
+case 2:
+YY_RULE_SETUP
+{ yy_push_state(COMMENT, yyscanner); }
+ YY_BREAK
+case 3:
+case 4:
+/* rule 4 can match eol */
+YY_RULE_SETUP
+;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+{ yy_pop_state(yyscanner); }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+{ return(INVARIANT); }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+{ return(HIGH_PRECISION); }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+{ return(MEDIUM_PRECISION); }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+{ return(LOW_PRECISION); }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+{ return(PRECISION); }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+{ return(ATTRIBUTE); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+{ return(CONST_QUAL); }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+{ return(UNIFORM); }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+{ return(VARYING); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+{ return(BREAK); }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+{ return(CONTINUE); }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+{ return(DO); }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+{ return(FOR); }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+{ return(WHILE); }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+{ return(IF); }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+{ return(ELSE); }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+{ return(IN_QUAL); }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+{ return(OUT_QUAL); }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+{ return(INOUT_QUAL); }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(FLOAT_TYPE); }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(INT_TYPE); }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(VOID_TYPE); }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(BOOL_TYPE); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+{ yylval->lex.b = true; return(BOOLCONSTANT); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+{ yylval->lex.b = false; return(BOOLCONSTANT); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+{ return(DISCARD); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+{ return(RETURN); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX2); }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX3); }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(MATRIX4); }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC2); }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC3); }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (VEC4); }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC2); }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC3); }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (IVEC4); }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC2); }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC3); }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return (BVEC4); }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return SAMPLER2D; }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return SAMPLERCUBE; }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+{ context->lexAfterType = true; return(STRUCT); }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+{
+ yylval->lex.string = NewPoolTString(yytext);
+ return check_type(yyscanner);
+}
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+{ context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;}
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+{ yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+{ yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+{ return(ADD_ASSIGN); }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+{ return(SUB_ASSIGN); }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+{ return(MUL_ASSIGN); }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+{ return(DIV_ASSIGN); }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+{ return(MOD_ASSIGN); }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+{ return(LEFT_ASSIGN); }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+{ return(RIGHT_ASSIGN); }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+{ return(AND_ASSIGN); }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+{ return(XOR_ASSIGN); }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+{ return(OR_ASSIGN); }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+{ return(INC_OP); }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+{ return(DEC_OP); }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+{ return(AND_OP); }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+{ return(OR_OP); }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+{ return(XOR_OP); }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+{ return(LE_OP); }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+{ return(GE_OP); }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+{ return(EQ_OP); }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+{ return(NE_OP); }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+{ return(LEFT_OP); }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+{ return(RIGHT_OP); }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(SEMICOLON); }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(LEFT_BRACE); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+{ return(RIGHT_BRACE); }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+{ if (context->inTypeParen) context->lexAfterType = false; return(COMMA); }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+{ return(COLON); }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+{ context->lexAfterType = false; return(EQUAL); }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+{ context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+{ context->inTypeParen = false; return(RIGHT_PAREN); }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+{ return(LEFT_BRACKET); }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+{ return(RIGHT_BRACKET); }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+{ BEGIN(FIELDS); return(DOT); }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+{ return(BANG); }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+{ return(DASH); }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+{ return(TILDE); }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+{ return(PLUS); }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+{ return(STAR); }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+{ return(SLASH); }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+{ return(PERCENT); }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+{ return(LEFT_ANGLE); }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+{ return(RIGHT_ANGLE); }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+{ return(VERTICAL_BAR); }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+{ return(CARET); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+{ return(AMPERSAND); }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+{ return(QUESTION); }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+{
+ BEGIN(INITIAL);
+ yylval->lex.string = NewPoolTString(yytext);
+ return FIELD_SELECTION;
+}
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+{}
+ YY_BREAK
+case 143:
+/* rule 143 can match eol */
+YY_RULE_SETUP
+{ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(COMMENT):
+case YY_STATE_EOF(FIELDS):
+{ context->AfterEOF = true; yyterminate(); }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+{ context->warning(yylineno, "Unknown char", yytext, ""); return 0; }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+ECHO;
+ YY_BREAK
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 411 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 411 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 410);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ if ( c == '\n' )
+
+ do{ yylineno++;
+ yycolumn=0;
+ }while(0)
+;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+ static void yy_push_state (int new_state , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( yyg->yy_start_stack_ptr >= yyg->yy_start_stack_depth )
+ {
+ yy_size_t new_size;
+
+ yyg->yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yyg->yy_start_stack_depth * sizeof( int );
+
+ if ( ! yyg->yy_start_stack )
+ yyg->yy_start_stack = (int *) yyalloc(new_size ,yyscanner );
+
+ else
+ yyg->yy_start_stack = (int *) yyrealloc((void *) yyg->yy_start_stack,new_size ,yyscanner );
+
+ if ( ! yyg->yy_start_stack )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ yyg->yy_start_stack[yyg->yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+
+ static void yy_pop_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( --yyg->yy_start_stack_ptr < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN(yyg->yy_start_stack[yyg->yy_start_stack_ptr]);
+}
+
+ static int yy_top_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyg->yy_start_stack[yyg->yy_start_stack_ptr - 1];
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+extern "C" {
+// Preprocessor interface.
+#include "compiler/preprocessor/preprocess.h"
+
+#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->infoSink.debug.message(EPrefixNone, 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(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 (!strcmp(tokens[0], "optimize")) {
+ if (numTokens != 4) {
+ CPPShInfoLogMsg("optimize pragma syntax is incorrect");
+ return;
+ }
+
+ if (strcmp(tokens[1], "(")) {
+ CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword");
+ return;
+ }
+
+ if (!strcmp(tokens[2], "on"))
+ context->contextPragma.optimize = true;
+ else if (!strcmp(tokens[2], "off"))
+ context->contextPragma.optimize = false;
+ else {
+ CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma");
+ return;
+ }
+
+ if (strcmp(tokens[3], ")")) {
+ CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma");
+ return;
+ }
+ } else if (!strcmp(tokens[0], "debug")) {
+ if (numTokens != 4) {
+ CPPShInfoLogMsg("debug pragma syntax is incorrect");
+ return;
+ }
+
+ if (strcmp(tokens[1], "(")) {
+ CPPShInfoLogMsg("\"(\" expected after 'debug' keyword");
+ return;
+ }
+
+ if (!strcmp(tokens[2], "on"))
+ context->contextPragma.debug = true;
+ else if (!strcmp(tokens[2], "off"))
+ context->contextPragma.debug = false;
+ else {
+ CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma");
+ return;
+ }
+
+ if (strcmp(tokens[3], ")")) {
+ CPPShInfoLogMsg("\")\" expected to end 'debug' pragma");
+ return;
+ }
+ } else {
+#ifdef PRAGMA_TABLE
+ //
+ // implementation specific pragma
+ // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma
+ // For now, just ignore the pragma that the implementation cannot recognize
+ // An Example of one such implementation for a pragma that has a syntax like
+ // #pragma pragmaname(pragmavalue)
+ // This implementation stores the current pragmavalue against the pragma name in pragmaTable.
+ //
+ if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) {
+ TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
+ TPragmaTable::iterator iter;
+ iter = pragmaTable.find(TString(tokens[0]));
+ if (iter != pragmaTable.end()) {
+ iter->second = tokens[2];
+ } else {
+ pragmaTable[ tokens[0] ] = tokens[2];
+ }
+ } else if (numTokens >= 2) {
+ TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable;
+ TPragmaTable::iterator iter;
+ iter = pragmaTable.find(TString(tokens[0]));
+ if (iter != pragmaTable.end()) {
+ iter->second = tokens[1];
+ } else {
+ pragmaTable[ tokens[0] ] = tokens[1];
+ }
+ }
+#endif // PRAGMA_TABLE
+ }
+}
+
+void StoreStr(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 = "";
+}
+
+TBehavior GetBehavior(const char* behavior)
+{
+ if (!strcmp("require", behavior))
+ return EBhRequire;
+ else if (!strcmp("enable", behavior))
+ return EBhEnable;
+ else if (!strcmp("disable", behavior))
+ return EBhDisable;
+ else if (!strcmp("warn", behavior))
+ return EBhWarn;
+ else {
+ CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str());
+ return EBhDisable;
+ }
+}
+
+void updateExtensionBehavior(const char* extName, const char* behavior)
+{
+ SETUP_CONTEXT(cpp);
+ TBehavior behaviorVal = GetBehavior(behavior);
+ TMap<TString, TBehavior>:: iterator iter;
+ TString msg;
+
+ // special cased for all extension
+ if (!strcmp(extName, "all")) {
+ if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) {
+ CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior");
+ return;
+ } else {
+ for (iter = context->extensionBehavior.begin(); iter != context->extensionBehavior.end(); ++iter)
+ iter->second = behaviorVal;
+ }
+ } else {
+ iter = context->extensionBehavior.find(TString(extName));
+ if (iter == context->extensionBehavior.end()) {
+ switch (behaviorVal) {
+ case EBhRequire:
+ CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str());
+ break;
+ case EBhEnable:
+ case EBhWarn:
+ case EBhDisable:
+ msg = TString("extension '") + extName + "' is not supported";
+ context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno);
+ break;
+ }
+ return;
+ } else
+ iter->second = behaviorVal;
+ }
+}
+} // extern "C"
+
+int string_input(char* buf, int max_size, yyscan_t yyscanner) {
+ int len;
+
+ if ((len = yylex_CPP(buf, max_size)) == 0)
+ return 0;
+ if (len >= max_size)
+ YY_FATAL_ERROR("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+
+ buf[len] = ' ';
+ return len+1;
+}
+
+int check_type(yyscan_t yyscanner) {
+ struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+ int token = IDENTIFIER;
+ TSymbol* symbol = yyextra->symbolTable.find(yytext);
+ if (yyextra->lexAfterType == false && symbol && symbol->isVariable()) {
+ TVariable* variable = static_cast<TVariable*>(symbol);
+ if (variable->isUserType()) {
+ yyextra->lexAfterType = true;
+ token = TYPE_NAME;
+ }
+ }
+ yylval->lex.symbol = symbol;
+ return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+ struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+ yyextra->error(yylineno, "Illegal use of reserved word", yytext, "");
+ yyextra->recover();
+ return 0;
+}
+
+void yyerror(TParseContext* context, const char* reason) {
+ struct yyguts_t* yyg = (struct yyguts_t*) context->scanner;
+
+ if (context->AfterEOF) {
+ context->error(yylineno, reason, "unexpected EOF", "");
+ } else {
+ context->error(yylineno, reason, yytext, "");
+ }
+ context->recover();
+}
+
+int glslang_initialize(TParseContext* context) {
+ yyscan_t scanner = NULL;
+ if (yylex_init_extra(context,&scanner))
+ return 1;
+
+ context->scanner = scanner;
+ return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+ yyscan_t scanner = context->scanner;
+ if (scanner == NULL) return 0;
+
+ context->scanner = NULL;
+ return yylex_destroy(scanner);
+}
+
+void glslang_scan(int count, const char* const string[], const int length[],
+ TParseContext* context) {
+ yyrestart(NULL,context->scanner);
+ yyset_lineno(EncodeSourceLoc(0, 1),context->scanner);
+ context->AfterEOF = false;
+
+ // Init preprocessor.
+ cpp->pC = context;
+ cpp->PaWhichStr = 0;
+ cpp->PaArgv = string;
+ cpp->PaArgc = count;
+ cpp->PaStrLen = length;
+ cpp->pastFirstStatement = 0;
+ ScanFromString(string[0]);
+}
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp
new file mode 100644
index 0000000..d00c7a3
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp
@@ -0,0 +1,4710 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ INVARIANT = 258,
+ HIGH_PRECISION = 259,
+ MEDIUM_PRECISION = 260,
+ LOW_PRECISION = 261,
+ PRECISION = 262,
+ ATTRIBUTE = 263,
+ CONST_QUAL = 264,
+ BOOL_TYPE = 265,
+ FLOAT_TYPE = 266,
+ INT_TYPE = 267,
+ BREAK = 268,
+ CONTINUE = 269,
+ DO = 270,
+ ELSE = 271,
+ FOR = 272,
+ IF = 273,
+ DISCARD = 274,
+ RETURN = 275,
+ BVEC2 = 276,
+ BVEC3 = 277,
+ BVEC4 = 278,
+ IVEC2 = 279,
+ IVEC3 = 280,
+ IVEC4 = 281,
+ VEC2 = 282,
+ VEC3 = 283,
+ VEC4 = 284,
+ MATRIX2 = 285,
+ MATRIX3 = 286,
+ MATRIX4 = 287,
+ IN_QUAL = 288,
+ OUT_QUAL = 289,
+ INOUT_QUAL = 290,
+ UNIFORM = 291,
+ VARYING = 292,
+ STRUCT = 293,
+ VOID_TYPE = 294,
+ WHILE = 295,
+ SAMPLER2D = 296,
+ SAMPLERCUBE = 297,
+ IDENTIFIER = 298,
+ TYPE_NAME = 299,
+ FLOATCONSTANT = 300,
+ INTCONSTANT = 301,
+ BOOLCONSTANT = 302,
+ FIELD_SELECTION = 303,
+ LEFT_OP = 304,
+ RIGHT_OP = 305,
+ INC_OP = 306,
+ DEC_OP = 307,
+ LE_OP = 308,
+ GE_OP = 309,
+ EQ_OP = 310,
+ NE_OP = 311,
+ AND_OP = 312,
+ OR_OP = 313,
+ XOR_OP = 314,
+ MUL_ASSIGN = 315,
+ DIV_ASSIGN = 316,
+ ADD_ASSIGN = 317,
+ MOD_ASSIGN = 318,
+ LEFT_ASSIGN = 319,
+ RIGHT_ASSIGN = 320,
+ AND_ASSIGN = 321,
+ XOR_ASSIGN = 322,
+ OR_ASSIGN = 323,
+ SUB_ASSIGN = 324,
+ LEFT_PAREN = 325,
+ RIGHT_PAREN = 326,
+ LEFT_BRACKET = 327,
+ RIGHT_BRACKET = 328,
+ LEFT_BRACE = 329,
+ RIGHT_BRACE = 330,
+ DOT = 331,
+ COMMA = 332,
+ COLON = 333,
+ EQUAL = 334,
+ SEMICOLON = 335,
+ BANG = 336,
+ DASH = 337,
+ TILDE = 338,
+ PLUS = 339,
+ STAR = 340,
+ SLASH = 341,
+ PERCENT = 342,
+ LEFT_ANGLE = 343,
+ RIGHT_ANGLE = 344,
+ VERTICAL_BAR = 345,
+ CARET = 346,
+ AMPERSAND = 347,
+ QUESTION = 348
+ };
+#endif
+/* Tokens. */
+#define INVARIANT 258
+#define HIGH_PRECISION 259
+#define MEDIUM_PRECISION 260
+#define LOW_PRECISION 261
+#define PRECISION 262
+#define ATTRIBUTE 263
+#define CONST_QUAL 264
+#define BOOL_TYPE 265
+#define FLOAT_TYPE 266
+#define INT_TYPE 267
+#define BREAK 268
+#define CONTINUE 269
+#define DO 270
+#define ELSE 271
+#define FOR 272
+#define IF 273
+#define DISCARD 274
+#define RETURN 275
+#define BVEC2 276
+#define BVEC3 277
+#define BVEC4 278
+#define IVEC2 279
+#define IVEC3 280
+#define IVEC4 281
+#define VEC2 282
+#define VEC3 283
+#define VEC4 284
+#define MATRIX2 285
+#define MATRIX3 286
+#define MATRIX4 287
+#define IN_QUAL 288
+#define OUT_QUAL 289
+#define INOUT_QUAL 290
+#define UNIFORM 291
+#define VARYING 292
+#define STRUCT 293
+#define VOID_TYPE 294
+#define WHILE 295
+#define SAMPLER2D 296
+#define SAMPLERCUBE 297
+#define IDENTIFIER 298
+#define TYPE_NAME 299
+#define FLOATCONSTANT 300
+#define INTCONSTANT 301
+#define BOOLCONSTANT 302
+#define FIELD_SELECTION 303
+#define LEFT_OP 304
+#define RIGHT_OP 305
+#define INC_OP 306
+#define DEC_OP 307
+#define LE_OP 308
+#define GE_OP 309
+#define EQ_OP 310
+#define NE_OP 311
+#define AND_OP 312
+#define OR_OP 313
+#define XOR_OP 314
+#define MUL_ASSIGN 315
+#define DIV_ASSIGN 316
+#define ADD_ASSIGN 317
+#define MOD_ASSIGN 318
+#define LEFT_ASSIGN 319
+#define RIGHT_ASSIGN 320
+#define AND_ASSIGN 321
+#define XOR_ASSIGN 322
+#define OR_ASSIGN 323
+#define SUB_ASSIGN 324
+#define LEFT_PAREN 325
+#define RIGHT_PAREN 326
+#define LEFT_BRACKET 327
+#define RIGHT_BRACKET 328
+#define LEFT_BRACE 329
+#define RIGHT_BRACE 330
+#define DOT 331
+#define COMMA 332
+#define COLON 333
+#define EQUAL 334
+#define SEMICOLON 335
+#define BANG 336
+#define DASH 337
+#define TILDE 338
+#define PLUS 339
+#define STAR 340
+#define SLASH 341
+#define PERCENT 342
+#define LEFT_ANGLE 343
+#define RIGHT_ANGLE 344
+#define VERTICAL_BAR 345
+#define CARET 346
+#define AMPERSAND 347
+#define QUESTION 348
+
+
+
+
+/* Copy the first part of user declarations. */
+
+
+//
+// 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 is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
+
+#include "compiler/SymbolTable.h"
+#include "compiler/ParseHelper.h"
+#include "GLSLANG/ShaderLang.h"
+
+#define YYLEX_PARAM context->scanner
+
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+
+{
+ struct {
+ TSourceLoc line;
+ union {
+ TString *string;
+ float f;
+ int i;
+ bool b;
+ };
+ TSymbol* symbol;
+ } lex;
+ struct {
+ TSourceLoc line;
+ TOperator op;
+ union {
+ TIntermNode* intermNode;
+ TIntermNodePair nodePair;
+ TIntermTyped* intermTypedNode;
+ TIntermAggregate* intermAggregate;
+ };
+ union {
+ TPublicType type;
+ TPrecision precision;
+ TQualifier qualifier;
+ TFunction* function;
+ TParameter param;
+ TTypeLine typeLine;
+ TTypeList* typeList;
+ };
+ } interm;
+}
+/* Line 187 of yacc.c. */
+
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations. */
+
+
+extern int yylex(YYSTYPE* yylval_param, void* yyscanner);
+extern void yyerror(TParseContext* context, const char* reason);
+
+#define FRAG_VERT_ONLY(S, L) { \
+ if (context->shaderType != SH_FRAGMENT_SHADER && \
+ context->shaderType != SH_VERTEX_SHADER) { \
+ context->error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
+
+#define VERTEX_ONLY(S, L) { \
+ if (context->shaderType != SH_VERTEX_SHADER) { \
+ context->error(L, " supported in vertex shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
+
+#define FRAG_ONLY(S, L) { \
+ if (context->shaderType != SH_FRAGMENT_SHADER) { \
+ context->error(L, " supported in fragment shaders only ", S, "", ""); \
+ context->recover(); \
+ } \
+}
+
+
+/* Line 216 of yacc.c. */
+
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss;
+ YYSTYPE yyvs;
+ };
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack, Stack, yysize); \
+ Stack = &yyptr->Stack; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 69
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 1334
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 94
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 78
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 193
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 296
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 348
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 5, 7, 9, 11, 13, 17, 19,
+ 24, 26, 30, 33, 36, 38, 40, 42, 46, 49,
+ 52, 55, 57, 60, 64, 67, 69, 71, 73, 75,
+ 78, 81, 84, 86, 88, 90, 92, 96, 100, 102,
+ 106, 110, 112, 114, 118, 122, 126, 130, 132, 136,
+ 140, 142, 144, 146, 148, 152, 154, 158, 160, 164,
+ 166, 172, 174, 178, 180, 182, 184, 186, 188, 190,
+ 194, 196, 199, 202, 207, 210, 212, 214, 217, 221,
+ 225, 228, 234, 238, 241, 245, 248, 249, 251, 253,
+ 255, 257, 259, 263, 269, 276, 282, 284, 287, 292,
+ 298, 303, 306, 308, 311, 313, 315, 317, 320, 322,
+ 324, 327, 329, 331, 333, 335, 340, 342, 344, 346,
+ 348, 350, 352, 354, 356, 358, 360, 362, 364, 366,
+ 368, 370, 372, 374, 376, 378, 380, 386, 391, 393,
+ 396, 400, 402, 406, 408, 413, 415, 417, 419, 421,
+ 423, 425, 427, 429, 431, 434, 435, 436, 442, 444,
+ 446, 449, 453, 455, 458, 460, 463, 469, 473, 475,
+ 477, 482, 483, 490, 491, 500, 501, 509, 511, 513,
+ 515, 516, 519, 523, 526, 529, 532, 536, 539, 541,
+ 544, 546, 548, 549
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 168, 0, -1, 43, -1, 95, -1, 46, -1, 45,
+ -1, 47, -1, 70, 122, 71, -1, 96, -1, 97,
+ 72, 98, 73, -1, 99, -1, 97, 76, 48, -1,
+ 97, 51, -1, 97, 52, -1, 122, -1, 100, -1,
+ 101, -1, 97, 76, 101, -1, 103, 71, -1, 102,
+ 71, -1, 104, 39, -1, 104, -1, 104, 120, -1,
+ 103, 77, 120, -1, 105, 70, -1, 137, -1, 43,
+ -1, 48, -1, 97, -1, 51, 106, -1, 52, 106,
+ -1, 107, 106, -1, 84, -1, 82, -1, 81, -1,
+ 106, -1, 108, 85, 106, -1, 108, 86, 106, -1,
+ 108, -1, 109, 84, 108, -1, 109, 82, 108, -1,
+ 109, -1, 110, -1, 111, 88, 110, -1, 111, 89,
+ 110, -1, 111, 53, 110, -1, 111, 54, 110, -1,
+ 111, -1, 112, 55, 111, -1, 112, 56, 111, -1,
+ 112, -1, 113, -1, 114, -1, 115, -1, 116, 57,
+ 115, -1, 116, -1, 117, 59, 116, -1, 117, -1,
+ 118, 58, 117, -1, 118, -1, 118, 93, 122, 78,
+ 120, -1, 119, -1, 106, 121, 120, -1, 79, -1,
+ 60, -1, 61, -1, 62, -1, 69, -1, 120, -1,
+ 122, 77, 120, -1, 119, -1, 125, 80, -1, 133,
+ 80, -1, 7, 138, 139, 80, -1, 126, 71, -1,
+ 128, -1, 127, -1, 128, 130, -1, 127, 77, 130,
+ -1, 135, 43, 70, -1, 137, 43, -1, 137, 43,
+ 72, 123, 73, -1, 136, 131, 129, -1, 131, 129,
+ -1, 136, 131, 132, -1, 131, 132, -1, -1, 33,
+ -1, 34, -1, 35, -1, 137, -1, 134, -1, 133,
+ 77, 43, -1, 133, 77, 43, 72, 73, -1, 133,
+ 77, 43, 72, 123, 73, -1, 133, 77, 43, 79,
+ 146, -1, 135, -1, 135, 43, -1, 135, 43, 72,
+ 73, -1, 135, 43, 72, 123, 73, -1, 135, 43,
+ 79, 146, -1, 3, 43, -1, 137, -1, 136, 137,
+ -1, 9, -1, 8, -1, 37, -1, 3, 37, -1,
+ 36, -1, 139, -1, 138, 139, -1, 4, -1, 5,
+ -1, 6, -1, 140, -1, 140, 72, 123, 73, -1,
+ 39, -1, 11, -1, 12, -1, 10, -1, 27, -1,
+ 28, -1, 29, -1, 21, -1, 22, -1, 23, -1,
+ 24, -1, 25, -1, 26, -1, 30, -1, 31, -1,
+ 32, -1, 41, -1, 42, -1, 141, -1, 44, -1,
+ 38, 43, 74, 142, 75, -1, 38, 74, 142, 75,
+ -1, 143, -1, 142, 143, -1, 137, 144, 80, -1,
+ 145, -1, 144, 77, 145, -1, 43, -1, 43, 72,
+ 123, 73, -1, 120, -1, 124, -1, 150, -1, 149,
+ -1, 147, -1, 156, -1, 157, -1, 160, -1, 167,
+ -1, 74, 75, -1, -1, -1, 74, 151, 155, 152,
+ 75, -1, 154, -1, 149, -1, 74, 75, -1, 74,
+ 155, 75, -1, 148, -1, 155, 148, -1, 80, -1,
+ 122, 80, -1, 18, 70, 122, 71, 158, -1, 148,
+ 16, 148, -1, 148, -1, 122, -1, 135, 43, 79,
+ 146, -1, -1, 40, 70, 161, 159, 71, 153, -1,
+ -1, 15, 162, 148, 40, 70, 122, 71, 80, -1,
+ -1, 17, 70, 163, 164, 166, 71, 153, -1, 156,
+ -1, 147, -1, 159, -1, -1, 165, 80, -1, 165,
+ 80, 122, -1, 14, 80, -1, 13, 80, -1, 20,
+ 80, -1, 20, 122, 80, -1, 19, 80, -1, 169,
+ -1, 168, 169, -1, 170, -1, 124, -1, -1, 125,
+ 171, 154, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 153, 153, 188, 191, 204, 209, 214, 220, 223,
+ 296, 299, 408, 418, 431, 439, 538, 541, 549, 553,
+ 560, 564, 571, 577, 586, 594, 656, 663, 673, 676,
+ 686, 696, 717, 718, 719, 724, 725, 734, 746, 747,
+ 755, 766, 770, 771, 781, 791, 801, 814, 815, 825,
+ 838, 842, 846, 850, 851, 864, 865, 878, 879, 892,
+ 893, 910, 911, 924, 925, 926, 927, 928, 932, 935,
+ 946, 954, 979, 984, 991, 1027, 1030, 1037, 1045, 1066,
+ 1085, 1096, 1125, 1130, 1140, 1145, 1155, 1158, 1161, 1164,
+ 1170, 1177, 1187, 1199, 1217, 1241, 1264, 1268, 1282, 1302,
+ 1331, 1351, 1427, 1436, 1459, 1462, 1468, 1476, 1484, 1492,
+ 1495, 1502, 1505, 1508, 1514, 1517, 1532, 1536, 1540, 1544,
+ 1553, 1558, 1563, 1568, 1573, 1578, 1583, 1588, 1593, 1598,
+ 1604, 1610, 1616, 1621, 1626, 1631, 1644, 1657, 1665, 1668,
+ 1683, 1714, 1718, 1724, 1732, 1748, 1752, 1756, 1757, 1763,
+ 1764, 1765, 1766, 1767, 1771, 1772, 1772, 1772, 1780, 1781,
+ 1786, 1789, 1797, 1800, 1806, 1807, 1811, 1819, 1823, 1833,
+ 1838, 1855, 1855, 1860, 1860, 1867, 1867, 1875, 1878, 1884,
+ 1887, 1893, 1897, 1904, 1911, 1918, 1925, 1936, 1945, 1949,
+ 1956, 1959, 1965, 1965
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "INVARIANT", "HIGH_PRECISION",
+ "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "ATTRIBUTE",
+ "CONST_QUAL", "BOOL_TYPE", "FLOAT_TYPE", "INT_TYPE", "BREAK", "CONTINUE",
+ "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "BVEC2", "BVEC3",
+ "BVEC4", "IVEC2", "IVEC3", "IVEC4", "VEC2", "VEC3", "VEC4", "MATRIX2",
+ "MATRIX3", "MATRIX4", "IN_QUAL", "OUT_QUAL", "INOUT_QUAL", "UNIFORM",
+ "VARYING", "STRUCT", "VOID_TYPE", "WHILE", "SAMPLER2D", "SAMPLERCUBE",
+ "IDENTIFIER", "TYPE_NAME", "FLOATCONSTANT", "INTCONSTANT",
+ "BOOLCONSTANT", "FIELD_SELECTION", "LEFT_OP", "RIGHT_OP", "INC_OP",
+ "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP",
+ "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN",
+ "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN",
+ "SUB_ASSIGN", "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET",
+ "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON",
+ "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH",
+ "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET",
+ "AMPERSAND", "QUESTION", "$accept", "variable_identifier",
+ "primary_expression", "postfix_expression", "integer_expression",
+ "function_call", "function_call_or_method", "function_call_generic",
+ "function_call_header_no_parameters",
+ "function_call_header_with_parameters", "function_call_header",
+ "function_identifier", "unary_expression", "unary_operator",
+ "multiplicative_expression", "additive_expression", "shift_expression",
+ "relational_expression", "equality_expression", "and_expression",
+ "exclusive_or_expression", "inclusive_or_expression",
+ "logical_and_expression", "logical_xor_expression",
+ "logical_or_expression", "conditional_expression",
+ "assignment_expression", "assignment_operator", "expression",
+ "constant_expression", "declaration", "function_prototype",
+ "function_declarator", "function_header_with_parameters",
+ "function_header", "parameter_declarator", "parameter_declaration",
+ "parameter_qualifier", "parameter_type_specifier",
+ "init_declarator_list", "single_declaration", "fully_specified_type",
+ "type_qualifier", "type_specifier", "precision_qualifier",
+ "type_specifier_no_prec", "type_specifier_nonarray", "struct_specifier",
+ "struct_declaration_list", "struct_declaration",
+ "struct_declarator_list", "struct_declarator", "initializer",
+ "declaration_statement", "statement", "simple_statement",
+ "compound_statement", "@1", "@2", "statement_no_new_scope",
+ "compound_statement_no_new_scope", "statement_list",
+ "expression_statement", "selection_statement",
+ "selection_rest_statement", "condition", "iteration_statement", "@3",
+ "@4", "@5", "for_init_statement", "conditionopt", "for_rest_statement",
+ "jump_statement", "translation_unit", "external_declaration",
+ "function_definition", "@6", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 94, 95, 96, 96, 96, 96, 96, 97, 97,
+ 97, 97, 97, 97, 98, 99, 100, 100, 101, 101,
+ 102, 102, 103, 103, 104, 105, 105, 105, 106, 106,
+ 106, 106, 107, 107, 107, 108, 108, 108, 109, 109,
+ 109, 110, 111, 111, 111, 111, 111, 112, 112, 112,
+ 113, 114, 115, 116, 116, 117, 117, 118, 118, 119,
+ 119, 120, 120, 121, 121, 121, 121, 121, 122, 122,
+ 123, 124, 124, 124, 125, 126, 126, 127, 127, 128,
+ 129, 129, 130, 130, 130, 130, 131, 131, 131, 131,
+ 132, 133, 133, 133, 133, 133, 134, 134, 134, 134,
+ 134, 134, 135, 135, 136, 136, 136, 136, 136, 137,
+ 137, 138, 138, 138, 139, 139, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 140, 141, 141, 142, 142,
+ 143, 144, 144, 145, 145, 146, 147, 148, 148, 149,
+ 149, 149, 149, 149, 150, 151, 152, 150, 153, 153,
+ 154, 154, 155, 155, 156, 156, 157, 158, 158, 159,
+ 159, 161, 160, 162, 160, 163, 160, 164, 164, 165,
+ 165, 166, 166, 167, 167, 167, 167, 167, 168, 168,
+ 169, 169, 171, 170
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 1, 1, 1, 1, 1, 3, 1, 4,
+ 1, 3, 2, 2, 1, 1, 1, 3, 2, 2,
+ 2, 1, 2, 3, 2, 1, 1, 1, 1, 2,
+ 2, 2, 1, 1, 1, 1, 3, 3, 1, 3,
+ 3, 1, 1, 3, 3, 3, 3, 1, 3, 3,
+ 1, 1, 1, 1, 3, 1, 3, 1, 3, 1,
+ 5, 1, 3, 1, 1, 1, 1, 1, 1, 3,
+ 1, 2, 2, 4, 2, 1, 1, 2, 3, 3,
+ 2, 5, 3, 2, 3, 2, 0, 1, 1, 1,
+ 1, 1, 3, 5, 6, 5, 1, 2, 4, 5,
+ 4, 2, 1, 2, 1, 1, 1, 2, 1, 1,
+ 2, 1, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 5, 4, 1, 2,
+ 3, 1, 3, 1, 4, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 0, 0, 5, 1, 1,
+ 2, 3, 1, 2, 1, 2, 5, 3, 1, 1,
+ 4, 0, 6, 0, 8, 0, 7, 1, 1, 1,
+ 0, 2, 3, 2, 2, 2, 3, 2, 1, 2,
+ 1, 1, 0, 3
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint8 yydefact[] =
+{
+ 0, 0, 111, 112, 113, 0, 105, 104, 119, 117,
+ 118, 123, 124, 125, 126, 127, 128, 120, 121, 122,
+ 129, 130, 131, 108, 106, 0, 116, 132, 133, 135,
+ 191, 192, 0, 76, 86, 0, 91, 96, 0, 102,
+ 0, 109, 114, 134, 0, 188, 190, 107, 101, 0,
+ 0, 0, 71, 0, 74, 86, 0, 87, 88, 89,
+ 77, 0, 86, 0, 72, 97, 103, 110, 0, 1,
+ 189, 0, 0, 0, 0, 138, 0, 193, 78, 83,
+ 85, 90, 0, 92, 79, 0, 0, 2, 5, 4,
+ 6, 27, 0, 0, 0, 34, 33, 32, 3, 8,
+ 28, 10, 15, 16, 0, 0, 21, 0, 35, 0,
+ 38, 41, 42, 47, 50, 51, 52, 53, 55, 57,
+ 59, 70, 0, 25, 73, 0, 143, 0, 141, 137,
+ 139, 0, 0, 173, 0, 0, 0, 0, 0, 155,
+ 160, 164, 35, 61, 68, 0, 146, 0, 102, 149,
+ 162, 148, 147, 0, 150, 151, 152, 153, 80, 82,
+ 84, 0, 0, 98, 0, 145, 100, 29, 30, 0,
+ 12, 13, 0, 0, 19, 18, 0, 116, 22, 24,
+ 31, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 115, 136, 0, 0, 140,
+ 184, 183, 0, 175, 0, 187, 185, 0, 171, 154,
+ 0, 64, 65, 66, 67, 63, 0, 0, 165, 161,
+ 163, 0, 93, 0, 95, 99, 7, 0, 14, 26,
+ 11, 17, 23, 36, 37, 40, 39, 45, 46, 43,
+ 44, 48, 49, 54, 56, 58, 0, 0, 142, 0,
+ 0, 0, 186, 0, 156, 62, 69, 0, 94, 9,
+ 0, 144, 0, 178, 177, 180, 0, 169, 0, 0,
+ 0, 81, 60, 0, 179, 0, 0, 168, 166, 0,
+ 0, 157, 0, 181, 0, 0, 0, 159, 172, 158,
+ 0, 182, 176, 167, 170, 174
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 98, 99, 100, 227, 101, 102, 103, 104, 105,
+ 106, 107, 142, 109, 110, 111, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 143, 144, 216, 145, 122,
+ 146, 147, 32, 33, 34, 79, 60, 61, 80, 35,
+ 36, 37, 38, 123, 40, 41, 42, 43, 74, 75,
+ 127, 128, 166, 149, 150, 151, 152, 210, 270, 288,
+ 289, 153, 154, 155, 278, 269, 156, 253, 202, 250,
+ 265, 275, 276, 157, 44, 45, 46, 53
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -250
+static const yytype_int16 yypact[] =
+{
+ 1225, 36, -250, -250, -250, 150, -250, -250, -250, -250,
+ -250, -250, -250, -250, -250, -250, -250, -250, -250, -250,
+ -250, -250, -250, -250, -250, -33, -250, -250, -250, -250,
+ -250, -60, -22, -17, 21, -62, -250, 22, 1266, -250,
+ 1290, -250, 11, -250, 1138, -250, -250, -250, -250, 1290,
+ 14, 1266, -250, 27, -250, 34, 41, -250, -250, -250,
+ -250, 1266, 129, 61, -250, 17, -250, -250, 908, -250,
+ -250, 31, 1266, 72, 1042, -250, 283, -250, -250, -250,
+ -250, 90, 1266, -46, -250, 194, 908, 65, -250, -250,
+ -250, -250, 908, 908, 908, -250, -250, -250, -250, -250,
+ -40, -250, -250, -250, 80, -25, 975, 87, -250, 908,
+ 35, 13, -250, -26, 68, -250, -250, -250, 110, 109,
+ -54, -250, 96, -250, -250, 1083, 98, 33, -250, -250,
+ -250, 91, 92, -250, 104, 107, 99, 760, 108, 105,
+ -250, -250, 24, -250, -250, 37, -250, -60, 112, -250,
+ -250, -250, -250, 365, -250, -250, -250, -250, 111, -250,
+ -250, 827, 908, -250, 113, -250, -250, -250, -250, 4,
+ -250, -250, 908, 1179, -250, -250, 908, 114, -250, -250,
+ -250, 908, 908, 908, 908, 908, 908, 908, 908, 908,
+ 908, 908, 908, 908, 908, -250, -250, 908, 72, -250,
+ -250, -250, 447, -250, 908, -250, -250, 42, -250, -250,
+ 447, -250, -250, -250, -250, -250, 908, 908, -250, -250,
+ -250, 908, -250, 115, -250, -250, -250, 116, 117, -250,
+ 120, -250, -250, -250, -250, 35, 35, -250, -250, -250,
+ -250, -26, -26, -250, 110, 109, 51, 119, -250, 144,
+ 611, 23, -250, 693, 447, -250, -250, 122, -250, -250,
+ 908, -250, 123, -250, -250, 693, 447, 117, 153, 126,
+ 128, -250, -250, 908, -250, 127, 137, 171, -250, 130,
+ 529, -250, 28, 908, 529, 447, 908, -250, -250, -250,
+ 131, 117, -250, -250, -250, -250
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -250, -250, -250, -250, -250, -250, -250, 39, -250, -250,
+ -250, -250, -45, -250, -18, -250, -79, -30, -250, -250,
+ -250, 38, 52, 20, -250, -63, -85, -250, -92, -71,
+ 6, 9, -250, -250, -250, 132, 172, 166, 148, -250,
+ -250, -246, -21, 0, 226, -24, -250, -250, 162, -66,
+ -250, 45, -159, -3, -136, -249, -250, -250, -250, -36,
+ 196, 46, 1, -250, -250, -13, -250, -250, -250, -250,
+ -250, -250, -250, -250, -250, 211, -250, -250
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -76
+static const yytype_int16 yytable[] =
+{
+ 39, 165, 169, 224, 193, 121, 30, 268, 130, 31,
+ 50, 170, 171, 62, 164, 63, 67, 220, 64, 268,
+ 52, 178, 121, 108, 56, 71, 161, 185, 186, 6,
+ 7, 287, 172, 162, 62, 287, 173, 56, 66, 194,
+ 108, 51, 6, 7, 39, 207, 175, 167, 168, 54,
+ 30, 73, 176, 31, 57, 58, 59, 23, 24, 130,
+ 55, 81, 187, 188, 180, 65, 249, 57, 58, 59,
+ 23, 24, 73, 47, 73, 226, 148, 165, 47, 48,
+ 228, 217, 81, 68, 211, 212, 213, 84, 72, 85,
+ 223, 232, -75, 214, 266, 183, 86, 184, 121, 290,
+ 217, 76, 246, 215, 83, 217, 237, 238, 239, 240,
+ 198, 124, 251, 199, 217, 126, 108, 218, 220, 217,
+ 181, 182, 252, 189, 190, 73, 247, 294, 217, 260,
+ 277, 255, 256, 158, 121, -26, 233, 234, 108, 108,
+ 108, 108, 108, 108, 108, 108, 108, 108, 108, 293,
+ 257, 174, 108, 148, 2, 3, 4, 179, 121, 241,
+ 242, 267, 57, 58, 59, 235, 236, 191, 192, 195,
+ 197, 200, 201, 267, 203, 272, 108, 204, 208, 205,
+ 209, 282, -25, 221, 262, -20, 225, 285, 258, 259,
+ -27, 291, 261, 273, 217, 271, 279, 280, 2, 3,
+ 4, 165, 148, 281, 8, 9, 10, 283, 284, 286,
+ 148, 295, 231, 245, 159, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 78, 82, 243,
+ 160, 49, 25, 26, 125, 27, 28, 87, 29, 88,
+ 89, 90, 91, 248, 244, 92, 93, 263, 292, 77,
+ 148, 264, 274, 148, 148, 70, 254, 0, 0, 0,
+ 0, 0, 0, 0, 94, 148, 148, 163, 0, 0,
+ 0, 0, 0, 0, 0, 95, 96, 0, 97, 0,
+ 148, 0, 0, 0, 148, 148, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 131, 132, 133, 0,
+ 134, 135, 136, 137, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 0, 0, 0, 23,
+ 24, 25, 26, 138, 27, 28, 87, 29, 88, 89,
+ 90, 91, 0, 0, 92, 93, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 94, 0, 0, 0, 139, 140, 0,
+ 0, 0, 0, 141, 95, 96, 0, 97, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 131, 132,
+ 133, 0, 134, 135, 136, 137, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 0,
+ 0, 23, 24, 25, 26, 138, 27, 28, 87, 29,
+ 88, 89, 90, 91, 0, 0, 92, 93, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 94, 0, 0, 0, 139,
+ 219, 0, 0, 0, 0, 141, 95, 96, 0, 97,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 131, 132, 133, 0, 134, 135, 136, 137, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 0, 0, 0, 23, 24, 25, 26, 138, 27, 28,
+ 87, 29, 88, 89, 90, 91, 0, 0, 92, 93,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 94, 0, 0,
+ 0, 139, 0, 0, 0, 0, 0, 141, 95, 96,
+ 0, 97, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 131, 132, 133, 0, 134, 135, 136, 137,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 0, 0, 0, 23, 24, 25, 26, 138,
+ 27, 28, 87, 29, 88, 89, 90, 91, 0, 0,
+ 92, 93, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 94,
+ 0, 0, 0, 76, 0, 0, 0, 0, 0, 141,
+ 95, 96, 0, 97, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 0, 0, 0, 23, 24, 25,
+ 26, 0, 27, 28, 87, 29, 88, 89, 90, 91,
+ 0, 0, 92, 93, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 94, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 141, 95, 96, 0, 97, 56, 2, 3, 4,
+ 0, 6, 7, 8, 9, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 0, 0, 0, 23,
+ 24, 25, 26, 0, 27, 28, 87, 29, 88, 89,
+ 90, 91, 0, 0, 92, 93, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 94, 2, 3, 4, 0, 0, 0,
+ 8, 9, 10, 0, 95, 96, 0, 97, 0, 0,
+ 0, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 0, 0, 0, 0, 0, 25, 26,
+ 0, 27, 28, 87, 29, 88, 89, 90, 91, 0,
+ 0, 92, 93, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 94, 2, 3, 4, 0, 0, 0, 8, 9, 10,
+ 206, 95, 96, 0, 97, 0, 0, 0, 11, 12,
+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+ 0, 0, 0, 0, 0, 25, 26, 0, 27, 28,
+ 87, 29, 88, 89, 90, 91, 0, 0, 92, 93,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 94, 0, 0,
+ 222, 0, 0, 0, 0, 0, 0, 0, 95, 96,
+ 0, 97, 2, 3, 4, 0, 0, 0, 8, 9,
+ 10, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 0, 0, 0, 0, 0, 25, 26, 0, 27,
+ 28, 87, 29, 88, 89, 90, 91, 0, 0, 92,
+ 93, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 94, 2,
+ 3, 4, 0, 0, 0, 8, 9, 10, 0, 95,
+ 96, 0, 97, 0, 0, 0, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 0,
+ 0, 0, 0, 25, 177, 0, 27, 28, 87, 29,
+ 88, 89, 90, 91, 0, 0, 92, 93, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 94, 2, 3, 4, 0,
+ 0, 0, 8, 9, 10, 0, 95, 96, 0, 97,
+ 0, 0, 0, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 0, 0, 0, 0, 0,
+ 25, 26, 0, 27, 28, 0, 29, 2, 3, 4,
+ 0, 0, 0, 8, 9, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 0, 129, 0, 0,
+ 0, 25, 26, 0, 27, 28, 0, 29, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 69, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 0, 0, 0, 0, 0, 0, 0, 196, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 0, 0, 0, 23, 24, 25, 26, 0, 27,
+ 28, 0, 29, 2, 3, 4, 0, 0, 0, 8,
+ 9, 10, 0, 0, 0, 0, 0, 0, 0, 0,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 0, 0, 0, 0, 0, 25, 26, 0,
+ 27, 28, 229, 29, 0, 0, 0, 230, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 0, 0,
+ 0, 23, 24, 25, 26, 0, 27, 28, 0, 29,
+ 2, 3, 4, 0, 0, 0, 8, 9, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 0,
+ 8, 9, 10, 0, 25, 26, 0, 27, 28, 0,
+ 29, 11, 12, 13, 14, 15, 16, 17, 18, 19,
+ 20, 21, 22, 0, 0, 0, 0, 0, 25, 26,
+ 0, 27, 28, 0, 29
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 0, 86, 94, 162, 58, 68, 0, 253, 74, 0,
+ 43, 51, 52, 34, 85, 77, 40, 153, 80, 265,
+ 80, 106, 85, 68, 3, 49, 72, 53, 54, 8,
+ 9, 280, 72, 79, 55, 284, 76, 3, 38, 93,
+ 85, 74, 8, 9, 44, 137, 71, 92, 93, 71,
+ 44, 51, 77, 44, 33, 34, 35, 36, 37, 125,
+ 77, 61, 88, 89, 109, 43, 202, 33, 34, 35,
+ 36, 37, 72, 37, 74, 71, 76, 162, 37, 43,
+ 172, 77, 82, 72, 60, 61, 62, 70, 74, 72,
+ 161, 176, 71, 69, 71, 82, 79, 84, 161, 71,
+ 77, 74, 194, 79, 43, 77, 185, 186, 187, 188,
+ 77, 80, 204, 80, 77, 43, 161, 80, 254, 77,
+ 85, 86, 80, 55, 56, 125, 197, 286, 77, 78,
+ 266, 216, 217, 43, 197, 70, 181, 182, 183, 184,
+ 185, 186, 187, 188, 189, 190, 191, 192, 193, 285,
+ 221, 71, 197, 153, 4, 5, 6, 70, 221, 189,
+ 190, 253, 33, 34, 35, 183, 184, 57, 59, 73,
+ 72, 80, 80, 265, 70, 260, 221, 70, 70, 80,
+ 75, 273, 70, 72, 40, 71, 73, 16, 73, 73,
+ 70, 283, 73, 70, 77, 73, 43, 71, 4, 5,
+ 6, 286, 202, 75, 10, 11, 12, 80, 71, 79,
+ 210, 80, 173, 193, 82, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 55, 62, 191,
+ 82, 5, 38, 39, 72, 41, 42, 43, 44, 45,
+ 46, 47, 48, 198, 192, 51, 52, 250, 284, 53,
+ 250, 250, 265, 253, 254, 44, 210, -1, -1, -1,
+ -1, -1, -1, -1, 70, 265, 266, 73, -1, -1,
+ -1, -1, -1, -1, -1, 81, 82, -1, 84, -1,
+ 280, -1, -1, -1, 284, 285, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, -1,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, -1, -1, -1, 36,
+ 37, 38, 39, 40, 41, 42, 43, 44, 45, 46,
+ 47, 48, -1, -1, 51, 52, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 70, -1, -1, -1, 74, 75, -1,
+ -1, -1, -1, 80, 81, 82, -1, 84, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, -1, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, -1,
+ -1, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, -1, -1, 51, 52, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 70, -1, -1, -1, 74,
+ 75, -1, -1, -1, -1, 80, 81, 82, -1, 84,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, -1, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, 36, 37, 38, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 48, -1, -1, 51, 52,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 70, -1, -1,
+ -1, 74, -1, -1, -1, -1, -1, 80, 81, 82,
+ -1, 84, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, -1, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, -1, -1, -1, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, -1, -1,
+ 51, 52, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 70,
+ -1, -1, -1, 74, -1, -1, -1, -1, -1, 80,
+ 81, 82, -1, 84, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, -1, -1, -1, -1, -1, -1,
+ -1, -1, 21, 22, 23, 24, 25, 26, 27, 28,
+ 29, 30, 31, 32, -1, -1, -1, 36, 37, 38,
+ 39, -1, 41, 42, 43, 44, 45, 46, 47, 48,
+ -1, -1, 51, 52, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 70, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 80, 81, 82, -1, 84, 3, 4, 5, 6,
+ -1, 8, 9, 10, 11, 12, -1, -1, -1, -1,
+ -1, -1, -1, -1, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, -1, -1, -1, 36,
+ 37, 38, 39, -1, 41, 42, 43, 44, 45, 46,
+ 47, 48, -1, -1, 51, 52, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 70, 4, 5, 6, -1, -1, -1,
+ 10, 11, 12, -1, 81, 82, -1, 84, -1, -1,
+ -1, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, -1, -1, -1, -1, 38, 39,
+ -1, 41, 42, 43, 44, 45, 46, 47, 48, -1,
+ -1, 51, 52, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 70, 4, 5, 6, -1, -1, -1, 10, 11, 12,
+ 80, 81, 82, -1, 84, -1, -1, -1, 21, 22,
+ 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ -1, -1, -1, -1, -1, 38, 39, -1, 41, 42,
+ 43, 44, 45, 46, 47, 48, -1, -1, 51, 52,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 70, -1, -1,
+ 73, -1, -1, -1, -1, -1, -1, -1, 81, 82,
+ -1, 84, 4, 5, 6, -1, -1, -1, 10, 11,
+ 12, -1, -1, -1, -1, -1, -1, -1, -1, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, -1, -1, -1, -1, 38, 39, -1, 41,
+ 42, 43, 44, 45, 46, 47, 48, -1, -1, 51,
+ 52, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 70, 4,
+ 5, 6, -1, -1, -1, 10, 11, 12, -1, 81,
+ 82, -1, 84, -1, -1, -1, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, -1,
+ -1, -1, -1, 38, 39, -1, 41, 42, 43, 44,
+ 45, 46, 47, 48, -1, -1, 51, 52, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 70, 4, 5, 6, -1,
+ -1, -1, 10, 11, 12, -1, 81, 82, -1, 84,
+ -1, -1, -1, 21, 22, 23, 24, 25, 26, 27,
+ 28, 29, 30, 31, 32, -1, -1, -1, -1, -1,
+ 38, 39, -1, 41, 42, -1, 44, 4, 5, 6,
+ -1, -1, -1, 10, 11, 12, -1, -1, -1, -1,
+ -1, -1, -1, -1, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, -1, 75, -1, -1,
+ -1, 38, 39, -1, 41, 42, -1, 44, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, -1,
+ -1, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, -1, -1, -1, -1, -1, -1, -1, 75, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, -1, -1, -1, 36, 37, 38, 39, -1, 41,
+ 42, -1, 44, 4, 5, 6, -1, -1, -1, 10,
+ 11, 12, -1, -1, -1, -1, -1, -1, -1, -1,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
+ 31, 32, -1, -1, -1, -1, -1, 38, 39, -1,
+ 41, 42, 43, 44, -1, -1, -1, 48, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, -1, -1,
+ -1, -1, -1, -1, -1, -1, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, -1, -1,
+ -1, 36, 37, 38, 39, -1, 41, 42, -1, 44,
+ 4, 5, 6, -1, -1, -1, 10, 11, 12, -1,
+ -1, -1, -1, -1, -1, -1, -1, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31, 32, -1,
+ 10, 11, 12, -1, 38, 39, -1, 41, 42, -1,
+ 44, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, -1, -1, -1, -1, -1, 38, 39,
+ -1, 41, 42, -1, 44
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 4, 5, 6, 7, 8, 9, 10, 11,
+ 12, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 36, 37, 38, 39, 41, 42, 44,
+ 124, 125, 126, 127, 128, 133, 134, 135, 136, 137,
+ 138, 139, 140, 141, 168, 169, 170, 37, 43, 138,
+ 43, 74, 80, 171, 71, 77, 3, 33, 34, 35,
+ 130, 131, 136, 77, 80, 43, 137, 139, 72, 0,
+ 169, 139, 74, 137, 142, 143, 74, 154, 130, 129,
+ 132, 137, 131, 43, 70, 72, 79, 43, 45, 46,
+ 47, 48, 51, 52, 70, 81, 82, 84, 95, 96,
+ 97, 99, 100, 101, 102, 103, 104, 105, 106, 107,
+ 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
+ 118, 119, 123, 137, 80, 142, 43, 144, 145, 75,
+ 143, 13, 14, 15, 17, 18, 19, 20, 40, 74,
+ 75, 80, 106, 119, 120, 122, 124, 125, 137, 147,
+ 148, 149, 150, 155, 156, 157, 160, 167, 43, 129,
+ 132, 72, 79, 73, 123, 120, 146, 106, 106, 122,
+ 51, 52, 72, 76, 71, 71, 77, 39, 120, 70,
+ 106, 85, 86, 82, 84, 53, 54, 88, 89, 55,
+ 56, 57, 59, 58, 93, 73, 75, 72, 77, 80,
+ 80, 80, 162, 70, 70, 80, 80, 122, 70, 75,
+ 151, 60, 61, 62, 69, 79, 121, 77, 80, 75,
+ 148, 72, 73, 123, 146, 73, 71, 98, 122, 43,
+ 48, 101, 120, 106, 106, 108, 108, 110, 110, 110,
+ 110, 111, 111, 115, 116, 117, 122, 123, 145, 148,
+ 163, 122, 80, 161, 155, 120, 120, 123, 73, 73,
+ 78, 73, 40, 147, 156, 164, 71, 122, 135, 159,
+ 152, 73, 120, 70, 159, 165, 166, 148, 158, 43,
+ 71, 75, 122, 80, 71, 16, 79, 149, 153, 154,
+ 71, 122, 153, 148, 146, 80
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (context, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, context); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, context)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ TParseContext* context;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (context);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, TParseContext* context)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, context)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ TParseContext* context;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, context);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+ yytype_int16 *bottom;
+ yytype_int16 *top;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; bottom <= top; ++bottom)
+ YYFPRINTF (stderr, " %d", *bottom);
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule, TParseContext* context)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule, context)
+ YYSTYPE *yyvsp;
+ int yyrule;
+ TParseContext* context;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , context);
+ fprintf (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule, context); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, TParseContext* context)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, context)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ TParseContext* context;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (context);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes. */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (TParseContext* context);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (TParseContext* context)
+#else
+int
+yyparse (context)
+ TParseContext* context;
+#endif
+#endif
+{
+ /* The look-ahead symbol. */
+int yychar;
+
+/* The semantic value of the look-ahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+ int yystate;
+ int yyn;
+ int yyresult;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+ /* Look-ahead token as an internal (translated) token number. */
+ int yytoken = 0;
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+ /* Three stacks and their tools:
+ `yyss': related to states,
+ `yyvs': related to semantic values,
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss = yyssa;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs = yyvsa;
+ YYSTYPE *yyvsp;
+
+
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ YYSIZE_T yystacksize = YYINITDEPTH;
+
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss);
+ YYSTACK_RELOCATE (yyvs);
+
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ look-ahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to look-ahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a look-ahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the look-ahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token unless it is eof. */
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 2:
+
+ {
+ // The symbol table search was done in the lexical phase
+ const TSymbol* symbol = (yyvsp[(1) - (1)].lex).symbol;
+ const TVariable* variable;
+ if (symbol == 0) {
+ context->error((yyvsp[(1) - (1)].lex).line, "undeclared identifier", (yyvsp[(1) - (1)].lex).string->c_str(), "");
+ context->recover();
+ TType type(EbtFloat, EbpUndefined);
+ TVariable* fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
+ context->symbolTable.insert(*fakeVariable);
+ variable = fakeVariable;
+ } else {
+ // This identifier can only be a variable type symbol
+ if (! symbol->isVariable()) {
+ context->error((yyvsp[(1) - (1)].lex).line, "variable expected", (yyvsp[(1) - (1)].lex).string->c_str(), "");
+ context->recover();
+ }
+ variable = static_cast<const TVariable*>(symbol);
+ }
+
+ // don't delete $1.string, it's used by error recovery, and the pool
+ // pop will reclaim the memory
+
+ if (variable->getType().getQualifier() == EvqConst ) {
+ ConstantUnion* constArray = variable->getConstPointer();
+ TType t(variable->getType());
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(constArray, t, (yyvsp[(1) - (1)].lex).line);
+ } else
+ (yyval.interm.intermTypedNode) = context->intermediate.addSymbol(variable->getUniqueId(),
+ variable->getName(),
+ variable->getType(), (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 3:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 4:
+
+ {
+ //
+ // INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
+ // check for overflow for constants
+ //
+ if (abs((yyvsp[(1) - (1)].lex).i) >= (1 << 16)) {
+ context->error((yyvsp[(1) - (1)].lex).line, " integer constant overflow", "", "");
+ context->recover();
+ }
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setIConst((yyvsp[(1) - (1)].lex).i);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 5:
+
+ {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setFConst((yyvsp[(1) - (1)].lex).f);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 6:
+
+ {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst((yyvsp[(1) - (1)].lex).b);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 7:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(2) - (3)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 8:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 9:
+
+ {
+ if (!(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode())
+ context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", (yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode()->getSymbol().c_str(), "");
+ else
+ context->error((yyvsp[(2) - (4)].lex).line, " left of '[' is not of type array, matrix, or vector ", "expression", "");
+ context->recover();
+ }
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst && (yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) { // constant folding for arrays
+ (yyval.interm.intermTypedNode) = context->addConstArrayNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+ } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector()) { // constant folding for vectors
+ TVectorFields fields;
+ fields.num = 1;
+ fields.offsets[0] = (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(); // need to do it this way because v.xy sends fields integer array
+ (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+ } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) { // constant folding for matrices
+ (yyval.interm.intermTypedNode) = context->addConstMatrixNode((yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+ }
+ } else {
+ if ((yyvsp[(3) - (4)].interm.intermTypedNode)->getQualifier() == EvqConst) {
+ if (((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() || (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()) && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getNominalSize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() && !(yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() ) {
+ context->error((yyvsp[(2) - (4)].lex).line, "", "[", "field selection out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+ context->recover();
+ } else {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getMaxArraySize() <= (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst()) {
+ if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst(), true, (yyvsp[(2) - (4)].lex).line))
+ context->recover();
+ } else {
+ if (context->arraySetMaxSize((yyvsp[(1) - (4)].interm.intermTypedNode)->getAsSymbolNode(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getTypePointer(), 0, false, (yyvsp[(2) - (4)].lex).line))
+ context->recover();
+ }
+ } else if ( (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst() >= (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize()) {
+ context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array index out of range '%d'", (yyvsp[(3) - (4)].interm.intermTypedNode)->getAsConstantUnion()->getUnionArrayPointer()->getIConst());
+ context->recover();
+ }
+ }
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+ }
+ } else {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getArraySize() == 0) {
+ context->error((yyvsp[(2) - (4)].lex).line, "", "[", "array must be redeclared with a size before being indexed with a variable");
+ context->recover();
+ }
+
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexIndirect, (yyvsp[(1) - (4)].interm.intermTypedNode), (yyvsp[(3) - (4)].interm.intermTypedNode), (yyvsp[(2) - (4)].lex).line);
+ }
+ }
+ if ((yyval.interm.intermTypedNode) == 0) {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setFConst(0.0f);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), (yyvsp[(2) - (4)].lex).line);
+ } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isArray()) {
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct())
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getStruct(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getTypeName()));
+ else
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize(), (yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix()));
+
+ if ((yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+ (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
+ } else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
+ else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isMatrix())
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (yyvsp[(1) - (4)].interm.intermTypedNode)->getNominalSize()));
+ else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector() && (yyvsp[(1) - (4)].interm.intermTypedNode)->getType().getQualifier() == EvqConst)
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqConst));
+ else if ((yyvsp[(1) - (4)].interm.intermTypedNode)->isVector())
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (4)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (4)].interm.intermTypedNode)->getPrecision(), EvqTemporary));
+ else
+ (yyval.interm.intermTypedNode)->setType((yyvsp[(1) - (4)].interm.intermTypedNode)->getType());
+ ;}
+ break;
+
+ case 10:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 11:
+
+ {
+ if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isArray()) {
+ context->error((yyvsp[(3) - (3)].lex).line, "cannot apply dot operator to an array", ".", "");
+ context->recover();
+ }
+
+ if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isVector()) {
+ TVectorFields fields;
+ if (! context->parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+ fields.num = 1;
+ fields.offsets[0] = 0;
+ context->recover();
+ }
+
+ if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) { // constant folding for vector fields
+ (yyval.interm.intermTypedNode) = context->addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].lex).line);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ else
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size()));
+ } else {
+ if (fields.num == 1) {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setIConst(fields.offsets[0]);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
+ } else {
+ TString vectorString = *(yyvsp[(3) - (3)].lex).string;
+ TIntermTyped* index = context->intermediate.addSwizzle(fields, (yyvsp[(3) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(), EvqTemporary, (int) vectorString.size()));
+ }
+ }
+ } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->isMatrix()) {
+ TMatrixFields fields;
+ if (! context->parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize(), fields, (yyvsp[(3) - (3)].lex).line)) {
+ fields.wholeRow = false;
+ fields.wholeCol = false;
+ fields.row = 0;
+ fields.col = 0;
+ context->recover();
+ }
+
+ if (fields.wholeRow || fields.wholeCol) {
+ context->error((yyvsp[(2) - (3)].lex).line, " non-scalar fields not implemented yet", ".", "");
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setIConst(0);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize()));
+ } else {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)->getNominalSize() + fields.row);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yyvsp[(3) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode)->setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)->getPrecision()));
+ }
+ } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getBasicType() == EbtStruct) {
+ bool fieldFound = false;
+ const TTypeList* fields = (yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getStruct();
+ if (fields == 0) {
+ context->error((yyvsp[(2) - (3)].lex).line, "structure has no fields", "Internal Error", "");
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ } else {
+ unsigned int i;
+ for (i = 0; i < fields->size(); ++i) {
+ if ((*fields)[i].type->getFieldName() == *(yyvsp[(3) - (3)].lex).string) {
+ fieldFound = true;
+ break;
+ }
+ }
+ if (fieldFound) {
+ if ((yyvsp[(1) - (3)].interm.intermTypedNode)->getType().getQualifier() == EvqConst) {
+ (yyval.interm.intermTypedNode) = context->addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ else {
+ (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+ // change the qualifier of the return type, not of the structure field
+ // as the structure definition is shared between various structures.
+ (yyval.interm.intermTypedNode)->getTypePointer()->setQualifier(EvqConst);
+ }
+ } else {
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setIConst(i);
+ TIntermTyped* index = context->intermediate.addConstantUnion(unionArray, *(*fields)[i].type, (yyvsp[(3) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode)->setType(*(*fields)[i].type);
+ }
+ } else {
+ context->error((yyvsp[(2) - (3)].lex).line, " no such field in structure", (yyvsp[(3) - (3)].lex).string->c_str(), "");
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ }
+ } else {
+ context->error((yyvsp[(2) - (3)].lex).line, " field selection requires structure, vector, or matrix on left hand side", (yyvsp[(3) - (3)].lex).string->c_str(), "");
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ // don't delete $3.string, it's from the pool
+ ;}
+ break;
+
+ case 12:
+
+ {
+ if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->unaryOpError((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 13:
+
+ {
+ if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->unaryOpError((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 14:
+
+ {
+ if (context->integerErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode), "[]"))
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 15:
+
+ {
+ TFunction* fnCall = (yyvsp[(1) - (1)].interm).function;
+ TOperator op = fnCall->getBuiltInOp();
+
+ if (op != EOpNull)
+ {
+ //
+ // Then this should be a constructor.
+ // Don't go through the symbol table for constructors.
+ // Their parameters will be verified algorithmically.
+ //
+ TType type(EbtVoid, EbpUndefined); // use this to get the type back
+ if (context->constructorErrorCheck((yyvsp[(1) - (1)].interm).line, (yyvsp[(1) - (1)].interm).intermNode, *fnCall, op, &type)) {
+ (yyval.interm.intermTypedNode) = 0;
+ } else {
+ //
+ // It's a constructor, of type 'type'.
+ //
+ (yyval.interm.intermTypedNode) = context->addConstructor((yyvsp[(1) - (1)].interm).intermNode, &type, op, fnCall, (yyvsp[(1) - (1)].interm).line);
+ }
+
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator(0, op, (yyvsp[(1) - (1)].interm).line);
+ }
+ (yyval.interm.intermTypedNode)->setType(type);
+ } else {
+ //
+ // Not a constructor. Find it in the symbol table.
+ //
+ const TFunction* fnCandidate;
+ bool builtIn;
+ fnCandidate = context->findFunction((yyvsp[(1) - (1)].interm).line, fnCall, &builtIn);
+ if (fnCandidate) {
+ //
+ // A declared function.
+ //
+ if (builtIn && !fnCandidate->getExtension().empty() &&
+ context->extensionErrorCheck((yyvsp[(1) - (1)].interm).line, fnCandidate->getExtension())) {
+ context->recover();
+ }
+ op = fnCandidate->getBuiltInOp();
+ if (builtIn && op != EOpNull) {
+ //
+ // A function call mapped to a built-in operation.
+ //
+ if (fnCandidate->getParamCount() == 1) {
+ //
+ // Treat it like a built-in unary operator.
+ //
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), " wrong operand type", "Internal Error",
+ "built in unary operator function. Type: %s",
+ static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString().c_str());
+ YYERROR;
+ }
+ } else {
+ (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yyvsp[(1) - (1)].interm).line);
+ }
+ } else {
+ // This is a real function call
+
+ (yyval.interm.intermTypedNode) = context->intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yyvsp[(1) - (1)].interm).line);
+ (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
+
+ // this is how we know whether the given function is a builtIn function or a user defined function
+ // if builtIn == false, it's a userDefined -> could be an overloaded builtIn function also
+ // if builtIn == true, it's definitely a builtIn function with EOpNull
+ if (!builtIn)
+ (yyval.interm.intermTypedNode)->getAsAggregate()->setUserDefined();
+ (yyval.interm.intermTypedNode)->getAsAggregate()->setName(fnCandidate->getMangledName());
+
+ TQualifier qual;
+ for (int i = 0; i < fnCandidate->getParamCount(); ++i) {
+ qual = fnCandidate->getParam(i).type->getQualifier();
+ if (qual == EvqOut || qual == EvqInOut) {
+ if (context->lValueErrorCheck((yyval.interm.intermTypedNode)->getLine(), "assign", (yyval.interm.intermTypedNode)->getAsAggregate()->getSequence()[i]->getAsTyped())) {
+ context->error((yyvsp[(1) - (1)].interm).intermNode->getLine(), "Constant value cannot be passed for 'out' or 'inout' parameters.", "Error", "");
+ context->recover();
+ }
+ }
+ }
+ }
+ (yyval.interm.intermTypedNode)->setType(fnCandidate->getReturnType());
+ } else {
+ // error message was put out by PaFindFunction()
+ // Put on a dummy node for error recovery
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setFConst(0.0f);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yyvsp[(1) - (1)].interm).line);
+ context->recover();
+ }
+ }
+ delete fnCall;
+ ;}
+ break;
+
+ case 16:
+
+ {
+ (yyval.interm) = (yyvsp[(1) - (1)].interm);
+ ;}
+ break;
+
+ case 17:
+
+ {
+ context->error((yyvsp[(3) - (3)].interm).line, "methods are not supported", "", "");
+ context->recover();
+ (yyval.interm) = (yyvsp[(3) - (3)].interm);
+ ;}
+ break;
+
+ case 18:
+
+ {
+ (yyval.interm) = (yyvsp[(1) - (2)].interm);
+ (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+ ;}
+ break;
+
+ case 19:
+
+ {
+ (yyval.interm) = (yyvsp[(1) - (2)].interm);
+ (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+ ;}
+ break;
+
+ case 20:
+
+ {
+ (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+ (yyval.interm).intermNode = 0;
+ ;}
+ break;
+
+ case 21:
+
+ {
+ (yyval.interm).function = (yyvsp[(1) - (1)].interm.function);
+ (yyval.interm).intermNode = 0;
+ ;}
+ break;
+
+ case 22:
+
+ {
+ TParameter param = { 0, new TType((yyvsp[(2) - (2)].interm.intermTypedNode)->getType()) };
+ (yyvsp[(1) - (2)].interm.function)->addParameter(param);
+ (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+ (yyval.interm).intermNode = (yyvsp[(2) - (2)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 23:
+
+ {
+ TParameter param = { 0, new TType((yyvsp[(3) - (3)].interm.intermTypedNode)->getType()) };
+ (yyvsp[(1) - (3)].interm).function->addParameter(param);
+ (yyval.interm).function = (yyvsp[(1) - (3)].interm).function;
+ (yyval.interm).intermNode = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+ ;}
+ break;
+
+ case 24:
+
+ {
+ (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+ ;}
+ break;
+
+ case 25:
+
+ {
+ //
+ // Constructor
+ //
+ if ((yyvsp[(1) - (1)].interm.type).array) {
+ // Constructors for arrays are not allowed.
+ context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", "array", "");
+ context->recover();
+ (yyvsp[(1) - (1)].interm.type).setArray(false);
+ }
+
+ TOperator op = EOpNull;
+ if ((yyvsp[(1) - (1)].interm.type).userDef) {
+ op = EOpConstructStruct;
+ } else {
+ switch ((yyvsp[(1) - (1)].interm.type).type) {
+ case EbtFloat:
+ if ((yyvsp[(1) - (1)].interm.type).matrix) {
+ switch((yyvsp[(1) - (1)].interm.type).size) {
+ case 2: op = EOpConstructMat2; break;
+ case 3: op = EOpConstructMat3; break;
+ case 4: op = EOpConstructMat4; break;
+ }
+ } else {
+ switch((yyvsp[(1) - (1)].interm.type).size) {
+ case 1: op = EOpConstructFloat; break;
+ case 2: op = EOpConstructVec2; break;
+ case 3: op = EOpConstructVec3; break;
+ case 4: op = EOpConstructVec4; break;
+ }
+ }
+ break;
+ case EbtInt:
+ switch((yyvsp[(1) - (1)].interm.type).size) {
+ case 1: op = EOpConstructInt; break;
+ case 2: FRAG_VERT_ONLY("ivec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec2; break;
+ case 3: FRAG_VERT_ONLY("ivec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec3; break;
+ case 4: FRAG_VERT_ONLY("ivec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructIVec4; break;
+ }
+ break;
+ case EbtBool:
+ switch((yyvsp[(1) - (1)].interm.type).size) {
+ case 1: op = EOpConstructBool; break;
+ case 2: FRAG_VERT_ONLY("bvec2", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec2; break;
+ case 3: FRAG_VERT_ONLY("bvec3", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec3; break;
+ case 4: FRAG_VERT_ONLY("bvec4", (yyvsp[(1) - (1)].interm.type).line); op = EOpConstructBVec4; break;
+ }
+ break;
+ default: break;
+ }
+ if (op == EOpNull) {
+ context->error((yyvsp[(1) - (1)].interm.type).line, "cannot construct this type", getBasicString((yyvsp[(1) - (1)].interm.type).type), "");
+ context->recover();
+ (yyvsp[(1) - (1)].interm.type).type = EbtFloat;
+ op = EOpConstructFloat;
+ }
+ }
+ TString tempString;
+ TType type((yyvsp[(1) - (1)].interm.type));
+ TFunction *function = new TFunction(&tempString, type, op);
+ (yyval.interm.function) = function;
+ ;}
+ break;
+
+ case 26:
+
+ {
+ if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+ context->recover();
+ TType type(EbtVoid, EbpUndefined);
+ TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
+ (yyval.interm.function) = function;
+ ;}
+ break;
+
+ case 27:
+
+ {
+ if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+ context->recover();
+ TType type(EbtVoid, EbpUndefined);
+ TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
+ (yyval.interm.function) = function;
+ ;}
+ break;
+
+ case 28:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 29:
+
+ {
+ if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->unaryOpError((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 30:
+
+ {
+ if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->unaryOpError((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 31:
+
+ {
+ if ((yyvsp[(1) - (2)].interm).op != EOpNull) {
+ (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].interm).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ const char* errorOp = "";
+ switch((yyvsp[(1) - (2)].interm).op) {
+ case EOpNegative: errorOp = "-"; break;
+ case EOpLogicalNot: errorOp = "!"; break;
+ default: break;
+ }
+ context->unaryOpError((yyvsp[(1) - (2)].interm).line, errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+ }
+ } else
+ (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 32:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNull; ;}
+ break;
+
+ case 33:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpNegative; ;}
+ break;
+
+ case 34:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpLogicalNot; ;}
+ break;
+
+ case 35:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 36:
+
+ {
+ FRAG_VERT_ONLY("*", (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 37:
+
+ {
+ FRAG_VERT_ONLY("/", (yyvsp[(2) - (3)].lex).line);
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 38:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 39:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 40:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 41:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 42:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 43:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 44:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 45:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 46:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 47:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 48:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 49:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 50:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 51:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 52:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 53:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 54:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 55:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 56:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 57:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 58:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ ConstantUnion *unionArray = new ConstantUnion[1];
+ unionArray->setBConst(false);
+ (yyval.interm.intermTypedNode) = context->intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yyvsp[(2) - (3)].lex).line);
+ }
+ ;}
+ break;
+
+ case 59:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 60:
+
+ {
+ if (context->boolErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.intermTypedNode)))
+ context->recover();
+
+ (yyval.interm.intermTypedNode) = context->intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yyvsp[(2) - (5)].lex).line);
+ if ((yyvsp[(3) - (5)].interm.intermTypedNode)->getType() != (yyvsp[(5) - (5)].interm.intermTypedNode)->getType())
+ (yyval.interm.intermTypedNode) = 0;
+
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (5)].lex).line, ":", (yyvsp[(3) - (5)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(5) - (5)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 61:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 62:
+
+ {
+ if (context->lValueErrorCheck((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = context->intermediate.addAssign((yyvsp[(2) - (3)].interm).op, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].interm).line);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->assignError((yyvsp[(2) - (3)].interm).line, "assign", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 63:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAssign; ;}
+ break;
+
+ case 64:
+
+ { FRAG_VERT_ONLY("*=", (yyvsp[(1) - (1)].lex).line); (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpMulAssign; ;}
+ break;
+
+ case 65:
+
+ { FRAG_VERT_ONLY("/=", (yyvsp[(1) - (1)].lex).line); (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpDivAssign; ;}
+ break;
+
+ case 66:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpAddAssign; ;}
+ break;
+
+ case 67:
+
+ { (yyval.interm).line = (yyvsp[(1) - (1)].lex).line; (yyval.interm).op = EOpSubAssign; ;}
+ break;
+
+ case 68:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 69:
+
+ {
+ (yyval.interm.intermTypedNode) = context->intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line);
+ if ((yyval.interm.intermTypedNode) == 0) {
+ context->binaryOpError((yyvsp[(2) - (3)].lex).line, ",", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString());
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(3) - (3)].interm.intermTypedNode);
+ }
+ ;}
+ break;
+
+ case 70:
+
+ {
+ if (context->constErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 71:
+
+ {
+ TFunction &function = *((yyvsp[(1) - (2)].interm).function);
+
+ TIntermAggregate *prototype = new TIntermAggregate;
+ prototype->setType(function.getReturnType());
+ prototype->setName(function.getName());
+
+ for (int i = 0; i < function.getParamCount(); i++)
+ {
+ const TParameter &param = function.getParam(i);
+ if (param.name != 0)
+ {
+ TVariable *variable = new TVariable(param.name, *param.type);
+
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+ }
+ else
+ {
+ prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line);
+ }
+ }
+
+ prototype->setOp(EOpPrototype);
+ (yyval.interm.intermNode) = prototype;
+ ;}
+ break;
+
+ case 72:
+
+ {
+ if ((yyvsp[(1) - (2)].interm).intermAggregate)
+ (yyvsp[(1) - (2)].interm).intermAggregate->setOp(EOpDeclaration);
+ (yyval.interm.intermNode) = (yyvsp[(1) - (2)].interm).intermAggregate;
+ ;}
+ break;
+
+ case 73:
+
+ {
+ context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type).type, (yyvsp[(2) - (4)].interm.precision) );
+ (yyval.interm.intermNode) = 0;
+ ;}
+ break;
+
+ case 74:
+
+ {
+ //
+ // Multiple declarations of the same function are allowed.
+ //
+ // If this is a definition, the definition production code will check for redefinitions
+ // (we don't know at this point if it's a definition or not).
+ //
+ // Redeclarations are allowed. But, return types and parameter qualifiers must match.
+ //
+ TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getMangledName()));
+ if (prevDec) {
+ if (prevDec->getReturnType() != (yyvsp[(1) - (2)].interm.function)->getReturnType()) {
+ context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same return type", (yyvsp[(1) - (2)].interm.function)->getReturnType().getBasicString(), "");
+ context->recover();
+ }
+ for (int i = 0; i < prevDec->getParamCount(); ++i) {
+ if (prevDec->getParam(i).type->getQualifier() != (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifier()) {
+ context->error((yyvsp[(2) - (2)].lex).line, "overloaded functions must have the same parameter qualifiers", (yyvsp[(1) - (2)].interm.function)->getParam(i).type->getQualifierString(), "");
+ context->recover();
+ }
+ }
+ }
+
+ //
+ // If this is a redeclaration, it could also be a definition,
+ // in which case, we want to use the variable names from this one, and not the one that's
+ // being redeclared. So, pass back up this declaration, not the one in the symbol table.
+ //
+ (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+ (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+
+ context->symbolTable.insert(*(yyval.interm).function);
+ ;}
+ break;
+
+ case 75:
+
+ {
+ (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+ ;}
+ break;
+
+ case 76:
+
+ {
+ (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+ ;}
+ break;
+
+ case 77:
+
+ {
+ // Add the parameter
+ (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+ if ((yyvsp[(2) - (2)].interm).param.type->getBasicType() != EbtVoid)
+ (yyvsp[(1) - (2)].interm.function)->addParameter((yyvsp[(2) - (2)].interm).param);
+ else
+ delete (yyvsp[(2) - (2)].interm).param.type;
+ ;}
+ break;
+
+ case 78:
+
+ {
+ //
+ // Only first parameter of one-parameter functions can be void
+ // The check for named parameters not being void is done in parameter_declarator
+ //
+ if ((yyvsp[(3) - (3)].interm).param.type->getBasicType() == EbtVoid) {
+ //
+ // This parameter > first is void
+ //
+ context->error((yyvsp[(2) - (3)].lex).line, "cannot be an argument type except for '(void)'", "void", "");
+ context->recover();
+ delete (yyvsp[(3) - (3)].interm).param.type;
+ } else {
+ // Add the parameter
+ (yyval.interm.function) = (yyvsp[(1) - (3)].interm.function);
+ (yyvsp[(1) - (3)].interm.function)->addParameter((yyvsp[(3) - (3)].interm).param);
+ }
+ ;}
+ break;
+
+ case 79:
+
+ {
+ if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal && (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) {
+ context->error((yyvsp[(2) - (3)].lex).line, "no qualifiers allowed for function return", getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier), "");
+ context->recover();
+ }
+ // make sure a sampler is not involved as well...
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (3)].lex).line, (yyvsp[(1) - (3)].interm.type)))
+ context->recover();
+
+ // Add the function as a prototype after parsing it (we do not support recursion)
+ TFunction *function;
+ TType type((yyvsp[(1) - (3)].interm.type));
+ function = new TFunction((yyvsp[(2) - (3)].lex).string, type);
+ (yyval.interm.function) = function;
+ ;}
+ break;
+
+ case 80:
+
+ {
+ if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) {
+ context->error((yyvsp[(2) - (2)].lex).line, "illegal use of type 'void'", (yyvsp[(2) - (2)].lex).string->c_str(), "");
+ context->recover();
+ }
+ if (context->reservedErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string))
+ context->recover();
+ TParameter param = {(yyvsp[(2) - (2)].lex).string, new TType((yyvsp[(1) - (2)].interm.type))};
+ (yyval.interm).line = (yyvsp[(2) - (2)].lex).line;
+ (yyval.interm).param = param;
+ ;}
+ break;
+
+ case 81:
+
+ {
+ // Check that we can make an array out of this type
+ if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+ context->recover();
+
+ if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
+ context->recover();
+
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+ context->recover();
+ (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+
+ TType* type = new TType((yyvsp[(1) - (5)].interm.type));
+ TParameter param = { (yyvsp[(2) - (5)].lex).string, type };
+ (yyval.interm).line = (yyvsp[(2) - (5)].lex).line;
+ (yyval.interm).param = param;
+ ;}
+ break;
+
+ case 82:
+
+ {
+ (yyval.interm) = (yyvsp[(3) - (3)].interm);
+ if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+ context->recover();
+ ;}
+ break;
+
+ case 83:
+
+ {
+ (yyval.interm) = (yyvsp[(2) - (2)].interm);
+ if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+ context->recover();
+ if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+ context->recover();
+ ;}
+ break;
+
+ case 84:
+
+ {
+ (yyval.interm) = (yyvsp[(3) - (3)].interm);
+ if (context->paramErrorCheck((yyvsp[(3) - (3)].interm).line, (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+ context->recover();
+ ;}
+ break;
+
+ case 85:
+
+ {
+ (yyval.interm) = (yyvsp[(2) - (2)].interm);
+ if (context->parameterSamplerErrorCheck((yyvsp[(2) - (2)].interm).line, (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+ context->recover();
+ if (context->paramErrorCheck((yyvsp[(2) - (2)].interm).line, EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+ context->recover();
+ ;}
+ break;
+
+ case 86:
+
+ {
+ (yyval.interm.qualifier) = EvqIn;
+ ;}
+ break;
+
+ case 87:
+
+ {
+ (yyval.interm.qualifier) = EvqIn;
+ ;}
+ break;
+
+ case 88:
+
+ {
+ (yyval.interm.qualifier) = EvqOut;
+ ;}
+ break;
+
+ case 89:
+
+ {
+ (yyval.interm.qualifier) = EvqInOut;
+ ;}
+ break;
+
+ case 90:
+
+ {
+ TParameter param = { 0, new TType((yyvsp[(1) - (1)].interm.type)) };
+ (yyval.interm).param = param;
+ ;}
+ break;
+
+ case 91:
+
+ {
+ (yyval.interm) = (yyvsp[(1) - (1)].interm);
+
+ if ((yyval.interm).type.precision == EbpUndefined) {
+ (yyval.interm).type.precision = context->symbolTable.getDefaultPrecision((yyvsp[(1) - (1)].interm).type.type);
+ if (context->precisionErrorCheck((yyvsp[(1) - (1)].interm).line, (yyval.interm).type.precision, (yyvsp[(1) - (1)].interm).type.type)) {
+ context->recover();
+ }
+ }
+ ;}
+ break;
+
+ case 92:
+
+ {
+ (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line), (yyvsp[(3) - (3)].lex).line);
+
+ if (context->structQualifierErrorCheck((yyvsp[(3) - (3)].lex).line, (yyval.interm).type))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
+ context->recover();
+
+ if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type))
+ context->recover();
+ ;}
+ break;
+
+ case 93:
+
+ {
+ if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type))
+ context->recover();
+
+ (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+ if (context->arrayTypeErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+ context->recover();
+ else {
+ (yyvsp[(1) - (5)].interm).type.setArray(true);
+ TVariable* variable;
+ if (context->arrayErrorCheck((yyvsp[(4) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable))
+ context->recover();
+ }
+ ;}
+ break;
+
+ case 94:
+
+ {
+ if (context->structQualifierErrorCheck((yyvsp[(3) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(3) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type))
+ context->recover();
+
+ (yyval.interm) = (yyvsp[(1) - (6)].interm);
+
+ if (context->arrayTypeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type) || context->arrayQualifierErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(1) - (6)].interm).type))
+ context->recover();
+ else {
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(4) - (6)].lex).line, (yyvsp[(5) - (6)].interm.intermTypedNode), size))
+ context->recover();
+ (yyvsp[(1) - (6)].interm).type.setArray(true, size);
+ TVariable* variable;
+ if (context->arrayErrorCheck((yyvsp[(4) - (6)].lex).line, *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
+ context->recover();
+ TType type = TType((yyvsp[(1) - (6)].interm).type);
+ type.setArraySize(size);
+ (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line);
+ }
+ ;}
+ break;
+
+ case 95:
+
+ {
+ if (context->structQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm).type))
+ context->recover();
+
+ (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+ TIntermNode* intermNode;
+ if (!context->executeInitializer((yyvsp[(3) - (5)].lex).line, *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) {
+ //
+ // build the intermediate representation
+ //
+ if (intermNode)
+ (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yyvsp[(4) - (5)].lex).line);
+ else
+ (yyval.interm).intermAggregate = (yyvsp[(1) - (5)].interm).intermAggregate;
+ } else {
+ context->recover();
+ (yyval.interm).intermAggregate = 0;
+ }
+ ;}
+ break;
+
+ case 96:
+
+ {
+ (yyval.interm).type = (yyvsp[(1) - (1)].interm.type);
+ (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType((yyvsp[(1) - (1)].interm.type)), (yyvsp[(1) - (1)].interm.type).line), (yyvsp[(1) - (1)].interm.type).line);
+ ;}
+ break;
+
+ case 97:
+
+ {
+ (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line), (yyvsp[(2) - (2)].lex).line);
+
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (2)].lex).line, (yyval.interm).type))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
+ context->recover();
+
+ (yyval.interm).type = (yyvsp[(1) - (2)].interm.type);
+
+ if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type))
+ context->recover();
+ ;}
+ break;
+
+ case 98:
+
+ {
+ (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line), (yyvsp[(2) - (4)].lex).line);
+
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+
+ (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+
+ if (context->arrayTypeErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+ else {
+ (yyvsp[(1) - (4)].interm.type).setArray(true);
+ TVariable* variable;
+ if (context->arrayErrorCheck((yyvsp[(3) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), variable))
+ context->recover();
+ }
+ ;}
+ break;
+
+ case 99:
+
+ {
+ TType type = TType((yyvsp[(1) - (5)].interm.type));
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+ context->recover();
+ type.setArraySize(size);
+ (yyval.interm).intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line), (yyvsp[(2) - (5)].lex).line);
+
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+ context->recover();
+
+ if (context->nonInitConstErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type)))
+ context->recover();
+
+ (yyval.interm).type = (yyvsp[(1) - (5)].interm.type);
+
+ if (context->arrayTypeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)) || context->arrayQualifierErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type)))
+ context->recover();
+ else {
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(3) - (5)].lex).line, (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+ context->recover();
+
+ (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+ TVariable* variable;
+ if (context->arrayErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
+ context->recover();
+ }
+ ;}
+ break;
+
+ case 100:
+
+ {
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+
+ (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+
+ TIntermNode* intermNode;
+ if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) {
+ //
+ // Build intermediate representation
+ //
+ if(intermNode)
+ (yyval.interm).intermAggregate = context->intermediate.makeAggregate(intermNode, (yyvsp[(3) - (4)].lex).line);
+ else
+ (yyval.interm).intermAggregate = 0;
+ } else {
+ context->recover();
+ (yyval.interm).intermAggregate = 0;
+ }
+ ;}
+ break;
+
+ case 101:
+
+ {
+ VERTEX_ONLY("invariant declaration", (yyvsp[(1) - (2)].lex).line);
+ (yyval.interm).qualifier = EvqInvariantVaryingOut;
+ (yyval.interm).intermAggregate = 0;
+ ;}
+ break;
+
+ case 102:
+
+ {
+ (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+
+ if ((yyvsp[(1) - (1)].interm.type).array) {
+ context->error((yyvsp[(1) - (1)].interm.type).line, "not supported", "first-class array", "");
+ context->recover();
+ (yyvsp[(1) - (1)].interm.type).setArray(false);
+ }
+ ;}
+ break;
+
+ case 103:
+
+ {
+ if ((yyvsp[(2) - (2)].interm.type).array) {
+ context->error((yyvsp[(2) - (2)].interm.type).line, "not supported", "first-class array", "");
+ context->recover();
+ (yyvsp[(2) - (2)].interm.type).setArray(false);
+ }
+
+ if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute &&
+ ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+ context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), "");
+ context->recover();
+ }
+ if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) &&
+ ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+ context->error((yyvsp[(2) - (2)].interm.type).line, "cannot be bool or int", getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier), "");
+ context->recover();
+ }
+ (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+ (yyval.interm.type).qualifier = (yyvsp[(1) - (2)].interm.type).qualifier;
+ ;}
+ break;
+
+ case 104:
+
+ {
+ (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 105:
+
+ {
+ VERTEX_ONLY("attribute", (yyvsp[(1) - (1)].lex).line);
+ if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "attribute"))
+ context->recover();
+ (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 106:
+
+ {
+ if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "varying"))
+ context->recover();
+ if (context->shaderType == SH_VERTEX_SHADER)
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yyvsp[(1) - (1)].lex).line);
+ else
+ (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 107:
+
+ {
+ if (context->globalErrorCheck((yyvsp[(1) - (2)].lex).line, context->symbolTable.atGlobalLevel(), "invariant varying"))
+ context->recover();
+ if (context->shaderType == SH_VERTEX_SHADER)
+ (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yyvsp[(1) - (2)].lex).line);
+ else
+ (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yyvsp[(1) - (2)].lex).line);
+ ;}
+ break;
+
+ case 108:
+
+ {
+ if (context->globalErrorCheck((yyvsp[(1) - (1)].lex).line, context->symbolTable.atGlobalLevel(), "uniform"))
+ context->recover();
+ (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 109:
+
+ {
+ (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+ ;}
+ break;
+
+ case 110:
+
+ {
+ (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+ (yyval.interm.type).precision = (yyvsp[(1) - (2)].interm.precision);
+ ;}
+ break;
+
+ case 111:
+
+ {
+ (yyval.interm.precision) = EbpHigh;
+ ;}
+ break;
+
+ case 112:
+
+ {
+ (yyval.interm.precision) = EbpMedium;
+ ;}
+ break;
+
+ case 113:
+
+ {
+ (yyval.interm.precision) = EbpLow;
+ ;}
+ break;
+
+ case 114:
+
+ {
+ (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+ ;}
+ break;
+
+ case 115:
+
+ {
+ (yyval.interm.type) = (yyvsp[(1) - (4)].interm.type);
+
+ if (context->arrayTypeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+ else {
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+ context->recover();
+ (yyval.interm.type).setArray(true, size);
+ }
+ ;}
+ break;
+
+ case 116:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtVoid, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 117:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 118:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 119:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 120:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(2);
+ ;}
+ break;
+
+ case 121:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(3);
+ ;}
+ break;
+
+ case 122:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(4);
+ ;}
+ break;
+
+ case 123:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(2);
+ ;}
+ break;
+
+ case 124:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(3);
+ ;}
+ break;
+
+ case 125:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtBool, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(4);
+ ;}
+ break;
+
+ case 126:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(2);
+ ;}
+ break;
+
+ case 127:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(3);
+ ;}
+ break;
+
+ case 128:
+
+ {
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtInt, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(4);
+ ;}
+ break;
+
+ case 129:
+
+ {
+ FRAG_VERT_ONLY("mat2", (yyvsp[(1) - (1)].lex).line);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(2, true);
+ ;}
+ break;
+
+ case 130:
+
+ {
+ FRAG_VERT_ONLY("mat3", (yyvsp[(1) - (1)].lex).line);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(3, true);
+ ;}
+ break;
+
+ case 131:
+
+ {
+ FRAG_VERT_ONLY("mat4", (yyvsp[(1) - (1)].lex).line);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtFloat, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).setAggregate(4, true);
+ ;}
+ break;
+
+ case 132:
+
+ {
+ FRAG_VERT_ONLY("sampler2D", (yyvsp[(1) - (1)].lex).line);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSampler2D, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 133:
+
+ {
+ FRAG_VERT_ONLY("samplerCube", (yyvsp[(1) - (1)].lex).line);
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yyvsp[(1) - (1)].lex).line);
+ ;}
+ break;
+
+ case 134:
+
+ {
+ FRAG_VERT_ONLY("struct", (yyvsp[(1) - (1)].interm.type).line);
+ (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+ (yyval.interm.type).qualifier = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ ;}
+ break;
+
+ case 135:
+
+ {
+ //
+ // This is for user defined type names. The lexical phase looked up the
+ // type.
+ //
+ TType& structure = static_cast<TVariable*>((yyvsp[(1) - (1)].lex).symbol)->getType();
+ TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+ (yyval.interm.type).setBasic(EbtStruct, qual, (yyvsp[(1) - (1)].lex).line);
+ (yyval.interm.type).userDef = &structure;
+ ;}
+ break;
+
+ case 136:
+
+ {
+ if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string))
+ context->recover();
+
+ TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), *(yyvsp[(2) - (5)].lex).string);
+ TVariable* userTypeDef = new TVariable((yyvsp[(2) - (5)].lex).string, *structure, true);
+ if (! context->symbolTable.insert(*userTypeDef)) {
+ context->error((yyvsp[(2) - (5)].lex).line, "redefinition", (yyvsp[(2) - (5)].lex).string->c_str(), "struct");
+ context->recover();
+ }
+ (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line);
+ (yyval.interm.type).userDef = structure;
+ ;}
+ break;
+
+ case 137:
+
+ {
+ TType* structure = new TType((yyvsp[(3) - (4)].interm.typeList), TString(""));
+ (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (4)].lex).line);
+ (yyval.interm.type).userDef = structure;
+ ;}
+ break;
+
+ case 138:
+
+ {
+ (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList);
+ ;}
+ break;
+
+ case 139:
+
+ {
+ (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList);
+ for (unsigned int i = 0; i < (yyvsp[(2) - (2)].interm.typeList)->size(); ++i) {
+ for (unsigned int j = 0; j < (yyval.interm.typeList)->size(); ++j) {
+ if ((*(yyval.interm.typeList))[j].type->getFieldName() == (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName()) {
+ context->error((*(yyvsp[(2) - (2)].interm.typeList))[i].line, "duplicate field name in structure:", "struct", (*(yyvsp[(2) - (2)].interm.typeList))[i].type->getFieldName().c_str());
+ context->recover();
+ }
+ }
+ (yyval.interm.typeList)->push_back((*(yyvsp[(2) - (2)].interm.typeList))[i]);
+ }
+ ;}
+ break;
+
+ case 140:
+
+ {
+ (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList);
+
+ if (context->voidErrorCheck((yyvsp[(1) - (3)].interm.type).line, (*(yyvsp[(2) - (3)].interm.typeList))[0].type->getFieldName(), (yyvsp[(1) - (3)].interm.type))) {
+ context->recover();
+ }
+ for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) {
+ //
+ // Careful not to replace already known aspects of type, like array-ness
+ //
+ TType* type = (*(yyval.interm.typeList))[i].type;
+ type->setBasicType((yyvsp[(1) - (3)].interm.type).type);
+ type->setNominalSize((yyvsp[(1) - (3)].interm.type).size);
+ type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix);
+
+ // don't allow arrays of arrays
+ if (type->isArray()) {
+ if (context->arrayTypeErrorCheck((yyvsp[(1) - (3)].interm.type).line, (yyvsp[(1) - (3)].interm.type)))
+ context->recover();
+ }
+ if ((yyvsp[(1) - (3)].interm.type).array)
+ type->setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
+ if ((yyvsp[(1) - (3)].interm.type).userDef) {
+ type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct());
+ type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName());
+ }
+ }
+ ;}
+ break;
+
+ case 141:
+
+ {
+ (yyval.interm.typeList) = NewPoolTTypeList();
+ (yyval.interm.typeList)->push_back((yyvsp[(1) - (1)].interm.typeLine));
+ ;}
+ break;
+
+ case 142:
+
+ {
+ (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine));
+ ;}
+ break;
+
+ case 143:
+
+ {
+ if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string))
+ context->recover();
+
+ (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
+ (yyval.interm.typeLine).line = (yyvsp[(1) - (1)].lex).line;
+ (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (1)].lex).string);
+ ;}
+ break;
+
+ case 144:
+
+ {
+ if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string))
+ context->recover();
+
+ (yyval.interm.typeLine).type = new TType(EbtVoid, EbpUndefined);
+ (yyval.interm.typeLine).line = (yyvsp[(1) - (4)].lex).line;
+ (yyval.interm.typeLine).type->setFieldName(*(yyvsp[(1) - (4)].lex).string);
+
+ int size;
+ if (context->arraySizeErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+ context->recover();
+ (yyval.interm.typeLine).type->setArraySize(size);
+ ;}
+ break;
+
+ case 145:
+
+ { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;}
+ break;
+
+ case 146:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 147:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); ;}
+ break;
+
+ case 148:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 149:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 150:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 151:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 152:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 153:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 154:
+
+ { (yyval.interm.intermAggregate) = 0; ;}
+ break;
+
+ case 155:
+
+ { context->symbolTable.push(); ;}
+ break;
+
+ case 156:
+
+ { context->symbolTable.pop(); ;}
+ break;
+
+ case 157:
+
+ {
+ if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0)
+ (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence);
+ (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
+ ;}
+ break;
+
+ case 158:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 159:
+
+ { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;}
+ break;
+
+ case 160:
+
+ {
+ (yyval.interm.intermNode) = 0;
+ ;}
+ break;
+
+ case 161:
+
+ {
+ if ((yyvsp[(2) - (3)].interm.intermAggregate))
+ (yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence);
+ (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
+ ;}
+ break;
+
+ case 162:
+
+ {
+ (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0);
+ ;}
+ break;
+
+ case 163:
+
+ {
+ (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0);
+ ;}
+ break;
+
+ case 164:
+
+ { (yyval.interm.intermNode) = 0; ;}
+ break;
+
+ case 165:
+
+ { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); ;}
+ break;
+
+ case 166:
+
+ {
+ if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode)))
+ context->recover();
+ (yyval.interm.intermNode) = context->intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yyvsp[(1) - (5)].lex).line);
+ ;}
+ break;
+
+ case 167:
+
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermNode);
+ ;}
+ break;
+
+ case 168:
+
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode);
+ (yyval.interm.nodePair).node2 = 0;
+ ;}
+ break;
+
+ case 169:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ if (context->boolErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)->getLine(), (yyvsp[(1) - (1)].interm.intermTypedNode)))
+ context->recover();
+ ;}
+ break;
+
+ case 170:
+
+ {
+ TIntermNode* intermNode;
+ if (context->structQualifierErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+ if (context->boolErrorCheck((yyvsp[(2) - (4)].lex).line, (yyvsp[(1) - (4)].interm.type)))
+ context->recover();
+
+ if (!context->executeInitializer((yyvsp[(2) - (4)].lex).line, *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode))
+ (yyval.interm.intermTypedNode) = (yyvsp[(4) - (4)].interm.intermTypedNode);
+ else {
+ context->recover();
+ (yyval.interm.intermTypedNode) = 0;
+ }
+ ;}
+ break;
+
+ case 171:
+
+ { context->symbolTable.push(); ++context->loopNestingLevel; ;}
+ break;
+
+ case 172:
+
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(1) - (6)].lex).line);
+ --context->loopNestingLevel;
+ ;}
+ break;
+
+ case 173:
+
+ { ++context->loopNestingLevel; ;}
+ break;
+
+ case 174:
+
+ {
+ if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
+ context->recover();
+
+ (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(4) - (8)].lex).line);
+ --context->loopNestingLevel;
+ ;}
+ break;
+
+ case 175:
+
+ { context->symbolTable.push(); ++context->loopNestingLevel; ;}
+ break;
+
+ case 176:
+
+ {
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
+ --context->loopNestingLevel;
+ ;}
+ break;
+
+ case 177:
+
+ {
+ (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+ ;}
+ break;
+
+ case 178:
+
+ {
+ (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+ ;}
+ break;
+
+ case 179:
+
+ {
+ (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 180:
+
+ {
+ (yyval.interm.intermTypedNode) = 0;
+ ;}
+ break;
+
+ case 181:
+
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode);
+ (yyval.interm.nodePair).node2 = 0;
+ ;}
+ break;
+
+ case 182:
+
+ {
+ (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode);
+ (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermTypedNode);
+ ;}
+ break;
+
+ case 183:
+
+ {
+ if (context->loopNestingLevel <= 0) {
+ context->error((yyvsp[(1) - (2)].lex).line, "continue statement only allowed in loops", "", "");
+ context->recover();
+ }
+ (yyval.interm.intermNode) = context->intermediate.addBranch(EOpContinue, (yyvsp[(1) - (2)].lex).line);
+ ;}
+ break;
+
+ case 184:
+
+ {
+ if (context->loopNestingLevel <= 0) {
+ context->error((yyvsp[(1) - (2)].lex).line, "break statement only allowed in loops", "", "");
+ context->recover();
+ }
+ (yyval.interm.intermNode) = context->intermediate.addBranch(EOpBreak, (yyvsp[(1) - (2)].lex).line);
+ ;}
+ break;
+
+ case 185:
+
+ {
+ (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line);
+ if (context->currentFunctionType->getBasicType() != EbtVoid) {
+ context->error((yyvsp[(1) - (2)].lex).line, "non-void function must return a value", "return", "");
+ context->recover();
+ }
+ ;}
+ break;
+
+ case 186:
+
+ {
+ (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line);
+ context->functionReturnsValue = true;
+ if (context->currentFunctionType->getBasicType() == EbtVoid) {
+ context->error((yyvsp[(1) - (3)].lex).line, "void function cannot return a value", "return", "");
+ context->recover();
+ } else if (*(context->currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)->getType()) {
+ context->error((yyvsp[(1) - (3)].lex).line, "function return is not matching type:", "return", "");
+ context->recover();
+ }
+ ;}
+ break;
+
+ case 187:
+
+ {
+ FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line);
+ (yyval.interm.intermNode) = context->intermediate.addBranch(EOpKill, (yyvsp[(1) - (2)].lex).line);
+ ;}
+ break;
+
+ case 188:
+
+ {
+ (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+ context->treeRoot = (yyval.interm.intermNode);
+ ;}
+ break;
+
+ case 189:
+
+ {
+ (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0);
+ context->treeRoot = (yyval.interm.intermNode);
+ ;}
+ break;
+
+ case 190:
+
+ {
+ (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+ ;}
+ break;
+
+ case 191:
+
+ {
+ (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+ ;}
+ break;
+
+ case 192:
+
+ {
+ TFunction* function = (yyvsp[(1) - (1)].interm).function;
+ TFunction* prevDec = static_cast<TFunction*>(context->symbolTable.find(function->getMangledName()));
+ //
+ // Note: 'prevDec' could be 'function' if this is the first time we've seen function
+ // as it would have just been put in the symbol table. Otherwise, we're looking up
+ // an earlier occurance.
+ //
+ if (prevDec->isDefined()) {
+ //
+ // Then this function already has a body.
+ //
+ context->error((yyvsp[(1) - (1)].interm).line, "function already has a body", function->getName().c_str(), "");
+ context->recover();
+ }
+ prevDec->setDefined();
+
+ //
+ // Raise error message if main function takes any parameters or return anything other than void
+ //
+ if (function->getName() == "main") {
+ if (function->getParamCount() > 0) {
+ context->error((yyvsp[(1) - (1)].interm).line, "function cannot take any parameter(s)", function->getName().c_str(), "");
+ context->recover();
+ }
+ if (function->getReturnType().getBasicType() != EbtVoid) {
+ context->error((yyvsp[(1) - (1)].interm).line, "", function->getReturnType().getBasicString(), "main function cannot return a value");
+ context->recover();
+ }
+ }
+
+ //
+ // New symbol table scope for body of function plus its arguments
+ //
+ context->symbolTable.push();
+
+ //
+ // Remember the return type for later checking for RETURN statements.
+ //
+ context->currentFunctionType = &(prevDec->getReturnType());
+ context->functionReturnsValue = false;
+
+ //
+ // Insert parameters into the symbol table.
+ // If the parameter has no name, it's not an error, just don't insert it
+ // (could be used for unused args).
+ //
+ // Also, accumulate the list of parameters into the HIL, so lower level code
+ // knows where to find parameters.
+ //
+ TIntermAggregate* paramNodes = new TIntermAggregate;
+ for (int i = 0; i < function->getParamCount(); i++) {
+ const TParameter& param = function->getParam(i);
+ if (param.name != 0) {
+ TVariable *variable = new TVariable(param.name, *param.type);
+ //
+ // Insert the parameters with name in the symbol table.
+ //
+ if (! context->symbolTable.insert(*variable)) {
+ context->error((yyvsp[(1) - (1)].interm).line, "redefinition", variable->getName().c_str(), "");
+ context->recover();
+ delete variable;
+ }
+
+ //
+ // Add the parameter to the HIL
+ //
+ paramNodes = context->intermediate.growAggregate(
+ paramNodes,
+ context->intermediate.addSymbol(variable->getUniqueId(),
+ variable->getName(),
+ variable->getType(), (yyvsp[(1) - (1)].interm).line),
+ (yyvsp[(1) - (1)].interm).line);
+ } else {
+ paramNodes = context->intermediate.growAggregate(paramNodes, context->intermediate.addSymbol(0, "", *param.type, (yyvsp[(1) - (1)].interm).line), (yyvsp[(1) - (1)].interm).line);
+ }
+ }
+ context->intermediate.setAggregateOperator(paramNodes, EOpParameters, (yyvsp[(1) - (1)].interm).line);
+ (yyvsp[(1) - (1)].interm).intermAggregate = paramNodes;
+ context->loopNestingLevel = 0;
+ ;}
+ break;
+
+ case 193:
+
+ {
+ //?? Check that all paths return a value if return type != void ?
+ // May be best done as post process phase on intermediate code
+ if (context->currentFunctionType->getBasicType() != EbtVoid && ! context->functionReturnsValue) {
+ context->error((yyvsp[(1) - (3)].interm).line, "function does not return a value:", "", (yyvsp[(1) - (3)].interm).function->getName().c_str());
+ context->recover();
+ }
+ context->symbolTable.pop();
+ (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), 0);
+ context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yyvsp[(1) - (3)].interm).line);
+ (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[(1) - (3)].interm).function->getMangledName().c_str());
+ (yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[(1) - (3)].interm).function->getReturnType());
+
+ // store the pragma information for debug and optimize and other vendor specific
+ // information. This information can be queried from the parse tree
+ (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize);
+ (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug);
+ (yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable);
+ ;}
+ break;
+
+
+/* Line 1267 of yacc.c. */
+
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (context, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (context, yymsg);
+ }
+ else
+ {
+ yyerror (context, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse look-ahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, context);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse look-ahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, context);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ if (yyn == YYFINAL)
+ YYACCEPT;
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (context, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, context);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, context);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+
+
+int glslang_parse(TParseContext* context) {
+ return yyparse(context);
+}
+
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h
new file mode 100644
index 0000000..05cbfd4
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h
@@ -0,0 +1,274 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ INVARIANT = 258,
+ HIGH_PRECISION = 259,
+ MEDIUM_PRECISION = 260,
+ LOW_PRECISION = 261,
+ PRECISION = 262,
+ ATTRIBUTE = 263,
+ CONST_QUAL = 264,
+ BOOL_TYPE = 265,
+ FLOAT_TYPE = 266,
+ INT_TYPE = 267,
+ BREAK = 268,
+ CONTINUE = 269,
+ DO = 270,
+ ELSE = 271,
+ FOR = 272,
+ IF = 273,
+ DISCARD = 274,
+ RETURN = 275,
+ BVEC2 = 276,
+ BVEC3 = 277,
+ BVEC4 = 278,
+ IVEC2 = 279,
+ IVEC3 = 280,
+ IVEC4 = 281,
+ VEC2 = 282,
+ VEC3 = 283,
+ VEC4 = 284,
+ MATRIX2 = 285,
+ MATRIX3 = 286,
+ MATRIX4 = 287,
+ IN_QUAL = 288,
+ OUT_QUAL = 289,
+ INOUT_QUAL = 290,
+ UNIFORM = 291,
+ VARYING = 292,
+ STRUCT = 293,
+ VOID_TYPE = 294,
+ WHILE = 295,
+ SAMPLER2D = 296,
+ SAMPLERCUBE = 297,
+ IDENTIFIER = 298,
+ TYPE_NAME = 299,
+ FLOATCONSTANT = 300,
+ INTCONSTANT = 301,
+ BOOLCONSTANT = 302,
+ FIELD_SELECTION = 303,
+ LEFT_OP = 304,
+ RIGHT_OP = 305,
+ INC_OP = 306,
+ DEC_OP = 307,
+ LE_OP = 308,
+ GE_OP = 309,
+ EQ_OP = 310,
+ NE_OP = 311,
+ AND_OP = 312,
+ OR_OP = 313,
+ XOR_OP = 314,
+ MUL_ASSIGN = 315,
+ DIV_ASSIGN = 316,
+ ADD_ASSIGN = 317,
+ MOD_ASSIGN = 318,
+ LEFT_ASSIGN = 319,
+ RIGHT_ASSIGN = 320,
+ AND_ASSIGN = 321,
+ XOR_ASSIGN = 322,
+ OR_ASSIGN = 323,
+ SUB_ASSIGN = 324,
+ LEFT_PAREN = 325,
+ RIGHT_PAREN = 326,
+ LEFT_BRACKET = 327,
+ RIGHT_BRACKET = 328,
+ LEFT_BRACE = 329,
+ RIGHT_BRACE = 330,
+ DOT = 331,
+ COMMA = 332,
+ COLON = 333,
+ EQUAL = 334,
+ SEMICOLON = 335,
+ BANG = 336,
+ DASH = 337,
+ TILDE = 338,
+ PLUS = 339,
+ STAR = 340,
+ SLASH = 341,
+ PERCENT = 342,
+ LEFT_ANGLE = 343,
+ RIGHT_ANGLE = 344,
+ VERTICAL_BAR = 345,
+ CARET = 346,
+ AMPERSAND = 347,
+ QUESTION = 348
+ };
+#endif
+/* Tokens. */
+#define INVARIANT 258
+#define HIGH_PRECISION 259
+#define MEDIUM_PRECISION 260
+#define LOW_PRECISION 261
+#define PRECISION 262
+#define ATTRIBUTE 263
+#define CONST_QUAL 264
+#define BOOL_TYPE 265
+#define FLOAT_TYPE 266
+#define INT_TYPE 267
+#define BREAK 268
+#define CONTINUE 269
+#define DO 270
+#define ELSE 271
+#define FOR 272
+#define IF 273
+#define DISCARD 274
+#define RETURN 275
+#define BVEC2 276
+#define BVEC3 277
+#define BVEC4 278
+#define IVEC2 279
+#define IVEC3 280
+#define IVEC4 281
+#define VEC2 282
+#define VEC3 283
+#define VEC4 284
+#define MATRIX2 285
+#define MATRIX3 286
+#define MATRIX4 287
+#define IN_QUAL 288
+#define OUT_QUAL 289
+#define INOUT_QUAL 290
+#define UNIFORM 291
+#define VARYING 292
+#define STRUCT 293
+#define VOID_TYPE 294
+#define WHILE 295
+#define SAMPLER2D 296
+#define SAMPLERCUBE 297
+#define IDENTIFIER 298
+#define TYPE_NAME 299
+#define FLOATCONSTANT 300
+#define INTCONSTANT 301
+#define BOOLCONSTANT 302
+#define FIELD_SELECTION 303
+#define LEFT_OP 304
+#define RIGHT_OP 305
+#define INC_OP 306
+#define DEC_OP 307
+#define LE_OP 308
+#define GE_OP 309
+#define EQ_OP 310
+#define NE_OP 311
+#define AND_OP 312
+#define OR_OP 313
+#define XOR_OP 314
+#define MUL_ASSIGN 315
+#define DIV_ASSIGN 316
+#define ADD_ASSIGN 317
+#define MOD_ASSIGN 318
+#define LEFT_ASSIGN 319
+#define RIGHT_ASSIGN 320
+#define AND_ASSIGN 321
+#define XOR_ASSIGN 322
+#define OR_ASSIGN 323
+#define SUB_ASSIGN 324
+#define LEFT_PAREN 325
+#define RIGHT_PAREN 326
+#define LEFT_BRACKET 327
+#define RIGHT_BRACKET 328
+#define LEFT_BRACE 329
+#define RIGHT_BRACE 330
+#define DOT 331
+#define COMMA 332
+#define COLON 333
+#define EQUAL 334
+#define SEMICOLON 335
+#define BANG 336
+#define DASH 337
+#define TILDE 338
+#define PLUS 339
+#define STAR 340
+#define SLASH 341
+#define PERCENT 342
+#define LEFT_ANGLE 343
+#define RIGHT_ANGLE 344
+#define VERTICAL_BAR 345
+#define CARET 346
+#define AMPERSAND 347
+#define QUESTION 348
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+
+{
+ struct {
+ TSourceLoc line;
+ union {
+ TString *string;
+ float f;
+ int i;
+ bool b;
+ };
+ TSymbol* symbol;
+ } lex;
+ struct {
+ TSourceLoc line;
+ TOperator op;
+ union {
+ TIntermNode* intermNode;
+ TIntermNodePair nodePair;
+ TIntermTyped* intermTypedNode;
+ TIntermAggregate* intermAggregate;
+ };
+ union {
+ TPublicType type;
+ TPrecision precision;
+ TQualifier qualifier;
+ TFunction* function;
+ TParameter param;
+ TTypeLine typeLine;
+ TTypeList* typeList;
+ };
+ } interm;
+}
+/* Line 1489 of yacc.c. */
+
+ YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
index db042dd..798a69a 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp
@@ -21,8 +21,8 @@
//
class TOutputTraverser : public TIntermTraverser {
public:
- TOutputTraverser(TInfoSink& i) : infoSink(i) { }
- TInfoSink& infoSink;
+ TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
+ TInfoSinkBase& sink;
protected:
void visitSymbol(TIntermSymbol*);
@@ -56,14 +56,14 @@ TString TType::getCompleteString() const
// Helper functions for printing, not part of traversing.
//
-void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
+void OutputTreeText(TInfoSinkBase& sink, TIntermNode* node, const int depth)
{
int i;
- infoSink.debug.location(node->getLine());
+ sink.location(node->getLine());
for (i = 0; i < depth; ++i)
- infoSink.debug << " ";
+ sink << " ";
}
//
@@ -77,226 +77,226 @@ void OutputTreeText(TInfoSink& infoSink, TIntermNode* node, const int depth)
void TOutputTraverser::visitSymbol(TIntermSymbol* node)
{
- OutputTreeText(infoSink, node, depth);
+ OutputTreeText(sink, node, depth);
- infoSink.debug << "'" << node->getSymbol() << "' ";
- infoSink.debug << "(" << node->getCompleteString() << ")\n";
+ sink << "'" << node->getSymbol() << "' ";
+ sink << "(" << node->getCompleteString() << ")\n";
}
bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
OutputTreeText(out, node, depth);
switch (node->getOp()) {
- case EOpAssign: out.debug << "move second child to first child"; break;
- case EOpInitialize: out.debug << "initialize first child with second child"; break;
- case EOpAddAssign: out.debug << "add second child into first child"; break;
- case EOpSubAssign: out.debug << "subtract second child into first child"; break;
- case EOpMulAssign: out.debug << "multiply second child into first child"; break;
- case EOpVectorTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
- case EOpVectorTimesScalarAssign: out.debug << "vector scale second child into first child"; break;
- case EOpMatrixTimesScalarAssign: out.debug << "matrix scale second child into first child"; break;
- case EOpMatrixTimesMatrixAssign: out.debug << "matrix mult second child into first child"; break;
- case EOpDivAssign: out.debug << "divide second child into first child"; break;
- case EOpIndexDirect: out.debug << "direct index"; break;
- case EOpIndexIndirect: out.debug << "indirect index"; break;
- case EOpIndexDirectStruct: out.debug << "direct index for structure"; break;
- case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
-
- case EOpAdd: out.debug << "add"; break;
- case EOpSub: out.debug << "subtract"; break;
- case EOpMul: out.debug << "component-wise multiply"; break;
- case EOpDiv: out.debug << "divide"; break;
- case EOpEqual: out.debug << "Compare Equal"; break;
- case EOpNotEqual: out.debug << "Compare Not Equal"; break;
- case EOpLessThan: out.debug << "Compare Less Than"; break;
- case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
- case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
- case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
-
- case EOpVectorTimesScalar: out.debug << "vector-scale"; break;
- case EOpVectorTimesMatrix: out.debug << "vector-times-matrix"; break;
- case EOpMatrixTimesVector: out.debug << "matrix-times-vector"; break;
- case EOpMatrixTimesScalar: out.debug << "matrix-scale"; break;
- case EOpMatrixTimesMatrix: out.debug << "matrix-multiply"; break;
-
- case EOpLogicalOr: out.debug << "logical-or"; break;
- case EOpLogicalXor: out.debug << "logical-xor"; break;
- case EOpLogicalAnd: out.debug << "logical-and"; break;
- default: out.debug << "<unknown op>";
+ case EOpAssign: out << "move second child to first child"; break;
+ case EOpInitialize: out << "initialize first child with second child"; break;
+ case EOpAddAssign: out << "add second child into first child"; break;
+ case EOpSubAssign: out << "subtract second child into first child"; break;
+ case EOpMulAssign: out << "multiply second child into first child"; break;
+ case EOpVectorTimesMatrixAssign: out << "matrix mult second child into first child"; break;
+ case EOpVectorTimesScalarAssign: out << "vector scale second child into first child"; break;
+ case EOpMatrixTimesScalarAssign: out << "matrix scale second child into first child"; break;
+ case EOpMatrixTimesMatrixAssign: out << "matrix mult second child into first child"; break;
+ case EOpDivAssign: out << "divide second child into first child"; break;
+ case EOpIndexDirect: out << "direct index"; break;
+ case EOpIndexIndirect: out << "indirect index"; break;
+ case EOpIndexDirectStruct: out << "direct index for structure"; break;
+ case EOpVectorSwizzle: out << "vector swizzle"; break;
+
+ case EOpAdd: out << "add"; break;
+ case EOpSub: out << "subtract"; break;
+ case EOpMul: out << "component-wise multiply"; break;
+ case EOpDiv: out << "divide"; break;
+ case EOpEqual: out << "Compare Equal"; break;
+ case EOpNotEqual: out << "Compare Not Equal"; break;
+ case EOpLessThan: out << "Compare Less Than"; break;
+ case EOpGreaterThan: out << "Compare Greater Than"; break;
+ case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
+ case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+
+ case EOpVectorTimesScalar: out << "vector-scale"; break;
+ case EOpVectorTimesMatrix: out << "vector-times-matrix"; break;
+ case EOpMatrixTimesVector: out << "matrix-times-vector"; break;
+ case EOpMatrixTimesScalar: out << "matrix-scale"; break;
+ case EOpMatrixTimesMatrix: out << "matrix-multiply"; break;
+
+ case EOpLogicalOr: out << "logical-or"; break;
+ case EOpLogicalXor: out << "logical-xor"; break;
+ case EOpLogicalAnd: out << "logical-and"; break;
+ default: out << "<unknown op>";
}
- out.debug << " (" << node->getCompleteString() << ")";
+ out << " (" << node->getCompleteString() << ")";
- out.debug << "\n";
+ out << "\n";
return true;
}
bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
OutputTreeText(out, node, depth);
switch (node->getOp()) {
- case EOpNegative: out.debug << "Negate value"; break;
+ case EOpNegative: out << "Negate value"; break;
case EOpVectorLogicalNot:
- case EOpLogicalNot: out.debug << "Negate conditional"; break;
-
- case EOpPostIncrement: out.debug << "Post-Increment"; break;
- case EOpPostDecrement: out.debug << "Post-Decrement"; break;
- case EOpPreIncrement: out.debug << "Pre-Increment"; break;
- case EOpPreDecrement: out.debug << "Pre-Decrement"; break;
-
- case EOpConvIntToBool: out.debug << "Convert int to bool"; break;
- case EOpConvFloatToBool:out.debug << "Convert float to bool";break;
- case EOpConvBoolToFloat:out.debug << "Convert bool to float";break;
- case EOpConvIntToFloat: out.debug << "Convert int to float"; break;
- case EOpConvFloatToInt: out.debug << "Convert float to int"; break;
- case EOpConvBoolToInt: out.debug << "Convert bool to int"; break;
-
- case EOpRadians: out.debug << "radians"; break;
- case EOpDegrees: out.debug << "degrees"; break;
- case EOpSin: out.debug << "sine"; break;
- case EOpCos: out.debug << "cosine"; break;
- case EOpTan: out.debug << "tangent"; break;
- case EOpAsin: out.debug << "arc sine"; break;
- case EOpAcos: out.debug << "arc cosine"; break;
- case EOpAtan: out.debug << "arc tangent"; break;
-
- case EOpExp: out.debug << "exp"; break;
- case EOpLog: out.debug << "log"; break;
- case EOpExp2: out.debug << "exp2"; break;
- case EOpLog2: out.debug << "log2"; break;
- case EOpSqrt: out.debug << "sqrt"; break;
- case EOpInverseSqrt: out.debug << "inverse sqrt"; break;
-
- case EOpAbs: out.debug << "Absolute value"; break;
- case EOpSign: out.debug << "Sign"; break;
- case EOpFloor: out.debug << "Floor"; break;
- case EOpCeil: out.debug << "Ceiling"; break;
- case EOpFract: out.debug << "Fraction"; break;
-
- case EOpLength: out.debug << "length"; break;
- case EOpNormalize: out.debug << "normalize"; break;
- // case EOpDPdx: out.debug << "dPdx"; break;
- // case EOpDPdy: out.debug << "dPdy"; break;
- // case EOpFwidth: out.debug << "fwidth"; break;
-
- case EOpAny: out.debug << "any"; break;
- case EOpAll: out.debug << "all"; break;
-
- default: out.debug.message(EPrefixError, "Bad unary op");
+ case EOpLogicalNot: out << "Negate conditional"; break;
+
+ case EOpPostIncrement: out << "Post-Increment"; break;
+ case EOpPostDecrement: out << "Post-Decrement"; break;
+ case EOpPreIncrement: out << "Pre-Increment"; break;
+ case EOpPreDecrement: out << "Pre-Decrement"; break;
+
+ case EOpConvIntToBool: out << "Convert int to bool"; break;
+ case EOpConvFloatToBool:out << "Convert float to bool";break;
+ case EOpConvBoolToFloat:out << "Convert bool to float";break;
+ case EOpConvIntToFloat: out << "Convert int to float"; break;
+ case EOpConvFloatToInt: out << "Convert float to int"; break;
+ case EOpConvBoolToInt: out << "Convert bool to int"; break;
+
+ case EOpRadians: out << "radians"; break;
+ case EOpDegrees: out << "degrees"; break;
+ case EOpSin: out << "sine"; break;
+ case EOpCos: out << "cosine"; break;
+ case EOpTan: out << "tangent"; break;
+ case EOpAsin: out << "arc sine"; break;
+ case EOpAcos: out << "arc cosine"; break;
+ case EOpAtan: out << "arc tangent"; break;
+
+ case EOpExp: out << "exp"; break;
+ case EOpLog: out << "log"; break;
+ case EOpExp2: out << "exp2"; break;
+ case EOpLog2: out << "log2"; break;
+ case EOpSqrt: out << "sqrt"; break;
+ case EOpInverseSqrt: out << "inverse sqrt"; break;
+
+ case EOpAbs: out << "Absolute value"; break;
+ case EOpSign: out << "Sign"; break;
+ case EOpFloor: out << "Floor"; break;
+ case EOpCeil: out << "Ceiling"; break;
+ case EOpFract: out << "Fraction"; break;
+
+ case EOpLength: out << "length"; break;
+ case EOpNormalize: out << "normalize"; break;
+ // case EOpDPdx: out << "dPdx"; break;
+ // case EOpDPdy: out << "dPdy"; break;
+ // case EOpFwidth: out << "fwidth"; break;
+
+ case EOpAny: out << "any"; break;
+ case EOpAll: out << "all"; break;
+
+ default: out.message(EPrefixError, "Bad unary op");
}
- out.debug << " (" << node->getCompleteString() << ")";
+ out << " (" << node->getCompleteString() << ")";
- out.debug << "\n";
+ out << "\n";
return true;
}
bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
if (node->getOp() == EOpNull) {
- out.debug.message(EPrefixError, "node is still EOpNull!");
+ out.message(EPrefixError, "node is still EOpNull!");
return true;
}
OutputTreeText(out, node, depth);
switch (node->getOp()) {
- case EOpSequence: out.debug << "Sequence\n"; return true;
- case EOpComma: out.debug << "Comma\n"; return true;
- case EOpFunction: out.debug << "Function Definition: " << node->getName(); break;
- case EOpFunctionCall: out.debug << "Function Call: " << node->getName(); break;
- case EOpParameters: out.debug << "Function Parameters: "; break;
-
- case EOpConstructFloat: out.debug << "Construct float"; break;
- case EOpConstructVec2: out.debug << "Construct vec2"; break;
- case EOpConstructVec3: out.debug << "Construct vec3"; break;
- case EOpConstructVec4: out.debug << "Construct vec4"; break;
- case EOpConstructBool: out.debug << "Construct bool"; break;
- case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
- case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
- case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
- case EOpConstructInt: out.debug << "Construct int"; break;
- case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
- case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
- case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
- case EOpConstructMat2: out.debug << "Construct mat2"; break;
- case EOpConstructMat3: out.debug << "Construct mat3"; break;
- case EOpConstructMat4: out.debug << "Construct mat4"; break;
- case EOpConstructStruct: out.debug << "Construct structure"; break;
-
- case EOpLessThan: out.debug << "Compare Less Than"; break;
- case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
- case EOpLessThanEqual: out.debug << "Compare Less Than or Equal"; break;
- case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
- case EOpVectorEqual: out.debug << "Equal"; break;
- case EOpVectorNotEqual: out.debug << "NotEqual"; break;
-
- case EOpMod: out.debug << "mod"; break;
- case EOpPow: out.debug << "pow"; break;
-
- case EOpAtan: out.debug << "arc tangent"; break;
-
- case EOpMin: out.debug << "min"; break;
- case EOpMax: out.debug << "max"; break;
- case EOpClamp: out.debug << "clamp"; break;
- case EOpMix: out.debug << "mix"; break;
- case EOpStep: out.debug << "step"; break;
- case EOpSmoothStep: out.debug << "smoothstep"; break;
-
- case EOpDistance: out.debug << "distance"; break;
- case EOpDot: out.debug << "dot-product"; break;
- case EOpCross: out.debug << "cross-product"; break;
- case EOpFaceForward: out.debug << "face-forward"; break;
- case EOpReflect: out.debug << "reflect"; break;
- case EOpRefract: out.debug << "refract"; break;
- case EOpMul: out.debug << "component-wise multiply"; break;
-
- default: out.debug.message(EPrefixError, "Bad aggregation op");
+ case EOpSequence: out << "Sequence\n"; return true;
+ case EOpComma: out << "Comma\n"; return true;
+ case EOpFunction: out << "Function Definition: " << node->getName(); break;
+ case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
+ case EOpParameters: out << "Function Parameters: "; break;
+
+ case EOpConstructFloat: out << "Construct float"; break;
+ case EOpConstructVec2: out << "Construct vec2"; break;
+ case EOpConstructVec3: out << "Construct vec3"; break;
+ case EOpConstructVec4: out << "Construct vec4"; break;
+ case EOpConstructBool: out << "Construct bool"; break;
+ case EOpConstructBVec2: out << "Construct bvec2"; break;
+ case EOpConstructBVec3: out << "Construct bvec3"; break;
+ case EOpConstructBVec4: out << "Construct bvec4"; break;
+ case EOpConstructInt: out << "Construct int"; break;
+ case EOpConstructIVec2: out << "Construct ivec2"; break;
+ case EOpConstructIVec3: out << "Construct ivec3"; break;
+ case EOpConstructIVec4: out << "Construct ivec4"; break;
+ case EOpConstructMat2: out << "Construct mat2"; break;
+ case EOpConstructMat3: out << "Construct mat3"; break;
+ case EOpConstructMat4: out << "Construct mat4"; break;
+ case EOpConstructStruct: out << "Construct structure"; break;
+
+ case EOpLessThan: out << "Compare Less Than"; break;
+ case EOpGreaterThan: out << "Compare Greater Than"; break;
+ case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
+ case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
+ case EOpVectorEqual: out << "Equal"; break;
+ case EOpVectorNotEqual: out << "NotEqual"; break;
+
+ case EOpMod: out << "mod"; break;
+ case EOpPow: out << "pow"; break;
+
+ case EOpAtan: out << "arc tangent"; break;
+
+ case EOpMin: out << "min"; break;
+ case EOpMax: out << "max"; break;
+ case EOpClamp: out << "clamp"; break;
+ case EOpMix: out << "mix"; break;
+ case EOpStep: out << "step"; break;
+ case EOpSmoothStep: out << "smoothstep"; break;
+
+ case EOpDistance: out << "distance"; break;
+ case EOpDot: out << "dot-product"; break;
+ case EOpCross: out << "cross-product"; break;
+ case EOpFaceForward: out << "face-forward"; break;
+ case EOpReflect: out << "reflect"; break;
+ case EOpRefract: out << "refract"; break;
+ case EOpMul: out << "component-wise multiply"; break;
+
+ default: out.message(EPrefixError, "Bad aggregation op");
}
if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
- out.debug << " (" << node->getCompleteString() << ")";
+ out << " (" << node->getCompleteString() << ")";
- out.debug << "\n";
+ out << "\n";
return true;
}
bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
OutputTreeText(out, node, depth);
- out.debug << "Test condition and select";
- out.debug << " (" << node->getCompleteString() << ")\n";
+ out << "Test condition and select";
+ out << " (" << node->getCompleteString() << ")\n";
++depth;
- OutputTreeText(infoSink, node, depth);
- out.debug << "Condition\n";
+ OutputTreeText(sink, node, depth);
+ out << "Condition\n";
node->getCondition()->traverse(this);
- OutputTreeText(infoSink, node, depth);
+ OutputTreeText(sink, node, depth);
if (node->getTrueBlock()) {
- out.debug << "true case\n";
+ out << "true case\n";
node->getTrueBlock()->traverse(this);
} else
- out.debug << "true case is null\n";
+ out << "true case is null\n";
if (node->getFalseBlock()) {
- OutputTreeText(infoSink, node, depth);
- out.debug << "false case\n";
+ OutputTreeText(sink, node, depth);
+ out << "false case\n";
node->getFalseBlock()->traverse(this);
}
@@ -307,7 +307,7 @@ bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
int size = node->getType().getObjectSize();
@@ -316,23 +316,23 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
switch (node->getUnionArrayPointer()[i].getType()) {
case EbtBool:
if (node->getUnionArrayPointer()[i].getBConst())
- out.debug << "true";
+ out << "true";
else
- out.debug << "false";
+ out << "false";
- out.debug << " (" << "const bool" << ")";
- out.debug << "\n";
+ out << " (" << "const bool" << ")";
+ out << "\n";
break;
case EbtFloat:
- out.debug << node->getUnionArrayPointer()[i].getFConst();
- out.debug << " (const float)\n";
+ out << node->getUnionArrayPointer()[i].getFConst();
+ out << " (const float)\n";
break;
case EbtInt:
- out.debug << node->getUnionArrayPointer()[i].getIConst();
- out.debug << " (const int)\n";
+ out << node->getUnionArrayPointer()[i].getIConst();
+ out << " (const int)\n";
break;
default:
- out.info.message(EPrefixInternalError, "Unknown constant", node->getLine());
+ out.message(EPrefixInternalError, "Unknown constant", node->getLine());
break;
}
}
@@ -340,35 +340,35 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
OutputTreeText(out, node, depth);
- out.debug << "Loop with condition ";
- if (! node->testFirst())
- out.debug << "not ";
- out.debug << "tested first\n";
+ out << "Loop with condition ";
+ if (node->getType() == ELoopDoWhile)
+ out << "not ";
+ out << "tested first\n";
++depth;
- OutputTreeText(infoSink, node, depth);
- if (node->getTest()) {
- out.debug << "Loop Condition\n";
- node->getTest()->traverse(this);
+ OutputTreeText(sink, node, depth);
+ if (node->getCondition()) {
+ out << "Loop Condition\n";
+ node->getCondition()->traverse(this);
} else
- out.debug << "No loop condition\n";
+ out << "No loop condition\n";
- OutputTreeText(infoSink, node, depth);
+ OutputTreeText(sink, node, depth);
if (node->getBody()) {
- out.debug << "Loop Body\n";
+ out << "Loop Body\n";
node->getBody()->traverse(this);
} else
- out.debug << "No loop body\n";
+ out << "No loop body\n";
- if (node->getTerminal()) {
- OutputTreeText(infoSink, node, depth);
- out.debug << "Loop Terminal Expression\n";
- node->getTerminal()->traverse(this);
+ if (node->getExpression()) {
+ OutputTreeText(sink, node, depth);
+ out << "Loop Terminal Expression\n";
+ node->getExpression()->traverse(this);
}
--depth;
@@ -378,25 +378,25 @@ bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
{
- TInfoSink& out = infoSink;
+ TInfoSinkBase& out = sink;
OutputTreeText(out, node, depth);
switch (node->getFlowOp()) {
- case EOpKill: out.debug << "Branch: Kill"; break;
- case EOpBreak: out.debug << "Branch: Break"; break;
- case EOpContinue: out.debug << "Branch: Continue"; break;
- case EOpReturn: out.debug << "Branch: Return"; break;
- default: out.debug << "Branch: Unknown Branch"; break;
+ case EOpKill: out << "Branch: Kill"; break;
+ case EOpBreak: out << "Branch: Break"; break;
+ case EOpContinue: out << "Branch: Continue"; break;
+ case EOpReturn: out << "Branch: Return"; break;
+ default: out << "Branch: Unknown Branch"; break;
}
if (node->getExpression()) {
- out.debug << " with expression\n";
+ out << " with expression\n";
++depth;
node->getExpression()->traverse(this);
--depth;
} else
- out.debug << "\n";
+ out << "\n";
return false;
}
@@ -411,7 +411,7 @@ void TIntermediate::outputTree(TIntermNode* root)
if (root == 0)
return;
- TOutputTraverser it(infoSink);
+ TOutputTraverser it(infoSink.info);
root->traverse(&it);
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
index d262905..f9fa1de 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h
@@ -129,9 +129,9 @@ enum TOperator {
EOpReflect,
EOpRefract,
- //EOpDPdx, // Fragment only, OES_standard_derivatives extension
- //EOpDPdy, // Fragment only, OES_standard_derivatives extension
- //EOpFwidth, // Fragment only, OES_standard_derivatives extension
+ EOpDFdx, // Fragment only, OES_standard_derivatives extension
+ EOpDFdy, // Fragment only, OES_standard_derivatives extension
+ EOpFwidth, // Fragment only, OES_standard_derivatives extension
EOpMatrixTimesMatrix,
@@ -184,6 +184,8 @@ enum TOperator {
EOpDivAssign,
};
+extern const char* getOperatorString(TOperator op);
+
class TIntermTraverser;
class TIntermAggregate;
class TIntermBinary;
@@ -262,30 +264,38 @@ protected:
//
// Handle for, do-while, and while loops.
//
+enum TLoopType {
+ ELoopFor,
+ ELoopWhile,
+ ELoopDoWhile,
+};
+
class TIntermLoop : public TIntermNode {
public:
- TIntermLoop(TIntermNode *init, TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
- init(init),
- body(aBody),
- test(aTest),
- terminal(aTerminal),
- first(testFirst) { }
+ TIntermLoop(TLoopType aType,
+ TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
+ TIntermNode* aBody) :
+ type(aType),
+ init(aInit),
+ cond(aCond),
+ expr(aExpr),
+ body(aBody) { }
virtual TIntermLoop* getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser*);
- TIntermNode *getInit() { return init; }
- TIntermNode *getBody() { return body; }
- TIntermTyped *getTest() { return test; }
- TIntermTyped *getTerminal() { return terminal; }
- bool testFirst() { return first; }
+ TLoopType getType() const { return type; }
+ TIntermNode* getInit() { return init; }
+ TIntermTyped* getCondition() { return cond; }
+ TIntermTyped* getExpression() { return expr; }
+ TIntermNode* getBody() { return body; }
protected:
- TIntermNode *init;
- TIntermNode *body; // code to loop over
- TIntermTyped *test; // exit condition associated with loop, could be 0 for 'for' loops
- TIntermTyped *terminal; // exists for for-loops
- bool first; // true for while and for, not for do-while
+ TLoopType type;
+ TIntermNode* init; // for-loop initialization
+ TIntermTyped* cond; // loop exit condition
+ TIntermTyped* expr; // for-loop expression
+ TIntermNode* body; // loop body
};
//
@@ -404,6 +414,7 @@ protected:
typedef TVector<TIntermNode*> TIntermSequence;
typedef TVector<int> TQualifierList;
+typedef TMap<TString, TString> TPragmaTable;
//
// Nodes that operate on an arbitrary sized set of children.
//
@@ -417,12 +428,13 @@ public:
virtual void traverse(TIntermTraverser*);
TIntermSequence& getSequence() { return sequence; }
+
void setName(const TString& n) { name = n; }
const TString& getName() const { return name; }
void setUserDefined() { userDefined = true; }
bool isUserDefined() { return userDefined; }
- TQualifierList& getQualifier() { return qualifier; }
+
void setOptimize(bool o) { optimize = o; }
bool getOptimize() { return optimize; }
void setDebug(bool d) { debug = d; }
@@ -434,9 +446,9 @@ protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
TIntermSequence sequence;
- TQualifierList qualifier;
TString name;
bool userDefined; // used for user defined function names
+
bool optimize;
bool debug;
TPragmaTable *pragmaTable;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h b/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
index 5fd4c69..56890bd 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/localintermediate.h
@@ -40,11 +40,11 @@ public:
TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
- TIntermNode* addLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
+ TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
TIntermBranch* addBranch(TOperator, TSourceLoc);
TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);
- bool postProcess(TIntermNode*, EShLanguage);
+ bool postProcess(TIntermNode*);
void remove(TIntermNode*);
void outputTree(TIntermNode*);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
index d887914..1af5064 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h
@@ -8,8 +8,8 @@
#define __OSINCLUDE_H
//
-// This file contains contains the window's specific datatypes and
-// declares any windows specific functions.
+// This file contains contains os-specific datatypes and
+// declares any os-specific functions.
//
#if defined(_WIN32) || defined(_WIN64)
@@ -22,7 +22,9 @@
#error Unsupported platform.
#endif
-#if defined(ANGLE_OS_WIN)
+#if defined(ANGLE_USE_NSPR)
+#include "prthread.h"
+#elif defined(ANGLE_OS_WIN)
#define STRICT
#define VC_EXTRALEAN 1
#include <windows.h>
@@ -30,20 +32,24 @@
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>
-#endif // ANGLE_OS_WIN
+#endif // ANGLE_USE_NSPR
+
#include "compiler/debug.h"
//
// Thread Local Storage Operations
//
-#if defined(ANGLE_OS_WIN)
+#if defined(ANGLE_USE_NSPR)
+typedef PRUintn OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX 0xFFFFFFFF
+#elif 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_OS_WIN
+#endif // ANGLE_USE_NSPR
OS_TLSIndex OS_AllocTLSIndex();
bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
@@ -51,8 +57,10 @@ bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
{
- assert(nIndex != OS_INVALID_TLS_INDEX);
-#if defined(ANGLE_OS_WIN)
+ ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+#if defined(ANGLE_USE_NSPR)
+ return PR_GetThreadPrivate(nIndex);
+#elif defined(ANGLE_OS_WIN)
return TlsGetValue(nIndex);
#elif defined(ANGLE_OS_POSIX)
return pthread_getspecific(nIndex);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp b/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp
new file mode 100644
index 0000000..f63d81e
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/ossource_nspr.cpp
@@ -0,0 +1,43 @@
+//
+// 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/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
index 5bfa902..69e3425 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h
@@ -89,10 +89,10 @@ struct CPPStruct_Rec {
// 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
- int* PaStrLen; // array of lengths of the PaArgv strings
- int PaArgc; // count of strings in the array
- char** PaArgv; // our array of strings to parse
+ 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;
};
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
index f15c56d..204a213 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c
@@ -191,6 +191,9 @@ static int CPPdefine(yystypepp * yylvalpp)
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);
@@ -267,9 +270,13 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
while (token > 0) {
if (token != '#') {
- while (token != '\n')
+ 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;
}
@@ -295,8 +302,13 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n')
+ 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;
}
@@ -467,9 +479,14 @@ static int CPPif(yystypepp * yylvalpp) {
}
token = eval(token, MIN_PREC, &res, &err, yylvalpp);
if (token != '\n') {
- CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
- while (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);
@@ -495,8 +512,13 @@ static int CPPifdef(int defined, yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
- while (token != '\n')
+ 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);
@@ -544,7 +566,10 @@ static int CPPerror(yystypepp * yylvalpp) {
const char *message;
while (token != '\n') {
- if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
+ 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));
@@ -670,7 +695,7 @@ static int CPPextension(yystypepp * yylvalpp)
{
int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
- char extensionName[80];
+ char extensionName[MAX_SYMBOL_NAME_LEN + 1];
if(token=='\n'){
DecLineNumber();
@@ -682,7 +707,8 @@ static int CPPextension(yystypepp * yylvalpp)
if (token != CPP_IDENTIFIER)
CPPErrorToInfoLog("#extension");
- strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+ 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 != ':') {
@@ -726,8 +752,13 @@ int readCPPline(yystypepp * yylvalpp)
token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
if (token != '\n') {
CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
- while (token != '\n')
+ 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{
@@ -743,8 +774,14 @@ int readCPPline(yystypepp * yylvalpp)
}
// 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')
+ 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;
+ break;
+ }
+ }
token = CPPelse(0, yylvalpp);
} else if (yylvalpp->sc_ident == endifAtom) {
--cpp->elsetracker;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
index 0602c91..88d196f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/preprocess.h
@@ -42,10 +42,10 @@ TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\****************************************************************************/
-# include "compiler/preprocessor/slglobals.h"
+#include "compiler/preprocessor/slglobals.h"
extern CPPStruct *cpp;
int InitCPPStruct(void);
int InitScanner(CPPStruct *cpp);
int InitAtomTable(AtomTable *atable, int htsize);
-int ScanFromString(char *s);
+int ScanFromString(const char *s);
char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
index c77d271..7b399a0 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c
@@ -45,6 +45,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// scanner.c
//
+#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -52,13 +53,13 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if 0
#include <ieeefp.h>
- #else
+#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;
@@ -133,49 +134,49 @@ int FreeScanner(void)
*/
static int str_getch(StringInputSrc *in)
{
- for(;;){
- if (*in->p){
- if (*in->p == '\n') {
+ 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;
+ }
+ 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') {
+ 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(char *s)
+int ScanFromString(const char *s)
{
- StringInputSrc *in = malloc(sizeof(StringInputSrc));
+ StringInputSrc *in = malloc(sizeof(StringInputSrc));
memset(in, 0, sizeof(StringInputSrc));
- in->p = s;
+ in->p = (char*) s;
in->base.line = 1;
in->base.scan = byte_scan;
in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
@@ -190,119 +191,63 @@ int ScanFromString(char *s)
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Floating point constants: /////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
-/*
- * lBuildFloatValue() - Quick and dirty conversion to floating point. Since all
- * we need is single precision this should be quite precise.
- */
-
-static float lBuildFloatValue(const char *str, int len, int exp)
-{
- double val, expval, ten;
- int ii, llen, absexp;
- float rv;
-
- val = 0.0;
- llen = len;
- for (ii = 0; ii < len; ii++)
- val = val*10.0 + (str[ii] - '0');
- if (exp != 0) {
- absexp = exp > 0 ? exp : -exp;
- expval = 1.0f;
- ten = 10.0;
- while (absexp) {
- if (absexp & 1)
- expval *= ten;
- ten *= ten;
- absexp >>= 1;
- }
- if (exp >= 0) {
- val *= expval;
- } else {
- val /= expval;
- }
- }
- rv = (float)val;
- if (isinff(rv)) {
- CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW");
- }
- return rv;
-} // lBuildFloatValue
+#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(char *str, int len, int ch, yystypepp * yylvalpp)
+static int lFloatConst(int ch, int len, yystypepp * yylvalpp)
{
- int HasDecimal, declen, exp, ExpSign;
- int str_len;
- float lval;
-
- HasDecimal = 0;
- declen = 0;
- exp = 0;
-
- str_len=len;
+ int alreadyComplained = 0;
+ assert((ch == '.') || (ch == 'e') || (ch == 'E'));
+
if (ch == '.') {
- str[len++]=ch;
- HasDecimal = 1;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- while (ch >= '0' && ch <= '9') {
- if (len < MAX_SYMBOL_NAME_LEN) {
- declen++;
- if (len > 0 || ch != '0') {
- str[len] = ch;
- len++;str_len++;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else {
- CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
- len = 1,str_len=1;
- }
- }
+ 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') {
- ExpSign = 1;
- str[len++]=ch;
+ APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if (ch == '+') {
- str[len++]=ch;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+ APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
+ ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
} else if (ch == '-') {
- ExpSign = -1;
- str[len++]=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') {
- exp = exp*10 + ch - '0';
- str[len++]=ch;
+ APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
}
} else {
- CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
+ CPPErrorToInfoLog("EXPONENT INVALID");
}
- exp *= ExpSign;
}
-
- if (len == 0) {
- lval = 0.0f;
- strcpy(str,"0.0");
- } else {
- str[len]='\0';
- lval = lBuildFloatValue(str, str_len, exp - declen);
+ 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");
}
- // Suffix:
-
- yylvalpp->sc_fval = lval;
- strcpy(yylvalpp->symbol_name,str);
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
return CPP_FLOATCONSTANT;
} // lFloatConst
@@ -312,29 +257,29 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp)
static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
{
- char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
char string_val[MAX_STRING_LEN + 1];
- int AlreadyComplained;
+ 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
+ return ch; // Single character token
case EOF:
return -1;
- case 'A': case 'B': case 'C': case 'D': case 'E':
+ 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':
@@ -347,39 +292,32 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
case 'u': case 'v': case 'w': case 'x': case 'y':
case 'z':
do {
- if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- } else {
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
+ 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 == '_');
- if (len >= MAX_SYMBOL_NAME_LEN)
- len = MAX_SYMBOL_NAME_LEN - 1;
- symbol_name[len] = '\0';
+ assert(len <= MAX_SYMBOL_NAME_LEN);
+ yylvalpp->symbol_name[len] = '\0';
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+ yylvalpp->sc_ident = LookUpAddString(atable, yylvalpp->symbol_name);
return CPP_IDENTIFIER;
break;
case '0':
- yylvalpp->symbol_name[len++] = ch;
+ APPEND_CHAR_S(ch, yylvalpp->symbol_name, len, MAX_SYMBOL_NAME_LEN);
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- if (ch == 'x' || ch == 'X') {
- yylvalpp->symbol_name[len++] = ch;
+ 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'))
{
- AlreadyComplained = 0;
ival = 0;
do {
- yylvalpp->symbol_name[len++] = ch;
- if (ival <= 0x0fffffff) {
+ 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') {
@@ -388,74 +326,67 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ii = ch - 'a' + 10;
}
ival = (ival << 4) | ii;
- } else {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
- AlreadyComplained = 1;
+ } 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("ERROR___ERROR_IN_HEX_CONSTANT");
+ 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;
+ cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+ yylvalpp->sc_int = ival;
return CPP_INTCONSTANT;
} else if (ch >= '0' && ch <= '7') { // octal integer constants
- AlreadyComplained = 0;
ival = 0;
do {
- yylvalpp->symbol_name[len++] = ch;
- if (ival <= 0x1fffffff) {
+ if ((ival <= 0x1fffffff) && (len < MAX_SYMBOL_NAME_LEN)) {
+ yylvalpp->symbol_name[len++] = ch;
ii = ch - '0';
ival = (ival << 3) | ii;
- } else {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
- AlreadyComplained = 1;
+ } 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(yylvalpp->symbol_name, len, ch, yylvalpp);
+ 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;
+ cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+ yylvalpp->sc_int = ival;
return CPP_INTCONSTANT;
} else {
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- ch = '0';
+ 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 {
- if (len < MAX_SYMBOL_NAME_LEN) {
- if (len > 0 || ch != '0') {
- yylvalpp->symbol_name[len] = ch;
- len++;
- }
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
+ 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 == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
- return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+ return lFloatConst(ch, len, yylvalpp);
} else {
+ assert(len <= MAX_SYMBOL_NAME_LEN);
yylvalpp->symbol_name[len] = '\0';
- cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+ cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
ival = 0;
- AlreadyComplained = 0;
for (ii = 0; ii < len; ii++) {
ch = yylvalpp->symbol_name[ii] - '0';
+ ival = ival*10 + ch;
if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
- if (!AlreadyComplained)
- CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
- AlreadyComplained = 1;
+ CPPErrorToInfoLog("INTEGER CONSTANT OVERFLOW");
+ break;
}
- ival = ival*10 + ch;
}
yylvalpp->sc_int = ival;
if(ival==0)
@@ -608,7 +539,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if (ch >= '0' && ch <= '9') {
cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
- return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
+ return lFloatConst('.', 0, yylvalpp);
} else {
if (ch == '.') {
return -1; // Special EOF hack
@@ -633,14 +564,14 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
while (ch != '*') {
if (ch == '\n') nlcount++;
if (ch == EOF) {
- CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+ CPPErrorToInfoLog("EOF IN COMMENT");
return -1;
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
}
ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
if (ch == EOF) {
- CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+ CPPErrorToInfoLog("EOF IN COMMENT");
return -1;
}
} while (ch != '/');
@@ -662,41 +593,40 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
CPPErrorToInfoLog("The line continuation character (\\) is not part of the OpenGL ES Shading Language");
return -1;
}
- if (len < MAX_STRING_LEN) {
- string_val[len] = ch;
- len++;
- ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
- }
+ 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("ERROR___CPP_EOL_IN_STRING");
+ CPPErrorToInfoLog("EOL IN STRING");
return ERROR_SY;
}
+ break;
}
}
} // byte_scan
int yylex_CPP(char* buf, int maxSize)
{
- yystypepp yylvalpp;
+ yystypepp yylvalpp;
int token = '\n';
for(;;) {
char* tokenString = 0;
token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
- if(check_EOF(token))
- return 0;
+ if(check_EOF(token))
+ return 0;
if (token == '#') {
if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
- token = readCPPline(&yylvalpp);
+ token = readCPPline(&yylvalpp);
if(check_EOF(token))
return 0;
- continue;
+ continue;
} else {
CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
return 0;
@@ -708,30 +638,28 @@ int yylex_CPP(char* buf, int maxSize)
cpp->pastFirstStatement = 1;
continue;
}
-
+
if (token == '\n')
continue;
-
- if (token == CPP_IDENTIFIER) {
- cpp->pastFirstStatement = 1;
+ cpp->pastFirstStatement = 1;
+
+ if (token == CPP_IDENTIFIER) {
tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
- } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){
- cpp->pastFirstStatement = 1;
+ } else if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
tokenString = yylvalpp.symbol_name;
- } else {
- cpp->pastFirstStatement = 1;
+ } else {
tokenString = GetStringOfAtom(atable,token);
- }
+ }
if (tokenString) {
- if ((signed)strlen(tokenString) >= maxSize) {
- cpp->tokensBeforeEOF = 1;
- return maxSize;
- } else if (strlen(tokenString) > 0) {
- strcpy(buf, tokenString);
- cpp->tokensBeforeEOF = 1;
- return (int)strlen(tokenString);
- }
+ int len = strlen(tokenString);
+ cpp->tokensBeforeEOF = 1;
+ if (len >= maxSize) {
+ return maxSize;
+ } else if (len > 0) {
+ strcpy(buf, tokenString);
+ return len;
+ }
return 0;
}
@@ -745,7 +673,7 @@ int check_EOF(int token)
{
if(token==-1){
if(cpp->ifdepth >0){
- CPPErrorToInfoLog("#endif missing!! Compilation stopped");
+ CPPErrorToInfoLog("#endif missing!! Compilation stopped");
cpp->CompileError=1;
}
return 1;
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
index 571fe57..0fee20d 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h
@@ -48,8 +48,9 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if !defined(__SCANNER_H)
#define __SCANNER_H 1
-#define MAX_SYMBOL_NAME_LEN 128
-#define MAX_STRING_LEN 512
+// These lengths do not include the NULL terminator.
+#define MAX_SYMBOL_NAME_LEN 127
+#define MAX_STRING_LEN 511
#include "compiler/preprocessor/parser.h"
@@ -59,8 +60,6 @@ typedef struct SourceLoc_Rec {
unsigned short file, line;
} SourceLoc;
-int yyparse (void);
-
int yylex_CPP(char* buf, int maxSize);
typedef struct InputSrc {
@@ -73,7 +72,7 @@ typedef struct InputSrc {
} InputSrc;
int InitScanner(CPPStruct *cpp); // Intialise the cpp scanner.
-int ScanFromString(char *); // Start scanning the input from the string mentioned.
+int ScanFromString(const char *); // Start scanning the input from the string mentioned.
int check_EOF(int); // check if we hit a EOF abruptly
void CPPErrorToInfoLog(char *); // sticking the msg,line into the Shader's.Info.log
void SetLineNumber(int);
diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
index 057cce8..aa83d2f 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
+++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c
@@ -52,6 +52,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "compiler/debug.h"
#include "compiler/preprocessor/slglobals.h"
+#include "compiler/util.h"
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
@@ -224,8 +225,7 @@ void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
case CPP_INTCONSTANT:
str=yylvalpp->symbol_name;
while (*str){
- lAddByte(pTok,(unsigned char) *str);
- *str++;
+ lAddByte(pTok, (unsigned char) *str++);
}
lAddByte(pTok, 0);
break;
@@ -276,8 +276,7 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
ch == '_')
{
if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
+ symbol_name[len++] = ch;
ch = lReadByte(pTok);
}
}
@@ -291,7 +290,7 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
while ((ch = lReadByte(pTok)) != 0)
if (len < MAX_STRING_LEN)
string_val[len++] = ch;
- string_val[len] = 0;
+ string_val[len] = '\0';
yylvalpp->sc_ident = LookUpAddString(atable, string_val);
break;
case CPP_FLOATCONSTANT:
@@ -300,15 +299,14 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
{
if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- 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(yylvalpp->symbol_name);
+ yylvalpp->sc_fval=(float)atof_dot(yylvalpp->symbol_name);
break;
case CPP_INTCONSTANT:
len = 0;
@@ -316,8 +314,7 @@ int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
while ((ch >= '0' && ch <= '9'))
{
if (len < MAX_SYMBOL_NAME_LEN) {
- symbol_name[len] = ch;
- len++;
+ symbol_name[len++] = ch;
ch = lReadByte(pTok);
}
}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/unistd.h b/Source/ThirdParty/ANGLE/src/compiler/unistd.h
deleted file mode 100644
index c7c9147..0000000
--- a/Source/ThirdParty/ANGLE/src/compiler/unistd.h
+++ /dev/null
@@ -1 +0,0 @@
-// This is a NULL file and is meant to be empty
diff --git a/Source/ThirdParty/ANGLE/src/compiler/util.cpp b/Source/ThirdParty/ANGLE/src/compiler/util.cpp
new file mode 100644
index 0000000..b46e4d0
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/util.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include <math.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#ifdef _MSC_VER
+ #include <locale.h>
+#else
+ #include <sstream>
+#endif
+
+double atof_dot(const char *str)
+{
+#ifdef _MSC_VER
+ _locale_t l = _create_locale(LC_NUMERIC, "C");
+ double result = _atof_l(str, l);
+ _free_locale(l);
+ return result;
+#else
+ double result;
+ std::istringstream s(str);
+ std::locale l("C");
+ s.imbue(l);
+ s >> result;
+ return result;
+#endif
+}
diff --git a/Source/ThirdParty/ANGLE/src/compiler/util.h b/Source/ThirdParty/ANGLE/src/compiler/util.h
new file mode 100644
index 0000000..35288b7
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/compiler/util.h
@@ -0,0 +1,21 @@
+//
+// 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.
+//
+
+#ifndef COMPILER_UTIL_H
+#define COMPILER_UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// atof_dot is like atof but forcing C locale, i.e. forcing '.' as decimal point.
+double atof_dot(const char *str);
+
+#ifdef __cplusplus
+} // end extern "C"
+#endif
+
+#endif // COMPILER_UTIL_H
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
index 21d4661..284f61d 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp
@@ -94,13 +94,6 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter
mBlueSize = 5;
mAlphaSize = 0;
break;
- case D3DFMT_X1R5G5B5:
- mBufferSize = 16;
- mRedSize = 5;
- mGreenSize = 5;
- mBlueSize = 5;
- mAlphaSize = 0;
- break;
case D3DFMT_X8R8G8B8:
mBufferSize = 32;
mRedSize = 8;
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
index e2802da..6f1a335 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp
@@ -17,7 +17,8 @@
#include "libEGL/main.h"
-#define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define REF_RAST 0 // Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define ENABLE_D3D9EX 1 // Enables use of the IDirect3D9Ex interface, when available
namespace egl
{
@@ -40,7 +41,6 @@ Display::Display(HDC deviceContext) : mDc(deviceContext)
mMinSwapInterval = 1;
mMaxSwapInterval = 1;
- setSwapInterval(1);
}
Display::~Display()
@@ -77,7 +77,7 @@ bool Display::initialize()
// 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 (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+ if (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
{
ASSERT(mD3d9ex);
mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
@@ -95,11 +95,26 @@ bool Display::initialize()
// UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to
}
- HRESULT result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ HRESULT result;
+
+ // Give up on getting device caps after about one second.
+ for (int i = 0; i < 10; ++i)
{
- return error(EGL_BAD_ALLOC, false);
+ 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))
@@ -108,6 +123,14 @@ bool Display::initialize()
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;
@@ -123,7 +146,7 @@ bool Display::initialize()
// 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,
+ // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format
D3DFMT_X8R8G8B8
};
@@ -183,13 +206,6 @@ bool Display::initialize()
mConfigSet.mSet.insert(configuration);
}
-
- if (!createDevice())
- {
- terminate();
-
- return false;
- }
}
if (!isInitialized())
@@ -199,23 +215,34 @@ bool Display::initialize()
return false;
}
+ 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);
+
return true;
}
void Display::terminate()
{
- for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ while (!mSurfaceSet.empty())
{
- delete *surface;
+ destroySurface(*mSurfaceSet.begin());
}
- for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
+ while (!mContextSet.empty())
{
- glDestroyContext(*context);
+ destroyContext(*mContextSet.begin());
}
if (mDevice)
{
+ // If the device is lost, reset it first to prevent leaving the driver in an unstable state
+ if (FAILED(mDevice->TestCooperativeLevel()))
+ {
+ resetDevice();
+ }
+
mDevice->Release();
mDevice = NULL;
}
@@ -314,33 +341,12 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
bool Display::createDevice()
{
- 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 = {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 = convertInterval(mMinSwapInterval);
- presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
- presentParameters.Windowed = TRUE;
-
+ 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)
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
{
return error(EGL_BAD_ALLOC, false);
}
@@ -349,14 +355,13 @@ bool Display::createDevice()
{
result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ if (FAILED(result))
{
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
return error(EGL_BAD_ALLOC, false);
}
}
- ASSERT(SUCCEEDED(result));
-
// Permanent non-default states
mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
@@ -365,6 +370,29 @@ bool Display::createDevice()
return true;
}
+bool Display::resetDevice()
+{
+ D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+ HRESULT result;
+
+ do
+ {
+ Sleep(0); // Give the graphics driver some CPU time
+
+ result = mDevice->Reset(&presentParameters);
+ }
+ while (result == D3DERR_DEVICELOST);
+
+ if (FAILED(result))
+ {
+ return error(EGL_BAD_ALLOC, false);
+ }
+
+ ASSERT(SUCCEEDED(result));
+
+ return true;
+}
+
Surface *Display::createWindowSurface(HWND window, EGLConfig config)
{
const Config *configuration = mConfigSet.get(config);
@@ -377,6 +405,27 @@ Surface *Display::createWindowSurface(HWND window, EGLConfig config)
EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
{
+ if (!mDevice)
+ {
+ if (!createDevice())
+ {
+ return NULL;
+ }
+ }
+ else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device
+ {
+ if (!resetDevice())
+ {
+ return NULL;
+ }
+
+ // Restore any surfaces that may have been lost
+ for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ {
+ (*surface)->resetSwapChain();
+ }
+ }
+
const egl::Config *config = mConfigSet.get(configHandle);
gl::Context *context = glCreateContext(config, shareContext);
@@ -395,6 +444,14 @@ void Display::destroyContext(gl::Context *context)
{
glDestroyContext(context);
mContextSet.erase(context);
+
+ if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device
+ {
+ for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
+ {
+ (*surface)->release();
+ }
+ }
}
bool Display::isInitialized()
@@ -430,37 +487,26 @@ bool Display::hasExistingWindowSurface(HWND window)
return false;
}
-void Display::setSwapInterval(GLint interval)
+EGLint Display::getMinSwapInterval()
{
- mSwapInterval = interval;
- mSwapInterval = std::max(mSwapInterval, mMinSwapInterval);
- mSwapInterval = std::min(mSwapInterval, mMaxSwapInterval);
-
- mPresentInterval = convertInterval(mSwapInterval);
+ return mMinSwapInterval;
}
-DWORD Display::getPresentInterval()
+EGLint Display::getMaxSwapInterval()
{
- return mPresentInterval;
+ return mMaxSwapInterval;
}
-DWORD Display::convertInterval(GLint interval)
+IDirect3DDevice9 *Display::getDevice()
{
- switch(interval)
+ if (!mDevice)
{
- 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();
+ if (!createDevice())
+ {
+ return NULL;
+ }
}
- return D3DPRESENT_INTERVAL_DEFAULT;
-}
-
-IDirect3DDevice9 *Display::getDevice()
-{
return mDevice;
}
@@ -487,4 +533,127 @@ bool Display::getCompressedTextureSupport()
return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
}
+
+bool Display::getFloatTextureSupport(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::getHalfFloatTextureSupport(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));
+}
+
+D3DPOOL Display::getBufferPool(DWORD usage) const
+{
+ if (mD3d9ex != NULL)
+ {
+ return D3DPOOL_DEFAULT;
+ }
+ else
+ {
+ if (!(usage & D3DUSAGE_DYNAMIC))
+ {
+ return D3DPOOL_MANAGED;
+ }
+ }
+
+ return D3DPOOL_DEFAULT;
+}
+
+bool Display::getEventQuerySupport()
+{
+ IDirect3DQuery9 *query;
+ HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query);
+ if (SUCCEEDED(result))
+ {
+ query->Release();
+ }
+
+ return result != D3DERR_NOTAVAILABLE;
+}
+
+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;
}
+} \ No newline at end of file
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.h b/Source/ThirdParty/ANGLE/src/libEGL/Display.h
index bd33012..4b74e1e 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Display.h
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.h
@@ -54,17 +54,25 @@ class Display
bool isValidSurface(egl::Surface *surface);
bool hasExistingWindowSurface(HWND window);
- void setSwapInterval(GLint interval);
- DWORD getPresentInterval();
- static DWORD convertInterval(GLint interval);
+ EGLint getMinSwapInterval();
+ EGLint getMaxSwapInterval();
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
virtual bool getCompressedTextureSupport();
+ virtual bool getEventQuerySupport();
+ virtual bool getFloatTextureSupport(bool *filtering, bool *renderable);
+ virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable);
+ virtual bool getLuminanceTextureSupport();
+ virtual bool getLuminanceAlphaTextureSupport();
+ virtual D3DPOOL getBufferPool(DWORD usage) const;
private:
DISALLOW_COPY_AND_ASSIGN(Display);
+
+ D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+
const HDC mDc;
HMODULE mD3d9Module;
@@ -78,11 +86,9 @@ class Display
HWND mDeviceWindow;
bool mSceneStarted;
- GLint mSwapInterval;
EGLint mMaxSwapInterval;
EGLint mMinSwapInterval;
- DWORD mPresentInterval;
-
+
typedef std::set<Surface*> SurfaceSet;
SurfaceSet mSurfaceSet;
@@ -92,6 +98,7 @@ class Display
ContextSet mContextSet;
bool createDevice();
+ bool resetDevice();
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
index a5638d4..2736a7f 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp
@@ -8,6 +8,8 @@
// such as the client area of a window, including any back buffers.
// Implements EGLSurface and related functionality. [EGL 1.4] section 2.2 page 3.
+#include <tchar.h>
+
#include "libEGL/Surface.h"
#include "common/debug.h"
@@ -23,7 +25,6 @@ Surface::Surface(Display *display, const Config *config, HWND window)
mSwapChain = NULL;
mDepthStencil = NULL;
mBackBuffer = NULL;
- mRenderTarget = NULL;
mFlipTexture = NULL;
mFlipState = NULL;
mPreFlipState = NULL;
@@ -31,52 +32,86 @@ Surface::Surface(Display *display, const Config *config, HWND window)
mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
+ mSwapInterval = -1;
+ setSwapInterval(1);
+ subclassWindow();
resetSwapChain();
}
Surface::~Surface()
{
+ unsubclassWindow();
+ release();
+}
+
+void Surface::release()
+{
if (mSwapChain)
{
mSwapChain->Release();
+ mSwapChain = NULL;
}
if (mBackBuffer)
{
mBackBuffer->Release();
- }
-
- if (mRenderTarget)
- {
- mRenderTarget->Release();
+ mBackBuffer = NULL;
}
if (mDepthStencil)
{
mDepthStencil->Release();
+ mDepthStencil = NULL;
}
if (mFlipTexture)
{
mFlipTexture->Release();
+ mFlipTexture = NULL;
}
if (mFlipState)
{
mFlipState->Release();
+ mFlipState = NULL;
}
if (mPreFlipState)
{
mPreFlipState->Release();
+ mPreFlipState = NULL;
}
}
void Surface::resetSwapChain()
{
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(false);
+
+ ERR("Could not retrieve the window dimensions");
+ return;
+ }
+
+ resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top);
+}
+
+void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight)
+{
IDirect3DDevice9 *device = mDisplay->getDevice();
+ if (device == NULL)
+ {
+ return;
+ }
+
+ // 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();
+ release();
+
D3DPRESENT_PARAMETERS presentParameters = {0};
presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
@@ -87,96 +122,57 @@ void Surface::resetSwapChain()
presentParameters.hDeviceWindow = getWindowHandle();
presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
- presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
+ presentParameters.PresentationInterval = mPresentInterval;
presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
presentParameters.Windowed = TRUE;
+ presentParameters.BackBufferWidth = backbufferWidth;
+ presentParameters.BackBufferHeight = backbufferHeight;
- RECT windowRect;
- if (!GetClientRect(getWindowHandle(), &windowRect))
- {
- ASSERT(false);
- return;
- }
-
- presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
- presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
-
- IDirect3DSwapChain9 *swapChain = NULL;
- HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain);
+ HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
ERR("Could not create additional swap chains: %08lX", result);
+ release();
return error(EGL_BAD_ALLOC);
}
- IDirect3DSurface9 *depthStencilSurface = NULL;
result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
- presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+ presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- swapChain->Release();
-
ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
- return error(EGL_BAD_ALLOC);
- }
-
- IDirect3DSurface9 *renderTarget = NULL;
- result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat,
- presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-
- swapChain->Release();
- depthStencilSurface->Release();
-
- ERR("Could not create render target surface for new swap chain: %08lX", result);
+ release();
return error(EGL_BAD_ALLOC);
}
ASSERT(SUCCEEDED(result));
- IDirect3DTexture9 *flipTexture = NULL;
result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
- presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL);
+ presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- swapChain->Release();
- depthStencilSurface->Release();
- renderTarget->Release();
-
ERR("Could not create flip texture for new swap chain: %08lX", result);
+ release();
return error(EGL_BAD_ALLOC);
}
- IDirect3DSurface9 *backBuffer = NULL;
- swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
-
- if (mSwapChain) mSwapChain->Release();
- if (mDepthStencil) mDepthStencil->Release();
- if (mBackBuffer) mBackBuffer->Release();
- if (mRenderTarget) mRenderTarget->Release();
- if (mFlipTexture) mFlipTexture->Release();
-
+ mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
mWidth = presentParameters.BackBufferWidth;
mHeight = presentParameters.BackBufferHeight;
- mSwapChain = swapChain;
- mDepthStencil = depthStencilSurface;
- mBackBuffer = backBuffer;
- mRenderTarget = renderTarget;
- mFlipTexture = flipTexture;
+ mPresentIntervalDirty = false;
+
+ InvalidateRect(mWindow, NULL, FALSE);
// The flip state block recorded mFlipTexture so it is now invalid.
releaseRecordedState(device);
@@ -199,6 +195,7 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
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);
@@ -206,7 +203,7 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
+ device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
@@ -214,7 +211,10 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
- device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
+ RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
+ device->SetScissorRect(&scissorRect);
+ D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
+ device->SetViewport(&viewport);
}
void Surface::applyFlipState(IDirect3DDevice9 *device)
@@ -275,8 +275,6 @@ void Surface::applyFlipState(IDirect3DDevice9 *device)
void Surface::restoreState(IDirect3DDevice9 *device)
{
- mPreFlipState->Apply();
-
device->SetRenderTarget(0, mPreFlipBackBuffer);
device->SetDepthStencilSurface(mPreFlipDepthStencil);
@@ -291,6 +289,8 @@ void Surface::restoreState(IDirect3DDevice9 *device)
mPreFlipDepthStencil->Release();
mPreFlipDepthStencil = NULL;
}
+
+ mPreFlipState->Apply();
}
// On the next flip, this will cause the state to be recorded from scratch.
@@ -309,8 +309,58 @@ void Surface::releaseRecordedState(IDirect3DDevice9 *device)
mPreFlipState = NULL;
}
}
+#define kSurfaceProperty _TEXT("Egl::SurfaceOwner")
+#define kParentWndProc _TEXT("Egl::SurfaceParentWndProc")
+
+static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
+ if (message == WM_SIZE) {
+ Surface* surf = reinterpret_cast<Surface*>(GetProp(hwnd, kSurfaceProperty));
+ if(surf) {
+ surf->checkForOutOfDateSwapChain();
+ }
+ }
+ WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc));
+ return CallWindowProc(prevWndFunc, hwnd, message, wparam, lparam);
+}
-bool Surface::checkForWindowResize()
+void Surface::subclassWindow()
+{
+ SetLastError(0);
+ LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc));
+ if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) {
+ mWindowSubclassed = false;
+ return;
+ }
+
+ SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this));
+ SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc));
+ mWindowSubclassed = true;
+}
+
+void Surface::unsubclassWindow()
+{
+ if(!mWindowSubclassed)
+ return;
+
+ // un-subclass
+ LONG parentWndFunc = reinterpret_cast<LONG>(GetProp(mWindow, kParentWndProc));
+
+ // Check the windowproc is still SurfaceWindowProc.
+ // If this assert fails, then it is likely the application has subclassed the
+ // hwnd as well and did not unsubclass before destroying its EGL context. The
+ // application should be modified to either subclass before initializing the
+ // EGL context, or to unsubclass before destroying the EGL context.
+ if(parentWndFunc) {
+ LONG prevWndFunc = SetWindowLong(mWindow, GWL_WNDPROC, parentWndFunc);
+ ASSERT(prevWndFunc == reinterpret_cast<LONG>(SurfaceWindowProc));
+ }
+
+ RemoveProp(mWindow, kSurfaceProperty);
+ RemoveProp(mWindow, kParentWndProc);
+ mWindowSubclassed = false;
+}
+
+bool Surface::checkForOutOfDateSwapChain()
{
RECT client;
if (!GetClientRect(getWindowHandle(), &client))
@@ -319,10 +369,14 @@ bool Surface::checkForWindowResize()
return false;
}
- if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
- {
- resetSwapChain();
+ // Grow the buffer now, if the window has grown. We need to grow now to avoid losing information.
+ int clientWidth = client.right - client.left;
+ int clientHeight = client.bottom - client.top;
+ bool sizeDirty = clientWidth != getWidth() || clientHeight != getHeight();
+ if (sizeDirty || mPresentIntervalDirty)
+ {
+ resetSwapChain(clientWidth, clientHeight);
if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
{
glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
@@ -330,57 +384,51 @@ bool Surface::checkForWindowResize()
return true;
}
-
return false;
}
-bool Surface::swap()
+DWORD Surface::convertInterval(EGLint interval)
{
- if (mSwapChain)
+ switch(interval)
{
- IDirect3DTexture9 *flipTexture = mFlipTexture;
- flipTexture->AddRef();
-
- IDirect3DSurface9 *renderTarget = mRenderTarget;
- renderTarget->AddRef();
+ 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();
+ }
- EGLint oldWidth = mWidth;
- EGLint oldHeight = mHeight;
+ return D3DPRESENT_INTERVAL_DEFAULT;
+}
- checkForWindowResize();
+bool Surface::swap()
+{
+ if (mSwapChain)
+ {
IDirect3DDevice9 *device = mDisplay->getDevice();
- IDirect3DSurface9 *textureSurface;
- flipTexture->GetSurfaceLevel(0, &textureSurface);
-
- mDisplay->endScene();
- device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
- renderTarget->Release();
-
applyFlipState(device);
- device->SetTexture(0, flipTexture);
-
- float xscale = (float)mWidth / oldWidth;
- float yscale = (float)mHeight / oldHeight;
+ device->SetTexture(0, mFlipTexture);
// Render the texture upside down into the back buffer
- // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
- float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
- {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f },
- {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
- { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f-yscale}}; // x, y, z, rhw, u, v
+ // Texcoords are chosen to flip the renderTarget about its Y axis.
+ float w = static_cast<float>(getWidth());
+ float h = static_cast<float>(getHeight());
+ float quad[4][6] = {{0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
+ {w - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
+ {w - 0.5f, h - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
+ {0 - 0.5f, h - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
- flipTexture->Release();
- textureSurface->Release();
-
restoreState(device);
mDisplay->endScene();
- HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, mDisplay->getPresentInterval());
+
+ HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
{
@@ -394,6 +442,7 @@ bool Surface::swap()
ASSERT(SUCCEEDED(result));
+ checkForOutOfDateSwapChain();
}
return true;
@@ -411,12 +460,14 @@ EGLint Surface::getHeight() const
IDirect3DSurface9 *Surface::getRenderTarget()
{
- if (mRenderTarget)
+ IDirect3DSurface9 *textureSurface = NULL;
+
+ if (mFlipTexture)
{
- mRenderTarget->AddRef();
+ mFlipTexture->GetSurfaceLevel(0, &textureSurface);
}
- return mRenderTarget;
+ return textureSurface;
}
IDirect3DSurface9 *Surface::getDepthStencil()
@@ -428,4 +479,19 @@ IDirect3DSurface9 *Surface::getDepthStencil()
return mDepthStencil;
}
+
+void Surface::setSwapInterval(EGLint interval)
+{
+ if (mSwapInterval == interval)
+ {
+ return;
+ }
+
+ mSwapInterval = interval;
+ mSwapInterval = std::max(mSwapInterval, mDisplay->getMinSwapInterval());
+ mSwapInterval = std::min(mSwapInterval, mDisplay->getMaxSwapInterval());
+
+ mPresentInterval = convertInterval(mSwapInterval);
+ mPresentIntervalDirty = true;
+}
}
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
index 5bc912c..422d3d5 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
+++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h
@@ -29,6 +29,9 @@ class Surface
~Surface();
+ void release();
+ void resetSwapChain();
+
HWND getWindowHandle();
bool swap();
@@ -38,18 +41,22 @@ class Surface
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
- private:
+ void setSwapInterval(EGLint interval);
+ bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update
+
+private:
DISALLOW_COPY_AND_ASSIGN(Surface);
Display *const mDisplay;
IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
- IDirect3DSurface9 *mRenderTarget;
IDirect3DSurface9 *mDepthStencil;
IDirect3DTexture9 *mFlipTexture;
- void resetSwapChain();
- bool checkForWindowResize();
+ void subclassWindow();
+ void unsubclassWindow();
+ void resetSwapChain(int backbufferWidth, int backbufferHeight);
+ static DWORD convertInterval(EGLint interval);
void applyFlipState(IDirect3DDevice9 *device);
void restoreState(IDirect3DDevice9 *device);
@@ -61,6 +68,7 @@ class Surface
IDirect3DSurface9 *mPreFlipDepthStencil;
const HWND mWindow; // Window that the surface is created for.
+ bool mWindowSubclassed; // Indicates whether we successfully subclassed mWindow for WM_RESIZE hooking
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
EGLint mWidth; // Width of surface
@@ -77,6 +85,9 @@ class Surface
// EGLenum textureTarget; // Type of texture: 2D or no texture
// EGLenum vgAlphaFormat; // Alpha format for OpenVG
// EGLenum vgColorSpace; // Color space for OpenVG
+ EGLint mSwapInterval;
+ DWORD mPresentInterval;
+ bool mPresentIntervalDirty;
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
index 5ceb6ef..8dfe6e5 100644
--- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
+++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp
@@ -360,6 +360,8 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG
default:
return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
}
+
+ attrib_list += 2;
}
}
@@ -746,7 +748,14 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval)
return EGL_FALSE;
}
- display->setSwapInterval(interval);
+ egl::Surface *draw_surface = static_cast<egl::Surface*>(egl::getCurrentDrawSurface());
+
+ if (draw_surface == NULL)
+ {
+ return error(EGL_BAD_SURFACE, EGL_FALSE);
+ }
+
+ draw_surface->setSwapInterval(interval);
return success(EGL_TRUE);
}
@@ -765,6 +774,28 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
try
{
+ // Get the requested client version (default is 1) and check it is two.
+ EGLint client_version = 1;
+ if (attrib_list)
+ {
+ for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
+ {
+ if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION)
+ {
+ client_version = attribute[1];
+ }
+ else
+ {
+ return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT);
+ }
+ }
+ }
+
+ if (client_version != 2)
+ {
+ return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT);
+ }
+
egl::Display *display = static_cast<egl::Display*>(dpy);
if (!validate(display, config))
@@ -825,7 +856,7 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice();
- if (!device || device->TestCooperativeLevel() != D3D_OK)
+ if (!device || FAILED(device->TestCooperativeLevel()))
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
index 00c878f..43ed8a0 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp
@@ -382,6 +382,11 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect)
{
+ if (!surface)
+ {
+ return NULL;
+ }
+
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
@@ -408,14 +413,8 @@ IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const
return error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
}
- RECT d3dSourceRect;
- d3dSourceRect.left = sourceRect.left;
- d3dSourceRect.right = sourceRect.right;
- d3dSourceRect.top = sourceRect.top;
- d3dSourceRect.bottom = sourceRect.bottom;
-
display->endScene();
- result = device->StretchRect(surface, &d3dSourceRect, textureSurface, NULL, D3DTEXF_NONE);
+ result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
textureSurface->Release();
@@ -467,10 +466,8 @@ void Blit::setCommonBlitState()
device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
- for (int i = 0; i < MAX_VERTEX_ATTRIBS+1; i++)
- {
- device->SetStreamSourceFreq(i, 1);
- }
+ RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
+ device->SetScissorRect(&scissorRect);
}
void Blit::render()
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
index 43993e7..17cea6c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp
@@ -10,6 +10,10 @@
#include "libGLESv2/Buffer.h"
+#include "libGLESv2/main.h"
+#include "libGLESv2/geometry/VertexDataManager.h"
+#include "libGLESv2/geometry/IndexDataManager.h"
+
namespace gl
{
@@ -18,11 +22,16 @@ Buffer::Buffer(GLuint id) : RefCountObject(id)
mContents = NULL;
mSize = 0;
mUsage = GL_DYNAMIC_DRAW;
+
+ mVertexBuffer = NULL;
+ mIndexBuffer = NULL;
}
Buffer::~Buffer()
{
delete[] mContents;
+ delete mVertexBuffer;
+ delete mIndexBuffer;
}
void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
@@ -46,11 +55,52 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage)
mSize = size;
mUsage = usage;
+
+ invalidateStaticData();
+
+ if (usage == GL_STATIC_DRAW)
+ {
+ mVertexBuffer = new StaticVertexBuffer(getDevice());
+ mIndexBuffer = new StaticIndexBuffer(getDevice());
+ }
}
void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset)
{
memcpy(mContents + offset, data, size);
+
+ if ((mVertexBuffer && mVertexBuffer->size() != 0) || (mIndexBuffer && mIndexBuffer->size() != 0))
+ {
+ invalidateStaticData();
+
+ if (mUsage == GL_STATIC_DRAW)
+ {
+ // If applications update the buffer data after it has already been used in a draw call,
+ // it most likely isn't used as a static buffer so we should fall back to streaming usage
+ // for best performance. So ignore the usage hint and don't create new static buffers.
+ // mVertexBuffer = new StaticVertexBuffer(getDevice());
+ // mIndexBuffer = new StaticIndexBuffer(getDevice());
+ }
+ }
+}
+
+StaticVertexBuffer *Buffer::getVertexBuffer()
+{
+ return mVertexBuffer;
+}
+
+StaticIndexBuffer *Buffer::getIndexBuffer()
+{
+ return mIndexBuffer;
+}
+
+void Buffer::invalidateStaticData()
+{
+ delete mVertexBuffer;
+ mVertexBuffer = NULL;
+
+ delete mIndexBuffer;
+ mIndexBuffer = NULL;
}
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
index 5611cc9..c2ed60f 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h
@@ -22,6 +22,8 @@
namespace gl
{
+class StaticVertexBuffer;
+class StaticIndexBuffer;
class Buffer : public RefCountObject
{
@@ -37,12 +39,19 @@ class Buffer : public RefCountObject
size_t size() const { return mSize; }
GLenum usage() const { return mUsage; }
+ StaticVertexBuffer *getVertexBuffer();
+ StaticIndexBuffer *getIndexBuffer();
+ void invalidateStaticData();
+
private:
DISALLOW_COPY_AND_ASSIGN(Buffer);
GLubyte *mContents;
size_t mSize;
GLenum mUsage;
+
+ StaticVertexBuffer *mVertexBuffer;
+ StaticIndexBuffer *mIndexBuffer;
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
index 48ef8fc..9be59c4 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp
@@ -19,15 +19,14 @@
#include "libGLESv2/Blit.h"
#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Fence.h"
#include "libGLESv2/FrameBuffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/RenderBuffer.h"
#include "libGLESv2/Shader.h"
#include "libGLESv2/Texture.h"
-#include "libGLESv2/geometry/backend.h"
#include "libGLESv2/geometry/VertexDataManager.h"
#include "libGLESv2/geometry/IndexDataManager.h"
-#include "libGLESv2/geometry/dx9.h"
#undef near
#undef far
@@ -83,6 +82,7 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
mState.scissorTest = false;
mState.dither = true;
mState.generateMipmapHint = GL_DONT_CARE;
+ mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
mState.lineWidth = 1.0f;
@@ -120,11 +120,8 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero = new Texture2D(0);
- mTextureCubeMapZero = new TextureCubeMap(0);
-
- mColorbufferZero = NULL;
- mDepthStencilbufferZero = NULL;
+ mTexture2DZero.set(new Texture2D(0));
+ mTextureCubeMapZero.set(new TextureCubeMap(0));
mState.activeSampler = 0;
bindArrayBuffer(0);
@@ -135,17 +132,11 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
bindDrawFramebuffer(0);
bindRenderbuffer(0);
- for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
- {
- mIncompleteTextures[type] = NULL;
- }
-
mState.currentProgram = 0;
mState.packAlignment = 4;
mState.unpackAlignment = 4;
- mBufferBackEnd = NULL;
mVertexDataManager = NULL;
mIndexDataManager = NULL;
mBlit = NULL;
@@ -158,6 +149,8 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext)
mHasBeenCurrent = false;
+ mSupportsCompressedTextures = false;
+ mSupportsEventQueries = false;
mMaxSupportedSamples = 0;
mMaskedClearSavedState = NULL;
markAllStateDirty();
@@ -180,6 +173,11 @@ Context::~Context()
deleteFramebuffer(mFramebufferMap.begin()->first);
}
+ while (!mFenceMap.empty())
+ {
+ deleteFence(mFenceMap.begin()->first);
+ }
+
while (!mMultiSampleSupport.empty())
{
delete [] mMultiSampleSupport.begin()->second;
@@ -196,7 +194,7 @@ Context::~Context()
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- delete mIncompleteTextures[type];
+ mIncompleteTextures[type].set(NULL);
}
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
@@ -206,14 +204,11 @@ Context::~Context()
mState.arrayBuffer.set(NULL);
mState.elementArrayBuffer.set(NULL);
- mState.texture2D.set(NULL);
- mState.textureCubeMap.set(NULL);
mState.renderbuffer.set(NULL);
- delete mTexture2DZero;
- delete mTextureCubeMapZero;
+ mTexture2DZero.set(NULL);
+ mTextureCubeMapZero.set(NULL);
- delete mBufferBackEnd;
delete mVertexDataManager;
delete mIndexDataManager;
delete mBlit;
@@ -234,11 +229,20 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
{
mDeviceCaps = display->getDeviceCaps();
- mBufferBackEnd = new Dx9BackEnd(this, device);
- mVertexDataManager = new VertexDataManager(this, mBufferBackEnd);
- mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
+ mVertexDataManager = new VertexDataManager(this, device);
+ mIndexDataManager = new IndexDataManager(this, device);
mBlit = new Blit(this);
+ mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
+
+ mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight),
+ (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
+ mMaxCubeTextureDimension = std::min(mMaxTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
+ mMaxRenderbufferDimension = mMaxTextureDimension;
+ mMaxTextureLevel = log2(mMaxTextureDimension) + 1;
+ TRACE("MaxTextureDimension=%d, MaxCubeTextureDimension=%d, MaxRenderbufferDimension=%d, MaxTextureLevel=%d",
+ mMaxTextureDimension, mMaxCubeTextureDimension, mMaxRenderbufferDimension, mMaxTextureLevel);
+
const D3DFORMAT renderBufferFormats[] =
{
D3DFMT_A8R8G8B8,
@@ -265,7 +269,14 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mMaxSupportedSamples = max;
+ mSupportsEventQueries = display->getEventQuerySupport();
mSupportsCompressedTextures = display->getCompressedTextureSupport();
+ mSupportsFloatTextures = display->getFloatTextureSupport(&mSupportsFloatLinearFilter, &mSupportsFloatRenderableTextures);
+ mSupportsHalfFloatTextures = display->getHalfFloatTextureSupport(&mSupportsHalfFloatLinearFilter, &mSupportsHalfFloatRenderableTextures);
+ mSupportsLuminanceTextures = display->getLuminanceTextureSupport();
+ mSupportsLuminanceAlphaTextures = display->getLuminanceAlphaTextureSupport();
+
+ mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16);
initExtensionString();
@@ -292,15 +303,16 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
setFramebufferZero(framebufferZero);
- defaultRenderTarget->Release();
+ if (defaultRenderTarget)
+ {
+ defaultRenderTarget->Release();
+ }
if (depthStencil)
{
depthStencil->Release();
}
- mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
-
markAllStateDirty();
}
@@ -309,6 +321,8 @@ void Context::markAllStateDirty()
{
mAppliedRenderTargetSerial = 0;
mAppliedDepthbufferSerial = 0;
+ mAppliedStencilbufferSerial = 0;
+ mDepthStencilInitialized = false;
mAppliedProgram = 0;
mClearStateDirty = true;
@@ -322,11 +336,6 @@ void Context::markAllStateDirty()
mSampleStateDirty = true;
mDitherStateDirty = true;
mFrontFaceDirty = true;
-
- if (mBufferBackEnd != NULL)
- {
- mBufferBackEnd->invalidate();
- }
}
void Context::setClearColor(float red, float green, float blue, float alpha)
@@ -650,6 +659,14 @@ void Context::setGenerateMipmapHint(GLenum hint)
mState.generateMipmapHint = hint;
}
+void Context::setFragmentShaderDerivativeHint(GLenum hint)
+{
+ mState.fragmentShaderDerivativeHint = hint;
+ // TODO: Propagate the hint to shader translator so we can write
+ // ddx, ddx_coarse, or ddx_fine depending on the hint.
+ // Ignore for now. It is valid for implementations to ignore hint.
+}
+
void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
{
mState.viewportX = x;
@@ -718,12 +735,12 @@ GLuint Context::getArrayBufferHandle() const
return mState.arrayBuffer.id();
}
-void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
+void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
{
- mState.vertexAttribute[attribNum].mEnabled = enabled;
+ mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
}
-const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
+const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
{
return mState.vertexAttribute[attribNum];
}
@@ -744,8 +761,7 @@ const void *Context::getVertexAttribPointer(unsigned int attribNum) const
return mState.vertexAttribute[attribNum].mPointer;
}
-// returns entire set of attributes as a block
-const AttributeState *Context::getVertexAttribBlock()
+const VertexAttributeArray &Context::getVertexAttributes()
{
return mState.vertexAttribute;
}
@@ -810,6 +826,20 @@ GLuint Context::createFramebuffer()
return handle;
}
+GLuint Context::createFence()
+{
+ unsigned int handle = 0;
+
+ while (mFenceMap.find(handle) != mFenceMap.end())
+ {
+ handle++;
+ }
+
+ mFenceMap[handle] = new Fence;
+
+ return handle;
+}
+
void Context::deleteBuffer(GLuint buffer)
{
if (mResourceManager->getBuffer(buffer))
@@ -863,6 +893,17 @@ void Context::deleteFramebuffer(GLuint framebuffer)
}
}
+void Context::deleteFence(GLuint fence)
+{
+ FenceMap::iterator fenceObject = mFenceMap.find(fence);
+
+ if (fenceObject != mFenceMap.end())
+ {
+ delete fenceObject->second;
+ mFenceMap.erase(fenceObject);
+ }
+}
+
Buffer *Context::getBuffer(GLuint handle)
{
return mResourceManager->getBuffer(handle);
@@ -916,18 +957,14 @@ void Context::bindTexture2D(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
- mState.texture2D.set(getTexture(texture));
-
- mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(mState.texture2D.get());
+ mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(getTexture(texture));
}
void Context::bindTextureCubeMap(GLuint texture)
{
mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
- mState.textureCubeMap.set(getTexture(texture));
-
- mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(mState.textureCubeMap.get());
+ mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(getTexture(texture));
}
void Context::bindReadFramebuffer(GLuint framebuffer)
@@ -1005,6 +1042,20 @@ Framebuffer *Context::getFramebuffer(unsigned int handle)
}
}
+Fence *Context::getFence(unsigned int handle)
+{
+ FenceMap::iterator fence = mFenceMap.find(handle);
+
+ if (fence == mFenceMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return fence->second;
+ }
+}
+
Buffer *Context::getArrayBuffer()
{
return mState.arrayBuffer.get();
@@ -1022,35 +1073,25 @@ Program *Context::getCurrentProgram()
Texture2D *Context::getTexture2D()
{
- if (mState.texture2D.id() == 0) // Special case: 0 refers to different initial textures based on the target
- {
- return mTexture2DZero;
- }
-
- return static_cast<Texture2D*>(mState.texture2D.get());
+ return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, SAMPLER_2D));
}
TextureCubeMap *Context::getTextureCubeMap()
{
- if (mState.textureCubeMap.id() == 0) // Special case: 0 refers to different initial textures based on the target
- {
- return mTextureCubeMapZero;
- }
-
- return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
+ return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, SAMPLER_CUBE));
}
Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
{
GLuint texid = mState.samplerTexture[type][sampler].id();
- if (texid == 0)
+ if (texid == 0) // Special case: 0 refers to different initial textures based on the target
{
switch (type)
{
default: UNREACHABLE();
- case SAMPLER_2D: return mTexture2DZero;
- case SAMPLER_CUBE: return mTextureCubeMapZero;
+ case SAMPLER_2D: return mTexture2DZero.get();
+ case SAMPLER_CUBE: return mTextureCubeMapZero.get();
}
}
@@ -1070,15 +1111,15 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params)
params[2] = mState.colorMaskBlue;
params[3] = mState.colorMaskAlpha;
break;
- case GL_CULL_FACE: *params = mState.cullFace;
- case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill;
- case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage;
- case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage;
- case GL_SCISSOR_TEST: *params = mState.scissorTest;
- case GL_STENCIL_TEST: *params = mState.stencilTest;
- case GL_DEPTH_TEST: *params = mState.depthTest;
- case GL_BLEND: *params = mState.blend;
- case GL_DITHER: *params = mState.dither;
+ 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;
default:
return false;
}
@@ -1141,24 +1182,25 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
{
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 = gl::MAX_VARYING_VECTORS; break;
+ case GL_MAX_VARYING_VECTORS: *params = getMaximumVaryingVectors(); break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS; break;
case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break;
- case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS; break;
- case GL_MAX_RENDERBUFFER_SIZE: *params = gl::MAX_RENDERBUFFER_SIZE; break;
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = getMaximumFragmentUniformVectors(); break;
+ case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); 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;
case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break;
- //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
- case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
- case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
+ //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+ case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
+ case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
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;
@@ -1183,8 +1225,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break;
case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break;
case GL_SUBPIXEL_BITS: *params = 4; break;
- case GL_MAX_TEXTURE_SIZE: *params = gl::MAX_TEXTURE_SIZE; break;
- case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE; break;
+ case GL_MAX_TEXTURE_SIZE: *params = getMaximumTextureDimension(); break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = getMaximumCubeTextureDimension(); break;
case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
{
if (supportsCompressedTextures())
@@ -1246,7 +1288,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
case GL_MAX_VIEWPORT_DIMS:
{
- int maxDimension = std::max((int)gl::MAX_RENDERBUFFER_SIZE, (int)gl::MAX_TEXTURE_SIZE);
+ int maxDimension = std::max(getMaximumRenderbufferDimension(), getMaximumTextureDimension());
params[0] = maxDimension;
params[1] = maxDimension;
}
@@ -1392,6 +1434,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
case GL_PACK_ALIGNMENT:
case GL_UNPACK_ALIGNMENT:
case GL_GENERATE_MIPMAP_HINT:
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
case GL_RED_BITS:
case GL_GREEN_BITS:
case GL_BLUE_BITS:
@@ -1535,6 +1578,12 @@ bool Context::applyRenderTarget(bool ignoreViewport)
}
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
+
+ if (!renderTarget)
+ {
+ return false; // Context must be lost
+ }
+
IDirect3DSurface9 *depthStencil = NULL;
unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
@@ -1550,26 +1599,43 @@ bool Context::applyRenderTarget(bool ignoreViewport)
if (framebufferObject->getDepthbufferType() != GL_NONE)
{
depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ return false;
+ }
+
depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
}
else if (framebufferObject->getStencilbufferType() != GL_NONE)
{
depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ return false;
+ }
+
stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
}
if (depthbufferSerial != mAppliedDepthbufferSerial ||
- stencilbufferSerial != mAppliedStencilbufferSerial)
+ stencilbufferSerial != mAppliedStencilbufferSerial ||
+ !mDepthStencilInitialized)
{
device->SetDepthStencilSurface(depthStencil);
mAppliedDepthbufferSerial = depthbufferSerial;
mAppliedStencilbufferSerial = stencilbufferSerial;
+ mDepthStencilInitialized = true;
}
D3DVIEWPORT9 viewport;
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
+ float zNear = clamp01(mState.zNear);
+ float zFar = clamp01(mState.zFar);
+
if (ignoreViewport)
{
viewport.X = 0;
@@ -1585,8 +1651,8 @@ bool Context::applyRenderTarget(bool ignoreViewport)
viewport.Y = std::max(mState.viewportY, 0);
viewport.Width = std::min(mState.viewportWidth, (int)desc.Width - (int)viewport.X);
viewport.Height = std::min(mState.viewportHeight, (int)desc.Height - (int)viewport.Y);
- viewport.MinZ = clamp01(mState.zNear);
- viewport.MaxZ = clamp01(mState.zFar);
+ viewport.MinZ = zNear;
+ viewport.MaxZ = zFar;
}
if (viewport.Width <= 0 || viewport.Height <= 0)
@@ -1623,27 +1689,21 @@ bool Context::applyRenderTarget(bool ignoreViewport)
GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation();
GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height};
- programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
+ programObject->setUniform2fv(halfPixelSize, 1, xy);
- GLint window = programObject->getDxViewportLocation();
+ GLint viewport = programObject->getDxViewportLocation();
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};
- programObject->setUniform4fv(window, 1, (GLfloat*)&whxy);
+ programObject->setUniform4fv(viewport, 1, whxy);
GLint depth = programObject->getDxDepthLocation();
- GLfloat dz[2] = {(mState.zFar - mState.zNear) / 2.0f, (mState.zNear + mState.zFar) / 2.0f};
- programObject->setUniform2fv(depth, 1, (GLfloat*)&dz);
+ GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f};
+ programObject->setUniform2fv(depth, 1, dz);
- GLint near = programObject->getDepthRangeNearLocation();
- programObject->setUniform1fv(near, 1, &mState.zNear);
-
- GLint far = programObject->getDepthRangeFarLocation();
- programObject->setUniform1fv(far, 1, &mState.zFar);
-
- GLint diff = programObject->getDepthRangeDiffLocation();
- GLfloat zDiff = mState.zFar - mState.zNear;
- programObject->setUniform1fv(diff, 1, &zDiff);
+ GLint depthRange = programObject->getDxDepthRangeLocation();
+ GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
+ programObject->setUniform3fv(depthRange, 1, nearFarDiff);
}
return true;
@@ -1830,39 +1890,46 @@ void Context::applyState(GLenum drawMode)
mPolygonOffsetStateDirty = false;
}
- if (framebufferObject->isMultisample() && mSampleStateDirty)
+ if (mSampleStateDirty)
{
- if (mState.sampleAlphaToCoverage)
+ if (framebufferObject->isMultisample())
{
- FIXME("Sample alpha to coverage is unimplemented.");
- }
+ if (mState.sampleAlphaToCoverage)
+ {
+ FIXME("Sample alpha to coverage is unimplemented.");
+ }
- if (mState.sampleCoverage)
- {
device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
- unsigned int mask = 0;
- if (mState.sampleCoverageValue != 0)
+ if (mState.sampleCoverage)
{
- float threshold = 0.5f;
-
- for (int i = 0; i < framebufferObject->getSamples(); ++i)
+ unsigned int mask = 0;
+ if (mState.sampleCoverageValue != 0)
{
- mask <<= 1;
+ float threshold = 0.5f;
- if ((i + 1) * mState.sampleCoverageValue >= threshold)
+ for (int i = 0; i < framebufferObject->getSamples(); ++i)
{
- threshold += 1.0f;
- mask |= 1;
+ mask <<= 1;
+
+ if ((i + 1) * mState.sampleCoverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
}
}
+
+ if (mState.sampleCoverageInvert)
+ {
+ mask = ~mask;
+ }
+
+ device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
}
-
- if (mState.sampleCoverageInvert)
+ else
{
- mask = ~mask;
+ device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
}
-
- device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
}
else
{
@@ -1887,18 +1954,18 @@ void Context::lookupAttributeMapping(TranslatedAttribute *attributes)
{
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- if (attributes[i].enabled)
+ if (attributes[i].active)
{
attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i);
}
}
}
-GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo)
+GLenum Context::applyVertexBuffer(GLint first, GLsizei count)
{
TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
- GLenum err = mVertexDataManager->preRenderValidate(first, count, translated);
+ GLenum err = mVertexDataManager->prepareVertexData(first, count, translated);
if (err != GL_NO_ERROR)
{
return err;
@@ -1906,53 +1973,20 @@ GLenum Context::applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool
lookupAttributeMapping(translated);
- mBufferBackEnd->setupAttributesPreDraw(translated);
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (translated[i].enabled && translated[i].nonArray)
- {
- err = mIndexDataManager->preRenderValidateUnindexed(mode, count, indexInfo);
- if (err != GL_NO_ERROR)
- {
- return err;
- }
+ mVertexDataManager->setupAttributes(translated);
- mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
-
- *useIndexing = true;
- return GL_NO_ERROR;
- }
- }
-
- *useIndexing = false;
return GL_NO_ERROR;
}
-GLenum Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
-{
- TranslatedAttribute translated[MAX_VERTEX_ATTRIBS];
-
- GLenum err = mVertexDataManager->preRenderValidate(indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, translated);
-
- if (err == GL_NO_ERROR)
- {
- lookupAttributeMapping(translated);
-
- mBufferBackEnd->setupAttributesPreDraw(translated);
- }
-
- return err;
-}
-
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
- GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
+ IDirect3DDevice9 *device = getDevice();
+ GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
if (err == GL_NO_ERROR)
{
- mBufferBackEnd->setupIndicesPreDraw(*indexInfo);
+ device->SetIndices(indexInfo->indexBuffer);
}
return err;
@@ -2048,6 +2082,12 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
}
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
+
+ if (!renderTarget)
+ {
+ return; // Context must be lost, return silently
+ }
+
IDirect3DDevice9 *device = getDevice();
D3DSURFACE_DESC desc;
@@ -2141,16 +2181,6 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
r = (rgb & 0xF800) * (1.0f / 0xF800);
}
break;
- case D3DFMT_X1R5G5B5:
- {
- unsigned short xrgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);
-
- a = 1.0f;
- b = (xrgb & 0x001F) * (1.0f / 0x001F);
- g = (xrgb & 0x03E0) * (1.0f / 0x03E0);
- r = (xrgb & 0x7C00) * (1.0f / 0x7C00);
- }
- break;
case D3DFMT_A1R5G5B5:
{
unsigned short argb = *(unsigned short*)(source + 2 * i + j * lock.Pitch);
@@ -2191,6 +2221,28 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
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 * lock.Pitch) + 0);
+ g = *((float*)(source + 16 * i + j * lock.Pitch) + 1);
+ b = *((float*)(source + 16 * i + j * lock.Pitch) + 2);
+ a = *((float*)(source + 16 * i + j * lock.Pitch) + 3);
+ }
+ break;
+ case D3DFMT_A16B16G16R16F:
+ {
+ // float formats in D3D are stored rgba, rather than the other way round
+ float abgr[4];
+
+ D3DXFloat16To32Array(abgr, (D3DXFLOAT16*)(source + 8 * i + j * lock.Pitch), 4);
+
+ a = abgr[3];
+ b = abgr[2];
+ g = abgr[1];
+ r = abgr[0];
+ }
+ break;
default:
UNIMPLEMENTED(); // FIXME
UNREACHABLE();
@@ -2314,6 +2366,12 @@ void Context::clear(GLbitfield mask)
if (framebufferObject->getStencilbufferType() != GL_NONE)
{
IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ if (!depthStencil)
+ {
+ ERR("Depth stencil pointer unexpectedly null.");
+ return;
+ }
+
D3DSURFACE_DESC desc;
depthStencil->GetDesc(&desc);
@@ -2346,6 +2404,11 @@ void Context::clear(GLbitfield mask)
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
+ if (!renderTarget)
+ {
+ return; // Context must be lost, return silently
+ }
+
D3DSURFACE_DESC desc;
renderTarget->GetDesc(&desc);
@@ -2381,7 +2444,7 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
- device->SetStreamSourceFreq(0, 1);
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
hr = device->EndStateBlock(&mMaskedClearSavedState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -2436,7 +2499,7 @@ void Context::clear(GLbitfield mask)
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
- device->SetStreamSourceFreq(0, 1);
+ device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
struct Vertex
{
@@ -2517,9 +2580,7 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
applyState(mode);
- TranslatedIndexData indexInfo;
- bool useIndexing;
- GLenum err = applyVertexBuffer(mode, first, count, &useIndexing, &indexInfo);
+ GLenum err = applyVertexBuffer(first, count);
if (err != GL_NO_ERROR)
{
return error(err);
@@ -2536,18 +2597,17 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
if (!cullSkipsDraw(mode))
{
display->startScene();
- if (useIndexing)
- {
- device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
- }
- else
+
+ device->DrawPrimitive(primitiveType, 0, primitiveCount);
+
+ if (mode == GL_LINE_LOOP) // Draw the last segment separately
{
- device->DrawPrimitive(primitiveType, 0, primitiveCount);
+ drawClosingLine(first, first + count - 1);
}
}
}
-void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices)
+void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
{
if (!mState.currentProgram)
{
@@ -2586,7 +2646,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
return error(err);
}
- err = applyVertexBuffer(indexInfo);
+ GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+ err = applyVertexBuffer(indexInfo.minIndex, vertexCount);
if (err != GL_NO_ERROR)
{
return error(err);
@@ -2603,7 +2664,13 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void*
if (!cullSkipsDraw(mode))
{
display->startScene();
- device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, indexInfo.maxIndex-indexInfo.minIndex+1, indexInfo.offset/indexInfo.indexSize, primitiveCount);
+
+ device->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount);
+
+ if (mode == GL_LINE_LOOP) // Draw the last segment separately
+ {
+ drawClosingLine(count, type, indices);
+ }
}
}
@@ -2631,7 +2698,6 @@ void Context::finish()
ASSERT(SUCCEEDED(result));
// Render something outside the render target
- device->SetStreamSourceFreq(0, 1);
device->SetPixelShader(NULL);
device->SetVertexShader(NULL);
device->SetFVF(D3DFVF_XYZRHW);
@@ -2687,6 +2753,93 @@ void Context::flush()
}
}
+void Context::drawClosingLine(unsigned int first, unsigned int last)
+{
+ IDirect3DDevice9 *device = getDevice();
+ IDirect3DIndexBuffer9 *indexBuffer = NULL;
+ HRESULT result = D3DERR_INVALIDCALL;
+
+ if (supports32bitIndices())
+ {
+ result = device->CreateIndexBuffer(8, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &indexBuffer, 0);
+
+ if (SUCCEEDED(result))
+ {
+ unsigned int *data;
+ result = indexBuffer->Lock(0, 0, (void**)&data, 0);
+
+ if (SUCCEEDED(result))
+ {
+ data[0] = last;
+ data[1] = first;
+ }
+ }
+ }
+ else
+ {
+ result = device->CreateIndexBuffer(4, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, 0);
+
+ if (SUCCEEDED(result))
+ {
+ unsigned short *data;
+ result = indexBuffer->Lock(0, 0, (void**)&data, 0);
+
+ if (SUCCEEDED(result))
+ {
+ data[0] = last;
+ data[1] = first;
+ }
+ }
+ }
+
+ if (SUCCEEDED(result))
+ {
+ indexBuffer->Unlock();
+ device->SetIndices(indexBuffer);
+
+ device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, 2, 0, 1);
+
+ indexBuffer->Release();
+ }
+ else
+ {
+ ERR("Could not create an index buffer for closing a line loop.");
+ error(GL_OUT_OF_MEMORY);
+ }
+}
+
+void Context::drawClosingLine(GLsizei count, GLenum type, const void *indices)
+{
+ unsigned int first = 0;
+ unsigned int last = 0;
+
+ if (mState.elementArrayBuffer.get())
+ {
+ Buffer *indexBuffer = mState.elementArrayBuffer.get();
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset;
+ }
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ first = static_cast<const GLubyte*>(indices)[0];
+ last = static_cast<const GLubyte*>(indices)[count - 1];
+ break;
+ case GL_UNSIGNED_SHORT:
+ first = static_cast<const GLushort*>(indices)[0];
+ last = static_cast<const GLushort*>(indices)[count - 1];
+ break;
+ case GL_UNSIGNED_INT:
+ first = static_cast<const GLuint*>(indices)[0];
+ last = static_cast<const GLuint*>(indices)[count - 1];
+ break;
+ default: UNREACHABLE();
+ }
+
+ drawClosingLine(first, last);
+}
+
void Context::recordInvalidEnum()
{
mInvalidEnum = true;
@@ -2759,6 +2912,16 @@ bool Context::supportsShaderModel3() const
return mSupportsShaderModel3;
}
+int Context::getMaximumVaryingVectors() const
+{
+ return mSupportsShaderModel3 ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
+}
+
+int Context::getMaximumFragmentUniformVectors() const
+{
+ return mSupportsShaderModel3 ? MAX_FRAGMENT_UNIFORM_VECTORS_SM3 : MAX_FRAGMENT_UNIFORM_VECTORS_SM2;
+}
+
int Context::getMaxSupportedSamples() const
{
return mMaxSupportedSamples;
@@ -2788,11 +2951,81 @@ int Context::getNearestSupportedSamples(D3DFORMAT format, int requested) const
return -1;
}
+bool Context::supportsEventQueries() const
+{
+ return mSupportsEventQueries;
+}
+
bool Context::supportsCompressedTextures() const
{
return mSupportsCompressedTextures;
}
+bool Context::supportsFloatTextures() const
+{
+ return mSupportsFloatTextures;
+}
+
+bool Context::supportsFloatLinearFilter() const
+{
+ return mSupportsFloatLinearFilter;
+}
+
+bool Context::supportsFloatRenderableTextures() const
+{
+ return mSupportsFloatRenderableTextures;
+}
+
+bool Context::supportsHalfFloatTextures() const
+{
+ return mSupportsHalfFloatTextures;
+}
+
+bool Context::supportsHalfFloatLinearFilter() const
+{
+ return mSupportsHalfFloatLinearFilter;
+}
+
+bool Context::supportsHalfFloatRenderableTextures() const
+{
+ return mSupportsHalfFloatRenderableTextures;
+}
+
+int Context::getMaximumRenderbufferDimension() const
+{
+ return mMaxRenderbufferDimension;
+}
+
+int Context::getMaximumTextureDimension() const
+{
+ return mMaxTextureDimension;
+}
+
+int Context::getMaximumCubeTextureDimension() const
+{
+ return mMaxCubeTextureDimension;
+}
+
+int Context::getMaximumTextureLevel() const
+{
+ return mMaxTextureLevel;
+}
+
+bool Context::supportsLuminanceTextures() const
+{
+ return mSupportsLuminanceTextures;
+}
+
+bool Context::supportsLuminanceAlphaTextures() const
+{
+ return mSupportsLuminanceAlphaTextures;
+}
+
+bool Context::supports32bitIndices() const
+{
+ return mSupports32bitIndices;
+}
+
void Context::detachBuffer(GLuint buffer)
{
// [OpenGL ES 2.0.24] section 2.9 page 22:
@@ -2903,7 +3136,7 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
Texture *Context::getIncompleteTexture(SamplerType type)
{
- Texture *t = mIncompleteTextures[type];
+ Texture *t = mIncompleteTextures[type].get();
if (t == NULL)
{
@@ -2939,7 +3172,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
break;
}
- mIncompleteTextures[type] = t;
+ mIncompleteTextures[type].set(t);
}
return t;
@@ -2978,7 +3211,7 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
mState.vertexAttribute[index].mCurrentValue[2] = values[2];
mState.vertexAttribute[index].mCurrentValue[3] = values[3];
- mVertexDataManager->dirtyCurrentValues();
+ mVertexDataManager->dirtyCurrentValue(index);
}
void Context::initExtensionString()
@@ -2988,18 +3221,44 @@ void Context::initExtensionString()
mExtensionString += "GL_EXT_read_format_bgra ";
mExtensionString += "GL_ANGLE_framebuffer_blit ";
mExtensionString += "GL_OES_rgb8_rgba8 ";
+ mExtensionString += "GL_OES_standard_derivatives ";
+
+ if (supportsEventQueries())
+ {
+ mExtensionString += "GL_NV_fence ";
+ }
if (supportsCompressedTextures())
{
mExtensionString += "GL_EXT_texture_compression_dxt1 ";
}
+ if (supportsFloatTextures())
+ {
+ mExtensionString += "GL_OES_texture_float ";
+ }
+
+ if (supportsHalfFloatTextures())
+ {
+ mExtensionString += "GL_OES_texture_half_float ";
+ }
+
+ if (supportsFloatLinearFilter())
+ {
+ mExtensionString += "GL_OES_texture_float_linear ";
+ }
+
+ if (supportsHalfFloatLinearFilter())
+ {
+ mExtensionString += "GL_OES_texture_half_float_linear ";
+ }
+
if (getMaxSupportedSamples() != 0)
{
mExtensionString += "GL_ANGLE_framebuffer_multisample ";
}
- if (mBufferBackEnd->supportIntIndices())
+ if (supports32bitIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
}
@@ -3178,10 +3437,10 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
}
bool partialBufferCopy = false;
- if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readFramebuffer->getColorbuffer()->getHeight() ||
- sourceTrimmedRect.right - sourceTrimmedRect.left < readFramebuffer->getColorbuffer()->getWidth() ||
- destTrimmedRect.bottom - destTrimmedRect.top < drawFramebuffer->getColorbuffer()->getHeight() ||
- destTrimmedRect.right - destTrimmedRect.left < drawFramebuffer->getColorbuffer()->getWidth() ||
+ 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)
{
partialBufferCopy = true;
@@ -3189,7 +3448,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1
if (mask & GL_COLOR_BUFFER_BIT)
{
- if (readFramebuffer->getColorbufferType() != drawFramebuffer->getColorbufferType() ||
+ 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())
{
ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
index 6bca756..2906664 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h
@@ -12,6 +12,7 @@
#define GL_APICALL
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#define EGLAPI
#include <EGL/egl.h>
#include <d3d9.h>
@@ -49,19 +50,20 @@ class Stencilbuffer;
class DepthStencilbuffer;
class VertexDataManager;
class IndexDataManager;
-class BufferBackEnd;
class Blit;
+class Fence;
enum
{
- MAX_VERTEX_ATTRIBS = 12,
- MAX_VERTEX_UNIFORM_VECTORS = 128,
- MAX_VARYING_VECTORS = 8,
+ MAX_VERTEX_ATTRIBS = 16,
+ MAX_VERTEX_UNIFORM_VECTORS = 256 - 2, // 256 is the minimum for SM2, and in practice the maximum for DX9. Reserve space for dx_HalfPixelSize and dx_DepthRange.
+ MAX_VARYING_VECTORS_SM2 = 8,
+ MAX_VARYING_VECTORS_SM3 = 10,
MAX_COMBINED_TEXTURE_IMAGE_UNITS = 16,
MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0,
MAX_TEXTURE_IMAGE_UNITS = 16,
- MAX_FRAGMENT_UNIFORM_VECTORS = 16,
- MAX_RENDERBUFFER_SIZE = 4096, // FIXME: Verify
+ MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3, // Reserve space for dx_Viewport, 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,
IMPLEMENTATION_COLOR_READ_FORMAT = GL_RGB,
@@ -83,32 +85,56 @@ struct Color
};
// Helper structure describing a single vertex attribute
-class AttributeState
+class VertexAttribute
{
public:
- AttributeState()
- : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
+ VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false)
{
- mCurrentValue[0] = 0;
- mCurrentValue[1] = 0;
- mCurrentValue[2] = 0;
- mCurrentValue[3] = 1;
+ mCurrentValue[0] = 0.0f;
+ mCurrentValue[1] = 0.0f;
+ mCurrentValue[2] = 0.0f;
+ mCurrentValue[3] = 1.0f;
}
- // From VertexArrayPointer
+ int typeSize() const
+ {
+ switch (mType)
+ {
+ case GL_BYTE: return mSize * sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte);
+ case GL_SHORT: return mSize * sizeof(GLshort);
+ case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort);
+ case GL_FIXED: return mSize * sizeof(GLfixed);
+ case GL_FLOAT: return mSize * sizeof(GLfloat);
+ default: UNREACHABLE(); return mSize * sizeof(GLfloat);
+ }
+ }
+
+ GLsizei stride() const
+ {
+ return mStride ? mStride : typeSize();
+ }
+
+ // From glVertexAttribPointer
GLenum mType;
GLint mSize;
bool mNormalized;
- GLsizei mStride; // 0 means natural stride
- const void *mPointer;
+ GLsizei mStride; // 0 means natural stride
- BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
+ union
+ {
+ const void *mPointer;
+ intptr_t mOffset;
+ };
- bool mEnabled; // From Enable/DisableVertexAttribArray
+ BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called.
- float mCurrentValue[4]; // From VertexAttrib4f
+ bool mArrayEnabled; // From glEnable/DisableVertexAttribArray
+ float mCurrentValue[4]; // From glVertexAttrib
};
+typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS];
+
// Helper structure to store all raw state
struct State
{
@@ -157,6 +183,7 @@ struct State
GLfloat lineWidth;
GLenum generateMipmapHint;
+ GLenum fragmentShaderDerivativeHint;
GLint viewportX;
GLint viewportY;
@@ -179,14 +206,12 @@ struct State
int activeSampler; // Active texture unit selector - GL_TEXTURE0
BindingPointer<Buffer> arrayBuffer;
BindingPointer<Buffer> elementArrayBuffer;
- BindingPointer<Texture> texture2D;
- BindingPointer<Texture> textureCubeMap;
GLuint readFramebuffer;
GLuint drawFramebuffer;
BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
- AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
+ VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS];
BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment;
@@ -264,6 +289,7 @@ class Context
void setLineWidth(GLfloat width);
void setGenerateMipmapHint(GLenum hint);
+ void setFragmentShaderDerivativeHint(GLenum hint);
void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
@@ -280,13 +306,13 @@ class Context
GLuint getArrayBufferHandle() const;
- void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
- const AttributeState &getVertexAttribState(unsigned int attribNum);
+ void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
+ const VertexAttribute &getVertexAttribState(unsigned int attribNum);
void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
- const AttributeState *getVertexAttribBlock();
+ const VertexAttributeArray &getVertexAttributes();
void setUnpackAlignment(GLint alignment);
GLint getUnpackAlignment() const;
@@ -312,6 +338,10 @@ class Context
GLuint createFramebuffer();
void deleteFramebuffer(GLuint framebuffer);
+ // Fences are owned by the Context.
+ GLuint createFence();
+ void deleteFence(GLuint fence);
+
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
@@ -328,6 +358,7 @@ class Context
void setVertexAttrib(GLuint index, const GLfloat *values);
Buffer *getBuffer(GLuint handle);
+ Fence *getFence(GLuint handle);
Shader *getShader(GLuint handle);
Program *getProgram(GLuint handle);
Texture *getTexture(GLuint handle);
@@ -351,20 +382,22 @@ class Context
bool applyRenderTarget(bool ignoreViewport);
void applyState(GLenum drawMode);
- GLenum applyVertexBuffer(GLenum mode, GLint first, GLsizei count, bool *useIndexing, TranslatedIndexData *indexInfo);
- GLenum applyVertexBuffer(const TranslatedIndexData &indexInfo);
+ GLenum applyVertexBuffer(GLint first, GLsizei count);
GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
- GLenum applyCountingIndexBuffer(GLenum mode, GLenum count, TranslatedIndexData *indexInfo);
void applyShaders();
void applyTextures();
void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
void clear(GLbitfield mask);
void drawArrays(GLenum mode, GLint first, GLsizei count);
- void drawElements(GLenum mode, GLsizei count, GLenum type, const void* indices);
+ void drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices);
void finish();
void flush();
+ // Draw the last segment of a line loop
+ void drawClosingLine(unsigned int first, unsigned int last);
+ void drawClosingLine(GLsizei count, GLenum type, const void *indices);
+
void recordInvalidEnum();
void recordInvalidValue();
void recordInvalidOperation();
@@ -374,10 +407,26 @@ class Context
GLenum getError();
bool supportsShaderModel3() const;
+ int getMaximumVaryingVectors() const;
+ int getMaximumFragmentUniformVectors() const;
+ int getMaximumRenderbufferDimension() const;
+ int getMaximumTextureDimension() const;
+ int getMaximumCubeTextureDimension() const;
+ int getMaximumTextureLevel() const;
GLsizei getMaxSupportedSamples() const;
int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
+ bool supportsEventQueries() const;
bool supportsCompressedTextures() const;
+ bool supportsFloatTextures() const;
+ bool supportsFloatLinearFilter() const;
+ bool supportsFloatRenderableTextures() const;
+ bool supportsHalfFloatTextures() const;
+ bool supportsHalfFloatLinearFilter() const;
+ bool supportsHalfFloatRenderableTextures() const;
+ bool supportsLuminanceTextures() const;
+ bool supportsLuminanceAlphaTextures() const;
+ bool supports32bitIndices() const;
void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -406,25 +455,24 @@ class Context
State mState;
- Texture2D *mTexture2DZero;
- TextureCubeMap *mTextureCubeMapZero;
-
- Colorbuffer *mColorbufferZero;
- DepthStencilbuffer *mDepthStencilbufferZero;
+ BindingPointer<Texture2D> mTexture2DZero;
+ BindingPointer<TextureCubeMap> mTextureCubeMapZero;
typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
+ typedef std::map<GLuint, Fence*> FenceMap;
+ FenceMap mFenceMap;
+
void initExtensionString();
std::string mExtensionString;
- BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager;
IndexDataManager *mIndexDataManager;
Blit *mBlit;
- Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
+ BindingPointer<Texture> mIncompleteTextures[SAMPLER_TYPE_COUNT];
// Recorded errors
bool mInvalidEnum;
@@ -439,11 +487,26 @@ class Context
unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
unsigned int mAppliedStencilbufferSerial;
+ bool mDepthStencilInitialized;
bool mSupportsShaderModel3;
+ int mMaxRenderbufferDimension;
+ int mMaxTextureDimension;
+ int mMaxCubeTextureDimension;
+ int mMaxTextureLevel;
std::map<D3DFORMAT, bool *> mMultiSampleSupport;
GLsizei mMaxSupportedSamples;
+ bool mSupportsEventQueries;
bool mSupportsCompressedTextures;
+ bool mSupportsFloatTextures;
+ bool mSupportsFloatLinearFilter;
+ bool mSupportsFloatRenderableTextures;
+ bool mSupportsHalfFloatTextures;
+ bool mSupportsHalfFloatLinearFilter;
+ bool mSupportsHalfFloatRenderableTextures;
+ bool mSupportsLuminanceTextures;
+ bool mSupportsLuminanceAlphaTextures;
+ bool mSupports32bitIndices;
// state caching flags
bool mClearStateDirty;
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp
new file mode 100644
index 0000000..7fbcb6a
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp
@@ -0,0 +1,134 @@
+//
+// 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.
+//
+
+// Fence.cpp: Implements the gl::Fence class, which supports the GL_NV_fence extension.
+
+#include "libGLESv2/Fence.h"
+
+#include "libGLESv2/main.h"
+
+namespace gl
+{
+
+Fence::Fence()
+{
+ mQuery = NULL;
+ mCondition = GL_NONE;
+ mStatus = GL_FALSE;
+}
+
+Fence::~Fence()
+{
+ if (mQuery != NULL)
+ {
+ mQuery->Release();
+ mQuery = NULL;
+ }
+}
+
+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;
+}
+
+void Fence::setFence(GLenum condition)
+{
+ if (mQuery != NULL)
+ {
+ mQuery->Release();
+ mQuery = NULL;
+ }
+
+ if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery)))
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ HRESULT result = mQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
+
+ mCondition = condition;
+ mStatus = GL_FALSE;
+}
+
+GLboolean Fence::testFence()
+{
+ if (mQuery == NULL)
+ {
+ return error(GL_INVALID_OPERATION, GL_TRUE);
+ }
+
+ HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+ if (result == D3DERR_DEVICELOST)
+ {
+ return error(GL_OUT_OF_MEMORY, GL_TRUE);
+ }
+
+ ASSERT(result == S_OK || result == S_FALSE);
+ mStatus = result == S_OK;
+ return mStatus;
+}
+
+void Fence::finishFence()
+{
+ if (mQuery == NULL)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ while (!testFence())
+ {
+ Sleep(0);
+ }
+}
+
+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 (result == D3DERR_DEVICELOST)
+ {
+ 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;
+ }
+}
+
+}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h
new file mode 100644
index 0000000..17bad78
--- /dev/null
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+// Fence.h: Defines the gl::Fence class, which supports the GL_NV_fence extension.
+
+#ifndef LIBGLESV2_FENCE_H_
+#define LIBGLESV2_FENCE_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+#include <d3d9.h>
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+
+class Fence
+{
+ public:
+ Fence();
+ virtual ~Fence();
+
+ GLboolean isFence();
+ void setFence(GLenum condition);
+ GLboolean testFence();
+ void finishFence();
+ void getFenceiv(GLenum pname, GLint *params);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Fence);
+
+ IDirect3DQuery9* mQuery;
+ GLenum mCondition;
+ GLboolean mStatus;
+};
+
+}
+
+#endif // LIBGLESV2_FENCE_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
index 5c4bc99..5fe01e0 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp
@@ -305,13 +305,32 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
- if (IsTextureTarget(mColorbufferType))
+ if (mColorbufferType == GL_RENDERBUFFER)
+ {
+ if (!gl::IsColorRenderable(colorbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+ }
+ else if (IsTextureTarget(mColorbufferType))
{
if (IsCompressed(colorbuffer->getFormat()))
{
return GL_FRAMEBUFFER_UNSUPPORTED;
}
+
+ if (colorbuffer->isFloatingPoint() && (!getContext()->supportsFloatRenderableTextures() ||
+ !getContext()->supportsHalfFloatRenderableTextures()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
+ if (colorbuffer->getFormat() == GL_LUMINANCE || colorbuffer->getFormat() == GL_LUMINANCE_ALPHA)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
}
+ else UNREACHABLE();
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
@@ -327,6 +346,11 @@ GLenum Framebuffer::completeness()
if (mDepthbufferType != GL_NONE)
{
+ if (mDepthbufferType != GL_RENDERBUFFER)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED; // Requires GL_OES_depth_texture
+ }
+
depthbuffer = getDepthbuffer();
if (!depthbuffer)
@@ -357,18 +381,15 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
-
- if (IsTextureTarget(mDepthbufferType))
- {
- if (IsCompressed(depthbuffer->getFormat()))
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
- }
}
if (mStencilbufferType != GL_NONE)
{
+ if (mStencilbufferType != GL_RENDERBUFFER)
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+
stencilbuffer = getStencilbuffer();
if (!stencilbuffer)
@@ -399,14 +420,6 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
}
-
- if (IsTextureTarget(mStencilbufferType))
- {
- if (IsCompressed(stencilbuffer->getFormat()))
- {
- return GL_FRAMEBUFFER_UNSUPPORTED;
- }
- }
}
if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
@@ -425,8 +438,8 @@ GLenum Framebuffer::completeness()
DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
{
mColorbufferType = GL_RENDERBUFFER;
- mDepthbufferType = GL_RENDERBUFFER;
- mStencilbufferType = GL_RENDERBUFFER;
+ mDepthbufferType = (depthStencil->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
+ mStencilbufferType = (depthStencil->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
mColorbufferPointer.set(new Renderbuffer(0, color));
@@ -449,6 +462,9 @@ int Framebuffer::getSamples()
GLenum DefaultFramebuffer::completeness()
{
+ // The default framebuffer should always be complete
+ ASSERT(Framebuffer::completeness() == GL_FRAMEBUFFER_COMPLETE);
+
return GL_FRAMEBUFFER_COMPLETE;
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
index a32bc9f..780c3e3 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp
@@ -45,7 +45,7 @@ UniformLocation::UniformLocation(const std::string &name, unsigned int element,
{
}
-Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
+Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial())
{
mFragmentShader = NULL;
mVertexShader = NULL;
@@ -63,8 +63,6 @@ Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(man
mDeleteStatus = false;
mRefCount = 0;
-
- mSerial = issueSerial();
}
Program::~Program()
@@ -205,7 +203,7 @@ GLint Program::getSamplerMapping(unsigned int samplerIndex)
logicalTextureUnit = mSamplers[samplerIndex].logicalTextureUnit;
}
- if (logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS)
+ if (logicalTextureUnit >= 0 && logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS)
{
return logicalTextureUnit;
}
@@ -243,26 +241,22 @@ void Program::setSamplerDirty(unsigned int samplerIndex, bool dirty)
GLint Program::getUniformLocation(const char *name, bool decorated)
{
- std::string nameStr(name);
+ std::string _name = decorated ? name : decorate(name);
int subscript = 0;
- size_t beginB = nameStr.find('[');
- size_t endB = nameStr.find(']');
- if (beginB != std::string::npos && endB != std::string::npos)
- {
- std::string subscrStr = nameStr.substr(beginB + 1, beginB - endB - 1);
- nameStr.erase(beginB);
- subscript = atoi(subscrStr.c_str());
- }
- if (!decorated)
+ // Strip any trailing array operator and retrieve the subscript
+ size_t open = _name.find_last_of('[');
+ size_t close = _name.find_last_of(']');
+ if (open != std::string::npos && close == _name.length() - 1)
{
- nameStr = decorate(nameStr);
+ subscript = atoi(_name.substr(open + 1).c_str());
+ _name.erase(open);
}
unsigned int numUniforms = mUniformIndex.size();
for (unsigned int location = 0; location < numUniforms; location++)
{
- if (mUniformIndex[location].name == nameStr &&
+ if (mUniformIndex[location].name == _name &&
mUniformIndex[location].element == subscript)
{
return location;
@@ -595,7 +589,9 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
Uniform *targetUniform = mUniforms[mUniformIndex[location].index];
targetUniform->dirty = true;
- if (targetUniform->type == GL_INT)
+ if (targetUniform->type == GL_INT ||
+ targetUniform->type == GL_SAMPLER_2D ||
+ targetUniform->type == GL_SAMPLER_CUBE)
{
int arraySize = targetUniform->arraySize;
@@ -949,6 +945,8 @@ void Program::applyUniforms()
case GL_FLOAT_MAT2: applyUniformMatrix2fv(location, arraySize, f); break;
case GL_FLOAT_MAT3: applyUniformMatrix3fv(location, arraySize, f); break;
case GL_FLOAT_MAT4: applyUniformMatrix4fv(location, arraySize, f); break;
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
case GL_INT: applyUniform1iv(location, arraySize, i); break;
case GL_INT_VEC2: applyUniform2iv(location, arraySize, i); break;
case GL_INT_VEC3: applyUniform3iv(location, arraySize, i); break;
@@ -1001,6 +999,9 @@ ID3DXBuffer *Program::compileToBinary(const char *hlsl, const char *profile, ID3
// Returns the number of used varying registers, or -1 if unsuccesful
int Program::packVaryings(const Varying *packing[][4])
{
+ Context *context = getContext();
+ const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++)
{
int n = VariableRowCount(varying->type) * varying->size;
@@ -1009,7 +1010,7 @@ int Program::packVaryings(const Varying *packing[][4])
if (m == 2 || m == 3 || m == 4)
{
- for (int r = 0; r <= MAX_VARYING_VECTORS - n && !success; r++)
+ for (int r = 0; r <= maxVaryingVectors - n && !success; r++)
{
bool available = true;
@@ -1043,7 +1044,7 @@ int Program::packVaryings(const Varying *packing[][4])
if (!success && m == 2)
{
- for (int r = MAX_VARYING_VECTORS - n; r >= 0 && !success; r--)
+ for (int r = maxVaryingVectors - n; r >= 0 && !success; r--)
{
bool available = true;
@@ -1080,7 +1081,7 @@ int Program::packVaryings(const Varying *packing[][4])
{
int space[4] = {0};
- for (int y = 0; y < MAX_VARYING_VECTORS; y++)
+ for (int y = 0; y < maxVaryingVectors; y++)
{
for (int x = 0; x < 4; x++)
{
@@ -1100,7 +1101,7 @@ int Program::packVaryings(const Varying *packing[][4])
if (space[column] > n)
{
- for (int r = 0; r < MAX_VARYING_VECTORS; r++)
+ for (int r = 0; r < maxVaryingVectors; r++)
{
if (!packing[r][column])
{
@@ -1133,7 +1134,7 @@ int Program::packVaryings(const Varying *packing[][4])
// Return the number of used registers
int registers = 0;
- for (int r = 0; r < MAX_VARYING_VECTORS; r++)
+ for (int r = 0; r < maxVaryingVectors; r++)
{
if (packing[r][0] || packing[r][1] || packing[r][2] || packing[r][3])
{
@@ -1151,7 +1152,7 @@ bool Program::linkVaryings()
return false;
}
- const Varying *packing[MAX_VARYING_VECTORS][4] = {NULL};
+ const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL};
int registers = packVaryings(packing);
if (registers < 0)
@@ -1159,7 +1160,11 @@ bool Program::linkVaryings()
return false;
}
- if (registers == MAX_VARYING_VECTORS && mFragmentShader->mUsesFragCoord)
+ Context *context = getContext();
+ const bool sm3 = context->supportsShaderModel3();
+ const int maxVaryingVectors = context->getMaximumVaryingVectors();
+
+ if (registers == maxVaryingVectors && mFragmentShader->mUsesFragCoord)
{
appendToInfoLog("No varying registers left to support gl_FragCoord");
@@ -1197,8 +1202,6 @@ bool Program::linkVaryings()
}
}
- Context *context = getContext();
- bool sm3 = context->supportsShaderModel3();
std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
mVertexHLSL += "struct VS_INPUT\n"
@@ -1371,6 +1374,9 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
mPixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ if (sm3) {
+ mPixelHLSL += " float2 dx_VPos : VPOS;\n";
+ }
}
if (mFragmentShader->mUsesPointCoord && sm3)
@@ -1395,10 +1401,15 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
- mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"
- " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
- " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"
- " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
+ mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n";
+ if (sm3) {
+ mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x;\n"
+ " gl_FragCoord.y = input.dx_VPos.y;\n";
+ } else {
+ mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
+ " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n";
+ }
+ mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n";
}
@@ -1525,9 +1536,7 @@ void Program::link()
// these uniforms are searched as already-decorated because gl_ and dx_
// are reserved prefixes, and do not receive additional decoration
- mDepthRangeNearLocation = getUniformLocation("gl_DepthRange.near", true);
- mDepthRangeFarLocation = getUniformLocation("gl_DepthRange.far", true);
- mDepthRangeDiffLocation = getUniformLocation("gl_DepthRange.diff", true);
+ mDxDepthRangeLocation = getUniformLocation("dx_DepthRange", true);
mDxDepthLocation = getUniformLocation("dx_Depth", true);
mDxViewportLocation = getUniformLocation("dx_Viewport", true);
mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
@@ -1650,32 +1659,38 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
{
if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{
- unsigned int samplerIndex = constantDescription.RegisterIndex;
-
- assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
+ for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++)
+ {
+ ASSERT(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
- mSamplers[samplerIndex].active = true;
- mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
- mSamplers[samplerIndex].logicalTextureUnit = 0;
- mSamplers[samplerIndex].dirty = true;
+ mSamplers[samplerIndex].active = true;
+ mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
+ mSamplers[samplerIndex].logicalTextureUnit = 0;
+ mSamplers[samplerIndex].dirty = true;
+ }
}
switch(constantDescription.Class)
{
case D3DXPC_STRUCT:
{
- for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
+ for (unsigned int arrayIndex = 0; arrayIndex < constantDescription.Elements; arrayIndex++)
{
- D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field);
+ for (unsigned int field = 0; field < constantDescription.StructMembers; field++)
+ {
+ D3DXHANDLE fieldHandle = mConstantTablePS->GetConstant(constantHandle, field);
- D3DXCONSTANT_DESC fieldDescription;
- UINT descriptionCount = 1;
+ D3DXCONSTANT_DESC fieldDescription;
+ UINT descriptionCount = 1;
- mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
+ mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount);
- if (!defineUniform(fieldHandle, fieldDescription, name + constantDescription.Name + "."))
- {
- return false;
+ std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : "";
+
+ if (!defineUniform(fieldHandle, fieldDescription, name + constantDescription.Name + structIndex + "."))
+ {
+ return false;
+ }
}
}
@@ -1737,10 +1752,16 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st
switch (constantDescription.Type)
{
case D3DXPT_SAMPLER2D:
+ switch (constantDescription.Columns)
+ {
+ case 1: return new Uniform(GL_SAMPLER_2D, name, constantDescription.Elements);
+ default: UNREACHABLE();
+ }
+ break;
case D3DXPT_SAMPLERCUBE:
switch (constantDescription.Columns)
{
- case 1: return new Uniform(GL_INT, name, constantDescription.Elements);
+ case 1: return new Uniform(GL_SAMPLER_CUBE, name, constantDescription.Elements);
default: UNREACHABLE();
}
break;
@@ -2205,14 +2226,14 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
{
unsigned int firstIndex = mConstantTablePS->GetSamplerIndex(constantPS);
- for (unsigned int samplerIndex = firstIndex; samplerIndex < firstIndex + count; samplerIndex++)
+ for (int i = 0; i < count; i++)
{
- GLint mappedSampler = v[0];
+ unsigned int samplerIndex = firstIndex + i;
- if (samplerIndex >= 0 && samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
+ if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{
ASSERT(mSamplers[samplerIndex].active);
- mSamplers[samplerIndex].logicalTextureUnit = mappedSampler;
+ mSamplers[samplerIndex].logicalTextureUnit = v[i];
mSamplers[samplerIndex].dirty = true;
}
}
@@ -2371,6 +2392,7 @@ void Program::resetInfoLog()
if (mInfoLog)
{
delete [] mInfoLog;
+ mInfoLog = NULL;
}
}
@@ -2434,9 +2456,7 @@ void Program::unlink(bool destroy)
mUniforms.pop_back();
}
- mDepthRangeDiffLocation = -1;
- mDepthRangeNearLocation = -1;
- mDepthRangeFarLocation = -1;
+ mDxDepthRangeLocation = -1;
mDxDepthLocation = -1;
mDxViewportLocation = -1;
mDxHalfPixelSizeLocation = -1;
@@ -2562,16 +2582,22 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade
void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- unsigned int attribute = 0;
- for (unsigned int i = 0; i < index; i++)
+ // Skip over inactive attributes
+ unsigned int activeAttribute = 0;
+ unsigned int attribute;
+ for (attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
{
- do
+ if (mLinkedAttribute[attribute].name.empty())
{
- attribute++;
+ continue;
+ }
- ASSERT(attribute < MAX_VERTEX_ATTRIBS); // index must be smaller than getActiveAttributeCount()
+ if (activeAttribute == index)
+ {
+ break;
}
- while (mLinkedAttribute[attribute].name.empty());
+
+ activeAttribute++;
}
if (bufsize > 0)
@@ -2624,18 +2650,26 @@ GLint Program::getActiveAttributeMaxLength()
void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
- unsigned int uniform = 0;
- for (unsigned int i = 0; i < index; i++)
+ // Skip over internal uniforms
+ unsigned int activeUniform = 0;
+ unsigned int uniform;
+ for (uniform = 0; uniform < mUniforms.size(); uniform++)
{
- do
+ if (mUniforms[uniform]->name.substr(0, 3) == "dx_")
{
- uniform++;
+ continue;
+ }
- ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+ if (activeUniform == index)
+ {
+ break;
}
- while (mUniforms[uniform]->name.substr(0, 3) == "dx_");
+
+ activeUniform++;
}
+ ASSERT(uniform < mUniforms.size()); // index must be smaller than getActiveUniformCount()
+
if (bufsize > 0)
{
std::string string = undecorate(mUniforms[uniform]->name);
@@ -2763,19 +2797,9 @@ void Program::getConstantHandles(Uniform *targetUniform, D3DXHANDLE *constantPS,
*constantVS = targetUniform->vsHandle;
}
-GLint Program::getDepthRangeDiffLocation() const
-{
- return mDepthRangeDiffLocation;
-}
-
-GLint Program::getDepthRangeNearLocation() const
-{
- return mDepthRangeNearLocation;
-}
-
-GLint Program::getDepthRangeFarLocation() const
+GLint Program::getDxDepthRangeLocation() const
{
- return mDepthRangeFarLocation;
+ return mDxDepthRangeLocation;
}
GLint Program::getDxDepthLocation() const
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
index 3021b7a..e9c149e 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h
@@ -94,9 +94,7 @@ class Program
bool getUniformfv(GLint location, GLfloat *params);
bool getUniformiv(GLint location, GLint *params);
- GLint getDepthRangeDiffLocation() const;
- GLint getDepthRangeNearLocation() const;
- GLint getDepthRangeFarLocation() const;
+ GLint getDxDepthRangeLocation() const;
GLint getDxDepthLocation() const;
GLint getDxViewportLocation() const;
GLint getDxHalfPixelSizeLocation() const;
@@ -204,9 +202,7 @@ class Program
typedef std::vector<UniformLocation> UniformIndex;
UniformIndex mUniformIndex;
- GLint mDepthRangeDiffLocation;
- GLint mDepthRangeNearLocation;
- GLint mDepthRangeFarLocation;
+ GLint mDxDepthRangeLocation;
GLint mDxDepthLocation;
GLint mDxViewportLocation;
GLint mDxHalfPixelSizeLocation;
@@ -220,7 +216,7 @@ class Program
unsigned int mRefCount;
- unsigned int mSerial;
+ const unsigned int mSerial;
static unsigned int mCurrentSerial;
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
index e3fd36e..2de1e71 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp
@@ -22,6 +22,7 @@ RefCountObject::RefCountObject(GLuint id)
RefCountObject::~RefCountObject()
{
+ ASSERT(mRefCount == 0);
}
void RefCountObject::addRef() const
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
index 0eb4637..6e4494b 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp
@@ -11,6 +11,7 @@
#include "libGLESv2/Renderbuffer.h"
#include "libGLESv2/main.h"
+#include "libGLESv2/Texture.h"
#include "libGLESv2/utilities.h"
namespace gl
@@ -86,9 +87,13 @@ void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
mStorage = newStorage;
}
-RenderbufferStorage::RenderbufferStorage()
+RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial())
{
- mSerial = issueSerial();
+ mWidth = 0;
+ mHeight = 0;
+ mFormat = GL_RGBA4;
+ mD3DFormat = D3DFMT_A8R8G8B8;
+ mSamples = 0;
}
RenderbufferStorage::~RenderbufferStorage()
@@ -141,6 +146,11 @@ GLenum RenderbufferStorage::getFormat() const
return mFormat;
}
+bool RenderbufferStorage::isFloatingPoint() const
+{
+ return false; // no floating point renderbuffers
+}
+
D3DFORMAT RenderbufferStorage::getD3DFormat() const
{
return mD3DFormat;
@@ -171,14 +181,17 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
renderTarget->GetDesc(&description);
setSize(description.Width, description.Height);
+ mFormat = dx2es::ConvertBackBufferFormat(description.Format);
mD3DFormat = description.Format;
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
}
- else
- {
- mD3DFormat = D3DFMT_UNKNOWN;
- mSamples = 0;
- }
+}
+
+Colorbuffer::Colorbuffer(const Texture* texture) : mRenderTarget(NULL)
+{
+ setSize(texture->getWidth(), texture->getHeight());
+ mD3DFormat = texture->getD3DFormat();
+ mSamples = 0;
}
Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
@@ -218,13 +231,6 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
mD3DFormat = requestedFormat;
mSamples = supportedSamples;
}
- else
- {
- setSize(0, 0);
- mFormat = GL_RGBA4;
- mD3DFormat = D3DFMT_UNKNOWN;
- mSamples = 0;
- }
}
Colorbuffer::~Colorbuffer()
@@ -307,15 +313,10 @@ DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepth
depthStencil->GetDesc(&description);
setSize(description.Width, description.Height);
- mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
+ mFormat = dx2es::ConvertDepthStencilFormat(description.Format);
mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
mD3DFormat = description.Format;
}
- else
- {
- mD3DFormat = D3DFMT_UNKNOWN;
- mSamples = 0;
- }
}
DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
@@ -352,13 +353,6 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
mD3DFormat = D3DFMT_D24S8;
mSamples = supportedSamples;
}
- else
- {
- setSize(0, 0);
- mFormat = GL_RGBA4; //default format
- mD3DFormat = D3DFMT_UNKNOWN;
- mSamples = 0;
- }
}
DepthStencilbuffer::~DepthStencilbuffer()
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
index cb8c06a..98510c2 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h
@@ -21,6 +21,7 @@
namespace gl
{
+ class Texture;
// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
// is called. The specific concrete type depends on whether the internal format is
@@ -42,6 +43,7 @@ class RenderbufferStorage
virtual int getWidth() const;
virtual int getHeight() const;
virtual GLenum getFormat() const;
+ virtual bool isFloatingPoint() const;
D3DFORMAT getD3DFormat() const;
GLsizei getSamples() const;
unsigned int getSerial() const;
@@ -53,7 +55,7 @@ class RenderbufferStorage
GLenum mFormat;
D3DFORMAT mD3DFormat;
GLsizei mSamples;
- unsigned int mSerial;
+ const unsigned int mSerial;
private:
DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
@@ -100,6 +102,7 @@ class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
+ explicit Colorbuffer(const Texture* texture);
Colorbuffer(int width, int height, GLenum format, GLsizei samples);
~Colorbuffer();
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
index b73ef2a..4c969d6 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp
@@ -34,19 +34,22 @@ Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mReso
if (result)
{
- TBuiltInResource resources;
- ShInitBuiltInResource(&resources);
+ ShBuiltInResources resources;
+ ShInitBuiltInResources(&resources);
+ Context *context = getContext();
+
resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
- resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
+ resources.MaxVaryingVectors = context->getMaximumVaryingVectors();
resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+ resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors();
resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
+ resources.OES_standard_derivatives = 1;
- mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
- mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
+ mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources);
+ mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources);
}
}
@@ -240,7 +243,7 @@ void Shader::parseVaryings()
char varyingType[256];
char varyingName[256];
- int matches = sscanf(input, "static %s %s", varyingType, varyingName);
+ int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
if (matches != 2)
{
@@ -280,21 +283,23 @@ void Shader::compileToHLSL(void *compiler)
delete[] mInfoLog;
mInfoLog = NULL;
- int result = ShCompile(compiler, &mSource, 1, EShOptNone, EDebugOpNone);
- const char *obj = ShGetObjectCode(compiler);
- const char *info = ShGetInfoLog(compiler);
+ int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE);
if (result)
{
- mHlsl = new char[strlen(obj) + 1];
- strcpy(mHlsl, obj);
+ int objCodeLen = 0;
+ ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
+ mHlsl = new char[objCodeLen];
+ ShGetObjectCode(compiler, mHlsl);
TRACE("\n%s", mHlsl);
}
else
{
- mInfoLog = new char[strlen(info) + 1];
- strcpy(mInfoLog, info);
+ int infoLogLen = 0;
+ ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
+ mInfoLog = new char[infoLogLen];
+ ShGetInfoLog(compiler, mInfoLog);
TRACE("\n%s", mInfoLog);
}
@@ -468,7 +473,7 @@ void VertexShader::parseAttributes()
char attributeType[256];
char attributeName[256];
- int matches = sscanf(input, "static %s _%s", attributeType, attributeName);
+ int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
if (matches != 2)
{
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
index 2e0b1e3..7c040f8 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp
@@ -10,6 +10,8 @@
#include "libGLESv2/Texture.h"
+#include <d3dx9tex.h>
+
#include <algorithm>
#include "common/debug.h"
@@ -45,6 +47,7 @@ Texture::Texture(GLuint id) : RefCountObject(id)
mDirtyMetaData = true;
mDirty = true;
mIsRenderable = false;
+ mType = GL_UNSIGNED_BYTE;
mBaseTexture = NULL;
}
@@ -174,86 +177,171 @@ GLuint Texture::getHeight() const
return mHeight;
}
+bool Texture::isFloatingPoint() const
+{
+ return (mType == GL_FLOAT || mType == GL_HALF_FLOAT_OES);
+}
+
+bool Texture::isRenderableFormat() const
+{
+ D3DFORMAT format = getD3DFormat();
+
+ switch(format)
+ {
+ case D3DFMT_L8:
+ case D3DFMT_A8L8:
+ case D3DFMT_DXT1:
+ return false;
+ case D3DFMT_A8R8G8B8:
+ case D3DFMT_X8R8G8B8:
+ case D3DFMT_A16B16G16R16F:
+ case D3DFMT_A32B32G32R32F:
+ return true;
+ default:
+ UNREACHABLE();
+ }
+
+ return false;
+}
+
// Selects an internal Direct3D 9 format for storing an Image
-D3DFORMAT Texture::selectFormat(GLenum format)
+D3DFORMAT Texture::selectFormat(GLenum format, GLenum type)
{
if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
return D3DFMT_DXT1;
}
- else
+ else if (type == GL_FLOAT)
+ {
+ return D3DFMT_A32B32G32R32F;
+ }
+ else if (type == GL_HALF_FLOAT_OES)
{
+ return D3DFMT_A16B16G16R16F;
+ }
+ else if (type == GL_UNSIGNED_BYTE)
+ {
+ if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures())
+ {
+ return D3DFMT_L8;
+ }
+ else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures())
+ {
+ return D3DFMT_A8L8;
+ }
+ else if (format == GL_RGB)
+ {
+ return D3DFMT_X8R8G8B8;
+ }
+
return D3DFMT_A8R8G8B8;
}
-}
-int Texture::imagePitch(const Image &img) const
-{
- return img.width * 4;
+ return D3DFMT_A8R8G8B8;
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
-// into the BGRA8 pixel rectangle at output with outputPitch bytes in between each line.
+// into the target pixel rectangle at output with outputPitch bytes in between each line.
void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const
+ GLint unpackAlignment, const void *input, size_t outputPitch, void *output, D3DSURFACE_DESC *description) const
{
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
- switch (format)
+ switch (type)
{
- case GL_ALPHA:
- loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
- break;
-
- case GL_LUMINANCE:
- loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
- break;
-
- case GL_LUMINANCE_ALPHA:
- loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
- break;
-
- case GL_RGB:
- switch (type)
+ case GL_UNSIGNED_BYTE:
+ switch (format)
{
- case GL_UNSIGNED_BYTE:
+ case GL_ALPHA:
+ loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_LUMINANCE:
+ loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, description->Format == D3DFMT_L8);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, description->Format == D3DFMT_A8L8);
+ break;
+ case GL_RGB:
loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
- case GL_UNSIGNED_SHORT_5_6_5:
- loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ case GL_RGBA:
+ loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_BGRA_EXT:
+ loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
default: UNREACHABLE();
}
break;
-
- case GL_RGBA:
- switch (type)
+ case GL_UNSIGNED_SHORT_5_6_5:
+ switch (format)
{
- case GL_UNSIGNED_BYTE:
- loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ case GL_RGB:
+ loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
- case GL_UNSIGNED_SHORT_4_4_4_4:
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ switch (format)
+ {
+ case GL_RGBA:
loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
- case GL_UNSIGNED_SHORT_5_5_5_1:
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ switch (format)
+ {
+ case GL_RGBA:
loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
default: UNREACHABLE();
}
break;
- case GL_BGRA_EXT:
- switch (type)
+ case GL_FLOAT:
+ switch (format)
{
- case GL_UNSIGNED_BYTE:
- loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+ case GL_ALPHA:
+ loadAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_LUMINANCE:
+ loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_RGB:
+ loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_RGBA:
+ loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_HALF_FLOAT_OES:
+ switch (format)
+ {
+ // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+ case GL_ALPHA:
+ loadAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_LUMINANCE:
+ loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_LUMINANCE_ALPHA:
+ loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_RGB:
+ loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+ case GL_RGBA:
+ loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
break;
-
default: UNREACHABLE();
}
break;
@@ -281,36 +369,174 @@ void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GL
}
}
+void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 16);
+ 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 Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 8);
+ 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 Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+ size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{
+ const int destBytesPerPixel = native? 1: 4;
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 + yoffset) * outputPitch + xoffset * 4;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
+
+ 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 Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 16);
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;
+ dest[4 * x + 3] = 1.0f;
+ }
+ }
+}
+
+void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 8);
+ 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 Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+ size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const
{
+ const int destBytesPerPixel = native? 2: 4;
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 + yoffset) * outputPitch + xoffset * 4;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * destBytesPerPixel;
+
+ 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 Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 16);
+ 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 Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 8);
for (int x = 0; x < width; x++)
{
dest[4 * x + 0] = source[2*x+0];
@@ -362,6 +588,46 @@ void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, G
}
}
+void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 16);
+ 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 Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 8);
+ 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 Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
@@ -424,6 +690,34 @@ void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width,
}
}
+void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 16);
+ memcpy(dest, source, width * 16);
+ }
+}
+
+void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t 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 + yoffset) * outputPitch + xoffset * 8;
+ memcpy(dest, source, width * 8);
+ }
+}
+
void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const
{
@@ -438,7 +732,7 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs
}
}
-void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img)
+void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img)
{
IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL;
@@ -465,7 +759,7 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image
levelToFetch = upsampleCount;
}
- HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format),
+ HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format, type),
D3DPOOL_SYSTEMMEM, &newTexture, NULL);
if (FAILED(result))
@@ -488,10 +782,13 @@ void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image
void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
{
- createSurface(width, height, format, img);
+ createSurface(width, height, format, type, img);
if (pixels != NULL && img->surface != NULL)
{
+ D3DSURFACE_DESC description;
+ img->surface->GetDesc(&description);
+
D3DLOCKED_RECT locked;
HRESULT result = img->surface->LockRect(&locked, NULL, 0);
@@ -499,7 +796,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
if (SUCCEEDED(result))
{
- loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
+ loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
img->surface->UnlockRect();
}
@@ -511,7 +808,7 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
{
- createSurface(width, height, format, img);
+ createSurface(width, height, format, GL_UNSIGNED_BYTE, img);
if (pixels != NULL && img->surface != NULL)
{
@@ -540,18 +837,30 @@ bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
return false;
}
- D3DLOCKED_RECT locked;
- HRESULT result = img->surface->LockRect(&locked, NULL, 0);
-
- ASSERT(SUCCEEDED(result));
+ if (!img->surface)
+ {
+ createSurface(img->width, img->height, format, type, img);
+ }
- if (SUCCEEDED(result))
+ if (pixels != NULL && img->surface != NULL)
{
- loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
- img->surface->UnlockRect();
+ D3DSURFACE_DESC description;
+ img->surface->GetDesc(&description);
+
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, NULL, 0);
+
+ ASSERT(SUCCEEDED(result));
+
+ if (SUCCEEDED(result))
+ {
+ loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description);
+ img->surface->UnlockRect();
+ }
+
+ img->dirty = true;
}
- img->dirty = true;
return true;
}
@@ -569,32 +878,215 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
return false;
}
- RECT updateRegion;
- updateRegion.left = xoffset;
- updateRegion.right = xoffset + width;
- updateRegion.bottom = yoffset + height;
- updateRegion.top = yoffset;
+ if (!img->surface)
+ {
+ createSurface(img->width, img->height, format, GL_UNSIGNED_BYTE, img);
+ }
+
+ if (pixels != NULL && img->surface != NULL)
+ {
+ RECT updateRegion;
+ updateRegion.left = xoffset;
+ updateRegion.right = xoffset + width;
+ updateRegion.bottom = yoffset + height;
+ updateRegion.top = yoffset;
- D3DLOCKED_RECT locked;
- HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
- ASSERT(SUCCEEDED(result));
+ ASSERT(SUCCEEDED(result));
- if (SUCCEEDED(result))
- {
- GLsizei inputPitch = ComputeCompressedPitch(width, format);
- int rows = imageSize / inputPitch;
- for (int i = 0; i < rows; ++i)
+ if (SUCCEEDED(result))
{
- memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
+ GLsizei inputPitch = ComputeCompressedPitch(width, format);
+ int rows = imageSize / inputPitch;
+ for (int i = 0; i < rows; ++i)
+ {
+ memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
+ }
+ img->surface->UnlockRect();
}
- img->surface->UnlockRect();
+
+ img->dirty = true;
}
- img->dirty = true;
return true;
}
+// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
+void Texture::copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
+{
+ IDirect3DDevice9 *device = getDevice();
+ IDirect3DSurface9 *surface = NULL;
+ D3DSURFACE_DESC description;
+ renderTarget->GetDesc(&description);
+
+ HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &surface, NULL);
+
+ if (!SUCCEEDED(result))
+ {
+ ERR("Could not create matching destination surface.");
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ result = device->GetRenderTargetData(renderTarget, surface);
+
+ if (!SUCCEEDED(result))
+ {
+ ERR("GetRenderTargetData unexpectedly failed.");
+ surface->Release();
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ D3DLOCKED_RECT sourceLock = {0};
+ RECT sourceRect = {x, y, x + width, y + height};
+ result = surface->LockRect(&sourceLock, &sourceRect, 0);
+
+ if (FAILED(result))
+ {
+ ERR("Failed to lock the source surface (rectangle might be invalid).");
+ surface->UnlockRect();
+ surface->Release();
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ if (!image->surface)
+ {
+ createSurface(width, height, internalFormat, mType, image);
+ }
+
+ if (image->surface == NULL)
+ {
+ ERR("Failed to create an image surface.");
+ surface->UnlockRect();
+ surface->Release();
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ D3DLOCKED_RECT destLock = {0};
+ RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+ result = image->surface->LockRect(&destLock, &destRect, 0);
+
+ if (FAILED(result))
+ {
+ ERR("Failed to lock the destination surface (rectangle might be invalid).");
+ surface->UnlockRect();
+ surface->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_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_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_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();
+ }
+
+ image->dirty = true;
+ mDirtyMetaData = true;
+ }
+
+ image->surface->UnlockRect();
+ surface->UnlockRect();
+ surface->Release();
+}
+
+D3DFORMAT Texture::getD3DFormat() const
+{
+ return selectFormat(getFormat(), mType);
+}
+
IDirect3DBaseTexture9 *Texture::getTexture()
{
if (!isComplete())
@@ -683,15 +1175,19 @@ int Texture::levelCount() const
return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
}
+bool Texture::isRenderable() const
+{
+ return mIsRenderable;
+}
+
Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexture = NULL;
- mColorbufferProxy = NULL;
}
Texture2D::~Texture2D()
{
- delete mColorbufferProxy;
+ mColorbufferProxy.set(NULL);
if (mTexture)
{
@@ -714,9 +1210,9 @@ GLenum Texture2D::getFormat() const
// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels.
// Call this when a particular level of the texture must be defined with a specific format, width and height.
//
-// Returns true if the existing texture was unsuitable had to be destroyed. If so, it will also set
+// Returns true if the existing texture was unsuitable and had to be destroyed. If so, it will also set
// a new height and width for the texture by working backwards from the given width and height.
-bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height)
+bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type)
{
bool widthOkay = (mWidth >> level == width);
bool heightOkay = (mHeight >> level == height);
@@ -725,7 +1221,9 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
|| (widthOkay && mHeight >> level == 0 && height == 1)
|| (heightOkay && mWidth >> level == 0 && width == 1));
- bool textureOkay = (sizeOkay && internalFormat == mImageArray[0].format);
+ bool typeOkay = (type == mType);
+
+ bool textureOkay = (sizeOkay && typeOkay && internalFormat == mImageArray[0].format);
if (!textureOkay)
{
@@ -735,7 +1233,7 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
// Purge all the levels and the texture.
- for (int i = 0; i < MAX_TEXTURE_LEVELS; i++)
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
if (mImageArray[i].surface != NULL)
{
@@ -756,6 +1254,7 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
mWidth = width << level;
mHeight = height << level;
mImageArray[0].format = internalFormat;
+ mType = type;
}
return !textureOkay;
@@ -763,14 +1262,14 @@ bool Texture2D::redefineTexture(GLint level, GLenum internalFormat, GLsizei widt
void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- redefineTexture(level, internalFormat, width, height);
+ redefineTexture(level, internalFormat, width, height, type);
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
}
void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
{
- redefineTexture(level, internalFormat, width, height);
+ redefineTexture(level, internalFormat, width, height, GL_UNSIGNED_BYTE);
Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]);
}
@@ -828,29 +1327,46 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
- if (redefineTexture(level, internalFormat, width, height))
+ IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+ if (!renderTarget)
{
- convertToRenderTarget();
- pushTexture(mTexture, true);
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
}
- else
+
+ bool redefined = redefineTexture(level, internalFormat, width, height, mType);
+
+ if (!isRenderableFormat())
{
- needRenderTarget();
+ copyNonRenderable(&mImageArray[level], internalFormat, 0, 0, x, y, width, height, renderTarget);
}
-
- if (width != 0 && height != 0 && level < levelCount())
+ else
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
+ if (redefined)
+ {
+ convertToRenderTarget();
+ pushTexture(mTexture, true);
+ }
+ else
+ {
+ needRenderTarget();
+ }
+
+ 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;
- HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
+ IDirect3DSurface9 *dest;
+ HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
- getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
- dest->Release();
+ getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
+ dest->Release();
+ }
}
mImageArray[level].width = width;
@@ -858,36 +1374,53 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
mImageArray[level].format = internalFormat;
}
-void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{
return error(GL_INVALID_VALUE);
}
- if (redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height))
+ IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+ if (!renderTarget)
{
- convertToRenderTarget();
- pushTexture(mTexture, true);
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
}
- else
+
+ bool redefined = redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, mType);
+
+ if (!isRenderableFormat())
{
- needRenderTarget();
+ copyNonRenderable(&mImageArray[level], getFormat(), xoffset, yoffset, x, y, width, height, renderTarget);
}
-
- if (level < levelCount())
+ else
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
+ if (redefined)
+ {
+ convertToRenderTarget();
+ pushTexture(mTexture, true);
+ }
+ else
+ {
+ needRenderTarget();
+ }
+
+ if (level < levelCount())
+ {
+ RECT sourceRect;
+ sourceRect.left = x;
+ sourceRect.right = x + width;
+ sourceRect.top = y;
+ sourceRect.bottom = y + height;
- IDirect3DSurface9 *dest;
- HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
+ IDirect3DSurface9 *dest;
+ HRESULT hr = mTexture->GetSurfaceLevel(level, &dest);
- getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest);
- dest->Release();
+ getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest);
+ dest->Release();
+ }
}
}
@@ -919,6 +1452,16 @@ bool Texture2D::isComplete() const
default: UNREACHABLE();
}
+ if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
+ (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
+ {
+ if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+ {
+ return false;
+ }
+ }
+
+
if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width))
|| (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height)))
{
@@ -967,7 +1510,7 @@ IDirect3DBaseTexture9 *Texture2D::createTexture()
IDirect3DTexture9 *texture;
IDirect3DDevice9 *device = getDevice();
- D3DFORMAT format = selectFormat(mImageArray[0].format);
+ D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL);
@@ -1018,7 +1561,7 @@ IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget()
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
- D3DFORMAT format = selectFormat(mImageArray[0].format);
+ D3DFORMAT format = selectFormat(mImageArray[0].format, mType);
HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
@@ -1123,23 +1666,50 @@ void Texture2D::generateMipmaps()
mImageArray[i].height = std::max(mImageArray[0].height >> i, 1);
}
- needRenderTarget();
-
- for (unsigned int i = 1; i <= q; i++)
+ if (isRenderable())
{
- IDirect3DSurface9 *upper = NULL;
- IDirect3DSurface9 *lower = NULL;
+ if (mTexture == NULL)
+ {
+ ERR(" failed because mTexture was null.");
+ return;
+ }
- mTexture->GetSurfaceLevel(i-1, &upper);
- mTexture->GetSurfaceLevel(i, &lower);
+ for (unsigned int i = 1; i <= q; i++)
+ {
+ IDirect3DSurface9 *upper = NULL;
+ IDirect3DSurface9 *lower = NULL;
+
+ mTexture->GetSurfaceLevel(i-1, &upper);
+ mTexture->GetSurfaceLevel(i, &lower);
+
+ if (upper != NULL && lower != NULL)
+ {
+ getBlitter()->boxFilter(upper, lower);
+ }
- if (upper != NULL && lower != NULL)
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
+ }
+ }
+ else
+ {
+ for (unsigned int i = 1; i <= q; i++)
{
- getBlitter()->boxFilter(upper, lower);
+ createSurface(mImageArray[i].width, mImageArray[i].height, mImageArray[i].format, mType, &mImageArray[i]);
+ if (mImageArray[i].surface == NULL)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+
+ if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[i].surface, NULL, NULL, mImageArray[i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+ {
+ ERR(" failed to load filter %d to %d.", i - 1, i);
+ }
+
+ mImageArray[i].dirty = true;
}
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
+ mDirtyMetaData = true;
}
}
@@ -1150,13 +1720,12 @@ Renderbuffer *Texture2D::getColorbuffer(GLenum target)
return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
- if (mColorbufferProxy == NULL)
+ if (mColorbufferProxy.get() == NULL)
{
- mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
- mColorbufferProxy->addRef();
+ mColorbufferProxy.set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target)));
}
- return mColorbufferProxy;
+ return mColorbufferProxy.get();
}
IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
@@ -1165,6 +1734,11 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
needRenderTarget();
+ if (mTexture == NULL)
+ {
+ return NULL;
+ }
+
IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetSurfaceLevel(0, &renderTarget);
@@ -1174,18 +1748,13 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexture = NULL;
-
- for (int i = 0; i < 6; i++)
- {
- mFaceProxies[i] = NULL;
- }
}
TextureCubeMap::~TextureCubeMap()
{
for (int i = 0; i < 6; i++)
{
- delete mFaceProxies[i];
+ mFaceProxies[i].set(NULL);
}
if (mTexture)
@@ -1277,19 +1846,19 @@ void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G
}
}
-void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
+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(face)][level]))
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(target)][level]))
{
- commitRect(face, level, xoffset, yoffset, width, height);
+ commitRect(target, level, xoffset, yoffset, width, height);
}
}
-void TextureCubeMap::subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+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(face)][level]))
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(target)][level]))
{
- commitRect(face, level, xoffset, yoffset, width, height);
+ commitRect(target, level, xoffset, yoffset, width, height);
}
}
@@ -1328,6 +1897,15 @@ bool TextureCubeMap::isComplete() const
}
}
+ if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) ||
+ (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter()))
+ {
+ if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST))
+ {
+ return false;
+ }
+ }
+
if (mipmapping)
{
if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE))
@@ -1368,7 +1946,7 @@ bool TextureCubeMap::isCompressed() const
IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
{
IDirect3DDevice9 *device = getDevice();
- D3DFORMAT format = selectFormat(mImageArray[0][0].format);
+ D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
IDirect3DCubeTexture9 *texture;
@@ -1424,7 +2002,7 @@ IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget()
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = getDevice();
- D3DFORMAT format = selectFormat(mImageArray[0][0].format);
+ D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType);
HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL);
@@ -1546,7 +2124,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
internalFormat, width);
// Purge all the levels and the texture.
- for (int i = 0; i < MAX_TEXTURE_LEVELS; i++)
+ for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
{
for (int f = 0; f < 6; f++)
{
@@ -1578,34 +2156,50 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
return !textureOkay;
}
-void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
- unsigned int faceindex = faceIndex(face);
+ IDirect3DSurface9 *renderTarget = source->getRenderTarget();
- if (redefineTexture(level, internalFormat, width))
+ if (!renderTarget)
{
- convertToRenderTarget();
- pushTexture(mTexture, true);
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
}
- else
+
+ unsigned int faceindex = faceIndex(target);
+ bool redefined = redefineTexture(level, internalFormat, width);
+
+ if (!isRenderableFormat())
{
- needRenderTarget();
+ copyNonRenderable(&mImageArray[faceindex][level], internalFormat, 0, 0, x, y, width, height, renderTarget);
}
+ else
+ {
+ if (redefined)
+ {
+ convertToRenderTarget();
+ pushTexture(mTexture, true);
+ }
+ else
+ {
+ needRenderTarget();
+ }
- ASSERT(width == height);
+ ASSERT(width == height);
- if (width > 0 && level < levelCount())
- {
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
+ if (width > 0 && level < levelCount())
+ {
+ RECT sourceRect;
+ sourceRect.left = x;
+ sourceRect.right = x + width;
+ sourceRect.top = y;
+ sourceRect.bottom = y + height;
- IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
+ IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
- getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
- dest->Release();
+ getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest);
+ dest->Release();
+ }
}
mImageArray[faceindex][level].width = width;
@@ -1644,37 +2238,55 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
return (SUCCEEDED(hr)) ? surface : NULL;
}
-void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
+void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
- GLsizei size = mImageArray[faceIndex(face)][level].width;
+ GLsizei size = mImageArray[faceIndex(target)][level].width;
if (xoffset + width > size || yoffset + height > size)
{
return error(GL_INVALID_VALUE);
}
- if (redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width))
+ IDirect3DSurface9 *renderTarget = source->getRenderTarget();
+
+ if (!renderTarget)
{
- convertToRenderTarget();
- pushTexture(mTexture, true);
+ ERR("Failed to retrieve the render target.");
+ return error(GL_OUT_OF_MEMORY);
}
- else
+
+ unsigned int faceindex = faceIndex(target);
+ bool redefined = redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width);
+
+ if (!isRenderableFormat())
{
- needRenderTarget();
+ copyNonRenderable(&mImageArray[faceindex][level], getFormat(), 0, 0, x, y, width, height, renderTarget);
}
-
- if (level < levelCount())
+ else
{
- RECT sourceRect;
- sourceRect.left = x;
- sourceRect.right = x + width;
- sourceRect.top = y;
- sourceRect.bottom = y + height;
+ if (redefined)
+ {
+ convertToRenderTarget();
+ pushTexture(mTexture, true);
+ }
+ else
+ {
+ needRenderTarget();
+ }
+
+ if (level < levelCount())
+ {
+ RECT sourceRect;
+ sourceRect.left = x;
+ sourceRect.right = x + width;
+ sourceRect.top = y;
+ sourceRect.bottom = y + height;
- IDirect3DSurface9 *dest = getCubeMapSurface(face, level);
+ IDirect3DSurface9 *dest = getCubeMapSurface(target, level);
- getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest);
- dest->Release();
+ getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest);
+ dest->Release();
+ }
}
}
@@ -1724,23 +2336,52 @@ void TextureCubeMap::generateMipmaps()
}
}
- needRenderTarget();
-
- for (unsigned int f = 0; f < 6; f++)
+ if (isRenderable())
{
- for (unsigned int i = 1; i <= q; i++)
+ if (mTexture == NULL)
{
- IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
- IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
+ return;
+ }
- if (upper != NULL && lower != NULL)
+ for (unsigned int f = 0; f < 6; f++)
+ {
+ for (unsigned int i = 1; i <= q; i++)
{
- getBlitter()->boxFilter(upper, lower);
+ IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1);
+ IDirect3DSurface9 *lower = getCubeMapSurface(f, i);
+
+ if (upper != NULL && lower != NULL)
+ {
+ getBlitter()->boxFilter(upper, lower);
+ }
+
+ if (upper != NULL) upper->Release();
+ if (lower != NULL) lower->Release();
}
+ }
+ }
+ else
+ {
+ for (unsigned int f = 0; f < 6; f++)
+ {
+ for (unsigned int i = 1; i <= q; i++)
+ {
+ createSurface(mImageArray[f][i].width, mImageArray[f][i].height, mImageArray[f][i].format, mType, &mImageArray[f][i]);
+ if (mImageArray[f][i].surface == NULL)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
- if (upper != NULL) upper->Release();
- if (lower != NULL) lower->Release();
+ if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[f][i].surface, NULL, NULL, mImageArray[f][i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0)))
+ {
+ ERR(" failed to load filter %d to %d.", i - 1, i);
+ }
+
+ mImageArray[f][i].dirty = true;
+ }
}
+
+ mDirtyMetaData = true;
}
}
@@ -1753,13 +2394,12 @@ Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target)
unsigned int face = faceIndex(target);
- if (mFaceProxies[face] == NULL)
+ if (mFaceProxies[face].get() == NULL)
{
- mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
- mFaceProxies[face]->addRef();
+ mFaceProxies[face].set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target)));
}
- return mFaceProxies[face];
+ return mFaceProxies[face].get();
}
IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
@@ -1767,7 +2407,12 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
ASSERT(IsCubemapTextureTarget(target));
needRenderTarget();
-
+
+ if (mTexture == NULL)
+ {
+ return NULL;
+ }
+
IDirect3DSurface9 *renderTarget = NULL;
mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex(target)), 0, &renderTarget);
@@ -1775,9 +2420,9 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
}
Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target)
- : Colorbuffer(NULL), mTexture(texture), mTarget(target)
+ : Colorbuffer(texture), mTexture(texture), mTarget(target)
{
- ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
+ ASSERT(IsTextureTarget(target));
}
void Texture::TextureColorbufferProxy::addRef() const
@@ -1814,4 +2459,9 @@ GLenum Texture::TextureColorbufferProxy::getFormat() const
return mTexture->getFormat();
}
+bool Texture::TextureColorbufferProxy::isFloatingPoint() const
+{
+ return mTexture->isFloatingPoint();
+}
+
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
index efa882c..ca7aec7 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h
@@ -18,6 +18,7 @@
#include <d3d9.h>
#include "libGLESv2/Renderbuffer.h"
+#include "libGLESv2/RefCountObject.h"
#include "libGLESv2/utilities.h"
#include "common/debug.h"
@@ -27,10 +28,13 @@ class Blit;
enum
{
- MAX_TEXTURE_SIZE = 2048,
- MAX_CUBE_MAP_TEXTURE_SIZE = 2048,
+ // These are the maximums the implementation can support
+ // The actual GL caps are limited by the device caps
+ // and should be queried from the Context
+ IMPLEMENTATION_MAX_TEXTURE_SIZE = 16384,
+ IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE = 16384,
- MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
+ IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE
};
class Texture : public RefCountObject
@@ -58,11 +62,15 @@ class Texture : public RefCountObject
virtual GLenum getFormat() const = 0;
virtual bool isComplete() const = 0;
virtual bool isCompressed() const = 0;
+ bool isFloatingPoint() const;
+ bool isRenderableFormat() const;
+ D3DFORMAT getD3DFormat() const;
IDirect3DBaseTexture9 *getTexture();
virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
+ virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) = 0;
bool isDirty() const;
@@ -85,6 +93,7 @@ class Texture : public RefCountObject
virtual int getWidth() const;
virtual int getHeight() const;
virtual GLenum getFormat() const;
+ virtual bool isFloatingPoint() const;
private:
Texture *mTexture;
@@ -106,13 +115,13 @@ class Texture : public RefCountObject
IDirect3DSurface9 *surface;
};
- static D3DFORMAT selectFormat(GLenum format);
- int imagePitch(const Image& img) const;
+ static D3DFORMAT selectFormat(GLenum format, GLenum type);
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
+ void copyNonRenderable(Image *image, GLenum internalFormat, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
void needRenderTarget();
@@ -129,50 +138,73 @@ class Texture : public RefCountObject
void dropTexture();
void pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable);
+ void createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img);
Blit *getBlitter();
int levelCount() const;
+ bool isRenderable() const;
+
unsigned int mWidth;
unsigned int mHeight;
GLenum mMinFilter;
GLenum mMagFilter;
GLenum mWrapS;
GLenum mWrapT;
+ GLenum mType;
+
+ bool mDirtyMetaData;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+ GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output, D3DSURFACE_DESC *description) const;
void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
- size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
- void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
+ void loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const;
+ void loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
bool mDirty;
- bool mDirtyMetaData;
bool mIsRenderable;
-
- void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
};
class Texture2D : public Texture
@@ -190,7 +222,7 @@ class Texture2D : public Texture
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
- void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
bool isCompressed() const;
@@ -209,14 +241,14 @@ class Texture2D : public Texture
virtual bool dirtyImageData() const;
- bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
+ bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
- Image mImageArray[MAX_TEXTURE_LEVELS];
+ Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS];
IDirect3DTexture9 *mTexture;
- Renderbuffer *mColorbufferProxy;
+ BindingPointer<Renderbuffer> mColorbufferProxy;
};
class TextureCubeMap : public Texture
@@ -238,10 +270,10 @@ class TextureCubeMap : public Texture
void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
- void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
- void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
- void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void subImageCompressed(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ void copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
bool isCompressed() const;
@@ -272,11 +304,11 @@ class TextureCubeMap : public Texture
void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width);
- Image mImageArray[6][MAX_TEXTURE_LEVELS];
+ Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];
IDirect3DCubeTexture9 *mTexture;
- Renderbuffer *mFaceProxies[6];
+ BindingPointer<Renderbuffer> mFaceProxies[6];
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
index d573579..f79d606 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.cpp
@@ -13,7 +13,7 @@
#include "libGLESv2/Buffer.h"
#include "libGLESv2/mathutil.h"
-#include "libGLESv2/geometry/backend.h"
+#include "libGLESv2/main.h"
namespace
{
@@ -23,239 +23,360 @@ namespace
namespace gl
{
-IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
- : mContext(context), mBackend(backend), mIntIndicesSupported(backend->supportIntIndices())
+IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device)
{
- mCountingBuffer = NULL;
- mCountingBufferSize = 0;
+ mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16);
- mLineLoopBuffer = NULL;
-
- mStreamBufferShort = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
-
- if (mIntIndicesSupported)
+ if (context->supports32bitIndices())
{
- mStreamBufferInt = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+ mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32);
}
else
{
- mStreamBufferInt = NULL;
+ mStreamingBufferInt = NULL;
}
}
IndexDataManager::~IndexDataManager()
{
- delete mStreamBufferShort;
- delete mStreamBufferInt;
- delete mCountingBuffer;
- delete mLineLoopBuffer;
+ delete mStreamingBufferShort;
+ delete mStreamingBufferInt;
}
-namespace
+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 InputIndexType, class OutputIndexType>
-void copyIndices(const InputIndexType *in, GLsizei count, OutputIndexType *out, GLuint *minIndex, GLuint *maxIndex)
+template <class IndexType>
+void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
{
- InputIndexType first = *in;
- GLuint minIndexSoFar = first;
- GLuint maxIndexSoFar = first;
+ *minIndex = indices[0];
+ *maxIndex = indices[0];
for (GLsizei i = 0; i < count; i++)
{
- if (minIndexSoFar > *in) minIndexSoFar = *in;
- if (maxIndexSoFar < *in) maxIndexSoFar = *in;
-
- *out++ = *in++;
+ if (*minIndex > indices[i]) *minIndex = indices[i];
+ if (*maxIndex < indices[i]) *maxIndex = indices[i];
}
-
- // It might be a line loop, so copy the loop index.
- *out = first;
-
- *minIndex = minIndexSoFar;
- *maxIndex = maxIndexSoFar;
}
+void computeRange(GLenum type, const void *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::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated)
+GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const void *indices, TranslatedIndexData *translated)
{
- ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_INT);
- ASSERT(count > 0);
+ D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16;
+ intptr_t offset = reinterpret_cast<intptr_t>(indices);
+ bool alignedOffset = false;
- if (arrayElementBuffer != NULL)
+ if (buffer != NULL)
{
- GLsizei offset = reinterpret_cast<GLsizei>(indices);
+ 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>(arrayElementBuffer->size()))
+ if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size()))
{
return GL_INVALID_OPERATION;
}
- indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + offset;
+ indices = static_cast<const GLubyte*>(buffer->data()) + offset;
}
- translated->count = count;
-
- std::size_t requiredSpace = spaceRequired(type, count);
-
- TranslatedIndexBuffer *streamIb = prepareIndexBuffer(type, requiredSpace);
+ StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
- size_t offset;
- void *output = streamIb->map(requiredSpace, &offset);
+ StaticIndexBuffer *staticBuffer = buffer ? buffer->getIndexBuffer() : NULL;
+ IndexBuffer *indexBuffer = streamingBuffer;
+ UINT streamOffset = 0;
- translated->buffer = streamIb;
- translated->offset = offset;
- translated->indexSize = indexSize(type);
-
- if (type == GL_UNSIGNED_BYTE)
+ if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset)
{
- const GLubyte *in = static_cast<const GLubyte*>(indices);
- GLushort *out = static_cast<GLushort*>(output);
+ indexBuffer = staticBuffer;
+ streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex);
- copyIndices(in, count, out, &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 if (type == GL_UNSIGNED_INT)
+ else
{
- const GLuint *in = static_cast<const GLuint*>(indices);
+ int convertCount = count;
- if (mIntIndicesSupported)
+ if (staticBuffer)
{
- GLuint *out = static_cast<GLuint*>(output);
+ if (staticBuffer->size() == 0 && alignedOffset)
+ {
+ indexBuffer = staticBuffer;
+ convertCount = buffer->size() / typeSize(type);
+ }
+ else
+ {
+ buffer->invalidateStaticData();
+ staticBuffer = NULL;
+ }
+ }
- copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
+ void *output = NULL;
+
+ if (indexBuffer)
+ {
+ indexBuffer->reserveSpace(convertCount * indexSize(format), type);
+ output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset);
}
- else
+
+ if (output == NULL)
{
- // When 32-bit indices are unsupported, fake them by truncating to 16-bit.
+ ERR("Failed to map index buffer.");
+ return GL_OUT_OF_MEMORY;
+ }
- GLushort *out = static_cast<GLushort*>(output);
+ convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output);
+ indexBuffer->unmap();
- copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
- }
- }
- else
- {
- const GLushort *in = static_cast<const GLushort*>(indices);
- GLushort *out = static_cast<GLushort*>(output);
+ computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
- copyIndices(in, count, out, &translated->minIndex, &translated->maxIndex);
+ if (staticBuffer)
+ {
+ streamOffset = (offset / typeSize(type)) * indexSize(format);
+ staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset);
+ }
}
- streamIb->unmap();
+ translated->indexBuffer = indexBuffer->getBuffer();
+ translated->startIndex = streamOffset / indexSize(format);
return GL_NO_ERROR;
}
-std::size_t IndexDataManager::indexSize(GLenum type) const
+std::size_t IndexDataManager::indexSize(D3DFORMAT format) const
{
- return (type == GL_UNSIGNED_INT && mIntIndicesSupported) ? sizeof(GLuint) : sizeof(GLushort);
+ 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_INT: return sizeof(GLuint);
case GL_UNSIGNED_SHORT: return sizeof(GLushort);
- default: UNREACHABLE();
- case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
+ default: UNREACHABLE(); return sizeof(GLushort);
}
}
-std::size_t IndexDataManager::spaceRequired(GLenum type, GLsizei count) const
+IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL)
{
- return (count + 1) * indexSize(type); // +1 because we always leave an extra for line loops
+ if (size > 0)
+ {
+ D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY);
+ HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL);
+
+ if (FAILED(result))
+ {
+ ERR("Out of memory allocating an index buffer of size %lu.", size);
+ }
+ }
}
-TranslatedIndexBuffer *IndexDataManager::prepareIndexBuffer(GLenum type, std::size_t requiredSpace)
+IndexBuffer::~IndexBuffer()
{
- bool use32 = (type == GL_UNSIGNED_INT && mIntIndicesSupported);
+ if (mIndexBuffer)
+ {
+ mIndexBuffer->Release();
+ }
+}
- TranslatedIndexBuffer *streamIb = use32 ? mStreamBufferInt : mStreamBufferShort;
+IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const
+{
+ return mIndexBuffer;
+}
- if (requiredSpace > streamIb->size())
+void IndexBuffer::unmap()
+{
+ if (mIndexBuffer)
{
- std::size_t newSize = std::max(requiredSpace, 2 * streamIb->size());
+ mIndexBuffer->Unlock();
+ }
+}
- TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize, use32 ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT);
+StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format)
+{
+ mWritePosition = 0;
+}
- delete streamIb;
+StreamingIndexBuffer::~StreamingIndexBuffer()
+{
+}
- streamIb = newStreamBuffer;
+void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset)
+{
+ void *mapPtr = NULL;
- if (use32)
- {
- mStreamBufferInt = streamIb;
- }
- else
+ if (mIndexBuffer)
+ {
+ HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
+
+ if (FAILED(result))
{
- mStreamBufferShort = streamIb;
+ ERR(" Lock failed with error 0x%08x", result);
+ return NULL;
}
- }
- streamIb->reserveSpace(requiredSpace);
+ *offset = mWritePosition;
+ mWritePosition += requiredSpace;
+ }
- return streamIb;
+ return mapPtr;
}
-GLenum IndexDataManager::preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo)
+void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type)
{
- if (count >= 65535) return GL_OUT_OF_MEMORY;
-
- if (mode == GL_LINE_LOOP)
+ if (requiredSpace > mBufferSize)
{
- // For line loops, create a single-use buffer that runs 0 - count-1, 0.
- delete mLineLoopBuffer;
- mLineLoopBuffer = mBackend->createIndexBuffer((count+1) * sizeof(unsigned short), GL_UNSIGNED_SHORT);
-
- unsigned short *indices = static_cast<unsigned short *>(mLineLoopBuffer->map());
-
- for (int i = 0; i < count; i++)
+ if (mIndexBuffer)
{
- indices[i] = i;
+ mIndexBuffer->Release();
+ mIndexBuffer = NULL;
}
- indices[count] = 0;
+ mBufferSize = std::max(requiredSpace, 2 * mBufferSize);
- mLineLoopBuffer->unmap();
+ 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);
+
+ if (FAILED(result))
+ {
+ ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
+ }
- indexInfo->buffer = mLineLoopBuffer;
- indexInfo->count = count + 1;
- indexInfo->maxIndex = count - 1;
+ mWritePosition = 0;
}
- else if (mCountingBufferSize < count)
+ else if (mWritePosition + requiredSpace > mBufferSize) // Recycle
{
- mCountingBufferSize = std::max(static_cast<GLsizei>(ceilPow2(count)), mCountingBufferSize*2);
+ void *dummy;
+ mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
+ mIndexBuffer->Unlock();
- delete mCountingBuffer;
- mCountingBuffer = mBackend->createIndexBuffer(count * sizeof(unsigned short), GL_UNSIGNED_SHORT);
+ mWritePosition = 0;
+ }
+}
- unsigned short *indices = static_cast<unsigned short *>(mCountingBuffer->map());
+StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN)
+{
+ mCacheType = GL_NONE;
+}
- for (int i = 0; i < count; i++)
+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))
{
- indices[i] = i;
+ ERR(" Lock failed with error 0x%08x", result);
+ return NULL;
}
- mCountingBuffer->unmap();
+ *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);
+
+ if (FAILED(result))
+ {
+ ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
+ }
- indexInfo->buffer = mCountingBuffer;
- indexInfo->count = count;
- indexInfo->maxIndex = count - 1;
+ mBufferSize = requiredSpace;
+ mCacheType = type;
}
- else
+ else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type)
{
- indexInfo->buffer = mCountingBuffer;
- indexInfo->count = count;
- indexInfo->maxIndex = count - 1;
+ // Already allocated
}
+ else UNREACHABLE(); // Static index buffers can't be resized
+}
- indexInfo->indexSize = sizeof(unsigned short);
- indexInfo->minIndex = 0;
- indexInfo->offset = 0;
+bool StaticIndexBuffer::lookupType(GLenum type)
+{
+ return mCacheType == type;
+}
- return GL_NO_ERROR;
+UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex)
+{
+ for (unsigned int range = 0; range < mCache.size(); range++)
+ {
+ if (mCache[range].offset == offset && mCache[range].count == count)
+ {
+ *minIndex = mCache[range].minIndex;
+ *maxIndex = mCache[range].maxIndex;
+
+ return mCache[range].streamOffset;
+ }
+ }
+
+ return -1;
+}
+
+void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset)
+{
+ IndexRange indexRange = {offset, count, minIndex, maxIndex, streamOffset};
+ mCache.push_back(indexRange);
}
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
index 00ebed2..d48249c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/IndexDataManager.h
@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_INDEXDATAMANAGER_H_
-#include <bitset>
+#include <vector>
#include <cstddef>
#define GL_APICALL
@@ -21,49 +21,98 @@
namespace gl
{
-class Buffer;
-class BufferBackEnd;
-class TranslatedIndexBuffer;
-struct FormatConverter;
-
struct TranslatedIndexData
{
- GLuint minIndex;
- GLuint maxIndex;
- GLuint count;
- GLuint indexSize;
+ UINT minIndex;
+ UINT maxIndex;
+ UINT startIndex;
- TranslatedIndexBuffer *buffer;
- GLsizei offset;
+ IDirect3DIndexBuffer9 *indexBuffer;
};
-class IndexDataManager
+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;
+
+ protected:
+ IDirect3DDevice9 *const mDevice;
+
+ IDirect3DIndexBuffer9 *mIndexBuffer;
+ UINT mBufferSize;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexBuffer);
+};
+
+class StreamingIndexBuffer : public IndexBuffer
+{
+ public:
+ StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format);
+ ~StreamingIndexBuffer();
+
+ void *map(UINT requiredSpace, UINT *offset);
+ void reserveSpace(UINT requiredSpace, GLenum type);
+
+ private:
+ UINT mWritePosition;
+};
+
+class StaticIndexBuffer : public IndexBuffer
{
public:
- IndexDataManager(Context *context, BufferBackEnd *backend);
- ~IndexDataManager();
+ explicit StaticIndexBuffer(IDirect3DDevice9 *device);
+ ~StaticIndexBuffer();
+
+ void *map(UINT requiredSpace, UINT *offset);
+ void reserveSpace(UINT requiredSpace, GLenum type);
- GLenum preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
- GLenum preRenderValidateUnindexed(GLenum mode, GLsizei count, TranslatedIndexData *indexInfo);
+ 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:
- std::size_t IndexDataManager::typeSize(GLenum type) const;
- std::size_t IndexDataManager::indexSize(GLenum type) const;
- std::size_t spaceRequired(GLenum type, GLsizei count) const;
- TranslatedIndexBuffer *prepareIndexBuffer(GLenum type, std::size_t requiredSpace);
+ GLenum mCacheType;
+
+ struct IndexRange
+ {
+ intptr_t offset;
+ GLsizei count;
+
+ UINT minIndex;
+ UINT maxIndex;
+ UINT streamOffset;
+ };
+
+ std::vector<IndexRange> mCache;
+};
+
+class IndexDataManager
+{
+ public:
+ IndexDataManager(Context *context, IDirect3DDevice9 *evice);
+ virtual ~IndexDataManager();
- Context *mContext;
- BufferBackEnd *mBackend;
+ GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices, TranslatedIndexData *translated);
- bool mIntIndicesSupported;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(IndexDataManager);
- TranslatedIndexBuffer *mStreamBufferShort;
- TranslatedIndexBuffer *mStreamBufferInt;
+ std::size_t typeSize(GLenum type) const;
+ std::size_t indexSize(D3DFORMAT format) const;
- TranslatedIndexBuffer *mCountingBuffer;
- GLsizei mCountingBufferSize;
+ IDirect3DDevice9 *const mDevice;
- TranslatedIndexBuffer *mLineLoopBuffer;
+ StreamingIndexBuffer *mStreamingBufferShort;
+ StreamingIndexBuffer *mStreamingBufferInt;
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
index 7762e07..99ece17 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.cpp
@@ -9,14 +9,13 @@
#include "libGLESv2/geometry/VertexDataManager.h"
-#include <limits>
-
#include "common/debug.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Program.h"
+#include "libGLESv2/main.h"
-#include "libGLESv2/geometry/backend.h"
+#include "libGLESv2/geometry/vertexconversion.h"
#include "libGLESv2/geometry/IndexDataManager.h"
namespace
@@ -27,245 +26,744 @@ namespace
namespace gl
{
-VertexDataManager::VertexDataManager(Context *context, BufferBackEnd *backend)
- : mContext(context), mBackend(backend), mDirtyCurrentValues(true), mCurrentValueOffset(0)
+VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device)
{
- mStreamBuffer = mBackend->createVertexBuffer(INITIAL_STREAM_BUFFER_SIZE);
- try
- {
- mCurrentValueBuffer = mBackend->createVertexBufferForStrideZero(4 * sizeof(float) * MAX_VERTEX_ATTRIBS);
- }
- catch (...)
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- delete mStreamBuffer;
- throw;
+ mDirtyCurrentValue[i] = true;
+ mCurrentValueBuffer[i] = NULL;
}
+
+ const D3DCAPS9 &caps = context->getDeviceCaps();
+ checkVertexCaps(caps.DeclTypes);
+
+ mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE);
}
VertexDataManager::~VertexDataManager()
{
- delete mStreamBuffer;
- delete mCurrentValueBuffer;
+ delete mStreamingBuffer;
+
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ delete mCurrentValueBuffer[i];
+ }
}
-std::bitset<MAX_VERTEX_ATTRIBS> VertexDataManager::getActiveAttribs() const
+UINT VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute)
{
- std::bitset<MAX_VERTEX_ATTRIBS> active;
+ Buffer *buffer = attribute.mBoundBuffer.get();
- Program *program = mContext->getCurrentProgram();
+ int inputStride = attribute.stride();
+ int elementSize = attribute.typeSize();
+ const FormatConverter &converter = formatConverter(attribute);
+ UINT streamOffset = 0;
- for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ void *output = NULL;
+
+ if (vertexBuffer)
{
- active[attributeIndex] = (program->getSemanticIndex(attributeIndex) != -1);
+ output = vertexBuffer->map(attribute, spaceRequired(attribute, count), &streamOffset);
}
- return active;
-}
+ if (output == NULL)
+ {
+ ERR("Failed to map vertex buffer.");
+ return -1;
+ }
-GLenum VertexDataManager::preRenderValidate(GLint start, GLsizei count,
- TranslatedAttribute *translated)
-{
- const AttributeState *attribs = mContext->getVertexAttribBlock();
- const std::bitset<MAX_VERTEX_ATTRIBS> activeAttribs = getActiveAttribs();
+ const char *input = NULL;
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ if (buffer)
+ {
+ int offset = attribute.mOffset;
+
+ input = static_cast<const char*>(buffer->data()) + offset;
+ }
+ else
{
- if (!activeAttribs[i] && attribs[i].mEnabled && attribs[i].mBoundBuffer != 0 && !mContext->getBuffer(attribs[i].mBoundBuffer))
- return GL_INVALID_OPERATION;
+ input = static_cast<const char*>(attribute.mPointer);
}
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ input += inputStride * start;
+
+ if (converter.identity && inputStride == elementSize)
{
- translated[i].enabled = activeAttribs[i];
+ memcpy(output, input, count * inputStride);
}
+ else
+ {
+ converter.convertArray(input, inputStride, count, output);
+ }
+
+ vertexBuffer->unmap();
- bool usesCurrentValues = false;
+ return streamOffset;
+}
+GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated)
+{
+ GLenum error = GL_NO_ERROR;
+ const VertexAttributeArray &attribs = mContext->getVertexAttributes();
+ Program *program = mContext->getCurrentProgram();
+
+ for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
+ {
+ translated[attributeIndex].active = (program->getSemanticIndex(attributeIndex) != -1);
+ }
+
+ // Determine the required storage size per used buffer
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- if (activeAttribs[i] && !attribs[i].mEnabled)
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+ if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
{
- usesCurrentValues = true;
- break;
+ StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
+
+ if (staticBuffer && staticBuffer->size() == 0)
+ {
+ int totalCount = buffer->size() / attribs[i].stride();
+ staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount));
+ }
+ else if (!staticBuffer || staticBuffer->lookupAttribute(attribs[i]) == -1)
+ {
+ if (mStreamingBuffer)
+ {
+ mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count));
+ }
+ }
}
}
- // Handle the identity-mapped attributes.
- // Process array attributes.
-
- std::size_t requiredSpace = 0;
-
+ // Invalidate static buffers if the attribute formats no longer match
for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- if (activeAttribs[i] && attribs[i].mEnabled)
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
+
+ if (translated[i].active && attribs[i].mArrayEnabled && buffer)
{
- requiredSpace += spaceRequired(attribs[i], count);
+ StaticVertexBuffer *staticBuffer = buffer->getVertexBuffer();
+
+ if (staticBuffer && staticBuffer->size() != 0)
+ {
+ bool matchingAttributes = true;
+
+ for (int j = 0; j < MAX_VERTEX_ATTRIBS; j++)
+ {
+ if (translated[j].active && attribs[j].mArrayEnabled && attribs[j].mBoundBuffer.get() == buffer)
+ {
+ if (staticBuffer->lookupAttribute(attribs[j]) == -1)
+ {
+ matchingAttributes = false;
+ break;
+ }
+ }
+ }
+
+ if (!matchingAttributes && mStreamingBuffer)
+ {
+ mStreamingBuffer->addRequiredSpaceFor(staticBuffer);
+ buffer->invalidateStaticData();
+ }
+ }
}
}
- if (requiredSpace > mStreamBuffer->size())
+ // Reserve the required space per used buffer
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- std::size_t newSize = std::max(requiredSpace, 3 * mStreamBuffer->size() / 2); // 1.5 x mStreamBuffer->size() is arbitrary and should be checked to see we don't have too many reallocations.
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
- TranslatedVertexBuffer *newStreamBuffer = mBackend->createVertexBuffer(newSize);
+ if (translated[i].active && attribs[i].mArrayEnabled && (buffer || attribs[i].mPointer))
+ {
+ ArrayVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
+ ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer;
- delete mStreamBuffer;
- mStreamBuffer = newStreamBuffer;
+ if (vertexBuffer)
+ {
+ vertexBuffer->reserveRequiredSpace();
+ }
+ }
}
- mStreamBuffer->reserveSpace(requiredSpace);
-
- for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ // Perform the vertex data translations
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- if (activeAttribs[i] && attribs[i].mEnabled)
+ if (translated[i].active)
{
- FormatConverter formatConverter = mBackend->getFormatConverter(attribs[i].mType, attribs[i].mSize, attribs[i].mNormalized);
+ Buffer *buffer = attribs[i].mBoundBuffer.get();
- translated[i].nonArray = false;
- translated[i].type = attribs[i].mType;
- translated[i].size = attribs[i].mSize;
- translated[i].normalized = attribs[i].mNormalized;
- translated[i].stride = formatConverter.outputVertexSize;
- translated[i].buffer = mStreamBuffer;
+ if (attribs[i].mArrayEnabled)
+ {
+ 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;
+ }
- size_t inputStride = interpretGlStride(attribs[i]);
- size_t elementSize = typeSize(attribs[i].mType) * attribs[i].mSize;
+ const FormatConverter &converter = formatConverter(attribs[i]);
- void *output = mStreamBuffer->map(spaceRequired(attribs[i], count), &translated[i].offset);
+ StaticVertexBuffer *staticBuffer = buffer ? buffer->getVertexBuffer() : NULL;
+ ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer);
- const void *input;
- if (attribs[i].mBoundBuffer)
- {
- Buffer *buffer = mContext->getBuffer(attribs[i].mBoundBuffer);
+ UINT streamOffset = -1;
+
+ if (staticBuffer)
+ {
+ streamOffset = staticBuffer->lookupAttribute(attribs[i]);
- size_t offset = reinterpret_cast<size_t>(attribs[i].mPointer);
+ if (streamOffset == -1)
+ {
+ // Convert the entire buffer
+ int totalCount = buffer->size() / attribs[i].stride();
+ int startIndex = attribs[i].mOffset / attribs[i].stride();
- // Before we calculate the required size below, make sure it can be computed without integer overflow.
- if (std::numeric_limits<std::size_t>::max() - start < static_cast<std::size_t>(count)
- || std::numeric_limits<std::size_t>::max() / inputStride < static_cast<std::size_t>(start + count - 1) // it's a prerequisite that count >= 1, so start+count-1 >= 0.
- || std::numeric_limits<std::size_t>::max() - offset < inputStride * (start + count - 1)
- || std::numeric_limits<std::size_t>::max() - elementSize < offset + inputStride * (start + count - 1) + elementSize)
+ streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i]);
+ }
+
+ if (streamOffset != -1)
+ {
+ streamOffset += (start + attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize;
+ }
+ }
+ else
{
- mStreamBuffer->unmap();
- return GL_INVALID_OPERATION;
+ streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i]);
}
- if (offset + inputStride * (start + count - 1) + elementSize > buffer->size())
+ if (streamOffset == -1)
{
- mStreamBuffer->unmap();
- return GL_INVALID_OPERATION;
+ return GL_OUT_OF_MEMORY;
}
- input = static_cast<const char*>(buffer->data()) + offset;
+ translated[i].vertexBuffer = vertexBuffer->getBuffer();
+ translated[i].type = converter.d3dDeclType;
+ translated[i].stride = converter.outputElementSize;
+ translated[i].offset = streamOffset;
}
else
{
- input = attribs[i].mPointer;
- }
+ if (mDirtyCurrentValue[i])
+ {
+ delete mCurrentValueBuffer[i];
+ mCurrentValueBuffer[i] = new ConstantVertexBuffer(mDevice, attribs[i].mCurrentValue[0], attribs[i].mCurrentValue[1], attribs[i].mCurrentValue[2], attribs[i].mCurrentValue[3]);
+ mDirtyCurrentValue[i] = false;
+ }
- input = static_cast<const char*>(input) + inputStride * start;
+ translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer();
- if (formatConverter.identity && inputStride == elementSize)
- {
- memcpy(output, input, count * inputStride);
+ translated[i].type = D3DDECLTYPE_FLOAT4;
+ translated[i].stride = 0;
+ translated[i].offset = 0;
}
- else
+ }
+ }
+
+ return GL_NO_ERROR;
+}
+
+std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count) const
+{
+ return formatConverter(attrib).outputElementSize * count;
+}
+
+// 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<GLuint, 16> { };
+template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 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) }, \
+ }
+
+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(GL_FIXED),
+ TRANSLATIONS_FOR_TYPE(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++)
{
- formatConverter.convertArray(input, inputStride, count, output);
+ 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;
+ }
+}
+
+void VertexDataManager::setupAttributes(const TranslatedAttribute *attributes)
+{
+ D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS];
+ D3DVERTEXELEMENT9 *element = &elements[0];
- mStreamBuffer->unmap();
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ {
+ if (attributes[i].active)
+ {
+ mDevice->SetStreamSource(i, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride);
+
+ element->Stream = i;
+ element->Offset = 0;
+ element->Type = attributes[i].type;
+ element->Method = D3DDECLMETHOD_DEFAULT;
+ element->Usage = D3DDECLUSAGE_TEXCOORD;
+ element->UsageIndex = attributes[i].semanticIndex;
+ element++;
}
}
- if (usesCurrentValues)
+ static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+ *element = end;
+
+ IDirect3DVertexDeclaration9 *vertexDeclaration;
+ mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
+ mDevice->SetVertexDeclaration(vertexDeclaration);
+ vertexDeclaration->Release();
+}
+
+VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL)
+{
+ if (size > 0)
{
- processNonArrayAttributes(attribs, activeAttribs, translated, count);
+ D3DPOOL pool = getDisplay()->getBufferPool(usageFlags);
+ HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL);
+
+ if (FAILED(result))
+ {
+ ERR("Out of memory allocating a vertex buffer of size %lu.", size);
+ }
}
+}
- return GL_NO_ERROR;
+VertexBuffer::~VertexBuffer()
+{
+ if (mVertexBuffer)
+ {
+ mVertexBuffer->Release();
+ }
}
-std::size_t VertexDataManager::typeSize(GLenum type) const
+void VertexBuffer::unmap()
{
- switch (type)
+ if (mVertexBuffer)
{
- case GL_BYTE: case GL_UNSIGNED_BYTE: return sizeof(GLbyte);
- case GL_SHORT: case GL_UNSIGNED_SHORT: return sizeof(GLshort);
- case GL_FIXED: return sizeof(GLfixed);
- case GL_FLOAT: return sizeof(GLfloat);
- default: UNREACHABLE(); return sizeof(GLfloat);
+ mVertexBuffer->Unlock();
}
}
-std::size_t VertexDataManager::interpretGlStride(const AttributeState &attrib) const
+IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const
{
- return attrib.mStride ? attrib.mStride : typeSize(attrib.mType) * attrib.mSize;
+ return mVertexBuffer;
}
-// Round up x (>=0) to the next multiple of multiple (>0).
-// 0 rounds up to 0.
-std::size_t VertexDataManager::roundUp(std::size_t x, std::size_t multiple) const
+ConstantVertexBuffer::ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w) : VertexBuffer(device, 4 * sizeof(float), D3DUSAGE_WRITEONLY)
{
- ASSERT(x >= 0);
- ASSERT(multiple > 0);
+ void *buffer = NULL;
- std::size_t remainder = x % multiple;
- if (remainder != 0)
+ if (mVertexBuffer)
{
- return x + multiple - remainder;
+ HRESULT result = mVertexBuffer->Lock(0, 0, &buffer, 0);
+
+ if (FAILED(result))
+ {
+ ERR("Lock failed with error 0x%08x", result);
+ }
}
- else
+
+ if (buffer)
{
- return x;
+ float *vector = (float*)buffer;
+
+ vector[0] = x;
+ vector[1] = y;
+ vector[2] = z;
+ vector[3] = w;
+
+ mVertexBuffer->Unlock();
}
}
-std::size_t VertexDataManager::spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const
+ConstantVertexBuffer::~ConstantVertexBuffer()
{
- std::size_t size = mBackend->getFormatConverter(attrib.mType, attrib.mSize, attrib.mNormalized).outputVertexSize;
- size *= maxVertex;
+}
- return roundUp(size, 4 * sizeof(GLfloat));
+ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags)
+{
+ mBufferSize = size;
+ mWritePosition = 0;
+ mRequiredSpace = 0;
}
-void VertexDataManager::processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated, std::size_t count)
+ArrayVertexBuffer::~ArrayVertexBuffer()
{
- if (mDirtyCurrentValues)
+}
+
+void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace)
+{
+ mRequiredSpace += requiredSpace;
+}
+
+void ArrayVertexBuffer::addRequiredSpaceFor(ArrayVertexBuffer *buffer)
+{
+ mRequiredSpace += buffer->mRequiredSpace;
+}
+
+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)
{
- std::size_t totalSize = 4 * sizeof(float) * MAX_VERTEX_ATTRIBS;
+ 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);
+
+ 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;
+ }
- mCurrentValueBuffer->reserveSpace(totalSize);
+ mRequiredSpace = 0;
+}
+
+StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY)
+{
+}
+
+StaticVertexBuffer::~StaticVertexBuffer()
+{
+}
- float* currentValues = static_cast<float*>(mCurrentValueBuffer->map(totalSize, &mCurrentValueOffset));
+void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, UINT *streamOffset)
+{
+ void *mapPtr = NULL;
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ if (mVertexBuffer)
+ {
+ HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
+
+ if (FAILED(result))
{
- // This assumes that the GL_FLOATx4 is supported by the back-end. (For D3D9, it is a mandatory format.)
- currentValues[i*4+0] = attribs[i].mCurrentValue[0];
- currentValues[i*4+1] = attribs[i].mCurrentValue[1];
- currentValues[i*4+2] = attribs[i].mCurrentValue[2];
- currentValues[i*4+3] = attribs[i].mCurrentValue[3];
+ ERR("Lock failed with error 0x%08x", result);
+ return NULL;
}
- mCurrentValueBuffer->unmap();
+ int attributeOffset = attribute.mOffset % attribute.stride();
+ VertexElement element = {attribute.mType, attribute.mSize, attribute.mNormalized, attributeOffset, mWritePosition};
+ mCache.push_back(element);
+
+ *streamOffset = mWritePosition;
+ mWritePosition += requiredSpace;
}
- for (std::size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
+ return mapPtr;
+}
+
+void StaticVertexBuffer::reserveRequiredSpace()
+{
+ if (!mVertexBuffer && mBufferSize == 0)
{
- if (activeAttribs[i] && !attribs[i].mEnabled)
+ D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY);
+ HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL);
+
+ if (FAILED(result))
{
- translated[i].nonArray = true;
+ ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
+ }
- translated[i].buffer = mCurrentValueBuffer;
+ mBufferSize = mRequiredSpace;
+ }
+ else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
+ {
+ // Already allocated
+ }
+ else UNREACHABLE(); // Static vertex buffers can't be resized
- translated[i].type = GL_FLOAT;
- translated[i].size = 4;
- translated[i].normalized = false;
- translated[i].stride = 0;
- translated[i].offset = mCurrentValueOffset + 4 * sizeof(float) * i;
+ mRequiredSpace = 0;
+}
+
+UINT 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].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/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
index 04900b8..257f2c3 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/VertexDataManager.h
@@ -10,7 +10,7 @@
#ifndef LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
#define LIBGLESV2_GEOMETRY_VERTEXDATAMANAGER_H_
-#include <bitset>
+#include <vector>
#include <cstddef>
#define GL_APICALL
@@ -21,44 +21,148 @@
namespace gl
{
-class Buffer;
-class BufferBackEnd;
-class TranslatedVertexBuffer;
-struct TranslatedAttribute;
-struct FormatConverter;
-struct TranslatedIndexData;
+struct TranslatedAttribute
+{
+ bool active;
+
+ D3DDECLTYPE type;
+ UINT offset;
+ UINT stride; // 0 means not to advance the read pointer at all
+ UINT semanticIndex;
+
+ IDirect3DVertexBuffer9 *vertexBuffer;
+};
+
+class VertexBuffer
+{
+ public:
+ VertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
+ virtual ~VertexBuffer();
+
+ void unmap();
+
+ IDirect3DVertexBuffer9 *getBuffer() const;
+
+ protected:
+ IDirect3DDevice9 *const mDevice;
+ IDirect3DVertexBuffer9 *mVertexBuffer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VertexBuffer);
+};
+
+class ConstantVertexBuffer : public VertexBuffer
+{
+ public:
+ ConstantVertexBuffer(IDirect3DDevice9 *device, float x, float y, float z, float w);
+ ~ConstantVertexBuffer();
+};
+
+class ArrayVertexBuffer : public VertexBuffer
+{
+ public:
+ ArrayVertexBuffer(IDirect3DDevice9 *device, UINT size, DWORD usageFlags);
+ ~ArrayVertexBuffer();
+
+ UINT size() const { return mBufferSize; }
+ virtual void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset) = 0;
+ virtual void reserveRequiredSpace() = 0;
+ void addRequiredSpace(UINT requiredSpace);
+ void addRequiredSpaceFor(ArrayVertexBuffer *buffer);
+
+ protected:
+ UINT mBufferSize;
+ UINT mWritePosition;
+ UINT mRequiredSpace;
+};
+
+class StreamingVertexBuffer : public ArrayVertexBuffer
+{
+ public:
+ StreamingVertexBuffer(IDirect3DDevice9 *device, UINT initialSize);
+ ~StreamingVertexBuffer();
+
+ void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
+ void reserveRequiredSpace();
+};
+
+class StaticVertexBuffer : public ArrayVertexBuffer
+{
+ public:
+ explicit StaticVertexBuffer(IDirect3DDevice9 *device);
+ ~StaticVertexBuffer();
+
+ void *map(const VertexAttribute &attribute, UINT requiredSpace, UINT *streamOffset);
+ void reserveRequiredSpace();
+
+ UINT lookupAttribute(const VertexAttribute &attribute); // Returns the offset into the vertex buffer, or -1 if not found
+
+ private:
+ struct VertexElement
+ {
+ GLenum type;
+ GLint size;
+ bool normalized;
+ int attributeOffset;
+
+ UINT streamOffset;
+ };
+
+ std::vector<VertexElement> mCache;
+};
class VertexDataManager
{
public:
- VertexDataManager(Context *context, BufferBackEnd *backend);
- ~VertexDataManager();
+ VertexDataManager(Context *context, IDirect3DDevice9 *backend);
+ virtual ~VertexDataManager();
- void dirtyCurrentValues() { mDirtyCurrentValues = true; }
+ void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; }
- GLenum preRenderValidate(GLint start,
- GLsizei count,
- TranslatedAttribute *outAttribs);
+ void setupAttributes(const TranslatedAttribute *attributes);
+ GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs);
private:
- std::bitset<MAX_VERTEX_ATTRIBS> getActiveAttribs() const;
+ DISALLOW_COPY_AND_ASSIGN(VertexDataManager);
+
+ UINT spaceRequired(const VertexAttribute &attrib, std::size_t count) const;
+ UINT writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute);
+
+ Context *const mContext;
+ IDirect3DDevice9 *const mDevice;
+
+ StreamingVertexBuffer *mStreamingBuffer;
+
+ bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS];
+ ConstantVertexBuffer *mCurrentValueBuffer[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;
+ };
- void processNonArrayAttributes(const AttributeState *attribs, const std::bitset<MAX_VERTEX_ATTRIBS> &activeAttribs, TranslatedAttribute *translated, std::size_t count);
+ enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
- std::size_t typeSize(GLenum type) const;
- std::size_t interpretGlStride(const AttributeState &attrib) const;
+ FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
- std::size_t roundUp(std::size_t x, std::size_t multiple) const;
- std::size_t spaceRequired(const AttributeState &attrib, std::size_t maxVertex) const;
+ struct TranslationDescription
+ {
+ DWORD capsFlag;
+ FormatConverter preferredConversion;
+ FormatConverter fallbackConversion;
+ };
- Context *mContext;
- BufferBackEnd *mBackend;
+ // 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]
- TranslatedVertexBuffer *mStreamBuffer;
+ void checkVertexCaps(DWORD declTypes);
- bool mDirtyCurrentValues;
- std::size_t mCurrentValueOffset; // Offset within mCurrentValueBuffer that the current attribute values were last loaded at.
- TranslatedVertexBuffer *mCurrentValueBuffer;
+ unsigned int typeIndex(GLenum type) const;
+ const FormatConverter &formatConverter(const VertexAttribute &attribute) const;
};
}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp
deleted file mode 100644
index 3f5e283..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.cpp
+++ /dev/null
@@ -1,38 +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.
-//
-
-// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
-// that must be implemented by any API-specific implementation of ANGLE.
-
-#include "libGLESv2/geometry/backend.h"
-
-#include "common/debug.h"
-
-namespace gl
-{
-
-void *TranslatedBuffer::map(std::size_t requiredSpace, std::size_t *offset)
-{
- ASSERT(requiredSpace <= mBufferSize);
-
- reserveSpace(requiredSpace);
-
- *offset = mCurrentPoint;
- mCurrentPoint += requiredSpace;
-
- return streamingMap(*offset, requiredSpace);
-}
-
-void TranslatedBuffer::reserveSpace(std::size_t requiredSpace)
-{
- if (mCurrentPoint + requiredSpace > mBufferSize)
- {
- recycle();
- mCurrentPoint = 0;
- }
-}
-
-}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h
deleted file mode 100644
index d18a908..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/backend.h
+++ /dev/null
@@ -1,110 +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.
-//
-
-// geometry/backend.h: Abstract classes BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer
-// that must be implemented by any API-specific implementation of ANGLE.
-
-#ifndef LIBGLESV2_GEOMETRY_BACKEND_H_
-#define LIBGLESV2_GEOMETRY_BACKEND_H_
-
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "libGLESv2/Context.h"
-
-namespace gl
-{
-class TranslatedVertexBuffer;
-class TranslatedIndexBuffer;
-
-struct FormatConverter
-{
- bool identity;
- std::size_t outputVertexSize;
- void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
-};
-
-struct TranslatedAttribute
-{
- bool enabled;
- bool nonArray;
-
- // These are the original untranslated values. (Or just have some sort of BufferBackEnd::TranslatedTypeKey.)
- GLenum type;
- std::size_t size;
- bool normalized;
-
- std::size_t offset;
-
- std::size_t stride; // 0 means not to advance the read pointer at all
-
- std::size_t semanticIndex;
-
- TranslatedVertexBuffer *buffer;
-};
-
-class BufferBackEnd
-{
- public:
- virtual ~BufferBackEnd() { }
-
- virtual bool supportIntIndices() = 0;
-
- virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size) = 0;
- virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size) = 0;
- virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type) = 0;
- virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize) = 0;
-
- // For an identity-mappable stream, verify that the stride and offset are okay.
- virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const = 0;
-
- virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo) = 0;
- virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes) = 0;
-};
-
-class TranslatedBuffer
-{
- public:
- explicit TranslatedBuffer(std::size_t size) : mBufferSize(size), mCurrentPoint(0) { }
- virtual ~TranslatedBuffer() { }
-
- std::size_t size() const { return mBufferSize; }
-
- virtual void *map() = 0;
- virtual void unmap() = 0;
-
- void reserveSpace(std::size_t requiredSpace);
-
- void *map(std::size_t requiredSpace, std::size_t *offset);
-
- protected:
- virtual void recycle() = 0;
- virtual void *streamingMap(std::size_t offset, std::size_t size) = 0;
-
- private:
- std::size_t mBufferSize;
- std::size_t mCurrentPoint;
-
- DISALLOW_COPY_AND_ASSIGN(TranslatedBuffer);
-};
-
-class TranslatedVertexBuffer : public TranslatedBuffer
-{
- public:
- explicit TranslatedVertexBuffer(std::size_t size) : TranslatedBuffer(size) { }
-};
-
-class TranslatedIndexBuffer : public TranslatedBuffer
-{
- public:
- explicit TranslatedIndexBuffer(std::size_t size) : TranslatedBuffer(size) { }
-};
-
-}
-
-#endif // LIBGLESV2_GEOMETRY_BACKEND_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp
deleted file mode 100644
index e51befb..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.cpp
+++ /dev/null
@@ -1,613 +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.
-//
-
-// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
-
-#include "libGLESv2/geometry/dx9.h"
-
-#include <cstddef>
-
-#define GL_APICALL
-#include <GLES2/gl2.h>
-
-#include "common/debug.h"
-
-#include "libGLESv2/Context.h"
-#include "libGLESv2/main.h"
-#include "libGLESv2/geometry/vertexconversion.h"
-#include "libGLESv2/geometry/IndexDataManager.h"
-
-namespace
-{
-// 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<GLuint, 16> { };
-template <> struct ConversionRule<GL_FIXED, false, D3DVT_FLOAT> : gl::FixedToFloat<GLuint, 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 };
-};
-
-}
-
-namespace gl
-{
-Dx9BackEnd::Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice)
- : mDevice(d3ddevice)
-{
- mDevice->AddRef();
-
- for (int i = 0; i < MAX_VERTEX_ATTRIBS; ++i)
- {
- mAppliedAttribEnabled[i] = true;
- mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
- }
-
- mStreamFrequency[MAX_VERTEX_ATTRIBS] = STREAM_FREQUENCY_UNINSTANCED;
-
- D3DCAPS9 caps = context->getDeviceCaps();
-
- IDirect3D9 *d3dObject;
- mDevice->GetDirect3D(&d3dObject);
-
- D3DADAPTER_IDENTIFIER9 ident;
- d3dObject->GetAdapterIdentifier(caps.AdapterOrdinal, 0, &ident);
- d3dObject->Release();
-
- // Instancing is mandatory for all HW with SM3 vertex shaders, but avoid hardware where it does not work.
- mUseInstancingForStrideZero = (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) && ident.VendorId != 0x8086);
- mSupportIntIndices = (caps.MaxVertexIndex >= (1 << 16));
-
- checkVertexCaps(caps.DeclTypes);
-}
-
-Dx9BackEnd::~Dx9BackEnd()
-{
- mDevice->Release();
-}
-
-bool Dx9BackEnd::supportIntIndices()
-{
- return mSupportIntIndices;
-}
-
-// 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) }, \
- }
-
-const Dx9BackEnd::TranslationDescription Dx9BackEnd::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(GL_FIXED),
- TRANSLATIONS_FOR_TYPE(GL_FLOAT)
-};
-
-void Dx9BackEnd::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;
- }
- }
- }
- }
-}
-
-TranslatedVertexBuffer *Dx9BackEnd::createVertexBuffer(std::size_t size)
-{
- return new Dx9VertexBuffer(mDevice, size);
-}
-
-TranslatedVertexBuffer *Dx9BackEnd::createVertexBufferForStrideZero(std::size_t size)
-{
- if (mUseInstancingForStrideZero)
- {
- return new Dx9VertexBuffer(mDevice, size);
- }
- else
- {
- return new Dx9VertexBufferZeroStrideWorkaround(mDevice, size);
- }
-}
-
-TranslatedIndexBuffer *Dx9BackEnd::createIndexBuffer(std::size_t size, GLenum type)
-{
- return new Dx9IndexBuffer(mDevice, size, type);
-}
-
-// This is used to index mAttributeTypes and mPossibleTranslations.
-unsigned int Dx9BackEnd::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;
- }
-}
-
-FormatConverter Dx9BackEnd::getFormatConverter(GLenum type, std::size_t size, bool normalize)
-{
- return mAttributeTypes[typeIndex(type)][normalize][size-1].formatConverter;
-}
-
-D3DDECLTYPE Dx9BackEnd::mapAttributeType(GLenum type, std::size_t size, bool normalize) const
-{
- return mAttributeTypes[typeIndex(type)][normalize][size-1].d3dDeclType;
-}
-
-bool Dx9BackEnd::validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const
-{
- // D3D9 requires the stream offset and stride to be a multiple of DWORD.
- return (stride % sizeof(DWORD) == 0 && offset % sizeof(DWORD) == 0);
-}
-
-IDirect3DVertexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedVertexBuffer *vb) const
-{
- return vb ? static_cast<Dx9VertexBuffer*>(vb)->getBuffer() : NULL;
-}
-
-IDirect3DIndexBuffer9 *Dx9BackEnd::getDxBuffer(TranslatedIndexBuffer *ib) const
-{
- return ib ? static_cast<Dx9IndexBuffer*>(ib)->getBuffer() : NULL;
-}
-
-GLenum Dx9BackEnd::setupIndicesPreDraw(const TranslatedIndexData &indexInfo)
-{
- mDevice->SetIndices(getDxBuffer(indexInfo.buffer));
- return GL_NO_ERROR;
-}
-
-GLenum Dx9BackEnd::setupAttributesPreDraw(const TranslatedAttribute *attributes)
-{
- HRESULT hr;
-
- D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS+1];
-
- D3DVERTEXELEMENT9 *nextElement = &elements[0];
-
- for (BYTE i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].enabled)
- {
- nextElement->Stream = i + 1; // Stream 0 is skipped because D3D does not permit it to be an instanced stream.
- nextElement->Offset = 0;
- nextElement->Type = static_cast<BYTE>(mapAttributeType(attributes[i].type, attributes[i].size, attributes[i].normalized));
- nextElement->Method = D3DDECLMETHOD_DEFAULT;
- nextElement->Usage = D3DDECLUSAGE_TEXCOORD;
- nextElement->UsageIndex = attributes[i].semanticIndex;
- nextElement++;
- }
- }
-
- static const D3DVERTEXELEMENT9 end = D3DDECL_END();
- *nextElement = end;
-
- IDirect3DVertexDeclaration9* vertexDeclaration;
- hr = mDevice->CreateVertexDeclaration(elements, &vertexDeclaration);
- mDevice->SetVertexDeclaration(vertexDeclaration);
- vertexDeclaration->Release();
-
- mDevice->SetStreamSource(0, NULL, 0, 0);
-
- bool nonArrayAttributes = false;
-
- for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].enabled)
- {
- if (attributes[i].nonArray) nonArrayAttributes = true;
-
- mDevice->SetStreamSource(i + 1, getDxBuffer(attributes[i].buffer), attributes[i].offset, attributes[i].stride);
- if (!mAppliedAttribEnabled[i])
- {
- mAppliedAttribEnabled[i] = true;
- }
- }
- else
- {
- if (mAppliedAttribEnabled[i])
- {
- mDevice->SetStreamSource(i + 1, 0, 0, 0);
- mAppliedAttribEnabled[i] = false;
- }
- }
- }
-
- if (mUseInstancingForStrideZero)
- {
- // When there are no stride zero attributes, we disable instancing so that DrawPrimitive can be used.
-
- if (nonArrayAttributes)
- {
- if (mStreamFrequency[0] != STREAM_FREQUENCY_INDEXED)
- {
- mStreamFrequency[0] = STREAM_FREQUENCY_INDEXED;
- mDevice->SetStreamSourceFreq(0, D3DSTREAMSOURCE_INDEXEDDATA | 1);
- }
-
- for (size_t i = 0; i < MAX_VERTEX_ATTRIBS; i++)
- {
- if (attributes[i].enabled)
- {
- if (attributes[i].nonArray)
- {
- if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INSTANCED)
- {
- mStreamFrequency[i+1] = STREAM_FREQUENCY_INSTANCED;
- mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INSTANCEDATA | 1);
- }
- }
- else
- {
- if (mStreamFrequency[i+1] != STREAM_FREQUENCY_INDEXED)
- {
- mStreamFrequency[i+1] = STREAM_FREQUENCY_INDEXED;
- mDevice->SetStreamSourceFreq(i + 1, D3DSTREAMSOURCE_INDEXEDDATA | 1);
- }
- }
- }
- }
- }
- else
- {
- for (size_t i = 0; i < MAX_VERTEX_ATTRIBS + 1; i++)
- {
- if (mStreamFrequency[i] != STREAM_FREQUENCY_UNINSTANCED)
- {
- mStreamFrequency[i] = STREAM_FREQUENCY_UNINSTANCED;
-
- // This should not be needed, but otherwise there is a buggy driver that will leave instancing
- // enabled for the first draw after it has been turned off.
- mDevice->SetStreamSourceFreq(i, D3DSTREAMSOURCE_INDEXEDDATA | 1);
-
- mDevice->SetStreamSourceFreq(i, 1);
- }
- }
- }
- }
-
- return GL_NO_ERROR;
-}
-
-Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size)
- : TranslatedVertexBuffer(size)
-{
- HRESULT hr = device->CreateVertexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
- if (hr != S_OK)
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", size);
- throw std::bad_alloc();
- }
-}
-
-Dx9BackEnd::Dx9VertexBuffer::Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags)
- : TranslatedVertexBuffer(size)
-{
- HRESULT hr = device->CreateVertexBuffer(size, usageFlags, 0, D3DPOOL_DEFAULT, &mVertexBuffer, NULL);
- if (hr != S_OK)
- {
- ERR("Out of memory allocating a vertex buffer of size %lu.", size);
- throw std::bad_alloc();
- }
-}
-
-
-Dx9BackEnd::Dx9VertexBuffer::~Dx9VertexBuffer()
-{
- mVertexBuffer->Release();
-}
-
-IDirect3DVertexBuffer9 *Dx9BackEnd::Dx9VertexBuffer::getBuffer() const
-{
- return mVertexBuffer;
-}
-
-void *Dx9BackEnd::Dx9VertexBuffer::map()
-{
- void *mapPtr;
-
- mVertexBuffer->Lock(0, 0, &mapPtr, 0);
-
- return mapPtr;
-}
-
-void Dx9BackEnd::Dx9VertexBuffer::unmap()
-{
- mVertexBuffer->Unlock();
-}
-
-void Dx9BackEnd::Dx9VertexBuffer::recycle()
-{
- void *dummy;
- mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
- mVertexBuffer->Unlock();
-}
-
-void *Dx9BackEnd::Dx9VertexBuffer::streamingMap(std::size_t offset, std::size_t size)
-{
- void *mapPtr;
-
- mVertexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
-
- return mapPtr;
-}
-
-// Normally VBs are created with D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, but some hardware & drivers won't render
-// if any stride-zero streams are in D3DUSAGE_DYNAMIC VBs, so this provides a way to create such VBs with only D3DUSAGE_WRITEONLY set.
-// D3DLOCK_DISCARD and D3DLOCK_NOOVERWRITE are only available on D3DUSAGE_DYNAMIC VBs, so we override methods to avoid using these flags.
-Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size)
- : Dx9VertexBuffer(device, size, D3DUSAGE_WRITEONLY)
-{
-}
-
-void Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::recycle()
-{
-}
-
-void *Dx9BackEnd::Dx9VertexBufferZeroStrideWorkaround::streamingMap(std::size_t offset, std::size_t size)
-{
- void *mapPtr;
-
- getBuffer()->Lock(offset, size, &mapPtr, 0);
-
- return mapPtr;
-}
-
-Dx9BackEnd::Dx9IndexBuffer::Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type)
- : TranslatedIndexBuffer(size)
-{
- ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT);
-
- D3DFORMAT format = (type == GL_UNSIGNED_SHORT) ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
-
- HRESULT hr = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, D3DPOOL_DEFAULT, &mIndexBuffer, NULL);
- if (hr != S_OK)
- {
- ERR("Out of memory allocating an index buffer of size %lu.", size);
- throw std::bad_alloc();
- }
-}
-
-Dx9BackEnd::Dx9IndexBuffer::~Dx9IndexBuffer()
-{
- mIndexBuffer->Release();
-}
-
-IDirect3DIndexBuffer9*Dx9BackEnd::Dx9IndexBuffer::getBuffer() const
-{
- return mIndexBuffer;
-}
-
-void *Dx9BackEnd::Dx9IndexBuffer::map()
-{
- void *mapPtr;
-
- mIndexBuffer->Lock(0, 0, &mapPtr, 0);
-
- return mapPtr;
-}
-
-void Dx9BackEnd::Dx9IndexBuffer::unmap()
-{
- mIndexBuffer->Unlock();
-}
-
-void Dx9BackEnd::Dx9IndexBuffer::recycle()
-{
- void *dummy;
- mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
- mIndexBuffer->Unlock();
-}
-
-void *Dx9BackEnd::Dx9IndexBuffer::streamingMap(std::size_t offset, std::size_t size)
-{
- void *mapPtr;
-
- mIndexBuffer->Lock(offset, size, &mapPtr, D3DLOCK_NOOVERWRITE);
-
- return mapPtr;
-}
-
-}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h b/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h
deleted file mode 100644
index 6068dd6..0000000
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/geometry/dx9.h
+++ /dev/null
@@ -1,137 +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.
-//
-
-// geometry/dx9.h: Direct3D 9-based implementation of BufferBackEnd, TranslatedVertexBuffer and TranslatedIndexBuffer.
-
-#ifndef LIBGLESV2_GEOMETRY_DX9_H_
-#define LIBGLESV2_GEOMETRY_DX9_H_
-
-#include <d3d9.h>
-
-#include "libGLESv2/Buffer.h"
-#include "libGLESv2/geometry/backend.h"
-
-namespace gl
-{
-
-class Dx9BackEnd : public BufferBackEnd
-{
- public:
- explicit Dx9BackEnd(Context *context, IDirect3DDevice9 *d3ddevice);
- ~Dx9BackEnd();
-
- virtual bool supportIntIndices();
-
- virtual TranslatedVertexBuffer *createVertexBuffer(std::size_t size);
- virtual TranslatedVertexBuffer *createVertexBufferForStrideZero(std::size_t size);
- virtual TranslatedIndexBuffer *createIndexBuffer(std::size_t size, GLenum type);
- virtual FormatConverter getFormatConverter(GLenum type, std::size_t size, bool normalize);
-
- virtual bool validateStream(GLenum type, std::size_t size, std::size_t stride, std::size_t offset) const;
-
- virtual GLenum setupIndicesPreDraw(const TranslatedIndexData &indexInfo);
- virtual GLenum setupAttributesPreDraw(const TranslatedAttribute *attributes);
-
- private:
- IDirect3DDevice9 *mDevice;
-
- bool mUseInstancingForStrideZero;
- bool mSupportIntIndices;
-
- bool mAppliedAttribEnabled[MAX_VERTEX_ATTRIBS];
-
- enum StreamFrequency
- {
- STREAM_FREQUENCY_UNINSTANCED = 0,
- STREAM_FREQUENCY_INDEXED,
- STREAM_FREQUENCY_INSTANCED
- };
-
- StreamFrequency mStreamFrequency[MAX_VERTEX_ATTRIBS+1];
-
- struct TranslationInfo
- {
- FormatConverter formatConverter;
- D3DDECLTYPE d3dDeclType;
- };
-
- enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
-
- TranslationInfo mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size-1]
-
- struct TranslationDescription
- {
- DWORD capsFlag;
- TranslationInfo preferredConversion;
- TranslationInfo 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;
-
- class Dx9VertexBuffer : public TranslatedVertexBuffer
- {
- public:
- Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size);
- virtual ~Dx9VertexBuffer();
-
- IDirect3DVertexBuffer9 *getBuffer() const;
-
- protected:
- Dx9VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags);
-
- virtual void *map();
- virtual void unmap();
-
- virtual void recycle();
- virtual void *streamingMap(std::size_t offset, std::size_t size);
-
- private:
- IDirect3DVertexBuffer9 *mVertexBuffer;
- };
-
- class Dx9VertexBufferZeroStrideWorkaround : public Dx9VertexBuffer
- {
- public:
- Dx9VertexBufferZeroStrideWorkaround(IDirect3DDevice9 *device, std::size_t size);
-
- protected:
- virtual void recycle();
- virtual void *streamingMap(std::size_t offset, std::size_t size);
- };
-
- class Dx9IndexBuffer : public TranslatedIndexBuffer
- {
- public:
- Dx9IndexBuffer(IDirect3DDevice9 *device, std::size_t size, GLenum type);
- virtual ~Dx9IndexBuffer();
-
- IDirect3DIndexBuffer9 *getBuffer() const;
-
- protected:
- virtual void *map();
- virtual void unmap();
-
- virtual void recycle();
- virtual void *streamingMap(std::size_t offset, std::size_t size);
-
- private:
- IDirect3DIndexBuffer9 *mIndexBuffer;
- };
-
- IDirect3DVertexBuffer9 *getDxBuffer(TranslatedVertexBuffer *vb) const;
- IDirect3DIndexBuffer9 *getDxBuffer(TranslatedIndexBuffer *ib) const;
-
- D3DDECLTYPE mapAttributeType(GLenum type, std::size_t size, bool normalized) const;
-};
-
-}
-
-#endif // LIBGLESV2_GEOMETRY_DX9_H_
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
index 25d083b..543c0d2 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp
@@ -20,6 +20,7 @@
#include "libGLESv2/utilities.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/Context.h"
+#include "libGLESv2/Fence.h"
#include "libGLESv2/Framebuffer.h"
#include "libGLESv2/Program.h"
#include "libGLESv2/Renderbuffer.h"
@@ -736,7 +737,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
try
{
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+ if (level < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -746,34 +747,6 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
return error(GL_INVALID_VALUE);
}
- switch (target)
- {
- case GL_TEXTURE_2D:
- if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (width != height)
- {
- return error(GL_INVALID_VALUE);
- }
-
- if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
-
switch (internalformat)
{
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
@@ -792,6 +765,41 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
if (context)
{
+ if (level > context->getMaximumTextureLevel())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ if (width > (context->getMaximumTextureDimension() >> level) ||
+ height > (context->getMaximumTextureDimension() >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (width != height)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+ height > (context->getMaximumCubeTextureDimension() >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
if (!context->supportsCompressedTextures())
{
return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
@@ -859,7 +867,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return error(GL_INVALID_ENUM);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+ if (level < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -888,6 +896,11 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
if (context)
{
+ if (level > context->getMaximumTextureLevel())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
if (!context->supportsCompressedTextures())
{
return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
@@ -978,48 +991,6 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_VALUE);
}
- switch (target)
- {
- case GL_TEXTURE_2D:
- if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (width != height)
- {
- return error(GL_INVALID_VALUE);
- }
-
- if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
-
- switch (internalformat)
- {
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RGB:
- case GL_RGBA:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
- break;
- default:
- return error(GL_INVALID_VALUE);
- }
-
if (border != 0)
{
return error(GL_INVALID_VALUE);
@@ -1029,20 +1000,38 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (context)
{
- if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
- internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ switch (target)
{
- if (context->supportsCompressedTextures())
+ case GL_TEXTURE_2D:
+ if (width > (context->getMaximumTextureDimension() >> level) ||
+ height > (context->getMaximumTextureDimension() >> level))
{
- return error(GL_INVALID_OPERATION);
+ return error(GL_INVALID_VALUE);
}
- else
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (width != height)
{
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_VALUE);
}
+
+ if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+ height > (context->getMaximumCubeTextureDimension() >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
}
gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
@@ -1054,6 +1043,59 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
}
gl::Colorbuffer *source = framebuffer->getColorbuffer();
+ GLenum colorbufferFormat = source->getFormat();
+
+ // [OpenGL ES 2.0.24] table 3.9
+ switch (internalformat)
+ {
+ case GL_ALPHA:
+ if (colorbufferFormat != GL_ALPHA &&
+ colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ if (colorbufferFormat != GL_RGB &&
+ colorbufferFormat != GL_RGB565 &&
+ colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ if (colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -1062,11 +1104,6 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
return error(GL_INVALID_OPERATION);
}
-
- if (texture->isCompressed())
- {
- return error(GL_INVALID_OPERATION);
- }
texture->copyImage(level, internalformat, x, y, width, height, source);
}
@@ -1079,17 +1116,9 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
- if (texture->isCompressed())
- {
- return error(GL_INVALID_OPERATION);
- }
-
texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
- else
- {
- UNREACHABLE();
- }
+ else UNREACHABLE();
}
}
catch(std::bad_alloc&)
@@ -1111,7 +1140,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_ENUM);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+ if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -1130,7 +1159,13 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
if (context)
{
+ if (level > context->getMaximumTextureLevel())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+
if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
return error(GL_INVALID_FRAMEBUFFER_OPERATION);
@@ -1142,42 +1177,70 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
}
gl::Colorbuffer *source = framebuffer->getColorbuffer();
+ GLenum colorbufferFormat = source->getFormat();
+ gl::Texture *texture = NULL;
+
if (target == GL_TEXTURE_2D)
{
- gl::Texture2D *texture = context->getTexture2D();
+ texture = context->getTexture2D();
+ }
+ else if (gl::IsCubemapTextureTarget(target))
+ {
+ texture = context->getTextureCubeMap();
+ }
+ else UNREACHABLE();
- if (!texture)
- {
- return error(GL_INVALID_OPERATION);
- }
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
- if (texture->isCompressed())
+ GLenum textureFormat = texture->getFormat();
+
+ // [OpenGL ES 2.0.24] table 3.9
+ switch (textureFormat)
+ {
+ case GL_ALPHA:
+ if (colorbufferFormat != GL_ALPHA &&
+ colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
{
return error(GL_INVALID_OPERATION);
}
-
- texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
- }
- else if (gl::IsCubemapTextureTarget(target))
- {
- gl::TextureCubeMap *texture = context->getTextureCubeMap();
-
- if (!texture)
+ break;
+ case GL_LUMINANCE:
+ case GL_RGB:
+ if (colorbufferFormat != GL_RGB &&
+ colorbufferFormat != GL_RGB565 &&
+ colorbufferFormat != GL_RGB8_OES &&
+ colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
{
return error(GL_INVALID_OPERATION);
}
-
- if (texture->isCompressed())
+ break;
+ case GL_LUMINANCE_ALPHA:
+ case GL_RGBA:
+ if (colorbufferFormat != GL_RGBA &&
+ colorbufferFormat != GL_RGBA4 &&
+ colorbufferFormat != GL_RGB5_A1 &&
+ colorbufferFormat != GL_RGBA8_OES)
{
return error(GL_INVALID_OPERATION);
}
-
- texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
- }
- else
- {
- UNREACHABLE();
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ return error(GL_INVALID_OPERATION);
+ default:
+ return error(GL_INVALID_OPERATION);
}
+
+ texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
}
}
@@ -1293,6 +1356,33 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
}
}
+void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
+{
+ TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
+
+ try
+ {
+ if (n < 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ context->deleteFence(fences[i]);
+ }
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -1624,7 +1714,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index)
if (context)
{
- context->setVertexAttribEnabled(index, false);
+ context->setEnableVertexAttribArray(index, false);
}
}
catch(std::bad_alloc&)
@@ -1669,20 +1759,25 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv
return error(GL_INVALID_VALUE);
}
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- case GL_UNSIGNED_SHORT:
- case GL_UNSIGNED_INT:
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
-
gl::Context *context = gl::getContext();
if (context)
{
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT:
+ break;
+ case GL_UNSIGNED_INT:
+ if (!context->supports32bitIndices())
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
context->drawElements(mode, count, type, indices);
}
}
@@ -1739,7 +1834,33 @@ void __stdcall glEnableVertexAttribArray(GLuint index)
if (context)
{
- context->setVertexAttribEnabled(index, true);
+ context->setEnableVertexAttribArray(index, true);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
+void __stdcall glFinishFenceNV(GLuint fence)
+{
+ TRACE("(GLuint fence = %d)", fence);
+
+ try
+ {
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Fence* fenceObject = context->getFence(fence);
+
+ if (fenceObject == NULL)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ fenceObject->finishFence();
}
}
catch(std::bad_alloc&)
@@ -2046,6 +2167,33 @@ void __stdcall glGenerateMipmap(GLenum target)
}
}
+void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
+{
+ TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
+
+ try
+ {
+ if (n < 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ for (int i = 0; i < n; i++)
+ {
+ fences[i] = context->createFence();
+ }
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
@@ -2421,6 +2569,33 @@ GLenum __stdcall glGetError(void)
return GL_NO_ERROR;
}
+void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
+{
+ TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
+
+ try
+ {
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Fence *fenceObject = context->getFence(fence);
+
+ if (fenceObject == NULL)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ fenceObject->getFenceiv(pname, params);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
{
TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
@@ -3287,12 +3462,12 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
- const gl::AttributeState &attribState = context->getVertexAttribState(index);
+ const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname)
{
case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- *params = (GLfloat)(attribState.mEnabled ? GL_TRUE : GL_FALSE);
+ *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = (GLfloat)attribState.mSize;
@@ -3340,12 +3515,12 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
- const gl::AttributeState &attribState = context->getVertexAttribState(index);
+ const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
switch (pname)
{
case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
- *params = (attribState.mEnabled ? GL_TRUE : GL_FALSE);
+ *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_SIZE:
*params = attribState.mSize;
@@ -3414,28 +3589,27 @@ void __stdcall glHint(GLenum target, GLenum mode)
try
{
- switch (target)
+ switch (mode)
{
- case GL_GENERATE_MIPMAP_HINT:
- switch (mode)
- {
- case GL_FASTEST:
- case GL_NICEST:
- case GL_DONT_CARE:
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
+ case GL_FASTEST:
+ case GL_NICEST:
+ case GL_DONT_CARE:
break;
default:
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_ENUM);
}
gl::Context *context = gl::getContext();
- if (context)
+ switch (target)
{
- if (target == GL_GENERATE_MIPMAP_HINT)
- context->setGenerateMipmapHint(mode);
+ case GL_GENERATE_MIPMAP_HINT:
+ if (context) context->setGenerateMipmapHint(mode);
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
+ if (context) context->setFragmentShaderDerivativeHint(mode);
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
}
}
catch(std::bad_alloc&)
@@ -3504,6 +3678,34 @@ GLboolean __stdcall glIsEnabled(GLenum cap)
return false;
}
+GLboolean __stdcall glIsFenceNV(GLuint fence)
+{
+ TRACE("(GLuint fence = %d)", fence);
+
+ try
+ {
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Fence *fenceObject = context->getFence(fence);
+
+ if (fenceObject == NULL)
+ {
+ return GL_FALSE;
+ }
+
+ return fenceObject->isFence();
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY, GL_FALSE);
+ }
+
+ return GL_FALSE;
+}
+
GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
{
TRACE("(GLuint framebuffer = %d)", framebuffer);
@@ -3841,22 +4043,12 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
return error(GL_INVALID_ENUM);
}
- switch (internalformat)
+ if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
{
- case GL_DEPTH_COMPONENT16:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGB565:
- case GL_STENCIL_INDEX8:
- case GL_DEPTH24_STENCIL8_OES:
- case GL_RGB8_OES:
- case GL_RGBA8_OES:
- break;
- default:
return error(GL_INVALID_ENUM);
}
- if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
+ if (width < 0 || height < 0 || samples < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -3865,7 +4057,9 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp
if (context)
{
- if (samples > context->getMaxSupportedSamples())
+ if (width > context->getMaximumRenderbufferDimension() ||
+ height > context->getMaximumRenderbufferDimension() ||
+ samples > context->getMaxSupportedSamples())
{
return error(GL_INVALID_VALUE);
}
@@ -3929,6 +4123,37 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
}
}
+void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
+{
+ TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
+
+ try
+ {
+ if (condition != GL_ALL_COMPLETED_NV)
+ {
+ return error(GL_INVALID_ENUM);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Fence *fenceObject = context->getFence(fence);
+
+ if (fenceObject == NULL)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ fenceObject->setFence(condition);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
@@ -4196,6 +4421,34 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu
}
}
+GLboolean __stdcall glTestFenceNV(GLuint fence)
+{
+ TRACE("(GLuint fence = %d)", fence);
+
+ try
+ {
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ gl::Fence *fenceObject = context->getFence(fence);
+
+ if (fenceObject == NULL)
+ {
+ return error(GL_INVALID_OPERATION, GL_TRUE);
+ }
+
+ return fenceObject->testFence();
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ error(GL_OUT_OF_MEMORY);
+ }
+
+ return GL_TRUE;
+}
+
void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
@@ -4215,34 +4468,6 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
return error(GL_INVALID_VALUE);
}
- switch (target)
- {
- case GL_TEXTURE_2D:
- if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- if (width != height)
- {
- return error(GL_INVALID_VALUE);
- }
-
- if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
- {
- return error(GL_INVALID_VALUE);
- }
- break;
- default:
- return error(GL_INVALID_ENUM);
- }
-
if (internalformat != format)
{
return error(GL_INVALID_OPERATION);
@@ -4256,6 +4481,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
switch (type)
{
case GL_UNSIGNED_BYTE:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4266,6 +4493,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
{
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4277,6 +4506,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
case GL_UNSIGNED_BYTE:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
break;
default:
return error(GL_INVALID_ENUM);
@@ -4307,6 +4538,36 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (context)
{
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ if (width > (context->getMaximumTextureDimension() >> level) ||
+ height > (context->getMaximumTextureDimension() >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (width != height)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (width > (context->getMaximumCubeTextureDimension() >> level) ||
+ height > (context->getMaximumCubeTextureDimension() >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
{
@@ -4320,6 +4581,21 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
}
}
+ if (type == GL_FLOAT)
+ {
+ if (!context->supportsFloatTextures())
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+ else if (type == GL_HALF_FLOAT_OES)
+ {
+ if (!context->supportsHalfFloatTextures())
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -4462,7 +4738,7 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_ENUM);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
+ if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -4486,6 +4762,26 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
if (context)
{
+ if (level > context->getMaximumTextureLevel())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (format == GL_FLOAT)
+ {
+ if (!context->supportsFloatTextures())
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+ else if (format == GL_HALF_FLOAT_OES)
+ {
+ if (!context->supportsHalfFloatTextures())
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -4500,6 +4796,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (format != texture->getFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -4516,6 +4817,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (format != texture->getFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else
@@ -5435,6 +5741,14 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
{
{"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
{"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
+ {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
+ {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
+ {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
+ {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
+ {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
+ {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
+ {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
+ {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
};
for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
index a043ed8..b2dc23c 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def
@@ -147,7 +147,14 @@ EXPORTS
glTexImage3DOES @143
glBlitFramebufferANGLE @149
glRenderbufferStorageMultisampleANGLE @150
-
+ glDeleteFencesNV @151
+ glFinishFenceNV @152
+ glGenFencesNV @153
+ glGetFenceivNV @154
+ glIsFenceNV @155
+ glSetFenceNV @156
+ glTestFenceNV @157
+
; EGL dependencies
glCreateContext @144 NONAME
glDestroyContext @145 NONAME
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
index 1f43e7a..0d95080 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj
@@ -201,6 +201,10 @@
>
</File>
<File
+ RelativePath=".\Fence.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Framebuffer.cpp"
>
</File>
@@ -244,14 +248,6 @@
Name="Geometry"
>
<File
- RelativePath=".\geometry\backend.cpp"
- >
- </File>
- <File
- RelativePath=".\geometry\dx9.cpp"
- >
- </File>
- <File
RelativePath=".\geometry\IndexDataManager.cpp"
>
</File>
@@ -279,6 +275,10 @@
>
</File>
<File
+ RelativePath=".\Fence.h"
+ >
+ </File>
+ <File
RelativePath=".\Framebuffer.h"
>
</File>
@@ -334,14 +334,6 @@
Name="Geometry"
>
<File
- RelativePath=".\geometry\backend.h"
- >
- </File>
- <File
- RelativePath=".\geometry\dx9.h"
- >
- </File>
- <File
RelativePath=".\geometry\IndexDataManager.h"
>
</File>
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
index 7fc2bc4..a3f5243 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp
@@ -25,6 +25,8 @@ int UniformComponentCount(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:
@@ -68,6 +70,8 @@ GLenum UniformComponentType(GLenum type)
case GL_FLOAT_MAT4:
return GL_FLOAT;
case GL_INT:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_CUBE:
case GL_INT_VEC2:
case GL_INT_VEC3:
case GL_INT_VEC4:
@@ -247,6 +251,28 @@ int ComputePixelSize(GLenum format, GLenum type)
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_5_6_5:
return sizeof(unsigned short);
+ case GL_FLOAT:
+ switch (format)
+ {
+ case GL_ALPHA: return sizeof(float);
+ case GL_LUMINANCE: return sizeof(float);
+ case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
+ case GL_RGB: return sizeof(float) * 3;
+ case GL_RGBA: return sizeof(float) * 4;
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_HALF_FLOAT_OES:
+ switch (format)
+ {
+ case GL_ALPHA: return sizeof(unsigned short);
+ case GL_LUMINANCE: return sizeof(unsigned short);
+ case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
+ case GL_RGB: return sizeof(unsigned short) * 3;
+ case GL_RGBA: return sizeof(unsigned short) * 4;
+ default: UNREACHABLE();
+ }
+ break;
default: UNREACHABLE();
}
@@ -283,6 +309,21 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
return false;
}
+ case GL_FLOAT:
+ case GL_HALF_FLOAT_OES:
+ switch (format)
+ {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ return true;
+
+ default:
+ return false;
+ }
+
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_5_5_5_1:
return (format == GL_RGBA);
@@ -295,6 +336,69 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
}
}
+bool IsColorRenderable(GLenum internalformat)
+{
+ switch (internalformat)
+ {
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ return true;
+ case GL_DEPTH_COMPONENT16:
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
+bool IsDepthRenderable(GLenum internalformat)
+{
+ switch (internalformat)
+ {
+ case GL_DEPTH_COMPONENT16:
+ case GL_DEPTH24_STENCIL8_OES:
+ return true;
+ case GL_STENCIL_INDEX8:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
+bool IsStencilRenderable(GLenum internalformat)
+{
+ switch (internalformat)
+ {
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ return true;
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGB565:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ case GL_DEPTH_COMPONENT16:
+ return false;
+ default:
+ UNIMPLEMENTED();
+ }
+
+ return false;
+}
+
}
namespace es2dx
@@ -508,6 +612,10 @@ 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:
@@ -515,7 +623,6 @@ unsigned int GetAlphaSize(D3DFORMAT colorFormat)
case D3DFMT_A1R5G5B5:
return 1;
case D3DFMT_X8R8G8B8:
- case D3DFMT_X1R5G5B5:
case D3DFMT_R5G6B5:
return 0;
default: UNREACHABLE();
@@ -527,6 +634,10 @@ unsigned int GetRedSize(D3DFORMAT colorFormat)
{
switch (colorFormat)
{
+ case D3DFMT_A16B16G16R16F:
+ return 16;
+ case D3DFMT_A32B32G32R32F:
+ return 32;
case D3DFMT_A2R10G10B10:
return 10;
case D3DFMT_A8R8G8B8:
@@ -534,7 +645,6 @@ unsigned int GetRedSize(D3DFORMAT colorFormat)
return 8;
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
- case D3DFMT_X1R5G5B5:
return 5;
default: UNREACHABLE();
}
@@ -545,13 +655,16 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat)
{
switch (colorFormat)
{
+ case D3DFMT_A16B16G16R16F:
+ return 16;
+ case D3DFMT_A32B32G32R32F:
+ return 32;
case D3DFMT_A2R10G10B10:
return 10;
case D3DFMT_A8R8G8B8:
case D3DFMT_X8R8G8B8:
return 8;
case D3DFMT_A1R5G5B5:
- case D3DFMT_X1R5G5B5:
return 5;
case D3DFMT_R5G6B5:
return 6;
@@ -564,6 +677,10 @@ unsigned int GetBlueSize(D3DFORMAT colorFormat)
{
switch (colorFormat)
{
+ case D3DFMT_A16B16G16R16F:
+ return 16;
+ case D3DFMT_A32B32G32R32F:
+ return 32;
case D3DFMT_A2R10G10B10:
return 10;
case D3DFMT_A8R8G8B8:
@@ -571,7 +688,6 @@ unsigned int GetBlueSize(D3DFORMAT colorFormat)
return 8;
case D3DFMT_A1R5G5B5:
case D3DFMT_R5G6B5:
- case D3DFMT_X1R5G5B5:
return 5;
default: UNREACHABLE();
}
@@ -591,46 +707,46 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat)
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
+ //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only
+ //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only
default:
UNREACHABLE();
}
return 0;
}
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
+bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount)
{
switch (primitiveType)
{
case GL_POINTS:
*d3dPrimitiveType = D3DPT_POINTLIST;
- *d3dPrimitiveCount = primitiveCount;
+ *d3dPrimitiveCount = elementCount;
break;
case GL_LINES:
*d3dPrimitiveType = D3DPT_LINELIST;
- *d3dPrimitiveCount = primitiveCount / 2;
+ *d3dPrimitiveCount = elementCount / 2;
break;
case GL_LINE_LOOP:
*d3dPrimitiveType = D3DPT_LINESTRIP;
- *d3dPrimitiveCount = primitiveCount;
+ *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 = primitiveCount - 1;
+ *d3dPrimitiveCount = elementCount - 1;
break;
case GL_TRIANGLES:
*d3dPrimitiveType = D3DPT_TRIANGLELIST;
- *d3dPrimitiveCount = primitiveCount / 3;
+ *d3dPrimitiveCount = elementCount / 3;
break;
case GL_TRIANGLE_STRIP:
*d3dPrimitiveType = D3DPT_TRIANGLESTRIP;
- *d3dPrimitiveCount = primitiveCount - 2;
+ *d3dPrimitiveCount = elementCount - 2;
break;
case GL_TRIANGLE_FAN:
*d3dPrimitiveType = D3DPT_TRIANGLEFAN;
- *d3dPrimitiveCount = primitiveCount - 2;
+ *d3dPrimitiveCount = elementCount - 2;
break;
default:
return false;
@@ -672,3 +788,40 @@ D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
}
}
+
+namespace dx2es
+{
+
+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)
+{
+ 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;
+}
+
+}
diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
index b6c8ce5..85e8f26 100644
--- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
+++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h
@@ -36,6 +36,10 @@ bool IsCubemapTextureTarget(GLenum target);
bool IsTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type);
+bool IsColorRenderable(GLenum internalformat);
+bool IsDepthRenderable(GLenum internalformat);
+bool IsStencilRenderable(GLenum internalformat);
+
}
namespace es2dx
@@ -57,7 +61,7 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat);
unsigned int GetBlueSize(D3DFORMAT colorFormat);
unsigned int GetDepthSize(D3DFORMAT depthFormat);
unsigned int GetStencilSize(D3DFORMAT stencilFormat);
-bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
+bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
@@ -65,4 +69,12 @@ GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
}
+namespace dx2es
+{
+
+GLenum ConvertBackBufferFormat(D3DFORMAT format);
+GLenum ConvertDepthStencilFormat(D3DFORMAT format);
+
+}
+
#endif // LIBGLESV2_UTILITIES_H