diff options
Diffstat (limited to 'Source/ThirdParty/ANGLE')
148 files changed, 24696 insertions, 7188 deletions
diff --git a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj index aa91bdb..a33c5ce 100644 --- a/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj +++ b/Source/ThirdParty/ANGLE/ANGLE.xcodeproj/project.pbxproj @@ -3,10 +3,15 @@ archiveVersion = 1; classes = { }; - objectVersion = 42; + objectVersion = 46; objects = { /* Begin PBXBuildFile section */ + 49951C0314B7AAB30060E96E /* length_limits.h in Headers */ = {isa = PBXBuildFile; fileRef = 49951C0214B7AAB30060E96E /* length_limits.h */; }; + 49951C0914B7AAD80060E96E /* BuiltInFunctionEmulator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */; }; + 49951C0A14B7AAD80060E96E /* BuiltInFunctionEmulator.h in Headers */ = {isa = PBXBuildFile; fileRef = 49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */; }; + 49951C0B14B7AAD80060E96E /* DetectRecursion.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49951C0714B7AAD80060E96E /* DetectRecursion.cpp */; }; + 49951C0C14B7AAD80060E96E /* DetectRecursion.h in Headers */ = {isa = PBXBuildFile; fileRef = 49951C0814B7AAD80060E96E /* DetectRecursion.h */; }; 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 */; }; @@ -23,6 +28,16 @@ 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 */; }; + A0AABE2C13AFE81000F2EBD1 /* ForLoopUnroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE2A13AFE81000F2EBD1 /* ForLoopUnroll.cpp */; }; + A0AABE2D13AFE81000F2EBD1 /* ForLoopUnroll.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE2B13AFE81000F2EBD1 /* ForLoopUnroll.h */; }; + A0AABE3013AFE83000F2EBD1 /* MapLongVariableNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE2E13AFE83000F2EBD1 /* MapLongVariableNames.cpp */; }; + A0AABE3113AFE83000F2EBD1 /* MapLongVariableNames.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE2F13AFE83000F2EBD1 /* MapLongVariableNames.h */; }; + A0AABE3413AFE84700F2EBD1 /* OutputGLSLBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE3213AFE84700F2EBD1 /* OutputGLSLBase.cpp */; }; + A0AABE3513AFE84700F2EBD1 /* OutputGLSLBase.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE3313AFE84700F2EBD1 /* OutputGLSLBase.h */; }; + A0AABE4413AFE94500F2EBD1 /* OutputESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE4213AFE94500F2EBD1 /* OutputESSL.cpp */; }; + A0AABE4513AFE94500F2EBD1 /* OutputESSL.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */; }; + A0AABE4813AFE96100F2EBD1 /* TranslatorESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */; }; + A0AABE4913AFE96100F2EBD1 /* TranslatorESSL.h in Headers */ = {isa = PBXBuildFile; fileRef = A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.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 */; }; @@ -53,6 +68,11 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 49951C0214B7AAB30060E96E /* length_limits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = length_limits.h; sourceTree = "<group>"; }; + 49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BuiltInFunctionEmulator.cpp; sourceTree = "<group>"; }; + 49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltInFunctionEmulator.h; sourceTree = "<group>"; }; + 49951C0714B7AAD80060E96E /* DetectRecursion.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DetectRecursion.cpp; sourceTree = "<group>"; }; + 49951C0814B7AAD80060E96E /* DetectRecursion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DetectRecursion.h; sourceTree = "<group>"; }; 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>"; }; @@ -73,6 +93,16 @@ 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>"; }; + A0AABE2A13AFE81000F2EBD1 /* ForLoopUnroll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ForLoopUnroll.cpp; sourceTree = "<group>"; }; + A0AABE2B13AFE81000F2EBD1 /* ForLoopUnroll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ForLoopUnroll.h; sourceTree = "<group>"; }; + A0AABE2E13AFE83000F2EBD1 /* MapLongVariableNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapLongVariableNames.cpp; sourceTree = "<group>"; }; + A0AABE2F13AFE83000F2EBD1 /* MapLongVariableNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapLongVariableNames.h; sourceTree = "<group>"; }; + A0AABE3213AFE84700F2EBD1 /* OutputGLSLBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputGLSLBase.cpp; sourceTree = "<group>"; }; + A0AABE3313AFE84700F2EBD1 /* OutputGLSLBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputGLSLBase.h; sourceTree = "<group>"; }; + A0AABE4213AFE94500F2EBD1 /* OutputESSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputESSL.cpp; sourceTree = "<group>"; }; + A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OutputESSL.h; sourceTree = "<group>"; }; + A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorESSL.cpp; sourceTree = "<group>"; }; + A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TranslatorESSL.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>"; }; @@ -340,14 +370,28 @@ FB39D2201200F35A00088E69 /* compiler */ = { isa = PBXGroup; children = ( + A0AABE3213AFE84700F2EBD1 /* OutputGLSLBase.cpp */, + A0AABE3313AFE84700F2EBD1 /* OutputGLSLBase.h */, + A0AABE4613AFE96100F2EBD1 /* TranslatorESSL.cpp */, + A0AABE4713AFE96100F2EBD1 /* TranslatorESSL.h */, + A0AABE4213AFE94500F2EBD1 /* OutputESSL.cpp */, + A0AABE4313AFE94500F2EBD1 /* OutputESSL.h */, + A0AABE2E13AFE83000F2EBD1 /* MapLongVariableNames.cpp */, + A0AABE2F13AFE83000F2EBD1 /* MapLongVariableNames.h */, + A0AABE2A13AFE81000F2EBD1 /* ForLoopUnroll.cpp */, + A0AABE2B13AFE81000F2EBD1 /* ForLoopUnroll.h */, FB39D2441200F35A00088E69 /* preprocessor */, FB39D2211200F35A00088E69 /* BaseTypes.h */, + 49951C0514B7AAD70060E96E /* BuiltInFunctionEmulator.cpp */, + 49951C0614B7AAD80060E96E /* BuiltInFunctionEmulator.h */, FB39D2221200F35A00088E69 /* CodeGenGLSL.cpp */, FB39D2241200F35A00088E69 /* Common.h */, 90D9B0F912E11DCB002D4255 /* Compiler.cpp */, FB39D2251200F35A00088E69 /* ConstantUnion.h */, FB39D2261200F35A00088E69 /* debug.cpp */, FB39D2271200F35A00088E69 /* debug.h */, + 49951C0714B7AAD80060E96E /* DetectRecursion.cpp */, + 49951C0814B7AAD80060E96E /* DetectRecursion.h */, 90D9B0FA12E11DCB002D4255 /* ExtensionBehavior.h */, 90D9B0FB12E11DCB002D4255 /* glslang_lex.cpp */, 90D9B0FC12E11DCB002D4255 /* glslang_tab.cpp */, @@ -415,6 +459,7 @@ FB39D2481200F35A00088E69 /* cpp.c */, FB39D2491200F35A00088E69 /* cpp.h */, FB39D24A1200F35A00088E69 /* cppstruct.c */, + 49951C0214B7AAB30060E96E /* length_limits.h */, FB39D24B1200F35A00088E69 /* memory.c */, FB39D24C1200F35A00088E69 /* memory.h */, FB39D24D1200F35A00088E69 /* parser.h */, @@ -455,6 +500,14 @@ 90D9B11612E11DD6002D4255 /* ValidateLimitations.h in Headers */, 90D9B11812E11DD6002D4255 /* VariableInfo.h in Headers */, 90D9B11A12E11DD6002D4255 /* VersionGLSL.h in Headers */, + A0AABE2D13AFE81000F2EBD1 /* ForLoopUnroll.h in Headers */, + A0AABE3113AFE83000F2EBD1 /* MapLongVariableNames.h in Headers */, + A0AABE3513AFE84700F2EBD1 /* OutputGLSLBase.h in Headers */, + A0AABE4513AFE94500F2EBD1 /* OutputESSL.h in Headers */, + A0AABE4913AFE96100F2EBD1 /* TranslatorESSL.h in Headers */, + 49951C0314B7AAB30060E96E /* length_limits.h in Headers */, + 49951C0A14B7AAD80060E96E /* BuiltInFunctionEmulator.h in Headers */, + 49951C0C14B7AAD80060E96E /* DetectRecursion.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -483,8 +536,12 @@ /* Begin PBXProject section */ FB39D0701200ED9200088E69 /* Project object */ = { isa = PBXProject; + attributes = { + LastUpgradeCheck = 0440; + }; buildConfigurationList = FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "ANGLE" */; - compatibilityVersion = "Xcode 2.4"; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( English, @@ -540,6 +597,13 @@ 90D9B11512E11DD6002D4255 /* ValidateLimitations.cpp in Sources */, 90D9B11712E11DD6002D4255 /* VariableInfo.cpp in Sources */, 90D9B11912E11DD6002D4255 /* VersionGLSL.cpp in Sources */, + A0AABE2C13AFE81000F2EBD1 /* ForLoopUnroll.cpp in Sources */, + A0AABE3013AFE83000F2EBD1 /* MapLongVariableNames.cpp in Sources */, + A0AABE3413AFE84700F2EBD1 /* OutputGLSLBase.cpp in Sources */, + A0AABE4413AFE94500F2EBD1 /* OutputESSL.cpp in Sources */, + A0AABE4813AFE96100F2EBD1 /* TranslatorESSL.cpp in Sources */, + 49951C0914B7AAD80060E96E /* BuiltInFunctionEmulator.cpp in Sources */, + 49951C0B14B7AAD80060E96E /* DetectRecursion.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Source/ThirdParty/ANGLE/Android.mk b/Source/ThirdParty/ANGLE/Android.mk new file mode 100644 index 0000000..e4b348b --- /dev/null +++ b/Source/ThirdParty/ANGLE/Android.mk @@ -0,0 +1,77 @@ +# +# Copyright (C) 2011, 2012, Sony Ericsson Mobile Communications AB +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the Sony Ericsson Mobile Communications AB nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL SONY ERICSSON MOBILE COMMUNICATIONS AB BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# Compiler src +LOCAL_SRC_FILES := \ + BuiltInFunctionEmulator.cpp \ + Compiler.cpp \ + DetectRecursion.cpp \ + ForLoopUnroll.cpp \ + InfoSink.cpp \ + Initialize.cpp \ + InitializeDll.cpp \ + IntermTraverse.cpp \ + Intermediate.cpp \ + MapLongVariableNames.cpp \ + ParseHelper.cpp \ + PoolAlloc.cpp \ + QualifierAlive.cpp \ + RemoveTree.cpp \ + ShaderLang.cpp \ + SymbolTable.cpp \ + ValidateLimitations.cpp \ + VariableInfo.cpp \ + debug.cpp \ + intermOut.cpp \ + ossource_posix.cpp \ + parseConst.cpp \ + util.cpp + +# Code generator +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + CodeGenGLSL.cpp \ + OutputESSL.cpp \ + OutputGLSL.cpp \ + OutputGLSLBase.cpp \ + TranslatorESSL.cpp \ + TranslatorGLSL.cpp \ + VersionGLSL.cpp \ + +# Generated files +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + glslang_lex.cpp \ + glslang_tab.cpp + +# Preprocessor +LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \ + preprocessor/atom.c \ + preprocessor/cpp.c \ + preprocessor/cppstruct.c \ + preprocessor/memory.c \ + preprocessor/scanner.c \ + preprocessor/symbols.c \ + preprocessor/tokens.c diff --git a/Source/ThirdParty/ANGLE/ChangeLog b/Source/ThirdParty/ANGLE/ChangeLog index 374c349..5029207 100644 --- a/Source/ThirdParty/ANGLE/ChangeLog +++ b/Source/ThirdParty/ANGLE/ChangeLog @@ -1,3 +1,1728 @@ +2012-03-26 Dean Jackson <dino@apple.com> + + Update ANGLE in WebKit + https://bugs.webkit.org/show_bug.cgi?id=81717 + + Reviewed by Kenneth Russell. + + Update angleproject to r1009. Synced the source directory + between the angle repository and WebKit. Ran the OS X Lion + version of Bison over the glslang.l input which generates + a slightly different output than angle provided. + + * include/EGL/eglext.h: + * include/GLES2/gl2ext.h: + * include/GLSLANG/ShaderLang.h: + * src/common/RefCountObject.cpp: Renamed from Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.cpp. + (RefCountObject::RefCountObject): + (RefCountObject::~RefCountObject): + (RefCountObject::addRef): + (RefCountObject::release): + (RefCountObjectBindingPointer::set): + * src/common/RefCountObject.h: Renamed from Source/ThirdParty/ANGLE/src/libGLESv2/RefCountObject.h. + (RefCountObject): + (RefCountObject::id): + (RefCountObjectBindingPointer): + (RefCountObjectBindingPointer::RefCountObjectBindingPointer): + (RefCountObjectBindingPointer::~RefCountObjectBindingPointer): + (RefCountObjectBindingPointer::get): + (RefCountObjectBindingPointer::id): + (RefCountObjectBindingPointer::operator ! ): + (BindingPointer): + (BindingPointer::set): + (BindingPointer::get): + (BindingPointer::operator -> ): + * src/common/debug.cpp: + (gl::output): + * src/common/version.h: + * src/compiler/BaseTypes.h: + * src/compiler/Compiler.cpp: + (TCompiler::TCompiler): + (TCompiler::~TCompiler): + (TCompiler::mapLongVariableNames): + * src/compiler/ConstantUnion.h: + (ConstantUnion::ConstantUnion): + (ConstantUnion::operator==): + (ConstantUnion::operator>): + (ConstantUnion::operator<): + * src/compiler/Intermediate.cpp: + (TIntermConstantUnion::fold): + * src/compiler/MapLongVariableNames.cpp: + (LongNameMap::LongNameMap): + (LongNameMap::~LongNameMap): + (LongNameMap::GetInstance): + (LongNameMap::Release): + (LongNameMap::Find): + (LongNameMap::Insert): + (LongNameMap::Size): + (MapLongVariableNames::MapLongVariableNames): + (MapLongVariableNames::visitSymbol): + (MapLongVariableNames::mapGlobalLongName): + * src/compiler/MapLongVariableNames.h: + (LongNameMap): + (MapLongVariableNames): + * src/compiler/OutputHLSL.cpp: + (sh::OutputHLSL::OutputHLSL): + (sh::OutputHLSL::header): + (sh::OutputHLSL::visitSymbol): + (sh::OutputHLSL::visitUnary): + (sh::OutputHLSL::visitAggregate): + (sh::OutputHLSL::visitLoop): + (sh::OutputHLSL::handleExcessiveLoop): + (sh::OutputHLSL::typeString): + (sh::OutputHLSL::addConstructor): + (sh::OutputHLSL::decorateUniform): + * src/compiler/OutputHLSL.h: + (OutputHLSL): + * src/compiler/PoolAlloc.cpp: + (TAllocation::checkGuardBlock): + * src/compiler/ShHandle.h: + (TCompiler): + * src/compiler/SymbolTable.cpp: + * src/compiler/SymbolTable.h: + (TSymbolTable): + (TSymbolTable::getOuterLevel): + * src/compiler/VariableInfo.cpp: + (getVariableDataType): + * src/compiler/glslang.l: + * src/compiler/glslang.y: + * src/compiler/glslang_lex.cpp: + (yy_buffer_state): + (yyguts_t): + (input): + (yyensure_buffer_stack): + (yy_scan_bytes): + (yyget_leng): + * src/compiler/glslang_tab.cpp: + * src/compiler/osinclude.h: + * src/compiler/preprocessor/cpp.c: + * src/compiler/preprocessor/memory.c: + * src/compiler/preprocessor/new/Context.cpp: Added. + (isMacroNameReserved): + (pp): + (pp::Context::Context): + (pp::Context::~Context): + (pp::Context::init): + (pp::Context::process): + (pp::Context::defineMacro): + (pp::Context::undefineMacro): + (pp::Context::isMacroDefined): + (pp::Context::reset): + (pp::Context::defineBuiltInMacro): + * src/compiler/preprocessor/new/Context.h: Added. + (pp): + (Context): + (pp::Context::lexer): + (pp::Context::output): + * src/compiler/preprocessor/new/Input.cpp: Added. + (pp): + (pp::Input::Input): + (pp::Input::eof): + (pp::Input::read): + (pp::Input::getChar): + (pp::Input::peekChar): + (pp::Input::switchToNextString): + (pp::Input::isStringEmpty): + (pp::Input::stringLength): + * src/compiler/preprocessor/new/Input.h: Added. + (pp): + (Input): + (pp::Input::error): + (pp::Input::stringIndex): + * src/compiler/preprocessor/new/Macro.cpp: Added. + (pp): + (pp::Macro::Macro): + (pp::Macro::~Macro): + * src/compiler/preprocessor/new/Macro.h: Added. + (pp): + (Macro): + (pp::Macro::type): + (pp::Macro::identifier): + (pp::Macro::parameters): + (pp::Macro::replacements): + * src/compiler/preprocessor/new/Preprocessor.cpp: Added. + (pp): + (pp::Preprocessor::Preprocessor): + (pp::Preprocessor::~Preprocessor): + (pp::Preprocessor::init): + (pp::Preprocessor::process): + (pp::Preprocessor::reset): + * src/compiler/preprocessor/new/Preprocessor.h: Added. + (pp): + (Preprocessor): + (pp::Preprocessor::begin): + (pp::Preprocessor::end): + * src/compiler/preprocessor/new/Token.cpp: Added. + (pp): + (pp::Token::encodeLocation): + (pp::Token::decodeLocation): + (pp::Token::Token): + (pp::Token::~Token): + (pp::operator<<): + * src/compiler/preprocessor/new/Token.h: Added. + (pp): + (Token): + (pp::Token::location): + (pp::Token::type): + (pp::Token::value): + * src/compiler/preprocessor/new/generate_parser.sh: Added. + * src/compiler/preprocessor/new/pp.l: Added. + * src/compiler/preprocessor/new/pp.y: Added. + * src/compiler/preprocessor/new/pp_lex.cpp: Added. + (yy_buffer_state): + (yy_trans_info): + (yyguts_t): + (yy_get_previous_state): + (yy_try_NUL_trans): + (input): + (pprestart): + (pp_switch_to_buffer): + (pp_load_buffer_state): + (pp_create_buffer): + (pp_delete_buffer): + (pp_init_buffer): + (pp_flush_buffer): + (pppush_buffer_state): + (pppop_buffer_state): + (ppensure_buffer_stack): + (pp_scan_buffer): + (pp_scan_string): + (pp_scan_bytes): + (yy_push_state): + (yy_pop_state): + (yy_top_state): + (yy_fatal_error): + (ppget_extra): + (ppget_lineno): + (ppget_column): + (ppget_in): + (ppget_out): + (ppget_leng): + (ppget_text): + (ppset_extra): + (ppset_lineno): + (ppset_column): + (ppset_in): + (ppset_out): + (ppget_debug): + (ppset_debug): + (ppget_lval): + (ppset_lval): + (ppget_lloc): + (ppset_lloc): + (pplex_init): + (pplex_init_extra): + (yy_init_globals): + (pplex_destroy): + (yy_flex_strncpy): + (yy_flex_strlen): + (ppalloc): + (pprealloc): + (ppfree): + (extractMacroName): + (pp): + (pp::Context::readInput): + (pp::Context::initLexer): + (pp::Context::destroyLexer): + * src/compiler/preprocessor/new/pp_tab.cpp: Added. + (YYLTYPE): + (yysyntax_error): + (yyerror): + (pushConditionalBlock): + (popConditionalBlock): + (pp::Context::parse): + * src/compiler/preprocessor/new/pp_tab.h: Added. + (YYLTYPE): + * src/compiler/preprocessor/new/stl_utils.h: Added. + (pp): + (Delete): + (pp::Delete::operator()): + (DeleteSecond): + (pp::DeleteSecond::operator()): + * src/compiler/preprocessor/new/token_type.h: Added. + * src/compiler/preprocessor/scanner.c: + (yylex_CPP): + * src/compiler/preprocessor/symbols.c: + * src/compiler/preprocessor/tokens.c: + * src/libEGL/Config.cpp: + (egl::ConfigSet::getConfigs): + * src/libEGL/Display.cpp: + (egl::Display::initialize): + (egl::Display::terminate): + (egl::Display::restoreLostDevice): + (egl::Display::sync): + (egl): + (egl::Display::allocateEventQuery): + (egl::Display::freeEventQuery): + (egl::Display::getFloat32TextureSupport): + (egl::Display::getFloat16TextureSupport): + (egl::Display::getEventQuerySupport): + (egl::Display::initExtensionString): + (egl::Display::shareHandleSupported): + (egl::Display::getOcclusionQuerySupport): + (egl::Display::getInstancingSupport): + * src/libEGL/Display.h: + (Display): + (egl::Display::isD3d9ExDevice): + * src/libEGL/Surface.cpp: + (egl::Surface::resetSwapChain): + * src/libEGL/libEGL.cpp: + * src/libEGL/libEGL.vcproj: + * src/libGLESv2/Blit.cpp: + (gl::Blit::setCommonBlitState): + * src/libGLESv2/Buffer.h: + (Buffer): + * src/libGLESv2/Context.cpp: + (gl::Context::Context): + (gl::Context::~Context): + (gl::Context::makeCurrent): + (gl::Context::getActiveQuery): + (gl): + (gl::Context::createFence): + (gl::Context::createQuery): + (gl::Context::deleteQuery): + (gl::Context::beginQuery): + (gl::Context::endQuery): + (gl::Context::getQuery): + (gl::Context::applyVertexBuffer): + (gl::Context::applyIndexBuffer): + (gl::Context::readPixels): + (gl::Context::clear): + (gl::Context::drawArrays): + (gl::Context::drawElements): + (gl::Context::sync): + (gl::Context::drawLineLoop): + (gl::Context::supportsOcclusionQueries): + (gl::Context::supportsInstancing): + (gl::Context::setVertexAttribDivisor): + (gl::Context::initExtensionString): + (gl::VertexDeclarationCache::applyDeclaration): + (gl::VertexDeclarationCache::markStateDirty): + * src/libGLESv2/Context.h: + (gl): + (gl::VertexAttribute::VertexAttribute): + (State): + (VertexDeclarationCache): + (Context): + * src/libGLESv2/Fence.cpp: + (gl::Fence::Fence): + (gl::Fence::~Fence): + (gl::Fence::setFence): + * src/libGLESv2/Fence.h: + (egl): + (Fence): + * src/libGLESv2/Framebuffer.cpp: + (gl::Framebuffer::lookupRenderbuffer): + (gl::Framebuffer::detachTexture): + (gl::Framebuffer::completeness): + * src/libGLESv2/Framebuffer.h: + * src/libGLESv2/IndexDataManager.cpp: + (gl::IndexDataManager::IndexDataManager): + (gl::IndexDataManager::~IndexDataManager): + (gl::computeRange): + (gl::IndexDataManager::prepareIndexData): + (gl::IndexDataManager::getCountingIndices): + (gl): + * src/libGLESv2/IndexDataManager.h: + (IndexDataManager): + * src/libGLESv2/Program.cpp: + (gl::Program::getUniformLocation): + (gl::Program::setUniform1fv): + (gl::Program::setUniform2fv): + (gl::Program::setUniform3fv): + (gl::Program::setUniform4fv): + (gl::Program::setUniform1iv): + (gl::Program::setUniform2iv): + (gl::Program::setUniform3iv): + (gl::Program::setUniform4iv): + (gl::Program::packVaryings): + (gl::Program::linkVaryings): + (gl::Program::defineUniform): + (gl::Program::createUniform): + (gl::Program::applyUniformnbv): + (gl::Program::applyUniform1iv): + (gl::Program::applyUniform2iv): + (gl::Program::applyUniform3iv): + (gl::Program::applyUniform4iv): + (gl::Program::getInfoLog): + * src/libGLESv2/Program.h: + (Program): + * src/libGLESv2/Query.cpp: Added. + (gl): + (gl::Query::Query): + (gl::Query::~Query): + (gl::Query::begin): + (gl::Query::end): + (gl::Query::getResult): + (gl::Query::isResultAvailable): + (gl::Query::getType): + (gl::Query::testQuery): + * src/libGLESv2/Query.h: Added. + (gl): + (Query): + * src/libGLESv2/Renderbuffer.cpp: + (gl): + (gl::RenderbufferInterface::addProxyRef): + (gl::RenderbufferInterface::releaseProxy): + (gl::RenderbufferTexture::RenderbufferTexture): + (gl::RenderbufferTexture::~RenderbufferTexture): + (gl::RenderbufferTexture::addProxyRef): + (gl::RenderbufferTexture::releaseProxy): + (gl::Renderbuffer::addRef): + (gl::Renderbuffer::release): + * src/libGLESv2/Renderbuffer.h: + (gl): + (RenderbufferInterface): + (RenderbufferTexture): + (Renderbuffer): + * src/libGLESv2/Shader.cpp: + (gl::Shader::Shader): + (gl::Shader::getInfoLog): + (gl::Shader::getSourceImpl): + (gl): + (gl::Shader::initializeCompiler): + (gl::Shader::parseVaryings): + (gl::Shader::uncompile): + (gl::Shader::compileToHLSL): + (gl::VertexShader::uncompile): + (gl::VertexShader::compile): + (gl::VertexShader::parseAttributes): + (gl::FragmentShader::compile): + * src/libGLESv2/Shader.h: + (Shader): + (VertexShader): + * src/libGLESv2/Texture.cpp: + (gl::Texture2D::Texture2D): + (gl::Texture2D::~Texture2D): + (gl): + (gl::Texture2D::addProxyRef): + (gl::Texture2D::releaseProxy): + (gl::Texture2D::getRenderbuffer): + (gl::TextureCubeMap::TextureCubeMap): + (gl::TextureCubeMap::~TextureCubeMap): + (gl::TextureCubeMap::addProxyRef): + (gl::TextureCubeMap::releaseProxy): + (gl::TextureCubeMap::isSamplerComplete): + (gl::TextureCubeMap::convertToRenderTarget): + (gl::TextureCubeMap::getRenderbuffer): + * src/libGLESv2/Texture.h: + (Texture): + (Texture2D): + (TextureCubeMap): + * src/libGLESv2/VertexDataManager.cpp: + (gl::VertexDataManager::writeAttributeData): + (gl::VertexDataManager::prepareVertexData): + (gl::VertexDataManager::spaceRequired): + (gl): + * src/libGLESv2/VertexDataManager.h: + (TranslatedAttribute): + (VertexDataManager): + * src/libGLESv2/libGLESv2.cpp: + * src/libGLESv2/libGLESv2.def: + * src/libGLESv2/libGLESv2.vcproj: + * src/libGLESv2/utilities.cpp: + (gl::IsInternalTextureTarget): + * src/libGLESv2/utilities.h: + (gl): + +2012-03-09 Ashod Nakashian <ashodnakashian@yahoo.com> + + Bash scripts should support LF endings only + https://bugs.webkit.org/show_bug.cgi?id=79509 + + Reviewed by David Kilzer. + + * src/compiler/generate_parser.sh: Added property svn:eol-style. + +2012-02-21 Sam Weinig <sam@webkit.org> + + Attempt to fix the Snow Leopard build. + + * Configurations/Base.xcconfig: + +2012-02-21 Sam Weinig <sam@webkit.org> + + Use libc++ when building with Clang on Mac + https://bugs.webkit.org/show_bug.cgi?id=78981 + + Reviewed by Dan Bernstein. + + * Configurations/Base.xcconfig: + +2012-01-07 Chris Marrin <cmarrin@apple.com> + + Fixed a warning in GTK build of ANGLE + + Unreviewed. + + * src/compiler/DetectRecursion.cpp: + (DetectRecursion::~DetectRecursion): + +2012-01-06 Mark Rowe <mrowe@apple.com> + + Regenerate a few files with a more appropriate version of bison. + + Rubber-stamped by Dan Bernstein. + + * src/compiler/glslang.l: Tweak the input so that it generates code that compiles without warnings. + * src/compiler/glslang_lex.cpp: + * src/compiler/glslang_tab.cpp: + * src/compiler/glslang_tab.h: + +2012-01-06 Chris Marrin <cmarrin@apple.com> + + Update ANGLE in WebKit tree + https://bugs.webkit.org/show_bug.cgi?id=75753 + + Reviewed by Simon Fraser. + + Updated ANGLE to r939. Fixed a compiler error (missing case in switch statement) + and added 5 new files to xcodeproj. Other than that it is a straight copy of + the files from the ANGLE repository. + + * ANGLE.xcodeproj/project.pbxproj: + * include/EGL/eglext.h: + * include/EGL/eglplatform.h: + * include/GLES2/gl2ext.h: + * include/GLSLANG/ShaderLang.h: + * src/common/debug.cpp: + (gl::output): + (gl::trace): + (gl::perfActive): + (gl::ScopedPerfEventHelper::ScopedPerfEventHelper): + (gl::ScopedPerfEventHelper::~ScopedPerfEventHelper): + * src/common/version.h: + * src/compiler/BaseTypes.h: + (getBasicString): + * src/compiler/BuiltInFunctionEmulator.cpp: Added. + (BuiltInFunctionEmulator::BuiltInFunctionEmulator): + (BuiltInFunctionEmulator::SetFunctionCalled): + (BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition): + (BuiltInFunctionEmulator::IdentifyFunction): + (BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation): + (BuiltInFunctionEmulator::Cleanup): + (BuiltInFunctionEmulator::GetEmulatedFunctionName): + * src/compiler/BuiltInFunctionEmulator.h: Added. + * src/compiler/Compiler.cpp: + (TCompiler::TCompiler): + (TCompiler::compile): + (TCompiler::clearResults): + (TCompiler::detectRecursion): + (TCompiler::getMappedNameMaxLength): + (TCompiler::getBuiltInFunctionEmulator): + * src/compiler/DetectRecursion.cpp: Added. + (DetectRecursion::FunctionNode::FunctionNode): + (DetectRecursion::FunctionNode::getName): + (DetectRecursion::FunctionNode::addCallee): + (DetectRecursion::FunctionNode::detectRecursion): + (DetectRecursion::DetectRecursion): + (DetectRecursion::~DetectRecursion): + (DetectRecursion::visitAggregate): + (DetectRecursion::detectRecursion): + (DetectRecursion::findFunctionByName): + * src/compiler/DetectRecursion.h: Added. + * src/compiler/ExtensionBehavior.h: + * src/compiler/ForLoopUnroll.cpp: + (ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling): + * src/compiler/ForLoopUnroll.h: + * src/compiler/Initialize.cpp: + (BuiltInFunctionsCommon): + (BuiltInFunctionsVertex): + (BuiltInFunctionsFragment): + (TBuiltIns::initialize): + (IdentifyBuiltIns): + (InitExtensionBehavior): + * src/compiler/MapLongVariableNames.cpp: + (MapLongVariableNames::MapLongVariableNames): + (MapLongVariableNames::visitSymbol): + (MapLongVariableNames::mapVaryingLongName): + * src/compiler/MapLongVariableNames.h: + * src/compiler/OutputGLSLBase.cpp: + (TOutputGLSLBase::visitUnary): + (TOutputGLSLBase::visitAggregate): + * src/compiler/OutputHLSL.cpp: + (sh::OutputHLSL::OutputHLSL): + (sh::OutputHLSL::header): + (sh::OutputHLSL::visitSymbol): + (sh::OutputHLSL::visitAggregate): + (sh::OutputHLSL::visitSelection): + (sh::OutputHLSL::visitLoop): + (sh::OutputHLSL::handleExcessiveLoop): + (sh::OutputHLSL::addConstructor): + (sh::OutputHLSL::decorate): + (sh::OutputHLSL::decorateUniform): + * src/compiler/OutputHLSL.h: + * src/compiler/ParseHelper.cpp: + (TParseContext::recover): + (TParseContext::reservedErrorCheck): + (TParseContext::constructorErrorCheck): + (TParseContext::extensionErrorCheck): + (TParseContext::supportsExtension): + (TParseContext::enterStructDeclaration): + (TParseContext::exitStructDeclaration): + (TParseContext::structNestingErrorCheck): + * src/compiler/ParseHelper.h: + (TParseContext::TParseContext): + * src/compiler/PoolAlloc.h: + (pool_allocator::pool_allocator): + (pool_allocator::operator=): + (pool_allocator::setAllocator): + (pool_allocator::getAllocator): + * src/compiler/ShHandle.h: + * src/compiler/ShaderLang.cpp: + (checkActiveUniformAndAttribMaxLengths): + (checkMappedNameMaxLength): + (getVariableInfo): + (ShInitBuiltInResources): + (ShGetInfo): + * src/compiler/SymbolTable.cpp: + (TType::computeDeepestStructNesting): + * src/compiler/TranslatorESSL.cpp: + (TranslatorESSL::translate): + (TranslatorESSL::writeExtensionBehavior): + * src/compiler/TranslatorGLSL.cpp: + (TranslatorGLSL::translate): + * src/compiler/Types.h: + (TType::TType): + (TType::copyType): + (TType::setStruct): + (TType::getDeepestStructNesting): + * src/compiler/UnfoldSelect.cpp: + (sh::UnfoldSelect::traverse): + (sh::UnfoldSelect::visitSelection): + (sh::UnfoldSelect::visitLoop): + (sh::UnfoldSelect::getNextTemporaryIndex): + * src/compiler/UnfoldSelect.h: + * src/compiler/ValidateLimitations.cpp: + * src/compiler/ValidateLimitations.h: + * src/compiler/VariableInfo.cpp: + (getVariableDataType): + * src/compiler/generate_glslang_lexer.sh: Removed. + * src/compiler/generate_glslang_parser.sh: Removed. + * src/compiler/generate_parser.sh: Added. + * src/compiler/glslang.l: + * src/compiler/glslang.y: + * src/compiler/glslang_lex.cpp: + (yy_get_previous_state): + (yy_try_NUL_trans): + * src/compiler/glslang_tab.cpp: + * src/compiler/glslang_tab.h: + * src/compiler/intermOut.cpp: + (TOutputTraverser::visitAggregate): + * src/compiler/intermediate.h: + (TIntermUnary::TIntermUnary): + (TIntermUnary::setUseEmulatedFunction): + (TIntermUnary::getUseEmulatedFunction): + (TIntermAggregate::TIntermAggregate): + (TIntermAggregate::setUseEmulatedFunction): + (TIntermAggregate::getUseEmulatedFunction): + * src/compiler/osinclude.h: + * src/compiler/ossource_posix.cpp: + (OS_AllocTLSIndex): + (OS_SetTLSValue): + (OS_FreeTLSIndex): + * src/compiler/preprocessor/atom.c: + (GrowAtomTable): + * src/compiler/preprocessor/length_limits.h: Added. + * src/compiler/preprocessor/scanner.h: + * src/libEGL/Display.cpp: + (egl::Display::getDisplay): + (egl::Display::Display): + (egl::Display::~Display): + (egl::Display::initialize): + (egl::Display::terminate): + (egl::Display::startScene): + (egl::Display::endScene): + (egl::Display::createDevice): + (egl::Display::initializeDevice): + (egl::Display::resetDevice): + (egl::Display::createWindowSurface): + (egl::Display::createOffscreenSurface): + (egl::Display::createContext): + (egl::Display::restoreLostDevice): + (egl::Display::notifyDeviceLost): + (egl::Display::isDeviceLost): + (egl::Display::testDeviceLost): + (egl::Display::testDeviceResettable): + (egl::Display::getDXT1TextureSupport): + (egl::Display::getDXT3TextureSupport): + (egl::Display::getDXT5TextureSupport): + (egl::Display::getFloat32TextureSupport): + (egl::Display::getFloat16TextureSupport): + (egl::Display::getTexturePool): + (egl::Display::initExtensionString): + * src/libEGL/Display.h: + * src/libEGL/Surface.cpp: + (egl::Surface::Surface): + (egl::Surface::initialize): + (egl::Surface::resetSwapChain): + (egl::Surface::subclassWindow): + (egl::Surface::unsubclassWindow): + (egl::Surface::swap): + (egl::Surface::postSubBuffer): + (egl::Surface::isPostSubBufferSupported): + * src/libEGL/Surface.h: + * src/libEGL/libEGL.cpp: + * src/libEGL/libEGL.rc: + * src/libEGL/libEGL.vcproj: + * src/libGLESv2/Buffer.cpp: + (gl::Buffer::bufferSubData): + * src/libGLESv2/Context.cpp: + (gl::Context::Context): + (gl::Context::makeCurrent): + (gl::Context::markAllStateDirty): + (gl::Context::markContextLost): + (gl::Context::isContextLost): + (gl::Context::setPackReverseRowOrder): + (gl::Context::getPackReverseRowOrder): + (gl::Context::deleteProgram): + (gl::Context::getDrawFramebuffer): + (gl::Context::bindDrawFramebuffer): + (gl::Context::useProgram): + (gl::Context::setFramebufferZero): + (gl::Context::getCurrentProgram): + (gl::Context::getBooleanv): + (gl::Context::getIntegerv): + (gl::Context::getQueryParameterInfo): + (gl::Context::applyRenderTarget): + (gl::Context::applyState): + (gl::Context::applyVertexBuffer): + (gl::Context::applyIndexBuffer): + (gl::Context::applyShaders): + (gl::Context::applyTextures): + (gl::Context::readPixels): + (gl::Context::clear): + (gl::Context::drawArrays): + (gl::Context::drawElements): + (gl::Context::sync): + (gl::Context::drawClosingLine): + (gl::Context::getResetStatus): + (gl::Context::isResetNotificationEnabled): + (gl::Context::supportsDXT1Textures): + (gl::Context::supportsDXT3Textures): + (gl::Context::supportsDXT5Textures): + (gl::Context::supportsFloat32Textures): + (gl::Context::supportsFloat32LinearFilter): + (gl::Context::supportsFloat32RenderableTextures): + (gl::Context::supportsFloat16Textures): + (gl::Context::supportsFloat16LinearFilter): + (gl::Context::supportsFloat16RenderableTextures): + (gl::Context::initExtensionString): + (gl::Context::initRendererString): + (gl::Context::getRendererString): + (gl::Context::blitFramebuffer): + (gl::VertexDeclarationCache::applyDeclaration): + (gl::VertexDeclarationCache::markStateDirty): + * src/libGLESv2/Context.h: + * src/libGLESv2/Fence.cpp: + (gl::Fence::testFence): + (gl::Fence::getFenceiv): + * src/libGLESv2/Framebuffer.cpp: + (gl::Framebuffer::setColorbuffer): + (gl::Framebuffer::setDepthbuffer): + (gl::Framebuffer::setStencilbuffer): + (gl::Framebuffer::getColorbuffer): + (gl::Framebuffer::getDepthbuffer): + (gl::Framebuffer::getStencilbuffer): + (gl::Framebuffer::hasStencil): + (gl::Framebuffer::completeness): + (gl::DefaultFramebuffer::DefaultFramebuffer): + * src/libGLESv2/Framebuffer.h: + * src/libGLESv2/IndexDataManager.cpp: + (gl::IndexDataManager::prepareIndexData): + (gl::IndexBuffer::IndexBuffer): + (gl::IndexBuffer::getSerial): + (gl::IndexBuffer::issueSerial): + (gl::StreamingIndexBuffer::reserveSpace): + (gl::StaticIndexBuffer::reserveSpace): + (gl::StaticIndexBuffer::lookupRange): + (gl::StaticIndexBuffer::addRange): + * src/libGLESv2/IndexDataManager.h: + (gl::StaticIndexBuffer::IndexRange::operator<): + * src/libGLESv2/Program.cpp: + (gl::Uniform::Uniform): + (gl::Uniform::isArray): + (gl::UniformLocation::UniformLocation): + (gl::Program::Program): + (gl::Program::detachShader): + (gl::Program::getUsedSamplerRange): + (gl::Program::getSamplerMapping): + (gl::Program::getUniformLocation): + (gl::Program::setUniform1fv): + (gl::Program::setUniform2fv): + (gl::Program::setUniform3fv): + (gl::transposeMatrix): + (gl::Program::setUniformMatrix2fv): + (gl::Program::setUniformMatrix3fv): + (gl::Program::setUniformMatrix4fv): + (gl::Program::getUniformfv): + (gl::Program::getUniformiv): + (gl::Program::applyUniforms): + (gl::Program::compileToBinary): + (gl::Program::linkVaryings): + (gl::Program::link): + (gl::Program::defineUniform): + (gl::Program::createUniform): + (gl::Program::decorateAttribute): + (gl::Program::undecorateUniform): + (gl::Program::applyUniformnbv): + (gl::Program::applyUniformnfv): + (gl::Program::applyUniform1iv): + (gl::Program::applyUniform2iv): + (gl::Program::applyUniform3iv): + (gl::Program::applyUniform4iv): + (gl::Program::applyUniformniv): + (gl::Program::appendToInfoLogSanitized): + (gl::Program::unlink): + (gl::Program::getActiveUniform): + (gl::Program::getActiveUniformCount): + (gl::Program::getActiveUniformMaxLength): + (gl::Program::validateSamplers): + (gl::Program::initializeConstantHandles): + (gl::Program::getDxCoordLocation): + * src/libGLESv2/Program.h: + * src/libGLESv2/Renderbuffer.cpp: + (gl::RenderbufferInterface::RenderbufferInterface): + (gl::RenderbufferInterface::getRedSize): + (gl::RenderbufferInterface::getGreenSize): + (gl::RenderbufferInterface::getBlueSize): + (gl::RenderbufferInterface::getAlphaSize): + (gl::RenderbufferInterface::getDepthSize): + (gl::RenderbufferInterface::getStencilSize): + (gl::RenderbufferTexture::RenderbufferTexture): + (gl::RenderbufferTexture::~RenderbufferTexture): + (gl::RenderbufferTexture::getRenderTarget): + (gl::RenderbufferTexture::getDepthStencil): + (gl::RenderbufferTexture::getWidth): + (gl::RenderbufferTexture::getHeight): + (gl::RenderbufferTexture::getInternalFormat): + (gl::RenderbufferTexture::getD3DFormat): + (gl::RenderbufferTexture::getSamples): + (gl::RenderbufferTexture::getSerial): + (gl::Renderbuffer::Renderbuffer): + (gl::Renderbuffer::~Renderbuffer): + (gl::Renderbuffer::getRenderTarget): + (gl::Renderbuffer::getDepthStencil): + (gl::Renderbuffer::getWidth): + (gl::Renderbuffer::getHeight): + (gl::Renderbuffer::getInternalFormat): + (gl::Renderbuffer::getD3DFormat): + (gl::Renderbuffer::getRedSize): + (gl::Renderbuffer::getGreenSize): + (gl::Renderbuffer::getBlueSize): + (gl::Renderbuffer::getAlphaSize): + (gl::Renderbuffer::getDepthSize): + (gl::Renderbuffer::getStencilSize): + (gl::Renderbuffer::getSamples): + (gl::Renderbuffer::getSerial): + (gl::Renderbuffer::setStorage): + (gl::RenderbufferStorage::getD3DFormat): + (gl::RenderbufferStorage::issueCubeSerials): + (gl::Colorbuffer::Colorbuffer): + (gl::Colorbuffer::getRenderTarget): + (gl::Depthbuffer::Depthbuffer): + (gl::Stencilbuffer::Stencilbuffer): + * src/libGLESv2/Renderbuffer.h: + (gl::RenderbufferInterface::~RenderbufferInterface): + * src/libGLESv2/Shader.cpp: + (gl::Shader::getTranslatedSourceLength): + (gl::Shader::getSourceImpl): + (gl::Shader::getSource): + (gl::Shader::getTranslatedSource): + * src/libGLESv2/Shader.h: + * src/libGLESv2/Texture.cpp: + (gl::ConvertTextureFormatType): + (gl::IsTextureFormatRenderable): + (gl::Image::Image): + (gl::Image::~Image): + (gl::Image::redefine): + (gl::Image::createSurface): + (gl::Image::lock): + (gl::Image::unlock): + (gl::Image::isRenderableFormat): + (gl::Image::getD3DFormat): + (gl::Image::getSurface): + (gl::Image::setManagedSurface): + (gl::Image::updateSurface): + (gl::Image::loadData): + (gl::Image::loadAlphaData): + (gl::Image::loadAlphaFloatData): + (gl::Image::loadAlphaHalfFloatData): + (gl::Image::loadLuminanceData): + (gl::Image::loadLuminanceFloatData): + (gl::Image::loadLuminanceHalfFloatData): + (gl::Image::loadLuminanceAlphaData): + (gl::Image::loadLuminanceAlphaFloatData): + (gl::Image::loadLuminanceAlphaHalfFloatData): + (gl::Image::loadRGBUByteData): + (gl::Image::loadRGB565Data): + (gl::Image::loadRGBFloatData): + (gl::Image::loadRGBHalfFloatData): + (gl::Image::loadRGBAUByteDataSSE2): + (gl::Image::loadRGBAUByteData): + (gl::Image::loadRGBA4444Data): + (gl::Image::loadRGBA5551Data): + (gl::Image::loadRGBAFloatData): + (gl::Image::loadRGBAHalfFloatData): + (gl::Image::loadBGRAData): + (gl::Image::loadCompressedData): + (gl::FlipCopyDXT1BlockFull): + (gl::FlipCopyDXT1BlockHalf): + (gl::FlipCopyDXT3BlockFull): + (gl::FlipCopyDXT3BlockHalf): + (gl::FlipCopyDXT5BlockFull): + (gl::FlipCopyDXT5BlockHalf): + (gl::Image::loadDXT1Data): + (gl::Image::loadDXT3Data): + (gl::Image::loadDXT5Data): + (gl::Image::copy): + (gl::TextureStorage::TextureStorage): + (gl::TextureStorage::~TextureStorage): + (gl::TextureStorage::isRenderTarget): + (gl::TextureStorage::isManaged): + (gl::TextureStorage::getPool): + (gl::TextureStorage::getTextureSerial): + (gl::TextureStorage::issueTextureSerial): + (gl::Texture::Texture): + (gl::Texture::~Texture): + (gl::Texture::setMinFilter): + (gl::Texture::setMagFilter): + (gl::Texture::setWrapS): + (gl::Texture::setWrapT): + (gl::Texture::setUsage): + (gl::Texture::getMinFilter): + (gl::Texture::getMagFilter): + (gl::Texture::getWrapS): + (gl::Texture::getWrapT): + (gl::Texture::getUsage): + (gl::Texture::setImage): + (gl::Texture::setCompressedImage): + (gl::Texture::subImage): + (gl::Texture::subImageCompressed): + (gl::Texture::getTexture): + (gl::Texture::hasDirtyParameters): + (gl::Texture::hasDirtyImages): + (gl::Texture::resetDirty): + (gl::Texture::getTextureSerial): + (gl::Texture::getRenderTargetSerial): + (gl::Texture::isImmutable): + (gl::Texture::creationLevels): + (gl::Texture::getBlitter): + (gl::Texture::copyToRenderTarget): + (gl::TextureStorage2D::TextureStorage2D): + (gl::TextureStorage2D::~TextureStorage2D): + (gl::TextureStorage2D::getSurfaceLevel): + (gl::TextureStorage2D::getBaseTexture): + (gl::TextureStorage2D::getRenderTargetSerial): + (gl::Texture2D::Texture2D): + (gl::Texture2D::~Texture2D): + (gl::Texture2D::getWidth): + (gl::Texture2D::getHeight): + (gl::Texture2D::getInternalFormat): + (gl::Texture2D::getType): + (gl::Texture2D::redefineImage): + (gl::Texture2D::setImage): + (gl::Texture2D::bindTexImage): + (gl::Texture2D::releaseTexImage): + (gl::Texture2D::setCompressedImage): + (gl::Texture2D::commitRect): + (gl::Texture2D::copyImage): + (gl::Texture2D::copySubImage): + (gl::Texture2D::storage): + (gl::Texture2D::isSamplerComplete): + (gl::Texture2D::isMipmapComplete): + (gl::Texture2D::getBaseTexture): + (gl::Texture2D::createTexture): + (gl::Texture2D::updateTexture): + (gl::Texture2D::convertToRenderTarget): + (gl::Texture2D::generateMipmaps): + (gl::Texture2D::getRenderbuffer): + (gl::Texture2D::getRenderTarget): + (gl::Texture2D::getStorage): + (gl::TextureStorageCubeMap::TextureStorageCubeMap): + (gl::TextureStorageCubeMap::~TextureStorageCubeMap): + (gl::TextureStorageCubeMap::getCubeMapSurface): + (gl::TextureStorageCubeMap::getBaseTexture): + (gl::TextureStorageCubeMap::getRenderTargetSerial): + (gl::TextureCubeMap::TextureCubeMap): + (gl::TextureCubeMap::~TextureCubeMap): + (gl::TextureCubeMap::getWidth): + (gl::TextureCubeMap::getHeight): + (gl::TextureCubeMap::getInternalFormat): + (gl::TextureCubeMap::getType): + (gl::TextureCubeMap::setCompressedImage): + (gl::TextureCubeMap::commitRect): + (gl::TextureCubeMap::subImage): + (gl::TextureCubeMap::subImageCompressed): + (gl::TextureCubeMap::isSamplerComplete): + (gl::TextureCubeMap::isCubeComplete): + (gl::TextureCubeMap::isMipmapCubeComplete): + (gl::TextureCubeMap::getBaseTexture): + (gl::TextureCubeMap::createTexture): + (gl::TextureCubeMap::updateTexture): + (gl::TextureCubeMap::convertToRenderTarget): + (gl::TextureCubeMap::setImage): + (gl::TextureCubeMap::redefineImage): + (gl::TextureCubeMap::copyImage): + (gl::TextureCubeMap::copySubImage): + (gl::TextureCubeMap::storage): + (gl::TextureCubeMap::generateMipmaps): + (gl::TextureCubeMap::getRenderbuffer): + (gl::TextureCubeMap::getRenderTarget): + (gl::TextureCubeMap::getStorage): + * src/libGLESv2/Texture.h: + (gl::Image::markDirty): + (gl::Image::markClean): + (gl::Image::getWidth): + (gl::Image::getHeight): + (gl::Image::getFormat): + (gl::Image::getType): + (gl::Image::isDirty): + * src/libGLESv2/VertexDataManager.cpp: + (gl::elementsInBuffer): + (gl::VertexDataManager::VertexDataManager): + (gl::VertexDataManager::writeAttributeData): + (gl::VertexDataManager::prepareVertexData): + (gl::VertexBuffer::VertexBuffer): + (gl::VertexBuffer::getSerial): + (gl::VertexBuffer::issueSerial): + (gl::StreamingVertexBuffer::reserveRequiredSpace): + (gl::StaticVertexBuffer::map): + (gl::StaticVertexBuffer::reserveRequiredSpace): + (gl::StaticVertexBuffer::lookupAttribute): + * src/libGLESv2/VertexDataManager.h: + (gl::ArrayVertexBuffer::size): + * src/libGLESv2/geometry/IndexDataManager.cpp: Removed. + * src/libGLESv2/geometry/IndexDataManager.h: Removed. + * src/libGLESv2/geometry/VertexDataManager.cpp: Removed. + * src/libGLESv2/geometry/VertexDataManager.h: Removed. + * src/libGLESv2/geometry/vertexconversion.h: Removed. + * src/libGLESv2/libGLESv2.cpp: + (validateSubImageParams): + (validReadFormatType): + (Extension::glBindTexImage): + * src/libGLESv2/libGLESv2.def: + * src/libGLESv2/libGLESv2.rc: + * src/libGLESv2/libGLESv2.vcproj: + * src/libGLESv2/main.cpp: + (gl::getNonLostContext): + (gl::checkDeviceLost): + * src/libGLESv2/main.h: + * src/libGLESv2/utilities.cpp: + (gl::UniformExternalComponentCount): + (gl::UniformInternalComponentCount): + (gl::UniformComponentSize): + (gl::UniformInternalSize): + (gl::UniformExternalSize): + (gl::ComputeCompressedSize): + (gl::IsCompressed): + (gl::ExtractFormat): + (gl::ExtractType): + (dx2es::IsFloat32Format): + (dx2es::IsFloat16Format): + * src/libGLESv2/utilities.h: + (isDeviceLostError): + +2011-11-11 Darin Adler <darin@apple.com> + + * ANGLE.xcodeproj/project.pbxproj: Let a newer Xcode update this file. + If an older Xcode downgrades this file and we have a risk of some kind of + oscillating commit situation, please contact me so I know not to do this again. + +2011-09-19 Adam Roben <aroben@apple.com> + + Let Xcode 4 do its thang with ANGLE.xcodeproj + + * ANGLE.xcodeproj/project.pbxproj: + +2011-09-13 Anders Carlsson <andersca@apple.com> + + Disable C++ exceptions when building with clang + https://bugs.webkit.org/show_bug.cgi?id=68031 + <rdar://problem/9556880> + + Reviewed by Mark Rowe. + + * Configurations/Base.xcconfig: + +2011-09-08 Andras Becsi <andras.becsi@nokia.com> + + [Qt] Build fails with strict compiler + https://bugs.webkit.org/show_bug.cgi?id=67778 + + Reviewed by Csaba Osztrogonác. + + * src/compiler/glslang_lex.cpp: Regenerate with generate_glslang_lexer.sh using a newer flex + to suppress warning and fix the build when using [-Werror=unused-result] + +2011-08-12 Mark Rowe <mrowe@apple.com> + + Be more forward-looking in the choice of compiler. + + Rubber-stamped by Jon Honeycutt. + + * Configurations/CompilerVersion.xcconfig: + +2011-08-11 Renata Hodovan <reni@webkit.org> + + [Qt]Fix warnings after r92805. + + Reviewed by Csaba Osztrogonác. + + Control reached the end non-void functions. + + * src/compiler/ossource_posix.cpp: + (OS_AllocTLSIndex): + (OS_SetTLSValue): + +2011-08-11 Renata Hodovan <reni@webkit.org> + + Build fix on Qt Windows 32-bit Release/Debug after r92805. + + Unreviewed. + + * src/compiler/ossource_posix.cpp: + (OS_FreeTLSIndex): + +2011-08-04 Mark Rowe <mrowe@apple.com> + + Future-proof Xcode configuration settings. + + * Configurations/Base.xcconfig: + * Configurations/CompilerVersion.xcconfig: + * Configurations/DebugRelease.xcconfig: + +2011-06-30 Mark Rowe <mrowe@apple.com> + + Rubber-stamped by Dan Bernstein. + + ANGLE shouldn't try to use internal SDKs. It doesn't need them! + + * Configurations/Base.xcconfig: + +2011-06-20 Zhenyao Mo <zmo@google.com> + + Reviewed by Kenneth Russell. + + Update ANGLE to r696 + https://bugs.webkit.org/show_bug.cgi?id=56396 + + * ANGLE.xcodeproj/project.pbxproj: + * include/EGL/eglext.h: + * include/GLSLANG/ShaderLang.h: + * src/build_angle.xcodeproj/project.pbxproj: + * src/common/debug.cpp: + (gl::output): + (gl::trace): + (gl::perfActive): + (gl::ScopedPerfEventHelper::ScopedPerfEventHelper): + (gl::ScopedPerfEventHelper::~ScopedPerfEventHelper): + * src/common/debug.h: + * src/common/version.h: Added. + * src/compiler/CodeGenGLSL.cpp: + (ConstructCompiler): + * src/compiler/CodeGenHLSL.cpp: + (ConstructCompiler): + * src/compiler/Compiler.cpp: + (TCompiler::compile): + (TCompiler::mapLongVariableNames): + (TCompiler::getMappedNameMaxLength): + (TCompiler::getExtensionBehavior): + * src/compiler/ConstantUnion.h: + (ConstantUnion::operator==): + (ConstantUnion::operator>): + (ConstantUnion::operator<): + * src/compiler/ExtensionBehavior.h: + (getBehaviorString): + * src/compiler/ForLoopUnroll.cpp: Added. + (ForLoopUnroll::FillLoopIndexInfo): + (ForLoopUnroll::Step): + (ForLoopUnroll::SatisfiesLoopCondition): + (ForLoopUnroll::NeedsToReplaceSymbolWithValue): + (ForLoopUnroll::GetLoopIndexValue): + (ForLoopUnroll::Push): + (ForLoopUnroll::Pop): + (ForLoopUnroll::getLoopIncrement): + (ForLoopUnroll::evaluateIntConstant): + * src/compiler/ForLoopUnroll.h: Added. + (ForLoopUnroll::ForLoopUnroll): + * src/compiler/Initialize.cpp: + (BuiltInFunctionsVertex): + * src/compiler/MapLongVariableNames.cpp: Added. + (MapLongVariableNames::MapLongVariableNames): + (MapLongVariableNames::visitSymbol): + (MapLongVariableNames::visitConstantUnion): + (MapLongVariableNames::visitBinary): + (MapLongVariableNames::visitUnary): + (MapLongVariableNames::visitSelection): + (MapLongVariableNames::visitAggregate): + (MapLongVariableNames::visitLoop): + (MapLongVariableNames::visitBranch): + (MapLongVariableNames::mapVaryingLongName): + * src/compiler/MapLongVariableNames.h: Added. + * src/compiler/OutputESSL.cpp: Added. + (TOutputESSL::TOutputESSL): + (TOutputESSL::writeVariablePrecision): + * src/compiler/OutputESSL.h: Added. + * src/compiler/OutputGLSL.cpp: + (TOutputGLSL::TOutputGLSL): + (TOutputGLSL::writeVariablePrecision): + * src/compiler/OutputGLSL.h: + * src/compiler/OutputGLSLBase.cpp: Added. + (TOutputGLSLBase::TOutputGLSLBase): + (TOutputGLSLBase::writeTriplet): + (TOutputGLSLBase::writeVariableType): + (TOutputGLSLBase::writeFunctionParameters): + (TOutputGLSLBase::writeConstantUnion): + (TOutputGLSLBase::visitSymbol): + (TOutputGLSLBase::visitConstantUnion): + (TOutputGLSLBase::visitBinary): + (TOutputGLSLBase::visitUnary): + (TOutputGLSLBase::visitSelection): + (TOutputGLSLBase::visitAggregate): + (TOutputGLSLBase::visitLoop): + (TOutputGLSLBase::visitBranch): + (TOutputGLSLBase::visitCodeBlock): + * src/compiler/OutputGLSLBase.h: Added. + (TOutputGLSLBase::objSink): + * src/compiler/OutputHLSL.cpp: + (sh::OutputHLSL::OutputHLSL): + (sh::OutputHLSL::header): + (sh::OutputHLSL::visitUnary): + (sh::OutputHLSL::visitAggregate): + (sh::OutputHLSL::visitSelection): + (sh::OutputHLSL::visitLoop): + (sh::OutputHLSL::visitBranch): + (sh::OutputHLSL::handleExcessiveLoop): + (sh::OutputHLSL::outputLineDirective): + * src/compiler/OutputHLSL.h: + * src/compiler/ParseHelper.cpp: + (TParseContext::precisionErrorCheck): + (TParseContext::constructorErrorCheck): + (TParseContext::nonInitErrorCheck): + * src/compiler/ParseHelper.h: + (TParseContext::TParseContext): + * src/compiler/ShHandle.h: + * src/compiler/ShaderLang.cpp: + (getVariableInfo): + (ShConstructCompiler): + (ShGetInfo): + (ShGetActiveAttrib): + (ShGetActiveUniform): + * src/compiler/TranslatorESSL.cpp: Added. + (TranslatorESSL::TranslatorESSL): + (TranslatorESSL::translate): + (TranslatorESSL::writeExtensionBehavior): + * src/compiler/TranslatorESSL.h: Added. + * src/compiler/ValidateLimitations.cpp: + (ValidateLimitations::visitBinary): + (ValidateLimitations::visitLoop): + * src/compiler/ValidateLimitations.h: + * src/compiler/VariableInfo.cpp: + (getVariableInfo): + (getBuiltInVariableInfo): + (getUserDefinedVariableInfo): + (CollectAttribsUniforms::visitAggregate): + * src/compiler/VariableInfo.h: + * src/compiler/VersionGLSL.cpp: + (TVersionGLSL::visitSymbol): + (TVersionGLSL::visitConstantUnion): + (TVersionGLSL::visitBinary): + (TVersionGLSL::visitUnary): + (TVersionGLSL::visitSelection): + (TVersionGLSL::visitAggregate): + (TVersionGLSL::visitLoop): + (TVersionGLSL::visitBranch): + * src/compiler/VersionGLSL.h: + * src/compiler/glslang.y: + * src/compiler/glslang_tab.cpp: + * src/compiler/glslang_tab.h: + * src/compiler/intermediate.h: + (TIntermLoop::TIntermLoop): + (TIntermLoop::setUnrollFlag): + (TIntermLoop::getUnrollFlag): + (TIntermSymbol::TIntermSymbol): + (TIntermSymbol::setId): + (TIntermSymbol::setSymbol): + (TIntermSymbol::getOriginalSymbol): + (TIntermAggregate::TIntermAggregate): + (TIntermAggregate::setEndLine): + (TIntermAggregate::getEndLine): + * src/compiler/preprocessor/atom.c: + (AddString): + * src/compiler/preprocessor/compile.h: + * src/compiler/preprocessor/cpp.c: + (CPPelse): + (eval): + (CPPif): + (CPPifdef): + (readCPPline): + (ChkCorrectElseNesting): + * src/compiler/preprocessor/cppstruct.c: + (ResetPreprocessor): + * src/compiler/preprocessor/scanner.c: + (byte_scan): + (yylex_CPP): + * src/compiler/preprocessor/scanner.h: + * src/libEGL/Config.cpp: + (egl::Config::Config): + (egl::Config::set): + (egl::ConfigSet::add): + (egl::ConfigSet::getConfigs): + * src/libEGL/Config.h: + * src/libEGL/Display.cpp: + (egl::Display::Display): + (egl::Display::initialize): + (egl::Display::terminate): + (egl::Display::getConfigAttrib): + (egl::Display::createDevice): + (egl::Display::createWindowSurface): + (egl::Display::createOffscreenSurface): + (egl::Display::createContext): + (egl::Display::destroyContext): + (egl::Display::isInitialized): + (egl::Display::getAdapterIdentifier): + (egl::Display::isDeviceLost): + (egl::Display::getBufferPool): + (egl::Display::initExtensionString): + (egl::Display::getExtensionString): + (egl::Display::getVertexTextureSupport): + (egl::Display::getNonPower2TextureSupport): + * src/libEGL/Display.h: + (egl::Display::isD3d9ExDevice): + * src/libEGL/Surface.cpp: + (egl::Surface::Surface): + (egl::Surface::initialize): + (egl::Surface::release): + (egl::Surface::resetSwapChain): + (egl::SurfaceWindowProc): + (egl::Surface::subclassWindow): + (egl::Surface::unsubclassWindow): + (egl::Surface::swap): + (egl::Surface::getRenderTarget): + (egl::Surface::getOffscreenTexture): + (egl::Surface::getTextureFormat): + (egl::Surface::getTextureTarget): + (egl::Surface::setBoundTexture): + (egl::Surface::getBoundTexture): + (egl::Surface::getFormat): + * src/libEGL/Surface.h: + (egl::Surface::getShareHandle): + * src/libEGL/libEGL.cpp: + (validateDisplay): + (validateConfig): + (validateContext): + (validateSurface): + * src/libEGL/libEGL.rc: Added. + * src/libEGL/libEGL.vcproj: + * src/libEGL/main.cpp: + (DllMain): + * src/libEGL/main.h: + * src/libEGL/resource.h: Added. + * src/libGLESv2/Blit.cpp: + (gl::Blit::initGeometry): + (gl::Blit::copy): + * src/libGLESv2/Blit.h: + * src/libGLESv2/Buffer.cpp: + (gl::Buffer::Buffer): + (gl::Buffer::~Buffer): + (gl::Buffer::bufferData): + (gl::Buffer::bufferSubData): + (gl::Buffer::getStaticVertexBuffer): + (gl::Buffer::getStaticIndexBuffer): + (gl::Buffer::invalidateStaticData): + (gl::Buffer::promoteStaticUsage): + * src/libGLESv2/Buffer.h: + * src/libGLESv2/Context.cpp: + (gl::Context::Context): + (gl::Context::~Context): + (gl::Context::makeCurrent): + (gl::Context::markAllStateDirty): + (gl::Context::setActiveSampler): + (gl::Context::createFramebuffer): + (gl::Context::createFence): + (gl::Context::deleteFramebuffer): + (gl::Context::deleteFence): + (gl::Context::bindTexture2D): + (gl::Context::bindTextureCubeMap): + (gl::Context::getTexture2D): + (gl::Context::getTextureCubeMap): + (gl::Context::getSamplerTexture): + (gl::Context::getIntegerv): + (gl::Context::applyRenderTarget): + (gl::Context::applyState): + (gl::Context::applyVertexBuffer): + (gl::Context::applyShaders): + (gl::Context::applyTextures): + (gl::Context::readPixels): + (gl::Context::clear): + (gl::Context::drawArrays): + (gl::Context::drawElements): + (gl::Context::finish): + (gl::Context::flush): + (gl::Context::drawClosingLine): + (gl::Context::getMaximumVertexTextureImageUnits): + (gl::Context::getMaximumCombinedTextureImageUnits): + (gl::Context::supportsNonPower2Texture): + (gl::Context::detachTexture): + (gl::Context::getIncompleteTexture): + (gl::Context::initExtensionString): + (gl::Context::blitFramebuffer): + (gl::VertexDeclarationCache::VertexDeclarationCache): + (gl::VertexDeclarationCache::~VertexDeclarationCache): + (gl::VertexDeclarationCache::applyDeclaration): + * src/libGLESv2/Context.h: + * src/libGLESv2/Framebuffer.cpp: + (gl::Framebuffer::lookupRenderbuffer): + (gl::Framebuffer::completeness): + * src/libGLESv2/Framebuffer.h: + * src/libGLESv2/HandleAllocator.cpp: Added. + (gl::HandleAllocator::HandleAllocator): + (gl::HandleAllocator::~HandleAllocator): + (gl::HandleAllocator::setBaseHandle): + (gl::HandleAllocator::allocate): + (gl::HandleAllocator::release): + * src/libGLESv2/HandleAllocator.h: Added. + * src/libGLESv2/IndexDataManager.cpp: Added. + (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/IndexDataManager.h: Added. + (gl::IndexBuffer::size): + * src/libGLESv2/Program.cpp: + (gl::Program::getSemanticIndex): + (gl::Program::getSamplerMapping): + (gl::Program::getSamplerTextureType): + (gl::Program::compileToBinary): + (gl::Program::packVaryings): + (gl::Program::linkVaryings): + (gl::Program::link): + (gl::Program::linkUniforms): + (gl::Program::defineUniform): + (gl::Program::applyUniform1iv): + (gl::Program::appendToInfoLogSanitized): + (gl::Program::unlink): + (gl::Program::getActiveUniformMaxLength): + (gl::Program::validate): + (gl::Program::validateSamplers): + * src/libGLESv2/Program.h: + * src/libGLESv2/Renderbuffer.cpp: + (gl::Renderbuffer::getWidth): + (gl::Renderbuffer::getHeight): + (gl::Renderbuffer::getInternalFormat): + (gl::Renderbuffer::getRedSize): + (gl::Renderbuffer::getGreenSize): + (gl::Renderbuffer::getBlueSize): + (gl::Renderbuffer::getAlphaSize): + (gl::Renderbuffer::getDepthSize): + (gl::Renderbuffer::getStencilSize): + (gl::Renderbuffer::getSamples): + (gl::RenderbufferStorage::RenderbufferStorage): + (gl::RenderbufferStorage::getWidth): + (gl::RenderbufferStorage::getHeight): + (gl::RenderbufferStorage::getInternalFormat): + (gl::RenderbufferStorage::getRedSize): + (gl::RenderbufferStorage::getGreenSize): + (gl::RenderbufferStorage::getBlueSize): + (gl::RenderbufferStorage::getAlphaSize): + (gl::RenderbufferStorage::getDepthSize): + (gl::RenderbufferStorage::getStencilSize): + (gl::RenderbufferStorage::getD3DFormat): + (gl::Colorbuffer::Colorbuffer): + (gl::Colorbuffer::getWidth): + (gl::Colorbuffer::getHeight): + (gl::Colorbuffer::getInternalFormat): + (gl::Colorbuffer::getType): + (gl::Colorbuffer::getD3DFormat): + (gl::Colorbuffer::isColorbuffer): + (gl::Colorbuffer::getRenderTarget): + (gl::DepthStencilbuffer::DepthStencilbuffer): + (gl::Depthbuffer::Depthbuffer): + (gl::Stencilbuffer::Stencilbuffer): + * src/libGLESv2/Renderbuffer.h: + * src/libGLESv2/ResourceManager.cpp: + (gl::ResourceManager::createBuffer): + (gl::ResourceManager::createShader): + (gl::ResourceManager::createProgram): + (gl::ResourceManager::createTexture): + (gl::ResourceManager::createRenderbuffer): + (gl::ResourceManager::deleteBuffer): + (gl::ResourceManager::deleteShader): + (gl::ResourceManager::deleteProgram): + (gl::ResourceManager::deleteTexture): + (gl::ResourceManager::deleteRenderbuffer): + (gl::ResourceManager::checkTextureAllocation): + * src/libGLESv2/ResourceManager.h: + * src/libGLESv2/Shader.cpp: + (gl::Shader::Shader): + (gl::Shader::compileToHLSL): + * src/libGLESv2/Shader.h: + * src/libGLESv2/Texture.cpp: + (gl::Texture::Image::Image): + (gl::Texture::Image::~Image): + (gl::Texture::Image::isRenderable): + (gl::Texture::Image::getD3DFormat): + (gl::Texture::Texture): + (gl::Texture::setMinFilter): + (gl::Texture::setMagFilter): + (gl::Texture::setWrapS): + (gl::Texture::setWrapT): + (gl::Texture::loadImageData): + (gl::Texture::loadAlphaImageData): + (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::loadRGBUByteImageData): + (gl::Texture::loadRGB565ImageData): + (gl::Texture::loadRGBFloatImageData): + (gl::Texture::loadRGBHalfFloatImageData): + (gl::Texture::loadRGBAUByteImageDataSSE2): + (gl::Texture::loadRGBAUByteImageData): + (gl::Texture::loadRGBA4444ImageData): + (gl::Texture::loadRGBA5551ImageData): + (gl::Texture::loadRGBAFloatImageData): + (gl::Texture::loadRGBAHalfFloatImageData): + (gl::Texture::loadBGRAImageData): + (gl::Texture::loadCompressedImageData): + (gl::Texture::createSurface): + (gl::Texture::setImage): + (gl::Texture::setCompressedImage): + (gl::Texture::subImage): + (gl::Texture::subImageCompressed): + (gl::Texture::copyToImage): + (gl::Texture::getTexture): + (gl::Texture::isDirtyParameter): + (gl::Texture::isDirtyImage): + (gl::Texture::resetDirty): + (gl::Texture::getSerial): + (gl::Texture::creationLevels): + (gl::Texture::levelCount): + (gl::Texture::issueSerial): + (gl::Texture2D::Texture2D): + (gl::Texture2D::~Texture2D): + (gl::Texture2D::getWidth): + (gl::Texture2D::getHeight): + (gl::Texture2D::getInternalFormat): + (gl::Texture2D::getType): + (gl::Texture2D::getD3DFormat): + (gl::Texture2D::redefineTexture): + (gl::Texture2D::setImage): + (gl::Texture2D::bindTexImage): + (gl::Texture2D::releaseTexImage): + (gl::Texture2D::setCompressedImage): + (gl::Texture2D::commitRect): + (gl::Texture2D::copyImage): + (gl::Texture2D::copySubImage): + (gl::Texture2D::isComplete): + (gl::Texture2D::isCompressed): + (gl::Texture2D::getBaseTexture): + (gl::Texture2D::createTexture): + (gl::Texture2D::updateTexture): + (gl::Texture2D::convertToRenderTarget): + (gl::Texture2D::generateMipmaps): + (gl::Texture2D::getRenderbuffer): + (gl::Texture2D::getRenderTarget): + (gl::TextureCubeMap::getWidth): + (gl::TextureCubeMap::getHeight): + (gl::TextureCubeMap::getInternalFormat): + (gl::TextureCubeMap::getType): + (gl::TextureCubeMap::getD3DFormat): + (gl::TextureCubeMap::setImagePosX): + (gl::TextureCubeMap::setImageNegX): + (gl::TextureCubeMap::setImagePosY): + (gl::TextureCubeMap::setImageNegY): + (gl::TextureCubeMap::setImagePosZ): + (gl::TextureCubeMap::setImageNegZ): + (gl::TextureCubeMap::setCompressedImage): + (gl::TextureCubeMap::commitRect): + (gl::TextureCubeMap::isComplete): + (gl::TextureCubeMap::isCompressed): + (gl::TextureCubeMap::getBaseTexture): + (gl::TextureCubeMap::createTexture): + (gl::TextureCubeMap::updateTexture): + (gl::TextureCubeMap::convertToRenderTarget): + (gl::TextureCubeMap::setImage): + (gl::TextureCubeMap::redefineTexture): + (gl::TextureCubeMap::copyImage): + (gl::TextureCubeMap::getCubeMapSurface): + (gl::TextureCubeMap::copySubImage): + (gl::TextureCubeMap::generateMipmaps): + (gl::TextureCubeMap::getRenderbuffer): + (gl::TextureCubeMap::getRenderTarget): + * src/libGLESv2/Texture.h: + * src/libGLESv2/VertexDataManager.cpp: Added. + (gl::VertexDataManager::VertexDataManager): + (gl::VertexDataManager::~VertexDataManager): + (gl::VertexDataManager::writeAttributeData): + (gl::VertexDataManager::prepareVertexData): + (gl::VertexDataManager::spaceRequired): + (gl::VertexDataManager::checkVertexCaps): + (gl::VertexDataManager::typeIndex): + (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/VertexDataManager.h: Added. + (gl::ArrayVertexBuffer::size): + (gl::VertexDataManager::dirtyCurrentValue): + * src/libGLESv2/libGLESv2.cpp: + (validImageSize): + (Extension::glBindTexImage): + * src/libGLESv2/libGLESv2.def: + * src/libGLESv2/libGLESv2.rc: Added. + * src/libGLESv2/libGLESv2.vcproj: + * src/libGLESv2/main.cpp: + (error): + * src/libGLESv2/mathutil.h: + (gl::clamp): + (gl::clamp01): + (gl::transformPixelRect): + (gl::transformPixelYOffset): + (gl::adjustWinding): + (gl::supportsSSE2): + * src/libGLESv2/resource.h: Added. + * src/libGLESv2/utilities.cpp: + (gl::ComputeCompressedPitch): + (es2dx::ConvertCubeFace): + (es2dx::ConvertPrimitiveType): + (es2dx::ConvertRenderbufferFormat): + (es2dx::GetMultisampleTypeFromSamples): + (dx2es::GetStencilSize): + (dx2es::GetAlphaSize): + (dx2es::GetRedSize): + (dx2es::GetGreenSize): + (dx2es::GetBlueSize): + (dx2es::GetDepthSize): + (getTempPath): + (writeFile): + * src/libGLESv2/utilities.h: + * src/libGLESv2/vertexconversion.h: Added. + (gl::Identity::convert): + (gl::Cast::convert): + (gl::Normalize::convert): + (gl::FixedToFloat::convert): + (gl::SimpleDefaultValues::zero): + (gl::SimpleDefaultValues::one): + (gl::NormalizedDefaultValues::zero): + (gl::NormalizedDefaultValues::one): + (gl::VertexDataConverter::convertArray): + (gl::VertexDataConverter::pointerAddBytes): + (gl::VertexDataConverter::copyComponent): + +2011-05-24 David Kilzer <ddkilzer@apple.com> + + Part 2 of 2: <http://webkit.org/b/60805> Enable -Wnewline-eof on ANGLE + + Reviewed by Adam Roben. + + * Configurations/Base.xcconfig: + (GCC_WARN_ABOUT_MISSING_NEWLINE): Added. Set to YES. + +2011-05-23 David Kilzer <ddkilzer@apple.com> + + Part 1 of 2: <http://webkit.org/b/60805> Enable -Wnewline-eof on ANGLE + + Merge ANGLE upstream commit r653 for Issue 154. + + * src/compiler/PoolAlloc.h: Added newline to end of file. + * src/compiler/ShHandle.h: Ditto. + * src/libEGL/Display.cpp: Ditto. + +2011-05-16 David Kilzer <ddkilzer@apple.com> + + <http://webkit.org/b/60913> C++ exceptions should not be enabled when building with llvm-gcc-4.2 + <rdar://problem/9446430> + + Reviewed by Mark Rowe. + + * Configurations/Base.xcconfig: Fixed typo. + +2011-05-04 David Kilzer <ddkilzer@apple.com> + + Part 2 of 2: <http://webkit.org/b/56337> Enable -Werror on ANGLE + + Reviewed by Adam Barth. + + * Configurations/Base.xcconfig: + (GCC_TREAT_WARNINGS_AS_ERRORS): Set to YES. + +2011-05-04 David Kilzer <ddkilzer@apple.com> + + Part 1 of 2: <http://webkit.org/b/56337> Enable -Werror on ANGLE + + Merge ANGLE upstream commits r572, r573, r574, r575. + + This unblocks enabling -Werror on ANGLE. Since all changes are + in the upstream repository, they may be safely overwritten + during the next ANGLE update. + + * src/compiler/ConstantUnion.h: + (ConstantUnion::operator==): Added a default case. + * src/compiler/Intermediate.cpp: + (TIntermBinary::promote): Added parentheses. + * src/compiler/ParseHelper.cpp: + (TParseContext::precisionErrorCheck): Added a default case. + * src/compiler/PoolAlloc.cpp: + (TAllocation::checkGuardBlock): Changed '%u' to '%lu' for size_t + variable. Put for loop inside #ifdef GUARD_BLOCKS/#endif macros + to fix tautological-compare warning. + (TAllocation::checkAllocList): Added newline to end of file. + +2011-04-26 Dan Bernstein <mitz@apple.com> + + Build fix. + + * Configurations/CompilerVersion.xcconfig: + +2011-04-26 Dan Bernstein <mitz@apple.com> + + Reviewed by Mark Rowe. + + Choose the compiler based on the Xcode version for Snow Leopard debug builds. + + * Configurations/Base.xcconfig: + * Configurations/CompilerVersion.xcconfig: Added. + 2011-03-17 Jeff Miller <jeffm@apple.com> Use a consistent set of file patterns in the svn:ignore property for all .xcodeproj directories, specifically: diff --git a/Source/ThirdParty/ANGLE/Configurations/Base.xcconfig b/Source/ThirdParty/ANGLE/Configurations/Base.xcconfig index c26baad..505a57d 100644 --- a/Source/ThirdParty/ANGLE/Configurations/Base.xcconfig +++ b/Source/ThirdParty/ANGLE/Configurations/Base.xcconfig @@ -1,7 +1,10 @@ +#include "CompilerVersion.xcconfig" + DEAD_CODE_STRIPPING = YES; -DEBUG_INFORMATION_FORMAT = dwarf; +DEBUG_INFORMATION_FORMAT = dwarf-with-dsym; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DEBUGGING_SYMBOLS = default; +GCC_ENABLE_CPP_EXCEPTIONS = NO; GCC_ENABLE_CPP_RTTI = NO; GCC_ENABLE_OBJC_EXCEPTIONS = YES; GCC_ENABLE_OBJC_GC = supported; @@ -14,51 +17,36 @@ GCC_PRECOMPILE_PREFIX_HEADER = NO; GCC_INLINES_ARE_PRIVATE_EXTERN = YES; GCC_SYMBOLS_PRIVATE_EXTERN = NO; GCC_THREADSAFE_STATICS = NO; -GCC_TREAT_WARNINGS_AS_ERRORS = NO; +GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; +GCC_WARN_ABOUT_MISSING_NEWLINE = YES; LINKER_DISPLAYS_MANGLED_NAMES = YES; PREBINDING = NO; STRIP_INSTALLED_PRODUCT = NO; +CLANG_CXX_LIBRARY = $(CLANG_CXX_LIBRARY_$(TARGET_MAC_OS_X_VERSION_MAJOR)); +CLANG_CXX_LIBRARY_1060 = libstdc++; +CLANG_CXX_LIBRARY_1070 = libc++; +CLANG_CXX_LIBRARY_1080 = libc++; +CLANG_CXX_LIBRARY_1090 = libc++; -TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); - - -// Use GCC 4.2 with Xcode 3.1, which includes GCC 4.2 but defaults to GCC 4.0. -// Note that Xcode versions as new as 3.1.2 use XCODE_VERSION_ACTUAL for the minor version -// number. Newer versions of Xcode use XCODE_VERSION_MINOR for the minor version, and -// XCODE_VERSION_ACTUAL for the full version number. -TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -TARGET_GCC_VERSION_ = $(TARGET_GCC_VERSION_1040); -TARGET_GCC_VERSION_1040 = GCC_40; -TARGET_GCC_VERSION_1050 = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_MINOR)); -TARGET_GCC_VERSION_1050_ = $(TARGET_GCC_VERSION_1050_$(XCODE_VERSION_ACTUAL)); -TARGET_GCC_VERSION_1050_0310 = GCC_42; -TARGET_GCC_VERSION_1050_0320 = GCC_42; -TARGET_GCC_VERSION_1060 = GCC_42; -TARGET_GCC_VERSION_1070 = $(TARGET_GCC_VERSION_1070_$(CONFIGURATION)); -TARGET_GCC_VERSION_1070_Debug = LLVM_COMPILER; -TARGET_GCC_VERSION_1070_Release = LLVM_GCC_42; -TARGET_GCC_VERSION_1070_Production = LLVM_GCC_42; - -GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION)); -GCC_VERSION_GCC_40 = 4.0; -GCC_VERSION_GCC_42 = 4.2; -GCC_VERSION_LLVM_GCC_42 = com.apple.compilers.llvmgcc42; -GCC_VERSION_LLVM_COMPILER = com.apple.compilers.llvm.clang.1_0; +REAL_PLATFORM_NAME = $(REAL_PLATFORM_NAME_$(PLATFORM_NAME)); +REAL_PLATFORM_NAME_ = $(REAL_PLATFORM_NAME_macosx); +REAL_PLATFORM_NAME_iphoneos = iphoneos; +REAL_PLATFORM_NAME_iphonesimulator = iphonesimulator; +REAL_PLATFORM_NAME_macosx = macosx; -// FIXME: Disable C++ exceptions in the LLVM Compiler once it supports enabling Obj-C exceptions without C++ exceptions. -GCC_ENABLE_CPP_EXCEPTIONS = $(GCC_ENABLE_CPP_EXCEPTIONS_$(TARGET_GCC_VERSION)); -GCC_ENABLE_CPP_EXCEPTIONS_GCC_40 = NO; -GCC_ENABLE_CPP_EXCEPTIONS_GCC_42 = NO; -GCC_ENABLE_CPP_EXCEPTIONS_LLVM_GCC = NO; -GCC_ENABLE_CPP_EXCEPTIONS_LLVM_COMPILER = YES; +TARGET_MAC_OS_X_VERSION_MAJOR = $(MAC_OS_X_VERSION_MAJOR); // If the target Mac OS X version does not match the current Mac OS X version then we'll want to build using the target version's SDK. SDKROOT = $(SDKROOT_$(MAC_OS_X_VERSION_MAJOR)_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -SDKROOT_1050_1040 = macosx10.4internal; -SDKROOT_1060_1040 = macosx10.4internal; -SDKROOT_1060_1050 = macosx10.5internal; -SDKROOT_1070_1040 = macosx10.4internal; -SDKROOT_1070_1050 = macosx10.5internal; -SDKROOT_1070_1060 = macosx10.6internal; +SDKROOT_1060_1050 = macosx10.5; +SDKROOT_1070_1050 = macosx10.5; +SDKROOT_1080_1050 = macosx10.5; +SDKROOT_1090_1050 = macosx10.5; +SDKROOT_1070_1060 = macosx10.6; +SDKROOT_1080_1060 = macosx10.6; +SDKROOT_1090_1060 = macosx10.6; +SDKROOT_1080_1070 = macosx10.7; +SDKROOT_1090_1070 = macosx10.7; +SDKROOT_1090_1080 = macosx10.8; diff --git a/Source/ThirdParty/ANGLE/Configurations/CompilerVersion.xcconfig b/Source/ThirdParty/ANGLE/Configurations/CompilerVersion.xcconfig new file mode 100644 index 0000000..a8c7f75 --- /dev/null +++ b/Source/ThirdParty/ANGLE/Configurations/CompilerVersion.xcconfig @@ -0,0 +1,84 @@ +// Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +IS_XCODE_0400 = $(IS_XCODE_0400_$(XCODE_VERSION_MINOR)); +IS_XCODE_0400_0400 = YES; + +IS_XCODE_0400_OR_0410 = $(IS_XCODE_0400_OR_0410_$(XCODE_VERSION_MINOR)); +IS_XCODE_0400_OR_0410_0400 = YES; +IS_XCODE_0400_OR_0410_0410 = YES; + +// The version of the LLVM Compiler in Xcode 4.0 and earlier have difficulty compiling our code. +LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS = $(LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS_$(XCODE_VERSION_MAJOR)); +LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS_0300 = YES; +LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS_0400 = $(LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS_IS_XCODE_0400_$(IS_XCODE_0400)); +LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS_IS_XCODE_0400_YES = YES; + +// The version of the LLVM Compiler in Xcode 4.1 and earlier do not generate fast enough code. +LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS = $(LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS_$(XCODE_VERSION_MAJOR)); +LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS_0300 = YES; +LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS_0400 = $(LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS_IS_XCODE_0400_OR_0410_$(IS_XCODE_0400_OR_0410)); +LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS_IS_XCODE_0400_OR_0410_YES = YES; + +LLVM_COMPILER_SUITABLE_FOR_DEBUG_BUILDS = $(LLVM_COMPILER_SUITABLE_FOR_DEBUG_BUILDS_$(LLVM_COMPILER_UNSUITABLE_FOR_DEBUG_BUILDS)); +LLVM_COMPILER_SUITABLE_FOR_DEBUG_BUILDS_ = YES; +LLVM_COMPILER_SUITABLE_FOR_DEBUG_BUILDS_YES = NO; + +LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS = $(LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS_$(LLVM_COMPILER_UNSUITABLE_FOR_OPTIMIZED_BUILDS)); +LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS_ = YES; +LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS_YES = NO; + + +// Use GCC 4.2 with Xcode 3.1, which includes GCC 4.2 but defaults to GCC 4.0. +// Note that Xcode versions as new as 3.1.2 use XCODE_VERSION_ACTUAL for the minor version +// number. Newer versions of Xcode use XCODE_VERSION_MINOR for the minor version, and +// XCODE_VERSION_ACTUAL for the full version number. +TARGET_GCC_VERSION = $(TARGET_GCC_VERSION_$(REAL_PLATFORM_NAME)); +TARGET_GCC_VERSION_iphoneos = LLVM_GCC_42; +TARGET_GCC_VERSION_iphonesimulator = GCC_42; +TARGET_GCC_VERSION_macosx = $(TARGET_GCC_VERSION_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)); + +TARGET_GCC_VERSION_macosx_1050 = $(TARGET_GCC_VERSION_macosx_1050_$(XCODE_VERSION_MINOR)); +TARGET_GCC_VERSION_macosx_1050_ = $(TARGET_GCC_VERSION_macosx_1050_$(XCODE_VERSION_ACTUAL)); +TARGET_GCC_VERSION_macosx_1050_0310 = GCC_42; +TARGET_GCC_VERSION_macosx_1050_0320 = GCC_42; + +TARGET_GCC_VERSION_macosx_1060 = $(TARGET_GCC_VERSION_macosx_1060_AND_1070_$(CONFIGURATION)); +TARGET_GCC_VERSION_macosx_1070 = $(TARGET_GCC_VERSION_macosx_1060_AND_1070_$(CONFIGURATION)); +TARGET_GCC_VERSION_macosx_1060_AND_1070_Debug = $(TARGET_GCC_VERSION_macosx_USE_LLVM_COMPILER_$(LLVM_COMPILER_SUITABLE_FOR_DEBUG_BUILDS)); +TARGET_GCC_VERSION_macosx_1060_AND_1070_Release = $(TARGET_GCC_VERSION_macosx_USE_LLVM_COMPILER_$(LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS)); +TARGET_GCC_VERSION_macosx_1060_AND_1070_Production = $(TARGET_GCC_VERSION_macosx_USE_LLVM_COMPILER_$(LLVM_COMPILER_SUITABLE_FOR_OPTIMIZED_BUILDS)); +TARGET_GCC_VERSION_macosx_1060_NON_LLVM_FALLBACK = GCC_42; +TARGET_GCC_VERSION_macosx_1070_NON_LLVM_FALLBACK = LLVM_GCC_42; + +TARGET_GCC_VERSION_macosx_USE_LLVM_COMPILER_YES = LLVM_COMPILER; +TARGET_GCC_VERSION_macosx_USE_LLVM_COMPILER_NO = $(TARGET_GCC_VERSION_macosx_$(TARGET_MAC_OS_X_VERSION_MAJOR)_NON_LLVM_FALLBACK); + +TARGET_GCC_VERSION_macosx_1080 = LLVM_COMPILER; +TARGET_GCC_VERSION_macosx_1090 = LLVM_COMPILER; + +GCC_VERSION = $(GCC_VERSION_$(TARGET_GCC_VERSION)); +GCC_VERSION_GCC_40 = 4.0; +GCC_VERSION_GCC_42 = 4.2; +GCC_VERSION_LLVM_GCC_42 = com.apple.compilers.llvmgcc42; +GCC_VERSION_LLVM_COMPILER = com.apple.compilers.llvm.clang.1_0; diff --git a/Source/ThirdParty/ANGLE/Configurations/DebugRelease.xcconfig b/Source/ThirdParty/ANGLE/Configurations/DebugRelease.xcconfig index 2d92931..be088b8 100644 --- a/Source/ThirdParty/ANGLE/Configurations/DebugRelease.xcconfig +++ b/Source/ThirdParty/ANGLE/Configurations/DebugRelease.xcconfig @@ -1,19 +1,20 @@ #include "Base.xcconfig" ARCHS = $(ARCHS_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -ARCHS_ = $(ARCHS_1040); -ARCHS_1040 = $(NATIVE_ARCH); ARCHS_1050 = $(NATIVE_ARCH); ARCHS_1060 = $(ARCHS_STANDARD_32_64_BIT); ARCHS_1070 = $(ARCHS_STANDARD_32_64_BIT); +ARCHS_1080 = $(ARCHS_STANDARD_32_64_BIT); +ARCHS_1090 = $(ARCHS_STANDARD_32_64_BIT); ONLY_ACTIVE_ARCH = YES; MACOSX_DEPLOYMENT_TARGET = $(MACOSX_DEPLOYMENT_TARGET_$(TARGET_MAC_OS_X_VERSION_MAJOR)); -MACOSX_DEPLOYMENT_TARGET_ = 10.4; -MACOSX_DEPLOYMENT_TARGET_1040 = 10.4; MACOSX_DEPLOYMENT_TARGET_1050 = 10.5; MACOSX_DEPLOYMENT_TARGET_1060 = 10.6; MACOSX_DEPLOYMENT_TARGET_1070 = 10.7; +MACOSX_DEPLOYMENT_TARGET_1080 = 10.8; +MACOSX_DEPLOYMENT_TARGET_1090 = 10.9; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; +DEBUG_INFORMATION_FORMAT = dwarf; diff --git a/Source/ThirdParty/ANGLE/include/EGL/eglext.h b/Source/ThirdParty/ANGLE/include/EGL/eglext.h index 638e336..b670840 100644 --- a/Source/ThirdParty/ANGLE/include/EGL/eglext.h +++ b/Source/ThirdParty/ANGLE/include/EGL/eglext.h @@ -6,7 +6,7 @@ extern "C" { #endif /* -** Copyright (c) 2007-2009 The Khronos Group Inc. +** Copyright (c) 2007-2012 The Khronos Group Inc. ** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the @@ -34,8 +34,8 @@ extern "C" { /* Header file version number */ /* Current version at http://www.khronos.org/registry/egl/ */ -/* $Revision: 10795 $ on $Date: 2010-03-19 17:04:17 -0700 (Fri, 19 Mar 2010) $ */ -#define EGL_EGLEXT_VERSION 5 +/* $Revision: 16473 $ on $Date: 2012-01-04 02:20:48 -0800 (Wed, 04 Jan 2012) $ */ +#define EGL_EGLEXT_VERSION 11 #ifndef EGL_KHR_config_attribs #define EGL_KHR_config_attribs 1 @@ -120,6 +120,7 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYIMAGEKHRPROC) (EGLDisplay dpy, EGL #define EGL_GL_RENDERBUFFER_KHR 0x30B9 /* eglCreateImageKHR target */ #endif +#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */ #ifndef EGL_KHR_reusable_sync #define EGL_KHR_reusable_sync 1 @@ -149,6 +150,7 @@ typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSy typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode); typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); #endif +#endif #ifndef EGL_KHR_image_base #define EGL_KHR_image_base 1 @@ -169,19 +171,25 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG #define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103 #endif +#ifndef EGL_KHR_lock_surface2 +#define EGL_KHR_lock_surface2 1 +#define EGL_BITMAP_PIXEL_SIZE_KHR 0x3110 +#endif + #ifndef EGL_NV_coverage_sample #define EGL_NV_coverage_sample 1 -#define EGL_COVERAGE_BUFFERS_NV 0x30E0 -#define EGL_COVERAGE_SAMPLES_NV 0x30E1 +#define EGL_COVERAGE_BUFFERS_NV 0x30E0 +#define EGL_COVERAGE_SAMPLES_NV 0x30E1 #endif #ifndef EGL_NV_depth_nonlinear #define EGL_NV_depth_nonlinear 1 -#define EGL_DEPTH_ENCODING_NV 0x30E2 +#define EGL_DEPTH_ENCODING_NV 0x30E2 #define EGL_DEPTH_ENCODING_NONE_NV 0 -#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 +#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3 #endif +#if KHRONOS_SUPPORT_INT64 /* EGLTimeNV requires 64-bit uint support */ #ifndef EGL_NV_sync #define EGL_NV_sync 1 #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV 0x30E6 @@ -198,7 +206,7 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EG #define EGL_SYNC_FENCE_NV 0x30EF #define EGL_NO_SYNC_NV ((EGLSyncNV)0) typedef void* EGLSyncNV; -typedef unsigned long long EGLTimeNV; +typedef khronos_utime_nanoseconds_t EGLTimeNV; #ifdef EGL_EGLEXT_PROTOTYPES EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list); EGLBoolean eglDestroySyncNV (EGLSyncNV sync); @@ -214,6 +222,124 @@ typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode); typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value); #endif +#endif + +#if KHRONOS_SUPPORT_INT64 /* Dependent on EGL_KHR_reusable_sync which requires 64-bit uint support */ +#ifndef EGL_KHR_fence_sync +#define EGL_KHR_fence_sync 1 +/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */ +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SYNC_FENCE_KHR 0x30F9 +#endif +#endif + +#ifndef EGL_HI_clientpixmap +#define EGL_HI_clientpixmap 1 + +/* Surface Attribute */ +#define EGL_CLIENT_PIXMAP_POINTER_HI 0x8F74 +/* + * Structure representing a client pixmap + * (pixmap's data is in client-space memory). + */ +struct EGLClientPixmapHI +{ + void* pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; +}; + +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurfaceHI(EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLSurface (EGLAPIENTRYP PFNEGLCREATEPIXMAPSURFACEHIPROC) (EGLDisplay dpy, EGLConfig config, struct EGLClientPixmapHI* pixmap); +#endif /* EGL_HI_clientpixmap */ + +#ifndef EGL_HI_colorformats +#define EGL_HI_colorformats 1 +/* Config Attribute */ +#define EGL_COLOR_FORMAT_HI 0x8F70 +/* Color Formats */ +#define EGL_COLOR_RGB_HI 0x8F71 +#define EGL_COLOR_RGBA_HI 0x8F72 +#define EGL_COLOR_ARGB_HI 0x8F73 +#endif /* EGL_HI_colorformats */ + +#ifndef EGL_MESA_drm_image +#define EGL_MESA_drm_image 1 +#define EGL_DRM_BUFFER_FORMAT_MESA 0x31D0 /* CreateDRMImageMESA attribute */ +#define EGL_DRM_BUFFER_USE_MESA 0x31D1 /* CreateDRMImageMESA attribute */ +#define EGL_DRM_BUFFER_FORMAT_ARGB32_MESA 0x31D2 /* EGL_IMAGE_FORMAT_MESA attribute value */ +#define EGL_DRM_BUFFER_MESA 0x31D3 /* eglCreateImageKHR target */ +#define EGL_DRM_BUFFER_STRIDE_MESA 0x31D4 +#define EGL_DRM_BUFFER_USE_SCANOUT_MESA 0x00000001 /* EGL_DRM_BUFFER_USE_MESA bits */ +#define EGL_DRM_BUFFER_USE_SHARE_MESA 0x00000002 /* EGL_DRM_BUFFER_USE_MESA bits */ +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLImageKHR EGLAPIENTRY eglCreateDRMImageMESA (EGLDisplay dpy, const EGLint *attrib_list); +EGLAPI EGLBoolean EGLAPIENTRY eglExportDRMImageMESA (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLImageKHR (EGLAPIENTRYP PFNEGLCREATEDRMIMAGEMESAPROC) (EGLDisplay dpy, const EGLint *attrib_list); +typedef EGLBoolean (EGLAPIENTRYP PFNEGLEXPORTDRMIMAGEMESAPROC) (EGLDisplay dpy, EGLImageKHR image, EGLint *name, EGLint *handle, EGLint *stride); +#endif + +#ifndef EGL_NV_post_sub_buffer +#define EGL_NV_post_sub_buffer 1 +#define EGL_POST_SUB_BUFFER_SUPPORTED_NV 0x30BE +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean EGLAPIENTRY eglPostSubBufferNV (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLBoolean (EGLAPIENTRYP PFNEGLPOSTSUBBUFFERNVPROC) (EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height); +#endif + +#ifndef EGL_ANGLE_query_surface_pointer +#define EGL_ANGLE_query_surface_pointer 1 +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLBoolean eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif +typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYSURFACEPOINTERANGLEPROC) (EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value); +#endif + +#ifndef EGL_ANGLE_software_display +#define EGL_ANGLE_software_display 1 +#define EGL_SOFTWARE_DISPLAY_ANGLE ((EGLNativeDisplayType)-1) +#endif + +#ifndef EGL_ANGLE_surface_d3d_texture_2d_share_handle +#define EGL_ANGLE_surface_d3d_texture_2d_share_handle 1 +#define EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE 0x3200 +#endif + +#ifndef EGL_NV_coverage_sample_resolve +#define EGL_NV_coverage_sample_resolve 1 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NV 0x3131 +#define EGL_COVERAGE_SAMPLE_RESOLVE_DEFAULT_NV 0x3132 +#define EGL_COVERAGE_SAMPLE_RESOLVE_NONE_NV 0x3133 +#endif + +#if KHRONOS_SUPPORT_INT64 /* EGLTimeKHR requires 64-bit uint support */ +#ifndef EGL_NV_system_time +#define EGL_NV_system_time 1 + +typedef khronos_utime_nanoseconds_t EGLuint64NV; + +#ifdef EGL_EGLEXT_PROTOTYPES +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeFrequencyNV(void); +EGLAPI EGLuint64NV EGLAPIENTRY eglGetSystemTimeNV(void); +#endif /* EGL_EGLEXT_PROTOTYPES */ +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMEFREQUENCYNVPROC) (void); +typedef EGLuint64NV (EGLAPIENTRYP PFNEGLGETSYSTEMTIMENVPROC) (void); +#endif +#endif + +#ifndef EGL_EXT_create_context_robustness +#define EGL_EXT_create_context_robustness 1 +#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT 0x30BF +#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT 0x3138 +#define EGL_NO_RESET_NOTIFICATION_EXT 0x31BE +#define EGL_LOSE_CONTEXT_ON_RESET_EXT 0x31BF +#endif #ifdef __cplusplus } diff --git a/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h b/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h index 22e855f..34283f2 100644 --- a/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h +++ b/Source/ThirdParty/ANGLE/include/EGL/eglplatform.h @@ -25,7 +25,7 @@ */ /* Platform-specific types and definitions for egl.h - * $Revision: 9724 $ on $Date: 2009-12-02 02:05:33 -0800 (Wed, 02 Dec 2009) $ + * $Revision: 12306 $ on $Date: 2010-08-25 09:51:28 -0700 (Wed, 25 Aug 2010) $ * * Adopters may modify khrplatform.h and this file to suit their platform. * You are encouraged to submit all modifications to the Khronos group so that @@ -60,6 +60,11 @@ * Windows Device Context. They must be defined in platform-specific * code below. The EGL-prefixed versions of Native*Type are the same * types, renamed in EGL 1.3 so all types in the API start with "EGL". + * + * Khronos STRONGLY RECOMMENDS that you use the default definitions + * provided below, since these changes affect both binary and source + * portability of applications using EGL running on different EGL + * implementations. */ #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) /* Win32 and WinCE */ @@ -78,7 +83,13 @@ typedef int EGLNativeDisplayType; typedef void *EGLNativeWindowType; typedef void *EGLNativePixmapType; -#elif defined(__unix__) +#elif defined(WL_EGL_PLATFORM) + +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; + +#elif defined(__unix__) && !defined(ANDROID) /* X11 (tentative) */ #include <X11/Xlib.h> @@ -88,6 +99,14 @@ typedef Display *EGLNativeDisplayType; typedef Pixmap EGLNativePixmapType; typedef Window EGLNativeWindowType; +#elif defined(ANDROID) + +struct egl_native_pixmap_t; + +typedef struct ANativeWindow* EGLNativeWindowType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef void* EGLNativeDisplayType; + #else #error "Platform not recognized" #endif diff --git a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h index 01844de..a124014 100644 --- a/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h +++ b/Source/ThirdParty/ANGLE/include/GLES2/gl2ext.h @@ -1,7 +1,7 @@ #ifndef __gl2ext_h_ #define __gl2ext_h_ -/* $Revision: 10798 $ on $Date:: 2010-03-19 17:34:30 -0700 #$ */ +/* $Revision: 16482 $ on $Date:: 2012-01-04 13:44:55 -0500 #$ */ #ifdef __cplusplus extern "C" { @@ -57,6 +57,15 @@ extern "C" { typedef void* GLeglImageOES; #endif +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +/* GLeglImageOES defined in GL_OES_EGL_image already. */ +#define GL_TEXTURE_EXTERNAL_OES 0x8D65 +#define GL_SAMPLER_EXTERNAL_OES 0x8D66 +#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 +#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 +#endif + /* GL_OES_element_index_uint */ #ifndef GL_OES_element_index_uint #define GL_UNSIGNED_INT 0x1405 @@ -180,6 +189,100 @@ typedef void* GLeglImageOES; #endif /*------------------------------------------------------------------------* + * ANGLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 +#define GL_MAX_SAMPLES_ANGLE 0x8D57 +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE 0x83F2 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE 0x83F3 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_TEXTURE_USAGE_ANGLE 0x93A2 +#define GL_FRAMEBUFFER_ATTACHMENT_ANGLE 0x93A3 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE 0x88FE +#endif + +/*------------------------------------------------------------------------* + * APPLE extension tokens + *------------------------------------------------------------------------*/ + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_RGB_422_APPLE 0x8A1F +#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA +#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_RENDERBUFFER_SAMPLES_APPLE 0x8CAB +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE 0x8D56 +#define GL_MAX_SAMPLES_APPLE 0x8D57 +#define GL_READ_FRAMEBUFFER_APPLE 0x8CA8 +#define GL_DRAW_FRAMEBUFFER_APPLE 0x8CA9 +#define GL_DRAW_FRAMEBUFFER_BINDING_APPLE 0x8CA6 +#define GL_READ_FRAMEBUFFER_BINDING_APPLE 0x8CAA +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_BGRA_EXT 0x80E1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_TEXTURE_MAX_LEVEL_APPLE 0x813D +#endif + +/*------------------------------------------------------------------------* + * ARM extension tokens + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_MALI_SHADER_BINARY_ARM 0x8F60 +#endif + +/* GL_ARM_rgba8 */ +/* No new tokens introduced by this extension. */ + +/*------------------------------------------------------------------------* * EXT extension tokens *------------------------------------------------------------------------*/ @@ -189,6 +292,29 @@ typedef void* GLeglImageOES; #define GL_MAX_EXT 0x8008 #endif +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_RGBA16F_EXT 0x881A +#define GL_RGB16F_EXT 0x881B +#define GL_RG16F_EXT 0x822F +#define GL_R16F_EXT 0x822D +#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT 0x8211 +#define GL_UNSIGNED_NORMALIZED_EXT 0x8C17 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_PROGRAM_PIPELINE_OBJECT_EXT 0x8A4F +#define GL_PROGRAM_OBJECT_EXT 0x8B40 +#define GL_SHADER_OBJECT_EXT 0x8B48 +#define GL_BUFFER_OBJECT_EXT 0x9151 +#define GL_QUERY_OBJECT_EXT 0x9153 +#define GL_VERTEX_ARRAY_OBJECT_EXT 0x9154 +#endif + +/* GL_EXT_debug_marker */ +/* No new tokens introduced by this extension. */ + /* GL_EXT_discard_framebuffer */ #ifndef GL_EXT_discard_framebuffer #define GL_COLOR_EXT 0x1800 @@ -196,9 +322,26 @@ typedef void* GLeglImageOES; #define GL_STENCIL_EXT 0x1802 #endif +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C +#define GL_RENDERBUFFER_SAMPLES_EXT 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x9134 +#define GL_MAX_SAMPLES_EXT 0x9135 +#endif + /* GL_EXT_multi_draw_arrays */ /* No new tokens introduced by this extension. */ +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_ANY_SAMPLES_PASSED_EXT 0x8C2F +#define GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT 0x8D6A +#define GL_CURRENT_QUERY_EXT 0x8865 +#define GL_QUERY_RESULT_EXT 0x8866 +#define GL_QUERY_RESULT_AVAILABLE_EXT 0x8867 +#endif + /* GL_EXT_read_format_bgra */ #ifndef GL_EXT_read_format_bgra #define GL_BGRA_EXT 0x80E1 @@ -206,6 +349,52 @@ typedef void* GLeglImageOES; #define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT 0x8366 #endif +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +/* reuse GL_NO_ERROR */ +#define GL_GUILTY_CONTEXT_RESET_EXT 0x8253 +#define GL_INNOCENT_CONTEXT_RESET_EXT 0x8254 +#define GL_UNKNOWN_CONTEXT_RESET_EXT 0x8255 +#define GL_CONTEXT_ROBUST_ACCESS_EXT 0x90F3 +#define GL_RESET_NOTIFICATION_STRATEGY_EXT 0x8256 +#define GL_LOSE_CONTEXT_ON_RESET_EXT 0x8252 +#define GL_NO_RESET_NOTIFICATION_EXT 0x8261 +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_VERTEX_SHADER_BIT_EXT 0x00000001 +#define GL_FRAGMENT_SHADER_BIT_EXT 0x00000002 +#define GL_ALL_SHADER_BITS_EXT 0xFFFFFFFF +#define GL_PROGRAM_SEPARABLE_EXT 0x8258 +#define GL_ACTIVE_PROGRAM_EXT 0x8259 +#define GL_PROGRAM_PIPELINE_BINDING_EXT 0x825A +#endif + +/* GL_EXT_shader_texture_lod */ +/* No new tokens introduced by this extension. */ + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_TEXTURE_COMPARE_MODE_EXT 0x884C +#define GL_TEXTURE_COMPARE_FUNC_EXT 0x884D +#define GL_COMPARE_REF_TO_TEXTURE_EXT 0x884E +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_SRGB_EXT 0x8C40 +#define GL_SRGB_ALPHA_EXT 0x8C42 +#define GL_SRGB8_ALPHA8_EXT 0x8C43 +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT 0x8210 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 +#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +#endif + /* GL_EXT_texture_filter_anisotropic */ #ifndef GL_EXT_texture_filter_anisotropic #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE @@ -217,15 +406,54 @@ typedef void* GLeglImageOES; #define GL_BGRA_EXT 0x80E1 #endif +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_RED_EXT 0x1903 +#define GL_RG_EXT 0x8227 +#define GL_R8_EXT 0x8229 +#define GL_RG8_EXT 0x822B +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_TEXTURE_IMMUTABLE_FORMAT_EXT 0x912F +#define GL_ALPHA8_EXT 0x803C +#define GL_LUMINANCE8_EXT 0x8040 +#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 +#define GL_RGBA32F_EXT 0x8814 +#define GL_RGB32F_EXT 0x8815 +#define GL_ALPHA32F_EXT 0x8816 +#define GL_LUMINANCE32F_EXT 0x8818 +#define GL_LUMINANCE_ALPHA32F_EXT 0x8819 +/* reuse GL_RGBA16F_EXT */ +#define GL_RGB16F_EXT 0x881B +#define GL_ALPHA16F_EXT 0x881C +#define GL_LUMINANCE16F_EXT 0x881E +#define GL_LUMINANCE_ALPHA16F_EXT 0x881F +#define GL_RGB10_A2_EXT 0x8059 +#define GL_RGB10_EXT 0x8052 +#define GL_BGRA8_EXT 0x93A1 +#endif + /* GL_EXT_texture_type_2_10_10_10_REV */ #ifndef GL_EXT_texture_type_2_10_10_10_REV #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368 #endif -/* GL_EXT_texture_compression_dxt1 */ -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#define GL_UNPACK_SKIP_ROWS 0x0CF3 +#define GL_UNPACK_SKIP_PIXELS 0x0CF4 +#endif + +/*------------------------------------------------------------------------* + * DMP extension tokens + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_SHADER_BINARY_DMP 0x9250 #endif /*------------------------------------------------------------------------* @@ -256,17 +484,18 @@ typedef void* GLeglImageOES; #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG 0x8C03 #endif +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_RENDERBUFFER_SAMPLES_IMG 0x9133 +#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG 0x9134 +#define GL_MAX_SAMPLES_IMG 0x9135 +#define GL_TEXTURE_SAMPLES_IMG 0x9136 +#endif + /*------------------------------------------------------------------------* * NV extension tokens *------------------------------------------------------------------------*/ -/* GL_NV_fence */ -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - /* GL_NV_coverage_sample */ #ifndef GL_NV_coverage_sample #define GL_COVERAGE_COMPONENT_NV 0x8ED0 @@ -285,10 +514,90 @@ typedef void* GLeglImageOES; #define GL_DEPTH_COMPONENT16_NONLINEAR_NV 0x8E2C #endif +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_MAX_DRAW_BUFFERS_NV 0x8824 +#define GL_DRAW_BUFFER0_NV 0x8825 +#define GL_DRAW_BUFFER1_NV 0x8826 +#define GL_DRAW_BUFFER2_NV 0x8827 +#define GL_DRAW_BUFFER3_NV 0x8828 +#define GL_DRAW_BUFFER4_NV 0x8829 +#define GL_DRAW_BUFFER5_NV 0x882A +#define GL_DRAW_BUFFER6_NV 0x882B +#define GL_DRAW_BUFFER7_NV 0x882C +#define GL_DRAW_BUFFER8_NV 0x882D +#define GL_DRAW_BUFFER9_NV 0x882E +#define GL_DRAW_BUFFER10_NV 0x882F +#define GL_DRAW_BUFFER11_NV 0x8830 +#define GL_DRAW_BUFFER12_NV 0x8831 +#define GL_DRAW_BUFFER13_NV 0x8832 +#define GL_DRAW_BUFFER14_NV 0x8833 +#define GL_DRAW_BUFFER15_NV 0x8834 +#define GL_COLOR_ATTACHMENT0_NV 0x8CE0 +#define GL_COLOR_ATTACHMENT1_NV 0x8CE1 +#define GL_COLOR_ATTACHMENT2_NV 0x8CE2 +#define GL_COLOR_ATTACHMENT3_NV 0x8CE3 +#define GL_COLOR_ATTACHMENT4_NV 0x8CE4 +#define GL_COLOR_ATTACHMENT5_NV 0x8CE5 +#define GL_COLOR_ATTACHMENT6_NV 0x8CE6 +#define GL_COLOR_ATTACHMENT7_NV 0x8CE7 +#define GL_COLOR_ATTACHMENT8_NV 0x8CE8 +#define GL_COLOR_ATTACHMENT9_NV 0x8CE9 +#define GL_COLOR_ATTACHMENT10_NV 0x8CEA +#define GL_COLOR_ATTACHMENT11_NV 0x8CEB +#define GL_COLOR_ATTACHMENT12_NV 0x8CEC +#define GL_COLOR_ATTACHMENT13_NV 0x8CED +#define GL_COLOR_ATTACHMENT14_NV 0x8CEE +#define GL_COLOR_ATTACHMENT15_NV 0x8CEF +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_MAX_COLOR_ATTACHMENTS_NV 0x8CDF +/* GL_COLOR_ATTACHMENT{0-15}_NV defined in GL_NV_draw_buffers already. */ +#endif + +/* GL_NV_fence */ +#ifndef GL_NV_fence +#define GL_ALL_COMPLETED_NV 0x84F2 +#define GL_FENCE_STATUS_NV 0x84F3 +#define GL_FENCE_CONDITION_NV 0x84F4 +#endif + +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_READ_BUFFER_NV 0x0C02 +#endif + +/* GL_NV_read_buffer_front */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_depth_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_read_stencil */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_compression_s3tc_update */ +/* No new tokens introduced by this extension. */ + +/* GL_NV_texture_npot_2D_mipmap */ +/* No new tokens introduced by this extension. */ + /*------------------------------------------------------------------------* * QCOM extension tokens *------------------------------------------------------------------------*/ +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 +#endif + /* GL_QCOM_driver_control */ /* No new tokens introduced by this extension. */ @@ -357,22 +666,12 @@ typedef void* GLeglImageOES; #endif /*------------------------------------------------------------------------* - * ANGLE extension tokens + * VIV extension tokens *------------------------------------------------------------------------*/ -/* GL_ANGLE_framebuffer_blit */ -#ifndef GL_ANGLE_framebuffer_blit -#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias GL_FRAMEBUFFER_BINDING -#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA -#endif - -/* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56 -#define GL_MAX_SAMPLES_ANGLE 0x8D57 +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_SHADER_BINARY_VIV 0x8FC4 #endif /*------------------------------------------------------------------------* @@ -419,6 +718,12 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image); #endif +/* GL_OES_EGL_image_external */ +#ifndef GL_OES_EGL_image_external +#define GL_OES_EGL_image_external 1 +/* glEGLImageTargetTexture2DOES defined in GL_OES_EGL_image already. */ +#endif + /* GL_OES_element_index_uint */ #ifndef GL_OES_element_index_uint #define GL_OES_element_index_uint 1 @@ -601,6 +906,114 @@ typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monito #endif /*------------------------------------------------------------------------* + * ANGLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_ANGLE_framebuffer_blit */ +#ifndef GL_ANGLE_framebuffer_blit +#define GL_ANGLE_framebuffer_blit 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif +typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +/* GL_ANGLE_framebuffer_multisample */ +#ifndef GL_ANGLE_framebuffer_multisample +#define GL_ANGLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +#endif + +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + +/* GL_ANGLE_texture_compression_dxt3 */ +#ifndef GL_ANGLE_texture_compression_dxt3 +#define GL_ANGLE_texture_compression_dxt3 1 +#endif + +/* GL_ANGLE_texture_compression_dxt5 */ +#ifndef GL_ANGLE_texture_compression_dxt5 +#define GL_ANGLE_texture_compression_dxt5 1 +#endif + +/* GL_ANGLE_translated_shader_source */ +#ifndef GL_ANGLE_translated_shader_source +#define GL_ANGLE_translated_shader_source 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGetTranslatedShaderSourceANGLE (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +#endif +typedef void (GL_APIENTRYP PFNGLGETTRANSLATEDSHADERSOURCEANGLEPROC) (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source); +#endif + +/* GL_ANGLE_texture_usage */ +#ifndef GL_ANGLE_texture_usage +#define GL_ANGLE_texture_usage 1 +#endif + +/* GL_ANGLE_instanced_arrays */ +#ifndef GL_ANGLE_instanced_arrays +#define GL_ANGLE_instanced_arrays 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glVertexAttribDivisorANGLE(GLuint index, GLuint divisor); +GL_APICALL void GL_APIENTRY glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount); +GL_APICALL void GL_APIENTRY glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif +typedef void (GL_APIENTRYP PFNGLVERTEXATTRIBDIVISORANGLEPROC) (GLuint index, GLuint divisor); +typedef void (GL_APIENTRYP PFNGLDRAWARRAYSINSTANCEDANGLEPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); +typedef void (GL_APIENTRYP PFNGLDRAWELEMENTSINSTANCEDANGLEPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); +#endif + +/*------------------------------------------------------------------------* + * APPLE extension functions + *------------------------------------------------------------------------*/ + +/* GL_APPLE_rgb_422 */ +#ifndef GL_APPLE_rgb_422 +#define GL_APPLE_rgb_422 1 +#endif + +/* GL_APPLE_framebuffer_multisample */ +#ifndef GL_APPLE_framebuffer_multisample +#define GL_APPLE_framebuffer_multisample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleAPPLE (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +GL_APICALL void GL_APIENTRY glResolveMultisampleFramebufferAPPLE (void); +#endif /* GL_GLEXT_PROTOTYPES */ +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEAPPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLRESOLVEMULTISAMPLEFRAMEBUFFERAPPLEPROC) (void); +#endif + +/* GL_APPLE_texture_format_BGRA8888 */ +#ifndef GL_APPLE_texture_format_BGRA8888 +#define GL_APPLE_texture_format_BGRA8888 1 +#endif + +/* GL_APPLE_texture_max_level */ +#ifndef GL_APPLE_texture_max_level +#define GL_APPLE_texture_max_level 1 +#endif + +/*------------------------------------------------------------------------* + * ARM extension functions + *------------------------------------------------------------------------*/ + +/* GL_ARM_mali_shader_binary */ +#ifndef GL_ARM_mali_shader_binary +#define GL_ARM_mali_shader_binary 1 +#endif + +/* GL_ARM_rgba8 */ +#ifndef GL_ARM_rgba8 +#define GL_ARM_rgba8 1 +#endif + +/*------------------------------------------------------------------------* * EXT extension functions *------------------------------------------------------------------------*/ @@ -609,6 +1022,35 @@ typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monito #define GL_EXT_blend_minmax 1 #endif +/* GL_EXT_color_buffer_half_float */ +#ifndef GL_EXT_color_buffer_half_float +#define GL_EXT_color_buffer_half_float 1 +#endif + +/* GL_EXT_debug_label */ +#ifndef GL_EXT_debug_label +#define GL_EXT_debug_label 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glLabelObjectEXT (GLenum type, GLuint object, GLsizei length, const GLchar *label); +GL_APICALL void GL_APIENTRY glGetObjectLabelEXT (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif +typedef void (GL_APIENTRYP PFNGLLABELOBJECTEXTPROC) (GLenum type, GLuint object, GLsizei length, const GLchar *label); +typedef void (GL_APIENTRYP PFNGLGETOBJECTLABELEXTPROC) (GLenum type, GLuint object, GLsizei bufSize, GLsizei *length, GLchar *label); +#endif + +/* GL_EXT_debug_marker */ +#ifndef GL_EXT_debug_marker +#define GL_EXT_debug_marker 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glInsertEventMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPushGroupMarkerEXT (GLsizei length, const GLchar *marker); +GL_APICALL void GL_APIENTRY glPopGroupMarkerEXT (void); +#endif +typedef void (GL_APIENTRYP PFNGLINSERTEVENTMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPUSHGROUPMARKEREXTPROC) (GLsizei length, const GLchar *marker); +typedef void (GL_APIENTRYP PFNGLPOPGROUPMARKEREXTPROC) (void); +#endif + /* GL_EXT_discard_framebuffer */ #ifndef GL_EXT_discard_framebuffer #define GL_EXT_discard_framebuffer 1 @@ -618,6 +1060,17 @@ GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numA typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments); #endif +/* GL_EXT_multisampled_render_to_texture */ +#ifndef GL_EXT_multisampled_render_to_texture +#define GL_EXT_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + #ifndef GL_EXT_multi_draw_arrays #define GL_EXT_multi_draw_arrays 1 #ifdef GL_GLEXT_PROTOTYPES @@ -628,11 +1081,134 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *fir typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif +/* GL_EXT_occlusion_query_boolean */ +#ifndef GL_EXT_occlusion_query_boolean +#define GL_EXT_occlusion_query_boolean 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glGenQueriesEXT (GLsizei n, GLuint *ids); +GL_APICALL void GL_APIENTRY glDeleteQueriesEXT (GLsizei n, const GLuint *ids); +GL_APICALL GLboolean GL_APIENTRY glIsQueryEXT (GLuint id); +GL_APICALL void GL_APIENTRY glBeginQueryEXT (GLenum target, GLuint id); +GL_APICALL void GL_APIENTRY glEndQueryEXT (GLenum target); +GL_APICALL void GL_APIENTRY glGetQueryivEXT (GLenum target, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glGetQueryObjectuivEXT (GLuint id, GLenum pname, GLuint *params); +#endif +typedef void (GL_APIENTRYP PFNGLGENQUERIESEXTPROC) (GLsizei n, GLuint *ids); +typedef void (GL_APIENTRYP PFNGLDELETEQUERIESEXTPROC) (GLsizei n, const GLuint *ids); +typedef GLboolean (GL_APIENTRYP PFNGLISQUERYEXTPROC) (GLuint id); +typedef void (GL_APIENTRYP PFNGLBEGINQUERYEXTPROC) (GLenum target, GLuint id); +typedef void (GL_APIENTRYP PFNGLENDQUERYEXTPROC) (GLenum target); +typedef void (GL_APIENTRYP PFNGLGETQUERYIVEXTPROC) (GLenum target, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLGETQUERYOBJECTUIVEXTPROC) (GLuint id, GLenum pname, GLuint *params); +#endif + /* GL_EXT_read_format_bgra */ #ifndef GL_EXT_read_format_bgra #define GL_EXT_read_format_bgra 1 #endif +/* GL_EXT_robustness */ +#ifndef GL_EXT_robustness +#define GL_EXT_robustness 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL GLenum GL_APIENTRY glGetGraphicsResetStatusEXT (void); +GL_APICALL void GL_APIENTRY glReadnPixelsEXT (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +GL_APICALL void GL_APIENTRY glGetnUniformfvEXT (GLuint program, GLint location, GLsizei bufSize, float *params); +GL_APICALL void GL_APIENTRY glGetnUniformivEXT (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif +typedef GLenum (GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSEXTPROC) (void); +typedef void (GL_APIENTRYP PFNGLREADNPIXELSEXTPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMFVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, float *params); +typedef void (GL_APIENTRYP PFNGLGETNUNIFORMIVEXTPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); +#endif + +/* GL_EXT_separate_shader_objects */ +#ifndef GL_EXT_separate_shader_objects +#define GL_EXT_separate_shader_objects 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glUseProgramStagesEXT (GLuint pipeline, GLbitfield stages, GLuint program); +GL_APICALL void GL_APIENTRY glActiveShaderProgramEXT (GLuint pipeline, GLuint program); +GL_APICALL GLuint GL_APIENTRY glCreateShaderProgramvEXT (GLenum type, GLsizei count, const GLchar **strings); +GL_APICALL void GL_APIENTRY glBindProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glDeleteProgramPipelinesEXT (GLsizei n, const GLuint *pipelines); +GL_APICALL void GL_APIENTRY glGenProgramPipelinesEXT (GLsizei n, GLuint *pipelines); +GL_APICALL GLboolean GL_APIENTRY glIsProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); +GL_APICALL void GL_APIENTRY glGetProgramPipelineivEXT (GLuint pipeline, GLenum pname, GLint *params); +GL_APICALL void GL_APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint x); +GL_APICALL void GL_APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint x, GLint y); +GL_APICALL void GL_APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z); +GL_APICALL void GL_APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +GL_APICALL void GL_APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat x); +GL_APICALL void GL_APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat x, GLfloat y); +GL_APICALL void GL_APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +GL_APICALL void GL_APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +GL_APICALL void GL_APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); +GL_APICALL void GL_APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GL_APICALL void GL_APIENTRY glValidateProgramPipelineEXT (GLuint pipeline); +GL_APICALL void GL_APIENTRY glGetProgramPipelineInfoLogEXT (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif +typedef void (GL_APIENTRYP PFNGLUSEPROGRAMSTAGESEXTPROC) (GLuint pipeline, GLbitfield stages, GLuint program); +typedef void (GL_APIENTRYP PFNGLACTIVESHADERPROGRAMEXTPROC) (GLuint pipeline, GLuint program); +typedef GLuint (GL_APIENTRYP PFNGLCREATESHADERPROGRAMVEXTPROC) (GLenum type, GLsizei count, const GLchar **strings); +typedef void (GL_APIENTRYP PFNGLBINDPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLDELETEPROGRAMPIPELINESEXTPROC) (GLsizei n, const GLuint *pipelines); +typedef void (GL_APIENTRYP PFNGLGENPROGRAMPIPELINESEXTPROC) (GLsizei n, GLuint *pipelines); +typedef GLboolean (GL_APIENTRYP PFNGLISPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEIVEXTPROC) (GLuint pipeline, GLenum pname, GLint *params); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint x, GLint y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat x); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +typedef void (GL_APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEEXTPROC) (GLuint pipeline); +typedef void (GL_APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGEXTPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); +#endif + +/* GL_EXT_shader_texture_lod */ +#ifndef GL_EXT_shader_texture_lod +#define GL_EXT_shader_texture_lod 1 +#endif + +/* GL_EXT_shadow_samplers */ +#ifndef GL_EXT_shadow_samplers +#define GL_EXT_shadow_samplers 1 +#endif + +/* GL_EXT_sRGB */ +#ifndef GL_EXT_sRGB +#define GL_EXT_sRGB 1 +#endif + +/* GL_EXT_texture_compression_dxt1 */ +#ifndef GL_EXT_texture_compression_dxt1 +#define GL_EXT_texture_compression_dxt1 1 +#endif + /* GL_EXT_texture_filter_anisotropic */ #ifndef GL_EXT_texture_filter_anisotropic #define GL_EXT_texture_filter_anisotropic 1 @@ -643,14 +1219,47 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL #define GL_EXT_texture_format_BGRA8888 1 #endif +/* GL_EXT_texture_rg */ +#ifndef GL_EXT_texture_rg +#define GL_EXT_texture_rg 1 +#endif + +/* GL_EXT_texture_storage */ +#ifndef GL_EXT_texture_storage +#define GL_EXT_texture_storage 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glTexStorage1DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTexStorage2DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTexStorage3DEXT (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +GL_APICALL void GL_APIENTRY glTextureStorage1DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +GL_APICALL void GL_APIENTRY glTextureStorage2DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +GL_APICALL void GL_APIENTRY glTextureStorage3DEXT (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE1DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE2DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXSTORAGE3DEXTPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE1DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); +#endif + /* GL_EXT_texture_type_2_10_10_10_REV */ #ifndef GL_EXT_texture_type_2_10_10_10_REV #define GL_EXT_texture_type_2_10_10_10_REV 1 #endif -/* GL_EXT_texture_compression_dxt1 */ -#ifndef GL_EXT_texture_compression_dxt1 -#define GL_EXT_texture_compression_dxt1 1 +/* GL_EXT_unpack_subimage */ +#ifndef GL_EXT_unpack_subimage +#define GL_EXT_unpack_subimage 1 +#endif + +/*------------------------------------------------------------------------* + * DMP extension functions + *------------------------------------------------------------------------*/ + +/* GL_DMP_shader_binary */ +#ifndef GL_DMP_shader_binary +#define GL_DMP_shader_binary 1 #endif /*------------------------------------------------------------------------* @@ -677,10 +1286,51 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL #define GL_IMG_texture_compression_pvrtc 1 #endif +/* GL_IMG_multisampled_render_to_texture */ +#ifndef GL_IMG_multisampled_render_to_texture +#define GL_IMG_multisampled_render_to_texture 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); +#endif +typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); +typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples); +#endif + /*------------------------------------------------------------------------* * NV extension functions *------------------------------------------------------------------------*/ +/* GL_NV_coverage_sample */ +#ifndef GL_NV_coverage_sample +#define GL_NV_coverage_sample 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); +GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +#endif +typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); +typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +#endif + +/* GL_NV_depth_nonlinear */ +#ifndef GL_NV_depth_nonlinear +#define GL_NV_depth_nonlinear 1 +#endif + +/* GL_NV_draw_buffers */ +#ifndef GL_NV_draw_buffers +#define GL_NV_draw_buffers 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glDrawBuffersNV (GLsizei n, const GLenum *bufs); +#endif +typedef void (GL_APIENTRYP PFNGLDRAWBUFFERSNVPROC) (GLsizei n, const GLenum *bufs); +#endif + +/* GL_NV_fbo_color_attachments */ +#ifndef GL_NV_fbo_color_attachments +#define GL_NV_fbo_color_attachments 1 +#endif + /* GL_NV_fence */ #ifndef GL_NV_fence #define GL_NV_fence 1 @@ -702,26 +1352,58 @@ typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); #endif -/* GL_NV_coverage_sample */ -#ifndef GL_NV_coverage_sample -#define GL_NV_coverage_sample 1 +/* GL_NV_read_buffer */ +#ifndef GL_NV_read_buffer +#define GL_NV_read_buffer 1 #ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask); -GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation); +GL_APICALL void GL_APIENTRY glReadBufferNV (GLenum mode); #endif -typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask); -typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation); +typedef void (GL_APIENTRYP PFNGLREADBUFFERNVPROC) (GLenum mode); #endif -/* GL_NV_depth_nonlinear */ -#ifndef GL_NV_depth_nonlinear -#define GL_NV_depth_nonlinear 1 +/* GL_NV_read_buffer_front */ +#ifndef GL_NV_read_buffer_front +#define GL_NV_read_buffer_front 1 +#endif + +/* GL_NV_read_depth */ +#ifndef GL_NV_read_depth +#define GL_NV_read_depth 1 +#endif + +/* GL_NV_read_depth_stencil */ +#ifndef GL_NV_read_depth_stencil +#define GL_NV_read_depth_stencil 1 +#endif + +/* GL_NV_read_stencil */ +#ifndef GL_NV_read_stencil +#define GL_NV_read_stencil 1 +#endif + +/* GL_NV_texture_compression_s3tc_update */ +#ifndef GL_NV_texture_compression_s3tc_update +#define GL_NV_texture_compression_s3tc_update 1 +#endif + +/* GL_NV_texture_npot_2D_mipmap */ +#ifndef GL_NV_texture_npot_2D_mipmap +#define GL_NV_texture_npot_2D_mipmap 1 #endif /*------------------------------------------------------------------------* * QCOM extension functions *------------------------------------------------------------------------*/ +/* GL_QCOM_alpha_test */ +#ifndef GL_QCOM_alpha_test +#define GL_QCOM_alpha_test 1 +#ifdef GL_GLEXT_PROTOTYPES +GL_APICALL void GL_APIENTRY glAlphaFuncQCOM (GLenum func, GLclampf ref); +#endif +typedef void (GL_APIENTRYP PFNGLALPHAFUNCQCOMPROC) (GLenum func, GLclampf ref); +#endif + /* GL_QCOM_driver_control */ #ifndef GL_QCOM_driver_control #define GL_QCOM_driver_control 1 @@ -797,31 +1479,12 @@ typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask); #endif /*------------------------------------------------------------------------* - * ANGLE extension functions + * VIV extension tokens *------------------------------------------------------------------------*/ -/* GL_ANGLE_framebuffer_blit */ -#ifndef GL_ANGLE_framebuffer_blit -#define GL_ANGLE_framebuffer_blit 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); -#endif -typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); -#endif - -/* GL_ANGLE_framebuffer_multisample */ -#ifndef GL_ANGLE_framebuffer_multisample -#define GL_ANGLE_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat, - GLsizei width, GLsizei height); -#endif -typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, - GLsizei width, GLsizei height); +/* GL_VIV_shader_binary */ +#ifndef GL_VIV_shader_binary +#define GL_VIV_shader_binary 1 #endif #ifdef __cplusplus diff --git a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h index d0664e4..a3fc935 100644 --- a/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h +++ b/Source/ThirdParty/ANGLE/include/GLSLANG/ShaderLang.h @@ -6,6 +6,23 @@ #ifndef _COMPILER_INTERFACE_INCLUDED_ #define _COMPILER_INTERFACE_INCLUDED_ +#if defined(COMPONENT_BUILD) +#if defined(_WIN32) || defined(_WIN64) + +#if defined(COMPILER_IMPLEMENTATION) +#define COMPILER_EXPORT __declspec(dllexport) +#else +#define COMPILER_EXPORT __declspec(dllimport) +#endif // defined(COMPILER_IMPLEMENTATION) + +#else // defined(WIN32) +#define COMPILER_EXPORT __attribute__((visibility("default"))) +#endif + +#else // defined(COMPONENT_BUILD) +#define COMPILER_EXPORT +#endif + // // This is the platform independent interface between an OGL driver // and the shading language compiler. @@ -17,7 +34,7 @@ extern "C" { // Version number for shader translation API. // It is incremented everytime the API changes. -#define SH_VERSION 103 +#define SH_VERSION 105 // // The names of the following enums have been derived by replacing GL prefix @@ -36,6 +53,12 @@ typedef enum { } ShShaderSpec; typedef enum { + SH_ESSL_OUTPUT = 0x8B45, + SH_GLSL_OUTPUT = 0x8B46, + SH_HLSL_OUTPUT = 0x8B47 +} ShShaderOutput; + +typedef enum { SH_NONE = 0, SH_INT = 0x1404, SH_FLOAT = 0x1406, @@ -53,7 +76,9 @@ typedef enum { SH_FLOAT_MAT3 = 0x8B5B, SH_FLOAT_MAT4 = 0x8B5C, SH_SAMPLER_2D = 0x8B5E, - SH_SAMPLER_CUBE = 0x8B60 + SH_SAMPLER_CUBE = 0x8B60, + SH_SAMPLER_2D_RECT_ARB = 0x8B63, + SH_SAMPLER_EXTERNAL_OES = 0x8D66 } ShDataType; typedef enum { @@ -62,16 +87,24 @@ typedef enum { SH_ACTIVE_UNIFORMS = 0x8B86, SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87, SH_ACTIVE_ATTRIBUTES = 0x8B89, - SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A + SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A, + SH_MAPPED_NAME_MAX_LENGTH = 0x8B8B } 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 + SH_VALIDATE = 0, + SH_VALIDATE_LOOP_INDEXING = 0x0001, + SH_INTERMEDIATE_TREE = 0x0002, + SH_OBJECT_CODE = 0x0004, + SH_ATTRIBUTES_UNIFORMS = 0x0008, + SH_LINE_DIRECTIVES = 0x0010, + SH_SOURCE_PATH = 0x0020, + SH_MAP_LONG_VARIABLE_NAMES = 0x0040, + SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX = 0x0080, + + // This is needed only as a workaround for certain OpenGL driver bugs. + SH_EMULATE_BUILT_IN_FUNCTIONS = 0x0100 } ShCompileOptions; // @@ -79,12 +112,12 @@ typedef enum { // compiler operations. // If the function succeeds, the return value is nonzero, else zero. // -int ShInitialize(); +COMPILER_EXPORT int ShInitialize(); // // Driver should call this at shutdown. // If the function succeeds, the return value is nonzero, else zero. // -int ShFinalize(); +COMPILER_EXPORT int ShFinalize(); // // Implementation dependent built-in resources (constants and extensions). @@ -105,12 +138,14 @@ typedef struct // Extensions. // Set to 1 to enable the extension, else 0. int OES_standard_derivatives; + int OES_EGL_image_external; + int ARB_texture_rectangle; } ShBuiltInResources; // // Initialize built-in resources with minimum expected values. // -void ShInitBuiltInResources(ShBuiltInResources* resources); +COMPILER_EXPORT void ShInitBuiltInResources(ShBuiltInResources* resources); // // ShHandle held by but opaque to the driver. It is allocated, @@ -124,15 +159,21 @@ typedef void* ShHandle; // // Driver calls these to create and destroy compiler objects. // -// Returns the handle of constructed compiler. +// Returns the handle of constructed compiler, null if the requested compiler is +// not supported. // 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. +// output: Specifies the output code type - SH_ESSL_OUTPUT, SH_GLSL_OUTPUT, +// or SH_HLSL_OUTPUT. // resources: Specifies the built-in resources. -ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec, - const ShBuiltInResources* resources); -void ShDestruct(ShHandle handle); +COMPILER_EXPORT ShHandle ShConstructCompiler( + ShShaderType type, + ShShaderSpec spec, + ShShaderOutput output, + const ShBuiltInResources* resources); +COMPILER_EXPORT void ShDestruct(ShHandle handle); // // Compiles the given shader source. @@ -159,7 +200,7 @@ void ShDestruct(ShHandle handle); // Can be queried by calling ShGetActiveAttrib() and // ShGetActiveUniform(). // -int ShCompile( +COMPILER_EXPORT int ShCompile( const ShHandle handle, const char* const shaderStrings[], const int numStrings, @@ -183,9 +224,13 @@ int ShCompile( // SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform // variable name including the null // termination character. +// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including +// the null termination character. // // params: Requested parameter -void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params); +COMPILER_EXPORT void ShGetInfo(const ShHandle handle, + ShShaderInfo pname, + int* params); // Returns nul-terminated information log for a compiled shader. // Parameters: @@ -195,7 +240,7 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params); // 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); +COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog); // Returns null-terminated object code for a compiled shader. // Parameters: @@ -205,7 +250,7 @@ void ShGetInfoLog(const ShHandle handle, char* infoLog); // 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); +COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode); // Returns information about an active attribute variable. // Parameters: @@ -221,12 +266,18 @@ void ShGetObjectCode(const ShHandle handle, char* objCode); // 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); +// mappedName: Returns a null terminated string containing the mapped name of +// the attribute variable, It is assumed that mappedName has enough +// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care +// about the mapped name. If the name is not mapped, then name and +// mappedName are the same. +COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle, + int index, + int* length, + int* size, + ShDataType* type, + char* name, + char* mappedName); // Returns information about an active uniform variable. // Parameters: @@ -242,12 +293,18 @@ void ShGetActiveAttrib(const ShHandle handle, // 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); +// mappedName: Returns a null terminated string containing the mapped name of +// the uniform variable, It is assumed that mappedName has enough +// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care +// about the mapped name. If the name is not mapped, then name and +// mappedName are the same. +COMPILER_EXPORT void ShGetActiveUniform(const ShHandle handle, + int index, + int* length, + int* size, + ShDataType* type, + char* name, + char* mappedName); #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 67f7e29..409b622 100644 --- a/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj +++ b/Source/ThirdParty/ANGLE/src/build_angle.xcodeproj/project.pbxproj @@ -13,136 +13,132 @@ buildPhases = ( ); dependencies = ( - FB3C506411F792970081F5BA /* PBXTargetDependency */, + A15E78BECDFF20BC3FFF040A /* PBXTargetDependency */, + BA246CA19435A9FA8AC69146 /* PBXTargetDependency */, + E4A3D33CA49D013550B8BA5F /* PBXTargetDependency */, ); name = All; productName = All; }; - 31349D665FAE642AEB49135E /* ANGLE Support */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 0AA54825BF5DF0A3FBA92B60 /* Build configuration list for PBXAggregateTarget "ANGLE Support" */; - buildPhases = ( - FA0D7125DB06A7A7716A5910 /* Action "flex_glslang" */, - 0D513F8B923949C156DB02C5 /* Action "bison_glslang" */, - ); - dependencies = ( - ); - name = "ANGLE Support"; - productName = "translator_common Support"; - }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 05563ADFEA15116D7233332F /* QualifierAlive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4857E18799D332C30EF460C7 /* QualifierAlive.cpp */; }; + 08A7933BD2F78A86B90200F6 /* Compiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A118E5003E5C0E253C53839 /* Compiler.cpp */; }; 0A216949103E1E228F9C12F0 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */; }; + 0AC1897E461A0D4758E3DCE3 /* VersionGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F727AEC906712EC238041464 /* VersionGLSL.cpp */; }; + 0E9456F464E16392D1CCD030 /* ValidateLimitations.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B148D967B8D288A8267BFF3A /* ValidateLimitations.cpp */; }; + 0EC09B3B254829F8F1D952D3 /* ForLoopUnroll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5DC9B647E10F65F66142ECC1 /* ForLoopUnroll.cpp */; }; + 1ED1D2C7C74C6B625AFB1CCF /* VariableInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27C11EE10FED2979931FFC11 /* VariableInfo.cpp */; }; + 296466566D8C0F023A553760 /* SearchSymbol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 228A6DEDDF08DB370394A7AD /* SearchSymbol.cpp */; }; + 2E7C0D3804B8308A493D9B4B /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F68A6AA811495718A6938C0 /* glslang_tab.cpp */; }; + 3021E0BF1BC8442FF1F2F2B4 /* glslang_lex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 73A57C6D413773AEBA3C47A6 /* glslang_lex.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 */; }; 3A96E9CAC8A25AF1564B652C /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 294F442A2606FEC55F12A28E /* memory.c */; }; + 3F18389BCB89370A930667F4 /* TranslatorGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6FB70DC74A21FBCD665ABDF9 /* TranslatorGLSL.cpp */; }; 40FC189B8A246EDF14C2FDE3 /* intermOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEAF6F3126C2EC4397785C3F /* intermOut.cpp */; }; + 4B4BDE7AD6266B39ED43C2D4 /* CodeGenHLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C49549DCCAF450EB761520E1 /* CodeGenHLSL.cpp */; }; 50DF00005CC4212F6FB1291D /* Intermediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F7C486C370A72938FE8160F /* Intermediate.cpp */; }; + 55CBD87573B803A173AC9129 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3EE7215A7AB4EF71C97D2545 /* util.cpp */; }; + 5F7B52A54DCE8155ED94ECF8 /* OutputHLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A5B5BB2526802479E19F993 /* OutputHLSL.cpp */; }; 6F9F875017A68ABE5D39FF19 /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 976C831A75EBE009A9861796 /* ParseHelper.cpp */; }; 888F1382498E2D74AF2801C8 /* debug.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4ABA230FEA3654B030E4C4FB /* debug.cpp */; }; + 896B720BD21F6749A7D83F30 /* MapLongVariableNames.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 57CF1F83E842901C42D44825 /* MapLongVariableNames.cpp */; }; + 93A41AF036E5EF87B366B563 /* TranslatorESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0A3A260F5379A7E2655D40F3 /* TranslatorESSL.cpp */; }; + 9886BCD5D0DD69B6FDE09DD8 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */; }; + 9B111B83FB636FD5CDEC32A0 /* OutputGLSLBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BCDF01F002ADE9DB8A3EF4FE /* OutputGLSLBase.cpp */; }; 9E8DFE1CCEF038BF2B65428C /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.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 */; }; B8BD2685A16B188CCDFB052B /* ShaderLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56C7E99BA500A84C35216FE0 /* ShaderLang.cpp */; }; BEBBF4F0819EA3D03977A8FC /* InfoSink.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6E6927BE5D3C2C82F86111DF /* InfoSink.cpp */; }; + C4AAB2BB4594C0DA318DCB1C /* OutputESSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DB2917C5B624712364DE4A75 /* OutputESSL.cpp */; }; + C75EB9292A0DDA45592A8ACF /* OutputGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 48B7402CC07A059FEF5EC351 /* OutputGLSL.cpp */; }; CB7F0EF0D6A89FA8C4DF5513 /* cpp.c in Sources */ = {isa = PBXBuildFile; fileRef = B75707B393B7EAB7DD9999CB /* cpp.c */; }; + D56F7D00E9B162E416D37DF0 /* CodeGenGLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B7B1127C75B576FC00D74AED /* CodeGenGLSL.cpp */; }; E1C7C5DFF0B2DFEC09387F4E /* PoolAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B64EABE738FC666A5E4E2F42 /* PoolAlloc.cpp */; }; E8C727AA8E9DC5E7B58857DF /* tokens.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D00745DA9914FDE274D03D5 /* tokens.c */; }; + E99D6D80DBF05ECE7108B26D /* TranslatorHLSL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C3DAFF6BF12BB7F4784D6C7E /* TranslatorHLSL.cpp */; }; F098F463EDABCF0769007678 /* scanner.c in Sources */ = {isa = PBXBuildFile; fileRef = FF3AA694DF9A4455A813234D /* scanner.c */; }; F5AE2A292DFAF8C158412AA2 /* IntermTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */; }; F6ABD58F8CAB7641D8BFE935 /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B7E5B0F04635E6090F0DE8EF /* SymbolTable.cpp */; }; - 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 */; }; - 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 */; }; - FB3C509511F794CE0081F5BA /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */; }; - FB3C509611F794CE0081F5BA /* Intermediate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F7C486C370A72938FE8160F /* Intermediate.cpp */; }; - FB3C509711F794CE0081F5BA /* intermOut.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEAF6F3126C2EC4397785C3F /* intermOut.cpp */; }; - FB3C509811F794CE0081F5BA /* IntermTraverse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */; }; - FB3C509A11F794CE0081F5BA /* ossource_posix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BE258486005F6696CC031622 /* ossource_posix.cpp */; }; - FB3C509B11F794CE0081F5BA /* parseConst.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */; }; - FB3C509C11F794CE0081F5BA /* ParseHelper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 976C831A75EBE009A9861796 /* ParseHelper.cpp */; }; - FB3C509D11F794CE0081F5BA /* PoolAlloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B64EABE738FC666A5E4E2F42 /* PoolAlloc.cpp */; }; - FB3C509E11F794CE0081F5BA /* QualifierAlive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4857E18799D332C30EF460C7 /* QualifierAlive.cpp */; }; - FB3C509F11F794CE0081F5BA /* RemoveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */; }; - FB3C50A011F794CE0081F5BA /* ShaderLang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56C7E99BA500A84C35216FE0 /* ShaderLang.cpp */; }; - FB3C50A111F794CE0081F5BA /* SymbolTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B7E5B0F04635E6090F0DE8EF /* SymbolTable.cpp */; }; - FB3C50A411F794FF0081F5BA /* atom.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C9B4616A65A5ABEF91FD6DC /* atom.c */; }; - FB3C50A511F794FF0081F5BA /* cpp.c in Sources */ = {isa = PBXBuildFile; fileRef = B75707B393B7EAB7DD9999CB /* cpp.c */; }; - FB3C50A611F794FF0081F5BA /* cppstruct.c in Sources */ = {isa = PBXBuildFile; fileRef = 8058A0A2A0A02386867517EA /* cppstruct.c */; }; - FB3C50A711F794FF0081F5BA /* memory.c in Sources */ = {isa = PBXBuildFile; fileRef = 294F442A2606FEC55F12A28E /* memory.c */; }; - FB3C50A811F794FF0081F5BA /* scanner.c in Sources */ = {isa = PBXBuildFile; fileRef = FF3AA694DF9A4455A813234D /* scanner.c */; }; - FB3C50A911F794FF0081F5BA /* symbols.c in Sources */ = {isa = PBXBuildFile; fileRef = F013A7240BDAE8A61413D8C0 /* symbols.c */; }; - FB3C50AA11F794FF0081F5BA /* tokens.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D00745DA9914FDE274D03D5 /* tokens.c */; }; - FB3C50AB11F7951B0081F5BA /* TranslatorGLSL.h in Sources */ = {isa = PBXBuildFile; fileRef = DDD3B7E3B7B35A0B8469AB87 /* TranslatorGLSL.h */; }; - FB3C50AC11F7951B0081F5BA /* OutputGLSL.h in Sources */ = {isa = PBXBuildFile; fileRef = 93D61CB0BCE54E069D71F920 /* OutputGLSL.h */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - E69BFBE2D1272620E46C3F8A /* PBXContainerItemProxy */ = { + 1F7242496103EDF29CC25D87 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DA188D8C6BF8073122539131 /* Project object */; proxyType = 1; - remoteGlobalIDString = 31349D665FAE642AEB49135E; - remoteInfo = "translator_common Support"; + remoteGlobalIDString = A838E9574B3FF14791DBDAB1; + remoteInfo = translator_hlsl; }; - FB3C506311F792970081F5BA /* PBXContainerItemProxy */ = { + 55D5F9BF727E4A3B6637802B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DA188D8C6BF8073122539131 /* Project object */; proxyType = 1; - remoteGlobalIDString = FB3C505511F7924A0081F5BA; - remoteInfo = angle; + remoteGlobalIDString = 6F4FD35CB3DFC89D70ECD432; + remoteInfo = translator_common; }; - FB3C50D011F79CCC0081F5BA /* PBXContainerItemProxy */ = { + 60D3546AC27B094D6CA04CD6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DA188D8C6BF8073122539131 /* Project object */; proxyType = 1; - remoteGlobalIDString = 31349D665FAE642AEB49135E; - remoteInfo = "ANGLE Support"; + remoteGlobalIDString = 5892C7A3695330437AFE5714; + remoteInfo = translator_glsl; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ 056FEADC7D95C6D4C9CF1113 /* scanner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scanner.h; sourceTree = "<group>"; }; + 0A118E5003E5C0E253C53839 /* Compiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Compiler.cpp; sourceTree = "<group>"; }; + 0A3A260F5379A7E2655D40F3 /* TranslatorESSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TranslatorESSL.cpp; sourceTree = "<group>"; }; 0C9B4616A65A5ABEF91FD6DC /* atom.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = atom.c; sourceTree = "<group>"; }; + 120AD0A3B7642FB5A9AE3A56 /* VersionGLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VersionGLSL.h; sourceTree = "<group>"; }; 12EAF028311EEA4753E82818 /* PoolAlloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PoolAlloc.h; sourceTree = "<group>"; }; 153BF06BF12C6F50496C6156 /* localintermediate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = localintermediate.h; sourceTree = "<group>"; }; + 182BAD50D4E58B884F5EB9F3 /* ForLoopUnroll.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForLoopUnroll.h; sourceTree = "<group>"; }; + 228A6DEDDF08DB370394A7AD /* SearchSymbol.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SearchSymbol.cpp; sourceTree = "<group>"; }; + 27C11EE10FED2979931FFC11 /* VariableInfo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VariableInfo.cpp; sourceTree = "<group>"; }; 27E4C7ED0B82E18DCBEDF1C9 /* BaseTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BaseTypes.h; sourceTree = "<group>"; }; 294F442A2606FEC55F12A28E /* memory.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memory.c; sourceTree = "<group>"; }; 2A765B86CBAF0D4A3E69DCA7 /* UnfoldSelect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UnfoldSelect.h; sourceTree = "<group>"; }; 2D00745DA9914FDE274D03D5 /* tokens.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = tokens.c; sourceTree = "<group>"; }; 2E7C9B6E6DB751E12A2F6CB6 /* InitializeGlobals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InitializeGlobals.h; sourceTree = "<group>"; }; 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_common.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 3EE7215A7AB4EF71C97D2545 /* util.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = util.cpp; sourceTree = "<group>"; }; + 3F68A6AA811495718A6938C0 /* glslang_tab.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_tab.cpp; sourceTree = "<group>"; }; 3F7C486C370A72938FE8160F /* Intermediate.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Intermediate.cpp; sourceTree = "<group>"; }; 4857E18799D332C30EF460C7 /* QualifierAlive.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = QualifierAlive.cpp; sourceTree = "<group>"; }; 48B7402CC07A059FEF5EC351 /* OutputGLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OutputGLSL.cpp; sourceTree = "<group>"; }; + 497C5C24EEF466FB4B50A259 /* glslang.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glslang.h; sourceTree = "<group>"; }; 4ABA230FEA3654B030E4C4FB /* debug.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = debug.cpp; sourceTree = "<group>"; }; + 4FCF32CB2D8A42C930A66B00 /* glslang_tab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glslang_tab.h; sourceTree = "<group>"; }; 528FF201839C6F233E26FFDA /* cpp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cpp.h; sourceTree = "<group>"; }; 56C7E99BA500A84C35216FE0 /* ShaderLang.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ShaderLang.cpp; sourceTree = "<group>"; }; + 57CF1F83E842901C42D44825 /* MapLongVariableNames.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MapLongVariableNames.cpp; sourceTree = "<group>"; }; 580B2A31F7C51A59B40F11A3 /* compile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = compile.h; sourceTree = "<group>"; }; 5A21599C59BC1A75A7FABA34 /* OutputHLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputHLSL.h; sourceTree = "<group>"; }; + 5D99354C4D8187D384C81207 /* VariableInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VariableInfo.h; sourceTree = "<group>"; }; + 5DC9B647E10F65F66142ECC1 /* ForLoopUnroll.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ForLoopUnroll.cpp; sourceTree = "<group>"; }; 60C3998C9CE66DE0C5B0FD99 /* InitializeDll.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = "<group>"; }; + 6BB66AB5873868E23675B6DB /* OutputESSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputESSL.h; 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>"; }; + 73A57C6D413773AEBA3C47A6 /* glslang_lex.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = glslang_lex.cpp; sourceTree = "<group>"; }; 799DC9611EE2EA3BA7CF5477 /* intermediate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = intermediate.h; sourceTree = "<group>"; }; 7C6BB12AB099556CF379D78F /* SymbolTable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SymbolTable.h; sourceTree = "<group>"; }; 7D9CF376DC5799B4C6B3331E /* symbols.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = symbols.h; sourceTree = "<group>"; }; 8058A0A2A0A02386867517EA /* cppstruct.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cppstruct.c; sourceTree = "<group>"; }; + 81CC4245A8E5AB5584D336F3 /* MapLongVariableNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MapLongVariableNames.h; sourceTree = "<group>"; }; 831399DEE5DABA09570FB3E7 /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; }; 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>"; }; + 90254842D72975672C2E9A93 /* ValidateLimitations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ValidateLimitations.h; 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>"; }; @@ -150,16 +146,22 @@ 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>"; }; + A1644B00E9304C407FDC5F47 /* libtranslator_glsl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_glsl.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A447F75F33DA4C4C123AC952 /* libtranslator_hlsl.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtranslator_hlsl.a; sourceTree = BUILT_PRODUCTS_DIR; }; + A51C728B615B41E1D59E9902 /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = util.h; 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>"; }; AE7674C52BDDDB28AF5FFD9F /* unistd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; }; + B148D967B8D288A8267BFF3A /* ValidateLimitations.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ValidateLimitations.cpp; sourceTree = "<group>"; }; B2F5CA11EEA92DF2384EFD93 /* ConstantUnion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConstantUnion.h; sourceTree = "<group>"; }; B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RemoveTree.cpp; sourceTree = "<group>"; }; + B55B359CF7E486DBC49BBF0A /* OutputGLSLBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OutputGLSLBase.h; sourceTree = "<group>"; }; B64EABE738FC666A5E4E2F42 /* PoolAlloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PoolAlloc.cpp; sourceTree = "<group>"; }; 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>"; }; + BCDF01F002ADE9DB8A3EF4FE /* OutputGLSLBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OutputGLSLBase.cpp; 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>"; }; @@ -171,15 +173,19 @@ D13C3693B9E40D37F2FAB34A /* tokens.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tokens.h; sourceTree = "<group>"; }; D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = parseConst.cpp; sourceTree = "<group>"; }; D40F78CB9BA0C89921FA319D /* RemoveTree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RemoveTree.h; sourceTree = "<group>"; }; + D53DDD0CDF15EE1DD01F1A20 /* TranslatorESSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TranslatorESSL.h; sourceTree = "<group>"; }; + DB2917C5B624712364DE4A75 /* OutputESSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = OutputESSL.cpp; sourceTree = "<group>"; }; DDD3B7E3B7B35A0B8469AB87 /* TranslatorGLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TranslatorGLSL.h; sourceTree = "<group>"; }; DEAF6F3126C2EC4397785C3F /* intermOut.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = intermOut.cpp; sourceTree = "<group>"; }; DEEAFC618A3B33F1FBFE3536 /* MMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MMap.h; sourceTree = "<group>"; }; E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; }; E3A29B6E9C21B67C25FF0D2B /* TranslatorHLSL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TranslatorHLSL.h; sourceTree = "<group>"; }; F013A7240BDAE8A61413D8C0 /* symbols.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = symbols.c; sourceTree = "<group>"; }; + F3E09DC8E1BF5D2958AACEDE /* SearchSymbol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchSymbol.h; sourceTree = "<group>"; }; + F727AEC906712EC238041464 /* VersionGLSL.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VersionGLSL.cpp; sourceTree = "<group>"; }; F74618F18FE5448115017C44 /* Common.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; }; F7B2971D4EB3836B94B7ECAF /* InfoSink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoSink.h; sourceTree = "<group>"; }; - FB3C505D11F7924A0081F5BA /* libangle.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libangle.a; sourceTree = BUILT_PRODUCTS_DIR; }; + F99E737D3FFD30CA5E354150 /* common.gypi */ = {isa = PBXFileReference; lastKnownFileType = text; name = common.gypi; path = ../build/common.gypi; sourceTree = "<group>"; }; FF3AA694DF9A4455A813234D /* scanner.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = scanner.c; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -191,7 +197,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - FB3C505A11F7924A0081F5BA /* Frameworks */ = { + CA71CBA633EFC63166BEC9F3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FE3679A0955B25EB7BF116E6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -228,16 +241,15 @@ 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 */, C49549DCCAF450EB761520E1 /* CodeGenHLSL.cpp */, F74618F18FE5448115017C44 /* Common.h */, + 0A118E5003E5C0E253C53839 /* Compiler.cpp */, B2F5CA11EEA92DF2384EFD93 /* ConstantUnion.h */, + 5DC9B647E10F65F66142ECC1 /* ForLoopUnroll.cpp */, + 182BAD50D4E58B884F5EB9F3 /* ForLoopUnroll.h */, 6E6927BE5D3C2C82F86111DF /* InfoSink.cpp */, F7B2971D4EB3836B94B7ECAF /* InfoSink.h */, A54F2ED0D82D7BBCA4E9EEEA /* Initialize.cpp */, @@ -249,8 +261,14 @@ C4FE988EF9A293867E5C771B /* IntermTraverse.cpp */, 3F7C486C370A72938FE8160F /* Intermediate.cpp */, DEEAFC618A3B33F1FBFE3536 /* MMap.h */, + 57CF1F83E842901C42D44825 /* MapLongVariableNames.cpp */, + 81CC4245A8E5AB5584D336F3 /* MapLongVariableNames.h */, + DB2917C5B624712364DE4A75 /* OutputESSL.cpp */, + 6BB66AB5873868E23675B6DB /* OutputESSL.h */, 48B7402CC07A059FEF5EC351 /* OutputGLSL.cpp */, 93D61CB0BCE54E069D71F920 /* OutputGLSL.h */, + BCDF01F002ADE9DB8A3EF4FE /* OutputGLSLBase.cpp */, + B55B359CF7E486DBC49BBF0A /* OutputGLSLBase.h */, 9A5B5BB2526802479E19F993 /* OutputHLSL.cpp */, 5A21599C59BC1A75A7FABA34 /* OutputHLSL.h */, 976C831A75EBE009A9861796 /* ParseHelper.cpp */, @@ -261,10 +279,14 @@ 9D47B1AC82E4EE859AC54243 /* QualifierAlive.h */, B436EFF06913FCB19C3522A7 /* RemoveTree.cpp */, D40F78CB9BA0C89921FA319D /* RemoveTree.h */, + 228A6DEDDF08DB370394A7AD /* SearchSymbol.cpp */, + F3E09DC8E1BF5D2958AACEDE /* SearchSymbol.h */, AE65E139AE10DE9EFAD8D5B1 /* ShHandle.h */, 56C7E99BA500A84C35216FE0 /* ShaderLang.cpp */, B7E5B0F04635E6090F0DE8EF /* SymbolTable.cpp */, 7C6BB12AB099556CF379D78F /* SymbolTable.h */, + 0A3A260F5379A7E2655D40F3 /* TranslatorESSL.cpp */, + D53DDD0CDF15EE1DD01F1A20 /* TranslatorESSL.h */, 6FB70DC74A21FBCD665ABDF9 /* TranslatorGLSL.cpp */, DDD3B7E3B7B35A0B8469AB87 /* TranslatorGLSL.h */, C3DAFF6BF12BB7F4784D6C7E /* TranslatorHLSL.cpp */, @@ -272,8 +294,18 @@ AA53B6632C76F905DF08E564 /* Types.h */, E3711A48A0BF16B1CBD77AC9 /* UnfoldSelect.cpp */, 2A765B86CBAF0D4A3E69DCA7 /* UnfoldSelect.h */, + B148D967B8D288A8267BFF3A /* ValidateLimitations.cpp */, + 90254842D72975672C2E9A93 /* ValidateLimitations.h */, + 27C11EE10FED2979931FFC11 /* VariableInfo.cpp */, + 5D99354C4D8187D384C81207 /* VariableInfo.h */, + F727AEC906712EC238041464 /* VersionGLSL.cpp */, + 120AD0A3B7642FB5A9AE3A56 /* VersionGLSL.h */, 4ABA230FEA3654B030E4C4FB /* debug.cpp */, 95276AA6B36FC1B1D913FCE4 /* debug.h */, + 497C5C24EEF466FB4B50A259 /* glslang.h */, + 73A57C6D413773AEBA3C47A6 /* glslang_lex.cpp */, + 3F68A6AA811495718A6938C0 /* glslang_tab.cpp */, + 4FCF32CB2D8A42C930A66B00 /* glslang_tab.h */, DEAF6F3126C2EC4397785C3F /* intermOut.cpp */, 799DC9611EE2EA3BA7CF5477 /* intermediate.h */, 153BF06BF12C6F50496C6156 /* localintermediate.h */, @@ -281,6 +313,8 @@ BE258486005F6696CC031622 /* ossource_posix.cpp */, D2C9C8EB4A7EFF5B67FF9DBF /* parseConst.cpp */, AE7674C52BDDDB28AF5FFD9F /* unistd.h */, + 3EE7215A7AB4EF71C97D2545 /* util.cpp */, + A51C728B615B41E1D59E9902 /* util.h */, ); name = Source; path = compiler; @@ -299,6 +333,7 @@ isa = PBXGroup; children = ( CF2B62E0820C831AF812D000 /* build_angle.gyp */, + F99E737D3FFD30CA5E354150 /* common.gypi */, ); name = Build; sourceTree = "<group>"; @@ -307,7 +342,8 @@ isa = PBXGroup; children = ( 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */, - FB3C505D11F7924A0081F5BA /* libangle.a */, + A1644B00E9304C407FDC5F47 /* libtranslator_glsl.a */, + A447F75F33DA4C4C123AC952 /* libtranslator_hlsl.a */, ); name = Products; sourceTree = "<group>"; @@ -315,6 +351,22 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 5892C7A3695330437AFE5714 /* translator_glsl */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8B8815CA2EFE60FD0C0361BF /* Build configuration list for PBXNativeTarget "translator_glsl" */; + buildPhases = ( + BABCE721106B5C1527EFEF0D /* Sources */, + CA71CBA633EFC63166BEC9F3 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = translator_glsl; + productName = translator_glsl; + productReference = A1644B00E9304C407FDC5F47 /* libtranslator_glsl.a */; + productType = "com.apple.product-type.library.static"; + }; 6F4FD35CB3DFC89D70ECD432 /* translator_common */ = { isa = PBXNativeTarget; buildConfigurationList = 34BB38E3A74418B2A063B49E /* Build configuration list for PBXNativeTarget "translator_common" */; @@ -325,28 +377,26 @@ buildRules = ( ); dependencies = ( - 291EE04202EC7967835FCC38 /* PBXTargetDependency */, ); name = translator_common; productName = translator_common; productReference = 3DDDC77216202A4DE1808BDB /* libtranslator_common.a */; productType = "com.apple.product-type.library.static"; }; - FB3C505511F7924A0081F5BA /* angle */ = { + A838E9574B3FF14791DBDAB1 /* translator_hlsl */ = { isa = PBXNativeTarget; - buildConfigurationList = FB3C505B11F7924A0081F5BA /* Build configuration list for PBXNativeTarget "angle" */; + buildConfigurationList = C71E79C7829FD796CF621B44 /* Build configuration list for PBXNativeTarget "translator_hlsl" */; buildPhases = ( - FB3C505611F7924A0081F5BA /* Sources */, - FB3C505A11F7924A0081F5BA /* Frameworks */, + 05F3BCA9518770BE3F1E0A38 /* Sources */, + FE3679A0955B25EB7BF116E6 /* Frameworks */, ); buildRules = ( ); dependencies = ( - FB3C50D111F79CCC0081F5BA /* PBXTargetDependency */, ); - name = angle; - productName = translator_glsl; - productReference = FB3C505D11F7924A0081F5BA /* libangle.a */; + name = translator_hlsl; + productName = translator_hlsl; + productReference = A447F75F33DA4C4C123AC952 /* libtranslator_hlsl.a */; productType = "com.apple.product-type.library.static"; }; /* End PBXNativeTarget section */ @@ -360,74 +410,61 @@ buildConfigurationList = 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */; compatibilityVersion = "Xcode 3.1"; hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); mainGroup = 5BBEFF9B91738297B95C568D; projectDirPath = ""; projectRoot = ""; targets = ( 1563D9916BFDAD853032CE1A /* All */, 6F4FD35CB3DFC89D70ECD432 /* translator_common */, - 31349D665FAE642AEB49135E /* ANGLE Support */, - FB3C505511F7924A0081F5BA /* angle */, + 5892C7A3695330437AFE5714 /* translator_glsl */, + A838E9574B3FF14791DBDAB1 /* translator_hlsl */, ); }; /* End PBXProject section */ -/* Begin PBXShellScriptBuildPhase section */ - 0D513F8B923949C156DB02C5 /* Action "bison_glslang" */ = { - isa = PBXShellScriptBuildPhase; +/* Begin PBXSourcesBuildPhase section */ + 05F3BCA9518770BE3F1E0A38 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - compiler/glslang.y, - ); - name = "Action \"bison_glslang\""; - outputPaths = ( - "$(INTERMEDIATE_DIR)/glslang_tab.cpp", - "$(INTERMEDIATE_DIR)/glslang_tab.h", + 4B4BDE7AD6266B39ED43C2D4 /* CodeGenHLSL.cpp in Sources */, + 5F7B52A54DCE8155ED94ECF8 /* OutputHLSL.cpp in Sources */, + E99D6D80DBF05ECE7108B26D /* TranslatorHLSL.cpp in Sources */, + 9886BCD5D0DD69B6FDE09DD8 /* UnfoldSelect.cpp in Sources */, + 296466566D8C0F023A553760 /* SearchSymbol.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo note: \"Executing bison on compiler/glslang.y\"\nexec bison --no-lines \"--defines=${INTERMEDIATE_DIR}/glslang_tab.h\" \"--skeleton=yacc.c\" \"--output=${INTERMEDIATE_DIR}/glslang_tab.cpp\" compiler/glslang.y\nexit 1\n"; - showEnvVarsInLog = 0; }; - FA0D7125DB06A7A7716A5910 /* Action "flex_glslang" */ = { - isa = PBXShellScriptBuildPhase; + BABCE721106B5C1527EFEF0D /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - compiler/glslang.l, - ); - name = "Action \"flex_glslang\""; - outputPaths = ( - "$(INTERMEDIATE_DIR)/glslang.cpp", + D56F7D00E9B162E416D37DF0 /* CodeGenGLSL.cpp in Sources */, + 0EC09B3B254829F8F1D952D3 /* ForLoopUnroll.cpp in Sources */, + C4AAB2BB4594C0DA318DCB1C /* OutputESSL.cpp in Sources */, + 9B111B83FB636FD5CDEC32A0 /* OutputGLSLBase.cpp in Sources */, + C75EB9292A0DDA45592A8ACF /* OutputGLSL.cpp in Sources */, + 93A41AF036E5EF87B366B563 /* TranslatorESSL.cpp in Sources */, + 3F18389BCB89370A930667F4 /* TranslatorGLSL.cpp in Sources */, + 0AC1897E461A0D4758E3DCE3 /* VersionGLSL.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "echo note: \"Executing flex on compiler/glslang.l\"\nexec flex --noline --nounistd \"--outfile=${INTERMEDIATE_DIR}/glslang.cpp\" compiler/glslang.l\nexit 1\n"; - showEnvVarsInLog = 0; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ EAA22CA63FD572FCCB913D22 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 08A7933BD2F78A86B90200F6 /* Compiler.cpp in Sources */, 888F1382498E2D74AF2801C8 /* debug.cpp in Sources */, + 3021E0BF1BC8442FF1F2F2B4 /* glslang_lex.cpp in Sources */, + 2E7C0D3804B8308A493D9B4B /* glslang_tab.cpp in Sources */, BEBBF4F0819EA3D03977A8FC /* InfoSink.cpp in Sources */, 3065D29E97FAC6E127388D15 /* Initialize.cpp in Sources */, 0A216949103E1E228F9C12F0 /* InitializeDll.cpp in Sources */, 50DF00005CC4212F6FB1291D /* Intermediate.cpp in Sources */, 40FC189B8A246EDF14C2FDE3 /* intermOut.cpp in Sources */, F5AE2A292DFAF8C158412AA2 /* IntermTraverse.cpp in Sources */, + 896B720BD21F6749A7D83F30 /* MapLongVariableNames.cpp in Sources */, 9E8DFE1CCEF038BF2B65428C /* parseConst.cpp in Sources */, 6F9F875017A68ABE5D39FF19 /* ParseHelper.cpp in Sources */, E1C7C5DFF0B2DFEC09387F4E /* PoolAlloc.cpp in Sources */, @@ -435,6 +472,9 @@ AC23F58FDD3C55F5CA18EED7 /* RemoveTree.cpp in Sources */, B8BD2685A16B188CCDFB052B /* ShaderLang.cpp in Sources */, F6ABD58F8CAB7641D8BFE935 /* SymbolTable.cpp in Sources */, + 55CBD87573B803A173AC9129 /* util.cpp in Sources */, + 0E9456F464E16392D1CCD030 /* ValidateLimitations.cpp in Sources */, + 1ED1D2C7C74C6B625AFB1CCF /* VariableInfo.cpp in Sources */, 32B1DBCD6B83F2146D787A62 /* atom.c in Sources */, CB7F0EF0D6A89FA8C4DF5513 /* cpp.c in Sources */, 35BE1BBEE6135A1CB0608EA8 /* cppstruct.c in Sources */, @@ -446,154 +486,200 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - FB3C505611F7924A0081F5BA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - FB3C50AB11F7951B0081F5BA /* TranslatorGLSL.h in Sources */, - FB3C50AC11F7951B0081F5BA /* OutputGLSL.h in Sources */, - FB3C50A411F794FF0081F5BA /* atom.c in Sources */, - FB3C50A511F794FF0081F5BA /* cpp.c in Sources */, - FB3C50A611F794FF0081F5BA /* cppstruct.c in Sources */, - FB3C50A711F794FF0081F5BA /* memory.c in Sources */, - FB3C50A811F794FF0081F5BA /* scanner.c in Sources */, - FB3C50A911F794FF0081F5BA /* symbols.c in Sources */, - FB3C50AA11F794FF0081F5BA /* tokens.c in Sources */, - FB3C505711F7924A0081F5BA /* CodeGenGLSL.cpp in Sources */, - FB3C509211F794CE0081F5BA /* debug.cpp in Sources */, - FB3C509311F794CE0081F5BA /* InfoSink.cpp in Sources */, - FB3C509411F794CE0081F5BA /* Initialize.cpp in Sources */, - FB3C509511F794CE0081F5BA /* InitializeDll.cpp in Sources */, - FB3C509611F794CE0081F5BA /* Intermediate.cpp in Sources */, - FB3C509711F794CE0081F5BA /* intermOut.cpp in Sources */, - FB3C509811F794CE0081F5BA /* IntermTraverse.cpp in Sources */, - FB3C509A11F794CE0081F5BA /* ossource_posix.cpp in Sources */, - FB3C505811F7924A0081F5BA /* OutputGLSL.cpp in Sources */, - FB3C509B11F794CE0081F5BA /* parseConst.cpp in Sources */, - FB3C509C11F794CE0081F5BA /* ParseHelper.cpp in Sources */, - FB3C509D11F794CE0081F5BA /* PoolAlloc.cpp in Sources */, - FB3C509E11F794CE0081F5BA /* QualifierAlive.cpp in Sources */, - FB3C509F11F794CE0081F5BA /* RemoveTree.cpp in Sources */, - FB3C50A011F794CE0081F5BA /* ShaderLang.cpp in Sources */, - FB3C50A111F794CE0081F5BA /* SymbolTable.cpp in Sources */, - FB3C505911F7924A0081F5BA /* TranslatorGLSL.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 291EE04202EC7967835FCC38 /* PBXTargetDependency */ = { + A15E78BECDFF20BC3FFF040A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 31349D665FAE642AEB49135E /* ANGLE Support */; - targetProxy = E69BFBE2D1272620E46C3F8A /* PBXContainerItemProxy */; + target = 6F4FD35CB3DFC89D70ECD432 /* translator_common */; + targetProxy = 55D5F9BF727E4A3B6637802B /* PBXContainerItemProxy */; }; - FB3C506411F792970081F5BA /* PBXTargetDependency */ = { + BA246CA19435A9FA8AC69146 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = FB3C505511F7924A0081F5BA /* angle */; - targetProxy = FB3C506311F792970081F5BA /* PBXContainerItemProxy */; + target = 5892C7A3695330437AFE5714 /* translator_glsl */; + targetProxy = 60D3546AC27B094D6CA04CD6 /* PBXContainerItemProxy */; }; - FB3C50D111F79CCC0081F5BA /* PBXTargetDependency */ = { + E4A3D33CA49D013550B8BA5F /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 31349D665FAE642AEB49135E /* ANGLE Support */; - targetProxy = FB3C50D011F79CCC0081F5BA /* PBXContainerItemProxy */; + target = A838E9574B3FF14791DBDAB1 /* translator_hlsl */; + targetProxy = 1F7242496103EDF29CC25D87 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 00BF2EBCBDF5678F4BA2FA92 /* Default */ = { + 322A8C62423B595E11BAD42D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - PRODUCT_NAME = "translator_common Support"; + PRODUCT_NAME = All; }; - name = Default; + name = Debug; }; - 1A12AA5D65ACDE71AE089EE3 /* Default */ = { + 4DA42A78D3B855C9CD8F658D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = translator_common; + }; + name = Release; + }; + 4F851F5BA5FA43E9E0B9CB86 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { PRODUCT_NAME = All; }; - name = Default; + name = Release; }; - 1F3F1218B5135FBB067DE809 /* Default */ = { + 88ADC9285519A668808B51EE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); HEADER_SEARCH_PATHS = ( ., ../include, ); - PRODUCT_NAME = translator_common; + PRODUCT_NAME = translator_glsl; + }; + name = Debug; + }; + 9DC66E1FF9349CDCC8D52C46 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; + SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; + }; + name = Debug; + }; + AF7C2CD10C6FEA076B141E6E /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = translator_glsl; + }; + name = Release; + }; + B096FAF032DB19AB637D38F0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = translator_hlsl; }; - name = Default; + name = Release; }; - BC5793C9A1FF021A81C66559 /* Default */ = { + C4546B14B0EB5EB8C5D39DC2 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)"; INTERMEDIATE_DIR = "$(PROJECT_DERIVED_FILE_DIR)/$(CONFIGURATION)"; - OBJROOT = ""; - ONLY_ACTIVE_ARCH = YES; SHARED_INTERMEDIATE_DIR = "$(SYMROOT)/DerivedSources/$(CONFIGURATION)"; - SYMROOT = "$(BUILD_DIR)"; }; - name = Default; + name = Release; + }; + F029E0D369FAFEA46BDAFCEE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); + HEADER_SEARCH_PATHS = ( + ., + ../include, + ); + PRODUCT_NAME = translator_hlsl; + }; + name = Debug; }; - FB3C505C11F7924A0081F5BA /* Default */ = { + FF01CDF4594E0FF9E581B319 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + "\"ANGLE_DISABLE_TRACE\"", + "\"ANGLE_COMPILE_OPTIMIZATION_LEVEL=D3DCOMPILE_OPTIMIZATION_LEVEL0\"", + ); HEADER_SEARCH_PATHS = ( ., ../include, ); - PRODUCT_NAME = angle; + PRODUCT_NAME = translator_common; }; - name = Default; + name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 0AA54825BF5DF0A3FBA92B60 /* Build configuration list for PBXAggregateTarget "ANGLE Support" */ = { + 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */ = { isa = XCConfigurationList; buildConfigurations = ( - 00BF2EBCBDF5678F4BA2FA92 /* Default */, + 9DC66E1FF9349CDCC8D52C46 /* Debug */, + C4546B14B0EB5EB8C5D39DC2 /* Release */, ); defaultConfigurationIsVisible = 1; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; - 0E59F8FE4A8099E8DDCA4CE7 /* Build configuration list for PBXProject "build_angle" */ = { + 34BB38E3A74418B2A063B49E /* Build configuration list for PBXNativeTarget "translator_common" */ = { isa = XCConfigurationList; buildConfigurations = ( - BC5793C9A1FF021A81C66559 /* Default */, + FF01CDF4594E0FF9E581B319 /* Debug */, + 4DA42A78D3B855C9CD8F658D /* Release */, ); defaultConfigurationIsVisible = 1; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; - 34BB38E3A74418B2A063B49E /* Build configuration list for PBXNativeTarget "translator_common" */ = { + 77CEFB7B40F05B0A804E6B2B /* Build configuration list for PBXAggregateTarget "All" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1F3F1218B5135FBB067DE809 /* Default */, + 322A8C62423B595E11BAD42D /* Debug */, + 4F851F5BA5FA43E9E0B9CB86 /* Release */, ); defaultConfigurationIsVisible = 1; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; - 77CEFB7B40F05B0A804E6B2B /* Build configuration list for PBXAggregateTarget "All" */ = { + 8B8815CA2EFE60FD0C0361BF /* Build configuration list for PBXNativeTarget "translator_glsl" */ = { isa = XCConfigurationList; buildConfigurations = ( - 1A12AA5D65ACDE71AE089EE3 /* Default */, + 88ADC9285519A668808B51EE /* Debug */, + AF7C2CD10C6FEA076B141E6E /* Release */, ); defaultConfigurationIsVisible = 1; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; - FB3C505B11F7924A0081F5BA /* Build configuration list for PBXNativeTarget "angle" */ = { + C71E79C7829FD796CF621B44 /* Build configuration list for PBXNativeTarget "translator_hlsl" */ = { isa = XCConfigurationList; buildConfigurations = ( - FB3C505C11F7924A0081F5BA /* Default */, + F029E0D369FAFEA46BDAFCEE /* Debug */, + B096FAF032DB19AB637D38F0 /* Release */, ); defaultConfigurationIsVisible = 1; - defaultConfigurationName = Default; + defaultConfigurationName = Debug; }; /* End XCConfigurationList section */ }; diff --git a/Source/ThirdParty/ANGLE/src/common/RefCountObject.cpp b/Source/ThirdParty/ANGLE/src/common/RefCountObject.cpp new file mode 100644 index 0000000..c1ef90c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/RefCountObject.cpp @@ -0,0 +1,47 @@ +// +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides +// lifecycle support for GL objects using the traditional BindObject scheme, but +// that need to be reference counted for correct cross-context deletion. +// (Concretely, textures, buffers and renderbuffers.) + +#include "RefCountObject.h" + +RefCountObject::RefCountObject(GLuint id) +{ + mId = id; + mRefCount = 0; +} + +RefCountObject::~RefCountObject() +{ + ASSERT(mRefCount == 0); +} + +void RefCountObject::addRef() const +{ + mRefCount++; +} + +void RefCountObject::release() const +{ + ASSERT(mRefCount > 0); + + if (--mRefCount == 0) + { + delete this; + } +} + +void RefCountObjectBindingPointer::set(RefCountObject *newObject) +{ + // addRef first in case newObject == mObject and this is the last reference to it. + if (newObject != NULL) newObject->addRef(); + if (mObject != NULL) mObject->release(); + + mObject = newObject; +} diff --git a/Source/ThirdParty/ANGLE/src/common/RefCountObject.h b/Source/ThirdParty/ANGLE/src/common/RefCountObject.h new file mode 100644 index 0000000..727c71c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/RefCountObject.h @@ -0,0 +1,65 @@ +// +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// RefCountObject.h: Defines the gl::RefCountObject base class that provides +// lifecycle support for GL objects using the traditional BindObject scheme, but +// that need to be reference counted for correct cross-context deletion. +// (Concretely, textures, buffers and renderbuffers.) + +#ifndef COMMON_REFCOUNTOBJECT_H_ +#define COMMON_REFCOUNTOBJECT_H_ + +#include <cstddef> + +#define GL_APICALL +#include <GLES2/gl2.h> + +#include "common/debug.h" + +class RefCountObject +{ + public: + explicit RefCountObject(GLuint id); + virtual ~RefCountObject(); + + virtual void addRef() const; + virtual void release() const; + + GLuint id() const { return mId; } + + private: + GLuint mId; + + mutable std::size_t mRefCount; +}; + +class RefCountObjectBindingPointer +{ + protected: + RefCountObjectBindingPointer() : mObject(NULL) { } + ~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up. + + void set(RefCountObject *newObject); + RefCountObject *get() const { return mObject; } + + public: + GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; } + bool operator ! () const { return (get() == NULL); } + + private: + RefCountObject *mObject; +}; + +template <class ObjectType> +class BindingPointer : public RefCountObjectBindingPointer +{ + public: + void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); } + ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); } + ObjectType *operator -> () const { return get(); } +}; + +#endif // COMMON_REFCOUNTOBJECT_H_ diff --git a/Source/ThirdParty/ANGLE/src/common/debug.cpp b/Source/ThirdParty/ANGLE/src/common/debug.cpp index 3de5d4e..845d258 100644 --- a/Source/ThirdParty/ANGLE/src/common/debug.cpp +++ b/Source/ThirdParty/ANGLE/src/common/debug.cpp @@ -1,44 +1,103 @@ -// -// 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. -// - -// debug.cpp: Debugging utilities. - -#include "common/debug.h" - -#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(TRACE_OUTPUT_FILE, "a"); - - if (file) - { - va_list vararg; - va_start(vararg, format); - vfprintf(file, format, vararg); - va_end(vararg); - - fclose(file); - } - } - } -#endif // !defined(ANGLE_DISABLE_TRACE) -} -} +//
+// 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.
+//
+
+// debug.cpp: Debugging utilities.
+
+#include "common/debug.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <d3d9.h>
+#include <windows.h>
+
+namespace gl
+{
+
+typedef void (WINAPI *PerfOutputFunction)(D3DCOLOR, LPCWSTR);
+
+static void output(bool traceFileDebugOnly, PerfOutputFunction perfFunc, const char *format, va_list vararg)
+{
+#if !defined(ANGLE_DISABLE_PERF)
+ if (perfActive())
+ {
+ char message[32768];
+ int len = vsprintf_s(message, format, vararg);
+ if (len < 0)
+ {
+ return;
+ }
+
+ // There are no ASCII variants of these D3DPERF functions.
+ wchar_t wideMessage[32768];
+ for (int i = 0; i < len; ++i)
+ {
+ wideMessage[i] = message[i];
+ }
+ wideMessage[len] = 0;
+
+ perfFunc(0, wideMessage);
+ }
+#endif
+
+#if !defined(ANGLE_DISABLE_TRACE)
+#if defined(NDEBUG)
+ if (traceFileDebugOnly)
+ {
+ return;
+ }
+#endif
+
+ FILE* file = fopen(TRACE_OUTPUT_FILE, "a");
+ if (file)
+ {
+ vfprintf(file, format, vararg);
+ fclose(file);
+ }
+#endif
+}
+
+void trace(bool traceFileDebugOnly, const char *format, ...)
+{
+ va_list vararg;
+ va_start(vararg, format);
+#if defined(ANGLE_DISABLE_PERF)
+ output(traceFileDebugOnly, NULL, format, vararg);
+#else
+ output(traceFileDebugOnly, D3DPERF_SetMarker, format, vararg);
+#endif
+ va_end(vararg);
+}
+
+bool perfActive()
+{
+#if defined(ANGLE_DISABLE_PERF)
+ return false;
+#else
+ static bool active = D3DPERF_GetStatus() != 0;
+ return active;
+#endif
+}
+
+ScopedPerfEventHelper::ScopedPerfEventHelper(const char* format, ...)
+{
+#if !defined(ANGLE_DISABLE_PERF)
+ va_list vararg;
+ va_start(vararg, format);
+ output(true, reinterpret_cast<PerfOutputFunction>(D3DPERF_BeginEvent), format, vararg);
+ va_end(vararg);
+#endif
+}
+
+ScopedPerfEventHelper::~ScopedPerfEventHelper()
+{
+#if !defined(ANGLE_DISABLE_PERF)
+ if (perfActive())
+ {
+ D3DPERF_EndEvent();
+ }
+#endif
+}
+}
diff --git a/Source/ThirdParty/ANGLE/src/common/debug.h b/Source/ThirdParty/ANGLE/src/common/debug.h index 2c4ec70..9828ecf 100644 --- a/Source/ThirdParty/ANGLE/src/common/debug.h +++ b/Source/ThirdParty/ANGLE/src/common/debug.h @@ -12,49 +12,87 @@ #include <stdio.h> #include <assert.h> +#include "common/angleutils.h" + +#if !defined(TRACE_OUTPUT_FILE) +#define TRACE_OUTPUT_FILE "debug.txt" +#endif + namespace gl { // Outputs text to the debugging log - void trace(const char *format, ...); + void trace(bool traceFileDebugOnly, const char *format, ...); + + // Returns whether D3DPERF is active. + bool perfActive(); + + // Pairs a D3D begin event with an end event. + class ScopedPerfEventHelper + { + public: + ScopedPerfEventHelper(const char* format, ...); + ~ScopedPerfEventHelper(); + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedPerfEventHelper); + }; } // A macro to output a trace of a function call and its arguments to the debugging log -#if !defined(NDEBUG) && !defined(ANGLE_DISABLE_TRACE) - #define TRACE(message, ...) gl::trace("trace: %s"message"\n", __FUNCTION__, __VA_ARGS__) +#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF) +#define TRACE(message, ...) (void(0)) +#else +#define TRACE(message, ...) gl::trace(true, "trace: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__) +#endif + +// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. +#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF) +#define FIXME(message, ...) (void(0)) #else - #define TRACE(...) ((void)0) +#define FIXME(message, ...) gl::trace(false, "fixme: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__) #endif -// A macro to output a function call and its arguments to the debugging log, to denote an item in need of fixing. Will occur even in release mode. -#define FIXME(message, ...) gl::trace("fixme: %s"message"\n", __FUNCTION__, __VA_ARGS__) +// A macro to output a function call and its arguments to the debugging log, in case of error. +#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF) +#define ERR(message, ...) (void(0)) +#else +#define ERR(message, ...) gl::trace(false, "err: %s(%d): "message"\n", __FUNCTION__, __LINE__, __VA_ARGS__) +#endif -// A macro to output a function call and its arguments to the debugging log, in case of error. Will occur even in release mode. -#define ERR(message, ...) gl::trace("err: %s"message"\n", __FUNCTION__, __VA_ARGS__) +// A macro to log a performance event around a scope. +#if defined(ANGLE_DISABLE_TRACE) && defined(ANGLE_DISABLE_PERF) +#define EVENT(message, ...) (void(0)) +#else +#define EVENT(message, ...) gl::ScopedPerfEventHelper scopedPerfEventHelper ## __LINE__(__FUNCTION__ message "\n", __VA_ARGS__); +#endif // A macro asserting a condition and outputting failures to the debug log +#if !defined(NDEBUG) #define ASSERT(expression) do { \ if(!(expression)) \ ERR("\t! Assert failed in %s(%d): "#expression"\n", __FUNCTION__, __LINE__); \ - assert(expression); \ + assert(expression); \ } while(0) - +#else +#define ASSERT(expression) (void(0)) +#endif // A macro to indicate unimplemented functionality -#ifndef NDEBUG - #define UNIMPLEMENTED() do { \ - FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ - } while(0) +#if !defined(NDEBUG) +#define UNIMPLEMENTED() do { \ + FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__); \ + assert(false); \ + } while(0) #else #define UNIMPLEMENTED() FIXME("\t! Unimplemented: %s(%d)\n", __FUNCTION__, __LINE__) #endif // A macro for code which is not expected to be reached under valid assumptions -#ifndef NDEBUG - #define UNREACHABLE() do { \ - ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ - assert(false); \ - } while(0) +#if !defined(NDEBUG) +#define UNREACHABLE() do { \ + ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__); \ + assert(false); \ + } while(0) #else #define UNREACHABLE() ERR("\t! Unreachable reached: %s(%d)\n", __FUNCTION__, __LINE__) #endif diff --git a/Source/ThirdParty/ANGLE/src/common/version.h b/Source/ThirdParty/ANGLE/src/common/version.h new file mode 100644 index 0000000..203c421 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/common/version.h @@ -0,0 +1,10 @@ +#define MAJOR_VERSION 1 +#define MINOR_VERSION 0 +#define BUILD_VERSION 0 +#define BUILD_REVISION 1009 + +#define STRINGIFY(x) #x +#define MACRO_STRINGIFY(x) STRINGIFY(x) + +#define REVISION_STRING MACRO_STRINGIFY(BUILD_REVISION) +#define VERSION_STRING MACRO_STRINGIFY(MAJOR_VERSION) "." MACRO_STRINGIFY(MINOR_VERSION) "." MACRO_STRINGIFY(BUILD_VERSION) "." MACRO_STRINGIFY(BUILD_REVISION) diff --git a/Source/ThirdParty/ANGLE/src/compiler/BaseTypes.h b/Source/ThirdParty/ANGLE/src/compiler/BaseTypes.h index 9f4a860..5f83185 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/BaseTypes.h +++ b/Source/ThirdParty/ANGLE/src/compiler/BaseTypes.h @@ -42,9 +42,12 @@ enum TBasicType EbtGuardSamplerBegin, // non type: see implementation of IsSampler() EbtSampler2D, EbtSamplerCube, + EbtSamplerExternalOES, // Only valid if OES_EGL_image_external exists. + EbtSampler2DRect, // Only valid if GL_ARB_texture_rectangle exists. EbtGuardSamplerEnd, // non type: see implementation of IsSampler() EbtStruct, EbtAddress, // should be deprecated?? + EbtInvariant, // used as a type when qualifying a previously declared variable as being invariant }; inline const char* getBasicString(TBasicType t) @@ -57,6 +60,8 @@ inline const char* getBasicString(TBasicType t) case EbtBool: return "bool"; break; case EbtSampler2D: return "sampler2D"; break; case EbtSamplerCube: return "samplerCube"; break; + case EbtSamplerExternalOES: return "samplerExternalOES"; break; + case EbtSampler2DRect: return "sampler2DRect"; break; case EbtStruct: return "structure"; break; default: return "unknown type"; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp new file mode 100644 index 0000000..3cd3927 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.cpp @@ -0,0 +1,437 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/BuiltInFunctionEmulator.h" + +#include "compiler/SymbolTable.h" + +namespace { + +// we use macros here instead of function definitions to work around more GLSL +// compiler bugs, in particular on NVIDIA hardware on Mac OSX. Macros are +// problematic because if the argument has side-effects they will be repeatedly +// evaluated. This is unlikely to show up in real shaders, but is something to +// consider. +const char* kFunctionEmulationVertexSource[] = { + "#error no emulation for atan(float, float)", + "vec2 webgl_atan_emu(vec2 y, vec2 x) { return vec2(atan(y[0], x[0]), atan(y[1], x[1])); }", + "vec3 webgl_atan_emu(vec3 y, vec3 x) { return vec3(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2])); }", + "vec4 webgl_atan_emu(vec4 y, vec4 x) { return vec4(atan(y[0], x[0]), atan(y[1], x[1]), atan(y[2], x[2]), atan(y[3], x[3])); }", + + "#error no emulation for cos(float)", + "#error no emulation for cos(vec2)", + "#error no emulation for cos(vec3)", + "#error no emulation for cos(vec4)", + + "#define webgl_distance_emu(x, y) ((x) >= (y) ? (x) - (y) : (y) - (x))", + "#error no emulation for distance(vec2, vec2)", + "#error no emulation for distance(vec3, vec3)", + "#error no emulation for distance(vec4, vec4)", + + "#define webgl_dot_emu(x, y) ((x) * (y))", + "#error no emulation for dot(vec2, vec2)", + "#error no emulation for dot(vec3, vec3)", + "#error no emulation for dot(vec4, vec4)", + + "#define webgl_length_emu(x) ((x) >= 0.0 ? (x) : -(x))", + "#error no emulation for length(vec2)", + "#error no emulation for length(vec3)", + "#error no emulation for length(vec4)", + + "#error no emulation for mod(float, float)", + "vec2 webgl_mod_emu(vec2 x, vec2 y) { return vec2(mod(x[0], y[0]), mod(x[1], y[1])); }", + "vec3 webgl_mod_emu(vec3 x, vec3 y) { return vec3(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2])); }", + "vec4 webgl_mod_emu(vec4 x, vec4 y) { return vec4(mod(x[0], y[0]), mod(x[1], y[1]), mod(x[2], y[2]), mod(x[3], y[3])); }", + + "#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) > 0.0 ? 1.0 : -1.0))", + "#error no emulation for normalize(vec2)", + "#error no emulation for normalize(vec3)", + "#error no emulation for normalize(vec4)", + + "#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))", + "#error no emulation for reflect(vec2, vec2)", + "#error no emulation for reflect(vec3, vec3)", + "#error no emulation for reflect(vec4, vec4)" +}; + +const char* kFunctionEmulationFragmentSource[] = { + "#error no emulation for atan(float, float)", + "#error no emulation for atan(vec2, vec2)", + "#error no emulation for atan(vec3, vec3)", + "#error no emulation for atan(vec4, vec4)", + + "webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }", + "webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }", + "webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }", + "webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }", + + "#error no emulation for distance(float, float)", + "#error no emulation for distance(vec2, vec2)", + "#error no emulation for distance(vec3, vec3)", + "#error no emulation for distance(vec4, vec4)", + + "#error no emulation for dot(float, float)", + "#error no emulation for dot(vec2, vec2)", + "#error no emulation for dot(vec3, vec3)", + "#error no emulation for dot(vec4, vec4)", + + "#error no emulation for length(float)", + "#error no emulation for length(vec2)", + "#error no emulation for length(vec3)", + "#error no emulation for length(vec4)", + + "#error no emulation for mod(float, float)", + "#error no emulation for mod(vec2, vec2)", + "#error no emulation for mod(vec3, vec3)", + "#error no emulation for mod(vec4, vec4)", + + "#error no emulation for normalize(float)", + "#error no emulation for normalize(vec2)", + "#error no emulation for normalize(vec3)", + "#error no emulation for normalize(vec4)", + + "#error no emulation for reflect(float, float)", + "#error no emulation for reflect(vec2, vec2)", + "#error no emulation for reflect(vec3, vec3)", + "#error no emulation for reflect(vec4, vec4)" +}; + +const bool kFunctionEmulationVertexMask[] = { +#if defined(__APPLE__) + // Work around ATI driver bugs in Mac. + false, // TFunctionAtan1_1 + false, // TFunctionAtan2_2 + false, // TFunctionAtan3_3 + false, // TFunctionAtan4_4 + false, // TFunctionCos1 + false, // TFunctionCos2 + false, // TFunctionCos3 + false, // TFunctionCos4 + true, // TFunctionDistance1_1 + false, // TFunctionDistance2_2 + false, // TFunctionDistance3_3 + false, // TFunctionDistance4_4 + true, // TFunctionDot1_1 + false, // TFunctionDot2_2 + false, // TFunctionDot3_3 + false, // TFunctionDot4_4 + true, // TFunctionLength1 + false, // TFunctionLength2 + false, // TFunctionLength3 + false, // TFunctionLength4 + false, // TFunctionMod1_1 + false, // TFunctionMod2_2 + false, // TFunctionMod3_3 + false, // TFunctionMod4_4 + true, // TFunctionNormalize1 + false, // TFunctionNormalize2 + false, // TFunctionNormalize3 + false, // TFunctionNormalize4 + true, // TFunctionReflect1_1 + false, // TFunctionReflect2_2 + false, // TFunctionReflect3_3 + false, // TFunctionReflect4_4 +#else + // Work around D3D driver bug in Win. + false, // TFunctionAtan1_1 + true, // TFunctionAtan2_2 + true, // TFunctionAtan3_3 + true, // TFunctionAtan4_4 + false, // TFunctionCos1 + false, // TFunctionCos2 + false, // TFunctionCos3 + false, // TFunctionCos4 + false, // TFunctionDistance1_1 + false, // TFunctionDistance2_2 + false, // TFunctionDistance3_3 + false, // TFunctionDistance4_4 + false, // TFunctionDot1_1 + false, // TFunctionDot2_2 + false, // TFunctionDot3_3 + false, // TFunctionDot4_4 + false, // TFunctionLength1 + false, // TFunctionLength2 + false, // TFunctionLength3 + false, // TFunctionLength4 + false, // TFunctionMod1_1 + true, // TFunctionMod2_2 + true, // TFunctionMod3_3 + true, // TFunctionMod4_4 + false, // TFunctionNormalize1 + false, // TFunctionNormalize2 + false, // TFunctionNormalize3 + false, // TFunctionNormalize4 + false, // TFunctionReflect1_1 + false, // TFunctionReflect2_2 + false, // TFunctionReflect3_3 + false, // TFunctionReflect4_4 +#endif + false // TFunctionUnknown +}; + +const bool kFunctionEmulationFragmentMask[] = { + false, // TFunctionAtan1_1 + false, // TFunctionAtan2_2 + false, // TFunctionAtan3_3 + false, // TFunctionAtan4_4 +#if defined(__APPLE__) + // Work around a ATI driver bug in Mac that causes crashes. + true, // TFunctionCos1 + true, // TFunctionCos2 + true, // TFunctionCos3 + true, // TFunctionCos4 +#else + false, // TFunctionCos1 + false, // TFunctionCos2 + false, // TFunctionCos3 + false, // TFunctionCos4 +#endif + false, // TFunctionDistance1_1 + false, // TFunctionDistance2_2 + false, // TFunctionDistance3_3 + false, // TFunctionDistance4_4 + false, // TFunctionDot1_1 + false, // TFunctionDot2_2 + false, // TFunctionDot3_3 + false, // TFunctionDot4_4 + false, // TFunctionLength1 + false, // TFunctionLength2 + false, // TFunctionLength3 + false, // TFunctionLength4 + false, // TFunctionMod1_1 + false, // TFunctionMod2_2 + false, // TFunctionMod3_3 + false, // TFunctionMod4_4 + false, // TFunctionNormalize1 + false, // TFunctionNormalize2 + false, // TFunctionNormalize3 + false, // TFunctionNormalize4 + false, // TFunctionReflect1_1 + false, // TFunctionReflect2_2 + false, // TFunctionReflect3_3 + false, // TFunctionReflect4_4 + false // TFunctionUnknown +}; + +class BuiltInFunctionEmulationMarker : public TIntermTraverser { +public: + BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator& emulator) + : mEmulator(emulator) + { + } + + virtual ~BuiltInFunctionEmulationMarker() {} + + virtual bool visitUnary(Visit visit, TIntermUnary* node) + { + if (visit == PreVisit) { + bool needToEmulate = mEmulator.SetFunctionCalled( + node->getOp(), node->getOperand()->getType()); + if (needToEmulate) + node->setUseEmulatedFunction(); + } + return true; + } + + virtual bool visitAggregate(Visit visit, TIntermAggregate* node) + { + if (visit == PreVisit) { + // Here we handle all the built-in functions instead of the ones we + // currently identified as problematic. + switch (node->getOp()) { + case EOpLessThan: + case EOpGreaterThan: + case EOpLessThanEqual: + case EOpGreaterThanEqual: + case EOpVectorEqual: + case EOpVectorNotEqual: + case EOpMod: + case EOpPow: + case EOpAtan: + case EOpMin: + case EOpMax: + case EOpClamp: + case EOpMix: + case EOpStep: + case EOpSmoothStep: + case EOpDistance: + case EOpDot: + case EOpCross: + case EOpFaceForward: + case EOpReflect: + case EOpRefract: + case EOpMul: + break; + default: + return true; + }; + const TIntermSequence& sequence = node->getSequence(); + // Right now we only handle built-in functions with two parameters. + if (sequence.size() != 2) + return true; + TIntermTyped* param1 = sequence[0]->getAsTyped(); + TIntermTyped* param2 = sequence[1]->getAsTyped(); + if (!param1 || !param2) + return true; + bool needToEmulate = mEmulator.SetFunctionCalled( + node->getOp(), param1->getType(), param2->getType()); + if (needToEmulate) + node->setUseEmulatedFunction(); + } + return true; + } + +private: + BuiltInFunctionEmulator& mEmulator; +}; + +} // anonymous namepsace + +BuiltInFunctionEmulator::BuiltInFunctionEmulator(ShShaderType shaderType) +{ + if (shaderType == SH_FRAGMENT_SHADER) { + mFunctionMask = kFunctionEmulationFragmentMask; + mFunctionSource = kFunctionEmulationFragmentSource; + } else { + mFunctionMask = kFunctionEmulationVertexMask; + mFunctionSource = kFunctionEmulationVertexSource; + } +} + +bool BuiltInFunctionEmulator::SetFunctionCalled( + TOperator op, const TType& param) +{ + TBuiltInFunction function = IdentifyFunction(op, param); + return SetFunctionCalled(function); +} + +bool BuiltInFunctionEmulator::SetFunctionCalled( + TOperator op, const TType& param1, const TType& param2) +{ + TBuiltInFunction function = IdentifyFunction(op, param1, param2); + return SetFunctionCalled(function); +} + +bool BuiltInFunctionEmulator::SetFunctionCalled( + BuiltInFunctionEmulator::TBuiltInFunction function) { + if (function == TFunctionUnknown || mFunctionMask[function] == false) + return false; + for (size_t i = 0; i < mFunctions.size(); ++i) { + if (mFunctions[i] == function) + return true; + } + mFunctions.push_back(function); + return true; +} + +void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition( + TInfoSinkBase& out, bool withPrecision) const +{ + if (mFunctions.size() == 0) + return; + out << "// BEGIN: Generated code for built-in function emulation\n\n"; + if (withPrecision) { + out << "#if defined(GL_FRAGMENT_PRECISION_HIGH)\n" + << "#define webgl_emu_precision highp\n" + << "#else\n" + << "#define webgl_emu_precision mediump\n" + << "#endif\n\n"; + } else { + out << "#define webgl_emu_precision\n\n"; + } + for (size_t i = 0; i < mFunctions.size(); ++i) { + out << mFunctionSource[mFunctions[i]] << "\n\n"; + } + out << "// END: Generated code for built-in function emulation\n\n"; +} + +BuiltInFunctionEmulator::TBuiltInFunction +BuiltInFunctionEmulator::IdentifyFunction( + TOperator op, const TType& param) +{ + if (param.getNominalSize() > 4) + return TFunctionUnknown; + unsigned int function = TFunctionUnknown; + switch (op) { + case EOpCos: + function = TFunctionCos1; + break; + case EOpLength: + function = TFunctionLength1; + break; + case EOpNormalize: + function = TFunctionNormalize1; + break; + default: + break; + } + if (function == TFunctionUnknown) + return TFunctionUnknown; + if (param.isVector()) + function += param.getNominalSize() - 1; + return static_cast<TBuiltInFunction>(function); +} + +BuiltInFunctionEmulator::TBuiltInFunction +BuiltInFunctionEmulator::IdentifyFunction( + TOperator op, const TType& param1, const TType& param2) +{ + // Right now for all the emulated functions with two parameters, the two + // parameters have the same type. + if (param1.isVector() != param2.isVector() || + param1.getNominalSize() != param2.getNominalSize() || + param1.getNominalSize() > 4) + return TFunctionUnknown; + + unsigned int function = TFunctionUnknown; + switch (op) { + case EOpAtan: + function = TFunctionAtan1_1; + break; + case EOpDistance: + function = TFunctionDistance1_1; + break; + case EOpDot: + function = TFunctionDot1_1; + break; + case EOpMod: + function = TFunctionMod1_1; + break; + case EOpReflect: + function = TFunctionReflect1_1; + break; + default: + break; + } + if (function == TFunctionUnknown) + return TFunctionUnknown; + if (param1.isVector()) + function += param1.getNominalSize() - 1; + return static_cast<TBuiltInFunction>(function); +} + +void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation( + TIntermNode* root) +{ + ASSERT(root); + + BuiltInFunctionEmulationMarker marker(*this); + root->traverse(&marker); +} + +void BuiltInFunctionEmulator::Cleanup() +{ + mFunctions.clear(); +} + +//static +TString BuiltInFunctionEmulator::GetEmulatedFunctionName( + const TString& name) +{ + ASSERT(name[name.length() - 1] == '('); + return "webgl_" + name.substr(0, name.length() - 1) + "_emu("; +} + diff --git a/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h new file mode 100644 index 0000000..b37b665 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/BuiltInFunctionEmulator.h @@ -0,0 +1,103 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_ +#define COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_ + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/InfoSink.h" +#include "compiler/intermediate.h" + +// +// This class decides which built-in functions need to be replaced with the +// emulated ones. +// It's only a workaround for OpenGL driver bugs, and isn't needed in general. +// +class BuiltInFunctionEmulator { +public: + BuiltInFunctionEmulator(ShShaderType shaderType); + // Records that a function is called by the shader and might needs to be + // emulated. If the function's group is not in mFunctionGroupFilter, this + // becomes an no-op. + // Returns true if the function call needs to be replaced with an emulated + // one. + bool SetFunctionCalled(TOperator op, const TType& param); + bool SetFunctionCalled( + TOperator op, const TType& param1, const TType& param2); + + // Output function emulation definition. This should be before any other + // shader source. + void OutputEmulatedFunctionDefinition(TInfoSinkBase& out, bool withPrecision) const; + + void MarkBuiltInFunctionsForEmulation(TIntermNode* root); + + void Cleanup(); + + // "name(" becomes "webgl_name_emu(". + static TString GetEmulatedFunctionName(const TString& name); + +private: + // + // Built-in functions. + // + enum TBuiltInFunction { + TFunctionAtan1_1 = 0, // float atan(float, float); + TFunctionAtan2_2, // vec2 atan(vec2, vec2); + TFunctionAtan3_3, // vec3 atan(vec3, vec2); + TFunctionAtan4_4, // vec4 atan(vec4, vec2); + + TFunctionCos1, // float cos(float); + TFunctionCos2, // vec2 cos(vec2); + TFunctionCos3, // vec3 cos(vec3); + TFunctionCos4, // vec4 cos(vec4); + + TFunctionDistance1_1, // float distance(float, float); + TFunctionDistance2_2, // vec2 distance(vec2, vec2); + TFunctionDistance3_3, // vec3 distance(vec3, vec3); + TFunctionDistance4_4, // vec4 distance(vec4, vec4); + + TFunctionDot1_1, // float dot(float, float); + TFunctionDot2_2, // vec2 dot(vec2, vec2); + TFunctionDot3_3, // vec3 dot(vec3, vec3); + TFunctionDot4_4, // vec4 dot(vec4, vec4); + + TFunctionLength1, // float length(float); + TFunctionLength2, // float length(vec2); + TFunctionLength3, // float length(vec3); + TFunctionLength4, // float length(vec4); + + TFunctionMod1_1, // float mod(float, float); + TFunctionMod2_2, // vec2 mod(vec2, vec2); + TFunctionMod3_3, // vec3 mod(vec3, vec3); + TFunctionMod4_4, // vec4 mod(vec4, vec4); + + TFunctionNormalize1, // float normalize(float); + TFunctionNormalize2, // vec2 normalize(vec2); + TFunctionNormalize3, // vec3 normalize(vec3); + TFunctionNormalize4, // vec4 normalize(vec4); + + TFunctionReflect1_1, // float reflect(float, float); + TFunctionReflect2_2, // vec2 reflect(vec2, vec2); + TFunctionReflect3_3, // vec3 reflect(vec3, vec3); + TFunctionReflect4_4, // vec4 reflect(vec4, vec4); + + TFunctionUnknown + }; + + TBuiltInFunction IdentifyFunction(TOperator op, const TType& param); + TBuiltInFunction IdentifyFunction( + TOperator op, const TType& param1, const TType& param2); + + bool SetFunctionCalled(TBuiltInFunction function); + + std::vector<TBuiltInFunction> mFunctions; + + const bool* mFunctionMask; // a boolean flag for each function. + const char** mFunctionSource; +}; + +#endif // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp index d140b37..226bf8f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenGLSL.cpp @@ -5,15 +5,24 @@ // #include "compiler/TranslatorGLSL.h" +#include "compiler/TranslatorESSL.h" // // This function must be provided to create the actual // compile object used by higher level code. It returns // a subclass of TCompiler. // -TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec) +TCompiler* ConstructCompiler( + ShShaderType type, ShShaderSpec spec, ShShaderOutput output) { - return new TranslatorGLSL(type, spec); + switch (output) { + case SH_GLSL_OUTPUT: + return new TranslatorGLSL(type, spec); + case SH_ESSL_OUTPUT: + return new TranslatorESSL(type, spec); + default: + return NULL; + } } // diff --git a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp index e04e789..f46ff66 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/CodeGenHLSL.cpp @@ -11,9 +11,15 @@ // compile object used by higher level code. It returns // a subclass of TCompiler. // -TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec) +TCompiler* ConstructCompiler( + ShShaderType type, ShShaderSpec spec, ShShaderOutput output) { - return new TranslatorHLSL(type, spec); + switch (output) { + case SH_HLSL_OUTPUT: + return new TranslatorHLSL(type, spec); + default: + return NULL; + } } // diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp index 649b457..f27cb75 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp @@ -1,10 +1,14 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +#include "compiler/BuiltInFunctionEmulator.h" +#include "compiler/DetectRecursion.h" +#include "compiler/ForLoopUnroll.h" #include "compiler/Initialize.h" +#include "compiler/MapLongVariableNames.h" #include "compiler/ParseHelper.h" #include "compiler/ShHandle.h" #include "compiler/ValidateLimitations.h" @@ -17,7 +21,10 @@ bool InitializeSymbolTable( { TIntermediate intermediate(infoSink); TExtensionBehavior extBehavior; - TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink); + InitExtensionBehavior(resources, extBehavior); + // The builtins deliberately don't specify precisions for the function + // arguments and return types. For that reason we don't try to check them. + TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink); GlobalParseContext = &parseContext; @@ -81,12 +88,16 @@ TShHandleBase::~TShHandleBase() { TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec) : shaderType(type), - shaderSpec(spec) + shaderSpec(spec), + builtInFunctionEmulator(type) { + longNameMap = LongNameMap::GetInstance(); } TCompiler::~TCompiler() { + ASSERT(longNameMap); + longNameMap->Release(); } bool TCompiler::Init(const ShBuiltInResources& resources) @@ -115,9 +126,19 @@ bool TCompiler::compile(const char* const shaderStrings[], if (shaderSpec == SH_WEBGL_SPEC) compileOptions |= SH_VALIDATE_LOOP_INDEXING; + // First string is path of source file if flag is set. The actual source follows. + const char* sourcePath = NULL; + int firstSource = 0; + if (compileOptions & SH_SOURCE_PATH) + { + sourcePath = shaderStrings[0]; + ++firstSource; + } + TIntermediate intermediate(infoSink); TParseContext parseContext(symbolTable, extensionBehavior, intermediate, - shaderType, shaderSpec, infoSink); + shaderType, shaderSpec, compileOptions, true, + sourcePath, infoSink); GlobalParseContext = &parseContext; // We preserve symbols at the built-in level from compile-to-compile. @@ -128,23 +149,40 @@ bool TCompiler::compile(const char* const shaderStrings[], // Parse shader. bool success = - (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) && + (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) && (parseContext.treeRoot != NULL); if (success) { TIntermNode* root = parseContext.treeRoot; success = intermediate.postProcess(root); + if (success) + success = detectRecursion(root); + if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); + // Unroll for-loop markup needs to happen after validateLimitations pass. + if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX)) + ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root); + + // Built-in function emulation needs to happen after validateLimitations pass. + if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS)) + builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root); + + // Call mapLongVariableNames() before collectAttribsUniforms() so in + // collectAttribsUniforms() we already have the mapped symbol names and + // we could composite mapped and original variable names. + if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES)) + mapLongVariableNames(root); + + if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) + collectAttribsUniforms(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. @@ -174,6 +212,27 @@ void TCompiler::clearResults() attribs.clear(); uniforms.clear(); + + builtInFunctionEmulator.Cleanup(); +} + +bool TCompiler::detectRecursion(TIntermNode* root) +{ + DetectRecursion detect; + root->traverse(&detect); + switch (detect.detectRecursion()) { + case DetectRecursion::kErrorNone: + return true; + case DetectRecursion::kErrorMissingMain: + infoSink.info.message(EPrefixError, "Missing main()"); + return false; + case DetectRecursion::kErrorRecursion: + infoSink.info.message(EPrefixError, "Function recursion detected"); + return false; + default: + UNREACHABLE(); + return false; + } } bool TCompiler::validateLimitations(TIntermNode* root) { @@ -187,3 +246,25 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root) CollectAttribsUniforms collect(attribs, uniforms); root->traverse(&collect); } + +void TCompiler::mapLongVariableNames(TIntermNode* root) +{ + ASSERT(longNameMap); + MapLongVariableNames map(longNameMap); + root->traverse(&map); +} + +int TCompiler::getMappedNameMaxLength() const +{ + return MAX_SHORTENED_IDENTIFIER_SIZE + 1; +} + +const TExtensionBehavior& TCompiler::getExtensionBehavior() const +{ + return extensionBehavior; +} + +const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const +{ + return builtInFunctionEmulator; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/ConstantUnion.h b/Source/ThirdParty/ANGLE/src/compiler/ConstantUnion.h index cf531ea..fd9d94d 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ConstantUnion.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ConstantUnion.h @@ -11,6 +11,10 @@ class ConstantUnion { public: + ConstantUnion() + { + iConst = 0; + } POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) void setIConst(int i) {iConst = i; type = EbtInt; } @@ -26,26 +30,17 @@ public: bool operator==(const int i) const { - if (i == iConst) - return true; - - return false; + return i == iConst; } bool operator==(const float f) const { - if (f == fConst) - return true; - - return false; + return f == fConst; } bool operator==(const bool b) const { - if (b == bConst) - return true; - - return false; + return b == bConst; } bool operator==(const ConstantUnion& constant) const @@ -55,23 +50,14 @@ public: switch (type) { case EbtInt: - if (constant.iConst == iConst) - return true; - - break; + return constant.iConst == iConst; case EbtFloat: - if (constant.fConst == fConst) - return true; - - break; + return constant.fConst == fConst; case EbtBool: - if (constant.bConst == bConst) - return true; - - break; + return constant.bConst == bConst; + default: + return false; } - - return false; } bool operator!=(const int i) const @@ -99,21 +85,12 @@ public: assert(type == constant.type); switch (type) { case EbtInt: - if (iConst > constant.iConst) - return true; - - return false; + return iConst > constant.iConst; case EbtFloat: - if (fConst > constant.fConst) - return true; - - return false; + return fConst > constant.fConst; default: - assert(false && "Default missing"); - return false; + return false; // Invalid operation, handled at semantic analysis } - - return false; } bool operator<(const ConstantUnion& constant) const @@ -121,21 +98,12 @@ public: assert(type == constant.type); switch (type) { case EbtInt: - if (iConst < constant.iConst) - return true; - - return false; + return iConst < constant.iConst; case EbtFloat: - if (fConst < constant.fConst) - return true; - - return false; + return fConst < constant.fConst; default: - assert(false && "Default missing"); - return false; + return false; // Invalid operation, handled at semantic analysis } - - return false; } ConstantUnion operator+(const ConstantUnion& constant) const diff --git a/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.cpp b/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.cpp new file mode 100644 index 0000000..c09780d --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.cpp @@ -0,0 +1,125 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/DetectRecursion.h" + +DetectRecursion::FunctionNode::FunctionNode(const TString& fname) + : name(fname), + visit(PreVisit) +{ +} + +const TString& DetectRecursion::FunctionNode::getName() const +{ + return name; +} + +void DetectRecursion::FunctionNode::addCallee( + DetectRecursion::FunctionNode* callee) +{ + for (size_t i = 0; i < callees.size(); ++i) { + if (callees[i] == callee) + return; + } + callees.push_back(callee); +} + +bool DetectRecursion::FunctionNode::detectRecursion() +{ + ASSERT(visit == PreVisit); + visit = InVisit; + for (size_t i = 0; i < callees.size(); ++i) { + switch (callees[i]->visit) { + case InVisit: + // cycle detected, i.e., recursion detected. + return true; + case PostVisit: + break; + case PreVisit: { + bool recursion = callees[i]->detectRecursion(); + if (recursion) + return true; + break; + } + default: + UNREACHABLE(); + break; + } + } + visit = PostVisit; + return false; +} + +DetectRecursion::DetectRecursion() + : currentFunction(NULL) +{ +} + +DetectRecursion::~DetectRecursion() +{ + for (size_t i = 0; i < functions.size(); ++i) + delete functions[i]; +} + +bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node) +{ + switch (node->getOp()) + { + case EOpPrototype: + // Function declaration. + // Don't add FunctionNode here because node->getName() is the + // unmangled function name. + break; + case EOpFunction: { + // Function definition. + if (visit == PreVisit) { + currentFunction = findFunctionByName(node->getName()); + if (currentFunction == NULL) { + currentFunction = new FunctionNode(node->getName()); + functions.push_back(currentFunction); + } + } + break; + } + case EOpFunctionCall: { + // Function call. + if (visit == PreVisit) { + ASSERT(currentFunction != NULL); + FunctionNode* func = findFunctionByName(node->getName()); + if (func == NULL) { + func = new FunctionNode(node->getName()); + functions.push_back(func); + } + currentFunction->addCallee(func); + } + break; + } + default: + break; + } + return true; +} + +DetectRecursion::ErrorCode DetectRecursion::detectRecursion() +{ + FunctionNode* main = findFunctionByName("main("); + if (main == NULL) + return kErrorMissingMain; + if (main->detectRecursion()) + return kErrorRecursion; + return kErrorNone; +} + +DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName( + const TString& name) +{ + for (size_t i = 0; i < functions.size(); ++i) { + if (functions[i]->getName() == name) + return functions[i]; + } + return NULL; +} + diff --git a/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.h b/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.h new file mode 100644 index 0000000..cfb55cf --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/DetectRecursion.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_DETECT_RECURSION_H_ +#define COMPILER_DETECT_RECURSION_H_ + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/intermediate.h" +#include "compiler/VariableInfo.h" + +// Traverses intermediate tree to detect function recursion. +class DetectRecursion : public TIntermTraverser { +public: + enum ErrorCode { + kErrorMissingMain, + kErrorRecursion, + kErrorNone + }; + + DetectRecursion(); + virtual ~DetectRecursion(); + + virtual bool visitAggregate(Visit, TIntermAggregate*); + + ErrorCode detectRecursion(); + +private: + class FunctionNode { + public: + FunctionNode(const TString& fname); + + const TString& getName() const; + + // If a function is already in the callee list, this becomes a no-op. + void addCallee(FunctionNode* callee); + + // Return true if recursive function calls are detected. + bool detectRecursion(); + + private: + // mangled function name is unique. + TString name; + + // functions that are directly called by this function. + TVector<FunctionNode*> callees; + + Visit visit; + }; + + FunctionNode* findFunctionByName(const TString& name); + + TVector<FunctionNode*> functions; + FunctionNode* currentFunction; +}; + +#endif // COMPILER_DETECT_RECURSION_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h index da96c24..e9bba4b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ExtensionBehavior.h @@ -13,9 +13,26 @@ typedef enum { EBhRequire, EBhEnable, EBhWarn, - EBhDisable + EBhDisable, + EBhUndefined, } TBehavior; +inline const char* getBehaviorString(TBehavior b) +{ + switch(b) { + case EBhRequire: + return "require"; + case EBhEnable: + return "enable"; + case EBhWarn: + return "warn"; + case EBhDisable: + return "disable"; + default: + return NULL; + } +} + typedef TMap<TString, TBehavior> TExtensionBehavior; #endif // _EXTENSION_TABLE_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.cpp b/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.cpp new file mode 100644 index 0000000..fdc3f44 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.cpp @@ -0,0 +1,215 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/ForLoopUnroll.h" + +namespace { + +class IntegerForLoopUnrollMarker : public TIntermTraverser { +public: + + virtual bool visitLoop(Visit, TIntermLoop* node) + { + // This is called after ValidateLimitations pass, so all the ASSERT + // should never fail. + // See ValidateLimitations::validateForLoopInit(). + ASSERT(node); + ASSERT(node->getType() == ELoopFor); + ASSERT(node->getInit()); + TIntermAggregate* decl = node->getInit()->getAsAggregate(); + ASSERT(decl && decl->getOp() == EOpDeclaration); + TIntermSequence& declSeq = decl->getSequence(); + ASSERT(declSeq.size() == 1); + TIntermBinary* declInit = declSeq[0]->getAsBinaryNode(); + ASSERT(declInit && declInit->getOp() == EOpInitialize); + ASSERT(declInit->getLeft()); + TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode(); + ASSERT(symbol); + TBasicType type = symbol->getBasicType(); + ASSERT(type == EbtInt || type == EbtFloat); + if (type == EbtInt) + node->setUnrollFlag(true); + return true; + } + +}; + +} // anonymous namepsace + +void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info) +{ + ASSERT(node->getType() == ELoopFor); + ASSERT(node->getUnrollFlag()); + + TIntermNode* init = node->getInit(); + ASSERT(init != NULL); + TIntermAggregate* decl = init->getAsAggregate(); + ASSERT((decl != NULL) && (decl->getOp() == EOpDeclaration)); + TIntermSequence& declSeq = decl->getSequence(); + ASSERT(declSeq.size() == 1); + TIntermBinary* declInit = declSeq[0]->getAsBinaryNode(); + ASSERT((declInit != NULL) && (declInit->getOp() == EOpInitialize)); + TIntermSymbol* symbol = declInit->getLeft()->getAsSymbolNode(); + ASSERT(symbol != NULL); + ASSERT(symbol->getBasicType() == EbtInt); + + info.id = symbol->getId(); + + ASSERT(declInit->getRight() != NULL); + TIntermConstantUnion* initNode = declInit->getRight()->getAsConstantUnion(); + ASSERT(initNode != NULL); + + info.initValue = evaluateIntConstant(initNode); + info.currentValue = info.initValue; + + TIntermNode* cond = node->getCondition(); + ASSERT(cond != NULL); + TIntermBinary* binOp = cond->getAsBinaryNode(); + ASSERT(binOp != NULL); + ASSERT(binOp->getRight() != NULL); + ASSERT(binOp->getRight()->getAsConstantUnion() != NULL); + + info.incrementValue = getLoopIncrement(node); + info.stopValue = evaluateIntConstant( + binOp->getRight()->getAsConstantUnion()); + info.op = binOp->getOp(); +} + +void ForLoopUnroll::Step() +{ + ASSERT(mLoopIndexStack.size() > 0); + TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1]; + info.currentValue += info.incrementValue; +} + +bool ForLoopUnroll::SatisfiesLoopCondition() +{ + ASSERT(mLoopIndexStack.size() > 0); + TLoopIndexInfo& info = mLoopIndexStack[mLoopIndexStack.size() - 1]; + // Relational operator is one of: > >= < <= == or !=. + switch (info.op) { + case EOpEqual: + return (info.currentValue == info.stopValue); + case EOpNotEqual: + return (info.currentValue != info.stopValue); + case EOpLessThan: + return (info.currentValue < info.stopValue); + case EOpGreaterThan: + return (info.currentValue > info.stopValue); + case EOpLessThanEqual: + return (info.currentValue <= info.stopValue); + case EOpGreaterThanEqual: + return (info.currentValue >= info.stopValue); + default: + UNREACHABLE(); + } + return false; +} + +bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol) +{ + for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin(); + i != mLoopIndexStack.end(); + ++i) { + if (i->id == symbol->getId()) + return true; + } + return false; +} + +int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol) +{ + for (TVector<TLoopIndexInfo>::iterator i = mLoopIndexStack.begin(); + i != mLoopIndexStack.end(); + ++i) { + if (i->id == symbol->getId()) + return i->currentValue; + } + UNREACHABLE(); + return false; +} + +void ForLoopUnroll::Push(TLoopIndexInfo& info) +{ + mLoopIndexStack.push_back(info); +} + +void ForLoopUnroll::Pop() +{ + mLoopIndexStack.pop_back(); +} + +// static +void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling( + TIntermNode* root) +{ + ASSERT(root); + + IntegerForLoopUnrollMarker marker; + root->traverse(&marker); +} + +int ForLoopUnroll::getLoopIncrement(TIntermLoop* node) +{ + TIntermNode* expr = node->getExpression(); + ASSERT(expr != NULL); + // 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; + TIntermConstantUnion* incrementNode = NULL; + if (unOp != NULL) { + op = unOp->getOp(); + } else if (binOp != NULL) { + op = binOp->getOp(); + ASSERT(binOp->getRight() != NULL); + incrementNode = binOp->getRight()->getAsConstantUnion(); + ASSERT(incrementNode != NULL); + } + + int increment = 0; + // The operator is one of: ++ -- += -=. + switch (op) { + case EOpPostIncrement: + case EOpPreIncrement: + ASSERT((unOp != NULL) && (binOp == NULL)); + increment = 1; + break; + case EOpPostDecrement: + case EOpPreDecrement: + ASSERT((unOp != NULL) && (binOp == NULL)); + increment = -1; + break; + case EOpAddAssign: + ASSERT((unOp == NULL) && (binOp != NULL)); + increment = evaluateIntConstant(incrementNode); + break; + case EOpSubAssign: + ASSERT((unOp == NULL) && (binOp != NULL)); + increment = - evaluateIntConstant(incrementNode); + break; + default: + ASSERT(false); + } + + return increment; +} + +int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node) +{ + ASSERT((node != NULL) && (node->getUnionArrayPointer() != NULL)); + return node->getUnionArrayPointer()->getIConst(); +} + diff --git a/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.h b/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.h new file mode 100644 index 0000000..e800e25 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/ForLoopUnroll.h @@ -0,0 +1,48 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/intermediate.h" + +struct TLoopIndexInfo { + int id; + int initValue; + int stopValue; + int incrementValue; + TOperator op; + int currentValue; +}; + +class ForLoopUnroll { +public: + ForLoopUnroll() { } + + void FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo& info); + + // Update the info.currentValue for the next loop iteration. + void Step(); + + // Return false if loop condition is no longer satisfied. + bool SatisfiesLoopCondition(); + + // Check if the symbol is the index of a loop that's unrolled. + bool NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol); + + // Return the current value of a given loop index symbol. + int GetLoopIndexValue(TIntermSymbol* symbol); + + void Push(TLoopIndexInfo& info); + void Pop(); + + static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root); + +private: + int getLoopIncrement(TIntermLoop* node); + + int evaluateIntConstant(TIntermConstantUnion* node); + + TVector<TLoopIndexInfo> mLoopIndexStack; +}; + diff --git a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp index 12b53fe..f3a19dc 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Initialize.cpp @@ -19,7 +19,7 @@ // Prototypes for built-in functions seen by both vertex and fragment shaders. // //============================================================================ -static TString BuiltInFunctionsCommon() +static TString BuiltInFunctionsCommon(const ShBuiltInResources& resources) { TString s; @@ -311,6 +311,26 @@ 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);")); + + if (resources.OES_EGL_image_external) { + s.append(TString("vec4 texture2D(samplerExternalOES sampler, vec2 coord);")); + s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec3 coord);")); + s.append(TString("vec4 texture2DProj(samplerExternalOES sampler, vec4 coord);")); + } + + if (resources.ARB_texture_rectangle) { + s.append(TString("vec4 texture2DRect(sampler2DRect sampler, vec2 coord);")); + s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec3 coord);")); + s.append(TString("vec4 texture2DRectProj(sampler2DRect sampler, vec4 coord);")); + } + + // // Noise functions. // //s.append(TString("float noise1(float x);")); @@ -353,17 +373,10 @@ static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources) // // Texture Functions. // - 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("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);")); return s; } @@ -380,11 +393,6 @@ static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources) // // 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);")); @@ -490,14 +498,14 @@ void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec, switch (type) { case SH_FRAGMENT_SHADER: builtInStrings.push_back(DefaultPrecisionFragment()); - builtInStrings.push_back(BuiltInFunctionsCommon()); + builtInStrings.push_back(BuiltInFunctionsCommon(resources)); builtInStrings.push_back(BuiltInFunctionsFragment(resources)); builtInStrings.push_back(StandardUniforms()); break; case SH_VERTEX_SHADER: builtInStrings.push_back(DefaultPrecisionVertex()); - builtInStrings.push_back(BuiltInFunctionsCommon()); + builtInStrings.push_back(BuiltInFunctionsCommon(resources)); builtInStrings.push_back(BuiltInFunctionsVertex(resources)); builtInStrings.push_back(StandardUniforms()); break; @@ -614,7 +622,7 @@ void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, switch(type) { case SH_FRAGMENT_SHADER: { // Set up gl_FragData. The array size. - TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true); + TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true); fragData.setArraySize(resources.MaxDrawBuffers); symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData)); } @@ -627,5 +635,9 @@ void InitExtensionBehavior(const ShBuiltInResources& resources, TExtensionBehavior& extBehavior) { if (resources.OES_standard_derivatives) - extBehavior["GL_OES_standard_derivatives"] = EBhDisable; + extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; + if (resources.OES_EGL_image_external) + extBehavior["GL_OES_EGL_image_external"] = EBhUndefined; + if (resources.ARB_texture_rectangle) + extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp index ea71234..ca6d8f7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/Intermediate.cpp @@ -1005,8 +1005,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink) case EOpAddAssign: case EOpSubAssign: case EOpDivAssign: - if (left->isMatrix() && right->isVector() || - left->isVector() && right->isMatrix()) + if ((left->isMatrix() && right->isVector()) || + (left->isVector() && right->isMatrix())) return false; setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix())); break; @@ -1017,8 +1017,8 @@ bool TIntermBinary::promote(TInfoSink& infoSink) case EOpGreaterThan: case EOpLessThanEqual: case EOpGreaterThanEqual: - if (left->isMatrix() && right->isVector() || - left->isVector() && right->isMatrix()) + if ((left->isMatrix() && right->isVector()) || + (left->isVector() && right->isMatrix())) return false; setType(TType(EbtBool, EbpUndefined)); break; @@ -1371,8 +1371,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNod newNode->setLine(getLine()); return newNode; } - - return this; } TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node) diff --git a/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp new file mode 100644 index 0000000..0c7e1a9 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.cpp @@ -0,0 +1,120 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/MapLongVariableNames.h" + +namespace { + +TString mapLongName(int id, const TString& name, bool isGlobal) +{ + ASSERT(name.size() > MAX_SHORTENED_IDENTIFIER_SIZE); + TStringStream stream; + stream << "webgl_"; + if (isGlobal) + stream << "g"; + stream << id << "_"; + stream << name.substr(0, MAX_SHORTENED_IDENTIFIER_SIZE - stream.str().size()); + return stream.str(); +} + +LongNameMap* gLongNameMapInstance = NULL; + +} // anonymous namespace + +LongNameMap::LongNameMap() + : refCount(0) +{ +} + +LongNameMap::~LongNameMap() +{ +} + +// static +LongNameMap* LongNameMap::GetInstance() +{ + if (gLongNameMapInstance == NULL) + gLongNameMapInstance = new LongNameMap; + gLongNameMapInstance->refCount++; + return gLongNameMapInstance; +} + +void LongNameMap::Release() +{ + ASSERT(gLongNameMapInstance == this); + ASSERT(refCount > 0); + refCount--; + if (refCount == 0) { + delete gLongNameMapInstance; + gLongNameMapInstance = NULL; + } +} + +const char* LongNameMap::Find(const char* originalName) const +{ + std::map<std::string, std::string>::const_iterator it = mLongNameMap.find( + originalName); + if (it != mLongNameMap.end()) + return (*it).second.c_str(); + return NULL; +} + +void LongNameMap::Insert(const char* originalName, const char* mappedName) +{ + mLongNameMap.insert(std::map<std::string, std::string>::value_type( + originalName, mappedName)); +} + +int LongNameMap::Size() const +{ + return mLongNameMap.size(); +} + +MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap) +{ + ASSERT(globalMap); + mGlobalMap = globalMap; +} + +void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol) +{ + ASSERT(symbol != NULL); + if (symbol->getSymbol().size() > MAX_SHORTENED_IDENTIFIER_SIZE) { + switch (symbol->getQualifier()) { + case EvqVaryingIn: + case EvqVaryingOut: + case EvqInvariantVaryingIn: + case EvqInvariantVaryingOut: + case EvqUniform: + symbol->setSymbol( + mapGlobalLongName(symbol->getSymbol())); + break; + default: + symbol->setSymbol( + mapLongName(symbol->getId(), symbol->getSymbol(), false)); + break; + }; + } +} + +bool MapLongVariableNames::visitLoop(Visit, TIntermLoop* node) +{ + if (node->getInit()) + node->getInit()->traverse(this); + return true; +} + +TString MapLongVariableNames::mapGlobalLongName(const TString& name) +{ + ASSERT(mGlobalMap); + const char* mappedName = mGlobalMap->Find(name.c_str()); + if (mappedName != NULL) + return mappedName; + int id = mGlobalMap->Size(); + TString rt = mapLongName(id, name, true); + mGlobalMap->Insert(name.c_str(), rt.c_str()); + return rt; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.h b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.h new file mode 100644 index 0000000..b8eff2a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/MapLongVariableNames.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_MAP_LONG_VARIABLE_NAMES_H_ +#define COMPILER_MAP_LONG_VARIABLE_NAMES_H_ + +#include "GLSLANG/ShaderLang.h" + +#include "compiler/intermediate.h" +#include "compiler/VariableInfo.h" + +// This size does not include '\0' in the end. +#define MAX_SHORTENED_IDENTIFIER_SIZE 32 + +// This is a ref-counted singleton. GetInstance() returns a pointer to the +// singleton, and after use, call Release(). GetInstance() and Release() should +// be paired. +class LongNameMap { +public: + static LongNameMap* GetInstance(); + void Release(); + + // Return the mapped name if <originalName, mappedName> is in the map; + // otherwise, return NULL. + const char* Find(const char* originalName) const; + + // Insert a pair into the map. + void Insert(const char* originalName, const char* mappedName); + + // Return the number of entries in the map. + int Size() const; + +private: + LongNameMap(); + ~LongNameMap(); + + size_t refCount; + std::map<std::string, std::string> mLongNameMap; +}; + +// Traverses intermediate tree to map attributes and uniforms names that are +// longer than MAX_SHORTENED_IDENTIFIER_SIZE to MAX_SHORTENED_IDENTIFIER_SIZE. +class MapLongVariableNames : public TIntermTraverser { +public: + MapLongVariableNames(LongNameMap* globalMap); + virtual ~MapLongVariableNames() {} + + virtual void visitSymbol(TIntermSymbol*); + virtual bool visitLoop(Visit, TIntermLoop*); + +private: + TString mapGlobalLongName(const TString& name); + + LongNameMap* mGlobalMap; +}; + +#endif // COMPILER_MAP_LONG_VARIABLE_NAMES_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.cpp new file mode 100644 index 0000000..64ee92d --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.cpp @@ -0,0 +1,22 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/OutputESSL.h" + +TOutputESSL::TOutputESSL(TInfoSinkBase& objSink) + : TOutputGLSLBase(objSink) +{ +} + +bool TOutputESSL::writeVariablePrecision(TPrecision precision) +{ + if (precision == EbpUndefined) + return false; + + TInfoSinkBase& out = objSink(); + out << getPrecisionString(precision); + return true; +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.h new file mode 100644 index 0000000..ef4063f --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputESSL.h @@ -0,0 +1,22 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef CROSSCOMPILERGLSL_OUTPUTESSL_H_ +#define CROSSCOMPILERGLSL_OUTPUTESSL_H_ + +#include "compiler/OutputGLSLBase.h" + +class TOutputESSL : public TOutputGLSLBase +{ +public: + TOutputESSL(TInfoSinkBase& objSink); + virtual ~TOutputESSL() {} + +protected: + virtual bool writeVariablePrecision(TPrecision precision); +}; + +#endif // CROSSCOMPILERGLSL_OUTPUTESSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp index 23476f2..dd31b4b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.cpp @@ -1,690 +1,17 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // #include "compiler/OutputGLSL.h" -#include "compiler/debug.h" - -namespace -{ -TString getTypeName(const TType& type) -{ - TInfoSinkBase out; - if (type.isMatrix()) - { - out << "mat"; - out << type.getNominalSize(); - } - else if (type.isVector()) - { - switch (type.getBasicType()) - { - case EbtFloat: out << "vec"; break; - case EbtInt: out << "ivec"; break; - case EbtBool: out << "bvec"; break; - default: UNREACHABLE(); break; - } - out << type.getNominalSize(); - } - else - { - if (type.getBasicType() == EbtStruct) - out << type.getTypeName(); - else - out << type.getBasicString(); - } - return TString(out.c_str()); -} - -TString arrayBrackets(const TType& type) -{ - ASSERT(type.isArray()); - TInfoSinkBase out; - out << "[" << type.getArraySize() << "]"; - return TString(out.c_str()); -} - -bool isSingleStatement(TIntermNode* node) { - if (const TIntermAggregate* aggregate = node->getAsAggregate()) - { - return (aggregate->getOp() != EOpFunction) && - (aggregate->getOp() != EOpSequence); - } - else if (const TIntermSelection* selection = node->getAsSelectionNode()) - { - // Ternary operators are usually part of an assignment operator. - // This handles those rare cases in which they are all by themselves. - return selection->usesTernaryOperator(); - } - else if (node->getAsLoopNode()) - { - return false; - } - return true; -} -} // namespace TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink) - : TIntermTraverser(true, true, true), - mObjSink(objSink), - mDeclaringVariables(false) -{ -} - -void TOutputGLSL::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr) + : TOutputGLSLBase(objSink) { - TInfoSinkBase& out = objSink(); - if (visit == PreVisit && preStr) - { - out << preStr; - } - else if (visit == InVisit && inStr) - { - out << inStr; - } - else if (visit == PostVisit && postStr) - { - out << postStr; - } -} - -void TOutputGLSL::writeVariableType(const TType& type) -{ - TInfoSinkBase& out = objSink(); - TQualifier qualifier = type.getQualifier(); - // TODO(alokp): Validate qualifier for variable declarations. - if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) - out << type.getQualifierString() << " "; - - // Declare the struct if we have not done so already. - if ((type.getBasicType() == EbtStruct) && - (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end())) - { - out << "struct " << type.getTypeName() << "{\n"; - const TTypeList* structure = type.getStruct(); - ASSERT(structure != NULL); - for (size_t i = 0; i < structure->size(); ++i) - { - const TType* fieldType = (*structure)[i].type; - ASSERT(fieldType != NULL); - out << getTypeName(*fieldType) << " " << fieldType->getFieldName(); - if (fieldType->isArray()) - out << arrayBrackets(*fieldType); - out << ";\n"; - } - out << "}"; - mDeclaredStructs.insert(type.getTypeName()); - } - else - { - out << getTypeName(type); - } -} - -void TOutputGLSL::writeFunctionParameters(const TIntermSequence& args) -{ - TInfoSinkBase& out = objSink(); - for (TIntermSequence::const_iterator iter = args.begin(); - iter != args.end(); ++iter) - { - const TIntermSymbol* arg = (*iter)->getAsSymbolNode(); - ASSERT(arg != NULL); - - const TType& type = arg->getType(); - TQualifier qualifier = type.getQualifier(); - // TODO(alokp): Validate qualifier for function arguments. - if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) - out << type.getQualifierString() << " "; - - out << getTypeName(type); - - const TString& name = arg->getSymbol(); - if (!name.empty()) - out << " " << name; - if (type.isArray()) - out << arrayBrackets(type); - - // Put a comma if this is not the last argument. - if (iter != args.end() - 1) - out << ", "; - } } -const ConstantUnion* TOutputGLSL::writeConstantUnion(const TType& type, - const ConstantUnion* pConstUnion) +bool TOutputGLSL::writeVariablePrecision(TPrecision) { - TInfoSinkBase& out = objSink(); - - if (type.getBasicType() == EbtStruct) - { - out << type.getTypeName() << "("; - const TTypeList* structure = type.getStruct(); - ASSERT(structure != NULL); - for (size_t i = 0; i < structure->size(); ++i) - { - const TType* fieldType = (*structure)[i].type; - ASSERT(fieldType != NULL); - pConstUnion = writeConstantUnion(*fieldType, pConstUnion); - if (i != structure->size() - 1) out << ", "; - } - out << ")"; - } - else - { - int size = type.getObjectSize(); - bool writeType = size > 1; - if (writeType) out << getTypeName(type) << "("; - for (int i = 0; i < size; ++i, ++pConstUnion) - { - switch (pConstUnion->getType()) - { - case EbtFloat: out << pConstUnion->getFConst(); break; - case EbtInt: out << pConstUnion->getIConst(); break; - case EbtBool: out << pConstUnion->getBConst(); break; - default: UNREACHABLE(); - } - if (i != size - 1) out << ", "; - } - if (writeType) out << ")"; - } - return pConstUnion; -} - -void TOutputGLSL::visitSymbol(TIntermSymbol* node) -{ - TInfoSinkBase& out = objSink(); - out << node->getSymbol(); - - if (mDeclaringVariables && node->getType().isArray()) - out << arrayBrackets(node->getType()); -} - -void TOutputGLSL::visitConstantUnion(TIntermConstantUnion* node) -{ - writeConstantUnion(node->getType(), node->getUnionArrayPointer()); -} - -bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - switch (node->getOp()) - { - case EOpInitialize: - if (visit == InVisit) - { - out << " = "; - // RHS of initialize is not being declared. - mDeclaringVariables = false; - } - break; - case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break; - case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break; - case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break; - case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break; - // Notice the fall-through. - case EOpMulAssign: - case EOpVectorTimesMatrixAssign: - case EOpVectorTimesScalarAssign: - case EOpMatrixTimesScalarAssign: - case EOpMatrixTimesMatrixAssign: - writeTriplet(visit, "(", " *= ", ")"); - break; - - case EOpIndexDirect: - case EOpIndexIndirect: - writeTriplet(visit, NULL, "[", "]"); - break; - case EOpIndexDirectStruct: - if (visit == InVisit) - { - out << "."; - // TODO(alokp): ASSERT - out << node->getType().getFieldName(); - visitChildren = false; - } - break; - case EOpVectorSwizzle: - if (visit == InVisit) - { - out << "."; - TIntermAggregate* rightChild = node->getRight()->getAsAggregate(); - TIntermSequence& sequence = rightChild->getSequence(); - for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit) - { - TIntermConstantUnion* element = (*sit)->getAsConstantUnion(); - ASSERT(element->getBasicType() == EbtInt); - ASSERT(element->getNominalSize() == 1); - const ConstantUnion& data = element->getUnionArrayPointer()[0]; - ASSERT(data.getType() == EbtInt); - switch (data.getIConst()) - { - case 0: out << "x"; break; - case 1: out << "y"; break; - case 2: out << "z"; break; - case 3: out << "w"; break; - default: UNREACHABLE(); break; - } - } - visitChildren = false; - } - break; - - case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break; - case EOpSub: writeTriplet(visit, "(", " - ", ")"); break; - case EOpMul: writeTriplet(visit, "(", " * ", ")"); break; - case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break; - case EOpMod: UNIMPLEMENTED(); break; - case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break; - case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break; - case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break; - case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break; - case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break; - case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break; - - // Notice the fall-through. - case EOpVectorTimesScalar: - case EOpVectorTimesMatrix: - case EOpMatrixTimesVector: - case EOpMatrixTimesScalar: - case EOpMatrixTimesMatrix: - writeTriplet(visit, "(", " * ", ")"); - break; - - case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break; - case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break; - case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break; - default: UNREACHABLE(); break; - } - - return visitChildren; -} - -bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node) -{ - switch (node->getOp()) - { - case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break; - case EOpVectorLogicalNot: writeTriplet(visit, "not(", NULL, ")"); break; - case EOpLogicalNot: writeTriplet(visit, "(!", NULL, ")"); break; - - case EOpPostIncrement: writeTriplet(visit, "(", NULL, "++)"); break; - case EOpPostDecrement: writeTriplet(visit, "(", NULL, "--)"); break; - case EOpPreIncrement: writeTriplet(visit, "(++", NULL, ")"); break; - case EOpPreDecrement: writeTriplet(visit, "(--", NULL, ")"); break; - - case EOpConvIntToBool: - case EOpConvFloatToBool: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: writeTriplet(visit, "bool(", NULL, ")"); break; - case 2: writeTriplet(visit, "bvec2(", NULL, ")"); break; - case 3: writeTriplet(visit, "bvec3(", NULL, ")"); break; - case 4: writeTriplet(visit, "bvec4(", NULL, ")"); break; - default: UNREACHABLE(); - } - break; - case EOpConvBoolToFloat: - case EOpConvIntToFloat: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: writeTriplet(visit, "float(", NULL, ")"); break; - case 2: writeTriplet(visit, "vec2(", NULL, ")"); break; - case 3: writeTriplet(visit, "vec3(", NULL, ")"); break; - case 4: writeTriplet(visit, "vec4(", NULL, ")"); break; - default: UNREACHABLE(); - } - break; - case EOpConvFloatToInt: - case EOpConvBoolToInt: - switch (node->getOperand()->getType().getNominalSize()) - { - case 1: writeTriplet(visit, "int(", NULL, ")"); break; - case 2: writeTriplet(visit, "ivec2(", NULL, ")"); break; - case 3: writeTriplet(visit, "ivec3(", NULL, ")"); break; - case 4: writeTriplet(visit, "ivec4(", NULL, ")"); break; - default: UNREACHABLE(); - } - break; - - case EOpRadians: writeTriplet(visit, "radians(", NULL, ")"); break; - case EOpDegrees: writeTriplet(visit, "degrees(", NULL, ")"); break; - case EOpSin: writeTriplet(visit, "sin(", NULL, ")"); break; - case EOpCos: writeTriplet(visit, "cos(", NULL, ")"); break; - case EOpTan: writeTriplet(visit, "tan(", NULL, ")"); break; - case EOpAsin: writeTriplet(visit, "asin(", NULL, ")"); break; - case EOpAcos: writeTriplet(visit, "acos(", NULL, ")"); break; - case EOpAtan: writeTriplet(visit, "atan(", NULL, ")"); break; - - case EOpExp: writeTriplet(visit, "exp(", NULL, ")"); break; - case EOpLog: writeTriplet(visit, "log(", NULL, ")"); break; - case EOpExp2: writeTriplet(visit, "exp2(", NULL, ")"); break; - case EOpLog2: writeTriplet(visit, "log2(", NULL, ")"); break; - case EOpSqrt: writeTriplet(visit, "sqrt(", NULL, ")"); break; - case EOpInverseSqrt: writeTriplet(visit, "inversesqrt(", NULL, ")"); break; - - case EOpAbs: writeTriplet(visit, "abs(", NULL, ")"); break; - case EOpSign: writeTriplet(visit, "sign(", NULL, ")"); break; - case EOpFloor: writeTriplet(visit, "floor(", NULL, ")"); break; - case EOpCeil: writeTriplet(visit, "ceil(", NULL, ")"); break; - case EOpFract: writeTriplet(visit, "fract(", NULL, ")"); break; - - 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; - - default: UNREACHABLE(); break; - } - - return true; -} - -bool TOutputGLSL::visitSelection(Visit visit, TIntermSelection* node) -{ - TInfoSinkBase& out = objSink(); - - if (node->usesTernaryOperator()) - { - // Notice two brackets at the beginning and end. The outer ones - // encapsulate the whole ternary expression. This preserves the - // order of precedence when ternary expressions are used in a - // compound expression, i.e., c = 2 * (a < b ? 1 : 2). - out << "(("; - node->getCondition()->traverse(this); - out << ") ? ("; - node->getTrueBlock()->traverse(this); - out << ") : ("; - node->getFalseBlock()->traverse(this); - out << "))"; - } - else - { - out << "if ("; - node->getCondition()->traverse(this); - out << ")\n"; - - incrementDepth(); - visitCodeBlock(node->getTrueBlock()); - - if (node->getFalseBlock()) - { - out << "else\n"; - visitCodeBlock(node->getFalseBlock()); - } - decrementDepth(); - } - return false; -} - -bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node) -{ - bool visitChildren = true; - TInfoSinkBase& out = objSink(); - switch (node->getOp()) - { - case EOpSequence: { - // Scope the sequences except when at the global scope. - if (depth > 0) out << "{\n"; - - incrementDepth(); - const TIntermSequence& sequence = node->getSequence(); - for (TIntermSequence::const_iterator iter = sequence.begin(); - iter != sequence.end(); ++iter) - { - TIntermNode* node = *iter; - ASSERT(node != NULL); - node->traverse(this); - - if (isSingleStatement(node)) - out << ";\n"; - } - decrementDepth(); - - // Scope the sequences except when at the global scope. - if (depth > 0) out << "}\n"; - visitChildren = false; - break; - } - case EOpPrototype: { - // Function declaration. - ASSERT(visit == PreVisit); - TString returnType = getTypeName(node->getType()); - out << returnType << " " << node->getName(); - - out << "("; - writeFunctionParameters(node->getSequence()); - out << ")"; - - visitChildren = false; - break; - } - case EOpFunction: { - // Function definition. - ASSERT(visit == PreVisit); - TString returnType = getTypeName(node->getType()); - TString functionName = TFunction::unmangleName(node->getName()); - out << returnType << " " << functionName; - - incrementDepth(); - // Function definition node contains one or two children nodes - // representing function parameters and function body. The latter - // is not present in case of empty function bodies. - const TIntermSequence& sequence = node->getSequence(); - ASSERT((sequence.size() == 1) || (sequence.size() == 2)); - TIntermSequence::const_iterator seqIter = sequence.begin(); - - // Traverse function parameters. - TIntermAggregate* params = (*seqIter)->getAsAggregate(); - ASSERT(params != NULL); - ASSERT(params->getOp() == EOpParameters); - params->traverse(this); - - // Traverse function body. - TIntermAggregate* body = ++seqIter != sequence.end() ? - (*seqIter)->getAsAggregate() : NULL; - visitCodeBlock(body); - decrementDepth(); - - // Fully processed; no need to visit children. - visitChildren = false; - break; - } - case EOpFunctionCall: - // Function call. - if (visit == PreVisit) - { - TString functionName = TFunction::unmangleName(node->getName()); - out << functionName << "("; - } - else if (visit == InVisit) - { - out << ", "; - } - else - { - out << ")"; - } - break; - case EOpParameters: { - // Function parameters. - ASSERT(visit == PreVisit); - out << "("; - writeFunctionParameters(node->getSequence()); - out << ")"; - visitChildren = false; - break; - } - case EOpDeclaration: { - // Variable declaration. - if (visit == PreVisit) - { - const TIntermSequence& sequence = node->getSequence(); - const TIntermTyped* variable = sequence.front()->getAsTyped(); - writeVariableType(variable->getType()); - out << " "; - mDeclaringVariables = true; - } - else if (visit == InVisit) - { - out << ", "; - mDeclaringVariables = true; - } - else - { - mDeclaringVariables = false; - } - break; - } - case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; - case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; - case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; - case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break; - case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break; - case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break; - case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break; - case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break; - case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break; - case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break; - case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break; - case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break; - case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break; - case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break; - case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break; - case EOpConstructStruct: - if (visit == PreVisit) - { - const TType& type = node->getType(); - ASSERT(type.getBasicType() == EbtStruct); - out << type.getTypeName() << "("; - } - else if (visit == InVisit) - { - out << ", "; - } - else - { - out << ")"; - } - break; - - case EOpLessThan: writeTriplet(visit, "lessThan(", ", ", ")"); break; - case EOpGreaterThan: writeTriplet(visit, "greaterThan(", ", ", ")"); break; - case EOpLessThanEqual: writeTriplet(visit, "lessThanEqual(", ", ", ")"); break; - case EOpGreaterThanEqual: writeTriplet(visit, "greaterThanEqual(", ", ", ")"); break; - case EOpVectorEqual: writeTriplet(visit, "equal(", ", ", ")"); break; - case EOpVectorNotEqual: writeTriplet(visit, "notEqual(", ", ", ")"); break; - case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break; - - case EOpMod: writeTriplet(visit, "mod(", ", ", ")"); break; - case EOpPow: writeTriplet(visit, "pow(", ", ", ")"); break; - case EOpAtan: writeTriplet(visit, "atan(", ", ", ")"); break; - case EOpMin: writeTriplet(visit, "min(", ", ", ")"); break; - case EOpMax: writeTriplet(visit, "max(", ", ", ")"); break; - case EOpClamp: writeTriplet(visit, "clamp(", ", ", ")"); break; - case EOpMix: writeTriplet(visit, "mix(", ", ", ")"); break; - case EOpStep: writeTriplet(visit, "step(", ", ", ")"); break; - case EOpSmoothStep: writeTriplet(visit, "smoothstep(", ", ", ")"); break; - - case EOpDistance: writeTriplet(visit, "distance(", ", ", ")"); break; - case EOpDot: writeTriplet(visit, "dot(", ", ", ")"); break; - case EOpCross: writeTriplet(visit, "cross(", ", ", ")"); break; - case EOpFaceForward: writeTriplet(visit, "faceforward(", ", ", ")"); break; - case EOpReflect: writeTriplet(visit, "reflect(", ", ", ")"); break; - case EOpRefract: writeTriplet(visit, "refract(", ", ", ")"); break; - case EOpMul: writeTriplet(visit, "matrixCompMult(", ", ", ")"); break; - - default: UNREACHABLE(); break; - } - return visitChildren; -} - -bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node) -{ - TInfoSinkBase& out = objSink(); - - incrementDepth(); - // Loop header. - TLoopType loopType = node->getType(); - if (loopType == ELoopFor) // for loop - { - out << "for ("; - if (node->getInit()) - node->getInit()->traverse(this); - out << "; "; - - if (node->getCondition()) - node->getCondition()->traverse(this); - out << "; "; - - 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"; - } - - // Loop body. - visitCodeBlock(node->getBody()); - - // Loop footer. - if (loopType == ELoopDoWhile) // do-while loop - { - out << "while ("; - ASSERT(node->getCondition() != NULL); - node->getCondition()->traverse(this); - out << ");\n"; - } - decrementDepth(); - - // No need to visit children. They have been already processed in - // this function. return false; } - -bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node) -{ - switch (node->getFlowOp()) - { - case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break; - case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break; - case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break; - case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break; - default: UNREACHABLE(); break; - } - - return true; -} - -void TOutputGLSL::visitCodeBlock(TIntermNode* node) { - TInfoSinkBase &out = objSink(); - if (node != NULL) - { - node->traverse(this); - // Single statements not part of a sequence need to be terminated - // with semi-colon. - if (isSingleStatement(node)) - out << ";\n"; - } - else - { - out << "{\n}\n"; // Empty code block. - } -} diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.h index aa203d4..0fe2356 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -7,43 +7,15 @@ #ifndef CROSSCOMPILERGLSL_OUTPUTGLSL_H_ #define CROSSCOMPILERGLSL_OUTPUTGLSL_H_ -#include <set> +#include "compiler/OutputGLSLBase.h" -#include "compiler/intermediate.h" -#include "compiler/ParseHelper.h" - -class TOutputGLSL : public TIntermTraverser +class TOutputGLSL : public TOutputGLSLBase { public: TOutputGLSL(TInfoSinkBase& objSink); protected: - TInfoSinkBase& objSink() { return mObjSink; } - void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr); - void writeVariableType(const TType& type); - void writeFunctionParameters(const TIntermSequence& args); - const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion); - - virtual void visitSymbol(TIntermSymbol* node); - virtual void visitConstantUnion(TIntermConstantUnion* node); - virtual bool visitBinary(Visit visit, TIntermBinary* node); - virtual bool visitUnary(Visit visit, TIntermUnary* node); - virtual bool visitSelection(Visit visit, TIntermSelection* node); - virtual bool visitAggregate(Visit visit, TIntermAggregate* node); - virtual bool visitLoop(Visit visit, TIntermLoop* node); - virtual bool visitBranch(Visit visit, TIntermBranch* node); - - void visitCodeBlock(TIntermNode* node); - -private: - TInfoSinkBase& mObjSink; - bool mDeclaringVariables; - - // Structs are declared as the tree is traversed. This set contains all - // the structs already declared. It is maintained so that a struct is - // declared only once. - typedef std::set<TString> DeclaredStructs; - DeclaredStructs mDeclaredStructs; + virtual bool writeVariablePrecision(TPrecision); }; #endif // CROSSCOMPILERGLSL_OUTPUTGLSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp new file mode 100644 index 0000000..552fa50 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.cpp @@ -0,0 +1,720 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/OutputGLSLBase.h" +#include "compiler/debug.h" + +namespace +{ +TString getTypeName(const TType& type) +{ + TInfoSinkBase out; + if (type.isMatrix()) + { + out << "mat"; + out << type.getNominalSize(); + } + else if (type.isVector()) + { + switch (type.getBasicType()) + { + case EbtFloat: out << "vec"; break; + case EbtInt: out << "ivec"; break; + case EbtBool: out << "bvec"; break; + default: UNREACHABLE(); break; + } + out << type.getNominalSize(); + } + else + { + if (type.getBasicType() == EbtStruct) + out << type.getTypeName(); + else + out << type.getBasicString(); + } + return TString(out.c_str()); +} + +TString arrayBrackets(const TType& type) +{ + ASSERT(type.isArray()); + TInfoSinkBase out; + out << "[" << type.getArraySize() << "]"; + return TString(out.c_str()); +} + +bool isSingleStatement(TIntermNode* node) { + if (const TIntermAggregate* aggregate = node->getAsAggregate()) + { + return (aggregate->getOp() != EOpFunction) && + (aggregate->getOp() != EOpSequence); + } + else if (const TIntermSelection* selection = node->getAsSelectionNode()) + { + // Ternary operators are usually part of an assignment operator. + // This handles those rare cases in which they are all by themselves. + return selection->usesTernaryOperator(); + } + else if (node->getAsLoopNode()) + { + return false; + } + return true; +} +} // namespace + +TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase& objSink) + : TIntermTraverser(true, true, true), + mObjSink(objSink), + mDeclaringVariables(false) +{ +} + +void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr) +{ + TInfoSinkBase& out = objSink(); + if (visit == PreVisit && preStr) + { + out << preStr; + } + else if (visit == InVisit && inStr) + { + out << inStr; + } + else if (visit == PostVisit && postStr) + { + out << postStr; + } +} + +void TOutputGLSLBase::writeVariableType(const TType& type) +{ + TInfoSinkBase& out = objSink(); + TQualifier qualifier = type.getQualifier(); + // TODO(alokp): Validate qualifier for variable declarations. + if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal)) + out << type.getQualifierString() << " "; + // Declare the struct if we have not done so already. + if ((type.getBasicType() == EbtStruct) && + (mDeclaredStructs.find(type.getTypeName()) == mDeclaredStructs.end())) + { + out << "struct " << type.getTypeName() << "{\n"; + const TTypeList* structure = type.getStruct(); + ASSERT(structure != NULL); + for (size_t i = 0; i < structure->size(); ++i) + { + const TType* fieldType = (*structure)[i].type; + ASSERT(fieldType != NULL); + if (writeVariablePrecision(fieldType->getPrecision())) + out << " "; + out << getTypeName(*fieldType) << " " << fieldType->getFieldName(); + if (fieldType->isArray()) + out << arrayBrackets(*fieldType); + out << ";\n"; + } + out << "}"; + mDeclaredStructs.insert(type.getTypeName()); + } + else + { + if (writeVariablePrecision(type.getPrecision())) + out << " "; + out << getTypeName(type); + } +} + +void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence& args) +{ + TInfoSinkBase& out = objSink(); + for (TIntermSequence::const_iterator iter = args.begin(); + iter != args.end(); ++iter) + { + const TIntermSymbol* arg = (*iter)->getAsSymbolNode(); + ASSERT(arg != NULL); + + const TType& type = arg->getType(); + writeVariableType(type); + + const TString& name = arg->getSymbol(); + if (!name.empty()) + out << " " << name; + if (type.isArray()) + out << arrayBrackets(type); + + // Put a comma if this is not the last argument. + if (iter != args.end() - 1) + out << ", "; + } +} + +const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType& type, + const ConstantUnion* pConstUnion) +{ + TInfoSinkBase& out = objSink(); + + if (type.getBasicType() == EbtStruct) + { + out << type.getTypeName() << "("; + const TTypeList* structure = type.getStruct(); + ASSERT(structure != NULL); + for (size_t i = 0; i < structure->size(); ++i) + { + const TType* fieldType = (*structure)[i].type; + ASSERT(fieldType != NULL); + pConstUnion = writeConstantUnion(*fieldType, pConstUnion); + if (i != structure->size() - 1) out << ", "; + } + out << ")"; + } + else + { + int size = type.getObjectSize(); + bool writeType = size > 1; + if (writeType) out << getTypeName(type) << "("; + for (int i = 0; i < size; ++i, ++pConstUnion) + { + switch (pConstUnion->getType()) + { + case EbtFloat: out << pConstUnion->getFConst(); break; + case EbtInt: out << pConstUnion->getIConst(); break; + case EbtBool: out << pConstUnion->getBConst(); break; + default: UNREACHABLE(); + } + if (i != size - 1) out << ", "; + } + if (writeType) out << ")"; + } + return pConstUnion; +} + +void TOutputGLSLBase::visitSymbol(TIntermSymbol* node) +{ + TInfoSinkBase& out = objSink(); + if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node)) + out << mLoopUnroll.GetLoopIndexValue(node); + else + out << node->getSymbol(); + + if (mDeclaringVariables && node->getType().isArray()) + out << arrayBrackets(node->getType()); +} + +void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node) +{ + writeConstantUnion(node->getType(), node->getUnionArrayPointer()); +} + +bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node) +{ + bool visitChildren = true; + TInfoSinkBase& out = objSink(); + switch (node->getOp()) + { + case EOpInitialize: + if (visit == InVisit) + { + out << " = "; + // RHS of initialize is not being declared. + mDeclaringVariables = false; + } + break; + case EOpAssign: writeTriplet(visit, "(", " = ", ")"); break; + case EOpAddAssign: writeTriplet(visit, "(", " += ", ")"); break; + case EOpSubAssign: writeTriplet(visit, "(", " -= ", ")"); break; + case EOpDivAssign: writeTriplet(visit, "(", " /= ", ")"); break; + // Notice the fall-through. + case EOpMulAssign: + case EOpVectorTimesMatrixAssign: + case EOpVectorTimesScalarAssign: + case EOpMatrixTimesScalarAssign: + case EOpMatrixTimesMatrixAssign: + writeTriplet(visit, "(", " *= ", ")"); + break; + + case EOpIndexDirect: + case EOpIndexIndirect: + writeTriplet(visit, NULL, "[", "]"); + break; + case EOpIndexDirectStruct: + if (visit == InVisit) + { + out << "."; + // TODO(alokp): ASSERT + out << node->getType().getFieldName(); + visitChildren = false; + } + break; + case EOpVectorSwizzle: + if (visit == InVisit) + { + out << "."; + TIntermAggregate* rightChild = node->getRight()->getAsAggregate(); + TIntermSequence& sequence = rightChild->getSequence(); + for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit) + { + TIntermConstantUnion* element = (*sit)->getAsConstantUnion(); + ASSERT(element->getBasicType() == EbtInt); + ASSERT(element->getNominalSize() == 1); + const ConstantUnion& data = element->getUnionArrayPointer()[0]; + ASSERT(data.getType() == EbtInt); + switch (data.getIConst()) + { + case 0: out << "x"; break; + case 1: out << "y"; break; + case 2: out << "z"; break; + case 3: out << "w"; break; + default: UNREACHABLE(); break; + } + } + visitChildren = false; + } + break; + + case EOpAdd: writeTriplet(visit, "(", " + ", ")"); break; + case EOpSub: writeTriplet(visit, "(", " - ", ")"); break; + case EOpMul: writeTriplet(visit, "(", " * ", ")"); break; + case EOpDiv: writeTriplet(visit, "(", " / ", ")"); break; + case EOpMod: UNIMPLEMENTED(); break; + case EOpEqual: writeTriplet(visit, "(", " == ", ")"); break; + case EOpNotEqual: writeTriplet(visit, "(", " != ", ")"); break; + case EOpLessThan: writeTriplet(visit, "(", " < ", ")"); break; + case EOpGreaterThan: writeTriplet(visit, "(", " > ", ")"); break; + case EOpLessThanEqual: writeTriplet(visit, "(", " <= ", ")"); break; + case EOpGreaterThanEqual: writeTriplet(visit, "(", " >= ", ")"); break; + + // Notice the fall-through. + case EOpVectorTimesScalar: + case EOpVectorTimesMatrix: + case EOpMatrixTimesVector: + case EOpMatrixTimesScalar: + case EOpMatrixTimesMatrix: + writeTriplet(visit, "(", " * ", ")"); + break; + + case EOpLogicalOr: writeTriplet(visit, "(", " || ", ")"); break; + case EOpLogicalXor: writeTriplet(visit, "(", " ^^ ", ")"); break; + case EOpLogicalAnd: writeTriplet(visit, "(", " && ", ")"); break; + default: UNREACHABLE(); break; + } + + return visitChildren; +} + +bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node) +{ + TString preString; + TString postString = ")"; + + switch (node->getOp()) + { + case EOpNegative: preString = "(-"; break; + case EOpVectorLogicalNot: preString = "not("; break; + case EOpLogicalNot: preString = "(!"; break; + + case EOpPostIncrement: preString = "("; postString = "++)"; break; + case EOpPostDecrement: preString = "("; postString = "--)"; break; + case EOpPreIncrement: preString = "(++"; break; + case EOpPreDecrement: preString = "(--"; break; + + case EOpConvIntToBool: + case EOpConvFloatToBool: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: preString = "bool("; break; + case 2: preString = "bvec2("; break; + case 3: preString = "bvec3("; break; + case 4: preString = "bvec4("; break; + default: UNREACHABLE(); + } + break; + case EOpConvBoolToFloat: + case EOpConvIntToFloat: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: preString = "float("; break; + case 2: preString = "vec2("; break; + case 3: preString = "vec3("; break; + case 4: preString = "vec4("; break; + default: UNREACHABLE(); + } + break; + case EOpConvFloatToInt: + case EOpConvBoolToInt: + switch (node->getOperand()->getType().getNominalSize()) + { + case 1: preString = "int("; break; + case 2: preString = "ivec2("; break; + case 3: preString = "ivec3("; break; + case 4: preString = "ivec4("; break; + default: UNREACHABLE(); + } + break; + + case EOpRadians: preString = "radians("; break; + case EOpDegrees: preString = "degrees("; break; + case EOpSin: preString = "sin("; break; + case EOpCos: preString = "cos("; break; + case EOpTan: preString = "tan("; break; + case EOpAsin: preString = "asin("; break; + case EOpAcos: preString = "acos("; break; + case EOpAtan: preString = "atan("; break; + + case EOpExp: preString = "exp("; break; + case EOpLog: preString = "log("; break; + case EOpExp2: preString = "exp2("; break; + case EOpLog2: preString = "log2("; break; + case EOpSqrt: preString = "sqrt("; break; + case EOpInverseSqrt: preString = "inversesqrt("; break; + + case EOpAbs: preString = "abs("; break; + case EOpSign: preString = "sign("; break; + case EOpFloor: preString = "floor("; break; + case EOpCeil: preString = "ceil("; break; + case EOpFract: preString = "fract("; break; + + case EOpLength: preString = "length("; break; + case EOpNormalize: preString = "normalize("; break; + + case EOpDFdx: preString = "dFdx("; break; + case EOpDFdy: preString = "dFdy("; break; + case EOpFwidth: preString = "fwidth("; break; + + case EOpAny: preString = "any("; break; + case EOpAll: preString = "all("; break; + + default: UNREACHABLE(); break; + } + + if (visit == PreVisit && node->getUseEmulatedFunction()) + preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); + writeTriplet(visit, preString.c_str(), NULL, postString.c_str()); + + return true; +} + +bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node) +{ + TInfoSinkBase& out = objSink(); + + if (node->usesTernaryOperator()) + { + // Notice two brackets at the beginning and end. The outer ones + // encapsulate the whole ternary expression. This preserves the + // order of precedence when ternary expressions are used in a + // compound expression, i.e., c = 2 * (a < b ? 1 : 2). + out << "(("; + node->getCondition()->traverse(this); + out << ") ? ("; + node->getTrueBlock()->traverse(this); + out << ") : ("; + node->getFalseBlock()->traverse(this); + out << "))"; + } + else + { + out << "if ("; + node->getCondition()->traverse(this); + out << ")\n"; + + incrementDepth(); + visitCodeBlock(node->getTrueBlock()); + + if (node->getFalseBlock()) + { + out << "else\n"; + visitCodeBlock(node->getFalseBlock()); + } + decrementDepth(); + } + return false; +} + +bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node) +{ + bool visitChildren = true; + TInfoSinkBase& out = objSink(); + TString preString; + bool delayedWrite = false; + switch (node->getOp()) + { + case EOpSequence: { + // Scope the sequences except when at the global scope. + if (depth > 0) out << "{\n"; + + incrementDepth(); + const TIntermSequence& sequence = node->getSequence(); + for (TIntermSequence::const_iterator iter = sequence.begin(); + iter != sequence.end(); ++iter) + { + TIntermNode* node = *iter; + ASSERT(node != NULL); + node->traverse(this); + + if (isSingleStatement(node)) + out << ";\n"; + } + decrementDepth(); + + // Scope the sequences except when at the global scope. + if (depth > 0) out << "}\n"; + visitChildren = false; + break; + } + case EOpPrototype: { + // Function declaration. + ASSERT(visit == PreVisit); + writeVariableType(node->getType()); + out << " " << node->getName(); + + out << "("; + writeFunctionParameters(node->getSequence()); + out << ")"; + + visitChildren = false; + break; + } + case EOpFunction: { + // Function definition. + ASSERT(visit == PreVisit); + writeVariableType(node->getType()); + out << " " << TFunction::unmangleName(node->getName()); + + incrementDepth(); + // Function definition node contains one or two children nodes + // representing function parameters and function body. The latter + // is not present in case of empty function bodies. + const TIntermSequence& sequence = node->getSequence(); + ASSERT((sequence.size() == 1) || (sequence.size() == 2)); + TIntermSequence::const_iterator seqIter = sequence.begin(); + + // Traverse function parameters. + TIntermAggregate* params = (*seqIter)->getAsAggregate(); + ASSERT(params != NULL); + ASSERT(params->getOp() == EOpParameters); + params->traverse(this); + + // Traverse function body. + TIntermAggregate* body = ++seqIter != sequence.end() ? + (*seqIter)->getAsAggregate() : NULL; + visitCodeBlock(body); + decrementDepth(); + + // Fully processed; no need to visit children. + visitChildren = false; + break; + } + case EOpFunctionCall: + // Function call. + if (visit == PreVisit) + { + TString functionName = TFunction::unmangleName(node->getName()); + out << functionName << "("; + } + else if (visit == InVisit) + { + out << ", "; + } + else + { + out << ")"; + } + break; + case EOpParameters: { + // Function parameters. + ASSERT(visit == PreVisit); + out << "("; + writeFunctionParameters(node->getSequence()); + out << ")"; + visitChildren = false; + break; + } + case EOpDeclaration: { + // Variable declaration. + if (visit == PreVisit) + { + const TIntermSequence& sequence = node->getSequence(); + const TIntermTyped* variable = sequence.front()->getAsTyped(); + writeVariableType(variable->getType()); + out << " "; + mDeclaringVariables = true; + } + else if (visit == InVisit) + { + out << ", "; + mDeclaringVariables = true; + } + else + { + mDeclaringVariables = false; + } + break; + } + case EOpConstructFloat: writeTriplet(visit, "float(", NULL, ")"); break; + case EOpConstructVec2: writeTriplet(visit, "vec2(", ", ", ")"); break; + case EOpConstructVec3: writeTriplet(visit, "vec3(", ", ", ")"); break; + case EOpConstructVec4: writeTriplet(visit, "vec4(", ", ", ")"); break; + case EOpConstructBool: writeTriplet(visit, "bool(", NULL, ")"); break; + case EOpConstructBVec2: writeTriplet(visit, "bvec2(", ", ", ")"); break; + case EOpConstructBVec3: writeTriplet(visit, "bvec3(", ", ", ")"); break; + case EOpConstructBVec4: writeTriplet(visit, "bvec4(", ", ", ")"); break; + case EOpConstructInt: writeTriplet(visit, "int(", NULL, ")"); break; + case EOpConstructIVec2: writeTriplet(visit, "ivec2(", ", ", ")"); break; + case EOpConstructIVec3: writeTriplet(visit, "ivec3(", ", ", ")"); break; + case EOpConstructIVec4: writeTriplet(visit, "ivec4(", ", ", ")"); break; + case EOpConstructMat2: writeTriplet(visit, "mat2(", ", ", ")"); break; + case EOpConstructMat3: writeTriplet(visit, "mat3(", ", ", ")"); break; + case EOpConstructMat4: writeTriplet(visit, "mat4(", ", ", ")"); break; + case EOpConstructStruct: + if (visit == PreVisit) + { + const TType& type = node->getType(); + ASSERT(type.getBasicType() == EbtStruct); + out << type.getTypeName() << "("; + } + else if (visit == InVisit) + { + out << ", "; + } + else + { + out << ")"; + } + break; + + case EOpLessThan: preString = "lessThan("; delayedWrite = true; break; + case EOpGreaterThan: preString = "greaterThan("; delayedWrite = true; break; + case EOpLessThanEqual: preString = "lessThanEqual("; delayedWrite = true; break; + case EOpGreaterThanEqual: preString = "greaterThanEqual("; delayedWrite = true; break; + case EOpVectorEqual: preString = "equal("; delayedWrite = true; break; + case EOpVectorNotEqual: preString = "notEqual("; delayedWrite = true; break; + case EOpComma: writeTriplet(visit, NULL, ", ", NULL); break; + + case EOpMod: preString = "mod("; delayedWrite = true; break; + case EOpPow: preString = "pow("; delayedWrite = true; break; + case EOpAtan: preString = "atan("; delayedWrite = true; break; + case EOpMin: preString = "min("; delayedWrite = true; break; + case EOpMax: preString = "max("; delayedWrite = true; break; + case EOpClamp: preString = "clamp("; delayedWrite = true; break; + case EOpMix: preString = "mix("; delayedWrite = true; break; + case EOpStep: preString = "step("; delayedWrite = true; break; + case EOpSmoothStep: preString = "smoothstep("; delayedWrite = true; break; + + case EOpDistance: preString = "distance("; delayedWrite = true; break; + case EOpDot: preString = "dot("; delayedWrite = true; break; + case EOpCross: preString = "cross("; delayedWrite = true; break; + case EOpFaceForward: preString = "faceforward("; delayedWrite = true; break; + case EOpReflect: preString = "reflect("; delayedWrite = true; break; + case EOpRefract: preString = "refract("; delayedWrite = true; break; + case EOpMul: preString = "matrixCompMult("; delayedWrite = true; break; + + default: UNREACHABLE(); break; + } + if (delayedWrite && visit == PreVisit && node->getUseEmulatedFunction()) + preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString); + if (delayedWrite) + writeTriplet(visit, preString.c_str(), ", ", ")"); + return visitChildren; +} + +bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node) +{ + TInfoSinkBase& out = objSink(); + + incrementDepth(); + // Loop header. + TLoopType loopType = node->getType(); + if (loopType == ELoopFor) // for loop + { + if (!node->getUnrollFlag()) { + out << "for ("; + if (node->getInit()) + node->getInit()->traverse(this); + out << "; "; + + if (node->getCondition()) + node->getCondition()->traverse(this); + out << "; "; + + 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"; + } + + // Loop body. + if (node->getUnrollFlag()) + { + TLoopIndexInfo indexInfo; + mLoopUnroll.FillLoopIndexInfo(node, indexInfo); + mLoopUnroll.Push(indexInfo); + while (mLoopUnroll.SatisfiesLoopCondition()) + { + visitCodeBlock(node->getBody()); + mLoopUnroll.Step(); + } + mLoopUnroll.Pop(); + } + else + { + visitCodeBlock(node->getBody()); + } + + // Loop footer. + if (loopType == ELoopDoWhile) // do-while loop + { + out << "while ("; + ASSERT(node->getCondition() != NULL); + node->getCondition()->traverse(this); + out << ");\n"; + } + decrementDepth(); + + // No need to visit children. They have been already processed in + // this function. + return false; +} + +bool TOutputGLSLBase::visitBranch(Visit visit, TIntermBranch* node) +{ + switch (node->getFlowOp()) + { + case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break; + case EOpBreak: writeTriplet(visit, "break", NULL, NULL); break; + case EOpContinue: writeTriplet(visit, "continue", NULL, NULL); break; + case EOpReturn: writeTriplet(visit, "return ", NULL, NULL); break; + default: UNREACHABLE(); break; + } + + return true; +} + +void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) { + TInfoSinkBase &out = objSink(); + if (node != NULL) + { + node->traverse(this); + // Single statements not part of a sequence need to be terminated + // with semi-colon. + if (isSingleStatement(node)) + out << ";\n"; + } + else + { + out << "{\n}\n"; // Empty code block. + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.h b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.h new file mode 100644 index 0000000..35f20a7 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputGLSLBase.h @@ -0,0 +1,54 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ +#define CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ + +#include <set> + +#include "compiler/ForLoopUnroll.h" +#include "compiler/intermediate.h" +#include "compiler/ParseHelper.h" + +class TOutputGLSLBase : public TIntermTraverser +{ +public: + TOutputGLSLBase(TInfoSinkBase& objSink); + virtual ~TOutputGLSLBase() {} + +protected: + TInfoSinkBase& objSink() { return mObjSink; } + void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr); + void writeVariableType(const TType& type); + virtual bool writeVariablePrecision(TPrecision precision) = 0; + void writeFunctionParameters(const TIntermSequence& args); + const ConstantUnion* writeConstantUnion(const TType& type, const ConstantUnion* pConstUnion); + + virtual void visitSymbol(TIntermSymbol* node); + virtual void visitConstantUnion(TIntermConstantUnion* node); + virtual bool visitBinary(Visit visit, TIntermBinary* node); + virtual bool visitUnary(Visit visit, TIntermUnary* node); + virtual bool visitSelection(Visit visit, TIntermSelection* node); + virtual bool visitAggregate(Visit visit, TIntermAggregate* node); + virtual bool visitLoop(Visit visit, TIntermLoop* node); + virtual bool visitBranch(Visit visit, TIntermBranch* node); + + void visitCodeBlock(TIntermNode* node); + +private: + TInfoSinkBase& mObjSink; + bool mDeclaringVariables; + + // Structs are declared as the tree is traversed. This set contains all + // the structs already declared. It is maintained so that a struct is + // declared only once. + typedef std::set<TString> DeclaredStructs; + DeclaredStructs mDeclaredStructs; + + ForLoopUnroll mLoopUnroll; +}; + +#endif // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp index 57e99d2..69b8c26 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -33,8 +33,11 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr mUsesTexture2D_bias = false; mUsesTexture2DProj = false; mUsesTexture2DProj_bias = false; + mUsesTexture2DProjLod = false; + mUsesTexture2DLod = false; mUsesTextureCube = false; mUsesTextureCube_bias = false; + mUsesTextureCubeLod = false; mUsesDepthRange = false; mUsesFragCoord = false; mUsesPointCoord = false; @@ -42,9 +45,12 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr mUsesPointSize = false; mUsesXor = false; mUsesMod1 = false; - mUsesMod2 = false; - mUsesMod3 = false; - mUsesMod4 = false; + mUsesMod2v = false; + mUsesMod2f = false; + mUsesMod3v = false; + mUsesMod3f = false; + mUsesMod4v = false; + mUsesMod4f = false; mUsesFaceforward1 = false; mUsesFaceforward2 = false; mUsesFaceforward3 = false; @@ -61,7 +67,10 @@ OutputHLSL::OutputHLSL(TParseContext &context) : TIntermTraverser(true, true, tr mUsesEqualBVec2 = false; mUsesEqualBVec3 = false; mUsesEqualBVec4 = false; - mUsesAtan2 = false; + mUsesAtan2_1 = false; + mUsesAtan2_2 = false; + mUsesAtan2_3 = false; + mUsesAtan2_4 = false; mScopeDepth = 0; @@ -133,7 +142,7 @@ void OutputHLSL::header() { if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end()) { - uniforms += "uniform " + typeString(type) + " " + decorate(name) + arrayString(type) + ";\n"; + uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) + ";\n"; } } else if (qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn) @@ -182,7 +191,7 @@ void OutputHLSL::header() if (mUsesFragCoord) { - out << "uniform float4 dx_Viewport;\n" + out << "uniform float4 dx_Coord;\n" "uniform float2 dx_Depth;\n"; } @@ -196,11 +205,25 @@ void OutputHLSL::header() out << uniforms; out << "\n"; + // The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored + // according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0) + // is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D + // convention, the Y coordinate passed to these functions is adjusted to compensate. + // + // The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0]. + // + // The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3 + // case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0]. + // + // For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the + // +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the + // +Y and -Y faces everywhere else throughout the code. + if (mUsesTexture2D) { out << "float4 gl_texture2D(sampler2D s, float2 t)\n" "{\n" - " return tex2D(s, t);\n" + " return tex2D(s, float2(t.x, 1 - t.y));\n" "}\n" "\n"; } @@ -209,7 +232,7 @@ void OutputHLSL::header() { out << "float4 gl_texture2D(sampler2D s, float2 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n" + " return tex2Dbias(s, float4(t.x, 1 - t.y, 0, bias));\n" "}\n" "\n"; } @@ -218,12 +241,12 @@ void OutputHLSL::header() { out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" "{\n" - " return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n" + " return tex2Dproj(s, float4(t.x, t.z - t.y, 0, t.z));\n" "}\n" "\n" "float4 gl_texture2DProj(sampler2D s, float4 t)\n" "{\n" - " return tex2Dproj(s, t);\n" + " return tex2Dproj(s, float4(t.x, t.w - t.y, t.z, t.w));\n" "}\n" "\n"; } @@ -232,12 +255,12 @@ void OutputHLSL::header() { out << "float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n" + " return tex2Dbias(s, float4(t.x / t.z, 1 - (t.y / t.z), 0, bias));\n" "}\n" "\n" "float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n" "{\n" - " return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n" + " return tex2Dbias(s, float4(t.x / t.w, 1 - (t.y / t.w), 0, bias));\n" "}\n" "\n"; } @@ -246,7 +269,7 @@ void OutputHLSL::header() { out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" "{\n" - " return texCUBE(s, t);\n" + " return texCUBE(s, float3(t.x, -t.y, t.z));\n" "}\n" "\n"; } @@ -255,7 +278,7 @@ void OutputHLSL::header() { out << "float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n" "{\n" - " return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n" + " return texCUBEbias(s, float4(t.x, -t.y, t.z, bias));\n" "}\n" "\n"; } @@ -283,7 +306,7 @@ void OutputHLSL::header() { if (mReferencedUniforms.find(name.c_str()) != mReferencedUniforms.end()) { - uniforms += "uniform " + typeString(type) + " " + decorate(name) + arrayString(type) + ";\n"; + uniforms += "uniform " + typeString(type) + " " + decorateUniform(name, type) + arrayString(type) + ";\n"; } } else if (qualifier == EvqAttribute) @@ -331,6 +354,84 @@ void OutputHLSL::header() "\n"; out << uniforms; out << "\n"; + + // The texture fetch functions "flip" the Y coordinate in one way or another. This is because textures are stored + // according to the OpenGL convention, i.e. (0, 0) is "bottom left", rather than the D3D convention where (0, 0) + // is "top left". Since the HLSL texture fetch functions expect textures to be stored according to the D3D + // convention, the Y coordinate passed to these functions is adjusted to compensate. + // + // The simplest case is texture2D where the mapping is Y -> 1-Y, which maps [0, 1] -> [1, 0]. + // + // The texture2DProj functions are more complicated because the projection divides by either Z or W. For the vec3 + // case, the mapping is Y -> Z-Y or Y/Z -> 1-Y/Z, which again maps [0, 1] -> [1, 0]. + // + // For cube textures the mapping is Y -> -Y, which maps [-1, 1] -> [1, -1]. This is not sufficient on its own for the + // +Y and -Y faces, which are now on the "wrong sides" of the cube. This is compensated for by exchanging the + // +Y and -Y faces everywhere else throughout the code. + + if (mUsesTexture2D) + { + out << "float4 gl_texture2D(sampler2D s, float2 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x, 1 - t.y, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DLod) + { + out << "float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n" + "{\n" + " return tex2Dlod(s, float4(t.x, 1 - t.y, 0, lod));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DProj) + { + out << "float4 gl_texture2DProj(sampler2D s, float3 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, 0));\n" + "}\n" + "\n" + "float4 gl_texture2DProj(sampler2D s, float4 t)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTexture2DProjLod) + { + out << "float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.z, 1 - t.y / t.z, 0, lod));\n" + "}\n" + "\n" + "float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n" + "{\n" + " return tex2Dlod(s, float4(t.x / t.w, 1 - t.y / t.w, 0, lod));\n" + "}\n" + "\n"; + } + + if (mUsesTextureCube) + { + out << "float4 gl_textureCube(samplerCUBE s, float3 t)\n" + "{\n" + " return texCUBElod(s, float4(t.x, -t.y, t.z, 0));\n" + "}\n" + "\n"; + } + + if (mUsesTextureCubeLod) + { + out << "float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n" + "{\n" + " return texCUBElod(s, float4(t.x, -t.y, t.z, lod));\n" + "}\n" + "\n"; + } } if (mUsesFragCoord) @@ -384,8 +485,17 @@ void OutputHLSL::header() "}\n" "\n"; } - - if (mUsesMod2) + + if (mUsesMod2v) + { + out << "float2 mod(float2 x, float2 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod2f) { out << "float2 mod(float2 x, float y)\n" "{\n" @@ -394,7 +504,16 @@ void OutputHLSL::header() "\n"; } - if (mUsesMod3) + if (mUsesMod3v) + { + out << "float3 mod(float3 x, float3 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod3f) { out << "float3 mod(float3 x, float y)\n" "{\n" @@ -403,7 +522,16 @@ void OutputHLSL::header() "\n"; } - if (mUsesMod4) + if (mUsesMod4v) + { + out << "float4 mod(float4 x, float4 y)\n" + "{\n" + " return x - y * floor(x / y);\n" + "}\n" + "\n"; + } + + if (mUsesMod4f) { out << "float4 mod(float4 x, float y)\n" "{\n" @@ -578,7 +706,7 @@ void OutputHLSL::header() "}\n"; } - if (mUsesAtan2) + if (mUsesAtan2_1) { out << "float atanyx(float y, float x)\n" "{\n" @@ -586,6 +714,39 @@ void OutputHLSL::header() " return atan2(y, x);\n" "}\n"; } + + if (mUsesAtan2_2) + { + out << "float2 atanyx(float2 y, float2 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n" + "}\n"; + } + + if (mUsesAtan2_3) + { + out << "float3 atanyx(float3 y, float3 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n" + "}\n"; + } + + if (mUsesAtan2_4) + { + out << "float4 atanyx(float4 y, float4 x)\n" + "{\n" + " if(x[0] == 0 && y[0] == 0) x[0] = 1;\n" + " if(x[1] == 0 && y[1] == 0) x[1] = 1;\n" + " if(x[2] == 0 && y[2] == 0) x[2] = 1;\n" + " if(x[3] == 0 && y[3] == 0) x[3] = 1;\n" + " return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n" + "}\n"; + } } void OutputHLSL::visitSymbol(TIntermSymbol *node) @@ -634,17 +795,22 @@ void OutputHLSL::visitSymbol(TIntermSymbol *node) if (qualifier == EvqUniform) { mReferencedUniforms.insert(name.c_str()); + out << decorateUniform(name, node->getType()); } else if (qualifier == EvqAttribute) { mReferencedAttributes.insert(name.c_str()); + out << decorate(name); } else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn) { mReferencedVaryings.insert(name.c_str()); + out << decorate(name); + } + else + { + out << decorate(name); } - - out << decorate(name); } } @@ -902,8 +1068,6 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) { - TInfoSinkBase &out = mBody; - switch (node->getOp()) { case EOpNegative: outputTriplet(visit, "(-", "", ")"); break; @@ -968,7 +1132,7 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) case EOpLength: outputTriplet(visit, "length(", "", ")"); break; case EOpNormalize: outputTriplet(visit, "normalize(", "", ")"); break; case EOpDFdx: outputTriplet(visit, "ddx(", "", ")"); break; - case EOpDFdy: outputTriplet(visit, "ddy(", "", ")"); 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; @@ -980,7 +1144,6 @@ bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node) bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { - ShShaderType shaderType = mContext.shaderType; TInfoSinkBase &out = mBody; switch (node->getOp()) @@ -989,6 +1152,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) { if (mInsideFunction) { + outputLineDirective(node->getLine()); out << "{\n"; mScopeDepth++; @@ -1005,6 +1169,8 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) for (TIntermSequence::iterator sit = node->getSequence().begin(); sit != node->getSequence().end(); sit++) { + outputLineDirective((*sit)->getLine()); + if (isSingleStatement(*sit)) { mUnfoldSelect->traverse(*sit); @@ -1017,6 +1183,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) if (mInsideFunction) { + outputLineDirective(node->getEndLine()); out << "}\n"; mScopeDepth--; @@ -1118,7 +1285,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) return false; } break; - case EOpComma: outputTriplet(visit, "", ", ", ""); break; + case EOpComma: outputTriplet(visit, "(", ", ", ")"); break; case EOpFunction: { TString name = TFunction::unmangleName(node->getName()); @@ -1145,6 +1312,11 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) if (symbol) { + if (symbol->getType().getStruct()) + { + addConstructor(symbol->getType(), scopedStruct(symbol->getType().getTypeName()), NULL); + } + out << argumentString(symbol); if (i < arguments.size() - 1) @@ -1157,13 +1329,16 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) sequence.erase(sequence.begin()); - out << ")\n" - "{\n"; - + out << ")\n"; + + outputLineDirective(node->getLine()); + out << "{\n"; + mInsideFunction = true; } else if (visit == PostVisit) { + outputLineDirective(node->getEndLine()); out << "}\n"; mInsideFunction = false; @@ -1226,15 +1401,33 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) } else if (name == "texture2DLod") { - UNIMPLEMENTED(); // Requires the vertex shader texture sampling extension + if (node->getSequence().size() == 3) + { + mUsesTexture2DLod = true; + } + else UNREACHABLE(); + + out << "gl_texture2DLod("; } else if (name == "texture2DProjLod") { - UNIMPLEMENTED(); // Requires the vertex shader texture sampling extension + if (node->getSequence().size() == 3) + { + mUsesTexture2DProjLod = true; + } + else UNREACHABLE(); + + out << "gl_texture2DProjLod("; } else if (name == "textureCubeLod") { - UNIMPLEMENTED(); // Requires the vertex shader texture sampling extension + if (node->getSequence().size() == 3) + { + mUsesTextureCubeLod = true; + } + else UNREACHABLE(); + + out << "gl_textureCubeLod("; } else UNREACHABLE(); } @@ -1322,12 +1515,17 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break; case EOpMod: { - switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument + // We need to look at the number of components in both arguments + switch (node->getSequence()[0]->getAsTyped()->getNominalSize() * 10 + + node->getSequence()[1]->getAsTyped()->getNominalSize()) { - case 1: mUsesMod1 = true; break; - case 2: mUsesMod2 = true; break; - case 3: mUsesMod3 = true; break; - case 4: mUsesMod4 = true; break; + case 11: mUsesMod1 = true; break; + case 22: mUsesMod2v = true; break; + case 21: mUsesMod2f = true; break; + case 33: mUsesMod3v = true; break; + case 31: mUsesMod3f = true; break; + case 44: mUsesMod4v = true; break; + case 41: mUsesMod4f = true; break; default: UNREACHABLE(); } @@ -1337,7 +1535,14 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) case EOpPow: outputTriplet(visit, "pow(", ", ", ")"); break; case EOpAtan: ASSERT(node->getSequence().size() == 2); // atan(x) is a unary operator - mUsesAtan2 = true; + switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) + { + case 1: mUsesAtan2_1 = true; break; + case 2: mUsesAtan2_2 = true; break; + case 3: mUsesAtan2_3 = true; break; + case 4: mUsesAtan2_4 = true; break; + default: UNREACHABLE(); + } outputTriplet(visit, "atanyx(", ", ", ")"); break; case EOpMin: outputTriplet(visit, "min(", ", ", ")"); break; @@ -1378,7 +1583,7 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) if (node->usesTernaryOperator()) { - out << "t" << mUnfoldSelect->getTemporaryIndex(); + out << "s" << mUnfoldSelect->getNextTemporaryIndex(); } else // if/else statement { @@ -1388,23 +1593,30 @@ bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node) node->getCondition()->traverse(this); - out << ")\n" - "{\n"; + out << ")\n"; + + outputLineDirective(node->getLine()); + out << "{\n"; if (node->getTrueBlock()) { node->getTrueBlock()->traverse(this); } + outputLineDirective(node->getLine()); out << ";}\n"; if (node->getFalseBlock()) { - out << "else\n" - "{\n"; + out << "else\n"; + + outputLineDirective(node->getFalseBlock()->getLine()); + out << "{\n"; + outputLineDirective(node->getFalseBlock()->getLine()); node->getFalseBlock()->traverse(this); + outputLineDirective(node->getFalseBlock()->getLine()); out << ";}\n"; } } @@ -1428,27 +1640,14 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) if (node->getType() == ELoopDoWhile) { - out << "do\n" - "{\n"; + out << "{do\n"; + + outputLineDirective(node->getLine()); + out << "{\n"; } else { - if (node->getInit()) - { - mUnfoldSelect->traverse(node->getInit()); - } - - if (node->getCondition()) - { - mUnfoldSelect->traverse(node->getCondition()); - } - - if (node->getExpression()) - { - mUnfoldSelect->traverse(node->getExpression()); - } - - out << "for("; + out << "{for("; if (node->getInit()) { @@ -1469,8 +1668,10 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) node->getExpression()->traverse(this); } - out << ")\n" - "{\n"; + out << ")\n"; + + outputLineDirective(node->getLine()); + out << "{\n"; } if (node->getBody()) @@ -1478,18 +1679,20 @@ bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node) node->getBody()->traverse(this); } - out << "}\n"; + outputLineDirective(node->getLine()); + out << ";}\n"; if (node->getType() == ELoopDoWhile) { + outputLineDirective(node->getCondition()->getLine()); out << "while(\n"; node->getCondition()->traverse(this); - out << ")"; + out << ");"; } - out << ";\n"; + out << "}\n"; return false; } @@ -1500,9 +1703,9 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) switch (node->getFlowOp()) { - case EOpKill: outputTriplet(visit, "discard", "", ""); break; - case EOpBreak: outputTriplet(visit, "break", "", ""); break; - case EOpContinue: outputTriplet(visit, "continue", "", ""); break; + case EOpKill: outputTriplet(visit, "discard;\n", "", ""); break; + case EOpBreak: outputTriplet(visit, "break;\n", "", ""); break; + case EOpContinue: outputTriplet(visit, "continue;\n", "", ""); break; case EOpReturn: if (visit == PreVisit) { @@ -1517,7 +1720,10 @@ bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node) } else if (visit == PostVisit) { - out << ";\n"; + if (node->getExpression()) + { + out << ";\n"; + } } break; default: UNREACHABLE(); @@ -1669,7 +1875,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) if (comparator == EOpLessThan) { - int iterations = (limit - initial + 1) / increment; + int iterations = (limit - initial) / increment; if (iterations <= 255) { @@ -1678,8 +1884,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) while (iterations > 0) { - int remainder = (limit - initial + 1) % increment; - int clampedLimit = initial + increment * std::min(255, iterations) - 1 - remainder; + int clampedLimit = initial + increment * std::min(255, iterations); // for(int index = initial; index < clampedLimit; index += increment) @@ -1697,15 +1902,18 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node) index->traverse(this); out << " += "; out << increment; - out << ")\n" - "{\n"; + out << ")\n"; + + outputLineDirective(node->getLine()); + out << "{\n"; if (node->getBody()) { node->getBody()->traverse(this); } - out << "}\n"; + outputLineDirective(node->getLine()); + out << ";}\n"; initial += 255 * increment; iterations -= 255; @@ -1737,6 +1945,22 @@ void OutputHLSL::outputTriplet(Visit visit, const TString &preString, const TStr } } +void OutputHLSL::outputLineDirective(int line) +{ + if ((mContext.compileOptions & SH_LINE_DIRECTIVES) && (line > 0)) + { + mBody << "\n"; + mBody << "#line " << line; + + if (mContext.sourcePath) + { + mBody << " \"" << mContext.sourcePath << "\""; + } + + mBody << "\n"; + } +} + TString OutputHLSL::argumentString(const TIntermSymbol *symbol) { TQualifier qualifier = symbol->getQualifier(); @@ -1839,6 +2063,8 @@ TString OutputHLSL::typeString(const TType &type) return "sampler2D"; case EbtSamplerCube: return "samplerCUBE"; + case EbtSamplerExternalOES: + return "sampler2D"; } } @@ -1880,6 +2106,11 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI return; // Nameless structures don't have constructors } + if (type.getStruct() && mStructNames.find(decorate(name)) != mStructNames.end()) + { + return; // Already added + } + TType ctorType = type; ctorType.clearArrayness(); ctorType.setPrecision(EbpHigh); @@ -1890,14 +2121,7 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI typedef std::vector<TType> ParameterArray; ParameterArray ctorParameters; - if (parameters) - { - for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) - { - ctorParameters.push_back((*parameter)->getAsTyped()->getType()); - } - } - else if (type.getStruct()) + if (type.getStruct()) { mStructNames.insert(decorate(name)); @@ -1926,6 +2150,13 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI ctorParameters.push_back(*fields[i].type); } } + else if (parameters) + { + for (TIntermSequence::const_iterator parameter = parameters->begin(); parameter != parameters->end(); parameter++) + { + ctorParameters.push_back((*parameter)->getAsTyped()->getType()); + } + } else UNREACHABLE(); TString constructor; @@ -2182,13 +2413,25 @@ TString OutputHLSL::structLookup(const TString &typeName) TString OutputHLSL::decorate(const TString &string) { - if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_") + if (string.compare(0, 3, "gl_") != 0 && string.compare(0, 3, "dx_") != 0) { return "_" + string; } - else + + return string; +} + +TString OutputHLSL::decorateUniform(const TString &string, const TType &type) +{ + if (type.isArray()) { - return string; + return "ar_" + string; // Allows identifying arrays of size 1 } + else if (type.getBasicType() == EbtSamplerExternalOES) + { + return "ex_" + string; + } + + return decorate(string); } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h index ddbd077..824bc07 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/OutputHLSL.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -31,7 +31,8 @@ class OutputHLSL : public TIntermTraverser static TString qualifierString(TQualifier qualifier); static TString arrayString(const TType &type); static TString initializer(const TType &type); - static TString decorate(const TString &string); // Prepend an underscore to avoid naming clashes + static TString decorate(const TString &string); // Prepends an underscore to avoid naming clashes + static TString decorateUniform(const TString &string, const TType &type); protected: void header(); @@ -49,6 +50,7 @@ class OutputHLSL : public TIntermTraverser bool isSingleStatement(TIntermNode *node); bool handleExcessiveLoop(TIntermLoop *node); void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString); + void outputLineDirective(int line); TString argumentString(const TIntermSymbol *symbol); int vectorSize(const TType &type) const; @@ -75,10 +77,13 @@ class OutputHLSL : public TIntermTraverser // Parameters determining what goes in the header output bool mUsesTexture2D; bool mUsesTexture2D_bias; + bool mUsesTexture2DLod; bool mUsesTexture2DProj; bool mUsesTexture2DProj_bias; + bool mUsesTexture2DProjLod; bool mUsesTextureCube; bool mUsesTextureCube_bias; + bool mUsesTextureCubeLod; bool mUsesDepthRange; bool mUsesFragCoord; bool mUsesPointCoord; @@ -86,9 +91,12 @@ class OutputHLSL : public TIntermTraverser bool mUsesPointSize; bool mUsesXor; bool mUsesMod1; - bool mUsesMod2; - bool mUsesMod3; - bool mUsesMod4; + bool mUsesMod2v; + bool mUsesMod2f; + bool mUsesMod3v; + bool mUsesMod3f; + bool mUsesMod4v; + bool mUsesMod4f; bool mUsesFaceforward1; bool mUsesFaceforward2; bool mUsesFaceforward3; @@ -105,7 +113,10 @@ class OutputHLSL : public TIntermTraverser bool mUsesEqualBVec2; bool mUsesEqualBVec3; bool mUsesEqualBVec4; - bool mUsesAtan2; + bool mUsesAtan2_1; + bool mUsesAtan2_2; + bool mUsesAtan2_3; + bool mUsesAtan2_4; typedef std::set<TString> Constructors; Constructors mConstructors; diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp index 53f3fa8..431f8d1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.cpp @@ -196,7 +196,6 @@ bool TParseContext::parseMatrixFields(const TString& compString, int matSize, TM // void TParseContext::recover() { - recoveredFromError = true; } // @@ -261,6 +260,8 @@ void TParseContext::binaryOpError(int line, const char* op, TString left, TStrin } bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicType type){ + if (!checksPrecisionErrors) + return false; switch( type ){ case EbtFloat: if( precision == EbpUndefined ){ @@ -274,6 +275,8 @@ bool TParseContext::precisionErrorCheck(int line, TPrecision precision, TBasicTy return true; } break; + default: + return false; } return false; } @@ -445,16 +448,16 @@ bool TParseContext::reservedErrorCheck(int line, const TString& identifier) { static const char* reservedErrMsg = "reserved built-in name"; if (!symbolTable.atBuiltInLevel()) { - if (identifier.substr(0, 3) == TString("gl_")) { + if (identifier.compare(0, 3, "gl_") == 0) { error(line, reservedErrMsg, "gl_", ""); return true; } if (shaderSpec == SH_WEBGL_SPEC) { - if (identifier.substr(0, 6) == TString("webgl_")) { + if (identifier.compare(0, 6, "webgl_") == 0) { error(line, reservedErrMsg, "webgl_", ""); return true; } - if (identifier.substr(0, 7) == TString("_webgl_")) { + if (identifier.compare(0, 7, "_webgl_") == 0) { error(line, reservedErrMsg, "_webgl_", ""); return true; } @@ -550,7 +553,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction return true; } - if (!type->isMatrix()) { + if (!type->isMatrix() || !matrixInMatrix) { if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) || (op == EOpConstructStruct && size < type->getObjectSize())) { error(line, "not enough data provided for construction", "constructor", ""); @@ -558,7 +561,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction } } - TIntermTyped* typed = node->getAsTyped(); + TIntermTyped *typed = node ? node->getAsTyped() : 0; if (typed == 0) { error(line, "constructor argument does not have a type", "constructor", ""); return true; @@ -880,16 +883,17 @@ bool TParseContext::nonInitConstErrorCheck(int line, TString& identifier, TPubli // // Returns true if there was an error. // -bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type) +bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable) { if (reservedErrorCheck(line, identifier)) recover(); - TVariable* variable = new TVariable(&identifier, TType(type)); + variable = new TVariable(&identifier, TType(type)); if (! symbolTable.insert(*variable)) { error(line, "redefinition", variable->getName().c_str(), ""); delete variable; + variable = 0; return true; } @@ -925,7 +929,8 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) error(line, "extension", extension.c_str(), "is not supported"); return true; } - if (iter->second == EBhDisable) { + // In GLSL ES, an extension's default behavior is "disable". + if (iter->second == EBhDisable || iter->second == EBhUndefined) { error(line, "extension", extension.c_str(), "is disabled"); return true; } @@ -938,6 +943,12 @@ bool TParseContext::extensionErrorCheck(int line, const TString& extension) return false; } +bool TParseContext::supportsExtension(const char* extension) +{ + TExtensionBehavior::const_iterator iter = extensionBehavior.find(extension); + return (iter != extensionBehavior.end()); +} + ///////////////////////////////////////////////////////////////////////////////// // // Non-Errors. @@ -1414,6 +1425,53 @@ TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* n return typedNode; } +bool TParseContext::enterStructDeclaration(int line, const TString& identifier) +{ + ++structNestingLevel; + + // Embedded structure definitions are not supported per GLSL ES spec. + // They aren't allowed in GLSL either, but we need to detect this here + // so we don't rely on the GLSL compiler to catch it. + if (structNestingLevel > 1) { + error(line, "", "Embedded struct definitions are not allowed", ""); + return true; + } + + return false; +} + +void TParseContext::exitStructDeclaration() +{ + --structNestingLevel; +} + +namespace { + +const int kWebGLMaxStructNesting = 4; + +} // namespace + +bool TParseContext::structNestingErrorCheck(TSourceLoc line, const TType& fieldType) +{ + if (shaderSpec != SH_WEBGL_SPEC) { + return false; + } + + if (fieldType.getBasicType() != EbtStruct) { + return false; + } + + // We're already inside a structure definition at this point, so add + // one to the field's struct nesting. + if (1 + fieldType.getDeepestStructNesting() > kWebGLMaxStructNesting) { + error(line, "", "", "Reference of struct type %s exceeds maximum struct nesting of %d", + fieldType.getTypeName().c_str(), kWebGLMaxStructNesting); + return true; + } + + return false; +} + // // Parse an array of strings using yyparse. // diff --git a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h index cb6e0d0..3e05763 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ParseHelper.h @@ -30,34 +30,58 @@ struct TPragma { // they can be passed to the parser without needing a global. // struct TParseContext { - 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), scanner(NULL), contextPragma(true, false) { } + TParseContext(TSymbolTable& symt, TExtensionBehavior& ext, TIntermediate& interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink& is) : + intermediate(interm), + symbolTable(symt), + extensionBehavior(ext), + infoSink(is), + shaderType(type), + shaderSpec(spec), + compileOptions(options), + sourcePath(sourcePath), + treeRoot(0), + numErrors(0), + lexAfterType(false), + loopNestingLevel(0), + structNestingLevel(0), + inTypeParen(false), + currentFunctionType(NULL), + functionReturnsValue(false), + checksPrecisionErrors(checksPrecErrors), + contextPragma(true, false), + scanner(NULL) { } 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. + TExtensionBehavior& extensionBehavior; // mapping between supported extensions and current behavior. TInfoSink& infoSink; ShShaderType shaderType; // vertex or fragment language (future: pack or unpack) ShShaderSpec shaderSpec; // The language specification compiler conforms to - GLES2 or WebGL. + int compileOptions; + const char* sourcePath; // Path of source file or NULL. TIntermNode* treeRoot; // root of parse tree being created - bool recoveredFromError; // true if a parse error has occurred, but we continue to parse int numErrors; bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier int loopNestingLevel; // 0 if outside all loops + int structNestingLevel; // incremented while parsing a struct declaration 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 + bool checksPrecisionErrors; // true if an error will be generated when a variable is declared without precision, explicit or implicit. + struct TPragma contextPragma; + TString HashErrMsg; + bool AfterEOF; + void* scanner; 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(); bool parseVectorFields(const TString&, int vecSize, TVectorFields&, int line); bool parseMatrixFields(const TString&, int matSize, TMatrixFields&, int line); + + bool reservedErrorCheck(int line, const TString& identifier); void assignError(int line, const char* op, TString left, TString right); void unaryOpError(int line, const char* op, TString operand); void binaryOpError(int line, const char* op, TString left, TString right); @@ -77,15 +101,19 @@ struct TParseContext { bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); bool structQualifierErrorCheck(int line, const TPublicType& pType); bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type); - bool containsSampler(TType& type); bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type); - bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type); + bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type, TVariable*& variable); bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool extensionErrorCheck(int line, const TString&); + bool supportsExtension(const char* extension); + + bool containsSampler(TType& type); + bool areAllChildConst(TIntermAggregate* aggrNode); 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); - bool areAllChildConst(TIntermAggregate* aggrNode); + bool arraySetMaxSize(TIntermSymbol*, TType*, int, bool, TSourceLoc); + TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, TSourceLoc); TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType& type); TIntermTyped* constructStruct(TIntermNode*, TType*, int, TSourceLoc, bool subset); @@ -94,11 +122,14 @@ struct TParseContext { TIntermTyped* addConstMatrixNode(int , TIntermTyped*, TSourceLoc); 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; + + // Performs an error check for embedded struct declarations. + // Returns true if an error was raised due to the declaration of + // this struct. + bool enterStructDeclaration(TSourceLoc line, const TString& identifier); + void exitStructDeclaration(); + + bool structNestingErrorCheck(TSourceLoc line, const TType& fieldType); }; int PaParseStrings(int count, const char* const string[], const int length[], diff --git a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp index 93e21e4..a600c02 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.cpp @@ -151,16 +151,23 @@ const unsigned char TAllocation::userDataFill = 0xcd; // void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const { +#ifdef GUARD_BLOCKS for (size_t x = 0; x < guardBlockSize; x++) { if (blockMem[x] != val) { char assertMsg[80]; // We don't print the assert message. It's here just to be helpful. - sprintf(assertMsg, "PoolAlloc: Damage %s %u byte allocation at 0x%p\n", +#if defined(_MSC_VER) + sprintf(assertMsg, "PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n", + locText, size, data()); +#else + sprintf(assertMsg, "PoolAlloc: Damage %s %zu byte allocation at 0x%p\n", locText, size, data()); +#endif assert(0 && "PoolAlloc: Damage in guard block"); } } +#endif } @@ -299,4 +306,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 051dc00..a8a59c6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h +++ b/Source/ThirdParty/ANGLE/src/compiler/PoolAlloc.h @@ -253,12 +253,18 @@ public: pointer address(reference x) const { return &x; } const_pointer address(const_reference x) const { return &x; } - pool_allocator() : allocator(GlobalPoolAllocator) { } - pool_allocator(TPoolAllocator& a) : allocator(a) { } + pool_allocator() : allocator(&GlobalPoolAllocator) { } + pool_allocator(TPoolAllocator& a) : allocator(&a) { } pool_allocator(const pool_allocator<T>& p) : allocator(p.allocator) { } + template <class Other> + pool_allocator<T>& operator=(const pool_allocator<Other>& p) { + allocator = p.allocator; + return *this; + } + template<class Other> - pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { } + pool_allocator(const pool_allocator<Other>& p) : allocator(&p.getAllocator()) { } #if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR) // libCStd on some platforms have a different allocate/deallocate interface. @@ -290,11 +296,11 @@ public: size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); } size_type max_size(int size) const { return static_cast<size_type>(-1) / size; } - void setAllocator(TPoolAllocator* a) { allocator = *a; } - TPoolAllocator& getAllocator() const { return allocator; } + void setAllocator(TPoolAllocator* a) { allocator = a; } + TPoolAllocator& getAllocator() const { return *allocator; } protected: - TPoolAllocator& allocator; + TPoolAllocator* allocator; }; -#endif // _POOLALLOC_INCLUDED_
\ No newline at end of file +#endif // _POOLALLOC_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h index e65c1ee..91c47e7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ShHandle.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -16,11 +16,13 @@ #include "GLSLANG/ShaderLang.h" +#include "compiler/BuiltInFunctionEmulator.h" #include "compiler/ExtensionBehavior.h" #include "compiler/InfoSink.h" #include "compiler/SymbolTable.h" #include "compiler/VariableInfo.h" +class LongNameMap; class TCompiler; // @@ -57,6 +59,7 @@ public: TInfoSink& getInfoSink() { return infoSink; } const TVariableInfoList& getAttribs() const { return attribs; } const TVariableInfoList& getUniforms() const { return uniforms; } + int getMappedNameMaxLength() const; protected: ShShaderType getShaderType() const { return shaderType; } @@ -65,13 +68,21 @@ protected: bool InitBuiltInSymbolTable(const ShBuiltInResources& resources); // Clears the results from the previous compilation. void clearResults(); + // Return true if function recursion is detected. + bool detectRecursion(TIntermNode* root); // 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); + // Map long variable names into shorter ones. + void mapLongVariableNames(TIntermNode* root); // Translate to object code. virtual void translate(TIntermNode* root) = 0; + // Get built-in extensions with default behavior. + const TExtensionBehavior& getExtensionBehavior() const; + + const BuiltInFunctionEmulator& getBuiltInFunctionEmulator() const; private: ShShaderType shaderType; @@ -83,10 +94,15 @@ private: // Built-in extensions with default behavior. TExtensionBehavior extensionBehavior; + BuiltInFunctionEmulator builtInFunctionEmulator; + // Results of compilation. TInfoSink infoSink; // Output sink. TVariableInfoList attribs; // Active attributes in the compiled shader. TVariableInfoList uniforms; // Active uniforms in the compiled shader. + + // Cached copy of the ref-counted singleton. + LongNameMap* longNameMap; }; // @@ -98,7 +114,8 @@ private: // destroy the machine dependent objects, which contain the // above machine independent information. // -TCompiler* ConstructCompiler(ShShaderType type, ShShaderSpec spec); +TCompiler* ConstructCompiler( + ShShaderType type, ShShaderSpec spec, ShShaderOutput output); void DeleteCompiler(TCompiler*); -#endif // _SHHANDLE_INCLUDED_
\ No newline at end of file +#endif // _SHHANDLE_INCLUDED_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp index 6cac61d..13f11b5 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ShaderLang.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -12,6 +12,7 @@ #include "GLSLANG/ShaderLang.h" #include "compiler/InitializeDll.h" +#include "compiler/preprocessor/length_limits.h" #include "compiler/ShHandle.h" // @@ -19,16 +20,21 @@ // and the shading language compiler. // -static int getVariableMaxLength(const TVariableInfoList& varList) +static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle, + int expectedValue) { - TString::size_type maxLen = 0; - for (TVariableInfoList::const_iterator i = varList.begin(); - i != varList.end(); ++i) - { - maxLen = std::max(maxLen, i->name.size()); - } - // Add 1 to include null-termination character. - return static_cast<int>(maxLen) + 1; + int activeUniformLimit = 0; + ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit); + int activeAttribLimit = 0; + ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit); + return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit); +} + +static bool checkMappedNameMaxLength(const ShHandle handle, int expectedValue) +{ + int mappedNameMaxLength = 0; + ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &mappedNameMaxLength); + return (expectedValue == mappedNameMaxLength); } static void getVariableInfo(ShShaderInfo varType, @@ -37,7 +43,8 @@ static void getVariableInfo(ShShaderInfo varType, int* length, int* size, ShDataType* type, - char* name) + char* name, + char* mappedName) { if (!handle || !size || !type || !name) return; @@ -58,7 +65,20 @@ static void getVariableInfo(ShShaderInfo varType, if (length) *length = varInfo.name.size(); *size = varInfo.size; *type = varInfo.type; - strcpy(name, varInfo.name.c_str()); + + // This size must match that queried by + // SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH + // in ShGetInfo, below. + int activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN; + ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength)); + strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength); + if (mappedName) { + // This size must match that queried by + // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below. + int maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN; + ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength)); + strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength); + } } // @@ -101,18 +121,21 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) // Extensions. resources->OES_standard_derivatives = 0; + resources->OES_EGL_image_external = 0; + resources->ARB_texture_rectangle = 0; } // // Driver calls these to create and destroy compiler objects. // ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec, + ShShaderOutput output, const ShBuiltInResources* resources) { if (!InitThread()) return 0; - TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec)); + TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(type, spec, output)); TCompiler* compiler = base->getAsCompiler(); if (compiler == 0) return 0; @@ -186,15 +209,19 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, int* params) *params = compiler->getUniforms().size(); break; case SH_ACTIVE_UNIFORM_MAX_LENGTH: - *params = getVariableMaxLength(compiler->getUniforms()); + *params = 1 + MAX_SYMBOL_NAME_LEN; break; case SH_ACTIVE_ATTRIBUTES: *params = compiler->getAttribs().size(); break; case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = getVariableMaxLength(compiler->getAttribs()); + *params = 1 + MAX_SYMBOL_NAME_LEN; + break; + case SH_MAPPED_NAME_MAX_LENGTH: + // Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to + // handle array and struct dereferences. + *params = 1 + MAX_SYMBOL_NAME_LEN; break; - default: UNREACHABLE(); } } @@ -236,10 +263,11 @@ void ShGetActiveAttrib(const ShHandle handle, int* length, int* size, ShDataType* type, - char* name) + char* name, + char* mappedName) { getVariableInfo(SH_ACTIVE_ATTRIBUTES, - handle, index, length, size, type, name); + handle, index, length, size, type, name, mappedName); } void ShGetActiveUniform(const ShHandle handle, @@ -247,8 +275,9 @@ void ShGetActiveUniform(const ShHandle handle, int* length, int* size, ShDataType* type, - char* name) + char* name, + char* mappedName) { getVariableInfo(SH_ACTIVE_UNIFORMS, - handle, index, length, size, type, name); + handle, index, length, size, type, name, mappedName); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp index 02817d4..edbea99 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.cpp @@ -9,10 +9,16 @@ // are documented in the header file. // +#if defined(_MSC_VER) +#pragma warning(disable: 4718) +#endif + #include "compiler/SymbolTable.h" #include <stdio.h> +#include <algorithm> + // // TType helper function needs a place to live. // @@ -71,6 +77,20 @@ int TType::getStructSize() const return structureSize; } +void TType::computeDeepestStructNesting() +{ + if (!getStruct()) { + return; + } + + int maxNesting = 0; + for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) { + maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting()); + } + + deepestStructNesting = 1 + maxNesting; +} + // // Dump functions. // diff --git a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h index 38bc657..33616dc 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h +++ b/Source/ThirdParty/ANGLE/src/compiler/SymbolTable.h @@ -302,6 +302,12 @@ public: assert(table.size() >= 2); return table[1]; } + + TSymbolTableLevel* getOuterLevel() { + assert(table.size() >= 2); + return table[currentLevel() - 1]; + } + void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp new file mode 100644 index 0000000..e3a2c2a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.cpp @@ -0,0 +1,40 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "compiler/TranslatorESSL.h" + +#include "compiler/OutputESSL.h" + +TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec) + : TCompiler(type, spec) { +} + +void TranslatorESSL::translate(TIntermNode* root) { + TInfoSinkBase& sink = getInfoSink().obj; + + // Write built-in extension behaviors. + writeExtensionBehavior(); + + // Write emulated built-in functions if needed. + getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition( + sink, getShaderType() == SH_FRAGMENT_SHADER); + + // Write translated shader. + TOutputESSL outputESSL(sink); + root->traverse(&outputESSL); +} + +void TranslatorESSL::writeExtensionBehavior() { + TInfoSinkBase& sink = getInfoSink().obj; + const TExtensionBehavior& extensionBehavior = getExtensionBehavior(); + for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin(); + iter != extensionBehavior.end(); ++iter) { + if (iter->second != EBhUndefined) { + sink << "#extension " << iter->first << " : " + << getBehaviorString(iter->second) << "\n"; + } + } +} diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.h b/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.h new file mode 100644 index 0000000..a1196bd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorESSL.h @@ -0,0 +1,23 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_TRANSLATORESSL_H_ +#define COMPILER_TRANSLATORESSL_H_ + +#include "compiler/ShHandle.h" + +class TranslatorESSL : public TCompiler { +public: + TranslatorESSL(ShShaderType type, ShShaderSpec spec); + +protected: + virtual void translate(TIntermNode* root); + +private: + void writeExtensionBehavior(); +}; + +#endif // COMPILER_TRANSLATORESSL_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp index 7a63ae1..bb07a1e 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/TranslatorGLSL.cpp @@ -31,6 +31,10 @@ void TranslatorGLSL::translate(TIntermNode* root) { // Write GLSL version. writeVersion(getShaderType(), root, sink); + // Write emulated built-in functions if needed. + getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition( + sink, false); + // Write translated shader. TOutputGLSL outputGLSL(sink); root->traverse(&outputGLSL); diff --git a/Source/ThirdParty/ANGLE/src/compiler/Types.h b/Source/ThirdParty/ANGLE/src/compiler/Types.h index d0fcc08..e1a18fd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/Types.h +++ b/Source/ThirdParty/ANGLE/src/compiler/Types.h @@ -85,21 +85,22 @@ 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), - maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0) + maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(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), - maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), fieldName(0), mangled(0), typeName(0) + maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0) { if (p.userDef) { structure = p.userDef->getStruct(); typeName = NewPoolTString(p.userDef->getTypeName().c_str()); + computeDeepestStructNesting(); } } TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) : type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), - maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), fieldName(0), mangled(0) + maxArraySize(0), arrayInformationType(0), structure(userDef), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0) { typeName = NewPoolTString(n.c_str()); } @@ -144,6 +145,7 @@ public: structureSize = copyOf.structureSize; maxArraySize = copyOf.maxArraySize; + deepestStructNesting = copyOf.deepestStructNesting; assert(copyOf.arrayInformationType == 0); arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level } @@ -202,7 +204,7 @@ public: bool isScalar() const { return size == 1 && !matrix && !structure; } TTypeList* getStruct() const { return structure; } - void setStruct(TTypeList* s) { structure = s; } + void setStruct(TTypeList* s) { structure = s; computeDeepestStructNesting(); } const TString& getTypeName() const { @@ -268,9 +270,24 @@ public: const char* getQualifierString() const { return ::getQualifierString(qualifier); } TString getCompleteString() const; + // If this type is a struct, returns the deepest struct nesting of + // any field in the struct. For example: + // struct nesting1 { + // vec4 position; + // }; + // struct nesting2 { + // nesting1 field1; + // vec4 field2; + // }; + // For type "nesting2", this method would return 2 -- the number + // of structures through which indirection must occur to reach the + // deepest field (nesting2.field1.position). + int getDeepestStructNesting() const { return deepestStructNesting; } + protected: void buildMangledName(TString&); int getStructSize() const; + void computeDeepestStructNesting(); TBasicType type : 6; TPrecision precision; @@ -284,6 +301,7 @@ protected: TTypeList* structure; // 0 unless this is a struct mutable int structureSize; + int deepestStructNesting; TString *fieldName; // for structure field names TString *mangled; diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp index a36c393..d3985e6 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.cpp @@ -20,8 +20,9 @@ UnfoldSelect::UnfoldSelect(TParseContext &context, OutputHLSL *outputHLSL) : mCo void UnfoldSelect::traverse(TIntermNode *node) { - mTemporaryIndex++; + int rewindIndex = mTemporaryIndex; node->traverse(this); + mTemporaryIndex = rewindIndex; } bool UnfoldSelect::visitSelection(Visit visit, TIntermSelection *node) @@ -30,36 +31,66 @@ bool UnfoldSelect::visitSelection(Visit visit, TIntermSelection *node) if (node->usesTernaryOperator()) { - int i = mTemporaryIndex++; + int i = mTemporaryIndex; - out << mOutputHLSL->typeString(node->getType()) << " t" << i << ";\n"; + out << mOutputHLSL->typeString(node->getType()) << " s" << i << ";\n"; + mTemporaryIndex = i + 1; node->getCondition()->traverse(this); out << "if("; + mTemporaryIndex = i + 1; node->getCondition()->traverse(mOutputHLSL); out << ")\n" "{\n"; + mTemporaryIndex = i + 1; node->getTrueBlock()->traverse(this); - out << " t" << i << " = "; + out << " s" << i << " = "; + mTemporaryIndex = i + 1; node->getTrueBlock()->traverse(mOutputHLSL); out << ";\n" "}\n" "else\n" "{\n"; + mTemporaryIndex = i + 1; node->getFalseBlock()->traverse(this); - out << " t" << i << " = "; + out << " s" << i << " = "; + mTemporaryIndex = i + 1; node->getFalseBlock()->traverse(mOutputHLSL); out << ";\n" "}\n"; - mTemporaryIndex--; + mTemporaryIndex = i + 1; } return false; } -int UnfoldSelect::getTemporaryIndex() +bool UnfoldSelect::visitLoop(Visit visit, TIntermLoop *node) { - return mTemporaryIndex; + int rewindIndex = mTemporaryIndex; + + if (node->getInit()) + { + node->getInit()->traverse(this); + } + + if (node->getCondition()) + { + node->getCondition()->traverse(this); + } + + if (node->getExpression()) + { + node->getExpression()->traverse(this); + } + + mTemporaryIndex = rewindIndex; + + return false; +} + +int UnfoldSelect::getNextTemporaryIndex() +{ + return mTemporaryIndex++; } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h index de296e4..4a3ba5f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h +++ b/Source/ThirdParty/ANGLE/src/compiler/UnfoldSelect.h @@ -23,8 +23,9 @@ class UnfoldSelect : public TIntermTraverser void traverse(TIntermNode *node); bool visitSelection(Visit visit, TIntermSelection *node); + bool visitLoop(Visit visit, TIntermLoop *node); - int getTemporaryIndex(); + int getNextTemporaryIndex(); protected: TParseContext &mContext; diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp index 886f693..767d0bf 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.cpp @@ -17,6 +17,17 @@ bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack& stack) { return false; } +void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack& stack) { + for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) { + if (i->index.id == symbol->getId()) { + ASSERT(i->loop != NULL); + i->loop->setUnrollFlag(true); + return; + } + } + UNREACHABLE(); +} + // Traverses a node to check if it represents a constant index expression. // Definition: // constant-index-expressions are a superset of constant-expressions. @@ -42,18 +53,46 @@ public: 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; }; + +// Traverses a node to check if it uses a loop index. +// If an int loop index is used in its body as a sampler array index, +// mark the loop for unroll. +class ValidateLoopIndexExpr : public TIntermTraverser { +public: + ValidateLoopIndexExpr(TLoopStack& stack) + : mUsesFloatLoopIndex(false), + mUsesIntLoopIndex(false), + mLoopStack(stack) {} + + bool usesFloatLoopIndex() const { return mUsesFloatLoopIndex; } + bool usesIntLoopIndex() const { return mUsesIntLoopIndex; } + + virtual void visitSymbol(TIntermSymbol* symbol) { + if (IsLoopIndex(symbol, mLoopStack)) { + switch (symbol->getBasicType()) { + case EbtFloat: + mUsesFloatLoopIndex = true; + break; + case EbtInt: + mUsesIntLoopIndex = true; + MarkLoopForUnroll(symbol, mLoopStack); + break; + default: + UNREACHABLE(); + } + } + } + +private: + bool mUsesFloatLoopIndex; + bool mUsesIntLoopIndex; + TLoopStack& mLoopStack; +}; } // namespace ValidateLimitations::ValidateLimitations(ShShaderType shaderType, @@ -64,14 +103,6 @@ ValidateLimitations::ValidateLimitations(ShShaderType shaderType, { } -void ValidateLimitations::visitSymbol(TIntermSymbol*) -{ -} - -void ValidateLimitations::visitConstantUnion(TIntermConstantUnion*) -{ -} - bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node) { // Check if loop index is modified in the loop body. @@ -80,7 +111,28 @@ bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node) // Check indexing. switch (node->getOp()) { case EOpIndexDirect: + validateIndexing(node); + break; case EOpIndexIndirect: +#if defined(__APPLE__) + // Loop unrolling is a work-around for a Mac Cg compiler bug where it + // crashes when a sampler array's index is also the loop index. + // Once Apple fixes this bug, we should remove the code in this CL. + // See http://codereview.appspot.com/4331048/. + if ((node->getLeft() != NULL) && (node->getRight() != NULL) && + (node->getLeft()->getAsSymbolNode())) { + TIntermSymbol* symbol = node->getLeft()->getAsSymbolNode(); + if (IsSampler(symbol->getBasicType()) && symbol->isArray()) { + ValidateLoopIndexExpr validate(mLoopStack); + node->getRight()->traverse(&validate); + if (validate.usesFloatLoopIndex()) { + error(node->getLine(), + "sampler array index is float loop index", + "for"); + } + } + } +#endif validateIndexing(node); break; default: break; @@ -96,11 +148,6 @@ bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node) return true; } -bool ValidateLimitations::visitSelection(Visit, TIntermSelection*) -{ - return true; -} - bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node) { switch (node->getOp()) { @@ -120,6 +167,7 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) TLoopInfo info; memset(&info, 0, sizeof(TLoopInfo)); + info.loop = node; if (!validateForLoopHeader(node, &info)) return false; @@ -134,11 +182,6 @@ bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node) return false; } -bool ValidateLimitations::visitBranch(Visit, TIntermBranch*) -{ - return true; -} - void ValidateLimitations::error(TSourceLoc loc, const char *reason, const char* token) { diff --git a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h index a4f5a28..a835cb3 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h +++ b/Source/ThirdParty/ANGLE/src/compiler/ValidateLimitations.h @@ -13,6 +13,7 @@ struct TLoopInfo { struct TIndex { int id; // symbol id. } index; + TIntermLoop* loop; }; typedef TVector<TLoopInfo> TLoopStack; @@ -24,14 +25,10 @@ public: 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); diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp index ad2e08f..1e9486f 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.cpp @@ -63,6 +63,8 @@ static ShDataType getVariableDataType(const TType& type) } case EbtSampler2D: return SH_SAMPLER_2D; case EbtSamplerCube: return SH_SAMPLER_CUBE; + case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES; + case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB; default: UNREACHABLE(); } return SH_NONE; @@ -70,32 +72,37 @@ static ShDataType getVariableDataType(const TType& type) static void getBuiltInVariableInfo(const TType& type, const TString& name, + const TString& mappedName, TVariableInfoList& infoList); static void getUserDefinedVariableInfo(const TType& type, const TString& name, + const TString& mappedName, TVariableInfoList& infoList); // Returns info for an attribute or uniform. static void getVariableInfo(const TType& type, const TString& name, + const TString& mappedName, 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); + TString lmappedName = mappedName + arrayBrackets(i); + getUserDefinedVariableInfo(type, lname, lmappedName, infoList); } } else { - getUserDefinedVariableInfo(type, name, infoList); + getUserDefinedVariableInfo(type, name, mappedName, infoList); } } else { - getBuiltInVariableInfo(type, name, infoList); + getBuiltInVariableInfo(type, name, mappedName, infoList); } } void getBuiltInVariableInfo(const TType& type, const TString& name, + const TString& mappedName, TVariableInfoList& infoList) { ASSERT(type.getBasicType() != EbtStruct); @@ -103,9 +110,11 @@ void getBuiltInVariableInfo(const TType& type, TVariableInfo varInfo; if (type.isArray()) { varInfo.name = (name + "[0]").c_str(); + varInfo.mappedName = (mappedName + "[0]").c_str(); varInfo.size = type.getArraySize(); } else { varInfo.name = name.c_str(); + varInfo.mappedName = mappedName.c_str(); varInfo.size = 1; } varInfo.type = getVariableDataType(type); @@ -114,16 +123,17 @@ void getBuiltInVariableInfo(const TType& type, void getUserDefinedVariableInfo(const TType& type, const TString& name, + const TString& mappedName, 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(), + name + "." + fieldType->getFieldName(), + mappedName + "." + fieldType->getFieldName(), infoList); } } @@ -186,7 +196,9 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node) // cannot be initialized in a shader, we must have only // TIntermSymbol nodes in the sequence. ASSERT(variable != NULL); - getVariableInfo(variable->getType(), variable->getSymbol(), + getVariableInfo(variable->getType(), + variable->getOriginalSymbol(), + variable->getSymbol(), infoList); } } diff --git a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h index 15a5c57..45ac9ea 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h +++ b/Source/ThirdParty/ANGLE/src/compiler/VariableInfo.h @@ -1,9 +1,12 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // +#ifndef COMPILER_VARIABLE_INFO_H_ +#define COMPILER_VARIABLE_INFO_H_ + #include "GLSLANG/ShaderLang.h" #include "compiler/intermediate.h" @@ -11,6 +14,7 @@ // It is currently being used to store info about active attribs and uniforms. struct TVariableInfo { TPersistString name; + TPersistString mappedName; ShDataType type; int size; }; @@ -22,6 +26,8 @@ public: CollectAttribsUniforms(TVariableInfoList& attribs, TVariableInfoList& uniforms); + virtual ~CollectAttribsUniforms() {} + virtual void visitSymbol(TIntermSymbol*); virtual void visitConstantUnion(TIntermConstantUnion*); virtual bool visitBinary(Visit, TIntermBinary*); @@ -36,3 +42,4 @@ private: TVariableInfoList& mUniforms; }; +#endif // COMPILER_VARIABLE_INFO_H_ diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp index 3f87820..26cee05 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.cpp @@ -9,13 +9,17 @@ static const int GLSL_VERSION_110 = 110; static const int GLSL_VERSION_120 = 120; -// We need to scan for two things: +// We need to scan for three 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. +// 3. Call to a matrix constructor with another matrix as argument. +// (These constructors were reserved in GLSL version 1.10.) +// +// If it weren't for (3) then we would only need to scan the global +// scope of the vertex shader. However, we need to scan the entire +// shader in both cases. // // TODO(alokp): The following two cases of invariant decalaration get lost // during parsing - they do not get carried over to the intermediate tree. @@ -34,40 +38,32 @@ TVersionGLSL::TVersionGLSL(ShShaderType type) 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; + bool visitChildren = true; switch (node->getOp()) { case EOpSequence: @@ -83,6 +79,19 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node) } break; } + case EOpConstructMat2: + case EOpConstructMat3: + case EOpConstructMat4: { + const TIntermSequence& sequence = node->getSequence(); + if (sequence.size() == 1) { + TIntermTyped* typed = sequence.front()->getAsTyped(); + if (typed && typed->isMatrix()) { + updateVersion(GLSL_VERSION_120); + } + } + break; + } + default: break; } @@ -91,13 +100,11 @@ bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node) bool TVersionGLSL::visitLoop(Visit, TIntermLoop*) { - ASSERT(mShaderType == SH_FRAGMENT_SHADER); return true; } bool TVersionGLSL::visitBranch(Visit, TIntermBranch*) { - ASSERT(mShaderType == SH_FRAGMENT_SHADER); return true; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h index 64d002b..376fcb8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h +++ b/Source/ThirdParty/ANGLE/src/compiler/VersionGLSL.h @@ -21,13 +21,15 @@ // - invariant keyword and its support. // - c++ style name hiding rules. // - built-in variable gl_PointCoord for fragment shaders. +// - matrix constructors taking matrix as argument. // 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. + // Returns 120 if "invariant" keyword, "gl_PointCoord", or + // matrix/matrix constructors are used in the shader. Else 110 is + // returned. int getVersion() { return mVersion; } virtual void visitSymbol(TIntermSymbol*); diff --git a/Source/ThirdParty/ANGLE/src/compiler/generate_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/generate_parser.sh new file mode 100755 index 0000000..e472191 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/generate_parser.sh @@ -0,0 +1,27 @@ +#!/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_lex.cpp, glslang_tab.h, and glslang_tab.cpp + +run_flex() +{ +input_file=$script_dir/$1.l +output_source=$script_dir/$1_lex.cpp +flex --noline --nounistd --outfile=$output_source $input_file +} + +run_bison() +{ +input_file=$script_dir/$1.y +output_header=$script_dir/$1_tab.h +output_source=$script_dir/$1_tab.cpp +bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file +} + +script_dir=$(dirname $0) + +# Generate Parser +run_flex glslang +run_bison glslang diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.l b/Source/ThirdParty/ANGLE/src/compiler/glslang.l index 5a7c5d5..9a0394b 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang.l +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.l @@ -9,7 +9,7 @@ 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, +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). */ @@ -20,7 +20,19 @@ WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). // found in the LICENSE file. // -// This file is auto-generated by generate_glslang_lexer.sh. DO NOT EDIT! +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +// Ignore errors in auto-generated code. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065) +#pragma warning(disable: 4189) +#pragma warning(disable: 4505) +#pragma warning(disable: 4701) +#endif } %{ @@ -120,6 +132,8 @@ O [0-7] "sampler2D" { context->lexAfterType = true; return SAMPLER2D; } "samplerCube" { context->lexAfterType = true; return SAMPLERCUBE; } +"samplerExternalOES" { context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; } +"sampler2DRect" { context->lexAfterType = true; return SAMPLER2DRECT; } "struct" { context->lexAfterType = true; return(STRUCT); } @@ -480,6 +494,8 @@ void updateExtensionBehavior(const char* extName, const char* behavior) msg = TString("extension '") + extName + "' is not supported"; context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); break; + default: + break; } return; } else diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang.y b/Source/ThirdParty/ANGLE/src/compiler/glslang.y index 5eae4b5..d6c8869 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang.y +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang.y @@ -9,7 +9,7 @@ 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 -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glslang_parser.sh, +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). */ @@ -20,7 +20,19 @@ WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h). // found in the LICENSE file. // -// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +// Ignore errors in auto-generated code. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065) +#pragma warning(disable: 4189) +#pragma warning(disable: 4505) +#pragma warning(disable: 4701) +#endif #include "compiler/SymbolTable.h" #include "compiler/ParseHelper.h" @@ -98,7 +110,7 @@ extern void yyerror(TParseContext* context, const char* reason); %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING %token <lex> STRUCT VOID_TYPE WHILE -%token <lex> SAMPLER2D SAMPLERCUBE +%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT %token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT %token <lex> FIELD_SELECTION @@ -129,7 +141,7 @@ extern void yyerror(TParseContext* context, const char* reason); %type <interm.intermNode> declaration external_declaration %type <interm.intermNode> for_init_statement compound_statement_no_new_scope %type <interm.nodePair> selection_rest_statement for_rest_statement -%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope +%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_with_scope %type <interm> single_declaration init_declarator_list %type <interm> parameter_declaration parameter_declarator parameter_type_specifier @@ -591,17 +603,10 @@ function_call_header // Grammar Note: Constructors look like functions, but are recognized as types. function_identifier - : type_specifier { + : type_specifier_nonarray { // // Constructor // - if ($1.array) { - // 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) { op = EOpConstructStruct; @@ -975,6 +980,8 @@ declaration prototype->setOp(EOpPrototype); $$ = prototype; + + context->symbolTable.pop(); } | init_declarator_list SEMICOLON { if ($1.intermAggregate) @@ -1019,7 +1026,9 @@ function_prototype $$.function = $1; $$.line = $2.line; - context->symbolTable.insert(*$$.function); + // We're at the inner scope level of the function's arguments and body statement. + // Add the function prototype to the surrounding scope instead. + context->symbolTable.getOuterLevel()->insert(*$$.function); } ; @@ -1077,6 +1086,8 @@ function_header TType type($1); function = new TFunction($2.string, type); $$ = function; + + context->symbolTable.push(); } ; @@ -1176,16 +1187,16 @@ parameter_type_specifier init_declarator_list : single_declaration { $$ = $1; - - if ($$.type.precision == EbpUndefined) { - $$.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 = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line), $3.line); + if ($1.type.type == EbtInvariant && !$3.symbol) + { + context->error($3.line, "undeclared identifier declared as invariant", $3.string->c_str(), ""); + context->recover(); + } + + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$3.string, TType($1.type), $3.line); + $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, symbol, $3.line); if (context->structQualifierErrorCheck($3.line, $$.type)) context->recover(); @@ -1193,8 +1204,11 @@ init_declarator_list if (context->nonInitConstErrorCheck($3.line, *$3.string, $$.type)) context->recover(); - if (context->nonInitErrorCheck($3.line, *$3.string, $$.type)) + TVariable* variable = 0; + if (context->nonInitErrorCheck($3.line, *$3.string, $$.type, variable)) context->recover(); + if (symbol && variable) + symbol->setId(variable->getUniqueId()); } | init_declarator_list COMMA IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { if (context->structQualifierErrorCheck($3.line, $1.type)) @@ -1230,12 +1244,12 @@ init_declarator_list if (context->arraySizeErrorCheck($4.line, $5, size)) context->recover(); $1.type.setArray(true, size); - TVariable* variable; + TVariable* variable = 0; if (context->arrayErrorCheck($4.line, *$3.string, $1.type, variable)) context->recover(); TType type = TType($1.type); type.setArraySize(size); - $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(0, *$3.string, type, $3.line), $3.line); + $$.intermAggregate = context->intermediate.growAggregate($1.intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *$3.string, type, $3.line), $3.line); } } | init_declarator_list COMMA IDENTIFIER EQUAL initializer { @@ -1266,7 +1280,8 @@ single_declaration $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, "", TType($1), $1.line), $1.line); } | fully_specified_type IDENTIFIER { - $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); + $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); if (context->structQualifierErrorCheck($2.line, $$.type)) context->recover(); @@ -1276,28 +1291,19 @@ single_declaration $$.type = $1; - if (context->nonInitErrorCheck($2.line, *$2.string, $$.type)) + TVariable* variable = 0; + if (context->nonInitErrorCheck($2.line, *$2.string, $$.type, variable)) context->recover(); + if (variable && symbol) + symbol->setId(variable->getUniqueId()); } | fully_specified_type IDENTIFIER LEFT_BRACKET RIGHT_BRACKET { - $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line), $2.line); - - if (context->structQualifierErrorCheck($2.line, $1)) - context->recover(); - - if (context->nonInitConstErrorCheck($2.line, *$2.string, $1)) - context->recover(); + context->error($2.line, "unsized array declarations not supported", $2.string->c_str(), ""); + context->recover(); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, TType($1), $2.line); + $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); $$.type = $1; - - if (context->arrayTypeErrorCheck($3.line, $1) || context->arrayQualifierErrorCheck($3.line, $1)) - context->recover(); - else { - $1.setArray(true); - TVariable* variable; - 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); @@ -1305,7 +1311,8 @@ single_declaration if (context->arraySizeErrorCheck($2.line, $4, size)) context->recover(); type.setArraySize(size); - $$.intermAggregate = context->intermediate.makeAggregate(context->intermediate.addSymbol(0, *$2.string, type, $2.line), $2.line); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *$2.string, type, $2.line); + $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); if (context->structQualifierErrorCheck($2.line, $1)) context->recover(); @@ -1323,9 +1330,11 @@ single_declaration context->recover(); $1.setArray(true, size); - TVariable* variable; + TVariable* variable = 0; if (context->arrayErrorCheck($3.line, *$2.string, $1, variable)) context->recover(); + if (variable && symbol) + symbol->setId(variable->getUniqueId()); } } | fully_specified_type IDENTIFIER EQUAL initializer { @@ -1350,8 +1359,21 @@ single_declaration } | INVARIANT IDENTIFIER { VERTEX_ONLY("invariant declaration", $1.line); - $$.qualifier = EvqInvariantVaryingOut; - $$.intermAggregate = 0; + if (context->globalErrorCheck($1.line, context->symbolTable.atGlobalLevel(), "invariant varying")) + context->recover(); + $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, $2.line); + if (!$2.symbol) + { + context->error($2.line, "undeclared identifier declared as invariant", $2.string->c_str(), ""); + context->recover(); + + $$.intermAggregate = 0; + } + else + { + TIntermSymbol *symbol = context->intermediate.addSymbol(0, *$2.string, TType($$.type), $2.line); + $$.intermAggregate = context->intermediate.makeAggregate(symbol, $2.line); + } } // @@ -1491,6 +1513,13 @@ type_qualifier type_specifier : type_specifier_no_prec { $$ = $1; + + if ($$.precision == EbpUndefined) { + $$.precision = context->symbolTable.getDefaultPrecision($1.type); + if (context->precisionErrorCheck($1.line, $$.precision, $1.type)) { + context->recover(); + } + } } | precision_qualifier type_specifier_no_prec { $$ = $2; @@ -1623,6 +1652,24 @@ type_specifier_nonarray TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.setBasic(EbtSamplerCube, qual, $1.line); } + | SAMPLER_EXTERNAL_OES { + if (!context->supportsExtension("GL_OES_EGL_image_external")) { + context->error($1.line, "unsupported type", "samplerExternalOES", ""); + context->recover(); + } + FRAG_VERT_ONLY("samplerExternalOES", $1.line); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSamplerExternalOES, qual, $1.line); + } + | SAMPLER2DRECT { + if (!context->supportsExtension("GL_ARB_texture_rectangle")) { + context->error($1.line, "unsupported type", "sampler2DRect", ""); + context->recover(); + } + FRAG_VERT_ONLY("sampler2DRect", $1.line); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + $$.setBasic(EbtSampler2DRect, qual, $1.line); + } | struct_specifier { FRAG_VERT_ONLY("struct", $1.line); $$ = $1; @@ -1641,11 +1688,11 @@ type_specifier_nonarray ; struct_specifier - : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE { + : STRUCT IDENTIFIER LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { if (context->reservedErrorCheck($2.line, *$2.string)) context->recover(); - TType* structure = new TType($4, *$2.string); + TType* structure = new TType($5, *$2.string); TVariable* userTypeDef = new TVariable($2.string, *structure, true); if (! context->symbolTable.insert(*userTypeDef)) { context->error($2.line, "redefinition", $2.string->c_str(), "struct"); @@ -1653,11 +1700,13 @@ struct_specifier } $$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.userDef = structure; + context->exitStructDeclaration(); } - | STRUCT LEFT_BRACE struct_declaration_list RIGHT_BRACE { - TType* structure = new TType($3, TString("")); + | STRUCT LEFT_BRACE { if (context->enterStructDeclaration($2.line, *$2.string)) context->recover(); } struct_declaration_list RIGHT_BRACE { + TType* structure = new TType($4, TString("")); $$.setBasic(EbtStruct, EvqTemporary, $1.line); $$.userDef = structure; + context->exitStructDeclaration(); } ; @@ -1694,6 +1743,7 @@ struct_declaration type->setBasicType($1.type); type->setNominalSize($1.size); type->setMatrix($1.matrix); + type->setPrecision($1.precision); // don't allow arrays of arrays if (type->isArray()) { @@ -1706,6 +1756,10 @@ struct_declaration type->setStruct($1.userDef->getStruct()); type->setTypeName($1.userDef->getTypeName()); } + + if (context->structNestingErrorCheck($1.line, *type)) { + context->recover(); + } } } ; @@ -1770,8 +1824,10 @@ simple_statement compound_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE { context->symbolTable.push(); } statement_list { context->symbolTable.pop(); } RIGHT_BRACE { - if ($3 != 0) + if ($3 != 0) { $3->setOp(EOpSequence); + $3->setEndLine($5.line); + } $$ = $3; } ; @@ -1781,14 +1837,21 @@ statement_no_new_scope | simple_statement { $$ = $1; } ; +statement_with_scope + : { context->symbolTable.push(); } compound_statement_no_new_scope { context->symbolTable.pop(); $$ = $2; } + | { context->symbolTable.push(); } simple_statement { context->symbolTable.pop(); $$ = $2; } + ; + compound_statement_no_new_scope // Statement that doesn't create a new scope, for selection_statement, iteration_statement : LEFT_BRACE RIGHT_BRACE { $$ = 0; } | LEFT_BRACE statement_list RIGHT_BRACE { - if ($2) + if ($2) { $2->setOp(EOpSequence); + $2->setEndLine($3.line); + } $$ = $2; } ; @@ -1816,11 +1879,11 @@ selection_statement ; selection_rest_statement - : statement ELSE statement { + : statement_with_scope ELSE statement_with_scope { $$.node1 = $1; $$.node2 = $3; } - | statement { + | statement_with_scope { $$.node1 = $1; $$.node2 = 0; } @@ -1857,7 +1920,7 @@ iteration_statement $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line); --context->loopNestingLevel; } - | DO { ++context->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { + | DO { ++context->loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON { if (context->boolErrorCheck($8.line, $6)) context->recover(); @@ -1994,11 +2057,6 @@ function_definition } // - // 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()); @@ -2050,7 +2108,7 @@ function_definition context->error($1.line, "function does not return a value:", "", $1.function->getName().c_str()); context->recover(); } - context->symbolTable.pop(); + $$ = context->intermediate.growAggregate($1.intermAggregate, $3, 0); context->intermediate.setAggregateOperator($$, EOpFunction, $1.line); $$->getAsAggregate()->setName($1.function->getMangledName().c_str()); @@ -2061,6 +2119,11 @@ function_definition $$->getAsAggregate()->setOptimize(context->contextPragma.optimize); $$->getAsAggregate()->setDebug(context->contextPragma.debug); $$->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable); + + if ($3 && $3->getAsAggregate()) + $$->getAsAggregate()->setEndLine($3->getAsAggregate()->getEndLine()); + + context->symbolTable.pop(); } ; diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp index 9d5f53f..59b7299 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_lex.cpp @@ -1,15 +1,27 @@ -#line 17 "compiler/glslang.l" +#line 17 "./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! +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +// Ignore errors in auto-generated code. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065) +#pragma warning(disable: 4189) +#pragma warning(disable: 4505) +#pragma warning(disable: 4701) +#endif -#line 13 "compiler/glslang_lex.cpp" +#line 25 "./glslang_lex.cpp" #define YY_INT_ALIGNED short int @@ -371,8 +383,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 145 -#define YY_END_OF_BUFFER 146 +#define YY_NUM_RULES 147 +#define YY_END_OF_BUFFER 148 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -380,53 +392,55 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[411] = +static yyconst flex_int16_t yy_accept[426] = { 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 + 0, 0, 0, 0, 0, 0, 148, 146, 145, 145, + 130, 136, 141, 125, 126, 134, 133, 122, 131, 129, + 135, 94, 94, 123, 119, 137, 124, 138, 142, 90, + 127, 128, 140, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 120, 139, 121, 132, 3, 4, 3, + 144, 147, 143, 116, 102, 121, 110, 105, 100, 108, + 98, 109, 99, 97, 2, 1, 101, 96, 92, 93, + 0, 0, 94, 128, 120, 127, 117, 113, 115, 114, + 118, 90, 106, 112, 90, 90, 90, 90, 90, 90, + + 90, 90, 90, 90, 17, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 20, 22, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 107, 111, 5, 143, + 0, 1, 96, 0, 0, 95, 91, 103, 104, 50, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 18, 90, 90, + 90, 90, 90, 90, 90, 90, 26, 90, 90, 90, + 90, 90, 90, 90, 90, 23, 90, 90, 90, 90, + + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 0, 97, + 0, 96, 90, 28, 90, 90, 87, 90, 90, 90, + 90, 90, 90, 90, 21, 53, 90, 90, 90, 90, + 90, 58, 72, 90, 90, 90, 90, 90, 90, 90, + 90, 69, 9, 33, 34, 35, 90, 90, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, + 90, 56, 29, 90, 90, 90, 90, 90, 90, 36, + 37, 38, 27, 90, 90, 90, 15, 42, 43, 44, + 51, 12, 90, 90, 90, 90, 83, 84, 85, 90, + + 30, 73, 25, 80, 81, 82, 7, 77, 78, 79, + 90, 24, 75, 90, 90, 39, 40, 41, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 70, 90, 90, + 90, 90, 90, 90, 90, 52, 90, 89, 90, 90, + 19, 90, 90, 90, 90, 71, 66, 61, 90, 90, + 90, 90, 90, 76, 57, 90, 64, 32, 90, 86, + 65, 49, 59, 90, 90, 90, 90, 90, 90, 90, + 90, 60, 31, 90, 90, 90, 8, 90, 90, 90, + 90, 90, 54, 13, 90, 14, 90, 90, 16, 67, + 90, 90, 90, 62, 90, 90, 90, 90, 55, 74, + + 63, 11, 68, 6, 88, 10, 45, 90, 90, 90, + 90, 90, 90, 46, 90, 90, 90, 48, 90, 90, + 90, 90, 90, 47, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -438,13 +452,13 @@ static yyconst flex_int32_t yy_ec[256] = 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, + 31, 31, 31, 31, 31, 31, 31, 31, 32, 31, + 31, 33, 34, 31, 31, 31, 31, 35, 31, 31, + 36, 1, 37, 38, 31, 1, 39, 40, 41, 42, - 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, + 43, 44, 45, 46, 47, 31, 48, 49, 50, 51, + 52, 53, 31, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 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, @@ -461,195 +475,201 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[64] = +static yyconst flex_int32_t yy_meta[67] = { 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 + 4, 4, 4, 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] = +static yyconst flex_int16_t yy_base[431] = { 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, 64, 65, 74, 0, 627, 628, 628, 628, + 602, 45, 135, 628, 628, 601, 132, 628, 131, 129, + 143, 155, 163, 599, 628, 179, 599, 47, 628, 0, + 628, 628, 126, 98, 108, 147, 158, 158, 165, 570, + 130, 107, 569, 148, 156, 563, 172, 576, 174, 181, + 177, 195, 572, 628, 173, 628, 628, 628, 628, 603, + 628, 628, 0, 628, 628, 628, 628, 628, 628, 628, + 628, 628, 628, 233, 628, 0, 628, 239, 255, 271, + 287, 0, 300, 628, 628, 628, 592, 628, 628, 628, + 591, 0, 628, 628, 564, 557, 560, 568, 567, 554, + + 569, 556, 562, 550, 547, 560, 547, 544, 544, 550, + 538, 545, 542, 552, 538, 544, 547, 548, 0, 187, + 547, 241, 533, 546, 537, 539, 529, 543, 540, 542, + 525, 530, 527, 516, 192, 530, 526, 528, 517, 520, + 274, 525, 517, 529, 114, 522, 628, 628, 628, 0, + 316, 0, 322, 338, 344, 351, 0, 628, 628, 0, + 514, 518, 527, 524, 508, 508, 205, 523, 520, 520, + 518, 515, 507, 513, 500, 511, 514, 0, 511, 499, + 506, 503, 507, 500, 489, 488, 501, 504, 501, 496, + 487, 247, 492, 495, 486, 483, 487, 493, 484, 475, + + 478, 476, 486, 472, 470, 470, 472, 469, 480, 479, + 328, 474, 469, 458, 260, 476, 478, 467, 358, 366, + 372, 378, 468, 0, 466, 276, 0, 458, 456, 464, + 453, 470, 459, 291, 0, 0, 453, 463, 463, 448, + 305, 0, 0, 450, 327, 451, 445, 444, 445, 444, + 382, 0, 0, 0, 0, 0, 440, 441, 446, 437, + 450, 445, 444, 436, 440, 432, 435, 439, 444, 443, + 434, 0, 0, 440, 429, 429, 434, 433, 430, 0, + 0, 0, 0, 420, 432, 434, 0, 0, 0, 0, + 0, 0, 422, 423, 417, 427, 0, 0, 0, 418, 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 + 425, 0, 0, 423, 419, 0, 0, 0, 415, 411, + 416, 406, 419, 405, 418, 407, 414, 0, 412, 414, + 398, 407, 413, 408, 396, 0, 398, 0, 397, 400, + 0, 389, 388, 388, 401, 0, 403, 0, 402, 401, + 386, 399, 386, 0, 0, 389, 0, 0, 381, 0, + 0, 0, 0, 378, 389, 382, 388, 385, 380, 372, + 382, 0, 0, 365, 371, 360, 0, 369, 366, 356, + 385, 364, 0, 0, 364, 0, 362, 361, 0, 0, + 360, 323, 308, 0, 298, 318, 270, 265, 0, 0, + + 0, 0, 0, 0, 0, 0, 279, 271, 240, 240, + 238, 237, 226, 0, 208, 188, 190, 0, 186, 173, + 187, 164, 158, 0, 628, 415, 417, 419, 423, 186 } ; -static yyconst flex_int16_t yy_def[416] = +static yyconst flex_int16_t yy_def[431] = { 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 + 425, 1, 426, 426, 425, 5, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 427, + 425, 425, 425, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 428, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 429, 425, 425, 425, 425, + 425, 430, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 427, 425, 425, 427, 427, 427, 427, 427, 427, + + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 425, 425, 425, 428, + 425, 429, 425, 425, 425, 425, 430, 425, 425, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 425, 425, + 425, 425, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 427, 427, 427, 427, 427, 427, + 427, 427, 427, 427, 0, 425, 425, 425, 425, 425 } ; -static yyconst flex_int16_t yy_nxt[671] = +static yyconst flex_int16_t yy_nxt[695] = { 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, + 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, - 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, 8, + 8, 8, 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 + 63, 63, 63, 63, 63, 63, 8, 8, 8, 8, + 67, 70, 72, 74, 74, 74, 74, 74, 74, 93, + 119, 75, 95, 96, 73, 71, 76, 120, 68, 97, + 216, 98, 217, 94, 121, 99, 77, 78, 116, 79, + 79, 79, 79, 79, 80, 78, 117, 83, 83, 83, + 83, 83, 83, 85, 81, 100, 123, 118, 157, 82, + 124, 424, 81, 423, 125, 101, 147, 81, 102, 86, + + 103, 87, 88, 110, 104, 81, 107, 126, 108, 105, + 128, 111, 132, 112, 82, 106, 113, 109, 422, 133, + 134, 421, 114, 137, 420, 129, 138, 141, 130, 135, + 204, 142, 136, 143, 139, 184, 148, 144, 185, 186, + 419, 140, 187, 418, 188, 205, 145, 74, 74, 74, + 74, 74, 74, 153, 153, 153, 153, 153, 153, 229, + 230, 417, 151, 254, 255, 256, 416, 78, 154, 79, + 79, 79, 79, 79, 80, 151, 280, 281, 282, 415, + 414, 154, 413, 78, 81, 80, 80, 80, 80, 80, + 80, 190, 288, 289, 290, 412, 155, 81, 155, 191, + + 81, 156, 156, 156, 156, 156, 156, 297, 298, 299, + 411, 410, 78, 81, 83, 83, 83, 83, 83, 83, + 211, 304, 305, 306, 409, 219, 408, 219, 212, 81, + 220, 220, 220, 220, 220, 220, 153, 153, 153, 153, + 153, 153, 81, 308, 309, 310, 407, 221, 406, 221, + 405, 154, 222, 222, 222, 222, 222, 222, 156, 156, + 156, 156, 156, 156, 154, 156, 156, 156, 156, 156, + 156, 275, 220, 220, 220, 220, 220, 220, 404, 276, + 220, 220, 220, 220, 220, 220, 222, 222, 222, 222, + 222, 222, 222, 222, 222, 222, 222, 222, 316, 317, + + 318, 396, 403, 402, 401, 400, 399, 395, 394, 393, + 392, 391, 397, 390, 398, 58, 58, 58, 58, 92, + 92, 150, 150, 152, 389, 152, 152, 388, 387, 386, + 385, 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, 425, 7, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425 + } ; -static yyconst flex_int16_t yy_chk[671] = +static yyconst flex_int16_t yy_chk[695] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -657,77 +677,81 @@ static yyconst flex_int16_t yy_chk[671] = 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, + 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, 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 + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 13, 17, 19, 20, 20, 20, 20, 20, 20, 33, + 42, 21, 34, 34, 19, 17, 21, 42, 13, 35, + 145, 35, 145, 33, 42, 35, 21, 22, 41, 22, + 22, 22, 22, 22, 22, 23, 41, 23, 23, 23, + 23, 23, 23, 26, 22, 36, 44, 41, 430, 22, + 44, 423, 23, 422, 45, 36, 55, 22, 36, 26, + + 37, 26, 26, 39, 37, 23, 38, 45, 38, 37, + 47, 39, 49, 39, 22, 37, 39, 38, 421, 49, + 49, 420, 39, 50, 419, 47, 50, 51, 47, 49, + 135, 51, 49, 52, 50, 120, 55, 52, 120, 120, + 417, 50, 120, 416, 120, 135, 52, 74, 74, 74, + 74, 74, 74, 78, 78, 78, 78, 78, 78, 167, + 167, 415, 74, 192, 192, 192, 413, 79, 78, 79, + 79, 79, 79, 79, 79, 74, 215, 215, 215, 412, + 411, 78, 410, 80, 79, 80, 80, 80, 80, 80, + 80, 122, 226, 226, 226, 409, 81, 79, 81, 122, + + 80, 81, 81, 81, 81, 81, 81, 234, 234, 234, + 408, 407, 83, 80, 83, 83, 83, 83, 83, 83, + 141, 241, 241, 241, 398, 151, 397, 151, 141, 83, + 151, 151, 151, 151, 151, 151, 153, 153, 153, 153, + 153, 153, 83, 245, 245, 245, 396, 154, 395, 154, + 393, 153, 154, 154, 154, 154, 154, 154, 155, 155, + 155, 155, 155, 155, 153, 156, 156, 156, 156, 156, + 156, 211, 219, 219, 219, 219, 219, 219, 392, 211, + 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, + 221, 221, 222, 222, 222, 222, 222, 222, 251, 251, + + 251, 381, 391, 388, 387, 385, 382, 380, 379, 378, + 376, 375, 381, 374, 381, 426, 426, 426, 426, 427, + 427, 428, 428, 429, 371, 429, 429, 370, 369, 368, + 367, 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, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425, 425, 425, 425, 425, 425, 425, + 425, 425, 425, 425 + } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[146] = +static yyconst flex_int32_t yy_rule_can_match_eol[148] = { 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, @@ -736,7 +760,7 @@ static yyconst flex_int32_t yy_rule_can_match_eol[146] = 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, }; + 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. @@ -756,7 +780,7 @@ 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, +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp). */ @@ -920,7 +944,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - int n; \ + yy_size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -1062,13 +1086,13 @@ yy_match: 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 ) + if ( yy_current_state >= 426 ) 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 ); + while ( yy_current_state != 425 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1079,7 +1103,7 @@ yy_find_action: if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { - int yyl; + yy_size_t yyl; for ( yyl = 0; yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) @@ -1285,15 +1309,15 @@ YY_RULE_SETUP YY_BREAK case 47: YY_RULE_SETUP -{ context->lexAfterType = true; return(STRUCT); } +{ context->lexAfterType = true; return SAMPLER_EXTERNAL_OES; } YY_BREAK case 48: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ context->lexAfterType = true; return SAMPLER2DRECT; } YY_BREAK case 49: YY_RULE_SETUP -{ return reserved_word(yyscanner); } +{ context->lexAfterType = true; return(STRUCT); } YY_BREAK case 50: YY_RULE_SETUP @@ -1449,220 +1473,228 @@ YY_RULE_SETUP YY_BREAK case 88: YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 89: +YY_RULE_SETUP +{ return reserved_word(yyscanner); } + YY_BREAK +case 90: +YY_RULE_SETUP { yylval->lex.string = NewPoolTString(yytext); return check_type(yyscanner); } YY_BREAK -case 89: +case 91: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 90: +case 92: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 91: +case 93: YY_RULE_SETUP { context->error(yylineno, "Invalid Octal number.", yytext, "", ""); context->recover(); return 0;} YY_BREAK -case 92: +case 94: YY_RULE_SETUP { yylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } YY_BREAK -case 93: +case 95: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 94: +case 96: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 95: +case 97: YY_RULE_SETUP { yylval->lex.f = static_cast<float>(atof_dot(yytext)); return(FLOATCONSTANT); } YY_BREAK -case 96: +case 98: YY_RULE_SETUP { return(ADD_ASSIGN); } YY_BREAK -case 97: +case 99: YY_RULE_SETUP { return(SUB_ASSIGN); } YY_BREAK -case 98: +case 100: YY_RULE_SETUP { return(MUL_ASSIGN); } YY_BREAK -case 99: +case 101: YY_RULE_SETUP { return(DIV_ASSIGN); } YY_BREAK -case 100: +case 102: YY_RULE_SETUP { return(MOD_ASSIGN); } YY_BREAK -case 101: +case 103: YY_RULE_SETUP { return(LEFT_ASSIGN); } YY_BREAK -case 102: +case 104: YY_RULE_SETUP { return(RIGHT_ASSIGN); } YY_BREAK -case 103: +case 105: YY_RULE_SETUP { return(AND_ASSIGN); } YY_BREAK -case 104: +case 106: YY_RULE_SETUP { return(XOR_ASSIGN); } YY_BREAK -case 105: +case 107: YY_RULE_SETUP { return(OR_ASSIGN); } YY_BREAK -case 106: +case 108: YY_RULE_SETUP { return(INC_OP); } YY_BREAK -case 107: +case 109: YY_RULE_SETUP { return(DEC_OP); } YY_BREAK -case 108: +case 110: YY_RULE_SETUP { return(AND_OP); } YY_BREAK -case 109: +case 111: YY_RULE_SETUP { return(OR_OP); } YY_BREAK -case 110: +case 112: YY_RULE_SETUP { return(XOR_OP); } YY_BREAK -case 111: +case 113: YY_RULE_SETUP { return(LE_OP); } YY_BREAK -case 112: +case 114: YY_RULE_SETUP { return(GE_OP); } YY_BREAK -case 113: +case 115: YY_RULE_SETUP { return(EQ_OP); } YY_BREAK -case 114: +case 116: YY_RULE_SETUP { return(NE_OP); } YY_BREAK -case 115: +case 117: YY_RULE_SETUP { return(LEFT_OP); } YY_BREAK -case 116: +case 118: YY_RULE_SETUP { return(RIGHT_OP); } YY_BREAK -case 117: +case 119: YY_RULE_SETUP { context->lexAfterType = false; return(SEMICOLON); } YY_BREAK -case 118: +case 120: YY_RULE_SETUP { context->lexAfterType = false; return(LEFT_BRACE); } YY_BREAK -case 119: +case 121: YY_RULE_SETUP { return(RIGHT_BRACE); } YY_BREAK -case 120: +case 122: YY_RULE_SETUP { if (context->inTypeParen) context->lexAfterType = false; return(COMMA); } YY_BREAK -case 121: +case 123: YY_RULE_SETUP { return(COLON); } YY_BREAK -case 122: +case 124: YY_RULE_SETUP { context->lexAfterType = false; return(EQUAL); } YY_BREAK -case 123: +case 125: YY_RULE_SETUP { context->lexAfterType = false; context->inTypeParen = true; return(LEFT_PAREN); } YY_BREAK -case 124: +case 126: YY_RULE_SETUP { context->inTypeParen = false; return(RIGHT_PAREN); } YY_BREAK -case 125: +case 127: YY_RULE_SETUP { return(LEFT_BRACKET); } YY_BREAK -case 126: +case 128: YY_RULE_SETUP { return(RIGHT_BRACKET); } YY_BREAK -case 127: +case 129: YY_RULE_SETUP { BEGIN(FIELDS); return(DOT); } YY_BREAK -case 128: +case 130: YY_RULE_SETUP { return(BANG); } YY_BREAK -case 129: +case 131: YY_RULE_SETUP { return(DASH); } YY_BREAK -case 130: +case 132: YY_RULE_SETUP { return(TILDE); } YY_BREAK -case 131: +case 133: YY_RULE_SETUP { return(PLUS); } YY_BREAK -case 132: +case 134: YY_RULE_SETUP { return(STAR); } YY_BREAK -case 133: +case 135: YY_RULE_SETUP { return(SLASH); } YY_BREAK -case 134: +case 136: YY_RULE_SETUP { return(PERCENT); } YY_BREAK -case 135: +case 137: YY_RULE_SETUP { return(LEFT_ANGLE); } YY_BREAK -case 136: +case 138: YY_RULE_SETUP { return(RIGHT_ANGLE); } YY_BREAK -case 137: +case 139: YY_RULE_SETUP { return(VERTICAL_BAR); } YY_BREAK -case 138: +case 140: YY_RULE_SETUP { return(CARET); } YY_BREAK -case 139: +case 141: YY_RULE_SETUP { return(AMPERSAND); } YY_BREAK -case 140: +case 142: YY_RULE_SETUP { return(QUESTION); } YY_BREAK -case 141: +case 143: YY_RULE_SETUP { BEGIN(INITIAL); @@ -1670,12 +1702,12 @@ YY_RULE_SETUP return FIELD_SELECTION; } YY_BREAK -case 142: +case 144: YY_RULE_SETUP {} YY_BREAK -case 143: -/* rule 143 can match eol */ +case 145: +/* rule 145 can match eol */ YY_RULE_SETUP { } YY_BREAK @@ -1684,11 +1716,11 @@ case YY_STATE_EOF(COMMENT): case YY_STATE_EOF(FIELDS): { context->AfterEOF = true; yyterminate(); } YY_BREAK -case 144: +case 146: YY_RULE_SETUP { context->warning(yylineno, "Unknown char", yytext, ""); return 0; } YY_BREAK -case 145: +case 147: YY_RULE_SETUP ECHO; YY_BREAK @@ -1984,7 +2016,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) 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 ) + if ( yy_current_state >= 426 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2013,11 +2045,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) 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 ) + if ( yy_current_state >= 426 ) 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); + yy_is_jam = (yy_current_state == 425); return yy_is_jam ? 0 : yy_current_state; } @@ -3096,6 +3128,8 @@ void updateExtensionBehavior(const char* extName, const char* behavior) msg = TString("extension '") + extName + "' is not supported"; context->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); break; + default: + break; } return; } else diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp index d00c7a3..37a0f05 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.cpp @@ -106,57 +106,59 @@ 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 + SAMPLER_EXTERNAL_OES = 298, + SAMPLER2DRECT = 299, + IDENTIFIER = 300, + TYPE_NAME = 301, + FLOATCONSTANT = 302, + INTCONSTANT = 303, + BOOLCONSTANT = 304, + FIELD_SELECTION = 305, + LEFT_OP = 306, + RIGHT_OP = 307, + INC_OP = 308, + DEC_OP = 309, + LE_OP = 310, + GE_OP = 311, + EQ_OP = 312, + NE_OP = 313, + AND_OP = 314, + OR_OP = 315, + XOR_OP = 316, + MUL_ASSIGN = 317, + DIV_ASSIGN = 318, + ADD_ASSIGN = 319, + MOD_ASSIGN = 320, + LEFT_ASSIGN = 321, + RIGHT_ASSIGN = 322, + AND_ASSIGN = 323, + XOR_ASSIGN = 324, + OR_ASSIGN = 325, + SUB_ASSIGN = 326, + LEFT_PAREN = 327, + RIGHT_PAREN = 328, + LEFT_BRACKET = 329, + RIGHT_BRACKET = 330, + LEFT_BRACE = 331, + RIGHT_BRACE = 332, + DOT = 333, + COMMA = 334, + COLON = 335, + EQUAL = 336, + SEMICOLON = 337, + BANG = 338, + DASH = 339, + TILDE = 340, + PLUS = 341, + STAR = 342, + SLASH = 343, + PERCENT = 344, + LEFT_ANGLE = 345, + RIGHT_ANGLE = 346, + VERTICAL_BAR = 347, + CARET = 348, + AMPERSAND = 349, + QUESTION = 350 }; #endif /* Tokens. */ @@ -200,57 +202,59 @@ #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 +#define SAMPLER_EXTERNAL_OES 298 +#define SAMPLER2DRECT 299 +#define IDENTIFIER 300 +#define TYPE_NAME 301 +#define FLOATCONSTANT 302 +#define INTCONSTANT 303 +#define BOOLCONSTANT 304 +#define FIELD_SELECTION 305 +#define LEFT_OP 306 +#define RIGHT_OP 307 +#define INC_OP 308 +#define DEC_OP 309 +#define LE_OP 310 +#define GE_OP 311 +#define EQ_OP 312 +#define NE_OP 313 +#define AND_OP 314 +#define OR_OP 315 +#define XOR_OP 316 +#define MUL_ASSIGN 317 +#define DIV_ASSIGN 318 +#define ADD_ASSIGN 319 +#define MOD_ASSIGN 320 +#define LEFT_ASSIGN 321 +#define RIGHT_ASSIGN 322 +#define AND_ASSIGN 323 +#define XOR_ASSIGN 324 +#define OR_ASSIGN 325 +#define SUB_ASSIGN 326 +#define LEFT_PAREN 327 +#define RIGHT_PAREN 328 +#define LEFT_BRACKET 329 +#define RIGHT_BRACKET 330 +#define LEFT_BRACE 331 +#define RIGHT_BRACE 332 +#define DOT 333 +#define COMMA 334 +#define COLON 335 +#define EQUAL 336 +#define SEMICOLON 337 +#define BANG 338 +#define DASH 339 +#define TILDE 340 +#define PLUS 341 +#define STAR 342 +#define SLASH 343 +#define PERCENT 344 +#define LEFT_ANGLE 345 +#define RIGHT_ANGLE 346 +#define VERTICAL_BAR 347 +#define CARET 348 +#define AMPERSAND 349 +#define QUESTION 350 @@ -259,12 +263,24 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +// Ignore errors in auto-generated code. +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wswitch-enum" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065) +#pragma warning(disable: 4189) +#pragma warning(disable: 4505) +#pragma warning(disable: 4701) +#endif #include "compiler/SymbolTable.h" #include "compiler/ParseHelper.h" @@ -325,7 +341,7 @@ typedef union YYSTYPE }; } interm; } -/* Line 187 of yacc.c. */ +/* Line 193 of yacc.c. */ YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -415,7 +431,7 @@ typedef short int yytype_int16; #define YYSIZE_MAXIMUM ((YYSIZE_T) -1) #ifndef YY_ -# if YYENABLE_NLS +# if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ # define YY_(msgid) dgettext ("bison-runtime", msgid) @@ -578,22 +594,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 69 +#define YYFINAL 71 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 1334 +#define YYLAST 1416 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 94 +#define YYNTOKENS 96 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 78 +#define YYNNTS 83 /* YYNRULES -- Number of rules. */ -#define YYNRULES 193 +#define YYNRULES 201 /* YYNRULES -- Number of states. */ -#define YYNSTATES 296 +#define YYNSTATES 304 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 348 +#define YYMAXUTOK 350 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -635,7 +651,8 @@ static const yytype_uint8 yytranslate[] = 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 + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95 }; #if YYDEBUG @@ -656,99 +673,102 @@ static const yytype_uint16 yyprhs[] = 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 + 368, 370, 372, 374, 376, 378, 380, 382, 384, 385, + 392, 393, 399, 401, 404, 408, 410, 414, 416, 421, + 423, 425, 427, 429, 431, 433, 435, 437, 439, 442, + 443, 444, 450, 452, 454, 455, 458, 459, 462, 465, + 469, 471, 474, 476, 479, 485, 489, 491, 493, 498, + 499, 506, 507, 516, 517, 525, 527, 529, 531, 532, + 535, 539, 542, 545, 548, 552, 555, 557, 560, 562, + 564, 565 }; /* 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, + 175, 0, -1, 45, -1, 97, -1, 48, -1, 47, + -1, 49, -1, 72, 124, 73, -1, 98, -1, 99, + 74, 100, 75, -1, 101, -1, 99, 78, 50, -1, + 99, 53, -1, 99, 54, -1, 124, -1, 102, -1, + 103, -1, 99, 78, 103, -1, 105, 73, -1, 104, + 73, -1, 106, 39, -1, 106, -1, 106, 122, -1, + 105, 79, 122, -1, 107, 72, -1, 142, -1, 45, + -1, 50, -1, 99, -1, 53, 108, -1, 54, 108, + -1, 109, 108, -1, 86, -1, 84, -1, 83, -1, + 108, -1, 110, 87, 108, -1, 110, 88, 108, -1, + 110, -1, 111, 86, 110, -1, 111, 84, 110, -1, + 111, -1, 112, -1, 113, 90, 112, -1, 113, 91, + 112, -1, 113, 55, 112, -1, 113, 56, 112, -1, + 113, -1, 114, 57, 113, -1, 114, 58, 113, -1, + 114, -1, 115, -1, 116, -1, 117, -1, 118, 59, + 117, -1, 118, -1, 119, 61, 118, -1, 119, -1, + 120, 60, 119, -1, 120, -1, 120, 95, 124, 80, + 122, -1, 121, -1, 108, 123, 122, -1, 81, -1, + 62, -1, 63, -1, 64, -1, 71, -1, 122, -1, + 124, 79, 122, -1, 121, -1, 127, 82, -1, 135, + 82, -1, 7, 140, 141, 82, -1, 128, 73, -1, + 130, -1, 129, -1, 130, 132, -1, 129, 79, 132, + -1, 137, 45, 72, -1, 139, 45, -1, 139, 45, + 74, 125, 75, -1, 138, 133, 131, -1, 133, 131, + -1, 138, 133, 134, -1, 133, 134, -1, -1, 33, + -1, 34, -1, 35, -1, 139, -1, 136, -1, 135, + 79, 45, -1, 135, 79, 45, 74, 75, -1, 135, + 79, 45, 74, 125, 75, -1, 135, 79, 45, 81, + 150, -1, 137, -1, 137, 45, -1, 137, 45, 74, + 75, -1, 137, 45, 74, 125, 75, -1, 137, 45, + 81, 150, -1, 3, 45, -1, 139, -1, 138, 139, -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, + 36, -1, 141, -1, 140, 141, -1, 4, -1, 5, + -1, 6, -1, 142, -1, 142, 74, 125, 75, -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 + 32, -1, 41, -1, 42, -1, 43, -1, 44, -1, + 143, -1, 46, -1, -1, 38, 45, 76, 144, 146, + 77, -1, -1, 38, 76, 145, 146, 77, -1, 147, + -1, 146, 147, -1, 139, 148, 82, -1, 149, -1, + 148, 79, 149, -1, 45, -1, 45, 74, 125, 75, + -1, 122, -1, 126, -1, 154, -1, 153, -1, 151, + -1, 163, -1, 164, -1, 167, -1, 174, -1, 76, + 77, -1, -1, -1, 76, 155, 162, 156, 77, -1, + 161, -1, 153, -1, -1, 159, 161, -1, -1, 160, + 153, -1, 76, 77, -1, 76, 162, 77, -1, 152, + -1, 162, 152, -1, 82, -1, 124, 82, -1, 18, + 72, 124, 73, 165, -1, 158, 16, 158, -1, 158, + -1, 124, -1, 137, 45, 81, 150, -1, -1, 40, + 72, 168, 166, 73, 157, -1, -1, 15, 169, 158, + 40, 72, 124, 73, 82, -1, -1, 17, 72, 170, + 171, 173, 73, 157, -1, 163, -1, 151, -1, 166, + -1, -1, 172, 82, -1, 172, 82, 124, -1, 14, + 82, -1, 13, 82, -1, 20, 82, -1, 20, 124, + 82, -1, 19, 82, -1, 176, -1, 175, 176, -1, + 177, -1, 126, -1, -1, 127, 178, 161, -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 + 0, 165, 165, 200, 203, 216, 221, 226, 232, 235, + 308, 311, 420, 430, 443, 451, 550, 553, 561, 565, + 572, 576, 583, 589, 598, 606, 661, 668, 678, 681, + 691, 701, 722, 723, 724, 729, 730, 739, 751, 752, + 760, 771, 775, 776, 786, 796, 806, 819, 820, 830, + 843, 847, 851, 855, 856, 869, 870, 883, 884, 897, + 898, 915, 916, 929, 930, 931, 932, 933, 937, 940, + 951, 959, 986, 991, 998, 1036, 1039, 1046, 1054, 1075, + 1096, 1107, 1136, 1141, 1151, 1156, 1166, 1169, 1172, 1175, + 1181, 1188, 1191, 1213, 1231, 1255, 1278, 1282, 1300, 1308, + 1340, 1360, 1449, 1458, 1481, 1484, 1490, 1498, 1506, 1514, + 1524, 1531, 1534, 1537, 1543, 1546, 1561, 1565, 1569, 1573, + 1582, 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, + 1633, 1639, 1645, 1650, 1655, 1664, 1673, 1678, 1691, 1691, + 1705, 1705, 1714, 1717, 1732, 1768, 1772, 1778, 1786, 1802, + 1806, 1810, 1811, 1817, 1818, 1819, 1820, 1821, 1825, 1826, + 1826, 1826, 1836, 1837, 1841, 1841, 1842, 1842, 1847, 1850, + 1860, 1863, 1869, 1870, 1874, 1882, 1886, 1896, 1901, 1918, + 1918, 1923, 1923, 1930, 1930, 1938, 1941, 1947, 1950, 1956, + 1960, 1967, 1974, 1981, 1988, 1999, 2008, 2012, 2019, 2022, + 2028, 2028 }; #endif @@ -764,16 +784,16 @@ static const char *const yytname[] = "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", + "SAMPLER_EXTERNAL_OES", "SAMPLER2DRECT", "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", @@ -792,16 +812,16 @@ static const char *const yytname[] = "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", + "@1", "@2", "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", + "compound_statement", "@3", "@4", "statement_no_new_scope", + "statement_with_scope", "@5", "@6", "compound_statement_no_new_scope", + "statement_list", "expression_statement", "selection_statement", + "selection_rest_statement", "condition", "iteration_statement", "@7", + "@8", "@9", "for_init_statement", "conditionopt", "for_rest_statement", "jump_statement", "translation_unit", "external_declaration", - "function_definition", "@6", 0 + "function_definition", "@10", 0 }; #endif @@ -819,33 +839,34 @@ static const yytype_uint16 yytoknum[] = 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 + 345, 346, 347, 348, 349, 350 }; # 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 + 0, 96, 97, 98, 98, 98, 98, 98, 99, 99, + 99, 99, 99, 99, 100, 101, 102, 102, 103, 103, + 104, 104, 105, 105, 106, 107, 107, 107, 108, 108, + 108, 108, 109, 109, 109, 110, 110, 110, 111, 111, + 111, 112, 113, 113, 113, 113, 113, 114, 114, 114, + 115, 116, 117, 118, 118, 119, 119, 120, 120, 121, + 121, 122, 122, 123, 123, 123, 123, 123, 124, 124, + 125, 126, 126, 126, 127, 128, 128, 129, 129, 130, + 131, 131, 132, 132, 132, 132, 133, 133, 133, 133, + 134, 135, 135, 135, 135, 135, 136, 136, 136, 136, + 136, 136, 137, 137, 138, 138, 138, 138, 138, 139, + 139, 140, 140, 140, 141, 141, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, + 142, 142, 142, 142, 142, 142, 142, 142, 144, 143, + 145, 143, 146, 146, 147, 148, 148, 149, 149, 150, + 151, 152, 152, 153, 153, 153, 153, 153, 154, 155, + 156, 154, 157, 157, 159, 158, 160, 158, 161, 161, + 162, 162, 163, 163, 164, 165, 165, 166, 166, 168, + 167, 169, 167, 170, 167, 171, 171, 172, 172, 173, + 173, 174, 174, 174, 174, 174, 175, 175, 176, 176, + 178, 177 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -864,13 +885,14 @@ static const yytype_uint8 yyr2[] = 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 + 1, 1, 1, 1, 1, 1, 1, 1, 0, 6, + 0, 5, 1, 2, 3, 1, 3, 1, 4, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, + 0, 5, 1, 1, 0, 2, 0, 2, 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 @@ -880,378 +902,398 @@ 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, + 129, 130, 131, 108, 106, 0, 116, 132, 133, 134, + 135, 137, 199, 200, 0, 76, 86, 0, 91, 96, + 0, 102, 0, 109, 114, 136, 0, 196, 198, 107, + 101, 0, 0, 140, 71, 0, 74, 86, 0, 87, + 88, 89, 77, 0, 86, 0, 72, 97, 103, 110, + 0, 1, 197, 0, 138, 0, 0, 201, 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, + 59, 70, 0, 25, 73, 0, 0, 0, 142, 0, + 0, 181, 0, 0, 0, 0, 0, 159, 168, 172, + 35, 61, 68, 0, 150, 0, 114, 153, 170, 152, + 151, 0, 154, 155, 156, 157, 80, 82, 84, 0, + 0, 98, 0, 149, 100, 29, 30, 0, 12, 13, + 0, 0, 19, 18, 0, 20, 22, 24, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 115, 0, 147, 0, 145, 141, 143, + 192, 191, 166, 183, 0, 195, 193, 0, 179, 158, + 0, 64, 65, 66, 67, 63, 0, 0, 173, 169, + 171, 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 + 44, 48, 49, 54, 56, 58, 0, 139, 0, 0, + 144, 0, 0, 0, 0, 0, 194, 0, 160, 62, + 69, 0, 94, 9, 0, 0, 146, 0, 165, 167, + 186, 185, 188, 166, 177, 0, 0, 0, 81, 60, + 148, 0, 187, 0, 0, 176, 174, 0, 0, 161, + 0, 189, 0, 166, 0, 163, 180, 162, 0, 190, + 184, 175, 178, 182 }; /* 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 + 106, 107, 140, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 141, 142, 216, 143, 122, + 144, 145, 34, 35, 36, 79, 62, 63, 80, 37, + 38, 39, 40, 41, 42, 43, 123, 45, 125, 75, + 127, 128, 196, 197, 164, 147, 148, 149, 150, 210, + 277, 296, 251, 252, 253, 297, 151, 152, 153, 286, + 276, 154, 257, 202, 254, 272, 283, 284, 155, 46, + 47, 48, 55 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -250 +#define YYPACT_NINF -266 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 + 1253, -20, -266, -266, -266, 148, -266, -266, -266, -266, + -266, -266, -266, -266, -266, -266, -266, -266, -266, -266, + -266, -266, -266, -266, -266, -39, -266, -266, -266, -266, + -266, -266, -266, -18, -2, 6, 21, -61, -266, 51, + 1296, -266, 1370, -266, 25, -266, 1209, -266, -266, -266, + -266, 1370, 42, -266, -266, 50, -266, 71, 95, -266, + -266, -266, -266, 1296, 123, 105, -266, 9, -266, -266, + 974, -266, -266, 81, -266, 1296, 290, -266, -266, -266, + -266, 125, 1296, -13, -266, 776, 974, 99, -266, -266, + -266, -266, 974, 974, 974, -266, -266, -266, -266, -266, + 35, -266, -266, -266, 100, -6, 1040, 104, -266, 974, + 36, -64, -266, -21, 102, -266, -266, -266, 113, 117, + -51, -266, 108, -266, -266, 1296, 129, 1109, -266, 97, + 103, -266, 112, 114, 106, 842, 115, 116, -266, -266, + 39, -266, -266, -43, -266, -18, 47, -266, -266, -266, + -266, 374, -266, -266, -266, -266, 118, -266, -266, 908, + 974, -266, 120, -266, -266, -266, -266, 19, -266, -266, + 974, 1333, -266, -266, 974, 119, -266, -266, -266, 974, + 974, 974, 974, 974, 974, 974, 974, 974, 974, 974, + 974, 974, 974, -266, 1152, 122, -29, -266, -266, -266, + -266, -266, 121, -266, 974, -266, -266, 5, -266, -266, + 458, -266, -266, -266, -266, -266, 974, 974, -266, -266, + -266, 974, -266, 137, -266, -266, -266, 138, 111, -266, + 142, -266, -266, -266, -266, 36, 36, -266, -266, -266, + -266, -21, -21, -266, 113, 117, 82, -266, 974, 129, + -266, 175, 50, 626, 710, 38, -266, 197, 458, -266, + -266, 141, -266, -266, 974, 155, -266, 145, -266, -266, + -266, -266, 197, 121, 111, 186, 159, 160, -266, -266, + -266, 974, -266, 166, 176, 236, -266, 174, 542, -266, + 43, 974, 542, 121, 974, -266, -266, -266, 177, 111, + -266, -266, -266, -266 }; /* 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 + -266, -266, -266, -266, -266, -266, -266, 85, -266, -266, + -266, -266, -44, -266, -15, -266, -55, -19, -266, -266, + -266, 72, 70, 73, -266, -66, -83, -266, -92, -73, + 13, 14, -266, -266, -266, 180, 206, 201, 184, -266, + -266, -241, -25, -30, 262, -4, 0, -266, -266, -266, + 143, -122, -266, 22, -145, 16, -144, -226, -266, -266, + -266, -17, -265, -266, -266, -54, 63, 20, -266, -266, + 4, -266, -266, -266, -266, -266, -266, -266, -266, -266, + 231, -266, -266 }; /* 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 +#define YYTABLE_NINF -165 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, + 44, 77, 167, 163, 121, 199, 52, 220, 285, 191, + 68, 64, 162, 32, 33, 224, 275, 49, 65, 121, + 181, 66, 182, 176, 58, 50, 108, 269, 301, 6, + 7, 275, 64, 81, 183, 184, 217, 53, 69, 218, + 44, 108, 44, 207, 192, 126, 44, 73, 165, 166, + 249, 44, 81, 250, 59, 60, 61, 23, 24, 32, + 33, 159, 295, 44, 54, 178, 295, 173, 160, 185, + 186, 56, 199, 174, 58, 44, 146, 163, 228, 6, + 7, 84, 44, 85, 217, 57, 223, 256, 168, 169, + 86, 232, 226, 121, -75, 126, 67, 126, 217, 70, + 246, 211, 212, 213, 59, 60, 61, 23, 24, 170, + 214, 273, 255, 171, 220, 108, 298, 217, 74, -25, + 215, 70, 217, 179, 180, 44, 76, 44, 237, 238, + 239, 240, 49, 259, 260, 233, 234, 108, 108, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 261, 302, + 83, 146, 2, 3, 4, 121, 59, 60, 61, 187, + 188, 217, 264, 124, 126, 274, 235, 236, 241, 242, + 156, -26, 189, 172, 195, 265, 177, 108, 190, 200, + 274, 279, 121, 193, 203, 201, 204, 208, 205, 290, + 217, -116, 221, 209, 44, 225, 248, -164, 268, 299, + 58, 2, 3, 4, 108, 6, 7, 8, 9, 10, + 146, 163, 262, 263, -27, 267, 278, 281, 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, + 280, 287, 288, 23, 24, 25, 26, 289, 27, 28, + 29, 30, 87, 31, 88, 89, 90, 91, 291, 292, + 92, 93, 293, 146, 146, 294, 231, 146, 146, 303, + 244, 243, 157, 78, 245, 82, 158, 51, 194, 94, + 270, 266, 146, 258, 271, 300, 282, 72, 0, 0, + 95, 96, 0, 97, 0, 0, 0, 0, 146, 0, + 0, 0, 146, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 129, 130, 131, 0, 132, 133, 134, + 135, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 0, 23, 24, 25, 26, + 136, 27, 28, 29, 30, 87, 31, 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, 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, 94, 0, 0, 0, 137, 138, 0, 0, + 0, 0, 139, 95, 96, 0, 97, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 129, 130, 131, + 0, 132, 133, 134, 135, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, + 23, 24, 25, 26, 136, 27, 28, 29, 30, 87, + 31, 88, 89, 90, 91, 0, 0, 92, 93, 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, 0, 0, 0, 0, 0, 94, 0, 0, 0, + 137, 219, 0, 0, 0, 0, 139, 95, 96, 0, + 97, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 129, 130, 131, 0, 132, 133, 134, 135, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 0, 0, 0, 23, 24, 25, 26, 136, 27, + 28, 29, 30, 87, 31, 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, + 94, 0, 0, 0, 137, 0, 0, 0, 0, 0, + 139, 95, 96, 0, 97, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 129, 130, 131, 0, 132, + 133, 134, 135, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 0, 0, 23, 24, + 25, 26, 136, 27, 28, 29, 30, 87, 31, 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, 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, + 0, 0, 0, 0, 94, 0, 0, 0, 76, 0, + 0, 0, 0, 0, 139, 95, 96, 0, 97, 1, + 2, 3, 4, 5, 6, 7, 8, 9, 10, 129, + 130, 131, 0, 132, 133, 134, 135, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 0, 23, 24, 25, 26, 136, 27, 28, 29, + 30, 87, 31, 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, 94, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 139, 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, 29, 30, 87, 31, 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, 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, + 0, 0, 94, 0, 0, 0, 8, 9, 10, 0, + 0, 0, 139, 95, 96, 0, 97, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, + 0, 0, 0, 0, 25, 26, 0, 27, 28, 29, + 30, 87, 31, 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, 161, 8, 9, 10, 0, 0, 0, 0, 95, + 96, 0, 97, 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, + 25, 26, 0, 27, 28, 29, 30, 87, 31, 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, 8, 9, + 10, 0, 0, 0, 206, 95, 96, 0, 97, 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, + 22, 0, 0, 0, 0, 0, 25, 26, 0, 27, + 28, 29, 30, 87, 31, 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, 8, 9, 10, 0, 0, 0, + 0, 95, 96, 0, 97, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, + 0, 0, 25, 26, 0, 27, 28, 29, 30, 87, + 31, 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, + 8, 9, 10, 0, 0, 0, 0, 95, 96, 0, + 97, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 0, 0, 0, 0, 0, 25, 175, + 0, 27, 28, 29, 30, 87, 31, 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, 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, + 27, 28, 29, 30, 0, 31, 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, 198, 0, 0, 0, + 25, 26, 0, 27, 28, 29, 30, 0, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 0, 0, 0, 0, 0, 0, 0, 247, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 0, 0, 23, 24, 25, 26, 0, + 27, 28, 29, 30, 0, 31, 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, 29, 30, 0, 31, 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, + 0, 0, 0, 0, 25, 26, 0, 27, 28, 29, + 30, 0, 31, 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, 29, 30, 229, 31, + 8, 9, 10, 230, 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, 0, 29 + 0, 27, 28, 29, 30, 0, 31 }; 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, + 0, 55, 94, 86, 70, 127, 45, 151, 273, 60, + 40, 36, 85, 0, 0, 160, 257, 37, 79, 85, + 84, 82, 86, 106, 3, 45, 70, 253, 293, 8, + 9, 272, 57, 63, 55, 56, 79, 76, 42, 82, + 40, 85, 42, 135, 95, 75, 46, 51, 92, 93, + 79, 51, 82, 82, 33, 34, 35, 36, 37, 46, + 46, 74, 288, 63, 82, 109, 292, 73, 81, 90, + 91, 73, 194, 79, 3, 75, 76, 160, 170, 8, + 9, 72, 82, 74, 79, 79, 159, 82, 53, 54, + 81, 174, 73, 159, 73, 125, 45, 127, 79, 74, + 192, 62, 63, 64, 33, 34, 35, 36, 37, 74, + 71, 73, 204, 78, 258, 159, 73, 79, 76, 72, + 81, 74, 79, 87, 88, 125, 76, 127, 183, 184, + 185, 186, 37, 216, 217, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 221, 294, + 45, 151, 4, 5, 6, 221, 33, 34, 35, 57, + 58, 79, 80, 82, 194, 257, 181, 182, 187, 188, + 45, 72, 59, 73, 45, 248, 72, 221, 61, 82, + 272, 264, 248, 75, 72, 82, 72, 72, 82, 281, + 79, 72, 74, 77, 194, 75, 74, 76, 252, 291, + 3, 4, 5, 6, 248, 8, 9, 10, 11, 12, + 210, 294, 75, 75, 72, 40, 75, 72, 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, + 75, 45, 73, 36, 37, 38, 39, 77, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 82, 73, + 53, 54, 16, 253, 254, 81, 171, 257, 258, 82, + 190, 189, 82, 57, 191, 64, 82, 5, 125, 72, + 254, 249, 272, 210, 254, 292, 272, 46, -1, -1, + 83, 84, -1, 86, -1, -1, -1, -1, 288, -1, + -1, -1, 292, 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, 49, + 50, -1, -1, 53, 54, -1, -1, -1, -1, -1, -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, 72, -1, -1, -1, 76, 77, -1, -1, + -1, -1, 82, 83, 84, -1, 86, 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, 49, 50, -1, -1, 53, 54, -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, 72, -1, -1, -1, + 76, 77, -1, -1, -1, -1, 82, 83, 84, -1, + 86, 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, 49, 50, -1, + -1, 53, 54, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 72, -1, -1, -1, 76, -1, -1, -1, -1, -1, + 82, 83, 84, -1, 86, 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, 49, 50, -1, -1, 53, 54, -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, -1, -1, -1, 72, -1, -1, -1, 76, -1, + -1, -1, -1, -1, 82, 83, 84, -1, 86, 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, 49, 50, -1, -1, 53, + 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 72, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 82, 83, + 84, -1, 86, 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, -1, -1, 38, 39, - -1, 41, 42, 43, 44, 45, 46, 47, 48, -1, - -1, 51, 52, -1, -1, -1, -1, -1, -1, -1, + 30, 31, 32, -1, -1, -1, 36, 37, 38, 39, + -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, -1, -1, 53, 54, -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, 72, -1, -1, -1, 10, 11, 12, -1, + -1, -1, 82, 83, 84, -1, 86, 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, 49, 50, -1, -1, 53, + 54, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 72, -1, + -1, 75, 10, 11, 12, -1, -1, -1, -1, 83, + 84, -1, 86, 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, 49, 50, -1, -1, 53, 54, -1, -1, -1, -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, + -1, -1, -1, -1, 72, -1, -1, -1, 10, 11, + 12, -1, -1, -1, 82, 83, 84, -1, 86, 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, + 42, 43, 44, 45, 46, 47, 48, 49, 50, -1, + -1, 53, 54, -1, -1, -1, -1, -1, -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, + 72, -1, -1, 75, 10, 11, 12, -1, -1, -1, + -1, 83, 84, -1, 86, 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, 49, 50, -1, -1, 53, 54, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 72, -1, -1, -1, + 10, 11, 12, -1, -1, -1, -1, 83, 84, -1, + 86, 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, 49, + 50, -1, -1, 53, 54, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 72, 4, 5, 6, -1, -1, -1, 10, + 11, 12, -1, 83, 84, -1, 86, -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, + 41, 42, 43, 44, -1, 46, 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, 77, -1, -1, -1, + 38, 39, -1, 41, 42, 43, 44, -1, 46, -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, 77, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, -1, -1, -1, 36, 37, 38, 39, -1, + 41, 42, 43, 44, -1, 46, 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, -1, 46, 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, + -1, -1, -1, -1, 38, 39, -1, 41, 42, 43, + 44, -1, 46, 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, + 10, 11, 12, 50, -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, -1, 44 + -1, 41, 42, 43, 44, -1, 46 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -1260,34 +1302,35 @@ 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 + 30, 31, 32, 36, 37, 38, 39, 41, 42, 43, + 44, 46, 126, 127, 128, 129, 130, 135, 136, 137, + 138, 139, 140, 141, 142, 143, 175, 176, 177, 37, + 45, 140, 45, 76, 82, 178, 73, 79, 3, 33, + 34, 35, 132, 133, 138, 79, 82, 45, 139, 141, + 74, 0, 176, 141, 76, 145, 76, 161, 132, 131, + 134, 139, 133, 45, 72, 74, 81, 45, 47, 48, + 49, 50, 53, 54, 72, 83, 84, 86, 97, 98, + 99, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 125, 142, 82, 144, 139, 146, 147, 13, + 14, 15, 17, 18, 19, 20, 40, 76, 77, 82, + 108, 121, 122, 124, 126, 127, 142, 151, 152, 153, + 154, 162, 163, 164, 167, 174, 45, 131, 134, 74, + 81, 75, 125, 122, 150, 108, 108, 124, 53, 54, + 74, 78, 73, 73, 79, 39, 122, 72, 108, 87, + 88, 84, 86, 55, 56, 90, 91, 57, 58, 59, + 61, 60, 95, 75, 146, 45, 148, 149, 77, 147, + 82, 82, 169, 72, 72, 82, 82, 124, 72, 77, + 155, 62, 63, 64, 71, 81, 123, 79, 82, 77, + 152, 74, 75, 125, 150, 75, 73, 100, 124, 45, + 50, 103, 122, 108, 108, 110, 110, 112, 112, 112, + 112, 113, 113, 117, 118, 119, 124, 77, 74, 79, + 82, 158, 159, 160, 170, 124, 82, 168, 162, 122, + 122, 125, 75, 75, 80, 125, 149, 40, 161, 153, + 151, 163, 171, 73, 124, 137, 166, 156, 75, 122, + 75, 72, 166, 172, 173, 158, 165, 45, 73, 77, + 124, 82, 73, 16, 81, 153, 157, 161, 73, 124, + 157, 158, 150, 82 }; #define yyerrok (yyerrstatus = 0) @@ -1361,7 +1404,7 @@ while (YYID (0)) we won't break user code: when these are the locations we know. */ #ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL # define YY_LOCATION_PRINT(File, Loc) \ fprintf (File, "%d.%d-%d.%d", \ (Loc).first_line, (Loc).first_column, \ @@ -2614,13 +2657,6 @@ yyreduce: // // 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; @@ -3119,6 +3155,8 @@ yyreduce: prototype->setOp(EOpPrototype); (yyval.interm.intermNode) = prototype; + + context->symbolTable.pop(); ;} break; @@ -3172,7 +3210,9 @@ yyreduce: (yyval.interm).function = (yyvsp[(1) - (2)].interm.function); (yyval.interm).line = (yyvsp[(2) - (2)].lex).line; - context->symbolTable.insert(*(yyval.interm).function); + // We're at the inner scope level of the function's arguments and body statement. + // Add the function prototype to the surrounding scope instead. + context->symbolTable.getOuterLevel()->insert(*(yyval.interm).function); ;} break; @@ -3240,6 +3280,8 @@ yyreduce: TType type((yyvsp[(1) - (3)].interm.type)); function = new TFunction((yyvsp[(2) - (3)].lex).string, type); (yyval.interm.function) = function; + + context->symbolTable.push(); ;} break; @@ -3360,20 +3402,20 @@ yyreduce: { (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 ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant && !(yyvsp[(3) - (3)].lex).symbol) + { + context->error((yyvsp[(3) - (3)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(3) - (3)].lex).string->c_str(), ""); + context->recover(); + } + + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yyvsp[(3) - (3)].lex).line); + (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yyvsp[(3) - (3)].lex).line); if (context->structQualifierErrorCheck((yyvsp[(3) - (3)].lex).line, (yyval.interm).type)) context->recover(); @@ -3381,8 +3423,11 @@ yyreduce: 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)) + TVariable* variable = 0; + if (context->nonInitErrorCheck((yyvsp[(3) - (3)].lex).line, *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable)) context->recover(); + if (symbol && variable) + symbol->setId(variable->getUniqueId()); ;} break; @@ -3426,12 +3471,12 @@ yyreduce: 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; + TVariable* variable = 0; 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); + (yyval.interm).intermAggregate = context->intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context->intermediate.addSymbol(variable ? variable->getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yyvsp[(3) - (6)].lex).line), (yyvsp[(3) - (6)].lex).line); } ;} break; @@ -3471,7 +3516,8 @@ yyreduce: 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); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yyvsp[(2) - (2)].lex).line); + (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (2)].lex).line); if (context->structQualifierErrorCheck((yyvsp[(2) - (2)].lex).line, (yyval.interm).type)) context->recover(); @@ -3481,32 +3527,23 @@ yyreduce: (yyval.interm).type = (yyvsp[(1) - (2)].interm.type); - if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type)) + TVariable* variable = 0; + if (context->nonInitErrorCheck((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable)) context->recover(); + if (variable && symbol) + symbol->setId(variable->getUniqueId()); ;} 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(); + context->error((yyvsp[(2) - (4)].lex).line, "unsized array declarations not supported", (yyvsp[(2) - (4)].lex).string->c_str(), ""); + context->recover(); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yyvsp[(2) - (4)].lex).line); + (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (4)].lex).line); (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; @@ -3518,7 +3555,8 @@ yyreduce: 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); + TIntermSymbol* symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yyvsp[(2) - (5)].lex).line); + (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (5)].lex).line); if (context->structQualifierErrorCheck((yyvsp[(2) - (5)].lex).line, (yyvsp[(1) - (5)].interm.type))) context->recover(); @@ -3536,9 +3574,11 @@ yyreduce: context->recover(); (yyvsp[(1) - (5)].interm.type).setArray(true, size); - TVariable* variable; + TVariable* variable = 0; if (context->arrayErrorCheck((yyvsp[(3) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable)) context->recover(); + if (variable && symbol) + symbol->setId(variable->getUniqueId()); } ;} break; @@ -3571,8 +3611,21 @@ yyreduce: { VERTEX_ONLY("invariant declaration", (yyvsp[(1) - (2)].lex).line); - (yyval.interm).qualifier = EvqInvariantVaryingOut; - (yyval.interm).intermAggregate = 0; + if (context->globalErrorCheck((yyvsp[(1) - (2)].lex).line, context->symbolTable.atGlobalLevel(), "invariant varying")) + context->recover(); + (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yyvsp[(2) - (2)].lex).line); + if (!(yyvsp[(2) - (2)].lex).symbol) + { + context->error((yyvsp[(2) - (2)].lex).line, "undeclared identifier declared as invariant", (yyvsp[(2) - (2)].lex).string->c_str(), ""); + context->recover(); + + (yyval.interm).intermAggregate = 0; + } + else + { + TIntermSymbol *symbol = context->intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyval.interm).type), (yyvsp[(2) - (2)].lex).line); + (yyval.interm).intermAggregate = context->intermediate.makeAggregate(symbol, (yyvsp[(2) - (2)].lex).line); + } ;} break; @@ -3667,6 +3720,13 @@ yyreduce: { (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type); + + 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.type).line, (yyval.interm.type).precision, (yyvsp[(1) - (1)].interm.type).type)) { + context->recover(); + } + } ;} break; @@ -3886,13 +3946,39 @@ yyreduce: case 134: { + if (!context->supportsExtension("GL_OES_EGL_image_external")) { + context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "samplerExternalOES", ""); + context->recover(); + } + FRAG_VERT_ONLY("samplerExternalOES", (yyvsp[(1) - (1)].lex).line); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yyvsp[(1) - (1)].lex).line); + ;} + break; + + case 135: + + { + if (!context->supportsExtension("GL_ARB_texture_rectangle")) { + context->error((yyvsp[(1) - (1)].lex).line, "unsupported type", "sampler2DRect", ""); + context->recover(); + } + FRAG_VERT_ONLY("sampler2DRect", (yyvsp[(1) - (1)].lex).line); + TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; + (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yyvsp[(1) - (1)].lex).line); + ;} + break; + + case 136: + + { 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: + case 137: { // @@ -3906,40 +3992,52 @@ yyreduce: ;} break; - case 136: + case 138: + + { if (context->enterStructDeclaration((yyvsp[(2) - (3)].lex).line, *(yyvsp[(2) - (3)].lex).string)) context->recover(); ;} + break; + + case 139: { - if (context->reservedErrorCheck((yyvsp[(2) - (5)].lex).line, *(yyvsp[(2) - (5)].lex).string)) + if (context->reservedErrorCheck((yyvsp[(2) - (6)].lex).line, *(yyvsp[(2) - (6)].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); + TType* structure = new TType((yyvsp[(5) - (6)].interm.typeList), *(yyvsp[(2) - (6)].lex).string); + TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].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->error((yyvsp[(2) - (6)].lex).line, "redefinition", (yyvsp[(2) - (6)].lex).string->c_str(), "struct"); context->recover(); } - (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line); + (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (6)].lex).line); (yyval.interm.type).userDef = structure; + context->exitStructDeclaration(); ;} break; - case 137: + case 140: + + { if (context->enterStructDeclaration((yyvsp[(2) - (2)].lex).line, *(yyvsp[(2) - (2)].lex).string)) context->recover(); ;} + break; + + case 141: { - TType* structure = new TType((yyvsp[(3) - (4)].interm.typeList), TString("")); - (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (4)].lex).line); + TType* structure = new TType((yyvsp[(4) - (5)].interm.typeList), TString("")); + (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yyvsp[(1) - (5)].lex).line); (yyval.interm.type).userDef = structure; + context->exitStructDeclaration(); ;} break; - case 138: + case 142: { (yyval.interm.typeList) = (yyvsp[(1) - (1)].interm.typeList); ;} break; - case 139: + case 143: { (yyval.interm.typeList) = (yyvsp[(1) - (2)].interm.typeList); @@ -3955,7 +4053,7 @@ yyreduce: ;} break; - case 140: + case 144: { (yyval.interm.typeList) = (yyvsp[(2) - (3)].interm.typeList); @@ -3971,6 +4069,7 @@ yyreduce: type->setBasicType((yyvsp[(1) - (3)].interm.type).type); type->setNominalSize((yyvsp[(1) - (3)].interm.type).size); type->setMatrix((yyvsp[(1) - (3)].interm.type).matrix); + type->setPrecision((yyvsp[(1) - (3)].interm.type).precision); // don't allow arrays of arrays if (type->isArray()) { @@ -3983,11 +4082,15 @@ yyreduce: type->setStruct((yyvsp[(1) - (3)].interm.type).userDef->getStruct()); type->setTypeName((yyvsp[(1) - (3)].interm.type).userDef->getTypeName()); } + + if (context->structNestingErrorCheck((yyvsp[(1) - (3)].interm.type).line, *type)) { + context->recover(); + } } ;} break; - case 141: + case 145: { (yyval.interm.typeList) = NewPoolTTypeList(); @@ -3995,14 +4098,14 @@ yyreduce: ;} break; - case 142: + case 146: { (yyval.interm.typeList)->push_back((yyvsp[(3) - (3)].interm.typeLine)); ;} break; - case 143: + case 147: { if (context->reservedErrorCheck((yyvsp[(1) - (1)].lex).line, *(yyvsp[(1) - (1)].lex).string)) @@ -4014,7 +4117,7 @@ yyreduce: ;} break; - case 144: + case 148: { if (context->reservedErrorCheck((yyvsp[(1) - (4)].lex).line, *(yyvsp[(1) - (4)].lex).string)) @@ -4031,126 +4134,150 @@ yyreduce: ;} break; - case 145: + case 149: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;} break; - case 146: + case 150: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 147: + case 151: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); ;} break; - case 148: + case 152: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 149: + case 153: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 150: + case 154: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 151: + case 155: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 152: + case 156: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 153: + case 157: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 154: + case 158: { (yyval.interm.intermAggregate) = 0; ;} break; - case 155: + case 159: { context->symbolTable.push(); ;} break; - case 156: + case 160: { context->symbolTable.pop(); ;} break; - case 157: + case 161: { - if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) + if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) { (yyvsp[(3) - (5)].interm.intermAggregate)->setOp(EOpSequence); + (yyvsp[(3) - (5)].interm.intermAggregate)->setEndLine((yyvsp[(5) - (5)].lex).line); + } (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate); ;} break; - case 158: + case 162: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 159: + case 163: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 160: + case 164: + + { context->symbolTable.push(); ;} + break; + + case 165: + + { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); ;} + break; + + case 166: + + { context->symbolTable.push(); ;} + break; + + case 167: + + { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); ;} + break; + + case 168: { (yyval.interm.intermNode) = 0; ;} break; - case 161: + case 169: { - if ((yyvsp[(2) - (3)].interm.intermAggregate)) + if ((yyvsp[(2) - (3)].interm.intermAggregate)) { (yyvsp[(2) - (3)].interm.intermAggregate)->setOp(EOpSequence); + (yyvsp[(2) - (3)].interm.intermAggregate)->setEndLine((yyvsp[(3) - (3)].lex).line); + } (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate); ;} break; - case 162: + case 170: { (yyval.interm.intermAggregate) = context->intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), 0); ;} break; - case 163: + case 171: { (yyval.interm.intermAggregate) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), 0); ;} break; - case 164: + case 172: { (yyval.interm.intermNode) = 0; ;} break; - case 165: + case 173: { (yyval.interm.intermNode) = static_cast<TIntermNode*>((yyvsp[(1) - (2)].interm.intermTypedNode)); ;} break; - case 166: + case 174: { if (context->boolErrorCheck((yyvsp[(1) - (5)].lex).line, (yyvsp[(3) - (5)].interm.intermTypedNode))) @@ -4159,7 +4286,7 @@ yyreduce: ;} break; - case 167: + case 175: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode); @@ -4167,7 +4294,7 @@ yyreduce: ;} break; - case 168: + case 176: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode); @@ -4175,7 +4302,7 @@ yyreduce: ;} break; - case 169: + case 177: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); @@ -4184,7 +4311,7 @@ yyreduce: ;} break; - case 170: + case 178: { TIntermNode* intermNode; @@ -4202,12 +4329,12 @@ yyreduce: ;} break; - case 171: + case 179: { context->symbolTable.push(); ++context->loopNestingLevel; ;} break; - case 172: + case 180: { context->symbolTable.pop(); @@ -4216,12 +4343,12 @@ yyreduce: ;} break; - case 173: + case 181: { ++context->loopNestingLevel; ;} break; - case 174: + case 182: { if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode))) @@ -4232,12 +4359,12 @@ yyreduce: ;} break; - case 175: + case 183: { context->symbolTable.push(); ++context->loopNestingLevel; ;} break; - case 176: + case 184: { context->symbolTable.pop(); @@ -4246,35 +4373,35 @@ yyreduce: ;} break; - case 177: + case 185: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 178: + case 186: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 179: + case 187: { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); ;} break; - case 180: + case 188: { (yyval.interm.intermTypedNode) = 0; ;} break; - case 181: + case 189: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode); @@ -4282,7 +4409,7 @@ yyreduce: ;} break; - case 182: + case 190: { (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode); @@ -4290,7 +4417,7 @@ yyreduce: ;} break; - case 183: + case 191: { if (context->loopNestingLevel <= 0) { @@ -4301,7 +4428,7 @@ yyreduce: ;} break; - case 184: + case 192: { if (context->loopNestingLevel <= 0) { @@ -4312,7 +4439,7 @@ yyreduce: ;} break; - case 185: + case 193: { (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(1) - (2)].lex).line); @@ -4323,7 +4450,7 @@ yyreduce: ;} break; - case 186: + case 194: { (yyval.interm.intermNode) = context->intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yyvsp[(1) - (3)].lex).line); @@ -4338,7 +4465,7 @@ yyreduce: ;} break; - case 187: + case 195: { FRAG_ONLY("discard", (yyvsp[(1) - (2)].lex).line); @@ -4346,7 +4473,7 @@ yyreduce: ;} break; - case 188: + case 196: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); @@ -4354,7 +4481,7 @@ yyreduce: ;} break; - case 189: + case 197: { (yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), 0); @@ -4362,21 +4489,21 @@ yyreduce: ;} break; - case 190: + case 198: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 191: + case 199: { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); ;} break; - case 192: + case 200: { TFunction* function = (yyvsp[(1) - (1)].interm).function; @@ -4410,11 +4537,6 @@ yyreduce: } // - // 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()); @@ -4461,7 +4583,7 @@ yyreduce: ;} break; - case 193: + case 201: { //?? Check that all paths return a value if return type != void ? @@ -4470,7 +4592,7 @@ yyreduce: 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()); @@ -4481,6 +4603,11 @@ yyreduce: (yyval.interm.intermNode)->getAsAggregate()->setOptimize(context->contextPragma.optimize); (yyval.interm.intermNode)->getAsAggregate()->setDebug(context->contextPragma.debug); (yyval.interm.intermNode)->getAsAggregate()->addToPragmaTable(context->contextPragma.pragmaTable); + + if ((yyvsp[(3) - (3)].interm.intermNode) && (yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()) + (yyval.interm.intermNode)->getAsAggregate()->setEndLine((yyvsp[(3) - (3)].interm.intermNode)->getAsAggregate()->getEndLine()); + + context->symbolTable.pop(); ;} break; diff --git a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h index 05cbfd4..23945b8 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h +++ b/Source/ThirdParty/ANGLE/src/compiler/glslang_tab.h @@ -79,57 +79,59 @@ 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 + SAMPLER_EXTERNAL_OES = 298, + SAMPLER2DRECT = 299, + IDENTIFIER = 300, + TYPE_NAME = 301, + FLOATCONSTANT = 302, + INTCONSTANT = 303, + BOOLCONSTANT = 304, + FIELD_SELECTION = 305, + LEFT_OP = 306, + RIGHT_OP = 307, + INC_OP = 308, + DEC_OP = 309, + LE_OP = 310, + GE_OP = 311, + EQ_OP = 312, + NE_OP = 313, + AND_OP = 314, + OR_OP = 315, + XOR_OP = 316, + MUL_ASSIGN = 317, + DIV_ASSIGN = 318, + ADD_ASSIGN = 319, + MOD_ASSIGN = 320, + LEFT_ASSIGN = 321, + RIGHT_ASSIGN = 322, + AND_ASSIGN = 323, + XOR_ASSIGN = 324, + OR_ASSIGN = 325, + SUB_ASSIGN = 326, + LEFT_PAREN = 327, + RIGHT_PAREN = 328, + LEFT_BRACKET = 329, + RIGHT_BRACKET = 330, + LEFT_BRACE = 331, + RIGHT_BRACE = 332, + DOT = 333, + COMMA = 334, + COLON = 335, + EQUAL = 336, + SEMICOLON = 337, + BANG = 338, + DASH = 339, + TILDE = 340, + PLUS = 341, + STAR = 342, + SLASH = 343, + PERCENT = 344, + LEFT_ANGLE = 345, + RIGHT_ANGLE = 346, + VERTICAL_BAR = 347, + CARET = 348, + AMPERSAND = 349, + QUESTION = 350 }; #endif /* Tokens. */ @@ -173,57 +175,59 @@ #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 +#define SAMPLER_EXTERNAL_OES 298 +#define SAMPLER2DRECT 299 +#define IDENTIFIER 300 +#define TYPE_NAME 301 +#define FLOATCONSTANT 302 +#define INTCONSTANT 303 +#define BOOLCONSTANT 304 +#define FIELD_SELECTION 305 +#define LEFT_OP 306 +#define RIGHT_OP 307 +#define INC_OP 308 +#define DEC_OP 309 +#define LE_OP 310 +#define GE_OP 311 +#define EQ_OP 312 +#define NE_OP 313 +#define AND_OP 314 +#define OR_OP 315 +#define XOR_OP 316 +#define MUL_ASSIGN 317 +#define DIV_ASSIGN 318 +#define ADD_ASSIGN 319 +#define MOD_ASSIGN 320 +#define LEFT_ASSIGN 321 +#define RIGHT_ASSIGN 322 +#define AND_ASSIGN 323 +#define XOR_ASSIGN 324 +#define OR_ASSIGN 325 +#define SUB_ASSIGN 326 +#define LEFT_PAREN 327 +#define RIGHT_PAREN 328 +#define LEFT_BRACKET 329 +#define RIGHT_BRACKET 330 +#define LEFT_BRACE 331 +#define RIGHT_BRACE 332 +#define DOT 333 +#define COMMA 334 +#define COLON 335 +#define EQUAL 336 +#define SEMICOLON 337 +#define BANG 338 +#define DASH 339 +#define TILDE 340 +#define PLUS 341 +#define STAR 342 +#define SLASH 343 +#define PERCENT 344 +#define LEFT_ANGLE 345 +#define RIGHT_ANGLE 346 +#define VERTICAL_BAR 347 +#define CARET 348 +#define AMPERSAND 349 +#define QUESTION 350 @@ -262,7 +266,7 @@ typedef union YYSTYPE }; } interm; } -/* Line 1489 of yacc.c. */ +/* Line 1529 of yacc.c. */ YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp index 798a69a..e83c7b7 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp +++ b/Source/ThirdParty/ANGLE/src/compiler/intermOut.cpp @@ -261,6 +261,8 @@ bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node) case EOpRefract: out << "refract"; break; case EOpMul: out << "component-wise multiply"; break; + case EOpDeclaration: out << "Declaration: "; break; + default: out.message(EPrefixError, "Bad aggregation op"); } diff --git a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h index f9fa1de..1e63073 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/intermediate.h +++ b/Source/ThirdParty/ANGLE/src/compiler/intermediate.h @@ -279,7 +279,8 @@ public: init(aInit), cond(aCond), expr(aExpr), - body(aBody) { } + body(aBody), + unrollFlag(false) { } virtual TIntermLoop* getAsLoopNode() { return this; } virtual void traverse(TIntermTraverser*); @@ -290,12 +291,17 @@ public: TIntermTyped* getExpression() { return expr; } TIntermNode* getBody() { return body; } + void setUnrollFlag(bool flag) { unrollFlag = flag; } + bool getUnrollFlag() { return unrollFlag; } + protected: TLoopType type; TIntermNode* init; // for-loop initialization TIntermTyped* cond; // loop exit condition TIntermTyped* expr; // for-loop expression TIntermNode* body; // loop body + + bool unrollFlag; // Whether the loop should be unrolled or not. }; // @@ -326,17 +332,23 @@ public: // per process globalpoolallocator, then it causes increased memory usage per compile // it is essential to use "symbol = sym" to assign to symbol TIntermSymbol(int i, const TString& sym, const TType& t) : - TIntermTyped(t), id(i) { symbol = sym;} + TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; } int getId() const { return id; } const TString& getSymbol() const { return symbol; } + void setId(int newId) { id = newId; } + void setSymbol(const TString& sym) { symbol = sym; } + + const TString& getOriginalSymbol() const { return originalSymbol; } + virtual void traverse(TIntermTraverser*); virtual TIntermSymbol* getAsSymbolNode() { return this; } protected: int id; TString symbol; + TString originalSymbol; }; class TIntermConstantUnion : public TIntermTyped { @@ -398,8 +410,8 @@ protected: // class TIntermUnary : public TIntermOperator { public: - TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {} - TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {} + TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {} + TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {} virtual void traverse(TIntermTraverser*); virtual TIntermUnary* getAsUnaryNode() { return this; } @@ -408,8 +420,15 @@ public: TIntermTyped* getOperand() { return operand; } bool promote(TInfoSink&); + void setUseEmulatedFunction() { useEmulatedFunction = true; } + bool getUseEmulatedFunction() { return useEmulatedFunction; } + protected: TIntermTyped* operand; + + // If set to true, replace the built-in function call with an emulated one + // to work around driver bugs. + bool useEmulatedFunction; }; typedef TVector<TIntermNode*> TIntermSequence; @@ -420,8 +439,8 @@ typedef TMap<TString, TString> TPragmaTable; // class TIntermAggregate : public TIntermOperator { public: - TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { } - TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { } + TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0), endLine(0), useEmulatedFunction(false) { } + TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0), useEmulatedFunction(false) { } ~TIntermAggregate() { delete pragmaTable; } virtual TIntermAggregate* getAsAggregate() { return this; } @@ -441,6 +460,11 @@ public: bool getDebug() { return debug; } void addToPragmaTable(const TPragmaTable& pTable); const TPragmaTable& getPragmaTable() const { return *pragmaTable; } + void setEndLine(TSourceLoc line) { endLine = line; } + TSourceLoc getEndLine() const { return endLine; } + + void setUseEmulatedFunction() { useEmulatedFunction = true; } + bool getUseEmulatedFunction() { return useEmulatedFunction; } protected: TIntermAggregate(const TIntermAggregate&); // disallow copy constructor @@ -452,6 +476,11 @@ protected: bool optimize; bool debug; TPragmaTable *pragmaTable; + TSourceLoc endLine; + + // If set to true, replace the built-in function call with an emulated one + // to work around driver bugs. + bool useEmulatedFunction; }; // @@ -505,6 +534,8 @@ public: rightToLeft(rightToLeft), depth(0) {} + virtual ~TIntermTraverser() {} + virtual void visitSymbol(TIntermSymbol*) {} virtual void visitConstantUnion(TIntermConstantUnion*) {} virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;} diff --git a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h index 1af5064..9b3acdf 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/osinclude.h +++ b/Source/ThirdParty/ANGLE/src/compiler/osinclude.h @@ -16,7 +16,8 @@ #define ANGLE_OS_WIN #elif defined(__APPLE__) || defined(__linux__) || \ defined(__FreeBSD__) || defined(__OpenBSD__) || \ - defined(__sun) + defined(__sun) || defined(ANDROID) || \ + defined(__GLIBC__) || defined(__GNU__) #define ANGLE_OS_POSIX #else #error Unsupported platform. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c index c5636b7..a17c319 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/atom.c @@ -182,12 +182,13 @@ static int AddString(StringTable *stable, const char *s) char *str; len = (int) strlen(s); - if (stable->nextFree + len + 1 >= stable->size) { + while (stable->nextFree + len + 1 >= stable->size) { assert(stable->size < 1000000); str = (char *) malloc(stable->size*2); memcpy(str, stable->strings, stable->size); free(stable->strings); stable->strings = str; + stable->size = stable->size*2; } loc = stable->nextFree; strcpy(&stable->strings[loc], s); @@ -334,7 +335,7 @@ static int GrowAtomTable(AtomTable *atable, int size) if (newmap) atable->amap = newmap; if (newrev) - atable->amap = newrev; + atable->arev = newrev; return -1; } memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int)); diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h index 69e3425..1180853 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/compile.h @@ -59,6 +59,7 @@ typedef struct Options_Rec{ int DumpAtomTable; } Options; +#define MAX_IF_NESTING 64 struct CPPStruct_Rec { // Public members SourceLoc *pLastSourceLoc; // Set at the start of each statement by the tree walkers @@ -80,7 +81,7 @@ struct CPPStruct_Rec { // Private members: SourceLoc ltokenLoc; int ifdepth; //current #if-#else-#endif nesting in the cpp.c file (pre-processor) - int elsedepth[64]; //Keep a track of #if depth..Max allowed is 64. + int elsedepth[MAX_IF_NESTING];//Keep a track of #if depth..Max allowed is 64. int elsetracker; //#if-#else and #endif constructs...Counter. const char *ErrMsg; int CompileError; //Indicate compile error when #error, #else,#elif mismatch. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c index 204a213..13a5df1 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cpp.c @@ -53,6 +53,12 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "compiler/preprocessor/slglobals.h" +#if defined(_MSC_VER) +#pragma warning(disable: 4054) +#pragma warning(disable: 4152) +#pragma warning(disable: 4706) +#endif + static int CPPif(yystypepp * yylvalpp); /* Don't use memory.c's replacements, as we clean up properly here */ @@ -84,7 +90,6 @@ static int extensionAtom = 0; static Scope *macros = 0; #define MAX_MACRO_ARGS 64 -#define MAX_IF_NESTING 64 static SourceLoc ifloc; /* outermost #if */ @@ -285,18 +290,30 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp) atom = yylvalpp->sc_ident; if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){ depth++; cpp->ifdepth++; cpp->elsetracker++; + if (cpp->ifdepth > MAX_IF_NESTING) { + CPPErrorToInfoLog("max #if nesting depth exceeded"); + cpp->CompileError = 1; + return 0; + } + // sanity check elsetracker + if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) { + CPPErrorToInfoLog("mismatched #if/#endif statements"); + cpp->CompileError = 1; + return 0; + } cpp->elsedepth[cpp->elsetracker] = 0; - } - else if (atom == endifAtom) { + } + else if (atom == endifAtom) { if(--depth<0){ - --cpp->elsetracker; + if (cpp->elsetracker) + --cpp->elsetracker; if (cpp->ifdepth) --cpp->ifdepth; break; } - --cpp->elsetracker; - --cpp->ifdepth; - } + --cpp->elsetracker; + --cpp->ifdepth; + } else if (((int)(matchelse) != 0)&& depth==0) { if (atom == elseAtom ) { token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); @@ -325,6 +342,7 @@ static int CPPelse(int matchelse, yystypepp * yylvalpp) else if((atom==elseAtom) && (!ChkCorrectElseNesting())){ CPPErrorToInfoLog("#else after a #else"); cpp->CompileError=1; + return 0; } }; return token; @@ -456,6 +474,17 @@ static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp) val = *res; token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); token = eval(token, binop[i].prec, res, err, yylvalpp); + + if (binop[i].op == op_div || binop[i].op == op_mod) + { + if (*res == 0) + { + CPPErrorToInfoLog("preprocessor divide or modulo by zero"); + *err = 1; + return token; + } + } + *res = binop[i].op(val, *res); } return token; @@ -469,15 +498,24 @@ error: static int CPPif(yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); int res = 0, err = 0; - cpp->elsetracker++; - cpp->elsedepth[cpp->elsetracker] = 0; + if (!cpp->ifdepth++) ifloc = *cpp->tokenLoc; - if(cpp->ifdepth >MAX_IF_NESTING){ + if(cpp->ifdepth > MAX_IF_NESTING){ CPPErrorToInfoLog("max #if nesting depth exceeded"); - return 0; - } - token = eval(token, MIN_PREC, &res, &err, yylvalpp); + cpp->CompileError = 1; + return 0; + } + cpp->elsetracker++; + // sanity check elsetracker + if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) { + CPPErrorToInfoLog("mismatched #if/#endif statements"); + cpp->CompileError = 1; + return 0; + } + cpp->elsedepth[cpp->elsetracker] = 0; + + token = eval(token, MIN_PREC, &res, &err, yylvalpp); if (token != '\n') { CPPWarningToInfoLog("unexpected tokens following #if preprocessor directive - expected a newline"); while (token != '\n') { @@ -499,12 +537,20 @@ static int CPPifdef(int defined, yystypepp * yylvalpp) { int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); int name = yylvalpp->sc_ident; - if(++cpp->ifdepth >MAX_IF_NESTING){ - CPPErrorToInfoLog("max #if nesting depth exceeded"); - return 0; - } - cpp->elsetracker++; + if(++cpp->ifdepth > MAX_IF_NESTING){ + CPPErrorToInfoLog("max #if nesting depth exceeded"); + cpp->CompileError = 1; + return 0; + } + cpp->elsetracker++; + // sanity check elsetracker + if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) { + CPPErrorToInfoLog("mismatched #if/#endif statements"); + cpp->CompileError = 1; + return 0; + } cpp->elsedepth[cpp->elsetracker] = 0; + if (token != CPP_IDENTIFIER) { defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef"); } else { @@ -748,6 +794,7 @@ int readCPPline(yystypepp * yylvalpp) if (!cpp->ifdepth ){ CPPErrorToInfoLog("#else mismatch"); cpp->CompileError=1; + return 0; } token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); if (token != '\n') { @@ -763,14 +810,17 @@ int readCPPline(yystypepp * yylvalpp) token = CPPelse(0, yylvalpp); }else{ CPPErrorToInfoLog("#else after a #else"); - cpp->ifdepth=0; + cpp->ifdepth = 0; + cpp->elsetracker = 0; cpp->pastFirstStatement = 1; + cpp->CompileError = 1; return 0; } } else if (yylvalpp->sc_ident == elifAtom) { if (!cpp->ifdepth){ CPPErrorToInfoLog("#elif mismatch"); cpp->CompileError=1; + return 0; } // this token is really a dont care, but we still need to eat the tokens token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); @@ -779,18 +829,22 @@ int readCPPline(yystypepp * yylvalpp) if (token <= 0) { // EOF or error CPPErrorToInfoLog("unexpect tokens following #elif preprocessor directive - expected a newline"); cpp->CompileError = 1; - break; + return 0; } } token = CPPelse(0, yylvalpp); } else if (yylvalpp->sc_ident == endifAtom) { - --cpp->elsetracker; if (!cpp->ifdepth){ CPPErrorToInfoLog("#endif mismatch"); cpp->CompileError=1; + return 0; } else - --cpp->ifdepth; + --cpp->ifdepth; + + if (cpp->elsetracker) + --cpp->elsetracker; + } else if (yylvalpp->sc_ident == ifAtom) { token = CPPif(yylvalpp); } else if (yylvalpp->sc_ident == ifdefAtom) { @@ -1051,9 +1105,14 @@ int MacroExpand(int atom, yystypepp * yylvalpp) int ChkCorrectElseNesting(void) { - if(cpp->elsedepth[cpp->elsetracker]==0){ - cpp->elsedepth[cpp->elsetracker]=1; - return 1; + // sanity check to make sure elsetracker is in a valid range + if (cpp->elsetracker < 0 || cpp->elsetracker >= MAX_IF_NESTING) { + return 0; + } + + if (cpp->elsedepth[cpp->elsetracker] == 0) { + cpp->elsedepth[cpp->elsetracker] = 1; + return 1; } return 0; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cppstruct.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cppstruct.c index 8e142bc..58cff31 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cppstruct.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/cppstruct.c @@ -92,12 +92,12 @@ int ResetPreprocessor(void) cpp->lastSourceLoc.file = 0; cpp->lastSourceLoc.line = 0; - cpp->pC=0; - cpp->CompileError=0; - cpp->ifdepth=0; - for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++) - cpp->elsedepth[cpp->elsetracker]=0; - cpp->elsetracker=0; + cpp->pC = 0; + cpp->CompileError = 0; + cpp->ifdepth = 0; + for(cpp->elsetracker = 0; cpp->elsetracker < MAX_IF_NESTING; cpp->elsetracker++) + cpp->elsedepth[cpp->elsetracker] = 0; + cpp->elsetracker = 0; cpp->tokensBeforeEOF = 0; return 1; } diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/length_limits.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/length_limits.h new file mode 100644 index 0000000..4f1f713 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/length_limits.h @@ -0,0 +1,21 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// +// length_limits.h +// + +#if !defined(__LENGTH_LIMITS_H) +#define __LENGTH_LIMITS_H 1 + +// These constants are factored out from the rest of the headers to +// make it easier to reference them from the compiler sources. + +// These lengths do not include the NULL terminator. +#define MAX_SYMBOL_NAME_LEN 256 +#define MAX_STRING_LEN 511 + +#endif // !(defined(__LENGTH_LIMITS_H) diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.c index e6fea7a..029521a 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/memory.c @@ -52,6 +52,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "compiler/preprocessor/memory.h" +#if defined(_MSC_VER) +#pragma warning(disable: 4706) +#endif + // default alignment and chunksize, if called with 0 arguments #define CHUNKSIZE (64*1024) #define ALIGN 8 diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp new file mode 100644 index 0000000..259cc43 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.cpp @@ -0,0 +1,139 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Context.h" + +#include <algorithm> +#include <sstream> + +#include "compiler/debug.h" +#include "stl_utils.h" +#include "token_type.h" + +static bool isMacroNameReserved(const std::string* name) +{ + ASSERT(name); + + // Names prefixed with "GL_" are reserved. + if (name->substr(0, 3) == "GL_") + return true; + + // Names containing two consecutive underscores are reserved. + if (name->find("__") != std::string::npos) + return true; + + return false; +} + +namespace pp +{ + +Context::Context() + : mLexer(NULL), + mInput(NULL), + mOutput(NULL) +{ +} + +Context::~Context() +{ + destroyLexer(); +} + +bool Context::init() +{ + return initLexer(); + + // TODO(alokp): Define built-in macros here so that we do not need to + // define them everytime in process(). +} + +bool Context::process(int count, + const char* const string[], + const int length[], + TokenVector* output) +{ + ASSERT((count >=0) && (string != NULL) && (output != NULL)); + + // Setup. + mInput = new Input(count, string, length); + mOutput = output; + defineBuiltInMacro("GL_ES", 1); + + // Parse. + bool success = parse(); + + // Cleanup. + reset(); + return success; +} + +bool Context::defineMacro(pp::Token::Location location, + pp::Macro::Type type, + std::string* name, + pp::TokenVector* parameters, + pp::TokenVector* replacements) +{ + std::auto_ptr<Macro> macro(new Macro(type, name, parameters, replacements)); + if (isMacroNameReserved(name)) + { + // TODO(alokp): Report error. + return false; + } + if (isMacroDefined(name)) + { + // TODO(alokp): Report error. + return false; + } + + mMacros[*name] = macro.release(); + return true; +} + +bool Context::undefineMacro(const std::string* name) +{ + MacroSet::iterator iter = mMacros.find(*name); + if (iter == mMacros.end()) + { + // TODO(alokp): Report error. + return false; + } + mMacros.erase(iter); + return true; +} + +bool Context::isMacroDefined(const std::string* name) +{ + return mMacros.find(*name) != mMacros.end(); +} + +// Reset to initialized state. +void Context::reset() +{ + std::for_each(mMacros.begin(), mMacros.end(), DeleteSecond()); + mMacros.clear(); + + delete mInput; + mInput = NULL; + + mOutput = NULL; +} + +void Context::defineBuiltInMacro(const std::string& name, int value) +{ + std::ostringstream stream; + stream << value; + Token* token = new Token(0, INT_CONSTANT, new std::string(stream.str())); + TokenVector* replacements = new pp::TokenVector(1, token); + + mMacros[name] = new Macro(Macro::kTypeObj, + new std::string(name), + NULL, + replacements); +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h new file mode 100644 index 0000000..a812747 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Context.h @@ -0,0 +1,60 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_CONTEXT_H_ +#define COMPILER_PREPROCESSOR_CONTEXT_H_ + +#include <map> + +#include "common/angleutils.h" +#include "Input.h" +#include "Macro.h" +#include "Token.h" + +namespace pp +{ + +class Context +{ + public: + Context(); + ~Context(); + + bool init(); + bool process(int count, const char* const string[], const int length[], + TokenVector* output); + + void* lexer() { return mLexer; } + int readInput(char* buf, int maxSize); + TokenVector* output() { return mOutput; } + + bool defineMacro(pp::Token::Location location, + pp::Macro::Type type, + std::string* name, + pp::TokenVector* parameters, + pp::TokenVector* replacements); + bool undefineMacro(const std::string* name); + bool isMacroDefined(const std::string* name); + + private: + DISALLOW_COPY_AND_ASSIGN(Context); + typedef std::map<std::string, Macro*> MacroSet; + + void reset(); + bool initLexer(); + void destroyLexer(); + void defineBuiltInMacro(const std::string& name, int value); + bool parse(); + + void* mLexer; // Lexer handle. + Input* mInput; + TokenVector* mOutput; + MacroSet mMacros; // Defined macros. +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_CONTEXT_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp new file mode 100644 index 0000000..694c3bd --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.cpp @@ -0,0 +1,165 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Input.h" + +#include <cstdio> + +#include "compiler/debug.h" + +namespace pp +{ + +Input::Input(int count, const char* const string[], const int length[]) + : mCount(count), + mString(string), + mLength(length), + mIndex(-1), + mSize(0), + mError(kErrorNone), + mState(kStateInitial) +{ + ASSERT(mCount >= 0); + switchToNextString(); +} + +bool Input::eof() const +{ + ASSERT(mIndex <= mCount); + return mIndex == mCount; +} + +int Input::read(char* buf, int bufSize) +{ + int nread = 0; + int startIndex = mIndex; + // Keep reading until the buffer is full or the current string is exhausted. + while ((mIndex == startIndex) && (nread < bufSize)) + { + int c = getChar(); + if (c == EOF) + { + if (mState == kStateBlockComment) + mError = kErrorUnexpectedEOF; + break; + } + + switch (mState) + { + case kStateInitial: + if (c == '/') + { + // Potentially a comment. + switch (peekChar()) + { + case '/': + getChar(); // Eat '/'. + mState = kStateLineComment; + break; + case '*': + getChar(); // Eat '*'. + mState = kStateBlockComment; + break; + default: + // Not a comment. + buf[nread++] = c; + break; + } + } else + { + buf[nread++] = c; + } + break; + + case kStateLineComment: + if (c == '\n') + { + buf[nread++] = c; + mState = kStateInitial; + } + break; + + case kStateBlockComment: + if (c == '*' && (peekChar() == '/')) + { + getChar(); // Eat '/'. + buf[nread++] = ' '; // Replace comment with whitespace. + mState = kStateInitial; + } else if (c == '\n') + { + // Line breaks are never skipped. + buf[nread++] = c; + } + break; + + default: + ASSERT(false); + break; + } + } + + return nread; +} + +int Input::getChar() +{ + if (eof()) return EOF; + + const char* str = mString[mIndex]; + int c = str[mSize++]; + + // Switch to next string if the current one is fully read. + int length = stringLength(mIndex); + // We never read from empty string. + ASSERT(length != 0); + if (((length < 0) && (str[mSize] == '\0')) || + ((length > 0) && (mSize == length))) + switchToNextString(); + + return c; +} + +int Input::peekChar() +{ + // Save the current read position. + int index = mIndex; + int size = mSize; + int c = getChar(); + + // Restore read position. + mIndex = index; + mSize = size; + return c; +} + +void Input::switchToNextString() +{ + ASSERT(mIndex < mCount); + + mSize = 0; + do + { + ++mIndex; + } while (!eof() && isStringEmpty(mIndex)); +} + +bool Input::isStringEmpty(int index) +{ + ASSERT(index < mCount); + + const char* str = mString[mIndex]; + int length = stringLength(mIndex); + return (length == 0) || ((length < 0) && (str[0] == '\0')); +} + +int Input::stringLength(int index) +{ + ASSERT(index < mCount); + return mLength ? mLength[index] : -1; +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h new file mode 100644 index 0000000..5a1b5d1 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Input.h @@ -0,0 +1,74 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_INPUT_H_ +#define COMPILER_PREPROCESSOR_INPUT_H_ + +namespace pp +{ + +// Reads the given set of strings into input buffer. +// Strips comments. +class Input +{ + public: + Input(int count, const char* const string[], const int length[]); + + enum Error + { + kErrorNone, + kErrorUnexpectedEOF + }; + Error error() const { return mError; } + + // Returns the index of string currently being scanned. + int stringIndex() const { return mIndex; } + // Returns true if EOF has reached. + bool eof() const; + + // Reads up to bufSize characters into buf. + // Returns the number of characters read. + // It replaces each comment by a whitespace. It reads only one string + // at a time so that the lexer has opportunity to update the string number + // for meaningful diagnostic messages. + int read(char* buf, int bufSize); + +private: + enum State + { + kStateInitial, + kStateLineComment, + kStateBlockComment + }; + + int getChar(); + int peekChar(); + // Switches input buffer to the next non-empty string. + // This is called when the current string is fully read. + void switchToNextString(); + // Returns true if the given string is empty. + bool isStringEmpty(int index); + // Return the length of the given string. + // Returns a negative value for null-terminated strings. + int stringLength(int index); + + // Input. + int mCount; + const char* const* mString; + const int* mLength; + + // Current read position. + int mIndex; // Index of string currently being scanned. + int mSize; // Size of string already scanned. + + // Current error and state. + Error mError; + State mState; +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_INPUT_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp new file mode 100644 index 0000000..fccca96 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.cpp @@ -0,0 +1,45 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Macro.h" + +#include <algorithm> + +#include "stl_utils.h" + +namespace pp +{ + +Macro::Macro(Type type, + std::string* name, + TokenVector* parameters, + TokenVector* replacements) + : mType(type), + mName(name), + mParameters(parameters), + mReplacements(replacements) +{ +} + +Macro::~Macro() +{ + delete mName; + + if (mParameters) + { + std::for_each(mParameters->begin(), mParameters->end(), Delete()); + delete mParameters; + } + + if (mReplacements) + { + std::for_each(mReplacements->begin(), mReplacements->end(), Delete()); + delete mReplacements; + } +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h new file mode 100644 index 0000000..e243306 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Macro.h @@ -0,0 +1,51 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_MACRO_H_ +#define COMPILER_PREPROCESSOR_MACRO_H_ + +#include <string> +#include <vector> + +#include "common/angleutils.h" +#include "Token.h" + +namespace pp +{ + +class Macro +{ + public: + enum Type + { + kTypeObj, + kTypeFunc + }; + + // Takes ownership of pointer parameters. + Macro(Type type, + std::string* name, + TokenVector* parameters, + TokenVector* replacements); + ~Macro(); + + Type type() const { return mType; } + const std::string* identifier() const { return mName; } + const TokenVector* parameters() const { return mParameters; } + const TokenVector* replacements() const { return mReplacements; } + + private: + DISALLOW_COPY_AND_ASSIGN(Macro); + + Type mType; + std::string* mName; + TokenVector* mParameters; + TokenVector* mReplacements; +}; + +} // namespace pp +#endif COMPILER_PREPROCESSOR_MACRO_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp new file mode 100644 index 0000000..ef49e57 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.cpp @@ -0,0 +1,53 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Preprocessor.h" + +#include <algorithm> + +#include "compiler/debug.h" +#include "Context.h" +#include "stl_utils.h" + +namespace pp +{ + +Preprocessor::Preprocessor() : mContext(NULL) +{ +} + +Preprocessor::~Preprocessor() +{ + delete mContext; +} + +bool Preprocessor::init() +{ + mContext = new Context; + return mContext->init(); +} + +bool Preprocessor::process(int count, + const char* const string[], + const int length[]) +{ + ASSERT((count >=0) && (string != NULL)); + if ((count < 0) || (string == NULL)) + return false; + + reset(); + + return mContext->process(count, string, length, &mTokens); +} + +void Preprocessor::reset() +{ + std::for_each(mTokens.begin(), mTokens.end(), Delete()); + mTokens.clear(); +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h new file mode 100644 index 0000000..885bb70 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Preprocessor.h @@ -0,0 +1,42 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_PREPROCESSOR_H_ +#define COMPILER_PREPROCESSOR_PREPROCESSOR_H_ + +#include "common/angleutils.h" +#include "Token.h" + +namespace pp +{ + +class Context; + +class Preprocessor +{ + public: + Preprocessor(); + ~Preprocessor(); + + bool init(); + + bool process(int count, const char* const string[], const int length[]); + TokenIterator begin() const { return mTokens.begin(); } + TokenIterator end() const { return mTokens.end(); } + + private: + DISALLOW_COPY_AND_ASSIGN(Preprocessor); + + // Reset to initialized state. + void reset(); + + Context* mContext; + TokenVector mTokens; // Output. +}; + +} // namespace pp +#endif // COMPILER_PREPROCESSOR_PREPROCESSOR_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp new file mode 100644 index 0000000..a2e759c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.cpp @@ -0,0 +1,55 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#include "Token.h" + +#include "token_type.h" + +static const int kLocationLineSize = 16; // in bits. +static const int kLocationLineMask = (1 << kLocationLineSize) - 1; + +namespace pp +{ + +Token::Location Token::encodeLocation(int line, int file) +{ + return (file << kLocationLineSize) | (line & kLocationLineMask); +} + +void Token::decodeLocation(Location loc, int* line, int* file) +{ + if (file) *file = loc >> kLocationLineSize; + if (line) *line = loc & kLocationLineMask; +} + +Token::Token(Location location, int type, std::string* value) + : mLocation(location), + mType(type), + mValue(value) +{ +} + +Token::~Token() { + delete mValue; +} + +std::ostream& operator<<(std::ostream& out, const Token& token) +{ + switch (token.type()) + { + case INT_CONSTANT: + case FLOAT_CONSTANT: + case IDENTIFIER: + out << *(token.value()); + break; + default: + out << static_cast<char>(token.type()); + break; + } + return out; +} +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h new file mode 100644 index 0000000..4f5a12b --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/Token.h @@ -0,0 +1,48 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_TOKEN_H_ +#define COMPILER_PREPROCESSOR_TOKEN_H_ + +#include <string> +#include <vector> + +#include "common/angleutils.h" + +namespace pp +{ + +class Token +{ + public: + typedef int Location; + static Location encodeLocation(int line, int file); + static void decodeLocation(Location loc, int* line, int* file); + + // Takes ownership of string. + Token(Location location, int type, std::string* value); + ~Token(); + + Location location() const { return mLocation; } + int type() const { return mType; } + const std::string* value() const { return mValue; } + + private: + DISALLOW_COPY_AND_ASSIGN(Token); + + Location mLocation; + int mType; + std::string* mValue; +}; + +typedef std::vector<Token*> TokenVector; +typedef TokenVector::const_iterator TokenIterator; + +extern std::ostream& operator<<(std::ostream& out, const Token& token); + +} // namepsace pp +#endif // COMPILER_PREPROCESSOR_TOKEN_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh new file mode 100755 index 0000000..5b32f71 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/generate_parser.sh @@ -0,0 +1,27 @@ +#!/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 preprocessor - pp_lex.cpp, pp_tab.h, and pp_tab.cpp + +run_flex() +{ +input_file=$script_dir/$1.l +output_source=$script_dir/$1_lex.cpp +flex --noline --nounistd --outfile=$output_source $input_file +} + +run_bison() +{ +input_file=$script_dir/$1.y +output_header=$script_dir/$1_tab.h +output_source=$script_dir/$1_tab.cpp +bison --no-lines --skeleton=yacc.c --defines=$output_header --output=$output_source $input_file +} + +script_dir=$(dirname $0) + +# Generate preprocessor +run_flex pp +run_bison pp diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l new file mode 100644 index 0000000..627ca04 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.l @@ -0,0 +1,181 @@ +/* +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +%top{ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! +} + +%{ +#include "compiler/debug.h" +#include "Context.h" +#include "pp_tab.h" + +#define YY_USER_ACTION \ + do { \ + yylloc->first_line = yylineno; \ + yylloc->first_column = yycolumn + 1; \ + yycolumn += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->readInput(buf, maxSize); + +static std::string* extractMacroName(const char* str, int len); +%} + +%option noyywrap nounput never-interactive +%option yylineno reentrant bison-bridge bison-locations +%option stack +%option prefix="pp" +%option extra-type="pp::Context*" + +HSPACE [ \t] +HASH ^{HSPACE}*#{HSPACE}* +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* +PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] + +DECIMAL_CONSTANT [1-9][0-9]* +OCTAL_CONSTANT 0[0-7]* +HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ + +DIGIT [0-9] +EXPONENT_PART [eE][+-]?{DIGIT}+ +FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") + +%% + +{HASH} { return HASH; } + +{HASH}define{HSPACE}+{IDENTIFIER}/[ \t\n] { + yylval->sval = extractMacroName(yytext, yyleng); + return HASH_DEFINE_OBJ; +} +{HASH}define{HSPACE}+{IDENTIFIER}/"(" { + yylval->sval = extractMacroName(yytext, yyleng); + return HASH_DEFINE_FUNC; +} +{HASH}undef{HSPACE}+ { return HASH_UNDEF; } + +{HASH}if { return HASH_IF; } +{HASH}ifdef { return HASH_IFDEF; } +{HASH}ifndef { return HASH_IFNDEF; } +{HASH}else { return HASH_ELSE; } +{HASH}elif { return HASH_ELIF; } +{HASH}endif { return HASH_ENDIF; } +"defined" { return DEFINED; } + +{HASH}error { return HASH_ERROR; } +{HASH}pragma { return HASH_PRAGMA; } +{HASH}extension { return HASH_EXTENSION; } +{HASH}version { return HASH_VERSION; } +{HASH}line { return HASH_LINE; } + +{IDENTIFIER} { + yylval->sval = new std::string(yytext, yyleng); + return IDENTIFIER; +} + +{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { + yylval->sval = new std::string(yytext, yyleng); + return INT_CONSTANT; +} + +({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { + yylval->sval = new std::string(yytext, yyleng); + return FLOAT_CONSTANT; +} + +{PUNCTUATOR} { return yytext[0]; } + +[ \t\v\f]+ { /* Ignore whitespace */ } + +\n { + ++yylineno; yycolumn = 0; + return yytext[0]; +} + +<*><<EOF>> { yyterminate(); } + +%% + +std::string* extractMacroName(const char* str, int len) +{ + // The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER} + // We just need to find the last HSPACE. + ASSERT(str && (len > 8)); // strlen("#define ") == 8; + + std::string* name = NULL; + for (int i = len - 1; i >= 0; --i) + { + if ((str[i] == ' ') || (str[i] == '\t')) + { + name = new std::string(str + i + 1, len - i - 1); + break; + } + } + ASSERT(name); + return name; +} + +namespace pp { + +int Context::readInput(char* buf, int maxSize) +{ + int nread = YY_NULL; + while (!mInput->eof() && + (mInput->error() == pp::Input::kErrorNone) && + (nread == YY_NULL)) + { + int line = 0, file = 0; + pp::Token::decodeLocation(yyget_lineno(mLexer), &line, &file); + file = mInput->stringIndex(); + yyset_lineno(pp::Token::encodeLocation(line, file), mLexer); + + nread = mInput->read(buf, maxSize); + + if (mInput->error() == pp::Input::kErrorUnexpectedEOF) + { + // TODO(alokp): Report error. + } + } + return nread; +} + +bool Context::initLexer() +{ + ASSERT(mLexer == NULL); + + if (yylex_init_extra(this, &mLexer)) + return false; + + yyrestart(0, mLexer); + return true; +} + +void Context::destroyLexer() +{ + ASSERT(mLexer); + + yylex_destroy(mLexer); + mLexer = NULL; +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y new file mode 100644 index 0000000..55193ab --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp.y @@ -0,0 +1,225 @@ +/* +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Yacc grammar for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_glsl_parser.sh, +WHICH GENERATES THE GLSL ES PARSER. +*/ + +%{ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! + +#include "Context.h" + +#define YYLEX_PARAM context->lexer() +#define YYDEBUG 1 +%} + +%pure-parser +%name-prefix="pp" +%locations +%parse-param {pp::Context* context} + +%union { + int ival; + std::string* sval; + pp::Token* tval; + pp::TokenVector* tlist; +} + +%{ +extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer); +static void yyerror(YYLTYPE* llocp, + pp::Context* context, + const char* reason); + +static void pushConditionalBlock(pp::Context* context, bool condition); +static void popConditionalBlock(pp::Context* context); +%} + +%token HASH HASH_UNDEF +%token HASH_IF HASH_IFDEF HASH_IFNDEF HASH_ELSE HASH_ELIF HASH_ENDIF DEFINED +%token HASH_ERROR HASH_PRAGMA HASH_EXTENSION HASH_VERSION HASH_LINE +%token <sval> HASH_DEFINE_OBJ HASH_DEFINE_FUNC +%token <sval> INT_CONSTANT FLOAT_CONSTANT IDENTIFIER +%type <ival> operator +%type <tval> conditional_token token +%type <tlist> parameter_list replacement_list conditional_list token_list +%% + +input + : /* empty */ + | input line +; + +line + : text_line + | control_line +; + +text_line + : '\n' + | token_list '\n' { + // TODO(alokp): Expand macros. + pp::TokenVector* out = context->output(); + out->insert(out->end(), $1->begin(), $1->end()); + delete $1; + } +; + +control_line + : HASH '\n' + | HASH_DEFINE_OBJ replacement_list '\n' { + context->defineMacro(@1.first_line, pp::Macro::kTypeObj, $1, NULL, $2); + } + | HASH_DEFINE_FUNC '(' parameter_list ')' replacement_list '\n' { + context->defineMacro(@1.first_line, pp::Macro::kTypeFunc, $1, $3, $5); + } + | HASH_UNDEF IDENTIFIER '\n' { + context->undefineMacro($2); + } + | HASH_IF conditional_list '\n' { + pushConditionalBlock(context, $2 ? true : false); + } + | HASH_IFDEF IDENTIFIER '\n' { + pushConditionalBlock(context, context->isMacroDefined($2)); + } + | HASH_IFNDEF IDENTIFIER '\n' { + pushConditionalBlock(context, !context->isMacroDefined($2)); + } + | HASH_ELIF conditional_list '\n' { + } + | HASH_ELSE '\n' { + } + | HASH_ENDIF '\n' { + popConditionalBlock(context); + } + | HASH_ERROR '\n' + | HASH_PRAGMA '\n' + | HASH_EXTENSION '\n' + | HASH_VERSION '\n' + | HASH_LINE '\n' +; + +replacement_list + : /* empty */ { $$ = NULL; } + | token_list + +parameter_list + : /* empty */ { $$ = NULL; } + | IDENTIFIER { + $$ = new pp::TokenVector; + $$->push_back(new pp::Token(@1.first_line, IDENTIFIER, $1)); + } + | parameter_list ',' IDENTIFIER { + $$ = $1; + $$->push_back(new pp::Token(@3.first_line, IDENTIFIER, $3)); + } + +conditional_list + : conditional_token { + $$ = new pp::TokenVector; + $$->push_back($1); + } + | conditional_list conditional_token { + $$ = $1; + $$->push_back($2); + } +; + +token_list + : token { + $$ = new pp::TokenVector; + $$->push_back($1); + } + | token_list token { + $$ = $1; + $$->push_back($2); + } +; + +conditional_token + : DEFINED IDENTIFIER { + } + | DEFINED '(' IDENTIFIER ')' { + } + | token +; + +token + : operator { + $$ = new pp::Token(@1.first_line, $1, NULL); + } + | INT_CONSTANT { + $$ = new pp::Token(@1.first_line, INT_CONSTANT, $1); + } + | FLOAT_CONSTANT { + $$ = new pp::Token(@1.first_line, FLOAT_CONSTANT, $1); + } + | IDENTIFIER { + $$ = new pp::Token(@1.first_line, IDENTIFIER, $1); + } +; + +operator + : '[' { $$ = '['; } + | ']' { $$ = ']'; } + | '<' { $$ = '<'; } + | '>' { $$ = '>'; } + | '(' { $$ = '('; } + | ')' { $$ = ')'; } + | '{' { $$ = '{'; } + | '}' { $$ = '}'; } + | '.' { $$ = '.'; } + | '+' { $$ = '+'; } + | '-' { $$ = '-'; } + | '/' { $$ = '/'; } + | '*' { $$ = '*'; } + | '%' { $$ = '%'; } + | '^' { $$ = '^'; } + | '|' { $$ = '|'; } + | '&' { $$ = '&'; } + | '~' { $$ = '~'; } + | '=' { $$ = '='; } + | '!' { $$ = '!'; } + | ':' { $$ = ':'; } + | ';' { $$ = ';'; } + | ',' { $$ = ','; } + | '?' { $$ = '?'; } +; + +%% + +void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason) +{ +} + +void pushConditionalBlock(pp::Context* context, bool condition) +{ +} + +void popConditionalBlock(pp::Context* context) +{ +} + +namespace pp { +bool Context::parse() +{ + yydebug = 1; + return yyparse(this) == 0 ? true : false; +} +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp new file mode 100644 index 0000000..717e7cc --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_lex.cpp @@ -0,0 +1,2268 @@ +#line 16 "compiler/preprocessor/new/pp.l" +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + + + +#line 13 "compiler/preprocessor/new/pp_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 pprestart(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 pplex. + * 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 pprestart()), 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 pprestart (FILE *input_file ,yyscan_t yyscanner ); +void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void pppop_buffer_state (yyscan_t yyscanner ); + +static void ppensure_buffer_stack (yyscan_t yyscanner ); +static void pp_load_buffer_state (yyscan_t yyscanner ); +static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *ppalloc (yy_size_t ,yyscan_t yyscanner ); +void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void ppfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer pp_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_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 ){\ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_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 ppwrap(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 23 +#define YY_END_OF_BUFFER 24 +/* 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[105] = + { 0, + 0, 0, 24, 23, 21, 22, 20, 20, 18, 18, + 17, 17, 21, 1, 21, 19, 19, 18, 0, 0, + 0, 18, 17, 17, 21, 1, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 19, 18, 17, 0, + 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, + 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 17, 0, 9, 8, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 17, 0, 10, + 12, 0, 6, 0, 0, 0, 0, 11, 0, 0, + 7, 13, 4, 0, 0, 0, 15, 0, 0, 2, + + 3, 0, 14, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 6, 1, 5, 5, 1, 7, + 5, 5, 8, 5, 8, 9, 5, 10, 11, 11, + 11, 11, 11, 11, 11, 12, 12, 5, 5, 5, + 5, 5, 5, 1, 13, 13, 13, 13, 14, 13, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 15, 15, + 5, 1, 5, 5, 15, 1, 17, 13, 13, 18, + + 19, 20, 21, 15, 22, 15, 15, 23, 24, 25, + 26, 27, 15, 28, 29, 30, 31, 32, 15, 33, + 15, 15, 5, 5, 5, 5, 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[34] = + { 0, + 1, 2, 3, 1, 1, 1, 3, 1, 1, 4, + 4, 4, 5, 6, 7, 7, 5, 5, 6, 5, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7 + } ; + +static yyconst flex_int16_t yy_base[111] = + { 0, + 0, 18, 184, 185, 11, 185, 185, 21, 28, 53, + 0, 164, 39, 71, 12, 32, 34, 1, 39, 44, + 0, 0, 0, 162, 64, 0, 0, 162, 46, 160, + 157, 150, 152, 157, 70, 47, 65, 0, 153, 154, + 62, 155, 144, 141, 67, 145, 152, 150, 139, 76, + 85, 141, 143, 144, 144, 140, 135, 141, 140, 140, + 138, 135, 136, 125, 134, 127, 185, 185, 131, 122, + 124, 128, 128, 185, 122, 125, 122, 125, 123, 185, + 185, 112, 185, 120, 113, 127, 97, 0, 107, 86, + 185, 185, 105, 76, 81, 34, 185, 97, 10, 185, + + 185, 103, 185, 185, 110, 114, 118, 121, 126, 132 + } ; + +static yyconst flex_int16_t yy_def[111] = + { 0, + 105, 105, 104, 104, 104, 104, 104, 104, 104, 104, + 106, 106, 104, 104, 104, 107, 107, 9, 18, 104, + 108, 10, 106, 106, 104, 14, 14, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 108, 106, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 106, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 106, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 106, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 106, 104, 104, + 104, 104, 104, 104, 109, 104, 104, 110, 104, 104, + + 104, 110, 104, 0, 104, 104, 104, 104, 104, 104 + } ; + +static yyconst flex_int16_t yy_nxt[219] = + { 0, + 4, 5, 6, 5, 7, 4, 7, 7, 8, 9, + 10, 10, 15, 15, 15, 15, 104, 12, 4, 13, + 6, 5, 7, 14, 7, 7, 8, 9, 10, 10, + 16, 16, 16, 104, 103, 12, 17, 18, 18, 19, + 25, 20, 15, 21, 26, 35, 20, 35, 19, 19, + 35, 36, 35, 37, 37, 37, 37, 37, 37, 99, + 21, 17, 22, 22, 22, 25, 20, 15, 41, 26, + 42, 20, 27, 43, 37, 37, 37, 50, 44, 51, + 51, 51, 95, 54, 59, 51, 51, 51, 28, 29, + 55, 60, 30, 31, 51, 51, 51, 32, 100, 100, + + 97, 33, 34, 101, 100, 100, 93, 96, 95, 101, + 11, 11, 11, 11, 11, 11, 11, 23, 23, 23, + 23, 16, 94, 16, 38, 38, 38, 98, 93, 92, + 98, 98, 98, 102, 102, 102, 102, 102, 102, 91, + 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, + 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, + 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, + 58, 57, 56, 53, 52, 49, 48, 47, 46, 45, + 40, 39, 24, 104, 3, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104 + } ; + +static yyconst flex_int16_t yy_chk[219] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 5, 15, 5, 15, 18, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 8, 8, 8, 18, 99, 2, 9, 9, 9, 9, + 13, 9, 13, 9, 13, 16, 9, 17, 19, 19, + 16, 20, 17, 20, 20, 20, 36, 36, 36, 96, + 9, 10, 10, 10, 10, 25, 10, 25, 29, 25, + 29, 10, 14, 29, 37, 37, 37, 35, 29, 35, + 35, 35, 95, 41, 45, 50, 50, 50, 14, 14, + 41, 45, 14, 14, 51, 51, 51, 14, 98, 98, + + 94, 14, 14, 98, 102, 102, 93, 90, 89, 102, + 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, + 106, 107, 87, 107, 108, 108, 108, 109, 86, 85, + 109, 109, 109, 110, 110, 110, 110, 110, 110, 84, + 82, 79, 78, 77, 76, 75, 73, 72, 71, 70, + 69, 66, 65, 64, 63, 62, 61, 60, 59, 58, + 57, 56, 55, 54, 53, 52, 49, 48, 47, 46, + 44, 43, 42, 40, 39, 34, 33, 32, 31, 30, + 28, 24, 12, 3, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + + 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 104, 104, 104 + } ; + +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[24] = + { 0, +0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 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-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +#include "compiler/debug.h" +#include "Context.h" +#include "pp_tab.h" + +#define YY_USER_ACTION \ + do { \ + yylloc->first_line = yylineno; \ + yylloc->first_column = yycolumn + 1; \ + yycolumn += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->readInput(buf, maxSize); + +static std::string* extractMacroName(const char* str, int len); + +#define INITIAL 0 + +#define YY_EXTRA_TYPE pp::Context* + +/* 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; + + YYLTYPE * yylloc_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 + + # define yylloc yyg->yylloc_r + +int pplex_init (yyscan_t* scanner); + +int pplex_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 pplex_destroy (yyscan_t yyscanner ); + +int ppget_debug (yyscan_t yyscanner ); + +void ppset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); + +void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *ppget_in (yyscan_t yyscanner ); + +void ppset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *ppget_out (yyscan_t yyscanner ); + +void ppset_out (FILE * out_str ,yyscan_t yyscanner ); + +int ppget_leng (yyscan_t yyscanner ); + +char *ppget_text (yyscan_t yyscanner ); + +int ppget_lineno (yyscan_t yyscanner ); + +void ppset_lineno (int line_number ,yyscan_t yyscanner ); + +YYSTYPE * ppget_lval (yyscan_t yyscanner ); + +void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *ppget_lloc (yyscan_t yyscanner ); + + void ppset_lloc (YYLTYPE * yylloc_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 ppwrap (yyscan_t yyscanner ); +#else +extern int ppwrap (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 pplex \ + (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int pplex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_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 \ + if ( yyleng > 0 ) \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ + (yytext[yyleng - 1] == '\n'); \ + 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; + + yylval = yylval_param; + + yylloc = yylloc_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 ) { + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_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_current_state += YY_AT_BOL(); +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 >= 105 ) + 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 != 104 ); + 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 +{ return HASH; } + YY_BREAK +case 2: +/* rule 2 can match eol */ +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +{ + yylval->sval = extractMacroName(yytext, yyleng); + return HASH_DEFINE_OBJ; +} + YY_BREAK +case 3: +*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ +yyg->yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +{ + yylval->sval = extractMacroName(yytext, yyleng); + return HASH_DEFINE_FUNC; +} + YY_BREAK +case 4: +YY_RULE_SETUP +{ return HASH_UNDEF; } + YY_BREAK +case 5: +YY_RULE_SETUP +{ return HASH_IF; } + YY_BREAK +case 6: +YY_RULE_SETUP +{ return HASH_IFDEF; } + YY_BREAK +case 7: +YY_RULE_SETUP +{ return HASH_IFNDEF; } + YY_BREAK +case 8: +YY_RULE_SETUP +{ return HASH_ELSE; } + YY_BREAK +case 9: +YY_RULE_SETUP +{ return HASH_ELIF; } + YY_BREAK +case 10: +YY_RULE_SETUP +{ return HASH_ENDIF; } + YY_BREAK +case 11: +YY_RULE_SETUP +{ return DEFINED; } + YY_BREAK +case 12: +YY_RULE_SETUP +{ return HASH_ERROR; } + YY_BREAK +case 13: +YY_RULE_SETUP +{ return HASH_PRAGMA; } + YY_BREAK +case 14: +YY_RULE_SETUP +{ return HASH_EXTENSION; } + YY_BREAK +case 15: +YY_RULE_SETUP +{ return HASH_VERSION; } + YY_BREAK +case 16: +YY_RULE_SETUP +{ return HASH_LINE; } + YY_BREAK +case 17: +YY_RULE_SETUP +{ + yylval->sval = new std::string(yytext, yyleng); + return IDENTIFIER; +} + YY_BREAK +case 18: +YY_RULE_SETUP +{ + yylval->sval = new std::string(yytext, yyleng); + return INT_CONSTANT; +} + YY_BREAK +case 19: +YY_RULE_SETUP +{ + yylval->sval = new std::string(yytext, yyleng); + return FLOAT_CONSTANT; +} + YY_BREAK +case 20: +YY_RULE_SETUP +{ return yytext[0]; } + YY_BREAK +case 21: +YY_RULE_SETUP +{ /* Ignore whitespace */ } + YY_BREAK +case 22: +/* rule 22 can match eol */ +YY_RULE_SETUP +{ + ++yylineno; yycolumn = 0; + return yytext[0]; +} + YY_BREAK +case YY_STATE_EOF(INITIAL): +{ yyterminate(); } + YY_BREAK +case 23: +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 + * pplex(). 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 ( ppwrap(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 pplex */ + +/* 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. */ + pprealloc((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; + pprestart(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 *) pprealloc((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; + yy_current_state += YY_AT_BOL(); + + 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 >= 105 ) + 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 >= 105 ) + 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 == 104); + + 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. */ + pprestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( ppwrap(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; + + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); + if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) + + 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 pprestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + pp_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void pp_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 + * pppop_buffer_state(); + * pppush_buffer_state(new_buffer); + */ + ppensure_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; + pp_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (ppwrap()) processing, but the only time this flag + * is looked at is after ppwrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void pp_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 pp_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_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 *) ppalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + pp_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with pp_create_buffer() + * @param yyscanner The scanner object. + */ + void pp_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 ) + ppfree((void *) b->yy_ch_buf ,yyscanner ); + + ppfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a pprestart() or at EOF. + */ + static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + pp_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then pp_init_buffer was _probably_ + * called from pprestart() 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 pp_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 ) + pp_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 pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + ppensure_buffer_stack(yyscanner); + + /* This block is copied from pp_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 pp_switch_to_buffer. */ + pp_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 pppop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + pp_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) { + pp_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 ppensure_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**)ppalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in ppensure_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**)pprealloc + (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 ppensure_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 pp_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) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_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; + + pp_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to pplex() 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 + * pp_scan_bytes() instead. + */ +YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to pplex() 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 pp_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 *) ppalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_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 = pp_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in pp_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 *) ppalloc(new_size ,yyscanner ); + + else + yyg->yy_start_stack = (int *) pprealloc((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 ppget_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 ppget_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 ppget_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 *ppget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *ppget_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 ppget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *ppget_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 ppset_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 ppset_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( "ppset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void ppset_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( "ppset_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 pp_switch_to_buffer + */ +void ppset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void ppset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int ppget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void ppset_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 * ppget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *ppget_lloc (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* User-visible API */ + +/* pplex_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 pplex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( 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 ); +} + +/* pplex_init_extra has the same functionality as pplex_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 ppalloc in + * the yyextra field. + */ + +int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + ppset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( 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)); + + ppset_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 pplex_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 + * pplex_init() + */ + return 0; +} + +/* pplex_destroy is for both reentrant and non-reentrant scanners. */ +int pplex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + pppop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + ppfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + ppfree(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 + * pplex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + ppfree ( 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 *ppalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *pprealloc (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 ppfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see pprealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +std::string* extractMacroName(const char* str, int len) +{ + // The input string is of the form {HASH}define{HSPACE}+{IDENTIFIER} + // We just need to find the last HSPACE. + ASSERT(str && (len > 8)); // strlen("#define ") == 8; + + std::string* name = NULL; + for (int i = len - 1; i >= 0; --i) + { + if ((str[i] == ' ') || (str[i] == '\t')) + { + name = new std::string(str + i + 1, len - i - 1); + break; + } + } + ASSERT(name); + return name; +} + +namespace pp { + +int Context::readInput(char* buf, int maxSize) +{ + int nread = YY_NULL; + while (!mInput->eof() && + (mInput->error() == pp::Input::kErrorNone) && + (nread == YY_NULL)) + { + int line = 0, file = 0; + pp::Token::decodeLocation(ppget_lineno(mLexer), &line, &file); + file = mInput->stringIndex(); + ppset_lineno(pp::Token::encodeLocation(line, file),mLexer); + + nread = mInput->read(buf, maxSize); + + if (mInput->error() == pp::Input::kErrorUnexpectedEOF) + { + // TODO(alokp): Report error. + } + } + return nread; +} + +bool Context::initLexer() +{ + ASSERT(mLexer == NULL); + + if (pplex_init_extra(this,&mLexer)) + return false; + + pprestart(0,mLexer); + return true; +} + +void Context::destroyLexer() +{ + ASSERT(mLexer); + + pplex_destroy(mLexer); + mLexer = NULL; +} + +} // namespace pp + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.cpp b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.cpp new file mode 100644 index 0000000..a7b6aa0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.cpp @@ -0,0 +1,2072 @@ +/* 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 1 + +/* Substitute the variable and function names. */ +#define yyparse ppparse +#define yylex pplex +#define yyerror pperror +#define yylval pplval +#define yychar ppchar +#define yydebug ppdebug +#define yynerrs ppnerrs +#define yylloc pplloc + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + HASH = 258, + HASH_UNDEF = 259, + HASH_IF = 260, + HASH_IFDEF = 261, + HASH_IFNDEF = 262, + HASH_ELSE = 263, + HASH_ELIF = 264, + HASH_ENDIF = 265, + DEFINED = 266, + HASH_ERROR = 267, + HASH_PRAGMA = 268, + HASH_EXTENSION = 269, + HASH_VERSION = 270, + HASH_LINE = 271, + HASH_DEFINE_OBJ = 272, + HASH_DEFINE_FUNC = 273, + INT_CONSTANT = 274, + FLOAT_CONSTANT = 275, + IDENTIFIER = 276 + }; +#endif +/* Tokens. */ +#define HASH 258 +#define HASH_UNDEF 259 +#define HASH_IF 260 +#define HASH_IFDEF 261 +#define HASH_IFNDEF 262 +#define HASH_ELSE 263 +#define HASH_ELIF 264 +#define HASH_ENDIF 265 +#define DEFINED 266 +#define HASH_ERROR 267 +#define HASH_PRAGMA 268 +#define HASH_EXTENSION 269 +#define HASH_VERSION 270 +#define HASH_LINE 271 +#define HASH_DEFINE_OBJ 272 +#define HASH_DEFINE_FUNC 273 +#define INT_CONSTANT 274 +#define FLOAT_CONSTANT 275 +#define IDENTIFIER 276 + + + + +/* Copy the first part of user declarations. */ + + +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT! + +#include "Context.h" + +#define YYLEX_PARAM context->lexer() +#define YYDEBUG 1 + + +/* 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 + +{ + int ival; + std::string* sval; + pp::Token* tval; + pp::TokenVector* tlist; +} +/* Line 187 of yacc.c. */ + + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +/* Copy the second part of user declarations. */ + + +extern int yylex(YYSTYPE* lvalp, YYLTYPE* llocp, void* lexer); +static void yyerror(YYLTYPE* llocp, + pp::Context* context, + const char* reason); + +static void pushConditionalBlock(pp::Context* context, bool condition); +static void popConditionalBlock(pp::Context* context); + + +/* 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 YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss; + YYSTYPE yyvs; + YYLTYPE yyls; +}; + +/* 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) + sizeof (YYLTYPE)) \ + + 2 * 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 2 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 247 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 47 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 12 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 62 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 91 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 276 + +#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, + 22, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 43, 2, 2, 2, 37, 40, 2, + 23, 24, 36, 33, 25, 34, 32, 35, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 44, 45, + 28, 42, 29, 46, 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, 26, 2, 27, 38, 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, 30, 39, 31, 41, 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 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 4, 7, 9, 11, 13, 16, 19, + 23, 30, 34, 38, 42, 46, 50, 53, 56, 59, + 62, 65, 68, 71, 72, 74, 75, 77, 81, 83, + 86, 88, 91, 94, 99, 101, 103, 105, 107, 109, + 111, 113, 115, 117, 119, 121, 123, 125, 127, 129, + 131, 133, 135, 137, 139, 141, 143, 145, 147, 149, + 151, 153, 155 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 48, 0, -1, -1, 48, 49, -1, 50, -1, 51, + -1, 22, -1, 55, 22, -1, 3, 22, -1, 17, + 52, 22, -1, 18, 23, 53, 24, 52, 22, -1, + 4, 21, 22, -1, 5, 54, 22, -1, 6, 21, + 22, -1, 7, 21, 22, -1, 9, 54, 22, -1, + 8, 22, -1, 10, 22, -1, 12, 22, -1, 13, + 22, -1, 14, 22, -1, 15, 22, -1, 16, 22, + -1, -1, 55, -1, -1, 21, -1, 53, 25, 21, + -1, 56, -1, 54, 56, -1, 57, -1, 55, 57, + -1, 11, 21, -1, 11, 23, 21, 24, -1, 57, + -1, 58, -1, 19, -1, 20, -1, 21, -1, 26, + -1, 27, -1, 28, -1, 29, -1, 23, -1, 24, + -1, 30, -1, 31, -1, 32, -1, 33, -1, 34, + -1, 35, -1, 36, -1, 37, -1, 38, -1, 39, + -1, 40, -1, 41, -1, 42, -1, 43, -1, 44, + -1, 45, -1, 25, -1, 46, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 63, 63, 65, 69, 70, 74, 75, 84, 85, + 88, 91, 94, 97, 100, 103, 105, 107, 110, 111, + 112, 113, 114, 118, 119, 122, 123, 127, 133, 137, + 144, 148, 155, 157, 159, 163, 166, 169, 172, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201 +}; +#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", "HASH", "HASH_UNDEF", "HASH_IF", + "HASH_IFDEF", "HASH_IFNDEF", "HASH_ELSE", "HASH_ELIF", "HASH_ENDIF", + "DEFINED", "HASH_ERROR", "HASH_PRAGMA", "HASH_EXTENSION", "HASH_VERSION", + "HASH_LINE", "HASH_DEFINE_OBJ", "HASH_DEFINE_FUNC", "INT_CONSTANT", + "FLOAT_CONSTANT", "IDENTIFIER", "'\\n'", "'('", "')'", "','", "'['", + "']'", "'<'", "'>'", "'{'", "'}'", "'.'", "'+'", "'-'", "'/'", "'*'", + "'%'", "'^'", "'|'", "'&'", "'~'", "'='", "'!'", "':'", "';'", "'?'", + "$accept", "input", "line", "text_line", "control_line", + "replacement_list", "parameter_list", "conditional_list", "token_list", + "conditional_token", "token", "operator", 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, 10, 40, 41, 44, 91, 93, 60, 62, + 123, 125, 46, 43, 45, 47, 42, 37, 94, 124, + 38, 126, 61, 33, 58, 59, 63 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 47, 48, 48, 49, 49, 50, 50, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 52, 52, 53, 53, 53, 54, 54, + 55, 55, 56, 56, 56, 57, 57, 57, 57, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 0, 2, 1, 1, 1, 2, 2, 3, + 6, 3, 3, 3, 3, 3, 2, 2, 2, 2, + 2, 2, 2, 0, 1, 0, 1, 3, 1, 2, + 1, 2, 2, 4, 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 +}; + +/* 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[] = +{ + 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 23, 0, 36, 37, + 38, 6, 43, 44, 61, 39, 40, 41, 42, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 62, 3, 4, 5, 0, + 30, 35, 8, 0, 0, 0, 28, 34, 0, 0, + 16, 0, 17, 18, 19, 20, 21, 22, 0, 24, + 25, 7, 31, 11, 32, 0, 12, 29, 13, 14, + 15, 9, 26, 0, 0, 23, 0, 33, 0, 27, + 10 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 1, 46, 47, 48, 68, 83, 55, 69, 56, + 57, 51 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -55 +static const yytype_int16 yypact[] = +{ + -55, 73, -55, -17, -18, 145, -10, -9, -16, 145, + -8, 22, 23, 24, 25, 27, 201, 28, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, 173, + -55, -55, -55, 30, -19, -3, -55, -55, 31, 32, + -55, 109, -55, -55, -55, -55, -55, -55, 33, 201, + 29, -55, -55, -55, -55, 35, -55, -55, -55, -55, + -55, -55, -55, -15, -11, 201, 36, -55, 37, -55, + -55 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -55, -55, -55, -55, -55, -27, -55, 51, 60, -54, + -1, -55 +}; + +/* 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 -1 +static const yytype_uint8 yytable[] = +{ + 50, 77, 74, 53, 75, 52, 60, 77, 54, 85, + 86, 58, 59, 87, 62, 50, 18, 19, 20, 76, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 63, 64, 65, 66, 72, 67, + 82, 70, 73, 78, 79, 81, 84, 89, 88, 90, + 61, 49, 0, 0, 0, 0, 0, 0, 72, 0, + 0, 0, 0, 2, 0, 0, 3, 4, 5, 6, + 7, 8, 9, 10, 50, 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, + 54, 0, 0, 0, 0, 0, 0, 0, 18, 19, + 20, 80, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 54, 0, 0, 0, + 0, 0, 0, 0, 18, 19, 20, 0, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 18, 19, 20, 71, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 18, 19, 20, 0, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45 +}; + +static const yytype_int8 yycheck[] = +{ + 1, 55, 21, 21, 23, 22, 22, 61, 11, 24, + 25, 21, 21, 24, 22, 16, 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, 22, 22, 22, 22, 49, 22, + 21, 23, 22, 22, 22, 22, 21, 21, 85, 22, + 9, 1, -1, -1, -1, -1, -1, -1, 69, -1, + -1, -1, -1, 0, -1, -1, 3, 4, 5, 6, + 7, 8, 9, 10, 85, 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, + 11, -1, -1, -1, -1, -1, -1, -1, 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, 11, -1, -1, -1, + -1, -1, -1, -1, 19, 20, 21, -1, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 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, + 19, 20, 21, -1, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 48, 0, 3, 4, 5, 6, 7, 8, 9, + 10, 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, 49, 50, 51, 55, + 57, 58, 22, 21, 11, 54, 56, 57, 21, 21, + 22, 54, 22, 22, 22, 22, 22, 22, 52, 55, + 23, 22, 57, 22, 21, 23, 22, 56, 22, 22, + 22, 22, 21, 53, 21, 24, 25, 24, 52, 21, + 22 +}; + +#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 (&yylloc, 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, &yylloc, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, &yylloc) +#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, Location, 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, YYLTYPE const * const yylocationp, pp::Context* context) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + pp::Context* context; +#endif +{ + if (!yyvaluep) + return; + YYUSE (yylocationp); + 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, YYLTYPE const * const yylocationp, pp::Context* context) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + YYLTYPE const * const yylocationp; + pp::Context* context; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + YY_LOCATION_PRINT (yyoutput, *yylocationp); + YYFPRINTF (yyoutput, ": "); + yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, 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, YYLTYPE *yylsp, int yyrule, pp::Context* context) +#else +static void +yy_reduce_print (yyvsp, yylsp, yyrule, context) + YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyrule; + pp::Context* 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)]) + , &(yylsp[(yyi + 1) - (yynrhs)]) , context); + fprintf (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, yylsp, 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, YYLTYPE *yylocationp, pp::Context* context) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, yylocationp, context) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + YYLTYPE *yylocationp; + pp::Context* context; +#endif +{ + YYUSE (yyvaluep); + YYUSE (yylocationp); + 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 (pp::Context* 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 (pp::Context* context) +#else +int +yyparse (context) + pp::Context* 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; +/* Location data for the look-ahead symbol. */ +YYLTYPE yylloc; + + 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; + + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp; + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[2]; + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + + /* 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; + yylsp = yyls; +#if YYLTYPE_IS_TRIVIAL + /* Initialize the default location before parsing starts. */ + yylloc.first_line = yylloc.last_line = 1; + yylloc.first_column = yylloc.last_column = 0; +#endif + + 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; + YYLTYPE *yyls1 = yyls; + + /* 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), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + yyls = yyls1; + 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); + YYSTACK_RELOCATE (yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + 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; + *++yylsp = yylloc; + 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]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 7: + + { + // TODO(alokp): Expand macros. + pp::TokenVector* out = context->output(); + out->insert(out->end(), (yyvsp[(1) - (2)].tlist)->begin(), (yyvsp[(1) - (2)].tlist)->end()); + delete (yyvsp[(1) - (2)].tlist); + ;} + break; + + case 9: + + { + context->defineMacro((yylsp[(1) - (3)]).first_line, pp::Macro::kTypeObj, (yyvsp[(1) - (3)].sval), NULL, (yyvsp[(2) - (3)].tlist)); + ;} + break; + + case 10: + + { + context->defineMacro((yylsp[(1) - (6)]).first_line, pp::Macro::kTypeFunc, (yyvsp[(1) - (6)].sval), (yyvsp[(3) - (6)].tlist), (yyvsp[(5) - (6)].tlist)); + ;} + break; + + case 11: + + { + context->undefineMacro((yyvsp[(2) - (3)].sval)); + ;} + break; + + case 12: + + { + pushConditionalBlock(context, (yyvsp[(2) - (3)].tlist) ? true : false); + ;} + break; + + case 13: + + { + pushConditionalBlock(context, context->isMacroDefined((yyvsp[(2) - (3)].sval))); + ;} + break; + + case 14: + + { + pushConditionalBlock(context, !context->isMacroDefined((yyvsp[(2) - (3)].sval))); + ;} + break; + + case 15: + + { + ;} + break; + + case 16: + + { + ;} + break; + + case 17: + + { + popConditionalBlock(context); + ;} + break; + + case 23: + + { (yyval.tlist) = NULL; ;} + break; + + case 25: + + { (yyval.tlist) = NULL; ;} + break; + + case 26: + + { + (yyval.tlist) = new pp::TokenVector; + (yyval.tlist)->push_back(new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval))); + ;} + break; + + case 27: + + { + (yyval.tlist) = (yyvsp[(1) - (3)].tlist); + (yyval.tlist)->push_back(new pp::Token((yylsp[(3) - (3)]).first_line, IDENTIFIER, (yyvsp[(3) - (3)].sval))); + ;} + break; + + case 28: + + { + (yyval.tlist) = new pp::TokenVector; + (yyval.tlist)->push_back((yyvsp[(1) - (1)].tval)); + ;} + break; + + case 29: + + { + (yyval.tlist) = (yyvsp[(1) - (2)].tlist); + (yyval.tlist)->push_back((yyvsp[(2) - (2)].tval)); + ;} + break; + + case 30: + + { + (yyval.tlist) = new pp::TokenVector; + (yyval.tlist)->push_back((yyvsp[(1) - (1)].tval)); + ;} + break; + + case 31: + + { + (yyval.tlist) = (yyvsp[(1) - (2)].tlist); + (yyval.tlist)->push_back((yyvsp[(2) - (2)].tval)); + ;} + break; + + case 32: + + { + ;} + break; + + case 33: + + { + ;} + break; + + case 35: + + { + (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, (yyvsp[(1) - (1)].ival), NULL); + ;} + break; + + case 36: + + { + (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, INT_CONSTANT, (yyvsp[(1) - (1)].sval)); + ;} + break; + + case 37: + + { + (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, FLOAT_CONSTANT, (yyvsp[(1) - (1)].sval)); + ;} + break; + + case 38: + + { + (yyval.tval) = new pp::Token((yylsp[(1) - (1)]).first_line, IDENTIFIER, (yyvsp[(1) - (1)].sval)); + ;} + break; + + case 39: + + { (yyval.ival) = '['; ;} + break; + + case 40: + + { (yyval.ival) = ']'; ;} + break; + + case 41: + + { (yyval.ival) = '<'; ;} + break; + + case 42: + + { (yyval.ival) = '>'; ;} + break; + + case 43: + + { (yyval.ival) = '('; ;} + break; + + case 44: + + { (yyval.ival) = ')'; ;} + break; + + case 45: + + { (yyval.ival) = '{'; ;} + break; + + case 46: + + { (yyval.ival) = '}'; ;} + break; + + case 47: + + { (yyval.ival) = '.'; ;} + break; + + case 48: + + { (yyval.ival) = '+'; ;} + break; + + case 49: + + { (yyval.ival) = '-'; ;} + break; + + case 50: + + { (yyval.ival) = '/'; ;} + break; + + case 51: + + { (yyval.ival) = '*'; ;} + break; + + case 52: + + { (yyval.ival) = '%'; ;} + break; + + case 53: + + { (yyval.ival) = '^'; ;} + break; + + case 54: + + { (yyval.ival) = '|'; ;} + break; + + case 55: + + { (yyval.ival) = '&'; ;} + break; + + case 56: + + { (yyval.ival) = '~'; ;} + break; + + case 57: + + { (yyval.ival) = '='; ;} + break; + + case 58: + + { (yyval.ival) = '!'; ;} + break; + + case 59: + + { (yyval.ival) = ':'; ;} + break; + + case 60: + + { (yyval.ival) = ';'; ;} + break; + + case 61: + + { (yyval.ival) = ','; ;} + break; + + case 62: + + { (yyval.ival) = '?'; ;} + 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; + *++yylsp = yyloc; + + /* 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 (&yylloc, 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 (&yylloc, context, yymsg); + } + else + { + yyerror (&yylloc, context, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + yyerror_range[0] = yylloc; + + 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, &yylloc, 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; + + yyerror_range[0] = yylsp[1-yylen]; + /* 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; + + yyerror_range[0] = *yylsp; + yydestruct ("Error: popping", + yystos[yystate], yyvsp, yylsp, context); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + *++yyvsp = yylval; + + yyerror_range[1] = yylloc; + /* Using YYLLOC is tempting, but would change the location of + the look-ahead. YYLOC is available though. */ + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + *++yylsp = yyloc; + + /* 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 (&yylloc, context, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEOF && yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, 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, yylsp, 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); +} + + + + + +void yyerror(YYLTYPE* llocp, pp::Context* context, const char* reason) +{ +} + +void pushConditionalBlock(pp::Context* context, bool condition) +{ +} + +void popConditionalBlock(pp::Context* context) +{ +} + +namespace pp { +bool Context::parse() +{ + yydebug = 1; + return yyparse(this) == 0 ? true : false; +} +} // namespace pp + + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h new file mode 100644 index 0000000..11ef806 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/pp_tab.h @@ -0,0 +1,119 @@ +/* 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 { + HASH = 258, + HASH_UNDEF = 259, + HASH_IF = 260, + HASH_IFDEF = 261, + HASH_IFNDEF = 262, + HASH_ELSE = 263, + HASH_ELIF = 264, + HASH_ENDIF = 265, + DEFINED = 266, + HASH_ERROR = 267, + HASH_PRAGMA = 268, + HASH_EXTENSION = 269, + HASH_VERSION = 270, + HASH_LINE = 271, + HASH_DEFINE_OBJ = 272, + HASH_DEFINE_FUNC = 273, + INT_CONSTANT = 274, + FLOAT_CONSTANT = 275, + IDENTIFIER = 276 + }; +#endif +/* Tokens. */ +#define HASH 258 +#define HASH_UNDEF 259 +#define HASH_IF 260 +#define HASH_IFDEF 261 +#define HASH_IFNDEF 262 +#define HASH_ELSE 263 +#define HASH_ELIF 264 +#define HASH_ENDIF 265 +#define DEFINED 266 +#define HASH_ERROR 267 +#define HASH_PRAGMA 268 +#define HASH_EXTENSION 269 +#define HASH_VERSION 270 +#define HASH_LINE 271 +#define HASH_DEFINE_OBJ 272 +#define HASH_DEFINE_FUNC 273 +#define INT_CONSTANT 274 +#define FLOAT_CONSTANT 275 +#define IDENTIFIER 276 + + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef union YYSTYPE + +{ + int ival; + std::string* sval; + pp::Token* tval; + pp::TokenVector* tlist; +} +/* Line 1489 of yacc.c. */ + + YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; +# define yyltype YYLTYPE /* obsolescent; will be withdrawn */ +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h new file mode 100644 index 0000000..0d1ce50 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/stl_utils.h @@ -0,0 +1,29 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// stl_utils.h: Common STL utilities. + +#ifndef COMMON_STLUTILS_H_ +#define COMMON_STLUTILS_H_ + +namespace pp +{ + +struct Delete +{ + template<class T> + void operator() (T x) { delete x; } +}; + +struct DeleteSecond +{ + template<class A, class B> + void operator() (std::pair<A, B>& x) { delete x.second; } +}; + +} // namespace pp +#endif // COMMON_STLUTILS_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h new file mode 100644 index 0000000..343a941 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/new/token_type.h @@ -0,0 +1,13 @@ +// +// Copyright (c) 2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +#ifndef COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ +#define COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ + +#include "pp_tab.h" + +#endif // COMPILER_PREPROCESSOR_TOKEN_TYPE_H_ + diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c index 7b399a0..60b66bd 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.c @@ -373,7 +373,7 @@ static int byte_scan(InputSrc *in, yystypepp * 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') { + if (ch == '.' || ch == 'e' || ch == 'E') { return lFloatConst(ch, len, yylvalpp); } else { assert(len <= MAX_SYMBOL_NAME_LEN); @@ -558,11 +558,9 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) return -1; return '\n'; } else if (ch == '*') { - int nlcount = 0; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); do { while (ch != '*') { - if (ch == '\n') nlcount++; if (ch == EOF) { CPPErrorToInfoLog("EOF IN COMMENT"); return -1; @@ -575,9 +573,6 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) return -1; } } while (ch != '/'); - if (nlcount) { - return '\n'; - } // Go try it again... } else if (ch == '=') { return CPP_DIV_ASSIGN; @@ -621,6 +616,12 @@ int yylex_CPP(char* buf, int maxSize) token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp); if(check_EOF(token)) return 0; + if (token < 0) { + // This check may need to be improved to support UTF-8 + // characters in comments. + CPPErrorToInfoLog("preprocessor encountered non-ASCII character in shader source"); + return 0; + } if (token == '#') { if (cpp->previous_token == '\n'|| cpp->previous_token == 0) { token = readCPPline(&yylvalpp); @@ -664,8 +665,6 @@ int yylex_CPP(char* buf, int maxSize) return 0; } } - - return 0; } // yylex //Checks if the token just read is EOF or not. diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h index 0fee20d..233d1dc 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/scanner.h @@ -48,10 +48,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if !defined(__SCANNER_H) #define __SCANNER_H 1 -// These lengths do not include the NULL terminator. -#define MAX_SYMBOL_NAME_LEN 127 -#define MAX_STRING_LEN 511 - +#include "compiler/preprocessor/length_limits.h" #include "compiler/preprocessor/parser.h" // Not really atom table stuff but needed first... diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.c index 5baedf5..f18b256 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/symbols.c @@ -51,6 +51,10 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "compiler/preprocessor/slglobals.h" +#if defined(_MSC_VER) +#pragma warning(disable: 4706) +#endif + /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Symbol Table Variables: /////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c index aa83d2f..d658c12 100644 --- a/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c +++ b/Source/ThirdParty/ANGLE/src/compiler/preprocessor/tokens.c @@ -54,6 +54,11 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "compiler/preprocessor/slglobals.h" #include "compiler/util.h" +#if defined(_MSC_VER) +#pragma warning(disable: 4054) +#pragma warning(disable: 4152) +#endif + /////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////// Preprocessor and Token Recorder and Playback: //////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp index 284f61d..89bc8d8 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.cpp @@ -19,10 +19,10 @@ using namespace std; namespace egl { -Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +Config::Config(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) : mDisplayMode(displayMode), mRenderTargetFormat(renderTargetFormat), mDepthStencilFormat(depthStencilFormat), mMultiSample(multiSample) { - set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample); + set(displayMode, minInterval, maxInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight); } void Config::setDefaults() @@ -62,8 +62,10 @@ void Config::setDefaults() mTransparentBlueValue = EGL_DONT_CARE; } -void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) { + mBindToTextureRGB = EGL_FALSE; + mBindToTextureRGBA = EGL_FALSE; switch (renderTargetFormat) { case D3DFMT_A1R5G5B5: @@ -86,6 +88,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mGreenSize = 8; mBlueSize = 8; mAlphaSize = 8; + mBindToTextureRGBA = true; break; case D3DFMT_R5G6B5: mBufferSize = 16; @@ -100,6 +103,7 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mGreenSize = 8; mBlueSize = 8; mAlphaSize = 0; + mBindToTextureRGB = true; break; default: UNREACHABLE(); // Other formats should not be valid @@ -107,8 +111,6 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mLuminanceSize = 0; mAlphaMaskSize = 0; - mBindToTextureRGB = EGL_FALSE; - mBindToTextureRGBA = EGL_FALSE; mColorBufferType = EGL_RGB_BUFFER; mConfigCaveat = (displayMode.Format == renderTargetFormat) ? EGL_NONE : EGL_SLOW_CONFIG; mConfigID = 0; @@ -116,6 +118,10 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter switch (depthStencilFormat) { + case D3DFMT_UNKNOWN: + mDepthSize = 0; + mStencilSize = 0; + break; // case D3DFMT_D16_LOCKABLE: // mDepthSize = 16; // mStencilSize = 0; @@ -158,9 +164,9 @@ void Config::set(D3DDISPLAYMODE displayMode, EGLint minInterval, EGLint maxInter mLevel = 0; mMatchNativePixmap = EGL_NONE; - mMaxPBufferWidth = 0; - mMaxPBufferHeight = 0; - mMaxPBufferPixels = 0; + mMaxPBufferWidth = texWidth; + mMaxPBufferHeight = texHeight; + mMaxPBufferPixels = texWidth*texHeight; mMaxSwapInterval = maxInterval; mMinSwapInterval = minInterval; mNativeRenderable = EGL_FALSE; @@ -282,9 +288,9 @@ ConfigSet::ConfigSet() { } -void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample) +void ConfigSet::add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight) { - Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample); + Config config(displayMode, minSwapInterval, maxSwapInterval, renderTargetFormat, depthStencilFormat, multiSample, texWidth, texHeight); mSet.insert(config); } @@ -315,28 +321,31 @@ bool ConfigSet::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint case EGL_RED_SIZE: match = config->mRedSize >= attribute[1]; break; case EGL_DEPTH_SIZE: match = config->mDepthSize >= attribute[1]; break; case EGL_STENCIL_SIZE: match = config->mStencilSize >= attribute[1]; break; - case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == attribute[1]; break; + case EGL_CONFIG_CAVEAT: match = config->mConfigCaveat == (EGLenum) attribute[1]; break; case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break; case EGL_LEVEL: match = config->mLevel >= attribute[1]; break; - case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break; + case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == (EGLBoolean) attribute[1]; break; case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break; case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break; case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break; case EGL_SURFACE_TYPE: match = (config->mSurfaceType & attribute[1]) == attribute[1]; break; - case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == attribute[1]; break; + case EGL_TRANSPARENT_TYPE: match = config->mTransparentType == (EGLenum) attribute[1]; break; case EGL_TRANSPARENT_BLUE_VALUE: match = config->mTransparentBlueValue == attribute[1]; break; case EGL_TRANSPARENT_GREEN_VALUE: match = config->mTransparentGreenValue == attribute[1]; break; case EGL_TRANSPARENT_RED_VALUE: match = config->mTransparentRedValue == attribute[1]; break; - case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == attribute[1]; break; - case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == attribute[1]; break; + case EGL_BIND_TO_TEXTURE_RGB: match = config->mBindToTextureRGB == (EGLBoolean) attribute[1]; break; + case EGL_BIND_TO_TEXTURE_RGBA: match = config->mBindToTextureRGBA == (EGLBoolean) attribute[1]; break; case EGL_MIN_SWAP_INTERVAL: match = config->mMinSwapInterval == attribute[1]; break; case EGL_MAX_SWAP_INTERVAL: match = config->mMaxSwapInterval == attribute[1]; break; case EGL_LUMINANCE_SIZE: match = config->mLuminanceSize >= attribute[1]; break; case EGL_ALPHA_MASK_SIZE: match = config->mAlphaMaskSize >= attribute[1]; break; - case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == attribute[1]; break; + case EGL_COLOR_BUFFER_TYPE: match = config->mColorBufferType == (EGLenum) attribute[1]; break; case EGL_RENDERABLE_TYPE: match = (config->mRenderableType & attribute[1]) == attribute[1]; break; case EGL_MATCH_NATIVE_PIXMAP: match = false; UNIMPLEMENTED(); break; case EGL_CONFORMANT: match = (config->mConformant & attribute[1]) == attribute[1]; break; + case EGL_MAX_PBUFFER_WIDTH: match = config->mMaxPBufferWidth >= attribute[1]; break; + case EGL_MAX_PBUFFER_HEIGHT: match = config->mMaxPBufferHeight >= attribute[1]; break; + case EGL_MAX_PBUFFER_PIXELS: match = config->mMaxPBufferPixels >= attribute[1]; break; default: return false; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Config.h b/Source/ThirdParty/ANGLE/src/libEGL/Config.h index b340f56..95626ed 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Config.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Config.h @@ -26,10 +26,10 @@ class Display; class Config { public: - Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + Config(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); void setDefaults(); - void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + void set(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); EGLConfig getHandle() const; const D3DDISPLAYMODE mDisplayMode; @@ -99,7 +99,7 @@ class ConfigSet public: ConfigSet(); - void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample); + void add(D3DDISPLAYMODE displayMode, EGLint minSwapInterval, EGLint maxSwapInterval, D3DFORMAT renderTargetFormat, D3DFORMAT depthStencilFormat, EGLint multiSample, EGLint texWidth, EGLint texHeight); size_t size() const; bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); const egl::Config *get(EGLConfig configHandle); diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp index 6f1a335..6a5cfd3 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,24 +11,70 @@ #include "libEGL/Display.h" #include <algorithm> +#include <map> #include <vector> #include "common/debug.h" +#include "libGLESv2/mathutil.h" +#include "libGLESv2/utilities.h" #include "libEGL/main.h" -#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 +// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros +#define REF_RAST 0 + +// The "Debug This Pixel..." feature in PIX often fails when using the +// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 +// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. +#if !defined(ANGLE_ENABLE_D3D9EX) +// Enables use of the IDirect3D9Ex interface, when available +#define ANGLE_ENABLE_D3D9EX 1 +#endif // !defined(ANGLE_ENABLE_D3D9EX) namespace egl { -Display::Display(HDC deviceContext) : mDc(deviceContext) +namespace +{ + typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; + DisplayMap displays; +} + +egl::Display *Display::getDisplay(EGLNativeDisplayType displayId) +{ + if (displays.find(displayId) != displays.end()) + { + return displays[displayId]; + } + + egl::Display *display = NULL; + + if (displayId == EGL_DEFAULT_DISPLAY) + { + display = new egl::Display(displayId, (HDC)NULL, false); + } + else if (displayId == EGL_SOFTWARE_DISPLAY_ANGLE) + { + display = new egl::Display(displayId, (HDC)NULL, true); + } + else + { + // FIXME: Check if displayId is a valid display device context + + display = new egl::Display(displayId, (HDC)displayId, false); + } + + displays[displayId] = display; + return display; +} + +Display::Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software) : mDc(deviceContext) { mD3d9Module = NULL; mD3d9 = NULL; - mD3d9ex = NULL; + mD3d9Ex = NULL; mDevice = NULL; + mDeviceEx = NULL; mDeviceWindow = NULL; mAdapter = D3DADAPTER_DEFAULT; @@ -41,11 +87,21 @@ Display::Display(HDC deviceContext) : mDc(deviceContext) mMinSwapInterval = 1; mMaxSwapInterval = 1; + mSoftwareDevice = software; + mDisplayId = displayId; + mDeviceLost = false; } Display::~Display() { terminate(); + + DisplayMap::iterator thisDisplay = displays.find(mDisplayId); + + if (thisDisplay != displays.end()) + { + displays.erase(thisDisplay); + } } bool Display::initialize() @@ -55,17 +111,15 @@ bool Display::initialize() return true; } - mD3d9Module = LoadLibrary(TEXT("d3d9.dll")); - if (mD3d9Module == NULL) + if (mSoftwareDevice) { - terminate(); - return false; + mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); + } + else + { + mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); } - - typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT); - Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9")); - - if (Direct3DCreate9Ptr == NULL) + if (mD3d9Module == NULL) { terminate(); return false; @@ -77,15 +131,15 @@ 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 (ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex))) + if (ANGLE_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { - ASSERT(mD3d9ex); - mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); + ASSERT(mD3d9Ex); + mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9)); ASSERT(mD3d9); } else { - mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION); + mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); } if (mD3d9) @@ -140,6 +194,8 @@ bool Display::initialize() if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);} if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);} + mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + const D3DFORMAT renderTargetFormats[] = { D3DFMT_A1R5G5B5, @@ -152,6 +208,7 @@ bool Display::initialize() const D3DFORMAT depthStencilFormats[] = { + D3DFMT_UNKNOWN, // D3DFMT_D16_LOCKABLE, D3DFMT_D32, // D3DFMT_D15S1, @@ -179,17 +236,26 @@ bool Display::initialize() for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++) { D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex]; - HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); + HRESULT result = D3D_OK; + + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); + } if (SUCCEEDED(result)) { - HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); + } if (SUCCEEDED(result)) { // FIXME: enumerate multi-sampling - configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0); + configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0, + mDeviceCaps.MaxTextureWidth, mDeviceCaps.MaxTextureHeight); } } } @@ -215,11 +281,19 @@ bool Display::initialize() return false; } + initExtensionString(); + static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); static const TCHAR className[] = TEXT("STATIC"); mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + if (!createDevice()) + { + terminate(); + return false; + } + return true; } @@ -235,10 +309,16 @@ void Display::terminate() destroyContext(*mContextSet.begin()); } + while (!mEventQueryPool.empty()) + { + mEventQueryPool.back()->Release(); + mEventQueryPool.pop_back(); + } + if (mDevice) { // If the device is lost, reset it first to prevent leaving the driver in an unstable state - if (FAILED(mDevice->TestCooperativeLevel())) + if (testDeviceLost()) { resetDevice(); } @@ -247,6 +327,12 @@ void Display::terminate() mDevice = NULL; } + if (mDeviceEx) + { + mDeviceEx->Release(); + mDeviceEx = NULL; + } + if (mD3d9) { mD3d9->Release(); @@ -259,15 +345,14 @@ void Display::terminate() mDeviceWindow = NULL; } - if (mD3d9ex) + if (mD3d9Ex) { - mD3d9ex->Release(); - mD3d9ex = NULL; + mD3d9Ex->Release(); + mD3d9Ex = NULL; } if (mD3d9Module) { - FreeLibrary(mD3d9Module); mD3d9Module = NULL; } } @@ -277,8 +362,11 @@ void Display::startScene() if (!mSceneStarted) { long result = mDevice->BeginScene(); - ASSERT(SUCCEEDED(result)); - mSceneStarted = true; + if (SUCCEEDED(result)) { + // This is defensive checking against the device being + // lost at unexpected times. + mSceneStarted = true; + } } } @@ -286,8 +374,9 @@ void Display::endScene() { if (mSceneStarted) { - long result = mDevice->EndScene(); - ASSERT(SUCCEEDED(result)); + // EndScene can fail if the device was lost, for example due + // to a TDR during a draw call. + mDevice->EndScene(); mSceneStarted = false; } } @@ -332,6 +421,9 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value) case EGL_RENDERABLE_TYPE: *value = configuration->mRenderableType; break; case EGL_MATCH_NATIVE_PIXMAP: *value = false; UNIMPLEMENTED(); break; case EGL_CONFORMANT: *value = configuration->mConformant; break; + case EGL_MAX_PBUFFER_WIDTH: *value = configuration->mMaxPBufferWidth; break; + case EGL_MAX_PBUFFER_HEIGHT: *value = configuration->mMaxPBufferHeight; break; + case EGL_MAX_PBUFFER_PIXELS: *value = configuration->mMaxPBufferPixels; break; default: return false; } @@ -362,48 +454,251 @@ bool Display::createDevice() } } + if (mD3d9Ex) + { + result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); + ASSERT(SUCCEEDED(result)); + } + + initializeDevice(); + + return true; +} + +// do any one-time device initialization +// NOTE: this is also needed after a device lost/reset +// to reset the scene status and ensure the default states are reset. +void Display::initializeDevice() +{ // Permanent non-default states mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); mSceneStarted = false; - - return true; } bool Display::resetDevice() { D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - HRESULT result; - - do + + HRESULT result = D3D_OK; + bool lost = testDeviceLost(); + int attempts = 3; + + while (lost && attempts > 0) { - Sleep(0); // Give the graphics driver some CPU time + if (mDeviceEx) + { + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, NULL); + } + else + { + result = mDevice->TestCooperativeLevel(); + + while (result == D3DERR_DEVICELOST) + { + Sleep(100); // Give the graphics driver some CPU time + result = mDevice->TestCooperativeLevel(); + } - result = mDevice->Reset(&presentParameters); + if (result == D3DERR_DEVICENOTRESET) + { + result = mDevice->Reset(&presentParameters); + } + } + + lost = testDeviceLost(); + attempts --; } - while (result == D3DERR_DEVICELOST); if (FAILED(result)) { + ERR("Reset/ResetEx failed multiple times: 0x%08X", result); return error(EGL_BAD_ALLOC, false); } - ASSERT(SUCCEEDED(result)); + // reset device defaults + initializeDevice(); return true; } -Surface *Display::createWindowSurface(HWND window, EGLConfig config) +EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList) { const Config *configuration = mConfigSet.get(config); + EGLint postSubBufferSupported = EGL_FALSE; + + if (attribList) + { + while (*attribList != EGL_NONE) + { + switch (attribList[0]) + { + case EGL_RENDER_BUFFER: + switch (attribList[1]) + { + case EGL_BACK_BUFFER: + break; + case EGL_SINGLE_BUFFER: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + postSubBufferSupported = attribList[1]; + break; + case EGL_VG_COLORSPACE: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + case EGL_VG_ALPHA_FORMAT: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + attribList += 2; + } + } + + if (hasExistingWindowSurface(window)) + { + return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); + } + + if (testDeviceLost()) + { + if (!restoreLostDevice()) + return EGL_NO_SURFACE; + } + + Surface *surface = new Surface(this, configuration, window, postSubBufferSupported); + + if (!surface->initialize()) + { + delete surface; + return EGL_NO_SURFACE; + } + + mSurfaceSet.insert(surface); + + return success(surface); +} + +EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList) +{ + EGLint width = 0, height = 0; + EGLenum textureFormat = EGL_NO_TEXTURE; + EGLenum textureTarget = EGL_NO_TEXTURE; + const Config *configuration = mConfigSet.get(config); + + if (attribList) + { + while (*attribList != EGL_NONE) + { + switch (attribList[0]) + { + case EGL_WIDTH: + width = attribList[1]; + break; + case EGL_HEIGHT: + height = attribList[1]; + break; + case EGL_LARGEST_PBUFFER: + if (attribList[1] != EGL_FALSE) + UNIMPLEMENTED(); // FIXME + break; + case EGL_TEXTURE_FORMAT: + switch (attribList[1]) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_RGB: + case EGL_TEXTURE_RGBA: + textureFormat = attribList[1]; + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_TEXTURE_TARGET: + switch (attribList[1]) + { + case EGL_NO_TEXTURE: + case EGL_TEXTURE_2D: + textureTarget = attribList[1]; + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + break; + case EGL_MIPMAP_TEXTURE: + if (attribList[1] != EGL_FALSE) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + break; + case EGL_VG_COLORSPACE: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + case EGL_VG_ALPHA_FORMAT: + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + default: + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + attribList += 2; + } + } + + if (width < 0 || height < 0) + { + return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } + + if (width == 0 || height == 0) + { + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + if (textureFormat != EGL_NO_TEXTURE && !getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height))) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) || + (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE)) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT)) + { + return error(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) || + (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE)) + { + return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); + } + + if (testDeviceLost()) + { + if (!restoreLostDevice()) + return EGL_NO_SURFACE; + } + + Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget); + + if (!surface->initialize()) + { + delete surface; + return EGL_NO_SURFACE; + } - Surface *surface = new Surface(this, configuration, window); mSurfaceSet.insert(surface); - return surface; + return success(surface); } -EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext) +EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { if (!mDevice) { @@ -412,28 +707,56 @@ EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *sha return NULL; } } - else if (FAILED(mDevice->TestCooperativeLevel())) // Lost device + else if (testDeviceLost()) // Lost device { - if (!resetDevice()) - { + if (!restoreLostDevice()) 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); + gl::Context *context = glCreateContext(config, shareContext, notifyResets, robustAccess); mContextSet.insert(context); + mDeviceLost = false; return context; } +bool Display::restoreLostDevice() +{ + for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++) + { + if ((*ctx)->isResetNotificationEnabled()) + return false; // If reset notifications have been requested, application must delete all contexts first + } + + // Release surface resources to make the Reset() succeed + for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) + { + (*surface)->release(); + } + + while (!mEventQueryPool.empty()) + { + mEventQueryPool.back()->Release(); + mEventQueryPool.pop_back(); + } + + if (!resetDevice()) + { + return false; + } + + // Restore any surfaces that may have been lost + for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) + { + (*surface)->resetSwapChain(); + } + + return true; +} + + void Display::destroySurface(egl::Surface *surface) { delete surface; @@ -444,17 +767,24 @@ void Display::destroyContext(gl::Context *context) { glDestroyContext(context); mContextSet.erase(context); +} - if (mContextSet.empty() && mDevice && FAILED(mDevice->TestCooperativeLevel())) // Last context of a lost device +void Display::notifyDeviceLost() +{ + for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++) { - for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++) - { - (*surface)->release(); - } + (*context)->markContextLost(); } + mDeviceLost = true; + error(EGL_CONTEXT_LOST); +} + +bool Display::isDeviceLost() +{ + return mDeviceLost; } -bool Display::isInitialized() +bool Display::isInitialized() const { return mD3d9 != NULL && mConfigSet.size() > 0; } @@ -515,6 +845,118 @@ D3DCAPS9 Display::getDeviceCaps() return mDeviceCaps; } +D3DADAPTER_IDENTIFIER9 *Display::getAdapterIdentifier() +{ + return &mAdapterIdentifier; +} + +bool Display::testDeviceLost() +{ + if (mDeviceEx) + { + return FAILED(mDeviceEx->CheckDeviceState(NULL)); + } + else if (mDevice) + { + return FAILED(mDevice->TestCooperativeLevel()); + } + + return false; // No device yet, so no reset required +} + +bool Display::testDeviceResettable() +{ + HRESULT status = D3D_OK; + + if (mDeviceEx) + { + status = mDeviceEx->CheckDeviceState(NULL); + } + else if (mDevice) + { + status = mDevice->TestCooperativeLevel(); + } + + switch (status) + { + case D3DERR_DEVICENOTRESET: + case D3DERR_DEVICEHUNG: + return true; + default: + return false; + } +} + +void Display::sync(bool block) +{ + HRESULT result; + + IDirect3DQuery9* query = allocateEventQuery(); + if (!query) + { + return; + } + + result = query->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + do + { + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + + if(block && result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + Sleep(0); + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (testDeviceLost()) + { + result = D3DERR_DEVICELOST; + } + } + } + while(block && result == S_FALSE); + + freeEventQuery(query); + + if (isDeviceLostError(result)) + { + notifyDeviceLost(); + } +} + +IDirect3DQuery9* Display::allocateEventQuery() +{ + IDirect3DQuery9 *query = NULL; + + if (mEventQueryPool.empty()) + { + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); + ASSERT(SUCCEEDED(result)); + } + else + { + query = mEventQueryPool.back(); + mEventQueryPool.pop_back(); + } + + return query; +} + +void Display::freeEventQuery(IDirect3DQuery9* query) +{ + if (mEventQueryPool.size() > 1000) + { + query->Release(); + } + else + { + mEventQueryPool.push_back(query); + } +} + void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) { for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) @@ -526,7 +968,7 @@ void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) } } -bool Display::getCompressedTextureSupport() +bool Display::getDXT1TextureSupport() { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -534,7 +976,23 @@ bool Display::getCompressedTextureSupport() return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); } -bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) +bool Display::getDXT3TextureSupport() +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3)); +} + +bool Display::getDXT5TextureSupport() +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5)); +} + +bool Display::getFloat32TextureSupport(bool *filtering, bool *renderable) { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -549,7 +1007,7 @@ bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); - if (!filtering && !renderable) + if (!*filtering && !*renderable) { return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && @@ -562,7 +1020,7 @@ bool Display::getFloatTextureSupport(bool *filtering, bool *renderable) } } -bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable) +bool Display::getFloat16TextureSupport(bool *filtering, bool *renderable) { D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -577,7 +1035,7 @@ bool Display::getHalfFloatTextureSupport(bool *filtering, bool *renderable) SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); - if (!filtering && !renderable) + if (!*filtering && !*renderable) { return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && @@ -608,7 +1066,7 @@ bool Display::getLuminanceAlphaTextureSupport() D3DPOOL Display::getBufferPool(DWORD usage) const { - if (mD3d9ex != NULL) + if (mD3d9Ex != NULL) { return D3DPOOL_DEFAULT; } @@ -623,16 +1081,35 @@ D3DPOOL Display::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -bool Display::getEventQuerySupport() +D3DPOOL Display::getTexturePool(bool renderable) const { - IDirect3DQuery9 *query; - HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); - if (SUCCEEDED(result)) + if (mD3d9Ex != NULL) { - query->Release(); + return D3DPOOL_DEFAULT; + } + else + { + if (!renderable) + { + return D3DPOOL_MANAGED; + } } - return result != D3DERR_NOTAVAILABLE; + return D3DPOOL_DEFAULT; +} + +bool Display::getEventQuerySupport() +{ + IDirect3DQuery9 *query = allocateEventQuery(); + if (query) + { + freeEventQuery(query); + return true; + } + else + { + return false; + } } D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() @@ -656,4 +1133,102 @@ D3DPRESENT_PARAMETERS Display::getDefaultPresentParameters() return presentParameters; } -}
\ No newline at end of file + +void Display::initExtensionString() +{ + HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); + + mExtensionString = ""; + + // Multi-vendor (EXT) extensions + mExtensionString += "EGL_EXT_create_context_robustness "; + + // ANGLE-specific extensions + if (shareHandleSupported()) + { + mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer "; + } + + mExtensionString += "EGL_ANGLE_query_surface_pointer "; + + if (swiftShader) + { + mExtensionString += "EGL_ANGLE_software_display "; + } + + if (shareHandleSupported()) + { + mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle "; + } + + mExtensionString += "EGL_NV_post_sub_buffer"; + + std::string::size_type end = mExtensionString.find_last_not_of(' '); + if (end != std::string::npos) + { + mExtensionString.resize(end+1); + } +} + +const char *Display::getExtensionString() const +{ + return mExtensionString.c_str(); +} + +bool Display::shareHandleSupported() const +{ + // PIX doesn't seem to support using share handles, so disable them. + return isD3d9ExDevice() && !gl::perfActive(); +} + +// Only Direct3D 10 ready devices support all the necessary vertex texture formats. +// We test this using D3D9 by checking support for the R16F format. +bool Display::getVertexTextureSupport() const +{ + if (!isInitialized() || mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(3, 0)) + { + return false; + } + + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F); + + return SUCCEEDED(result); +} + +bool Display::getNonPower2TextureSupport() const +{ + return !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL); +} + +bool Display::getOcclusionQuerySupport() const +{ + if (!isInitialized()) + { + return false; + } + + IDirect3DQuery9 *query = NULL; + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &query); + + if (SUCCEEDED(result) && query) + { + query->Release(); + return true; + } + else + { + return false; + } +} + +bool Display::getInstancingSupport() const +{ + return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Display.h b/Source/ThirdParty/ANGLE/src/libEGL/Display.h index 4b74e1e..5028431 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Display.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Display.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -18,6 +18,7 @@ #include <d3d9.h> #include <set> +#include <vector> #include "libGLESv2/Context.h" @@ -29,8 +30,6 @@ namespace egl class Display { public: - Display(HDC deviceContext); - ~Display(); bool initialize(); @@ -39,16 +38,19 @@ class Display virtual void startScene(); virtual void endScene(); + static egl::Display *getDisplay(EGLNativeDisplayType displayId); + bool getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig); bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value); - egl::Surface *createWindowSurface(HWND window, EGLConfig config); - EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext); + EGLSurface createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList); + EGLSurface createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList); + EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess); void destroySurface(egl::Surface *surface); void destroyContext(gl::Context *context); - bool isInitialized(); + bool isInitialized() const; bool isValidConfig(EGLConfig config); bool isValidContext(gl::Context *context); bool isValidSurface(egl::Surface *surface); @@ -59,20 +61,45 @@ class Display virtual IDirect3DDevice9 *getDevice(); virtual D3DCAPS9 getDeviceCaps(); + virtual D3DADAPTER_IDENTIFIER9 *getAdapterIdentifier(); + virtual bool testDeviceLost(); + virtual bool testDeviceResettable(); + virtual void sync(bool block); + virtual IDirect3DQuery9* allocateEventQuery(); + virtual void freeEventQuery(IDirect3DQuery9* query); virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); - virtual bool getCompressedTextureSupport(); + virtual bool getDXT1TextureSupport(); + virtual bool getDXT3TextureSupport(); + virtual bool getDXT5TextureSupport(); virtual bool getEventQuerySupport(); - virtual bool getFloatTextureSupport(bool *filtering, bool *renderable); - virtual bool getHalfFloatTextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); virtual bool getLuminanceTextureSupport(); virtual bool getLuminanceAlphaTextureSupport(); + virtual bool getVertexTextureSupport() const; + virtual bool getNonPower2TextureSupport() const; + virtual bool getOcclusionQuerySupport() const; + virtual bool getInstancingSupport() const; virtual D3DPOOL getBufferPool(DWORD usage) const; + virtual D3DPOOL getTexturePool(bool renderable) const; + + virtual void notifyDeviceLost(); + bool isDeviceLost(); + + bool isD3d9ExDevice() const { return mD3d9Ex != NULL; } + const char *getExtensionString() const; + bool shareHandleSupported() const; private: DISALLOW_COPY_AND_ASSIGN(Display); + Display(EGLNativeDisplayType displayId, HDC deviceContext, bool software); + D3DPRESENT_PARAMETERS getDefaultPresentParameters(); + bool restoreLostDevice(); + + EGLNativeDisplayType mDisplayId; const HDC mDc; HMODULE mD3d9Module; @@ -80,14 +107,21 @@ class Display UINT mAdapter; D3DDEVTYPE mDeviceType; IDirect3D9 *mD3d9; // Always valid after successful initialization. - IDirect3D9Ex *mD3d9ex; // Might be null if D3D9Ex is not supported. + IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3DDevice9 *mDevice; + IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. + + // A pool of event queries that are currently unused. + std::vector<IDirect3DQuery9*> mEventQueryPool; + D3DCAPS9 mDeviceCaps; + D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; HWND mDeviceWindow; bool mSceneStarted; EGLint mMaxSwapInterval; EGLint mMinSwapInterval; + bool mSoftwareDevice; typedef std::set<Surface*> SurfaceSet; SurfaceSet mSurfaceSet; @@ -96,9 +130,14 @@ class Display typedef std::set<gl::Context*> ContextSet; ContextSet mContextSet; + bool mDeviceLost; bool createDevice(); + void initializeDevice(); bool resetDevice(); + + void initExtensionString(); + std::string mExtensionString; }; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp index 2736a7f..07ad3cf 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.cpp @@ -13,21 +13,43 @@ #include "libEGL/Surface.h" #include "common/debug.h" +#include "libGLESv2/Texture.h" #include "libEGL/main.h" #include "libEGL/Display.h" +#include <dwmapi.h> + namespace egl { -Surface::Surface(Display *display, const Config *config, HWND window) - : mDisplay(display), mConfig(config), mWindow(window) + +namespace +{ +const int versionWindowsVista = MAKEWORD(0x00, 0x06); +const int versionWindows7 = MAKEWORD(0x01, 0x06); + +// Return the version of the operating system in a format suitable for ordering +// comparison. +int getComparableOSVersion() +{ + DWORD version = GetVersion(); + int majorVersion = LOBYTE(LOWORD(version)); + int minorVersion = HIBYTE(LOWORD(version)); + return MAKEWORD(minorVersion, majorVersion); +} +} + +Surface::Surface(Display *display, const Config *config, HWND window, EGLint postSubBufferSupported) + : mDisplay(display), mConfig(config), mWindow(window), mPostSubBufferSupported(postSubBufferSupported) { mSwapChain = NULL; mDepthStencil = NULL; - mBackBuffer = NULL; - mFlipTexture = NULL; - mFlipState = NULL; - mPreFlipState = NULL; + mRenderTarget = NULL; + mOffscreenTexture = NULL; + mShareHandle = NULL; + mTexture = NULL; + mTextureFormat = EGL_NO_TEXTURE; + mTextureTarget = EGL_NO_TEXTURE; mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio mRenderBuffer = EGL_BACK_BUFFER; @@ -36,7 +58,25 @@ Surface::Surface(Display *display, const Config *config, HWND window) setSwapInterval(1); subclassWindow(); - resetSwapChain(); +} + +Surface::Surface(Display *display, const Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureType) + : mDisplay(display), mWindow(NULL), mConfig(config), mShareHandle(shareHandle), mWidth(width), mHeight(height), mPostSubBufferSupported(EGL_FALSE) +{ + mSwapChain = NULL; + mDepthStencil = NULL; + mRenderTarget = NULL; + mOffscreenTexture = NULL; + mWindowSubclassed = false; + mTexture = NULL; + mTextureFormat = textureFormat; + mTextureTarget = textureType; + + mPixelAspectRatio = (EGLint)(1.0 * EGL_DISPLAY_SCALING); // FIXME: Determine actual pixel aspect ratio + mRenderBuffer = EGL_BACK_BUFFER; + mSwapBehavior = EGL_BUFFER_PRESERVED; + mSwapInterval = -1; + setSwapInterval(1); } Surface::~Surface() @@ -45,6 +85,34 @@ Surface::~Surface() release(); } +bool Surface::initialize() +{ + ASSERT(!mSwapChain && !mOffscreenTexture && !mDepthStencil); + + if (!resetSwapChain()) + return false; + + // Modify present parameters for this window, if we are composited, + // to minimize the amount of queuing done by DWM between our calls to + // present and the actual screen. + if (mWindow && (getComparableOSVersion() >= versionWindowsVista)) { + BOOL isComposited; + HRESULT result = DwmIsCompositionEnabled(&isComposited); + if (SUCCEEDED(result) && isComposited) { + DWM_PRESENT_PARAMETERS presentParams; + memset(&presentParams, 0, sizeof(presentParams)); + presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS); + presentParams.cBuffer = 2; + + result = DwmSetPresentParameters(mWindow, &presentParams); + if (FAILED(result)) + ERR("Unable to set present parameters: 0x%08X", result); + } + } + + return true; +} + void Surface::release() { if (mSwapChain) @@ -53,68 +121,116 @@ void Surface::release() mSwapChain = NULL; } - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - if (mDepthStencil) { mDepthStencil->Release(); mDepthStencil = NULL; } - if (mFlipTexture) + if (mRenderTarget) { - mFlipTexture->Release(); - mFlipTexture = NULL; + mRenderTarget->Release(); + mRenderTarget = NULL; } - if (mFlipState) + if (mOffscreenTexture) { - mFlipState->Release(); - mFlipState = NULL; + mOffscreenTexture->Release(); + mOffscreenTexture = NULL; } - if (mPreFlipState) + if (mTexture) { - mPreFlipState->Release(); - mPreFlipState = NULL; + mTexture->releaseTexImage(); + mTexture = NULL; } } -void Surface::resetSwapChain() +bool Surface::resetSwapChain() { + if (!mWindow) + { + return resetSwapChain(mWidth, mHeight); + } + RECT windowRect; if (!GetClientRect(getWindowHandle(), &windowRect)) { ASSERT(false); ERR("Could not retrieve the window dimensions"); - return; + return false; } - resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); + return resetSwapChain(windowRect.right - windowRect.left, windowRect.bottom - windowRect.top); } -void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) +bool Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) { IDirect3DDevice9 *device = mDisplay->getDevice(); if (device == NULL) { - return; + return false; + } + + IDirect3DSurface9* preservedRenderTarget = NULL; + if (mPostSubBufferSupported && mRenderTarget) + { + preservedRenderTarget = mRenderTarget; + preservedRenderTarget->AddRef(); } // 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}; + HRESULT result; + + bool useFlipEx = (getComparableOSVersion() >= versionWindows7) && mDisplay->isD3d9ExDevice(); + + // FlipEx causes unseemly stretching when resizing windows AND when one + // draws outside of the WM_PAINT callback. While this is seldom a problem in + // single process applications, it is particuarly noticeable in multiprocess + // applications. Therefore, if the creator process of our window is not in + // the current process, disable use of FlipEx. + DWORD windowPID; + GetWindowThreadProcessId(mWindow, &windowPID); + if (windowPID != GetCurrentProcessId()) + { + useFlipEx = false; + } + + // Various hardware does not support D3DSWAPEFFECT_FLIPEX when either the + // device format or back buffer format is not 32-bit. + HDC deviceContext = GetDC(0); + int deviceFormatBits = GetDeviceCaps(deviceContext, BITSPIXEL); + ReleaseDC(0, deviceContext); + if (mConfig->mBufferSize != 32 || deviceFormatBits != 32) + { + useFlipEx = false; + } + + // D3DSWAPEFFECT_FLIPEX is always VSYNCed + if (mSwapInterval == 0) + { + useFlipEx = false; + } + + // D3DSWAPEFFECT_FLIPEX does not preserve the back buffer. + if (mPostSubBufferSupported) + { + useFlipEx = false; + } presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat; + // We set BackBufferCount = 1 even when we use D3DSWAPEFFECT_FLIPEX. + // We do this because DirectX docs are a bit vague whether to set this to 1 + // or 2. The runtime seems to accept 1, so we speculate that either it is + // forcing it to 2 without telling us, or better, doing something smart + // behind the scenes knowing that we don't need more. presentParameters.BackBufferCount = 1; presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat; presentParameters.EnableAutoDepthStencil = FALSE; @@ -123,200 +239,131 @@ void Surface::resetSwapChain(int backbufferWidth, int backbufferHeight) presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented presentParameters.PresentationInterval = mPresentInterval; - presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + // Use flipEx on Win7 or greater. + if(useFlipEx) + presentParameters.SwapEffect = D3DSWAPEFFECT_FLIPEX; + else + presentParameters.SwapEffect = mPostSubBufferSupported ? D3DSWAPEFFECT_COPY : D3DSWAPEFFECT_DISCARD; presentParameters.Windowed = TRUE; presentParameters.BackBufferWidth = backbufferWidth; presentParameters.BackBufferHeight = backbufferHeight; - HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); - - if (FAILED(result)) + if (mWindow) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); + } else { + HANDLE *pShareHandle = NULL; + if (mDisplay->shareHandleSupported()) { + pShareHandle = &mShareHandle; + } - ERR("Could not create additional swap chains: %08lX", result); - release(); - return error(EGL_BAD_ALLOC); + result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, + presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, pShareHandle); } - result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, - presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, - presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); - if (FAILED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); - ERR("Could not create depthstencil surface for new swap chain: %08lX", result); + ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); release(); - return error(EGL_BAD_ALLOC); - } - ASSERT(SUCCEEDED(result)); - - result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET, - presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &mFlipTexture, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - ERR("Could not create flip texture for new swap chain: %08lX", result); - release(); - return error(EGL_BAD_ALLOC); - } - - mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); - mWidth = presentParameters.BackBufferWidth; - mHeight = presentParameters.BackBufferHeight; - - mPresentIntervalDirty = false; - - InvalidateRect(mWindow, NULL, FALSE); - - // The flip state block recorded mFlipTexture so it is now invalid. - releaseRecordedState(device); -} - -HWND Surface::getWindowHandle() -{ - return mWindow; -} - -void Surface::writeRecordableFlipState(IDirect3DDevice9 *device) -{ - // Disable all pipeline operations - device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); - device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); - device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); - - // Just sample the texture - 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->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); - device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - 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) -{ - HRESULT hr; - - if (mFlipState == NULL) - { - // Create two state blocks both recording the states that are changed when swapping. - - // mPreFlipState will record the original state each entry. - hr = device->BeginStateBlock(); - ASSERT(SUCCEEDED(hr)); - writeRecordableFlipState(device); - hr = device->EndStateBlock(&mPreFlipState); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - if (SUCCEEDED(hr)) + + if (preservedRenderTarget) { - mPreFlipState->Capture(); + preservedRenderTarget->Release(); + preservedRenderTarget = NULL; } - // mFlipState will record the state for the swap operation. - hr = device->BeginStateBlock(); - ASSERT(SUCCEEDED(hr)); - - writeRecordableFlipState(device); - - hr = device->EndStateBlock(&mFlipState); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - if (FAILED(hr)) + if(isDeviceLostError(result)) { - mFlipState = NULL; - mPreFlipState->Release(); - mPreFlipState = NULL; + mDisplay->notifyDeviceLost(); + return false; } else { - hr = mFlipState->Apply(); - ASSERT(SUCCEEDED(hr)); + return error(EGL_BAD_ALLOC, false); + } + } + + if (mWindow) + { + mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mRenderTarget); + if (!preservedRenderTarget) + { + InvalidateRect(mWindow, NULL, FALSE); } } else { - hr = mPreFlipState->Capture(); - ASSERT(SUCCEEDED(hr)); - hr = mFlipState->Apply(); - ASSERT(SUCCEEDED(hr)); + mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); } - device->GetRenderTarget(0, &mPreFlipBackBuffer); - device->GetDepthStencilSurface(&mPreFlipDepthStencil); + if (preservedRenderTarget) + { + RECT rect = + { + 0, 0, + mWidth, mHeight + }; - device->SetRenderTarget(0, mBackBuffer); - device->SetDepthStencilSurface(NULL); -} + if (rect.right > static_cast<LONG>(presentParameters.BackBufferWidth)) + { + rect.right = presentParameters.BackBufferWidth; + } -void Surface::restoreState(IDirect3DDevice9 *device) -{ - device->SetRenderTarget(0, mPreFlipBackBuffer); - device->SetDepthStencilSurface(mPreFlipDepthStencil); + if (rect.bottom > static_cast<LONG>(presentParameters.BackBufferHeight)) + { + rect.bottom = presentParameters.BackBufferHeight; + } - if (mPreFlipBackBuffer) + mDisplay->endScene(); + device->StretchRect(preservedRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); + + preservedRenderTarget->Release(); + preservedRenderTarget = NULL; + } + + if (mConfig->mDepthStencilFormat != D3DFMT_UNKNOWN) { - mPreFlipBackBuffer->Release(); - mPreFlipBackBuffer = NULL; + result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, + presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType, + presentParameters.MultiSampleQuality, FALSE, &mDepthStencil, NULL); } - if (mPreFlipDepthStencil) + if (FAILED(result)) { - mPreFlipDepthStencil->Release(); - mPreFlipDepthStencil = NULL; + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); + + ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + release(); + return error(EGL_BAD_ALLOC, false); } - mPreFlipState->Apply(); + mWidth = presentParameters.BackBufferWidth; + mHeight = presentParameters.BackBufferHeight; + + mPresentIntervalDirty = false; + return true; } -// On the next flip, this will cause the state to be recorded from scratch. -// In particular we need to do this if the flip texture changes. -void Surface::releaseRecordedState(IDirect3DDevice9 *device) +HWND Surface::getWindowHandle() { - if (mFlipState) - { - mFlipState->Release(); - mFlipState = NULL; - } - - if (mPreFlipState) - { - mPreFlipState->Release(); - mPreFlipState = NULL; - } + return mWindow; } + + #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) { +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(); + if(surf) + { + surf->checkForOutOfDateSwapChain(); } } WNDPROC prevWndFunc = reinterpret_cast<WNDPROC >(GetProp(hwnd, kParentWndProc)); @@ -325,39 +372,55 @@ static LRESULT CALLBACK SurfaceWindowProc(HWND hwnd, UINT message, WPARAM wparam void Surface::subclassWindow() { - SetLastError(0); - LONG oldWndProc = SetWindowLong(mWindow, GWL_WNDPROC, reinterpret_cast<LONG>(SurfaceWindowProc)); - if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) { - mWindowSubclassed = false; - return; - } + if (!mWindow) + { + return; + } - SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); - SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); - mWindowSubclassed = true; + DWORD processId; + DWORD threadId = GetWindowThreadProcessId(mWindow, &processId); + if (processId != GetCurrentProcessId() || threadId != GetCurrentThreadId()) + { + return; + } + + SetLastError(0); + LONG_PTR oldWndProc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); + if(oldWndProc == 0 && GetLastError() != ERROR_SUCCESS) + { + mWindowSubclassed = false; + return; + } + + SetProp(mWindow, kSurfaceProperty, reinterpret_cast<HANDLE>(this)); + SetProp(mWindow, kParentWndProc, reinterpret_cast<HANDLE>(oldWndProc)); + 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)); - } + if(!mWindowSubclassed) + { + return; + } + + // un-subclass + LONG_PTR parentWndFunc = reinterpret_cast<LONG_PTR>(GetProp(mWindow, kParentWndProc)); - RemoveProp(mWindow, kSurfaceProperty); - RemoveProp(mWindow, kParentWndProc); - mWindowSubclassed = false; + // Check the windowproc is still SurfaceWindowProc. + // If this assert fails, then it is likely the application has subclassed the + // hwnd as well and did not unsubclass before destroying its EGL context. The + // application should be modified to either subclass before initializing the + // EGL context, or to unsubclass before destroying the EGL context. + if(parentWndFunc) + { + LONG_PTR prevWndFunc = SetWindowLongPtr(mWindow, GWLP_WNDPROC, parentWndFunc); + ASSERT(prevWndFunc == reinterpret_cast<LONG_PTR>(SurfaceWindowProc)); + } + + RemoveProp(mWindow, kSurfaceProperty); + RemoveProp(mWindow, kParentWndProc); + mWindowSubclassed = false; } bool Surface::checkForOutOfDateSwapChain() @@ -402,40 +465,79 @@ DWORD Surface::convertInterval(EGLint interval) return D3DPRESENT_INTERVAL_DEFAULT; } - bool Surface::swap() { if (mSwapChain) { - IDirect3DDevice9 *device = mDisplay->getDevice(); + mDisplay->endScene(); + + HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + return error(EGL_BAD_ALLOC, false); + } + + if (isDeviceLostError(result)) + { + mDisplay->notifyDeviceLost(); + return false; + } - applyFlipState(device); - device->SetTexture(0, mFlipTexture); + ASSERT(SUCCEEDED(result)); - // Render the texture upside down into the back buffer - // 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 + checkForOutOfDateSwapChain(); + } + + return true; +} - mDisplay->startScene(); - device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); +bool Surface::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (x < 0 || y < 0 || width < 0 || height < 0) + { + return error(EGL_BAD_PARAMETER, false); + } - restoreState(device); + if (!mPostSubBufferSupported) + { + // Spec is not clear about how this should be handled. + return true; + } + if (mSwapChain) + { mDisplay->endScene(); - HRESULT result = mSwapChain->Present(NULL, NULL, NULL, NULL, 0); + RECT rect = + { + x, mHeight - y - height, + x + width, mHeight - y + }; + + if (rect.right > mWidth) + { + rect.right = mWidth; + } + + if (rect.bottom > mHeight) + { + rect.bottom = mHeight; + } + + if (rect.left == rect.right || rect.top == rect.bottom) + { + return true; + } + + HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) { return error(EGL_BAD_ALLOC, false); } - if (result == D3DERR_DEVICELOST) + if (result == D3DERR_DEVICELOST || result == D3DERR_DEVICEHUNG || result == D3DERR_DEVICEREMOVED) { return error(EGL_CONTEXT_LOST, false); } @@ -458,16 +560,19 @@ EGLint Surface::getHeight() const return mHeight; } -IDirect3DSurface9 *Surface::getRenderTarget() +EGLint Surface::isPostSubBufferSupported() const { - IDirect3DSurface9 *textureSurface = NULL; + return mPostSubBufferSupported; +} - if (mFlipTexture) +IDirect3DSurface9 *Surface::getRenderTarget() +{ + if (mRenderTarget) { - mFlipTexture->GetSurfaceLevel(0, &textureSurface); + mRenderTarget->AddRef(); } - return textureSurface; + return mRenderTarget; } IDirect3DSurface9 *Surface::getDepthStencil() @@ -480,6 +585,16 @@ IDirect3DSurface9 *Surface::getDepthStencil() return mDepthStencil; } +IDirect3DTexture9 *Surface::getOffscreenTexture() +{ + if (mOffscreenTexture) + { + mOffscreenTexture->AddRef(); + } + + return mOffscreenTexture; +} + void Surface::setSwapInterval(EGLint interval) { if (mSwapInterval == interval) @@ -494,4 +609,29 @@ void Surface::setSwapInterval(EGLint interval) mPresentInterval = convertInterval(mSwapInterval); mPresentIntervalDirty = true; } + +EGLenum Surface::getTextureFormat() const +{ + return mTextureFormat; +} + +EGLenum Surface::getTextureTarget() const +{ + return mTextureTarget; +} + +void Surface::setBoundTexture(gl::Texture2D *texture) +{ + mTexture = texture; +} + +gl::Texture2D *Surface::getBoundTexture() const +{ + return mTexture; +} + +D3DFORMAT Surface::getFormat() const +{ + return mConfig->mRenderTargetFormat; +} } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h index 422d3d5..35260de 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/Surface.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/Surface.h @@ -17,6 +17,11 @@ #include "common/angleutils.h" +namespace gl +{ +class Texture2D; +} + namespace egl { class Display; @@ -25,48 +30,56 @@ class Config; class Surface { public: - Surface(Display *display, const egl::Config *config, HWND window); + Surface(Display *display, const egl::Config *config, HWND window, EGLint postSubBufferSupported); + Surface(Display *display, const egl::Config *config, HANDLE shareHandle, EGLint width, EGLint height, EGLenum textureFormat, EGLenum textureTarget); ~Surface(); + bool initialize(); void release(); - void resetSwapChain(); + bool resetSwapChain(); HWND getWindowHandle(); bool swap(); + bool postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height); virtual EGLint getWidth() const; virtual EGLint getHeight() const; + virtual EGLint isPostSubBufferSupported() const; + virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); + virtual IDirect3DTexture9 *getOffscreenTexture(); + + HANDLE getShareHandle() { return mShareHandle; } void setSwapInterval(EGLint interval); bool checkForOutOfDateSwapChain(); // Returns true if swapchain changed due to resize or interval update + virtual EGLenum getTextureFormat() const; + virtual EGLenum getTextureTarget() const; + virtual D3DFORMAT getFormat() const; + + virtual void setBoundTexture(gl::Texture2D *texture); + virtual gl::Texture2D *getBoundTexture() const; + private: DISALLOW_COPY_AND_ASSIGN(Surface); Display *const mDisplay; IDirect3DSwapChain9 *mSwapChain; - IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mDepthStencil; - IDirect3DTexture9 *mFlipTexture; + IDirect3DSurface9* mRenderTarget; + IDirect3DTexture9* mOffscreenTexture; + + HANDLE mShareHandle; void subclassWindow(); void unsubclassWindow(); - void resetSwapChain(int backbufferWidth, int backbufferHeight); + bool resetSwapChain(int backbufferWidth, int backbufferHeight); static DWORD convertInterval(EGLint interval); - void applyFlipState(IDirect3DDevice9 *device); - void restoreState(IDirect3DDevice9 *device); - void writeRecordableFlipState(IDirect3DDevice9 *device); - void releaseRecordedState(IDirect3DDevice9 *device); - IDirect3DStateBlock9 *mFlipState; - IDirect3DStateBlock9 *mPreFlipState; - IDirect3DSurface9 *mPreFlipBackBuffer; - 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 @@ -81,13 +94,16 @@ private: EGLint mPixelAspectRatio; // Display aspect ratio EGLenum mRenderBuffer; // Render buffer EGLenum mSwapBehavior; // Buffer swap behavior -// EGLenum textureFormat; // Format of texture: RGB, RGBA, or no texture -// EGLenum textureTarget; // Type of texture: 2D or no texture + EGLenum mTextureFormat; // Format of texture: RGB, RGBA, or no texture + EGLenum mTextureTarget; // Type of texture: 2D or no texture // EGLenum vgAlphaFormat; // Alpha format for OpenVG // EGLenum vgColorSpace; // Color space for OpenVG EGLint mSwapInterval; + EGLint mPostSubBufferSupported; + DWORD mPresentInterval; bool mPresentIntervalDirty; + gl::Texture2D *mTexture; }; } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp index 8dfe6e5..4b7f9e1 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp @@ -9,13 +9,15 @@ #include <exception> #include "common/debug.h" +#include "common/version.h" #include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" #include "libEGL/main.h" #include "libEGL/Display.h" -bool validate(egl::Display *display) +bool validateDisplay(egl::Display *display) { if (display == EGL_NO_DISPLAY) { @@ -30,9 +32,9 @@ bool validate(egl::Display *display) return true; } -bool validate(egl::Display *display, EGLConfig config) +bool validateConfig(egl::Display *display, EGLConfig config) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -45,9 +47,9 @@ bool validate(egl::Display *display, EGLConfig config) return true; } -bool validate(egl::Display *display, gl::Context *context) +bool validateContext(egl::Display *display, gl::Context *context) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -60,9 +62,9 @@ bool validate(egl::Display *display, gl::Context *context) return true; } -bool validate(egl::Display *display, egl::Surface *surface) +bool validateSurface(egl::Display *display, egl::Surface *surface) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -79,7 +81,7 @@ extern "C" { EGLint __stdcall eglGetError(void) { - TRACE("()"); + EVENT("()"); EGLint error = egl::getCurrentError(); @@ -93,34 +95,21 @@ EGLint __stdcall eglGetError(void) EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id) { - TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); + EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); try { - // FIXME: Return the same EGLDisplay handle when display_id already created a display - - if (display_id == EGL_DEFAULT_DISPLAY) - { - return new egl::Display((HDC)NULL); - } - else - { - // FIXME: Check if display_id is a valid display device context - - return new egl::Display((HDC)display_id); - } + return egl::Display::getDisplay(display_id); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, major, minor); try @@ -146,13 +135,11 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { - TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy); + EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); try { @@ -171,19 +158,17 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return NULL; } @@ -193,11 +178,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) case EGL_CLIENT_APIS: return success("OpenGL_ES"); case EGL_EXTENSIONS: - return success(""); + return display->getExtensionString(); case EGL_VENDOR: - return success("TransGaming Inc."); + return success("Google Inc."); case EGL_VERSION: - return success("1.4 (git-devel "__DATE__" " __TIME__")"); + return success("1.4 (ANGLE "VERSION_STRING")"); } return error(EGL_BAD_PARAMETER, (const char*)NULL); @@ -206,13 +191,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { return error(EGL_BAD_ALLOC, (const char*)NULL); } - - return NULL; } EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, configs, config_size, num_config); @@ -220,7 +203,7 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -243,13 +226,11 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)", dpy, attrib_list, configs, config_size, num_config); @@ -257,7 +238,7 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -282,20 +263,18 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, config, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_FALSE; } @@ -311,20 +290,18 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } @@ -336,113 +313,70 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } - if (attrib_list) - { - while (*attrib_list != EGL_NONE) - { - switch (attrib_list[0]) - { - case EGL_RENDER_BUFFER: - switch (attrib_list[1]) - { - case EGL_BACK_BUFFER: - break; - case EGL_SINGLE_BUFFER: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - break; - case EGL_VG_COLORSPACE: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - case EGL_VG_ALPHA_FORMAT: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - - attrib_list += 2; - } - } - - if (display->hasExistingWindowSurface(window)) - { - return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); - } - - EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config); - - return success(surface); + return display->createWindowSurface(window, config, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, config, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME - - return success(EGL_NO_DISPLAY); + return display->createOffscreenSurface(config, NULL, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } UNIMPLEMENTED(); // FIXME - return success(EGL_NO_DISPLAY); + return success(EGL_NO_SURFACE); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -460,20 +394,19 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, surface, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -483,8 +416,6 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - switch (attribute) { case EGL_VG_ALPHA_FORMAT: @@ -535,6 +466,9 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint case EGL_WIDTH: *value = eglSurface->getWidth(); break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = eglSurface->isPostSubBufferSupported(); + break; default: return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); } @@ -545,13 +479,48 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} - return EGL_FALSE; +EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value) +{ + TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", + dpy, surface, attribute, value); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + switch (attribute) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + *value = (void*) eglSurface->getShareHandle(); + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + } + + return success(EGL_TRUE); + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } } EGLBoolean __stdcall eglBindAPI(EGLenum api) { - TRACE("(EGLenum api = 0x%X)", api); + EVENT("(EGLenum api = 0x%X)", api); try { @@ -574,13 +543,11 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLenum __stdcall eglQueryAPI(void) { - TRACE("()"); + EVENT("()"); try { @@ -592,13 +559,11 @@ EGLenum __stdcall eglQueryAPI(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitClient(void) { - TRACE("()"); + EVENT("()"); try { @@ -610,13 +575,11 @@ EGLBoolean __stdcall eglWaitClient(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseThread(void) { - TRACE("()"); + EVENT("()"); try { @@ -628,13 +591,11 @@ EGLBoolean __stdcall eglReleaseThread(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, buftype, buffer, config, attrib_list); @@ -642,33 +603,35 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME + if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) + { + return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } - return success(EGL_NO_SURFACE); + return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)", dpy, surface, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -681,24 +644,46 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getBoundTexture()) + { + return error(EGL_BAD_ACCESS, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + if (!glBindTexImage(eglSurface)) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } return success(EGL_TRUE); } @@ -706,24 +691,43 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + gl::Texture2D *texture = eglSurface->getBoundTexture(); + + if (texture) + { + texture->releaseTexImage(); + } return success(EGL_TRUE); } @@ -731,19 +735,17 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -763,29 +765,45 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list); try { // Get the requested client version (default is 1) and check it is two. EGLint client_version = 1; + bool reset_notification = false; + bool robust_access = false; + if (attrib_list) { for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2) { - if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION) + switch (attribute[0]) { + case EGL_CONTEXT_CLIENT_VERSION: client_version = attribute[1]; - } - else - { + break; + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (attribute[1] == EGL_TRUE) + { + return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented + // robust_access = true; + } + else if (attribute[1] != EGL_FALSE) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) + reset_notification = true; + else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); } } @@ -796,34 +814,41 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); } + if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification) + { + return error(EGL_BAD_MATCH, EGL_NO_CONTEXT); + } + egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_CONTEXT; } - EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context)); + EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access); - return success(context); + if (context) + return success(context); + else + return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -833,7 +858,7 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return error(EGL_BAD_CONTEXT, EGL_FALSE); } - display->destroyContext((gl::Context*)ctx); + display->destroyContext(context); return success(EGL_TRUE); } @@ -841,13 +866,11 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, draw, read, ctx); try @@ -856,18 +879,24 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface gl::Context *context = static_cast<gl::Context*>(ctx); IDirect3DDevice9 *device = display->getDevice(); - if (!device || FAILED(device->TestCooperativeLevel())) + if (!device || display->testDeviceLost()) + { + display->notifyDeviceLost(); + return EGL_FALSE; + } + + if (display->isDeviceLost()) { return error(EGL_CONTEXT_LOST, EGL_FALSE); } - if (ctx != EGL_NO_CONTEXT && !validate(display, context)) + if (ctx != EGL_NO_CONTEXT && !validateContext(display, context)) { return EGL_FALSE; } - if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) || - (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read)))) + if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) || + (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read)))) { return EGL_FALSE; } @@ -889,13 +918,11 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglGetCurrentContext(void) { - TRACE("()"); + EVENT("()"); try { @@ -907,13 +934,11 @@ EGLContext __stdcall eglGetCurrentContext(void) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { - TRACE("(EGLint readdraw = %d)", readdraw); + EVENT("(EGLint readdraw = %d)", readdraw); try { @@ -936,13 +961,11 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLDisplay __stdcall eglGetCurrentDisplay(void) { - TRACE("()"); + EVENT("()"); try { @@ -954,20 +977,19 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, ctx, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -980,13 +1002,11 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitGL(void) { - TRACE("()"); + EVENT("()"); try { @@ -998,13 +1018,11 @@ EGLBoolean __stdcall eglWaitGL(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitNative(EGLint engine) { - TRACE("(EGLint engine = %d)", engine); + EVENT("(EGLint engine = %d)", engine); try { @@ -1016,30 +1034,32 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + if (surface == EGL_NO_SURFACE) { return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - if (eglSurface->swap()) { return success(EGL_TRUE); @@ -1055,17 +1075,23 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + UNIMPLEMENTED(); // FIXME return success(0); @@ -1074,13 +1100,48 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} + +EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->postSubBuffer(x, y, width, height)) + { + return success(EGL_TRUE); + } + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } return EGL_FALSE; } __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname) { - TRACE("(const char *procname = \"%s\")", procname); + EVENT("(const char *procname = \"%s\")", procname); try { @@ -1092,6 +1153,8 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char static const Extension eglExtensions[] = { + {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE}, + {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV}, {"", NULL}, }; @@ -1109,7 +1172,5 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char { return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL); } - - return NULL; } } diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc new file mode 100644 index 0000000..5d1f32f --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <windows.h> +#include "../common/version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""../common/version.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "ANGLE libEGL Dynamic Link Library" + VALUE "FileVersion", VERSION_STRING + VALUE "InternalName", "libEGL" + VALUE "LegalCopyright", "Copyright (C) 2011 Google Inc." + VALUE "OriginalFilename", "libEGL.dll" + VALUE "PrivateBuild", VERSION_STRING + VALUE "ProductName", "ANGLE libEGL Dynamic Link Library" + VALUE "ProductVersion", VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj index 4f8d0b2..c3e8a4b 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.vcproj @@ -12,6 +12,9 @@ <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> @@ -47,9 +50,11 @@ BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -62,9 +67,10 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="dxguid.lib" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" LinkIncremental="2" ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" GenerateDebugInformation="true" SubSystem="2" RandomizedBaseAddress="1" @@ -125,9 +131,11 @@ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" RuntimeLibrary="0" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -140,9 +148,10 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="dxguid.lib" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" LinkIncremental="1" ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" GenerateDebugInformation="true" SubSystem="2" OptimizeReferences="2" @@ -174,6 +183,172 @@ CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" /> </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" + LinkIncremental="2" + ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" + GenerateDebugInformation="true" + SubSystem="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEGL_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib dxguid.lib dwmapi.lib" + LinkIncremental="1" + ModuleDefinitionFile="libEGL.def" + DelayLoadDLLs="dwmapi.dll" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libEGL.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> </Configurations> <References> </References> @@ -238,14 +413,26 @@ > </File> <File + RelativePath=".\resource.h" + > + </File> + <File RelativePath=".\Surface.h" > </File> + <File + RelativePath="..\common\version.h" + > + </File> </Filter> <File RelativePath=".\libEGL.def" > </File> + <File + RelativePath=".\libEGL.rc" + > + </File> </Files> <Globals> </Globals> diff --git a/Source/ThirdParty/ANGLE/src/libEGL/main.cpp b/Source/ThirdParty/ANGLE/src/libEGL/main.cpp index d9902d2..1c107bf 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/main.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/main.cpp @@ -18,16 +18,16 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { case DLL_PROCESS_ATTACH: { - #ifndef NDEBUG - FILE *debug = fopen("debug.txt", "rt"); - - if (debug) - { - fclose(debug); - debug = fopen("debug.txt", "wt"); // Erase - fclose(debug); - } - #endif +#if !defined(ANGLE_DISABLE_TRACE) + FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt"); + + if (debug) + { + fclose(debug); + debug = fopen(TRACE_OUTPUT_FILE, "wt"); // Erase + fclose(debug); + } +#endif currentTLS = TlsAlloc(); diff --git a/Source/ThirdParty/ANGLE/src/libEGL/main.h b/Source/ThirdParty/ANGLE/src/libEGL/main.h index d6dc759..d09d9e6 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/main.h +++ b/Source/ThirdParty/ANGLE/src/libEGL/main.h @@ -11,6 +11,7 @@ #define EGLAPI #include <EGL/egl.h> +#include <EGL/eglext.h> namespace egl { diff --git a/Source/ThirdParty/ANGLE/src/libEGL/resource.h b/Source/ThirdParty/ANGLE/src/libEGL/resource.h new file mode 100644 index 0000000..3921f4c --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libEGL/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by libEGL.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp index 43ed8a0..a248d69 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.cpp @@ -155,16 +155,23 @@ void Blit::initGeometry() IDirect3DDevice9 *device = getDevice(); - HRESULT hr = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); + HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); - if (FAILED(hr)) + if (FAILED(result)) { - ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return error(GL_OUT_OF_MEMORY); + } + + void *lockPtr = NULL; + result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); + + if (FAILED(result) || lockPtr == NULL) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); return error(GL_OUT_OF_MEMORY); } - void *lockPtr; - mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); memcpy(lockPtr, quad, sizeof(quad)); mQuadVertexBuffer->Unlock(); @@ -174,10 +181,11 @@ void Blit::initGeometry() D3DDECL_END() }; - hr = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); - if (FAILED(hr)) + result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); + + if (FAILED(result)) { - ASSERT(hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); return error(GL_OUT_OF_MEMORY); } } @@ -287,6 +295,34 @@ bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) return true; } +bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +{ + IDirect3DDevice9 *device = getDevice(); + + D3DSURFACE_DESC sourceDesc; + D3DSURFACE_DESC destDesc; + source->GetDesc(&sourceDesc); + dest->GetDesc(&destDesc); + + if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET) // Can use StretchRect + { + RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)}; + HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return error(GL_OUT_OF_MEMORY, false); + } + } + else + { + return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest); + } + + return true; +} + bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) { IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); @@ -468,6 +504,11 @@ void Blit::setCommonBlitState() RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle device->SetScissorRect(&scissorRect); + + for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } } void Blit::render() diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.h index a83aac3..8928ecd 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Blit.h @@ -30,6 +30,10 @@ class Blit // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); + + // Copy from source surface to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) // source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0. bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp index 17cea6c..dd12e3c 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.cpp @@ -11,8 +11,8 @@ #include "libGLESv2/Buffer.h" #include "libGLESv2/main.h" -#include "libGLESv2/geometry/VertexDataManager.h" -#include "libGLESv2/geometry/IndexDataManager.h" +#include "libGLESv2/VertexDataManager.h" +#include "libGLESv2/IndexDataManager.h" namespace gl { @@ -23,15 +23,16 @@ Buffer::Buffer(GLuint id) : RefCountObject(id) mSize = 0; mUsage = GL_DYNAMIC_DRAW; - mVertexBuffer = NULL; - mIndexBuffer = NULL; + mStaticVertexBuffer = NULL; + mStaticIndexBuffer = NULL; + mUnmodifiedDataUse = 0; } Buffer::~Buffer() { delete[] mContents; - delete mVertexBuffer; - delete mIndexBuffer; + delete mStaticVertexBuffer; + delete mStaticIndexBuffer; } void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) @@ -60,47 +61,57 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) if (usage == GL_STATIC_DRAW) { - mVertexBuffer = new StaticVertexBuffer(getDevice()); - mIndexBuffer = new StaticIndexBuffer(getDevice()); + mStaticVertexBuffer = new StaticVertexBuffer(getDevice()); + mStaticIndexBuffer = 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)) + + if ((mStaticVertexBuffer && mStaticVertexBuffer->size() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->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()); - } } + + mUnmodifiedDataUse = 0; } -StaticVertexBuffer *Buffer::getVertexBuffer() +StaticVertexBuffer *Buffer::getStaticVertexBuffer() { - return mVertexBuffer; + return mStaticVertexBuffer; } -StaticIndexBuffer *Buffer::getIndexBuffer() +StaticIndexBuffer *Buffer::getStaticIndexBuffer() { - return mIndexBuffer; + return mStaticIndexBuffer; } void Buffer::invalidateStaticData() { - delete mVertexBuffer; - mVertexBuffer = NULL; + delete mStaticVertexBuffer; + mStaticVertexBuffer = NULL; + + delete mStaticIndexBuffer; + mStaticIndexBuffer = NULL; + + mUnmodifiedDataUse = 0; +} + +// Creates static buffers if sufficient used data has been left unmodified +void Buffer::promoteStaticUsage(int dataSize) +{ + if (!mStaticVertexBuffer && !mStaticIndexBuffer) + { + mUnmodifiedDataUse += dataSize; - delete mIndexBuffer; - mIndexBuffer = NULL; + if (mUnmodifiedDataUse > 3 * mSize) + { + mStaticVertexBuffer = new StaticVertexBuffer(getDevice()); + mStaticIndexBuffer = new StaticIndexBuffer(getDevice()); + } + } } } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h index c2ed60f..7019c4e 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Buffer.h @@ -18,7 +18,7 @@ #include <GLES2/gl2.h> #include "common/angleutils.h" -#include "libGLESv2/RefCountObject.h" +#include "common/RefCountObject.h" namespace gl { @@ -39,19 +39,21 @@ class Buffer : public RefCountObject size_t size() const { return mSize; } GLenum usage() const { return mUsage; } - StaticVertexBuffer *getVertexBuffer(); - StaticIndexBuffer *getIndexBuffer(); + StaticVertexBuffer *getStaticVertexBuffer(); + StaticIndexBuffer *getStaticIndexBuffer(); void invalidateStaticData(); + void promoteStaticUsage(int dataSize); private: DISALLOW_COPY_AND_ASSIGN(Buffer); GLubyte *mContents; - size_t mSize; + GLsizeiptr mSize; GLenum mUsage; - StaticVertexBuffer *mVertexBuffer; - StaticIndexBuffer *mIndexBuffer; + StaticVertexBuffer *mStaticVertexBuffer; + StaticIndexBuffer *mStaticIndexBuffer; + GLsizeiptr mUnmodifiedDataUse; }; } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp index 9be59c4..66cd5c0 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -22,20 +22,27 @@ #include "libGLESv2/Fence.h" #include "libGLESv2/FrameBuffer.h" #include "libGLESv2/Program.h" +#include "libGLESv2/Query.h" #include "libGLESv2/RenderBuffer.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Texture.h" -#include "libGLESv2/geometry/VertexDataManager.h" -#include "libGLESv2/geometry/IndexDataManager.h" +#include "libGLESv2/VertexDataManager.h" +#include "libGLESv2/IndexDataManager.h" #undef near #undef far namespace gl { -Context::Context(const egl::Config *config, const gl::Context *shareContext) - : mConfig(config) +Context::Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) : mConfig(config) { + ASSERT(robustAccess == false); // Unimplemented + + mDisplay = NULL; + mDevice = NULL; + + mFenceHandleAllocator.setBaseHandle(0); + setClearColor(0.0f, 0.0f, 0.0f, 0.0f); mState.depthClearValue = 1.0f; @@ -136,10 +143,12 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext) mState.packAlignment = 4; mState.unpackAlignment = 4; + mState.packReverseRowOrder = false; mVertexDataManager = NULL; mIndexDataManager = NULL; mBlit = NULL; + mLineLoopIB = NULL; mInvalidEnum = false; mInvalidValue = false; @@ -148,9 +157,17 @@ Context::Context(const egl::Config *config, const gl::Context *shareContext) mInvalidFramebufferOperation = false; mHasBeenCurrent = false; - - mSupportsCompressedTextures = false; + mContextLost = false; + mResetStatus = GL_NO_ERROR; + mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT); + mRobustAccess = robustAccess; + + mSupportsDXT1Textures = false; + mSupportsDXT3Textures = false; + mSupportsDXT5Textures = false; mSupportsEventQueries = false; + mSupportsOcclusionQueries = false; + mNumCompressedTextureFormats = 0; mMaxSupportedSamples = 0; mMaskedClearSavedState = NULL; markAllStateDirty(); @@ -178,21 +195,26 @@ Context::~Context() deleteFence(mFenceMap.begin()->first); } + while (!mQueryMap.empty()) + { + deleteQuery(mQueryMap.begin()->first); + } + while (!mMultiSampleSupport.empty()) { delete [] mMultiSampleSupport.begin()->second; mMultiSampleSupport.erase(mMultiSampleSupport.begin()); } - for (int type = 0; type < SAMPLER_TYPE_COUNT; type++) + for (int type = 0; type < TEXTURE_TYPE_COUNT; type++) { - for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) + for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++) { mState.samplerTexture[type][sampler].set(NULL); } } - for (int type = 0; type < SAMPLER_TYPE_COUNT; type++) + for (int type = 0; type < TEXTURE_TYPE_COUNT; type++) { mIncompleteTextures[type].set(NULL); } @@ -202,6 +224,11 @@ Context::~Context() mState.vertexAttribute[i].mBoundBuffer.set(NULL); } + for (int i = 0; i < QUERY_TYPE_COUNT; i++) + { + mState.activeQuery[i].set(NULL); + } + mState.arrayBuffer.set(NULL); mState.elementArrayBuffer.set(NULL); mState.renderbuffer.set(NULL); @@ -212,6 +239,7 @@ Context::~Context() delete mVertexDataManager; delete mIndexDataManager; delete mBlit; + delete mLineLoopIB; if (mMaskedClearSavedState) { @@ -223,17 +251,21 @@ Context::~Context() void Context::makeCurrent(egl::Display *display, egl::Surface *surface) { - IDirect3DDevice9 *device = display->getDevice(); + mDisplay = display; + mDevice = mDisplay->getDevice(); if (!mHasBeenCurrent) { - mDeviceCaps = display->getDeviceCaps(); + mDeviceCaps = mDisplay->getDeviceCaps(); - mVertexDataManager = new VertexDataManager(this, device); - mIndexDataManager = new IndexDataManager(this, device); + mVertexDataManager = new VertexDataManager(this, mDevice); + mIndexDataManager = new IndexDataManager(this, mDevice); mBlit = new Blit(this); - mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0); + mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); + mSupportsVertexTexture = mDisplay->getVertexTextureSupport(); + mSupportsNonPower2Texture = mDisplay->getNonPower2TextureSupport(); + mSupportsInstancing = mDisplay->getInstancingSupport(); mMaxTextureDimension = std::min(std::min((int)mDeviceCaps.MaxTextureWidth, (int)mDeviceCaps.MaxTextureHeight), (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE); @@ -255,7 +287,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i) { bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray); + mDisplay->getMultiSampleSupport(renderBufferFormats[i], multisampleArray); mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray; for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) @@ -269,16 +301,34 @@ 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(); + mSupportsEventQueries = mDisplay->getEventQuerySupport(); + mSupportsOcclusionQueries = mDisplay->getOcclusionQuerySupport(); + mSupportsDXT1Textures = mDisplay->getDXT1TextureSupport(); + mSupportsDXT3Textures = mDisplay->getDXT3TextureSupport(); + mSupportsDXT5Textures = mDisplay->getDXT5TextureSupport(); + mSupportsFloat32Textures = mDisplay->getFloat32TextureSupport(&mSupportsFloat32LinearFilter, &mSupportsFloat32RenderableTextures); + mSupportsFloat16Textures = mDisplay->getFloat16TextureSupport(&mSupportsFloat16LinearFilter, &mSupportsFloat16RenderableTextures); + mSupportsLuminanceTextures = mDisplay->getLuminanceTextureSupport(); + mSupportsLuminanceAlphaTextures = mDisplay->getLuminanceAlphaTextureSupport(); mSupports32bitIndices = mDeviceCaps.MaxVertexIndex >= (1 << 16); + mNumCompressedTextureFormats = 0; + if (supportsDXT1Textures()) + { + mNumCompressedTextureFormats += 2; + } + if (supportsDXT3Textures()) + { + mNumCompressedTextureFormats += 1; + } + if (supportsDXT5Textures()) + { + mNumCompressedTextureFormats += 1; + } + initExtensionString(); + initRendererString(); mState.viewportX = 0; mState.viewportY = 0; @@ -319,11 +369,26 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface) // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. void Context::markAllStateDirty() { + for (int t = 0; t < MAX_TEXTURE_IMAGE_UNITS; t++) + { + mAppliedTextureSerialPS[t] = 0; + } + + for (int t = 0; t < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; t++) + { + mAppliedTextureSerialVS[t] = 0; + } + + mAppliedProgramSerial = 0; mAppliedRenderTargetSerial = 0; mAppliedDepthbufferSerial = 0; mAppliedStencilbufferSerial = 0; + mAppliedIBSerial = 0; mDepthStencilInitialized = false; - mAppliedProgram = 0; + mViewportInitialized = false; + mRenderTargetDescInitialized = false; + + mVertexDeclarationCache.markStateDirty(); mClearStateDirty = true; mCullStateDirty = true; @@ -336,6 +401,20 @@ void Context::markAllStateDirty() mSampleStateDirty = true; mDitherStateDirty = true; mFrontFaceDirty = true; + mDxUniformsDirty = true; + mCachedCurrentProgram = NULL; +} + +void Context::markContextLost() +{ + if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT) + mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT; + mContextLost = true; +} + +bool Context::isContextLost() +{ + return mContextLost; } void Context::setClearColor(float red, float green, float blue, float alpha) @@ -710,7 +789,7 @@ void Context::setDepthMask(bool mask) } } -void Context::setActiveSampler(int active) +void Context::setActiveSampler(unsigned int active) { mState.activeSampler = active; } @@ -735,6 +814,32 @@ GLuint Context::getArrayBufferHandle() const return mState.arrayBuffer.id(); } +GLuint Context::getActiveQuery(GLenum target) const +{ + Query *queryObject = NULL; + + switch (target) + { + case GL_ANY_SAMPLES_PASSED_EXT: + queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED].get(); + break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE].get(); + break; + default: + ASSERT(false); + } + + if (queryObject) + { + return queryObject->id(); + } + else + { + return 0; + } +} + void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) { mState.vertexAttribute[attribNum].mArrayEnabled = enabled; @@ -786,6 +891,16 @@ GLint Context::getUnpackAlignment() const return mState.unpackAlignment; } +void Context::setPackReverseRowOrder(bool reverseRowOrder) +{ + mState.packReverseRowOrder = reverseRowOrder; +} + +bool Context::getPackReverseRowOrder() const +{ + return mState.packReverseRowOrder; +} + GLuint Context::createBuffer() { return mResourceManager->createBuffer(); @@ -814,12 +929,7 @@ GLuint Context::createRenderbuffer() // Returns an unused framebuffer name GLuint Context::createFramebuffer() { - unsigned int handle = 1; - - while (mFramebufferMap.find(handle) != mFramebufferMap.end()) - { - handle++; - } + GLuint handle = mFramebufferHandleAllocator.allocate(); mFramebufferMap[handle] = NULL; @@ -828,14 +938,19 @@ GLuint Context::createFramebuffer() GLuint Context::createFence() { - unsigned int handle = 0; + GLuint handle = mFenceHandleAllocator.allocate(); - while (mFenceMap.find(handle) != mFenceMap.end()) - { - handle++; - } + mFenceMap[handle] = new Fence(mDisplay); - mFenceMap[handle] = new Fence; + return handle; +} + +// Returns an unused query name +GLuint Context::createQuery() +{ + GLuint handle = mQueryHandleAllocator.allocate(); + + mQueryMap[handle] = NULL; return handle; } @@ -858,6 +973,7 @@ void Context::deleteShader(GLuint shader) void Context::deleteProgram(GLuint program) { mResourceManager->deleteProgram(program); + mCachedCurrentProgram = NULL; } void Context::deleteTexture(GLuint texture) @@ -888,6 +1004,7 @@ void Context::deleteFramebuffer(GLuint framebuffer) { detachFramebuffer(framebuffer); + mFramebufferHandleAllocator.release(framebufferObject->first); delete framebufferObject->second; mFramebufferMap.erase(framebufferObject); } @@ -899,11 +1016,26 @@ void Context::deleteFence(GLuint fence) if (fenceObject != mFenceMap.end()) { + mFenceHandleAllocator.release(fenceObject->first); delete fenceObject->second; mFenceMap.erase(fenceObject); } } +void Context::deleteQuery(GLuint query) +{ + QueryMap::iterator queryObject = mQueryMap.find(query); + if (queryObject != mQueryMap.end()) + { + mQueryHandleAllocator.release(queryObject->first); + if (queryObject->second) + { + queryObject->second->release(); + } + mQueryMap.erase(queryObject); + } +} + Buffer *Context::getBuffer(GLuint handle) { return mResourceManager->getBuffer(handle); @@ -936,7 +1068,7 @@ Framebuffer *Context::getReadFramebuffer() Framebuffer *Context::getDrawFramebuffer() { - return getFramebuffer(mState.drawFramebuffer); + return mBoundDrawFramebuffer; } void Context::bindArrayBuffer(unsigned int buffer) @@ -955,16 +1087,16 @@ void Context::bindElementArrayBuffer(unsigned int buffer) void Context::bindTexture2D(GLuint texture) { - mResourceManager->checkTextureAllocation(texture, SAMPLER_2D); + mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); - mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(getTexture(texture)); + mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture)); } void Context::bindTextureCubeMap(GLuint texture) { - mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE); + mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); - mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(getTexture(texture)); + mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture)); } void Context::bindReadFramebuffer(GLuint framebuffer) @@ -985,6 +1117,8 @@ void Context::bindDrawFramebuffer(GLuint framebuffer) } mState.drawFramebuffer = framebuffer; + + mBoundDrawFramebuffer = getFramebuffer(framebuffer); } void Context::bindRenderbuffer(GLuint renderbuffer) @@ -1003,6 +1137,8 @@ void Context::useProgram(GLuint program) { Program *newProgram = mResourceManager->getProgram(program); Program *oldProgram = mResourceManager->getProgram(priorProgram); + mCachedCurrentProgram = NULL; + mDxUniformsDirty = true; if (newProgram) { @@ -1016,10 +1152,103 @@ void Context::useProgram(GLuint program) } } +void Context::beginQuery(GLenum target, GLuint query) +{ + // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> + // of zero, if the active query object name for <target> is non-zero (for the + // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if + // the active query for either target is non-zero), if <id> is the name of an + // existing query object whose type does not match <target>, or if <id> is the + // active query object name for any query type, the error INVALID_OPERATION is + // generated. + + // Ensure no other queries are active + // NOTE: If other queries than occlusion are supported, we will need to check + // separately that: + // a) The query ID passed is not the current active query for any target/type + // b) There are no active queries for the requested target (and in the case + // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, + // no query may be active for either if glBeginQuery targets either. + for (int i = 0; i < QUERY_TYPE_COUNT; i++) + { + if (mState.activeQuery[i].get() != NULL) + { + return error(GL_INVALID_OPERATION); + } + } + + QueryType qType; + switch (target) + { + case GL_ANY_SAMPLES_PASSED_EXT: + qType = QUERY_ANY_SAMPLES_PASSED; + break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; + break; + default: + ASSERT(false); + return; + } + + Query *queryObject = getQuery(query, true, target); + + // check that name was obtained with glGenQueries + if (!queryObject) + { + return error(GL_INVALID_OPERATION); + } + + // check for type mismatch + if (queryObject->getType() != target) + { + return error(GL_INVALID_OPERATION); + } + + // set query as active for specified target + mState.activeQuery[qType].set(queryObject); + + // begin query + queryObject->begin(); +} + +void Context::endQuery(GLenum target) +{ + QueryType qType; + + switch (target) + { + case GL_ANY_SAMPLES_PASSED_EXT: + qType = QUERY_ANY_SAMPLES_PASSED; + break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; + break; + default: + ASSERT(false); + return; + } + + Query *queryObject = mState.activeQuery[qType].get(); + + if (queryObject == NULL) + { + return error(GL_INVALID_OPERATION); + } + + queryObject->end(); + + mState.activeQuery[qType].set(NULL); +} + void Context::setFramebufferZero(Framebuffer *buffer) { delete mFramebufferMap[0]; mFramebufferMap[0] = buffer; + if (mState.drawFramebuffer == 0) + { + mBoundDrawFramebuffer = buffer; + } } void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) @@ -1056,6 +1285,25 @@ Fence *Context::getFence(unsigned int handle) } } +Query *Context::getQuery(unsigned int handle, bool create, GLenum type) +{ + QueryMap::iterator query = mQueryMap.find(handle); + + if (query == mQueryMap.end()) + { + return NULL; + } + else + { + if (!query->second && create) + { + query->second = new Query(handle, type); + query->second->addRef(); + } + return query->second; + } +} + Buffer *Context::getArrayBuffer() { return mState.arrayBuffer.get(); @@ -1068,20 +1316,24 @@ Buffer *Context::getElementArrayBuffer() Program *Context::getCurrentProgram() { - return mResourceManager->getProgram(mState.currentProgram); + if (!mCachedCurrentProgram) + { + mCachedCurrentProgram = mResourceManager->getProgram(mState.currentProgram); + } + return mCachedCurrentProgram; } Texture2D *Context::getTexture2D() { - return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, SAMPLER_2D)); + return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); } TextureCubeMap *Context::getTextureCubeMap() { - return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, SAMPLER_CUBE)); + return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); } -Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type) +Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) { GLuint texid = mState.samplerTexture[type][sampler].id(); @@ -1090,8 +1342,8 @@ Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type) switch (type) { default: UNREACHABLE(); - case SAMPLER_2D: return mTexture2DZero.get(); - case SAMPLER_CUBE: return mTextureCubeMapZero.get(); + case TEXTURE_2D: return mTexture2DZero.get(); + case TEXTURE_CUBE: return mTextureCubeMapZero.get(); } } @@ -1102,24 +1354,25 @@ bool Context::getBooleanv(GLenum pname, GLboolean *params) { switch (pname) { - case GL_SHADER_COMPILER: *params = GL_TRUE; break; - case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; - case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; + case GL_SHADER_COMPILER: *params = GL_TRUE; break; + case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; + case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; case GL_COLOR_WRITEMASK: params[0] = mState.colorMaskRed; params[1] = mState.colorMaskGreen; params[2] = mState.colorMaskBlue; params[3] = mState.colorMaskAlpha; break; - case GL_CULL_FACE: *params = mState.cullFace; break; - case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; - case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; - case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; - case GL_SCISSOR_TEST: *params = mState.scissorTest; break; - case GL_STENCIL_TEST: *params = mState.stencilTest; break; - case GL_DEPTH_TEST: *params = mState.depthTest; break; - case GL_BLEND: *params = mState.blend; break; - case GL_DITHER: *params = mState.dither; break; + case GL_CULL_FACE: *params = mState.cullFace; break; + case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; + case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; + case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; + case GL_SCISSOR_TEST: *params = mState.scissorTest; break; + case GL_STENCIL_TEST: *params = mState.stencilTest; break; + case GL_DEPTH_TEST: *params = mState.depthTest; break; + case GL_BLEND: *params = mState.blend; break; + case GL_DITHER: *params = mState.dither; break; + case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE; break; default: return false; } @@ -1183,8 +1436,8 @@ 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 = 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_COMBINED_TEXTURE_IMAGE_UNITS: *params = getMaximumCombinedTextureImageUnits(); break; + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = getMaximumVertexTextureImageUnits(); break; case GL_MAX_TEXTURE_IMAGE_UNITS: *params = gl::MAX_TEXTURE_IMAGE_UNITS; break; case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = getMaximumFragmentUniformVectors(); break; case GL_MAX_RENDERBUFFER_SIZE: *params = getMaximumRenderbufferDimension(); break; @@ -1198,6 +1451,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) 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_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mState.packReverseRowOrder; 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; @@ -1228,18 +1482,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) 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()) - { - // at current, only GL_COMPRESSED_RGB_S3TC_DXT1_EXT and - // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT are supported - *params = 2; - } - else - { - *params = 0; - } - } + params[0] = mNumCompressedTextureFormats; break; case GL_MAX_SAMPLES_ANGLE: { @@ -1295,10 +1538,18 @@ bool Context::getIntegerv(GLenum pname, GLint *params) break; case GL_COMPRESSED_TEXTURE_FORMATS: { - if (supportsCompressedTextures()) + if (supportsDXT1Textures()) + { + *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + } + if (supportsDXT3Textures()) + { + *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + } + if (supportsDXT5Textures()) { - params[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - params[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; } } break; @@ -1322,7 +1573,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_ALPHA_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::Colorbuffer *colorbuffer = framebuffer->getColorbuffer(); + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); if (colorbuffer) { @@ -1343,7 +1594,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_DEPTH_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::DepthStencilbuffer *depthbuffer = framebuffer->getDepthbuffer(); + gl::Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); if (depthbuffer) { @@ -1358,7 +1609,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params) case GL_STENCIL_BITS: { gl::Framebuffer *framebuffer = getDrawFramebuffer(); - gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer(); + gl::Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); if (stencilbuffer) { @@ -1372,26 +1623,29 @@ bool Context::getIntegerv(GLenum pname, GLint *params) break; case GL_TEXTURE_BINDING_2D: { - if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1) + if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1) { error(GL_INVALID_OPERATION); return false; } - *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler].id(); + *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id(); } break; case GL_TEXTURE_BINDING_CUBE_MAP: { - if (mState.activeSampler < 0 || mState.activeSampler > gl::MAX_TEXTURE_IMAGE_UNITS - 1) + if (mState.activeSampler < 0 || mState.activeSampler > getMaximumCombinedTextureImageUnits() - 1) { error(GL_INVALID_OPERATION); return false; } - *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].id(); + *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id(); } break; + case GL_RESET_NOTIFICATION_STRATEGY_EXT: + *params = mResetStrategy; + break; default: return false; } @@ -1410,7 +1664,12 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu // application. switch (pname) { - case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */ + case GL_COMPRESSED_TEXTURE_FORMATS: + { + *type = GL_INT; + *numParams = mNumCompressedTextureFormats; + } + break; case GL_SHADER_BINARY_FORMATS: { *type = GL_INT; @@ -1432,6 +1691,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu case GL_RENDERBUFFER_BINDING: case GL_CURRENT_PROGRAM: case GL_PACK_ALIGNMENT: + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: case GL_UNPACK_ALIGNMENT: case GL_GENERATE_MIPMAP_HINT: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: @@ -1476,6 +1736,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu case GL_IMPLEMENTATION_COLOR_READ_FORMAT: case GL_TEXTURE_BINDING_2D: case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_RESET_NOTIFICATION_STRATEGY_EXT: { *type = GL_INT; *numParams = 1; @@ -1519,6 +1780,7 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu case GL_DEPTH_TEST: case GL_BLEND: case GL_DITHER: + case GL_CONTEXT_ROBUST_ACCESS_EXT: { *type = GL_BOOL; *numParams = 1; @@ -1566,34 +1828,30 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu // scissor rectangle to the Direct3D 9 device bool Context::applyRenderTarget(bool ignoreViewport) { - IDirect3DDevice9 *device = getDevice(); - Framebuffer *framebufferObject = getDrawFramebuffer(); if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) { - error(GL_INVALID_FRAMEBUFFER_OPERATION); - - return false; + return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); } - IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); - - if (!renderTarget) - { - return false; // Context must be lost - } - - IDirect3DSurface9 *depthStencil = NULL; - + bool renderTargetChanged = false; unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { - device->SetRenderTarget(0, renderTarget); + IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); + if (!renderTarget) + { + return false; // Context must be lost + } + mDevice->SetRenderTarget(0, renderTarget); mAppliedRenderTargetSerial = renderTargetSerial; mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets. + renderTargetChanged = true; + renderTarget->Release(); } + IDirect3DSurface9 *depthStencil = NULL; unsigned int depthbufferSerial = 0; unsigned int stencilbufferSerial = 0; if (framebufferObject->getDepthbufferType() != GL_NONE) @@ -1623,15 +1881,25 @@ bool Context::applyRenderTarget(bool ignoreViewport) stencilbufferSerial != mAppliedStencilbufferSerial || !mDepthStencilInitialized) { - device->SetDepthStencilSurface(depthStencil); + mDevice->SetDepthStencilSurface(depthStencil); mAppliedDepthbufferSerial = depthbufferSerial; mAppliedStencilbufferSerial = stencilbufferSerial; mDepthStencilInitialized = true; } + if (!mRenderTargetDescInitialized || renderTargetChanged) + { + IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); + if (!renderTarget) + { + return false; // Context must be lost + } + renderTarget->GetDesc(&mRenderTargetDesc); + mRenderTargetDescInitialized = true; + renderTarget->Release(); + } + D3DVIEWPORT9 viewport; - D3DSURFACE_DESC desc; - renderTarget->GetDesc(&desc); float zNear = clamp01(mState.zNear); float zFar = clamp01(mState.zFar); @@ -1640,17 +1908,18 @@ bool Context::applyRenderTarget(bool ignoreViewport) { viewport.X = 0; viewport.Y = 0; - viewport.Width = desc.Width; - viewport.Height = desc.Height; + viewport.Width = mRenderTargetDesc.Width; + viewport.Height = mRenderTargetDesc.Height; viewport.MinZ = 0.0f; viewport.MaxZ = 1.0f; } else { - viewport.X = std::max(mState.viewportX, 0); - 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); + RECT rect = transformPixelRect(mState.viewportX, mState.viewportY, mState.viewportWidth, mState.viewportHeight, mRenderTargetDesc.Height); + viewport.X = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + viewport.Y = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + viewport.Width = clamp(rect.right - rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width) - static_cast<LONG>(viewport.X)); + viewport.Height = clamp(rect.bottom - rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height) - static_cast<LONG>(viewport.Y)); viewport.MinZ = zNear; viewport.MaxZ = zFar; } @@ -1660,42 +1929,49 @@ bool Context::applyRenderTarget(bool ignoreViewport) return false; // Nothing to render } - device->SetViewport(&viewport); + if (renderTargetChanged || !mViewportInitialized || memcmp(&viewport, &mSetViewport, sizeof mSetViewport) != 0) + { + mDevice->SetViewport(&viewport); + mSetViewport = viewport; + mViewportInitialized = true; + mDxUniformsDirty = true; + } if (mScissorStateDirty) { if (mState.scissorTest) { - RECT rect = {mState.scissorX, - mState.scissorY, - mState.scissorX + mState.scissorWidth, - mState.scissorY + mState.scissorHeight}; - rect.right = std::min(static_cast<UINT>(rect.right), desc.Width); - rect.bottom = std::min(static_cast<UINT>(rect.bottom), desc.Height); - device->SetScissorRect(&rect); - device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); + RECT rect = transformPixelRect(mState.scissorX, mState.scissorY, mState.scissorWidth, mState.scissorHeight, mRenderTargetDesc.Height); + rect.left = clamp(rect.left, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + rect.top = clamp(rect.top, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + rect.right = clamp(rect.right, 0L, static_cast<LONG>(mRenderTargetDesc.Width)); + rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(mRenderTargetDesc.Height)); + mDevice->SetScissorRect(&rect); + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); } else { - device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); } mScissorStateDirty = false; } - if (mState.currentProgram) + if (mState.currentProgram && mDxUniformsDirty) { Program *programObject = getCurrentProgram(); GLint halfPixelSize = programObject->getDxHalfPixelSizeLocation(); - GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height}; + GLfloat xy[2] = {1.0f / viewport.Width, -1.0f / viewport.Height}; programObject->setUniform2fv(halfPixelSize, 1, xy); - GLint viewport = programObject->getDxViewportLocation(); - GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f, + // These values are used for computing gl_FragCoord in Program::linkVaryings(). The approach depends on Shader Model 3.0 support. + GLint coord = programObject->getDxCoordLocation(); + float h = mSupportsShaderModel3 ? mRenderTargetDesc.Height : mState.viewportHeight / 2.0f; + GLfloat whxy[4] = {mState.viewportWidth / 2.0f, h, (float)mState.viewportX + mState.viewportWidth / 2.0f, (float)mState.viewportY + mState.viewportHeight / 2.0f}; - programObject->setUniform4fv(viewport, 1, whxy); + programObject->setUniform4fv(coord, 1, whxy); GLint depth = programObject->getDxDepthLocation(); GLfloat dz[2] = {(zFar - zNear) / 2.0f, (zNear + zFar) / 2.0f}; @@ -1704,6 +1980,7 @@ bool Context::applyRenderTarget(bool ignoreViewport) GLint depthRange = programObject->getDxDepthRangeLocation(); GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; programObject->setUniform3fv(depthRange, 1, nearFarDiff); + mDxUniformsDirty = false; } return true; @@ -1712,28 +1989,37 @@ bool Context::applyRenderTarget(bool ignoreViewport) // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device void Context::applyState(GLenum drawMode) { - IDirect3DDevice9 *device = getDevice(); Program *programObject = getCurrentProgram(); + Framebuffer *framebufferObject = getDrawFramebuffer(); + + GLenum adjustedFrontFace = adjustWinding(mState.frontFace); + GLint frontCCW = programObject->getDxFrontCCWLocation(); - GLint ccw = (mState.frontFace == GL_CCW); + GLint ccw = (adjustedFrontFace == GL_CCW); programObject->setUniform1iv(frontCCW, 1, &ccw); GLint pointsOrLines = programObject->getDxPointsOrLinesLocation(); GLint alwaysFront = !isTriangleMode(drawMode); programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront); - Framebuffer *framebufferObject = getDrawFramebuffer(); + D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier(); + bool zeroColorMaskAllowed = identifier->VendorId != 0x1002; + // Apparently some ATI cards have a bug where a draw with a zero color + // write mask can cause later draws to have incorrect results. Instead, + // set a nonzero color write mask but modify the blend state so that no + // drawing is done. + // http://code.google.com/p/angleproject/issues/detail?id=169 if (mCullStateDirty || mFrontFaceDirty) { if (mState.cullFace) { - device->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, mState.frontFace)); + mDevice->SetRenderState(D3DRS_CULLMODE, es2dx::ConvertCullMode(mState.cullMode, adjustedFrontFace)); } else { - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); } mCullStateDirty = false; @@ -1741,61 +2027,66 @@ void Context::applyState(GLenum drawMode) if (mDepthStateDirty) { - if (mState.depthTest && framebufferObject->getDepthbufferType() != GL_NONE) + if (mState.depthTest) { - device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc)); + mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); + mDevice->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc)); } else { - device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); } mDepthStateDirty = false; } + if (!zeroColorMaskAllowed && (mMaskStateDirty || mBlendStateDirty)) + { + mBlendStateDirty = true; + mMaskStateDirty = true; + } + if (mBlendStateDirty) { if (mState.blend) { - device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); if (mState.sourceBlendRGB != GL_CONSTANT_ALPHA && mState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && mState.destBlendRGB != GL_CONSTANT_ALPHA && mState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) { - device->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor)); + mDevice->SetRenderState(D3DRS_BLENDFACTOR, es2dx::ConvertColor(mState.blendColor)); } else { - device->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha), + mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(unorm<8>(mState.blendColor.alpha), unorm<8>(mState.blendColor.alpha), unorm<8>(mState.blendColor.alpha), unorm<8>(mState.blendColor.alpha))); } - device->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB)); - device->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB)); - device->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB)); + mDevice->SetRenderState(D3DRS_SRCBLEND, es2dx::ConvertBlendFunc(mState.sourceBlendRGB)); + mDevice->SetRenderState(D3DRS_DESTBLEND, es2dx::ConvertBlendFunc(mState.destBlendRGB)); + mDevice->SetRenderState(D3DRS_BLENDOP, es2dx::ConvertBlendOp(mState.blendEquationRGB)); if (mState.sourceBlendRGB != mState.sourceBlendAlpha || mState.destBlendRGB != mState.destBlendAlpha || mState.blendEquationRGB != mState.blendEquationAlpha) { - device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - - device->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha)); - device->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha)); - device->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha)); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, es2dx::ConvertBlendFunc(mState.sourceBlendAlpha)); + mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, es2dx::ConvertBlendFunc(mState.destBlendAlpha)); + mDevice->SetRenderState(D3DRS_BLENDOPALPHA, es2dx::ConvertBlendOp(mState.blendEquationAlpha)); } else { - device->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); } } else { - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); } mBlendStateDirty = false; @@ -1805,8 +2096,8 @@ void Context::applyState(GLenum drawMode) { if (mState.stencilTest && framebufferObject->hasStencil()) { - device->SetRenderState(D3DRS_STENCILENABLE, TRUE); - device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); + mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); // FIXME: Unsupported by D3D9 const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; @@ -1821,50 +2112,65 @@ void Context::applyState(GLenum drawMode) } // get the maximum size of the stencil ref - gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); + gl::Renderbuffer *stencilbuffer = framebufferObject->getStencilbuffer(); GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask); + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(mState.stencilFunc)); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilMask); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(mState.stencilFail)); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(mState.stencilPassDepthFail)); - device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + mDevice->SetRenderState(adjustedFrontFace == GL_CCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(mState.stencilPassDepthPass)); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilBackWritemask); + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, es2dx::ConvertComparison(mState.stencilBackFunc)); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, (mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, mState.stencilBackMask); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, es2dx::ConvertStencilOp(mState.stencilBackFail)); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, es2dx::ConvertStencilOp(mState.stencilBackPassDepthFail)); - device->SetRenderState(mState.frontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + mDevice->SetRenderState(adjustedFrontFace == GL_CW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, es2dx::ConvertStencilOp(mState.stencilBackPassDepthPass)); } else { - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); } mStencilStateDirty = false; + mFrontFaceDirty = false; } if (mMaskStateDirty) { - device->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, - mState.colorMaskBlue, mState.colorMaskAlpha)); - device->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE); + int colorMask = es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, + mState.colorMaskBlue, mState.colorMaskAlpha); + if (colorMask == 0 && !zeroColorMaskAllowed) + { + // Enable green channel, but set blending so nothing will be drawn. + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + } + else + { + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); + } + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, mState.depthMask ? TRUE : FALSE); mMaskStateDirty = false; } @@ -1873,18 +2179,18 @@ void Context::applyState(GLenum drawMode) { if (mState.polygonOffsetFill) { - gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer(); + gl::Renderbuffer *depthbuffer = framebufferObject->getDepthbuffer(); if (depthbuffer) { - device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor)); + mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor)); float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); - device->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias)); + mDevice->SetRenderState(D3DRS_DEPTHBIAS, *((DWORD*)&depthBias)); } } else { - device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - device->SetRenderState(D3DRS_DEPTHBIAS, 0); + mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); + mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); } mPolygonOffsetStateDirty = false; @@ -1892,48 +2198,41 @@ void Context::applyState(GLenum drawMode) if (mSampleStateDirty) { - if (framebufferObject->isMultisample()) + if (mState.sampleAlphaToCoverage) { - if (mState.sampleAlphaToCoverage) - { - FIXME("Sample alpha to coverage is unimplemented."); - } + FIXME("Sample alpha to coverage is unimplemented."); + } - device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - if (mState.sampleCoverage) + mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + if (mState.sampleCoverage) + { + unsigned int mask = 0; + if (mState.sampleCoverageValue != 0) { - unsigned int mask = 0; - if (mState.sampleCoverageValue != 0) + float threshold = 0.5f; + + for (int i = 0; i < framebufferObject->getSamples(); ++i) { - float threshold = 0.5f; + mask <<= 1; - for (int i = 0; i < framebufferObject->getSamples(); ++i) + if ((i + 1) * mState.sampleCoverageValue >= threshold) { - mask <<= 1; - - if ((i + 1) * mState.sampleCoverageValue >= threshold) - { - threshold += 1.0f; - mask |= 1; - } + threshold += 1.0f; + mask |= 1; } } - - if (mState.sampleCoverageInvert) - { - mask = ~mask; - } - - device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask); } - else + + if (mState.sampleCoverageInvert) { - device->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + mask = ~mask; } + + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, mask); } else { - device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); } mSampleStateDirty = false; @@ -1941,52 +2240,37 @@ void Context::applyState(GLenum drawMode) if (mDitherStateDirty) { - device->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE); + mDevice->SetRenderState(D3DRS_DITHERENABLE, mState.dither ? TRUE : FALSE); mDitherStateDirty = false; } - - mFrontFaceDirty = false; } -// Fill in the semanticIndex field of the array of TranslatedAttributes based on the active GLSL program. -void Context::lookupAttributeMapping(TranslatedAttribute *attributes) +GLenum Context::applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw) { - for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) - { - if (attributes[i].active) - { - attributes[i].semanticIndex = getCurrentProgram()->getSemanticIndex(i); - } - } -} + TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; -GLenum Context::applyVertexBuffer(GLint first, GLsizei count) -{ - TranslatedAttribute translated[MAX_VERTEX_ATTRIBS]; - - GLenum err = mVertexDataManager->prepareVertexData(first, count, translated); + GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instances); if (err != GL_NO_ERROR) { return err; } - lookupAttributeMapping(translated); - - mVertexDataManager->setupAttributes(translated); - - return GL_NO_ERROR; + return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, getCurrentProgram(), instances, repeatDraw); } // 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 Context::applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - IDirect3DDevice9 *device = getDevice(); GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo); if (err == GL_NO_ERROR) { - device->SetIndices(indexInfo->indexBuffer); + if (indexInfo->serial != mAppliedIBSerial) + { + mDevice->SetIndices(indexInfo->indexBuffer); + mAppliedIBSerial = indexInfo->serial; + } } return err; @@ -1995,19 +2279,16 @@ GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode // Applies the shaders and shader constants to the Direct3D 9 device void Context::applyShaders() { - IDirect3DDevice9 *device = getDevice(); Program *programObject = getCurrentProgram(); - IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader(); - IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader(); - - device->SetVertexShader(vertexShader); - device->SetPixelShader(pixelShader); - - if (programObject->getSerial() != mAppliedProgram) + if (programObject->getSerial() != mAppliedProgramSerial) { + IDirect3DVertexShader9 *vertexShader = programObject->getVertexShader(); + IDirect3DPixelShader9 *pixelShader = programObject->getPixelShader(); + + mDevice->SetPixelShader(pixelShader); + mDevice->SetVertexShader(vertexShader); programObject->dirtyAllUniforms(); - programObject->dirtyAllSamplers(); - mAppliedProgram = programObject->getSerial(); + mAppliedProgramSerial = programObject->getSerial(); } programObject->applyUniforms(); @@ -2016,58 +2297,96 @@ void Context::applyShaders() // Applies the textures and sampler states to the Direct3D 9 device void Context::applyTextures() { - IDirect3DDevice9 *device = getDevice(); + applyTextures(SAMPLER_PIXEL); + + if (mSupportsVertexTexture) + { + applyTextures(SAMPLER_VERTEX); + } +} + +// For each Direct3D 9 sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +void Context::applyTextures(SamplerType type) +{ Program *programObject = getCurrentProgram(); - for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) + int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; // Range of Direct3D 9 samplers of given sampler type + unsigned int *appliedTextureSerial = (type == SAMPLER_PIXEL) ? mAppliedTextureSerialPS : mAppliedTextureSerialVS; + int d3dSamplerOffset = (type == SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int samplerRange = programObject->getUsedSamplerRange(type); + + for (int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) { - int textureUnit = programObject->getSamplerMapping(sampler); + int textureUnit = programObject->getSamplerMapping(type, samplerIndex); // OpenGL texture image unit index + int d3dSampler = samplerIndex + d3dSamplerOffset; + if (textureUnit != -1) { - SamplerType textureType = programObject->getSamplerType(sampler); + TextureType textureType = programObject->getSamplerTextureType(type, samplerIndex); Texture *texture = getSamplerTexture(textureUnit, textureType); - if (programObject->isSamplerDirty(sampler) || texture->isDirty()) + if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters() || texture->hasDirtyImages()) { - if (texture->isComplete()) - { - GLenum wrapS = texture->getWrapS(); - GLenum wrapT = texture->getWrapT(); - GLenum minFilter = texture->getMinFilter(); - GLenum magFilter = texture->getMagFilter(); - - device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS)); - device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT)); + IDirect3DBaseTexture9 *d3dTexture = texture->getTexture(); - device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter)); - D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; - es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter); - device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter); - device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter); + if (d3dTexture) + { + if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyParameters()) + { + GLenum wrapS = texture->getWrapS(); + GLenum wrapT = texture->getWrapT(); + GLenum minFilter = texture->getMinFilter(); + GLenum magFilter = texture->getMagFilter(); + + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT)); + + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter)); + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; + es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); + } - device->SetTexture(sampler, texture->getTexture()); + if (appliedTextureSerial[samplerIndex] != texture->getTextureSerial() || texture->hasDirtyImages()) + { + mDevice->SetTexture(d3dSampler, d3dTexture); + } } else { - device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture()); + mDevice->SetTexture(d3dSampler, getIncompleteTexture(textureType)->getTexture()); } - } - programObject->setSamplerDirty(sampler, false); + appliedTextureSerial[samplerIndex] = texture->getTextureSerial(); + texture->resetDirty(); + } } else { - if (programObject->isSamplerDirty(sampler)) + if (appliedTextureSerial[samplerIndex] != 0) { - device->SetTexture(sampler, NULL); - programObject->setSamplerDirty(sampler, false); + mDevice->SetTexture(d3dSampler, NULL); + appliedTextureSerial[samplerIndex] = 0; } - } + } + } + + for (int samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) + { + if (appliedTextureSerial[samplerIndex] != 0) + { + mDevice->SetTexture(samplerIndex + d3dSamplerOffset, NULL); + appliedTextureSerial[samplerIndex] = 0; + } } } -void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) +void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei *bufSize, void* pixels) { Framebuffer *framebuffer = getReadFramebuffer(); @@ -2081,55 +2400,93 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum return error(GL_INVALID_OPERATION); } - IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget(); + GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); + // sized query sanity check + if (bufSize) + { + int requiredSize = outputPitch * height; + if (requiredSize > *bufSize) + { + return error(GL_INVALID_OPERATION); + } + } + IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget(); if (!renderTarget) { return; // Context must be lost, return silently } - IDirect3DDevice9 *device = getDevice(); - D3DSURFACE_DESC desc; renderTarget->GetDesc(&desc); - IDirect3DSurface9 *systemSurface; - HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL); - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) { + UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target + renderTarget->Release(); return error(GL_OUT_OF_MEMORY); } - ASSERT(SUCCEEDED(result)); + HRESULT result; + IDirect3DSurface9 *systemSurface = NULL; + bool directToPixels = getPackReverseRowOrder() && getPackAlignment() <= 4 && mDisplay->isD3d9ExDevice() && + x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && + desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; + if (directToPixels) + { + // Use the pixels ptr as a shared handle to write directly into client's memory + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, &pixels); + if (FAILED(result)) + { + // Try again without the shared handle + directToPixels = false; + } + } - if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) + if (!directToPixels) { - UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, NULL); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return error(GL_OUT_OF_MEMORY); + } } - result = device->GetRenderTargetData(renderTarget, systemSurface); + result = mDevice->GetRenderTargetData(renderTarget, systemSurface); + renderTarget->Release(); + renderTarget = NULL; if (FAILED(result)) { systemSurface->Release(); - switch (result) + // It turns out that D3D will sometimes produce more error + // codes than those documented. + if (checkDeviceLost(result)) + return error(GL_OUT_OF_MEMORY); + else { - case D3DERR_DRIVERINTERNALERROR: - case D3DERR_DEVICELOST: - return error(GL_OUT_OF_MEMORY); - default: - UNREACHABLE(); - return; // No sensible error to generate + UNREACHABLE(); + return; } + + } + + if (directToPixels) + { + systemSurface->Release(); + return; } D3DLOCKED_RECT lock; - RECT rect = {std::max(x, 0), - std::max(y, 0), - std::min(x + width, (int)desc.Width), - std::min(y + height, (int)desc.Height)}; + RECT rect = transformPixelRect(x, y, width, height, desc.Height); + rect.left = clamp(rect.left, 0L, static_cast<LONG>(desc.Width)); + rect.top = clamp(rect.top, 0L, static_cast<LONG>(desc.Height)); + rect.right = clamp(rect.right, 0L, static_cast<LONG>(desc.Width)); + rect.bottom = clamp(rect.bottom, 0L, static_cast<LONG>(desc.Height)); result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); @@ -2141,11 +2498,21 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum return; // No sensible error to generate } - unsigned char *source = (unsigned char*)lock.pBits; unsigned char *dest = (unsigned char*)pixels; unsigned short *dest16 = (unsigned short*)pixels; - GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); + unsigned char *source; + int inputPitch; + if (getPackReverseRowOrder()) + { + source = (unsigned char*)lock.pBits; + inputPitch = lock.Pitch; + } + else + { + source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); + inputPitch = -lock.Pitch; + } for (int j = 0; j < rect.bottom - rect.top; j++) { @@ -2157,7 +2524,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum // an RGBA source buffer. Note that buffers with no // alpha go through the slow path below. memcpy(dest + j * outputPitch, - source + j * lock.Pitch, + source + j * inputPitch, (rect.right - rect.left) * 4); continue; } @@ -2173,7 +2540,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum { case D3DFMT_R5G6B5: { - unsigned short rgb = *(unsigned short*)(source + 2 * i + j * lock.Pitch); + unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); a = 1.0f; b = (rgb & 0x001F) * (1.0f / 0x001F); @@ -2183,7 +2550,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum break; case D3DFMT_A1R5G5B5: { - unsigned short argb = *(unsigned short*)(source + 2 * i + j * lock.Pitch); + unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); a = (argb & 0x8000) ? 1.0f : 0.0f; b = (argb & 0x001F) * (1.0f / 0x001F); @@ -2193,7 +2560,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum break; case D3DFMT_A8R8G8B8: { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); a = (argb & 0xFF000000) * (1.0f / 0xFF000000); b = (argb & 0x000000FF) * (1.0f / 0x000000FF); @@ -2203,7 +2570,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum break; case D3DFMT_X8R8G8B8: { - unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); + unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); a = 1.0f; b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); @@ -2213,7 +2580,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum break; case D3DFMT_A2R10G10B10: { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * lock.Pitch); + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); a = (argb & 0xC0000000) * (1.0f / 0xC0000000); b = (argb & 0x000003FF) * (1.0f / 0x000003FF); @@ -2224,10 +2591,10 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum 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); + r = *((float*)(source + 16 * i + j * inputPitch) + 0); + g = *((float*)(source + 16 * i + j * inputPitch) + 1); + b = *((float*)(source + 16 * i + j * inputPitch) + 2); + a = *((float*)(source + 16 * i + j * inputPitch) + 3); } break; case D3DFMT_A16B16G16R16F: @@ -2235,7 +2602,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum // 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); + D3DXFloat16To32Array(abgr, (D3DXFLOAT16*)(source + 8 * i + j * inputPitch), 4); a = abgr[3]; b = abgr[2]; @@ -2246,6 +2613,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum default: UNIMPLEMENTED(); // FIXME UNREACHABLE(); + return; } switch (format) @@ -2330,13 +2698,9 @@ void Context::clear(GLbitfield mask) if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) { - error(GL_INVALID_FRAMEBUFFER_OPERATION); - - return; + return error(GL_INVALID_FRAMEBUFFER_OPERATION); } - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); DWORD flags = 0; if (mask & GL_COLOR_BUFFER_BIT) @@ -2375,7 +2739,7 @@ void Context::clear(GLbitfield mask) D3DSURFACE_DESC desc; depthStencil->GetDesc(&desc); - unsigned int stencilSize = es2dx::GetStencilSize(desc.Format); + unsigned int stencilSize = dx2es::GetStencilSize(desc.Format); stencilUnmasked = (0x1 << stencilSize) - 1; if (stencilUnmasked != 0x0) @@ -2396,23 +2760,13 @@ void Context::clear(GLbitfield mask) } D3DCOLOR color = D3DCOLOR_ARGB(unorm<8>(mState.colorClearValue.alpha), - unorm<8>(mState.colorClearValue.red), - unorm<8>(mState.colorClearValue.green), - unorm<8>(mState.colorClearValue.blue)); + unorm<8>(mState.colorClearValue.red), + unorm<8>(mState.colorClearValue.green), + unorm<8>(mState.colorClearValue.blue)); float depth = clamp01(mState.depthClearValue); int stencil = mState.stencilClearValue & 0x000000FF; - IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget(); - - if (!renderTarget) - { - return; // Context must be lost, return silently - } - - D3DSURFACE_DESC desc; - renderTarget->GetDesc(&desc); - - bool alphaUnmasked = (es2dx::GetAlphaSize(desc.Format) == 0) || mState.colorMaskAlpha; + bool alphaUnmasked = (dx2es::GetAlphaSize(mRenderTargetDesc.Format) == 0) || mState.colorMaskAlpha; const bool needMaskedStencilClear = (flags & D3DCLEAR_STENCIL) && (mState.stencilWritemask & stencilUnmasked) != stencilUnmasked; @@ -2428,25 +2782,37 @@ void Context::clear(GLbitfield mask) HRESULT hr; if (mMaskedClearSavedState == NULL) { - hr = device->BeginStateBlock(); + hr = mDevice->BeginStateBlock(); ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - device->SetRenderState(D3DRS_ZENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); - device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); - device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - - hr = device->EndStateBlock(&mMaskedClearSavedState); + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + mDevice->SetPixelShader(NULL); + mDevice->SetVertexShader(NULL); + mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); + mDevice->SetStreamSource(0, NULL, 0, 0); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + mDevice->SetStreamSourceFreq(i, 1); + } + + hr = mDevice->EndStateBlock(&mMaskedClearSavedState); ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); } @@ -2458,88 +2824,86 @@ void Context::clear(GLbitfield mask) ASSERT(SUCCEEDED(hr)); } - device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - device->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - device->SetRenderState(D3DRS_ZENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); if (flags & D3DCLEAR_TARGET) { - device->SetRenderState(D3DRS_COLORWRITEENABLE, (mState.colorMaskRed ? D3DCOLORWRITEENABLE_RED : 0) | - (mState.colorMaskGreen ? D3DCOLORWRITEENABLE_GREEN : 0) | - (mState.colorMaskBlue ? D3DCOLORWRITEENABLE_BLUE : 0) | - (mState.colorMaskAlpha ? D3DCOLORWRITEENABLE_ALPHA : 0)); + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, es2dx::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); } else { - device->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); } if (stencilUnmasked != 0x0 && (flags & D3DCLEAR_STENCIL)) { - device->SetRenderState(D3DRS_STENCILENABLE, TRUE); - device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); - device->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - device->SetRenderState(D3DRS_STENCILREF, stencil); - device->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask); - device->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); - device->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE); - device->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_STENCILREF, stencil); + mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, mState.stencilWritemask); + mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); mStencilStateDirty = true; } else { - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); } - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); - device->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); - device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - - struct Vertex + mDevice->SetPixelShader(NULL); + mDevice->SetVertexShader(NULL); + mDevice->SetFVF(D3DFVF_XYZRHW); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { - float x, y, z, w; - D3DCOLOR diffuse; - }; + mDevice->SetStreamSourceFreq(i, 1); + } + + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges + quad[0][0] = -0.5f; + quad[0][1] = mRenderTargetDesc.Height - 0.5f; + quad[0][2] = 0.0f; + quad[0][3] = 1.0f; + + quad[1][0] = mRenderTargetDesc.Width - 0.5f; + quad[1][1] = mRenderTargetDesc.Height - 0.5f; + quad[1][2] = 0.0f; + quad[1][3] = 1.0f; + + quad[2][0] = -0.5f; + quad[2][1] = -0.5f; + quad[2][2] = 0.0f; + quad[2][3] = 1.0f; - Vertex quad[4]; - quad[0].x = 0.0f; - quad[0].y = (float)desc.Height; - quad[0].z = 0.0f; - quad[0].w = 1.0f; - quad[0].diffuse = color; - - quad[1].x = (float)desc.Width; - quad[1].y = (float)desc.Height; - quad[1].z = 0.0f; - quad[1].w = 1.0f; - quad[1].diffuse = color; - - quad[2].x = 0.0f; - quad[2].y = 0.0f; - quad[2].z = 0.0f; - quad[2].w = 1.0f; - quad[2].diffuse = color; - - quad[3].x = (float)desc.Width; - quad[3].y = 0.0f; - quad[3].z = 0.0f; - quad[3].w = 1.0f; - quad[3].diffuse = color; - - display->startScene(); - device->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(Vertex)); + quad[3][0] = mRenderTargetDesc.Width - 0.5f; + quad[3][1] = -0.5f; + quad[3][2] = 0.0f; + quad[3][3] = 1.0f; + + mDisplay->startScene(); + mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4])); if (flags & D3DCLEAR_ZBUFFER) { - device->SetRenderState(D3DRS_ZENABLE, TRUE); - device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - device->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); + mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); } if (mMaskedClearSavedState != NULL) @@ -2549,19 +2913,17 @@ void Context::clear(GLbitfield mask) } else if (flags) { - device->Clear(0, NULL, flags, color, depth, stencil); + mDevice->Clear(0, NULL, flags, color, depth, stencil); } } -void Context::drawArrays(GLenum mode, GLint first, GLsizei count) +void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances) { if (!mState.currentProgram) { return error(GL_INVALID_OPERATION); } - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); D3DPRIMITIVETYPE primitiveType; int primitiveCount; @@ -2580,7 +2942,8 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) applyState(mode); - GLenum err = applyVertexBuffer(first, count); + GLsizei repeatDraw = 1; + GLenum err = applyVertexBuffer(first, count, instances, &repeatDraw); if (err != GL_NO_ERROR) { return error(err); @@ -2589,25 +2952,49 @@ void Context::drawArrays(GLenum mode, GLint first, GLsizei count) applyShaders(); applyTextures(); - if (!getCurrentProgram()->validateSamplers()) + if (!getCurrentProgram()->validateSamplers(false)) { return error(GL_INVALID_OPERATION); } if (!cullSkipsDraw(mode)) { - display->startScene(); + mDisplay->startScene(); - device->DrawPrimitive(primitiveType, 0, primitiveCount); + if (mode == GL_LINE_LOOP) + { + drawLineLoop(count, GL_NONE, NULL, 0); + } + else if (instances > 0) + { + StaticIndexBuffer *countingIB = mIndexDataManager->getCountingIndices(count); + if (countingIB) + { + if (mAppliedIBSerial != countingIB->getSerial()) + { + mDevice->SetIndices(countingIB->getBuffer()); + mAppliedIBSerial = countingIB->getSerial(); + } - if (mode == GL_LINE_LOOP) // Draw the last segment separately + for (int i = 0; i < repeatDraw; i++) + { + mDevice->DrawIndexedPrimitive(primitiveType, 0, 0, count, 0, primitiveCount); + } + } + else + { + ERR("Could not create a counting index buffer for glDrawArraysInstanced."); + return error(GL_OUT_OF_MEMORY); + } + } + else // Regular case { - drawClosingLine(first, first + count - 1); + mDevice->DrawPrimitive(primitiveType, 0, primitiveCount); } } } -void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) +void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances) { if (!mState.currentProgram) { @@ -2619,8 +3006,6 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void * return error(GL_INVALID_OPERATION); } - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); D3DPRIMITIVETYPE primitiveType; int primitiveCount; @@ -2647,7 +3032,8 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void * } GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; - err = applyVertexBuffer(indexInfo.minIndex, vertexCount); + GLsizei repeatDraw = 1; + err = applyVertexBuffer(indexInfo.minIndex, vertexCount, instances, &repeatDraw); if (err != GL_NO_ERROR) { return error(err); @@ -2656,188 +3042,178 @@ void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void * applyShaders(); applyTextures(); - if (!getCurrentProgram()->validateSamplers()) + if (!getCurrentProgram()->validateSamplers(false)) { return error(GL_INVALID_OPERATION); } if (!cullSkipsDraw(mode)) { - display->startScene(); - - 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); - } - } -} - -void Context::finish() -{ - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); - IDirect3DQuery9 *occlusionQuery = NULL; - - HRESULT result = device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery); - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - return error(GL_OUT_OF_MEMORY); - } - - ASSERT(SUCCEEDED(result)); - - if (occlusionQuery) - { - IDirect3DStateBlock9 *savedState = NULL; - device->CreateStateBlock(D3DSBT_ALL, &savedState); - - HRESULT result = occlusionQuery->Issue(D3DISSUE_BEGIN); - ASSERT(SUCCEEDED(result)); - - // Render something outside the render target - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); - device->SetFVF(D3DFVF_XYZRHW); - float data[4] = {-1.0f, -1.0f, -1.0f, 1.0f}; - display->startScene(); - device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data)); - - result = occlusionQuery->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); + mDisplay->startScene(); - while (occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE) + if (mode == GL_LINE_LOOP) { - // Keep polling, but allow other threads to do something useful first - Sleep(0); + drawLineLoop(count, type, indices, indexInfo.minIndex); } - - occlusionQuery->Release(); - - if (savedState) + else { - savedState->Apply(); - savedState->Release(); + for (int i = 0; i < repeatDraw; i++) + { + mDevice->DrawIndexedPrimitive(primitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, primitiveCount); + } } } } -void Context::flush() +// Implements glFlush when block is false, glFinish when block is true +void Context::sync(bool block) { - IDirect3DDevice9 *device = getDevice(); - IDirect3DQuery9 *eventQuery = NULL; - - HRESULT result = device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery); + mDisplay->sync(block); +} - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) +void Context::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex) +{ + // Get the raw indices for an indexed draw + if (type != GL_NONE && mState.elementArrayBuffer.get()) { - return error(GL_OUT_OF_MEMORY); + Buffer *indexBuffer = mState.elementArrayBuffer.get(); + intptr_t offset = reinterpret_cast<intptr_t>(indices); + indices = static_cast<const GLubyte*>(indexBuffer->data()) + offset; } - ASSERT(SUCCEEDED(result)); + UINT startIndex = 0; + bool succeeded = false; - if (eventQuery) + if (supports32bitIndices()) { - HRESULT result = eventQuery->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); + const int spaceNeeded = (count + 1) * sizeof(unsigned int); - result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); - eventQuery->Release(); - - if (result == D3DERR_DEVICELOST) + if (!mLineLoopIB) { - error(GL_OUT_OF_MEMORY); + mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32); } - } -} - -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)) + if (mLineLoopIB) { - unsigned int *data; - result = indexBuffer->Lock(0, 0, (void**)&data, 0); + mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_INT); - if (SUCCEEDED(result)) + UINT offset = 0; + unsigned int *data = static_cast<unsigned int*>(mLineLoopIB->map(spaceNeeded, &offset)); + startIndex = offset / 4; + + if (data) { - data[0] = last; - data[1] = first; + switch (type) + { + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = i; + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLubyte*>(indices)[i]; + } + data[count] = static_cast<const GLubyte*>(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLushort*>(indices)[i]; + } + data[count] = static_cast<const GLushort*>(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLuint*>(indices)[i]; + } + data[count] = static_cast<const GLuint*>(indices)[0]; + break; + default: UNREACHABLE(); + } + + mLineLoopIB->unmap(); + succeeded = true; } } } else { - result = device->CreateIndexBuffer(4, D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, 0); + const int spaceNeeded = (count + 1) * sizeof(unsigned short); - if (SUCCEEDED(result)) + if (!mLineLoopIB) { - unsigned short *data; - result = indexBuffer->Lock(0, 0, (void**)&data, 0); + mLineLoopIB = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16); + } - if (SUCCEEDED(result)) + if (mLineLoopIB) + { + mLineLoopIB->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT); + + UINT offset = 0; + unsigned short *data = static_cast<unsigned short*>(mLineLoopIB->map(spaceNeeded, &offset)); + startIndex = offset / 2; + + if (data) { - data[0] = last; - data[1] = first; + switch (type) + { + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = i; + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLubyte*>(indices)[i]; + } + data[count] = static_cast<const GLubyte*>(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLushort*>(indices)[i]; + } + data[count] = static_cast<const GLushort*>(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast<const GLuint*>(indices)[i]; + } + data[count] = static_cast<const GLuint*>(indices)[0]; + break; + default: UNREACHABLE(); + } + + mLineLoopIB->unmap(); + succeeded = true; } } } - if (SUCCEEDED(result)) + if (succeeded) { - indexBuffer->Unlock(); - device->SetIndices(indexBuffer); - - device->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, 2, 0, 1); + if (mAppliedIBSerial != mLineLoopIB->getSerial()) + { + mDevice->SetIndices(mLineLoopIB->getBuffer()); + mAppliedIBSerial = mLineLoopIB->getSerial(); + } - indexBuffer->Release(); + mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); } 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(); + ERR("Could not create a looping index buffer for GL_LINE_LOOP."); + return error(GL_OUT_OF_MEMORY); } - - drawClosingLine(first, last); } void Context::recordInvalidEnum() @@ -2907,6 +3283,36 @@ GLenum Context::getError() return GL_NO_ERROR; } +GLenum Context::getResetStatus() +{ + if (mResetStatus == GL_NO_ERROR) + { + bool lost = mDisplay->testDeviceLost(); + + if (lost) + { + mDisplay->notifyDeviceLost(); // Sets mResetStatus + } + } + + GLenum status = mResetStatus; + + if (mResetStatus != GL_NO_ERROR) + { + if (mDisplay->testDeviceResettable()) + { + mResetStatus = GL_NO_ERROR; + } + } + + return status; +} + +bool Context::isResetNotificationEnabled() +{ + return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT); +} + bool Context::supportsShaderModel3() const { return mSupportsShaderModel3; @@ -2917,6 +3323,16 @@ int Context::getMaximumVaryingVectors() const return mSupportsShaderModel3 ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2; } +unsigned int Context::getMaximumVertexTextureImageUnits() const +{ + return mSupportsVertexTexture ? MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF : 0; +} + +unsigned int Context::getMaximumCombinedTextureImageUnits() const +{ + return MAX_TEXTURE_IMAGE_UNITS + getMaximumVertexTextureImageUnits(); +} + int Context::getMaximumFragmentUniformVectors() const { return mSupportsShaderModel3 ? MAX_FRAGMENT_UNIFORM_VECTORS_SM3 : MAX_FRAGMENT_UNIFORM_VECTORS_SM2; @@ -2956,39 +3372,54 @@ bool Context::supportsEventQueries() const return mSupportsEventQueries; } -bool Context::supportsCompressedTextures() const +bool Context::supportsOcclusionQueries() const +{ + return mSupportsOcclusionQueries; +} + +bool Context::supportsDXT1Textures() const +{ + return mSupportsDXT1Textures; +} + +bool Context::supportsDXT3Textures() const +{ + return mSupportsDXT3Textures; +} + +bool Context::supportsDXT5Textures() const { - return mSupportsCompressedTextures; + return mSupportsDXT5Textures; } -bool Context::supportsFloatTextures() const +bool Context::supportsFloat32Textures() const { - return mSupportsFloatTextures; + return mSupportsFloat32Textures; } -bool Context::supportsFloatLinearFilter() const +bool Context::supportsFloat32LinearFilter() const { - return mSupportsFloatLinearFilter; + return mSupportsFloat32LinearFilter; } -bool Context::supportsFloatRenderableTextures() const +bool Context::supportsFloat32RenderableTextures() const { - return mSupportsFloatRenderableTextures; + return mSupportsFloat32RenderableTextures; } -bool Context::supportsHalfFloatTextures() const +bool Context::supportsFloat16Textures() const { - return mSupportsHalfFloatTextures; + return mSupportsFloat16Textures; } -bool Context::supportsHalfFloatLinearFilter() const +bool Context::supportsFloat16LinearFilter() const { - return mSupportsHalfFloatLinearFilter; + return mSupportsFloat16LinearFilter; } -bool Context::supportsHalfFloatRenderableTextures() const +bool Context::supportsFloat16RenderableTextures() const { - return mSupportsHalfFloatRenderableTextures; + return mSupportsFloat16RenderableTextures; } int Context::getMaximumRenderbufferDimension() const @@ -3026,6 +3457,16 @@ bool Context::supports32bitIndices() const return mSupports32bitIndices; } +bool Context::supportsNonPower2Texture() const +{ + return mSupportsNonPower2Texture; +} + +bool Context::supportsInstancing() const +{ + return mSupportsInstancing; +} + void Context::detachBuffer(GLuint buffer) { // [OpenGL ES 2.0.24] section 2.9 page 22: @@ -3057,9 +3498,9 @@ void Context::detachTexture(GLuint texture) // If a texture object is deleted, it is as if all texture units which are bound to that texture object are // rebound to texture object zero - for (int type = 0; type < SAMPLER_TYPE_COUNT; type++) + for (int type = 0; type < TEXTURE_TYPE_COUNT; type++) { - for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) + for (int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; sampler++) { if (mState.samplerTexture[type][sampler].id() == texture) { @@ -3134,7 +3575,7 @@ void Context::detachRenderbuffer(GLuint renderbuffer) } } -Texture *Context::getIncompleteTexture(SamplerType type) +Texture *Context::getIncompleteTexture(TextureType type) { Texture *t = mIncompleteTextures[type].get(); @@ -3146,26 +3587,26 @@ Texture *Context::getIncompleteTexture(SamplerType type) { default: UNREACHABLE(); - // default falls through to SAMPLER_2D + // default falls through to TEXTURE_2D - case SAMPLER_2D: + case TEXTURE_2D: { Texture2D *incomplete2d = new Texture2D(Texture::INCOMPLETE_TEXTURE_ID); - incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); t = incomplete2d; } break; - case SAMPLER_CUBE: + case TEXTURE_CUBE: { TextureCubeMap *incompleteCube = new TextureCubeMap(Texture::INCOMPLETE_TEXTURE_ID); - incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); - incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); + incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color); t = incompleteCube; } @@ -3214,53 +3655,100 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values) mVertexDataManager->dirtyCurrentValue(index); } +void Context::setVertexAttribDivisor(GLuint index, GLuint divisor) +{ + ASSERT(index < gl::MAX_VERTEX_ATTRIBS); + + mState.vertexAttribute[index].mDivisor = divisor; +} + +// keep list sorted in following order +// OES extensions +// EXT extensions +// Vendor extensions void Context::initExtensionString() { + mExtensionString = ""; + + // OES extensions + if (supports32bitIndices()) + { + mExtensionString += "GL_OES_element_index_uint "; + } + mExtensionString += "GL_OES_packed_depth_stencil "; - mExtensionString += "GL_EXT_texture_format_BGRA8888 "; - mExtensionString += "GL_EXT_read_format_bgra "; - mExtensionString += "GL_ANGLE_framebuffer_blit "; mExtensionString += "GL_OES_rgb8_rgba8 "; mExtensionString += "GL_OES_standard_derivatives "; - if (supportsEventQueries()) + if (supportsFloat16Textures()) { - mExtensionString += "GL_NV_fence "; + mExtensionString += "GL_OES_texture_half_float "; } - - if (supportsCompressedTextures()) + if (supportsFloat16LinearFilter()) { - mExtensionString += "GL_EXT_texture_compression_dxt1 "; + mExtensionString += "GL_OES_texture_half_float_linear "; } - - if (supportsFloatTextures()) + if (supportsFloat32Textures()) { mExtensionString += "GL_OES_texture_float "; } + if (supportsFloat32LinearFilter()) + { + mExtensionString += "GL_OES_texture_float_linear "; + } - if (supportsHalfFloatTextures()) + if (supportsNonPower2Texture()) { - mExtensionString += "GL_OES_texture_half_float "; + mExtensionString += "GL_OES_texture_npot "; } - if (supportsFloatLinearFilter()) + // Multi-vendor (EXT) extensions + if (supportsOcclusionQueries()) { - mExtensionString += "GL_OES_texture_float_linear "; + mExtensionString += "GL_EXT_occlusion_query_boolean "; } - if (supportsHalfFloatLinearFilter()) + mExtensionString += "GL_EXT_read_format_bgra "; + mExtensionString += "GL_EXT_robustness "; + + if (supportsDXT1Textures()) { - mExtensionString += "GL_OES_texture_half_float_linear "; + mExtensionString += "GL_EXT_texture_compression_dxt1 "; } + mExtensionString += "GL_EXT_texture_format_BGRA8888 "; + mExtensionString += "GL_EXT_texture_storage "; + + // ANGLE-specific extensions + mExtensionString += "GL_ANGLE_framebuffer_blit "; if (getMaxSupportedSamples() != 0) { mExtensionString += "GL_ANGLE_framebuffer_multisample "; } - if (supports32bitIndices()) + if (supportsInstancing()) { - mExtensionString += "GL_OES_element_index_uint "; + mExtensionString += "GL_ANGLE_instanced_arrays "; + } + + mExtensionString += "GL_ANGLE_pack_reverse_row_order "; + + if (supportsDXT3Textures()) + { + mExtensionString += "GL_ANGLE_texture_compression_dxt3 "; + } + if (supportsDXT5Textures()) + { + mExtensionString += "GL_ANGLE_texture_compression_dxt5 "; + } + + mExtensionString += "GL_ANGLE_texture_usage "; + mExtensionString += "GL_ANGLE_translated_shader_source "; + + // Other vendor-specific extensions + if (supportsEventQueries()) + { + mExtensionString += "GL_NV_fence "; } std::string::size_type end = mExtensionString.find_last_not_of(' '); @@ -3275,12 +3763,24 @@ const char *Context::getExtensionString() const return mExtensionString.c_str(); } +void Context::initRendererString() +{ + D3DADAPTER_IDENTIFIER9 *identifier = mDisplay->getAdapterIdentifier(); + + mRendererString = "ANGLE ("; + mRendererString += identifier->Description; + mRendererString += ")"; +} + +const char *Context::getRendererString() const +{ + return mRendererString.c_str(); +} + void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask) { - IDirect3DDevice9 *device = getDevice(); - Framebuffer *readFramebuffer = getReadFramebuffer(); Framebuffer *drawFramebuffer = getDrawFramebuffer(); @@ -3295,6 +3795,11 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 return error(GL_INVALID_OPERATION); } + int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth(); + int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight(); + int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth(); + int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight(); + RECT sourceRect; RECT destRect; @@ -3313,21 +3818,19 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 destRect.right = dstX0; } - // Arguments to StretchRect must be in D3D-style (0-top) coordinates, so we must - // flip our Y-values here if (srcY0 < srcY1) { - sourceRect.bottom = srcY1; - destRect.bottom = dstY1; - sourceRect.top = srcY0; - destRect.top = dstY0; + sourceRect.top = readBufferHeight - srcY1; + destRect.top = drawBufferHeight - dstY1; + sourceRect.bottom = readBufferHeight - srcY0; + destRect.bottom = drawBufferHeight - dstY0; } else { - sourceRect.bottom = srcY0; - destRect.bottom = dstY0; - sourceRect.top = srcY1; - destRect.top = dstY1; + sourceRect.top = readBufferHeight - srcY0; + destRect.top = drawBufferHeight - dstY0; + sourceRect.bottom = readBufferHeight - srcY1; + destRect.bottom = drawBufferHeight - dstY1; } RECT sourceScissoredRect = sourceRect; @@ -3382,11 +3885,6 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 destTrimmedRect.left += xDiff; } - int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth(); - int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight(); - int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth(); - int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight(); - if (sourceTrimmedRect.right > readBufferWidth) { int xDiff = sourceTrimmedRect.right - readBufferWidth; @@ -3470,8 +3968,8 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) { - DepthStencilbuffer *readDSBuffer = NULL; - DepthStencilbuffer *drawDSBuffer = NULL; + Renderbuffer *readDSBuffer = NULL; + Renderbuffer *drawDSBuffer = NULL; // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have // both a depth and stencil buffer, it will be the same buffer. @@ -3523,13 +4021,18 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 if (blitRenderTarget || blitDepthStencil) { - egl::Display *display = getDisplay(); - display->endScene(); + mDisplay->endScene(); if (blitRenderTarget) { - HRESULT result = device->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect, - drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE); + IDirect3DSurface9* readRenderTarget = readFramebuffer->getRenderTarget(); + IDirect3DSurface9* drawRenderTarget = drawFramebuffer->getRenderTarget(); + + HRESULT result = mDevice->StretchRect(readRenderTarget, &sourceTrimmedRect, + drawRenderTarget, &destTrimmedRect, D3DTEXF_NONE); + + readRenderTarget->Release(); + drawRenderTarget->Release(); if (FAILED(result)) { @@ -3540,7 +4043,7 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 if (blitDepthStencil) { - HRESULT result = device->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE); + HRESULT result = mDevice->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE); if (FAILED(result)) { @@ -3551,13 +4054,204 @@ void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1 } } +VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + mVertexDeclCache[i].vertexDeclaration = NULL; + mVertexDeclCache[i].lruCount = 0; + } +} + +VertexDeclarationCache::~VertexDeclarationCache() +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + if (mVertexDeclCache[i].vertexDeclaration) + { + mVertexDeclCache[i].vertexDeclaration->Release(); + } + } +} + +GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program, GLsizei instances, GLsizei *repeatDraw) +{ + *repeatDraw = 1; + + int indexedAttribute = MAX_VERTEX_ATTRIBS; + int instancedAttribute = MAX_VERTEX_ATTRIBS; + + if (instances > 0) + { + // Find an indexed attribute to be mapped to D3D stream 0 + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (attributes[i].active) + { + if (indexedAttribute == MAX_VERTEX_ATTRIBS) + { + if (attributes[i].divisor == 0) + { + indexedAttribute = i; + } + } + else if (instancedAttribute == MAX_VERTEX_ATTRIBS) + { + if (attributes[i].divisor != 0) + { + instancedAttribute = i; + } + } + else break; // Found both an indexed and instanced attribute + } + } + + if (indexedAttribute == MAX_VERTEX_ATTRIBS) + { + return GL_INVALID_OPERATION; + } + } + + D3DVERTEXELEMENT9 elements[MAX_VERTEX_ATTRIBS + 1]; + D3DVERTEXELEMENT9 *element = &elements[0]; + + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (attributes[i].active) + { + int stream = i; + + if (instances > 0) + { + // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced. + if (instancedAttribute == MAX_VERTEX_ATTRIBS) + { + *repeatDraw = instances; + } + else + { + if (i == indexedAttribute) + { + stream = 0; + } + else if (i == 0) + { + stream = indexedAttribute; + } + + UINT frequency = 1; + + if (attributes[i].divisor == 0) + { + frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances; + } + else + { + frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor; + } + + device->SetStreamSourceFreq(stream, frequency); + mInstancingEnabled = true; + } + } + + if (mAppliedVBs[stream].serial != attributes[i].serial || + mAppliedVBs[stream].stride != attributes[i].stride || + mAppliedVBs[stream].offset != attributes[i].offset) + { + device->SetStreamSource(stream, attributes[i].vertexBuffer, attributes[i].offset, attributes[i].stride); + mAppliedVBs[stream].serial = attributes[i].serial; + mAppliedVBs[stream].stride = attributes[i].stride; + mAppliedVBs[stream].offset = attributes[i].offset; + } + + element->Stream = stream; + element->Offset = 0; + element->Type = attributes[i].type; + element->Method = D3DDECLMETHOD_DEFAULT; + element->Usage = D3DDECLUSAGE_TEXCOORD; + element->UsageIndex = program->getSemanticIndex(i); + element++; + } + } + + if (instances == 0 || instancedAttribute == MAX_VERTEX_ATTRIBS) + { + if (mInstancingEnabled) + { + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } + + mInstancingEnabled = false; + } + } + + static const D3DVERTEXELEMENT9 end = D3DDECL_END(); + *(element++) = end; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + VertexDeclCacheEntry *entry = &mVertexDeclCache[i]; + if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration) + { + entry->lruCount = ++mMaxLru; + if(entry->vertexDeclaration != mLastSetVDecl) + { + device->SetVertexDeclaration(entry->vertexDeclaration); + mLastSetVDecl = entry->vertexDeclaration; + } + + return GL_NO_ERROR; + } + } + + VertexDeclCacheEntry *lastCache = mVertexDeclCache; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + if (mVertexDeclCache[i].lruCount < lastCache->lruCount) + { + lastCache = &mVertexDeclCache[i]; + } + } + + if (lastCache->vertexDeclaration != NULL) + { + lastCache->vertexDeclaration->Release(); + lastCache->vertexDeclaration = NULL; + // mLastSetVDecl is set to the replacement, so we don't have to worry + // about it. + } + + memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); + device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + device->SetVertexDeclaration(lastCache->vertexDeclaration); + mLastSetVDecl = lastCache->vertexDeclaration; + lastCache->lruCount = ++mMaxLru; + + return GL_NO_ERROR; +} + +void VertexDeclarationCache::markStateDirty() +{ + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + mAppliedVBs[i].serial = 0; + } + + mLastSetVDecl = NULL; + mInstancingEnabled = true; // Forces it to be disabled when not used +} + } extern "C" { -gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext) +gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess) { - return new gl::Context(config, shareContext); + return new gl::Context(config, shareContext, notifyResets, robustAccess); } void glDestroyContext(gl::Context *context) diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h index 2906664..8dccf0f 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Context.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -18,10 +18,12 @@ #include <d3d9.h> #include <map> +#include <hash_map> #include "common/angleutils.h" +#include "common/RefCountObject.h" #include "libGLESv2/ResourceManager.h" -#include "libGLESv2/RefCountObject.h" +#include "libGLESv2/HandleAllocator.h" namespace egl { @@ -46,23 +48,29 @@ class Renderbuffer; class RenderbufferStorage; class Colorbuffer; class Depthbuffer; +class StreamingIndexBuffer; class Stencilbuffer; class DepthStencilbuffer; class VertexDataManager; class IndexDataManager; class Blit; class Fence; +class Query; enum { + D3D9_MAX_FLOAT_CONSTANTS = 256, + D3D9_MAX_BOOL_CONSTANTS = 16, + D3D9_MAX_INT_CONSTANTS = 16, + MAX_VERTEX_ATTRIBS = 16, - MAX_VERTEX_UNIFORM_VECTORS = 256 - 2, // 256 is the minimum for SM2, and in practice the maximum for DX9. Reserve space for dx_HalfPixelSize and dx_DepthRange. + MAX_VERTEX_UNIFORM_VECTORS = D3D9_MAX_FLOAT_CONSTANTS - 2, // Reserve space for dx_HalfPixelSize and dx_DepthRange. MAX_VARYING_VECTORS_SM2 = 8, MAX_VARYING_VECTORS_SM3 = 10, - MAX_COMBINED_TEXTURE_IMAGE_UNITS = 16, - MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0, MAX_TEXTURE_IMAGE_UNITS = 16, - 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_VERTEX_TEXTURE_IMAGE_UNITS_VTF = 4, // For devices supporting vertex texture fetch + MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF, + MAX_FRAGMENT_UNIFORM_VECTORS_SM2 = 32 - 3, // Reserve space for dx_Coord, dx_Depth, and dx_DepthRange. dx_PointOrLines and dx_FrontCCW use separate bool registers. MAX_FRAGMENT_UNIFORM_VECTORS_SM3 = 224 - 3, MAX_DRAW_BUFFERS = 1, @@ -70,6 +78,14 @@ enum IMPLEMENTATION_COLOR_READ_TYPE = GL_UNSIGNED_SHORT_5_6_5 }; +enum QueryType +{ + QUERY_ANY_SAMPLES_PASSED, + QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE, + + QUERY_TYPE_COUNT +}; + const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f; const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f; const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f; @@ -88,7 +104,7 @@ struct Color class VertexAttribute { public: - VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false) + VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0) { mCurrentValue[0] = 0.0f; mCurrentValue[1] = 0.0f; @@ -131,6 +147,7 @@ class VertexAttribute bool mArrayEnabled; // From glEnable/DisableVertexAttribArray float mCurrentValue[4]; // From glVertexAttrib + unsigned int mDivisor; }; typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS]; @@ -203,7 +220,7 @@ struct State bool colorMaskAlpha; bool depthMask; - int activeSampler; // Active texture unit selector - GL_TEXTURE0 + unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0 BindingPointer<Buffer> arrayBuffer; BindingPointer<Buffer> elementArrayBuffer; GLuint readFramebuffer; @@ -212,16 +229,53 @@ struct State GLuint currentProgram; VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS]; - BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS]; + BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF]; + BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT]; GLint unpackAlignment; GLint packAlignment; + bool packReverseRowOrder; +}; + +// Helper class to construct and cache vertex declarations +class VertexDeclarationCache +{ + public: + VertexDeclarationCache(); + ~VertexDeclarationCache(); + + GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], Program *program, GLsizei instances, GLsizei *repeatDraw); + + void markStateDirty(); + + private: + UINT mMaxLru; + + enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 16 }; + + struct VBData + { + unsigned int serial; + unsigned int stride; + unsigned int offset; + }; + + VBData mAppliedVBs[MAX_VERTEX_ATTRIBS]; + IDirect3DVertexDeclaration9 *mLastSetVDecl; + bool mInstancingEnabled; + + struct VertexDeclCacheEntry + { + D3DVERTEXELEMENT9 cachedElements[MAX_VERTEX_ATTRIBS + 1]; + UINT lruCount; + IDirect3DVertexDeclaration9 *vertexDeclaration; + } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES]; }; class Context { public: - Context(const egl::Config *config, const gl::Context *shareContext); + Context(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess); ~Context(); @@ -229,6 +283,9 @@ class Context void markAllStateDirty(); + virtual void markContextLost(); + bool isContextLost(); + // State manipulation void setClearColor(float red, float green, float blue, float alpha); @@ -298,7 +355,7 @@ class Context void setColorMask(bool red, bool green, bool blue, bool alpha); void setDepthMask(bool mask); - void setActiveSampler(int active); + void setActiveSampler(unsigned int active); GLuint getReadFramebufferHandle() const; GLuint getDrawFramebufferHandle() const; @@ -306,6 +363,8 @@ class Context GLuint getArrayBufferHandle() const; + GLuint getActiveQuery(GLenum target) const; + void setEnableVertexAttribArray(unsigned int attribNum, bool enabled); const VertexAttribute &getVertexAttribState(unsigned int attribNum); void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, @@ -320,6 +379,9 @@ class Context void setPackAlignment(GLint alignment); GLint getPackAlignment() const; + void setPackReverseRowOrder(bool reverseRowOrder); + bool getPackReverseRowOrder() const; + // These create and destroy methods are merely pass-throughs to // ResourceManager, which owns these object types GLuint createBuffer(); @@ -341,6 +403,10 @@ class Context // Fences are owned by the Context. GLuint createFence(); void deleteFence(GLuint fence); + + // Queries are owned by the Context; + GLuint createQuery(); + void deleteQuery(GLuint query); void bindArrayBuffer(GLuint buffer); void bindElementArrayBuffer(GLuint buffer); @@ -351,11 +417,15 @@ class Context void bindRenderbuffer(GLuint renderbuffer); void useProgram(GLuint program); + void beginQuery(GLenum target, GLuint query); + void endQuery(GLenum target); + void setFramebufferZero(Framebuffer *framebuffer); void setRenderbufferStorage(RenderbufferStorage *renderbuffer); void setVertexAttrib(GLuint index, const GLfloat *values); + void setVertexAttribDivisor(GLuint index, GLuint divisor); Buffer *getBuffer(GLuint handle); Fence *getFence(GLuint handle); @@ -364,13 +434,14 @@ class Context Texture *getTexture(GLuint handle); Framebuffer *getFramebuffer(GLuint handle); Renderbuffer *getRenderbuffer(GLuint handle); + Query *getQuery(GLuint handle, bool create, GLenum type); Buffer *getArrayBuffer(); Buffer *getElementArrayBuffer(); Program *getCurrentProgram(); Texture2D *getTexture2D(); TextureCubeMap *getTextureCubeMap(); - Texture *getSamplerTexture(unsigned int sampler, SamplerType type); + Texture *getSamplerTexture(unsigned int sampler, TextureType type); Framebuffer *getReadFramebuffer(); Framebuffer *getDrawFramebuffer(); @@ -380,23 +451,13 @@ class Context bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams); - bool applyRenderTarget(bool ignoreViewport); - void applyState(GLenum drawMode); - GLenum applyVertexBuffer(GLint first, GLsizei count); - GLenum applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - void applyShaders(); - void applyTextures(); - - void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels); + void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, 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 finish(); - void flush(); + void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances); + void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances); + void sync(bool block); // flush/finish - // 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 drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex); void recordInvalidEnum(); void recordInvalidValue(); @@ -405,9 +466,13 @@ class Context void recordInvalidFramebufferOperation(); GLenum getError(); + GLenum getResetStatus(); + virtual bool isResetNotificationEnabled(); bool supportsShaderModel3() const; int getMaximumVaryingVectors() const; + unsigned int getMaximumVertexTextureImageUnits() const; + unsigned int getMaximumCombinedTextureImageUnits() const; int getMaximumFragmentUniformVectors() const; int getMaximumRenderbufferDimension() const; int getMaximumTextureDimension() const; @@ -416,17 +481,23 @@ class Context GLsizei getMaxSupportedSamples() const; int getNearestSupportedSamples(D3DFORMAT format, int requested) const; const char *getExtensionString() const; + const char *getRendererString() 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 supportsOcclusionQueries() const; + bool supportsDXT1Textures() const; + bool supportsDXT3Textures() const; + bool supportsDXT5Textures() const; + bool supportsFloat32Textures() const; + bool supportsFloat32LinearFilter() const; + bool supportsFloat32RenderableTextures() const; + bool supportsFloat16Textures() const; + bool supportsFloat16LinearFilter() const; + bool supportsFloat16RenderableTextures() const; bool supportsLuminanceTextures() const; bool supportsLuminanceAlphaTextures() const; bool supports32bitIndices() const; + bool supportsNonPower2Texture() const; + bool supportsInstancing() const; void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, @@ -439,40 +510,59 @@ class Context private: DISALLOW_COPY_AND_ASSIGN(Context); - void lookupAttributeMapping(TranslatedAttribute *attributes); + bool applyRenderTarget(bool ignoreViewport); + void applyState(GLenum drawMode); + GLenum applyVertexBuffer(GLint first, GLsizei count, GLsizei instances, GLsizei *repeatDraw); + GLenum applyIndexBuffer(const GLvoid *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + void applyShaders(); + void applyTextures(); + void applyTextures(SamplerType type); void detachBuffer(GLuint buffer); void detachTexture(GLuint texture); void detachFramebuffer(GLuint framebuffer); void detachRenderbuffer(GLuint renderbuffer); - Texture *getIncompleteTexture(SamplerType type); + Texture *getIncompleteTexture(TextureType type); bool cullSkipsDraw(GLenum drawMode); bool isTriangleMode(GLenum drawMode); + void initExtensionString(); + void initRendererString(); + const egl::Config *const mConfig; + egl::Display *mDisplay; + IDirect3DDevice9 *mDevice; - State mState; + State mState; BindingPointer<Texture2D> mTexture2DZero; BindingPointer<TextureCubeMap> mTextureCubeMapZero; - typedef std::map<GLuint, Framebuffer*> FramebufferMap; + typedef stdext::hash_map<GLuint, Framebuffer*> FramebufferMap; FramebufferMap mFramebufferMap; + HandleAllocator mFramebufferHandleAllocator; - typedef std::map<GLuint, Fence*> FenceMap; + typedef stdext::hash_map<GLuint, Fence*> FenceMap; FenceMap mFenceMap; + HandleAllocator mFenceHandleAllocator; + + typedef stdext::hash_map<GLuint, Query*> QueryMap; + QueryMap mQueryMap; + HandleAllocator mQueryHandleAllocator; - void initExtensionString(); std::string mExtensionString; + std::string mRendererString; VertexDataManager *mVertexDataManager; IndexDataManager *mIndexDataManager; Blit *mBlit; + + StreamingIndexBuffer *mLineLoopIB; - BindingPointer<Texture> mIncompleteTextures[SAMPLER_TYPE_COUNT]; + BindingPointer<Texture> mIncompleteTextures[TEXTURE_TYPE_COUNT]; // Recorded errors bool mInvalidEnum; @@ -481,15 +571,33 @@ class Context bool mOutOfMemory; bool mInvalidFramebufferOperation; + // Current/lost context flags bool mHasBeenCurrent; - - unsigned int mAppliedProgram; + bool mContextLost; + GLenum mResetStatus; + GLenum mResetStrategy; + bool mRobustAccess; + + unsigned int mAppliedTextureSerialPS[MAX_TEXTURE_IMAGE_UNITS]; + unsigned int mAppliedTextureSerialVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF]; + unsigned int mAppliedProgramSerial; unsigned int mAppliedRenderTargetSerial; unsigned int mAppliedDepthbufferSerial; unsigned int mAppliedStencilbufferSerial; + unsigned int mAppliedIBSerial; bool mDepthStencilInitialized; + bool mViewportInitialized; + D3DVIEWPORT9 mSetViewport; + bool mRenderTargetDescInitialized; + D3DSURFACE_DESC mRenderTargetDesc; + bool mDxUniformsDirty; + Program *mCachedCurrentProgram; + Framebuffer *mBoundDrawFramebuffer; bool mSupportsShaderModel3; + bool mSupportsVertexTexture; + bool mSupportsNonPower2Texture; + bool mSupportsInstancing; int mMaxRenderbufferDimension; int mMaxTextureDimension; int mMaxCubeTextureDimension; @@ -497,16 +605,20 @@ class Context std::map<D3DFORMAT, bool *> mMultiSampleSupport; GLsizei mMaxSupportedSamples; bool mSupportsEventQueries; - bool mSupportsCompressedTextures; - bool mSupportsFloatTextures; - bool mSupportsFloatLinearFilter; - bool mSupportsFloatRenderableTextures; - bool mSupportsHalfFloatTextures; - bool mSupportsHalfFloatLinearFilter; - bool mSupportsHalfFloatRenderableTextures; + bool mSupportsOcclusionQueries; + bool mSupportsDXT1Textures; + bool mSupportsDXT3Textures; + bool mSupportsDXT5Textures; + bool mSupportsFloat32Textures; + bool mSupportsFloat32LinearFilter; + bool mSupportsFloat32RenderableTextures; + bool mSupportsFloat16Textures; + bool mSupportsFloat16LinearFilter; + bool mSupportsFloat16RenderableTextures; bool mSupportsLuminanceTextures; bool mSupportsLuminanceAlphaTextures; bool mSupports32bitIndices; + int mNumCompressedTextureFormats; // state caching flags bool mClearStateDirty; @@ -527,17 +639,20 @@ class Context D3DCAPS9 mDeviceCaps; ResourceManager *mResourceManager; + + VertexDeclarationCache mVertexDeclarationCache; }; } extern "C" { // Exported functions for use by EGL -gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext); +gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext, bool notifyResets, bool robustAccess); void glDestroyContext(gl::Context *context); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); gl::Context *glGetCurrentContext(); __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); +bool __stdcall glBindTexImage(egl::Surface *surface); } #endif // INCLUDE_CONTEXT_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp index 7fbcb6a..14d1239 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.cpp @@ -13,8 +13,9 @@ namespace gl { -Fence::Fence() -{ +Fence::Fence(egl::Display* display) +{ + mDisplay = display; mQuery = NULL; mCondition = GL_NONE; mStatus = GL_FALSE; @@ -24,8 +25,7 @@ Fence::~Fence() { if (mQuery != NULL) { - mQuery->Release(); - mQuery = NULL; + mDisplay->freeEventQuery(mQuery); } } @@ -38,15 +38,13 @@ GLboolean Fence::isFence() void Fence::setFence(GLenum condition) { - if (mQuery != NULL) + if (!mQuery) { - mQuery->Release(); - mQuery = NULL; - } - - if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_EVENT, &mQuery))) - { - return error(GL_OUT_OF_MEMORY); + mQuery = mDisplay->allocateEventQuery(); + if (!mQuery) + { + return error(GL_OUT_OF_MEMORY); + } } HRESULT result = mQuery->Issue(D3DISSUE_END); @@ -65,7 +63,7 @@ GLboolean Fence::testFence() HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); - if (result == D3DERR_DEVICELOST) + if (checkDeviceLost(result)) { return error(GL_OUT_OF_MEMORY, GL_TRUE); } @@ -110,7 +108,7 @@ void Fence::getFenceiv(GLenum pname, GLint *params) HRESULT result = mQuery->GetData(NULL, 0, 0); - if (result == D3DERR_DEVICELOST) + if (checkDeviceLost(result)) { params[0] = GL_TRUE; return error(GL_OUT_OF_MEMORY); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h index 17bad78..9626cb0 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Fence.h @@ -15,13 +15,18 @@ #include "common/angleutils.h" +namespace egl +{ +class Display; +} + namespace gl { class Fence { public: - Fence(); + explicit Fence(egl::Display* display); virtual ~Fence(); GLboolean isFence(); @@ -33,6 +38,7 @@ class Fence private: DISALLOW_COPY_AND_ASSIGN(Fence); + egl::Display* mDisplay; IDirect3DQuery9* mQuery; GLenum mCondition; GLboolean mStatus; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp index 5fe01e0..730fffc 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.cpp @@ -44,9 +44,9 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const { buffer = context->getRenderbuffer(handle); } - else if (IsTextureTarget(type)) + else if (IsInternalTextureTarget(type)) { - buffer = context->getTexture(handle)->getColorbuffer(type); + buffer = context->getTexture(handle)->getRenderbuffer(type); } else { @@ -58,37 +58,37 @@ Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer) { - mColorbufferType = type; + mColorbufferType = (colorbuffer != 0) ? type : GL_NONE; mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer)); } void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer) { - mDepthbufferType = type; + mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE; mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer)); } void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer) { - mStencilbufferType = type; + mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE; mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer)); } void Framebuffer::detachTexture(GLuint texture) { - if (mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType)) + if (mColorbufferPointer.id() == texture && IsInternalTextureTarget(mColorbufferType)) { mColorbufferType = GL_NONE; mColorbufferPointer.set(NULL); } - if (mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType)) + if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType)) { mDepthbufferType = GL_NONE; mDepthbufferPointer.set(NULL); } - if (mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType)) + if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType)) { mStencilbufferType = GL_NONE; mStencilbufferPointer.set(NULL); @@ -181,46 +181,19 @@ unsigned int Framebuffer::getStencilbufferSerial() return 0; } -Colorbuffer *Framebuffer::getColorbuffer() +Renderbuffer *Framebuffer::getColorbuffer() { - Renderbuffer *rb = mColorbufferPointer.get(); - - if (rb != NULL && rb->isColorbuffer()) - { - return static_cast<Colorbuffer*>(rb->getStorage()); - } - else - { - return NULL; - } + return mColorbufferPointer.get(); } -DepthStencilbuffer *Framebuffer::getDepthbuffer() +Renderbuffer *Framebuffer::getDepthbuffer() { - Renderbuffer *rb = mDepthbufferPointer.get(); - - if (rb != NULL && rb->isDepthbuffer()) - { - return static_cast<DepthStencilbuffer*>(rb->getStorage()); - } - else - { - return NULL; - } + return mDepthbufferPointer.get(); } -DepthStencilbuffer *Framebuffer::getStencilbuffer() +Renderbuffer *Framebuffer::getStencilbuffer() { - Renderbuffer *rb = mStencilbufferPointer.get(); - - if (rb != NULL && rb->isStencilbuffer()) - { - return static_cast<DepthStencilbuffer*>(rb->getStorage()); - } - else - { - return NULL; - } + return mStencilbufferPointer.get(); } GLenum Framebuffer::getColorbufferType() @@ -257,7 +230,7 @@ bool Framebuffer::hasStencil() { if (mStencilbufferType != GL_NONE) { - DepthStencilbuffer *stencilbufferObject = getStencilbuffer(); + Renderbuffer *stencilbufferObject = getStencilbuffer(); if (stencilbufferObject) { @@ -268,23 +241,6 @@ bool Framebuffer::hasStencil() return false; } -bool Framebuffer::isMultisample() -{ - // If the framebuffer is not complete, attachment samples may be mismatched, and it - // cannot be used as a multisample framebuffer. If it is complete, it is required to - // have a color attachment, and all its attachments must have the same number of samples, - // so the number of samples for the colorbuffer will indicate whether the framebuffer is - // multisampled. - if (completeness() == GL_FRAMEBUFFER_COMPLETE && getColorbuffer()->getSamples() > 0) - { - return true; - } - else - { - return false; - } -} - GLenum Framebuffer::completeness() { int width = 0; @@ -293,7 +249,7 @@ GLenum Framebuffer::completeness() if (mColorbufferType != GL_NONE) { - Colorbuffer *colorbuffer = getColorbuffer(); + Renderbuffer *colorbuffer = getColorbuffer(); if (!colorbuffer) { @@ -307,25 +263,25 @@ GLenum Framebuffer::completeness() if (mColorbufferType == GL_RENDERBUFFER) { - if (!gl::IsColorRenderable(colorbuffer->getFormat())) + if (!gl::IsColorRenderable(colorbuffer->getInternalFormat())) { return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT; } } - else if (IsTextureTarget(mColorbufferType)) + else if (IsInternalTextureTarget(mColorbufferType)) { - if (IsCompressed(colorbuffer->getFormat())) + if (IsCompressed(colorbuffer->getInternalFormat())) { return GL_FRAMEBUFFER_UNSUPPORTED; } - if (colorbuffer->isFloatingPoint() && (!getContext()->supportsFloatRenderableTextures() || - !getContext()->supportsHalfFloatRenderableTextures())) + if ((dx2es::IsFloat32Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat32RenderableTextures()) || + (dx2es::IsFloat16Format(colorbuffer->getD3DFormat()) && !getContext()->supportsFloat16RenderableTextures())) { return GL_FRAMEBUFFER_UNSUPPORTED; } - if (colorbuffer->getFormat() == GL_LUMINANCE || colorbuffer->getFormat() == GL_LUMINANCE_ALPHA) + if (colorbuffer->getInternalFormat() == GL_LUMINANCE || colorbuffer->getInternalFormat() == GL_LUMINANCE_ALPHA) { return GL_FRAMEBUFFER_UNSUPPORTED; } @@ -341,8 +297,8 @@ GLenum Framebuffer::completeness() return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; } - DepthStencilbuffer *depthbuffer = NULL; - DepthStencilbuffer *stencilbuffer = NULL; + Renderbuffer *depthbuffer = NULL; + Renderbuffer *stencilbuffer = NULL; if (mDepthbufferType != GL_NONE) { @@ -424,8 +380,8 @@ GLenum Framebuffer::completeness() if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER) { - if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES || - stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES || + if (depthbuffer->getInternalFormat() != GL_DEPTH24_STENCIL8_OES || + stencilbuffer->getInternalFormat() != GL_DEPTH24_STENCIL8_OES || depthbuffer->getSerial() != stencilbuffer->getSerial()) { return GL_FRAMEBUFFER_UNSUPPORTED; @@ -435,17 +391,17 @@ GLenum Framebuffer::completeness() return GL_FRAMEBUFFER_COMPLETE; } -DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil) +DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil) { - mColorbufferType = GL_RENDERBUFFER; - mDepthbufferType = (depthStencil->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE; - mStencilbufferType = (depthStencil->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE; - - mColorbufferPointer.set(new Renderbuffer(0, color)); + mColorbufferPointer.set(new Renderbuffer(0, colorbuffer)); Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil); mDepthbufferPointer.set(depthStencilRenderbuffer); mStencilbufferPointer.set(depthStencilRenderbuffer); + + mColorbufferType = GL_RENDERBUFFER; + mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE; + mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE; } int Framebuffer::getSamples() diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h index 0995145..b73f9a0 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Framebuffer.h @@ -15,7 +15,7 @@ #include <d3d9.h> #include "common/angleutils.h" -#include "libGLESv2/RefCountObject.h" +#include "common/RefCountObject.h" namespace gl { @@ -46,9 +46,9 @@ class Framebuffer unsigned int getDepthbufferSerial(); unsigned int getStencilbufferSerial(); - Colorbuffer *getColorbuffer(); - DepthStencilbuffer *getDepthbuffer(); - DepthStencilbuffer *getStencilbuffer(); + Renderbuffer *getColorbuffer(); + Renderbuffer *getDepthbuffer(); + Renderbuffer *getStencilbuffer(); GLenum getColorbufferType(); GLenum getDepthbufferType(); @@ -59,7 +59,6 @@ class Framebuffer GLuint getStencilbufferHandle(); bool hasStencil(); - bool isMultisample(); int getSamples(); virtual GLenum completeness(); @@ -83,7 +82,7 @@ class Framebuffer class DefaultFramebuffer : public Framebuffer { public: - DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil); + DefaultFramebuffer(Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil); virtual GLenum completeness(); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.cpp new file mode 100644 index 0000000..c498f8a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.cpp @@ -0,0 +1,63 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleAllocator.cpp: Implements the gl::HandleAllocator class, which is used +// to allocate GL handles. + +#include "libGLESv2/HandleAllocator.h" + +#include "libGLESv2/main.h" + +namespace gl +{ + +HandleAllocator::HandleAllocator() : mBaseValue(1), mNextValue(1) +{ +} + +HandleAllocator::~HandleAllocator() +{ +} + +void HandleAllocator::setBaseHandle(GLuint value) +{ + ASSERT(mBaseValue == mNextValue); + mBaseValue = value; + mNextValue = value; +} + +GLuint HandleAllocator::allocate() +{ + if (mFreeValues.size()) + { + GLuint handle = mFreeValues.back(); + mFreeValues.pop_back(); + return handle; + } + return mNextValue++; +} + +void HandleAllocator::release(GLuint handle) +{ + if (handle == mNextValue - 1) + { + // Don't drop below base value + if(mNextValue > mBaseValue) + { + mNextValue--; + } + } + else + { + // Only free handles that we own - don't drop below the base value + if (handle >= mBaseValue) + { + mFreeValues.push_back(handle); + } + } +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.h b/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.h new file mode 100644 index 0000000..a92e168 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/HandleAllocator.h @@ -0,0 +1,45 @@ +// +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// HandleAllocator.h: Defines the gl::HandleAllocator class, which is used to +// allocate GL handles. + +#ifndef LIBGLESV2_HANDLEALLOCATOR_H_ +#define LIBGLESV2_HANDLEALLOCATOR_H_ + +#define GL_APICALL +#include <GLES2/gl2.h> + +#include <vector> + +#include "common/angleutils.h" + +namespace gl +{ + +class HandleAllocator +{ + public: + HandleAllocator(); + virtual ~HandleAllocator(); + + void setBaseHandle(GLuint value); + + GLuint allocate(); + void release(GLuint handle); + + private: + DISALLOW_COPY_AND_ASSIGN(HandleAllocator); + + GLuint mBaseValue; + GLuint mNextValue; + typedef std::vector<GLuint> HandleList; + HandleList mFreeValues; +}; + +} + +#endif // LIBGLESV2_HANDLEALLOCATOR_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.cpp new file mode 100644 index 0000000..3dc0aef --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.cpp @@ -0,0 +1,473 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexDataManager.cpp: Defines the IndexDataManager, a class that +// runs the Buffer translation process for index buffers. + +#include "libGLESv2/IndexDataManager.h" + +#include "common/debug.h" + +#include "libGLESv2/Buffer.h" +#include "libGLESv2/mathutil.h" +#include "libGLESv2/main.h" + +namespace gl +{ +unsigned int IndexBuffer::mCurrentSerial = 1; + +IndexDataManager::IndexDataManager(Context *context, IDirect3DDevice9 *device) : mDevice(device) +{ + mStreamingBufferShort = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX16); + + if (context->supports32bitIndices()) + { + mStreamingBufferInt = new StreamingIndexBuffer(mDevice, INITIAL_INDEX_BUFFER_SIZE, D3DFMT_INDEX32); + + if (!mStreamingBufferInt) + { + // Don't leave it in a half-initialized state + delete mStreamingBufferShort; + mStreamingBufferShort = NULL; + } + } + else + { + mStreamingBufferInt = NULL; + } + + if (!mStreamingBufferShort) + { + ERR("Failed to allocate the streaming index buffer(s)."); + } + + mCountingBuffer = NULL; +} + +IndexDataManager::~IndexDataManager() +{ + delete mStreamingBufferShort; + delete mStreamingBufferInt; + delete mCountingBuffer; +} + +void convertIndices(GLenum type, const void *input, GLsizei count, void *output) +{ + if (type == GL_UNSIGNED_BYTE) + { + const GLubyte *in = static_cast<const GLubyte*>(input); + GLushort *out = static_cast<GLushort*>(output); + + for (GLsizei i = 0; i < count; i++) + { + out[i] = in[i]; + } + } + else if (type == GL_UNSIGNED_INT) + { + memcpy(output, input, count * sizeof(GLuint)); + } + else if (type == GL_UNSIGNED_SHORT) + { + memcpy(output, input, count * sizeof(GLushort)); + } + else UNREACHABLE(); +} + +template <class IndexType> +void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex) +{ + *minIndex = indices[0]; + *maxIndex = indices[0]; + + for (GLsizei i = 0; i < count; i++) + { + if (*minIndex > indices[i]) *minIndex = indices[i]; + if (*maxIndex < indices[i]) *maxIndex = indices[i]; + } +} + +void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex) +{ + if (type == GL_UNSIGNED_BYTE) + { + computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex); + } + else if (type == GL_UNSIGNED_INT) + { + computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex); + } + else if (type == GL_UNSIGNED_SHORT) + { + computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex); + } + else UNREACHABLE(); +} + +GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated) +{ + if (!mStreamingBufferShort) + { + return GL_OUT_OF_MEMORY; + } + + D3DFORMAT format = (type == GL_UNSIGNED_INT) ? D3DFMT_INDEX32 : D3DFMT_INDEX16; + intptr_t offset = reinterpret_cast<intptr_t>(indices); + bool alignedOffset = false; + + if (buffer != NULL) + { + switch (type) + { + case GL_UNSIGNED_BYTE: alignedOffset = (offset % sizeof(GLubyte) == 0); break; + case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break; + case GL_UNSIGNED_INT: alignedOffset = (offset % sizeof(GLuint) == 0); break; + default: UNREACHABLE(); alignedOffset = false; + } + + if (typeSize(type) * count + offset > static_cast<std::size_t>(buffer->size())) + { + return GL_INVALID_OPERATION; + } + + indices = static_cast<const GLubyte*>(buffer->data()) + offset; + } + + StreamingIndexBuffer *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort; + + StaticIndexBuffer *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL; + IndexBuffer *indexBuffer = streamingBuffer; + UINT streamOffset = 0; + + if (staticBuffer && staticBuffer->lookupType(type) && alignedOffset) + { + indexBuffer = staticBuffer; + streamOffset = staticBuffer->lookupRange(offset, count, &translated->minIndex, &translated->maxIndex); + + if (streamOffset == -1) + { + streamOffset = (offset / typeSize(type)) * indexSize(format); + computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); + staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset); + } + } + else + { + int convertCount = count; + + if (staticBuffer) + { + if (staticBuffer->size() == 0 && alignedOffset) + { + indexBuffer = staticBuffer; + convertCount = buffer->size() / typeSize(type); + } + else + { + buffer->invalidateStaticData(); + staticBuffer = NULL; + } + } + + void *output = NULL; + + if (indexBuffer) + { + indexBuffer->reserveSpace(convertCount * indexSize(format), type); + output = indexBuffer->map(indexSize(format) * convertCount, &streamOffset); + } + + if (output == NULL) + { + ERR("Failed to map index buffer."); + return GL_OUT_OF_MEMORY; + } + + convertIndices(type, staticBuffer ? buffer->data() : indices, convertCount, output); + indexBuffer->unmap(); + + computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex); + + if (staticBuffer) + { + streamOffset = (offset / typeSize(type)) * indexSize(format); + staticBuffer->addRange(offset, count, translated->minIndex, translated->maxIndex, streamOffset); + } + } + + translated->indexBuffer = indexBuffer->getBuffer(); + translated->serial = indexBuffer->getSerial(); + translated->startIndex = streamOffset / indexSize(format); + + if (buffer) + { + buffer->promoteStaticUsage(count * typeSize(type)); + } + + return GL_NO_ERROR; +} + +std::size_t IndexDataManager::indexSize(D3DFORMAT format) const +{ + return (format == D3DFMT_INDEX32) ? sizeof(unsigned int) : sizeof(unsigned short); +} + +std::size_t IndexDataManager::typeSize(GLenum type) const +{ + switch (type) + { + case GL_UNSIGNED_INT: return sizeof(GLuint); + case GL_UNSIGNED_SHORT: return sizeof(GLushort); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + default: UNREACHABLE(); return sizeof(GLushort); + } +} + +StaticIndexBuffer *IndexDataManager::getCountingIndices(GLsizei count) +{ + if (count <= 65536) // 16-bit indices + { + const unsigned int spaceNeeded = count * sizeof(unsigned short); + + if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded) + { + delete mCountingBuffer; + mCountingBuffer = new StaticIndexBuffer(mDevice); + mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_SHORT); + + UINT offset; + unsigned short *data = static_cast<unsigned short*>(mCountingBuffer->map(spaceNeeded, &offset)); + + if (data) + { + for(int i = 0; i < count; i++) + { + data[i] = i; + } + + mCountingBuffer->unmap(); + } + } + } + else if (mStreamingBufferInt) // 32-bit indices supported + { + const unsigned int spaceNeeded = count * sizeof(unsigned int); + + if (!mCountingBuffer || mCountingBuffer->size() < spaceNeeded) + { + delete mCountingBuffer; + mCountingBuffer = new StaticIndexBuffer(mDevice); + mCountingBuffer->reserveSpace(spaceNeeded, GL_UNSIGNED_INT); + + UINT offset; + unsigned int *data = static_cast<unsigned int*>(mCountingBuffer->map(spaceNeeded, &offset)); + + if (data) + { + for(int i = 0; i < count; i++) + { + data[i] = i; + } + + mCountingBuffer->unmap(); + } + } + } + else return NULL; + + return mCountingBuffer; +} + +IndexBuffer::IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format) : mDevice(device), mBufferSize(size), mIndexBuffer(NULL) +{ + if (size > 0) + { + D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); + HRESULT result = device->CreateIndexBuffer(size, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, format, pool, &mIndexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating an index buffer of size %lu.", size); + } + } +} + +IndexBuffer::~IndexBuffer() +{ + if (mIndexBuffer) + { + mIndexBuffer->Release(); + } +} + +IDirect3DIndexBuffer9 *IndexBuffer::getBuffer() const +{ + return mIndexBuffer; +} + +unsigned int IndexBuffer::getSerial() const +{ + return mSerial; +} + +unsigned int IndexBuffer::issueSerial() +{ + return mCurrentSerial++; +} + +void IndexBuffer::unmap() +{ + if (mIndexBuffer) + { + mIndexBuffer->Unlock(); + } +} + +StreamingIndexBuffer::StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format) : IndexBuffer(device, initialSize, format) +{ + mWritePosition = 0; +} + +StreamingIndexBuffer::~StreamingIndexBuffer() +{ +} + +void *StreamingIndexBuffer::map(UINT requiredSpace, UINT *offset) +{ + void *mapPtr = NULL; + + if (mIndexBuffer) + { + HRESULT result = mIndexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE); + + if (FAILED(result)) + { + ERR(" Lock failed with error 0x%08x", result); + return NULL; + } + + *offset = mWritePosition; + mWritePosition += requiredSpace; + } + + return mapPtr; +} + +void StreamingIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type) +{ + if (requiredSpace > mBufferSize) + { + if (mIndexBuffer) + { + mIndexBuffer->Release(); + mIndexBuffer = NULL; + } + + mBufferSize = std::max(requiredSpace, 2 * mBufferSize); + + D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); + HRESULT result = mDevice->CreateIndexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize); + } + + mWritePosition = 0; + } + else if (mWritePosition + requiredSpace > mBufferSize) // Recycle + { + void *dummy; + mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + mIndexBuffer->Unlock(); + + mWritePosition = 0; + } +} + +StaticIndexBuffer::StaticIndexBuffer(IDirect3DDevice9 *device) : IndexBuffer(device, 0, D3DFMT_UNKNOWN) +{ + mCacheType = GL_NONE; +} + +StaticIndexBuffer::~StaticIndexBuffer() +{ +} + +void *StaticIndexBuffer::map(UINT requiredSpace, UINT *offset) +{ + void *mapPtr = NULL; + + if (mIndexBuffer) + { + HRESULT result = mIndexBuffer->Lock(0, requiredSpace, &mapPtr, 0); + + if (FAILED(result)) + { + ERR(" Lock failed with error 0x%08x", result); + return NULL; + } + + *offset = 0; + } + + return mapPtr; +} + +void StaticIndexBuffer::reserveSpace(UINT requiredSpace, GLenum type) +{ + if (!mIndexBuffer && mBufferSize == 0) + { + D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY); + HRESULT result = mDevice->CreateIndexBuffer(requiredSpace, D3DUSAGE_WRITEONLY, type == GL_UNSIGNED_INT ? D3DFMT_INDEX32 : D3DFMT_INDEX16, pool, &mIndexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize); + } + + mBufferSize = requiredSpace; + mCacheType = type; + } + else if (mIndexBuffer && mBufferSize >= requiredSpace && mCacheType == type) + { + // Already allocated + } + else UNREACHABLE(); // Static index buffers can't be resized +} + +bool StaticIndexBuffer::lookupType(GLenum type) +{ + return mCacheType == type; +} + +UINT StaticIndexBuffer::lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex) +{ + IndexRange range = {offset, count}; + + std::map<IndexRange, IndexResult>::iterator res = mCache.find(range); + + if (res == mCache.end()) + { + return -1; + } + + *minIndex = res->second.minIndex; + *maxIndex = res->second.maxIndex; + return res->second.streamOffset; +} + +void StaticIndexBuffer::addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset) +{ + IndexRange indexRange = {offset, count}; + IndexResult indexResult = {minIndex, maxIndex, streamOffset}; + mCache[indexRange] = indexResult; +} + +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.h new file mode 100644 index 0000000..c1d4168 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/IndexDataManager.h @@ -0,0 +1,149 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// IndexDataManager.h: Defines the IndexDataManager, a class that +// runs the Buffer translation process for index buffers. + +#ifndef LIBGLESV2_INDEXDATAMANAGER_H_ +#define LIBGLESV2_INDEXDATAMANAGER_H_ + +#include <vector> +#include <cstddef> + +#define GL_APICALL +#include <GLES2/gl2.h> + +#include "libGLESv2/Context.h" + +namespace +{ + enum { INITIAL_INDEX_BUFFER_SIZE = 4096 * sizeof(GLuint) }; +} + +namespace gl +{ + +struct TranslatedIndexData +{ + UINT minIndex; + UINT maxIndex; + UINT startIndex; + + IDirect3DIndexBuffer9 *indexBuffer; + unsigned int serial; +}; + +class IndexBuffer +{ + public: + IndexBuffer(IDirect3DDevice9 *device, UINT size, D3DFORMAT format); + virtual ~IndexBuffer(); + + UINT size() const { return mBufferSize; } + virtual void *map(UINT requiredSpace, UINT *offset) = 0; + void unmap(); + virtual void reserveSpace(UINT requiredSpace, GLenum type) = 0; + + IDirect3DIndexBuffer9 *getBuffer() const; + unsigned int getSerial() const; + + protected: + IDirect3DDevice9 *const mDevice; + + IDirect3DIndexBuffer9 *mIndexBuffer; + UINT mBufferSize; + + unsigned int mSerial; + static unsigned int issueSerial(); + static unsigned int mCurrentSerial; + + private: + DISALLOW_COPY_AND_ASSIGN(IndexBuffer); +}; + +class StreamingIndexBuffer : public IndexBuffer +{ + public: + StreamingIndexBuffer(IDirect3DDevice9 *device, UINT initialSize, D3DFORMAT format); + ~StreamingIndexBuffer(); + + virtual void *map(UINT requiredSpace, UINT *offset); + virtual void reserveSpace(UINT requiredSpace, GLenum type); + + private: + UINT mWritePosition; +}; + +class StaticIndexBuffer : public IndexBuffer +{ + public: + explicit StaticIndexBuffer(IDirect3DDevice9 *device); + ~StaticIndexBuffer(); + + virtual void *map(UINT requiredSpace, UINT *offset); + virtual void reserveSpace(UINT requiredSpace, GLenum type); + + bool lookupType(GLenum type); + UINT lookupRange(intptr_t offset, GLsizei count, UINT *minIndex, UINT *maxIndex); // Returns the offset into the index buffer, or -1 if not found + void addRange(intptr_t offset, GLsizei count, UINT minIndex, UINT maxIndex, UINT streamOffset); + + private: + GLenum mCacheType; + + struct IndexRange + { + intptr_t offset; + GLsizei count; + + bool operator<(const IndexRange& rhs) const + { + if (offset != rhs.offset) + { + return offset < rhs.offset; + } + if (count != rhs.count) + { + return count < rhs.count; + } + return false; + } + }; + + struct IndexResult + { + UINT minIndex; + UINT maxIndex; + UINT streamOffset; + }; + + std::map<IndexRange, IndexResult> mCache; +}; + +class IndexDataManager +{ + public: + IndexDataManager(Context *context, IDirect3DDevice9 *evice); + virtual ~IndexDataManager(); + + GLenum prepareIndexData(GLenum type, GLsizei count, Buffer *arrayElementBuffer, const GLvoid *indices, TranslatedIndexData *translated); + StaticIndexBuffer *getCountingIndices(GLsizei count); + + private: + DISALLOW_COPY_AND_ASSIGN(IndexDataManager); + + std::size_t typeSize(GLenum type) const; + std::size_t indexSize(D3DFORMAT format) const; + + IDirect3DDevice9 *const mDevice; + + StreamingIndexBuffer *mStreamingBufferShort; + StreamingIndexBuffer *mStreamingBufferInt; + StaticIndexBuffer *mCountingBuffer; +}; + +} + +#endif // LIBGLESV2_INDEXDATAMANAGER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp index 780c3e3..a5e38bf 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -15,9 +15,16 @@ #include "libGLESv2/Shader.h" #include "libGLESv2/utilities.h" +#include <string> + +#if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) +#define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 +#endif + namespace gl { unsigned int Program::mCurrentSerial = 1; +const char *fakepath = "C:\\fakepath"; std::string str(int i) { @@ -26,13 +33,13 @@ std::string str(int i) return buffer; } -Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize) +Uniform::Uniform(GLenum type, const std::string &_name, unsigned int arraySize) + : type(type), _name(_name), name(Program::undecorateUniform(_name)), arraySize(arraySize) { - int bytes = UniformTypeSize(type) * arraySize; + int bytes = UniformInternalSize(type) * arraySize; data = new unsigned char[bytes]; memset(data, 0, bytes); dirty = true; - handlesSet = false; } Uniform::~Uniform() @@ -40,13 +47,19 @@ Uniform::~Uniform() delete[] data; } -UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) - : name(name), element(element), index(index) +bool Uniform::isArray() +{ + return _name.compare(0, 3, "ar_") == 0; +} + +UniformLocation::UniformLocation(const std::string &_name, unsigned int element, unsigned int index) + : name(Program::undecorateUniform(_name)), element(element), index(index) { } Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle), mSerial(issueSerial()) { + mDevice = getDevice(); mFragmentShader = NULL; mVertexShader = NULL; @@ -131,8 +144,6 @@ bool Program::detachShader(Shader *shader) } else UNREACHABLE(); - unlink(); - return true; } @@ -182,28 +193,54 @@ GLuint Program::getAttributeLocation(const char *name) int Program::getSemanticIndex(int attributeIndex) { - if (attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS) + ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS); + + return mSemanticIndex[attributeIndex]; +} + +// Returns one more than the highest sampler index used. +GLint Program::getUsedSamplerRange(SamplerType type) +{ + switch (type) { - return mSemanticIndex[attributeIndex]; + case SAMPLER_PIXEL: + return mUsedPixelSamplerRange; + case SAMPLER_VERTEX: + return mUsedVertexSamplerRange; + default: + UNREACHABLE(); + return 0; } - - return -1; } -// Returns the index of the texture unit corresponding to a Direct3D 9 sampler -// index referenced in the compiled HLSL shader -GLint Program::getSamplerMapping(unsigned int samplerIndex) +// Returns the index of the texture image unit (0-19) corresponding to a Direct3D 9 sampler +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +GLint Program::getSamplerMapping(SamplerType type, unsigned int samplerIndex) { - assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])); - GLint logicalTextureUnit = -1; - if (mSamplers[samplerIndex].active) + switch (type) { - logicalTextureUnit = mSamplers[samplerIndex].logicalTextureUnit; + case SAMPLER_PIXEL: + ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); + + if (mSamplersPS[samplerIndex].active) + { + logicalTextureUnit = mSamplersPS[samplerIndex].logicalTextureUnit; + } + break; + case SAMPLER_VERTEX: + ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); + + if (mSamplersVS[samplerIndex].active) + { + logicalTextureUnit = mSamplersVS[samplerIndex].logicalTextureUnit; + } + break; + default: UNREACHABLE(); } - if (logicalTextureUnit >= 0 && logicalTextureUnit < MAX_TEXTURE_IMAGE_UNITS) + if (logicalTextureUnit >= 0 && logicalTextureUnit < (GLint)getContext()->getMaximumCombinedTextureImageUnits()) { return logicalTextureUnit; } @@ -211,52 +248,43 @@ GLint Program::getSamplerMapping(unsigned int samplerIndex) return -1; } -SamplerType Program::getSamplerType(unsigned int samplerIndex) +// Returns the texture type for a given Direct3D 9 sampler type and +// index (0-15 for the pixel shader and 0-3 for the vertex shader). +TextureType Program::getSamplerTextureType(SamplerType type, unsigned int samplerIndex) { - assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])); - assert(mSamplers[samplerIndex].active); - - return mSamplers[samplerIndex].type; -} - -bool Program::isSamplerDirty(unsigned int samplerIndex) const -{ - if (samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])) + switch (type) { - return mSamplers[samplerIndex].dirty; + case SAMPLER_PIXEL: + ASSERT(samplerIndex < sizeof(mSamplersPS)/sizeof(mSamplersPS[0])); + ASSERT(mSamplersPS[samplerIndex].active); + return mSamplersPS[samplerIndex].textureType; + case SAMPLER_VERTEX: + ASSERT(samplerIndex < sizeof(mSamplersVS)/sizeof(mSamplersVS[0])); + ASSERT(mSamplersVS[samplerIndex].active); + return mSamplersVS[samplerIndex].textureType; + default: UNREACHABLE(); } - else UNREACHABLE(); - - return false; -} -void Program::setSamplerDirty(unsigned int samplerIndex, bool dirty) -{ - if (samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])) - { - mSamplers[samplerIndex].dirty = dirty; - } - else UNREACHABLE(); + return TEXTURE_2D; } -GLint Program::getUniformLocation(const char *name, bool decorated) +GLint Program::getUniformLocation(std::string name) { - std::string _name = decorated ? name : decorate(name); - int subscript = 0; + unsigned int subscript = 0; // 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) + size_t open = name.find_last_of('['); + size_t close = name.find_last_of(']'); + if (open != std::string::npos && close == name.length() - 1) { - subscript = atoi(_name.substr(open + 1).c_str()); - _name.erase(open); + 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 == _name && + if (mUniformIndex[location].name == name && mUniformIndex[location].element == subscript) { return location; @@ -285,8 +313,17 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat), - v, sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = 0; + target[2] = 0; + target[3] = 0; + target += 4; + v += 1; + } } else if (targetUniform->type == GL_BOOL) { @@ -296,7 +333,7 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; for (int i = 0; i < count; ++i) { @@ -309,11 +346,6 @@ bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean), - boolParams, sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -342,8 +374,17 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 2, - v, 2 * sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = v[1]; + target[2] = 0; + target[3] = 0; + target += 4; + v += 2; + } } else if (targetUniform->type == GL_BOOL_VEC2) { @@ -354,7 +395,7 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 2]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; for (int i = 0; i < count * 2; ++i) { @@ -367,11 +408,6 @@ bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 2, - boolParams, 2 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -400,8 +436,17 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 3, - v, 3 * sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 4; + + for (int i = 0; i < count; i++) + { + target[0] = v[0]; + target[1] = v[1]; + target[2] = v[2]; + target[3] = 0; + target += 4; + v += 3; + } } else if (targetUniform->type == GL_BOOL_VEC3) { @@ -411,7 +456,7 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 3]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; for (int i = 0; i < count * 3; ++i) { @@ -424,11 +469,6 @@ bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 3, - boolParams, 3 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -468,7 +508,7 @@ bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 4]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; for (int i = 0; i < count * 4; ++i) { @@ -481,11 +521,6 @@ bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 4, - boolParams, 4 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -495,6 +530,37 @@ bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v) return true; } +template<typename T, int targetWidth, int targetHeight, int srcWidth, int srcHeight> +void transposeMatrix(T *target, const GLfloat *value) +{ + int copyWidth = std::min(targetWidth, srcWidth); + int copyHeight = std::min(targetHeight, srcHeight); + + for (int x = 0; x < copyWidth; x++) + { + for (int y = 0; y < copyHeight; y++) + { + target[x * targetWidth + y] = (T)value[y * srcWidth + x]; + } + } + // clear unfilled right side + for (int y = 0; y < copyHeight; y++) + { + for (int x = srcWidth; x < targetWidth; x++) + { + target[y * targetWidth + x] = (T)0; + } + } + // clear unfilled bottom. + for (int y = srcHeight; y < targetHeight; y++) + { + for (int x = 0; x < targetWidth; x++) + { + target[y * targetWidth + x] = (T)0; + } + } +} + bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) { if (location < 0 || location >= (int)mUniformIndex.size()) @@ -517,8 +583,13 @@ bool Program::setUniformMatrix2fv(GLint location, GLsizei count, const GLfloat * count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 4, - value, 4 * sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8; + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,2,2,2>(target, value); + target += 8; + value += 4; + } return true; } @@ -545,12 +616,18 @@ bool Program::setUniformMatrix3fv(GLint location, GLsizei count, const GLfloat * count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 9, - value, 9 * sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12; + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,3,3,3>(target, value); + target += 12; + value += 9; + } return true; } + bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) { if (location < 0 || location >= (int)mUniformIndex.size()) @@ -573,8 +650,13 @@ bool Program::setUniformMatrix4fv(GLint location, GLsizei count, const GLfloat * count = std::min(arraySize - (int)mUniformIndex[location].element, count); - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16, - value, 16 * sizeof(GLfloat) * count); + GLfloat *target = (GLfloat*)(targetUniform->data + mUniformIndex[location].element * sizeof(GLfloat) * 16); + for (int i = 0; i < count; i++) + { + transposeMatrix<GLfloat,4,4,4,4>(target, value); + target += 16; + value += 16; + } return true; } @@ -611,7 +693,7 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element; for (int i = 0; i < count; ++i) { @@ -624,11 +706,6 @@ bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean), - boolParams, sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -668,7 +745,7 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 2]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 2; for (int i = 0; i < count * 2; ++i) { @@ -681,11 +758,6 @@ bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 2, - boolParams, 2 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -725,7 +797,7 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 3]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 3; for (int i = 0; i < count * 3; ++i) { @@ -738,11 +810,6 @@ bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 3, - boolParams, 3 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -782,7 +849,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) return false; // attempting to write an array to a non-array uniform is an INVALID_OPERATION count = std::min(arraySize - (int)mUniformIndex[location].element, count); - GLboolean *boolParams = new GLboolean[count * 4]; + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * 4; for (int i = 0; i < count * 4; ++i) { @@ -795,11 +862,6 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) boolParams[i] = GL_TRUE; } } - - memcpy(targetUniform->data + mUniformIndex[location].element * sizeof(GLboolean) * 4, - boolParams, 4 * sizeof(GLboolean) * count); - - delete [] boolParams; } else { @@ -809,7 +871,7 @@ bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v) return true; } -bool Program::getUniformfv(GLint location, GLfloat *params) +bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params) { if (location < 0 || location >= (int)mUniformIndex.size()) { @@ -818,41 +880,67 @@ bool Program::getUniformfv(GLint location, GLfloat *params) Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - unsigned int count = UniformComponentCount(targetUniform->type); - - switch (UniformComponentType(targetUniform->type)) + // sized queries -- ensure the provided buffer is large enough + if (bufSize) { - case GL_BOOL: + int requiredBytes = UniformExternalSize(targetUniform->type); + if (*bufSize < requiredBytes) { - GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * count; - - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; - } + return false; } + } + + switch (targetUniform->type) + { + case GL_FLOAT_MAT2: + transposeMatrix<GLfloat,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); + break; + case GL_FLOAT_MAT3: + transposeMatrix<GLfloat,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); break; - case GL_FLOAT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * count * sizeof(GLfloat), - count * sizeof(GLfloat)); + case GL_FLOAT_MAT4: + transposeMatrix<GLfloat,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); break; - case GL_INT: + default: { - GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * count; + unsigned int count = UniformExternalComponentCount(targetUniform->type); + unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); - for (unsigned int i = 0; i < count; ++i) + switch (UniformComponentType(targetUniform->type)) { - params[i] = (float)intParams[i]; + case GL_BOOL: + { + GLboolean *boolParams = (GLboolean*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f; + } + } + break; + case GL_FLOAT: + memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLfloat), + count * sizeof(GLfloat)); + break; + case GL_INT: + { + GLint *intParams = (GLint*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (float)intParams[i]; + } + } + break; + default: UNREACHABLE(); } } - break; - default: UNREACHABLE(); } return true; } -bool Program::getUniformiv(GLint location, GLint *params) +bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params) { if (location < 0 || location >= (int)mUniformIndex.size()) { @@ -861,35 +949,67 @@ bool Program::getUniformiv(GLint location, GLint *params) Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - unsigned int count = UniformComponentCount(targetUniform->type); - - switch (UniformComponentType(targetUniform->type)) + // sized queries -- ensure the provided buffer is large enough + if (bufSize) { - case GL_BOOL: + int requiredBytes = UniformExternalSize(targetUniform->type); + if (*bufSize < requiredBytes) { - GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * count; + return false; + } + } - for (unsigned int i = 0; i < count; ++i) - { - params[i] = (GLint)boolParams[i]; - } + switch (targetUniform->type) + { + case GL_FLOAT_MAT2: + { + transposeMatrix<GLint,2,2,4,2>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 8); + } + break; + case GL_FLOAT_MAT3: + { + transposeMatrix<GLint,3,3,4,3>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 12); } break; - case GL_FLOAT: + case GL_FLOAT_MAT4: + { + transposeMatrix<GLint,4,4,4,4>(params, (GLfloat*)targetUniform->data + mUniformIndex[location].element * 16); + } + break; + default: { - GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * count; + unsigned int count = UniformExternalComponentCount(targetUniform->type); + unsigned int internalCount = UniformInternalComponentCount(targetUniform->type); - for (unsigned int i = 0; i < count; ++i) + switch (UniformComponentType(targetUniform->type)) { - params[i] = (GLint)floatParams[i]; + case GL_BOOL: + { + GLboolean *boolParams = targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (GLint)boolParams[i]; + } + } + break; + case GL_FLOAT: + { + GLfloat *floatParams = (GLfloat*)targetUniform->data + mUniformIndex[location].element * internalCount; + + for (unsigned int i = 0; i < count; ++i) + { + params[i] = (GLint)floatParams[i]; + } + } + break; + case GL_INT: + memcpy(params, targetUniform->data + mUniformIndex[location].element * internalCount * sizeof(GLint), + count * sizeof(GLint)); + break; + default: UNREACHABLE(); } } - break; - case GL_INT: - memcpy(params, targetUniform->data + mUniformIndex[location].element * count * sizeof(GLint), - count * sizeof(GLint)); - break; - default: UNREACHABLE(); } return true; @@ -904,26 +1024,11 @@ void Program::dirtyAllUniforms() } } -void Program::dirtyAllSamplers() -{ - for (unsigned int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; ++index) - { - mSamplers[index].dirty = true; - } -} - // Applies all the uniforms set for this program object to the Direct3D 9 device void Program::applyUniforms() { - unsigned int numUniforms = mUniformIndex.size(); - for (unsigned int location = 0; location < numUniforms; location++) - { - if (mUniformIndex[location].element != 0) - { - continue; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + for (std::vector<Uniform*>::iterator ub = mUniforms.begin(), ue = mUniforms.end(); ub != ue; ++ub) { + Uniform *targetUniform = *ub; if (targetUniform->dirty) { @@ -934,23 +1039,23 @@ void Program::applyUniforms() switch (targetUniform->type) { - case GL_BOOL: applyUniform1bv(location, arraySize, b); break; - case GL_BOOL_VEC2: applyUniform2bv(location, arraySize, b); break; - case GL_BOOL_VEC3: applyUniform3bv(location, arraySize, b); break; - case GL_BOOL_VEC4: applyUniform4bv(location, arraySize, b); break; - case GL_FLOAT: applyUniform1fv(location, arraySize, f); break; - case GL_FLOAT_VEC2: applyUniform2fv(location, arraySize, f); break; - case GL_FLOAT_VEC3: applyUniform3fv(location, arraySize, f); break; - case GL_FLOAT_VEC4: applyUniform4fv(location, arraySize, f); break; - 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_BOOL: applyUniformnbv(targetUniform, arraySize, 1, b); break; + case GL_BOOL_VEC2: applyUniformnbv(targetUniform, arraySize, 2, b); break; + case GL_BOOL_VEC3: applyUniformnbv(targetUniform, arraySize, 3, b); break; + case GL_BOOL_VEC4: applyUniformnbv(targetUniform, arraySize, 4, b); break; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: applyUniformnfv(targetUniform, f); break; case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: - case GL_INT: applyUniform1iv(location, arraySize, i); break; - case GL_INT_VEC2: applyUniform2iv(location, arraySize, i); break; - case GL_INT_VEC3: applyUniform3iv(location, arraySize, i); break; - case GL_INT_VEC4: applyUniform4iv(location, arraySize, i); break; + case GL_INT: applyUniform1iv(targetUniform, arraySize, i); break; + case GL_INT_VEC2: applyUniform2iv(targetUniform, arraySize, i); break; + case GL_INT_VEC3: applyUniform3iv(targetUniform, arraySize, i); break; + case GL_INT_VEC4: applyUniform4iv(targetUniform, arraySize, i); break; default: UNREACHABLE(); } @@ -961,38 +1066,76 @@ void Program::applyUniforms() } // Compiles the HLSL code of the attached shaders into executable binaries -ID3DXBuffer *Program::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) +ID3D10Blob *Program::compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable) { if (!hlsl) { return NULL; } - ID3DXBuffer *binary = NULL; - ID3DXBuffer *errorMessage = NULL; - - HRESULT result = D3DXCompileShader(hlsl, (UINT)strlen(hlsl), NULL, NULL, "main", profile, 0, &binary, &errorMessage, constantTable); - - if (SUCCEEDED(result)) + DWORD result; + UINT flags = 0; + std::string sourceText; + if (perfActive()) { - return binary; - } + flags |= D3DCOMPILE_DEBUG; +#ifdef NDEBUG + flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; +#else + flags |= D3DCOMPILE_SKIP_OPTIMIZATION; +#endif - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + std::string sourcePath = getTempPath(); + sourceText = std::string("#line 2 \"") + sourcePath + std::string("\"\n\n") + std::string(hlsl); + writeFile(sourcePath.c_str(), sourceText.c_str(), sourceText.size()); + } + else { - return error(GL_OUT_OF_MEMORY, (ID3DXBuffer*)NULL); + flags |= ANGLE_COMPILE_OPTIMIZATION_LEVEL; + sourceText = hlsl; } + ID3D10Blob *binary = NULL; + ID3D10Blob *errorMessage = NULL; + result = D3DCompile(hlsl, strlen(hlsl), fakepath, NULL, NULL, "main", profile, flags, 0, &binary, &errorMessage); + if (errorMessage) { const char *message = (const char*)errorMessage->GetBufferPointer(); - appendToInfoLog("%s\n", message); + appendToInfoLogSanitized(message); TRACE("\n%s", hlsl); TRACE("\n%s", message); + + errorMessage->Release(); + errorMessage = NULL; + } + + if (FAILED(result)) + { + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + error(GL_OUT_OF_MEMORY); + } + + return NULL; + } + + result = D3DXGetShaderConstantTable(static_cast<const DWORD*>(binary->GetBufferPointer()), constantTable); + + if (FAILED(result)) + { + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + error(GL_OUT_OF_MEMORY); + } + + binary->Release(); + + return NULL; } - return NULL; + return binary; } // Packs varyings into generic varying registers, using the algorithm from [OpenGL ES Shading Language 1.00 rev. 17] appendix A section 7 page 111 @@ -1002,7 +1145,7 @@ 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++) + for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) { int n = VariableRowCount(varying->type) * varying->size; int m = VariableColumnCount(varying->type); @@ -1093,13 +1236,13 @@ int Program::packVaryings(const Varying *packing[][4]) for (int x = 0; x < 4; x++) { - if (space[x] > n && space[x] < space[column]) + if (space[x] >= n && space[x] < space[column]) { column = x; } } - if (space[column] > n) + if (space[column] >= n) { for (int r = 0; r < maxVaryingVectors; r++) { @@ -1152,6 +1295,20 @@ bool Program::linkVaryings() return false; } + // Reset the varying register assignments + for (VaryingList::iterator fragVar = mFragmentShader->mVaryings.begin(); fragVar != mFragmentShader->mVaryings.end(); fragVar++) + { + fragVar->reg = -1; + fragVar->col = -1; + } + + for (VaryingList::iterator vtxVar = mVertexShader->mVaryings.begin(); vtxVar != mVertexShader->mVaryings.end(); vtxVar++) + { + vtxVar->reg = -1; + vtxVar->col = -1; + } + + // Map the varyings to the register file const Varying *packing[MAX_VARYING_VECTORS_SM3][4] = {NULL}; int registers = packVaryings(packing); @@ -1160,6 +1317,7 @@ bool Program::linkVaryings() return false; } + // Write the HLSL input/output declarations Context *context = getContext(); const bool sm3 = context->supportsShaderModel3(); const int maxVaryingVectors = context->getMaximumVaryingVectors(); @@ -1171,11 +1329,11 @@ bool Program::linkVaryings() return false; } - for (VaryingList::iterator input = mFragmentShader->varyings.begin(); input != mFragmentShader->varyings.end(); input++) + for (VaryingList::iterator input = mFragmentShader->mVaryings.begin(); input != mFragmentShader->mVaryings.end(); input++) { bool matched = false; - for (VaryingList::iterator output = mVertexShader->varyings.begin(); output != mVertexShader->varyings.end(); output++) + for (VaryingList::iterator output = mVertexShader->mVaryings.begin(); output != mVertexShader->mVaryings.end(); output++) { if (output->name == input->name) { @@ -1196,7 +1354,7 @@ bool Program::linkVaryings() if (!matched) { - appendToInfoLog("Fragment varying varying %s does not match any vertex varying", input->name.c_str()); + appendToInfoLog("Fragment varying %s does not match any vertex varying", input->name.c_str()); return false; } @@ -1222,7 +1380,7 @@ bool Program::linkVaryings() default: UNREACHABLE(); } - mVertexHLSL += decorate(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; + mVertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; semanticIndex += VariableRowCount(attribute->type); } @@ -1257,14 +1415,14 @@ bool Program::linkVaryings() for (AttributeArray::iterator attribute = mVertexShader->mAttributes.begin(); attribute != mVertexShader->mAttributes.end(); attribute++) { - mVertexHLSL += " " + decorate(attribute->name) + " = "; + mVertexHLSL += " " + decorateAttribute(attribute->name) + " = "; if (VariableRowCount(attribute->type) > 1) // Matrix { mVertexHLSL += "transpose"; } - mVertexHLSL += "(input." + decorate(attribute->name) + ");\n"; + mVertexHLSL += "(input." + decorateAttribute(attribute->name) + ");\n"; } mVertexHLSL += "\n" @@ -1272,7 +1430,7 @@ bool Program::linkVaryings() "\n" " VS_OUTPUT output;\n" " output.gl_Position.x = gl_Position.x - dx_HalfPixelSize.x * gl_Position.w;\n" - " output.gl_Position.y = -(gl_Position.y - dx_HalfPixelSize.y * gl_Position.w);\n" + " output.gl_Position.y = gl_Position.y - dx_HalfPixelSize.y * gl_Position.w;\n" " output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n" " output.gl_Position.w = gl_Position.w;\n"; @@ -1286,7 +1444,7 @@ bool Program::linkVaryings() mVertexHLSL += " output.gl_FragCoord = gl_Position;\n"; } - for (VaryingList::iterator varying = mVertexShader->varyings.begin(); varying != mVertexShader->varyings.end(); varying++) + for (VaryingList::iterator varying = mVertexShader->mVaryings.begin(); varying != mVertexShader->mVaryings.end(); varying++) { if (varying->reg >= 0) { @@ -1354,7 +1512,7 @@ bool Program::linkVaryings() mPixelHLSL += "struct PS_INPUT\n" "{\n"; - for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++) + for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) { if (varying->reg >= 0) { @@ -1402,20 +1560,27 @@ bool Program::linkVaryings() if (mFragmentShader->mUsesFragCoord) { 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"; + + if (sm3) + { + // dx_Coord.y contains the render target height. See Context::applyRenderTarget() + mPixelHLSL += " gl_FragCoord.x = input.dx_VPos.x + 0.5;\n" + " gl_FragCoord.y = dx_Coord.y - input.dx_VPos.y - 0.5;\n"; } + else + { + // dx_Coord contains the viewport width/2, height/2, center.x and center.y. See Context::applyRenderTarget() + mPixelHLSL += " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Coord.x + dx_Coord.z;\n" + " gl_FragCoord.y = -(input.gl_FragCoord.y * rhw) * dx_Coord.y + dx_Coord.w;\n"; + } + mPixelHLSL += " gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n" " gl_FragCoord.w = rhw;\n"; } if (mFragmentShader->mUsesPointCoord && sm3) { - mPixelHLSL += " gl_PointCoord = float2(input.gl_PointCoord.x, 1.0 - input.gl_PointCoord.y);\n"; + mPixelHLSL += " gl_PointCoord = input.gl_PointCoord;\n"; } if (mFragmentShader->mUsesFrontFacing) @@ -1423,7 +1588,7 @@ bool Program::linkVaryings() mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n"; } - for (VaryingList::iterator varying = mFragmentShader->varyings.begin(); varying != mFragmentShader->varyings.end(); varying++) + for (VaryingList::iterator varying = mFragmentShader->mVaryings.begin(); varying != mFragmentShader->mVaryings.end(); varying++) { if (varying->reg >= 0) { @@ -1461,9 +1626,6 @@ bool Program::linkVaryings() " return output;\n" "}\n"; - TRACE("\n%s", mPixelHLSL.c_str()); - TRACE("\n%s", mVertexHLSL.c_str()); - return true; } @@ -1496,14 +1658,13 @@ void Program::link() const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0"; const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0"; - ID3DXBuffer *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS); - ID3DXBuffer *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS); + ID3D10Blob *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS); + ID3D10Blob *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS); if (vertexBinary && pixelBinary) { - IDirect3DDevice9 *device = getDevice(); - HRESULT vertexResult = device->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable); - HRESULT pixelResult = device->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable); + HRESULT vertexResult = mDevice->CreateVertexShader((DWORD*)vertexBinary->GetBufferPointer(), &mVertexExecutable); + HRESULT pixelResult = mDevice->CreatePixelShader((DWORD*)pixelBinary->GetBufferPointer(), &mPixelExecutable); if (vertexResult == D3DERR_OUTOFVIDEOMEMORY || vertexResult == E_OUTOFMEMORY || pixelResult == D3DERR_OUTOFVIDEOMEMORY || pixelResult == E_OUTOFMEMORY) { @@ -1536,12 +1697,12 @@ void Program::link() // these uniforms are searched as already-decorated because gl_ and dx_ // are reserved prefixes, and do not receive additional decoration - mDxDepthRangeLocation = getUniformLocation("dx_DepthRange", true); - mDxDepthLocation = getUniformLocation("dx_Depth", true); - mDxViewportLocation = getUniformLocation("dx_Viewport", true); - mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true); - mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW", true); - mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines", true); + mDxDepthRangeLocation = getUniformLocation("dx_DepthRange"); + mDxDepthLocation = getUniformLocation("dx_Depth"); + mDxCoordLocation = getUniformLocation("dx_Coord"); + mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize"); + mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW"); + mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines"); mLinked = true; // Success } @@ -1642,7 +1803,8 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable) for (unsigned int constantIndex = 0; constantIndex < constantTableDescription.Constants; constantIndex++) { D3DXHANDLE constantHandle = constantTable->GetConstant(0, constantIndex); - constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); + HRESULT result = constantTable->GetConstantDesc(constantHandle, &constantDescription, &descriptionCount); + ASSERT(SUCCEEDED(result)); if (!defineUniform(constantHandle, constantDescription)) { @@ -1659,14 +1821,46 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT { if (constantDescription.RegisterSet == D3DXRS_SAMPLER) { - for (unsigned int samplerIndex = constantDescription.RegisterIndex; samplerIndex < constantDescription.RegisterIndex + constantDescription.RegisterCount; samplerIndex++) + for (unsigned int i = 0; i < constantDescription.RegisterCount; i++) { - ASSERT(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0])); + D3DXHANDLE psConstant = mConstantTablePS->GetConstantByName(NULL, constantDescription.Name); + D3DXHANDLE vsConstant = mConstantTableVS->GetConstantByName(NULL, constantDescription.Name); - mSamplers[samplerIndex].active = true; - mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D; - mSamplers[samplerIndex].logicalTextureUnit = 0; - mSamplers[samplerIndex].dirty = true; + if (psConstant) + { + unsigned int samplerIndex = mConstantTablePS->GetSamplerIndex(psConstant) + i; + + if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) + { + mSamplersPS[samplerIndex].active = true; + mSamplersPS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersPS[samplerIndex].logicalTextureUnit = 0; + mUsedPixelSamplerRange = std::max(samplerIndex + 1, mUsedPixelSamplerRange); + } + else + { + appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS); + return false; + } + } + + if (vsConstant) + { + unsigned int samplerIndex = mConstantTableVS->GetSamplerIndex(vsConstant) + i; + + if (samplerIndex < getContext()->getMaximumVertexTextureImageUnits()) + { + mSamplersVS[samplerIndex].active = true; + mSamplersVS[samplerIndex].textureType = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? TEXTURE_CUBE : TEXTURE_2D; + mSamplersVS[samplerIndex].logicalTextureUnit = 0; + mUsedVertexSamplerRange = std::max(samplerIndex + 1, mUsedVertexSamplerRange); + } + else + { + appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", getContext()->getMaximumVertexTextureImageUnits()); + return false; + } + } } } @@ -1683,7 +1877,8 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT D3DXCONSTANT_DESC fieldDescription; UINT descriptionCount = 1; - mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount); + HRESULT result = mConstantTablePS->GetConstantDesc(fieldHandle, &fieldDescription, &descriptionCount); + ASSERT(SUCCEEDED(result)); std::string structIndex = (constantDescription.Elements > 1) ? ("[" + str(arrayIndex) + "]") : ""; @@ -1707,9 +1902,9 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT } } -bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name) +bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) { - Uniform *uniform = createUniform(constantDescription, name); + Uniform *uniform = createUniform(constantDescription, _name); if(!uniform) { @@ -1717,7 +1912,7 @@ bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::s } // Check if already defined - GLint location = getUniformLocation(name.c_str(), true); + GLint location = getUniformLocation(uniform->name); GLenum type = uniform->type; if (location >= 0) @@ -1734,18 +1929,21 @@ bool Program::defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::s } } + initializeConstantHandles(uniform, &uniform->ps, mConstantTablePS); + initializeConstantHandles(uniform, &uniform->vs, mConstantTableVS); + mUniforms.push_back(uniform); unsigned int uniformIndex = mUniforms.size() - 1; for (unsigned int i = 0; i < uniform->arraySize; ++i) { - mUniformIndex.push_back(UniformLocation(name, i, uniformIndex)); + mUniformIndex.push_back(UniformLocation(_name, i, uniformIndex)); } return true; } -Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name) +Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &_name) { if (constantDescription.Rows == 1) // Vectors and scalars { @@ -1754,44 +1952,44 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st case D3DXPT_SAMPLER2D: switch (constantDescription.Columns) { - case 1: return new Uniform(GL_SAMPLER_2D, name, constantDescription.Elements); + 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_SAMPLER_CUBE, name, constantDescription.Elements); + case 1: return new Uniform(GL_SAMPLER_CUBE, _name, constantDescription.Elements); default: UNREACHABLE(); } break; case D3DXPT_BOOL: switch (constantDescription.Columns) { - case 1: return new Uniform(GL_BOOL, name, constantDescription.Elements); - case 2: return new Uniform(GL_BOOL_VEC2, name, constantDescription.Elements); - case 3: return new Uniform(GL_BOOL_VEC3, name, constantDescription.Elements); - case 4: return new Uniform(GL_BOOL_VEC4, name, constantDescription.Elements); + case 1: return new Uniform(GL_BOOL, _name, constantDescription.Elements); + case 2: return new Uniform(GL_BOOL_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_BOOL_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_BOOL_VEC4, _name, constantDescription.Elements); default: UNREACHABLE(); } break; case D3DXPT_INT: switch (constantDescription.Columns) { - case 1: return new Uniform(GL_INT, name, constantDescription.Elements); - case 2: return new Uniform(GL_INT_VEC2, name, constantDescription.Elements); - case 3: return new Uniform(GL_INT_VEC3, name, constantDescription.Elements); - case 4: return new Uniform(GL_INT_VEC4, name, constantDescription.Elements); + case 1: return new Uniform(GL_INT, _name, constantDescription.Elements); + case 2: return new Uniform(GL_INT_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_INT_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_INT_VEC4, _name, constantDescription.Elements); default: UNREACHABLE(); } break; case D3DXPT_FLOAT: switch (constantDescription.Columns) { - case 1: return new Uniform(GL_FLOAT, name, constantDescription.Elements); - case 2: return new Uniform(GL_FLOAT_VEC2, name, constantDescription.Elements); - case 3: return new Uniform(GL_FLOAT_VEC3, name, constantDescription.Elements); - case 4: return new Uniform(GL_FLOAT_VEC4, name, constantDescription.Elements); + case 1: return new Uniform(GL_FLOAT, _name, constantDescription.Elements); + case 2: return new Uniform(GL_FLOAT_VEC2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_FLOAT_VEC3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_FLOAT_VEC4, _name, constantDescription.Elements); default: UNREACHABLE(); } break; @@ -1806,9 +2004,9 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st case D3DXPT_FLOAT: switch (constantDescription.Rows) { - case 2: return new Uniform(GL_FLOAT_MAT2, name, constantDescription.Elements); - case 3: return new Uniform(GL_FLOAT_MAT3, name, constantDescription.Elements); - case 4: return new Uniform(GL_FLOAT_MAT4, name, constantDescription.Elements); + case 2: return new Uniform(GL_FLOAT_MAT2, _name, constantDescription.Elements); + case 3: return new Uniform(GL_FLOAT_MAT3, _name, constantDescription.Elements); + case 4: return new Uniform(GL_FLOAT_MAT4, _name, constantDescription.Elements); default: UNREACHABLE(); } break; @@ -1821,410 +2019,125 @@ Uniform *Program::createUniform(const D3DXCONSTANT_DESC &constantDescription, st } // This method needs to match OutputHLSL::decorate -std::string Program::decorate(const std::string &string) -{ - if (string.substr(0, 3) != "gl_" && string.substr(0, 3) != "dx_") - { - return "_" + string; - } - else - { - return string; - } -} - -std::string Program::undecorate(const std::string &string) +std::string Program::decorateAttribute(const std::string &name) { - if (string.substr(0, 1) == "_") + if (name.compare(0, 3, "gl_") != 0 && name.compare(0, 3, "dx_") != 0) { - return string.substr(1); + return "_" + name; } - else - { - return string; - } -} - -bool Program::applyUniform1bv(GLint location, GLsizei count, const GLboolean *v) -{ - BOOL *vector = new BOOL[count]; - for (int i = 0; i < count; i++) - { - if (v[i] == GL_FALSE) - vector[i] = 0; - else - vector[i] = 1; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetBoolArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetBoolArray(device, constantVS, vector, count); - } - - delete [] vector; - - return true; -} - -bool Program::applyUniform2bv(GLint location, GLsizei count, const GLboolean *v) -{ - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f), - (v[1] == GL_FALSE ? 0.0f : 1.0f), 0, 0); - - v += 2; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); - } - - delete[] vector; - - return true; -} - -bool Program::applyUniform3bv(GLint location, GLsizei count, const GLboolean *v) -{ - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f), - (v[1] == GL_FALSE ? 0.0f : 1.0f), - (v[2] == GL_FALSE ? 0.0f : 1.0f), 0); - - v += 3; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); - } - - delete[] vector; - - return true; -} - -bool Program::applyUniform4bv(GLint location, GLsizei count, const GLboolean *v) -{ - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; - - for (int i = 0; i < count; i++) - { - vector[i] = D3DXVECTOR4((v[0] == GL_FALSE ? 0.0f : 1.0f), - (v[1] == GL_FALSE ? 0.0f : 1.0f), - (v[2] == GL_FALSE ? 0.0f : 1.0f), - (v[3] == GL_FALSE ? 0.0f : 1.0f)); - - v += 3; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); - } - - delete [] vector; - - return true; -} - -bool Program::applyUniform1fv(GLint location, GLsizei count, const GLfloat *v) -{ - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetFloatArray(device, constantPS, v, count); - } - - if (constantVS) - { - mConstantTableVS->SetFloatArray(device, constantVS, v, count); - } - - return true; + + return name; } -bool Program::applyUniform2fv(GLint location, GLsizei count, const GLfloat *v) +std::string Program::undecorateUniform(const std::string &_name) { - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; - - for (int i = 0; i < count; i++) + if (_name[0] == '_') { - vector[i] = D3DXVECTOR4(v[0], v[1], 0, 0); - - v += 2; + return _name.substr(1); } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) + else if (_name.compare(0, 3, "ar_") == 0) { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); + return _name.substr(3); } - - delete[] vector; - - return true; + + return _name; } -bool Program::applyUniform3fv(GLint location, GLsizei count, const GLfloat *v) +void Program::applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v) { - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; + float vector[D3D9_MAX_FLOAT_CONSTANTS * 4]; + BOOL boolVector[D3D9_MAX_BOOL_CONSTANTS]; - for (int i = 0; i < count; i++) + if (targetUniform->ps.registerCount && targetUniform->ps.registerSet == D3DXRS_FLOAT4 || + targetUniform->vs.registerCount && targetUniform->vs.registerSet == D3DXRS_FLOAT4) { - vector[i] = D3DXVECTOR4(v[0], v[1], v[2], 0); - - v += 3; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + for (int i = 0; i < count; i++) + { + for (int j = 0; j < 4; j++) + { + if (j < width) + { + vector[i * 4 + j] = (v[i * width + j] == GL_FALSE) ? 0.0f : 1.0f; + } + else + { + vector[i * 4 + j] = 0.0f; + } + } + } } - if (constantVS) + if (targetUniform->ps.registerCount && targetUniform->ps.registerSet == D3DXRS_BOOL || + targetUniform->vs.registerCount && targetUniform->vs.registerSet == D3DXRS_BOOL) { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); + int psCount = targetUniform->ps.registerSet == D3DXRS_BOOL ? targetUniform->ps.registerCount : 0; + int vsCount = targetUniform->vs.registerSet == D3DXRS_BOOL ? targetUniform->vs.registerCount : 0; + int copyCount = std::min(count * width, std::max(psCount, vsCount)); + ASSERT(copyCount <= D3D9_MAX_BOOL_CONSTANTS); + for (int i = 0; i < copyCount; i++) + { + boolVector[i] = v[i] != GL_FALSE; + } } - delete[] vector; - - return true; -} - -bool Program::applyUniform4fv(GLint location, GLsizei count, const GLfloat *v) -{ - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) + if (targetUniform->ps.registerCount) { - mConstantTablePS->SetVectorArray(device, constantPS, (D3DXVECTOR4*)v, count); + if (targetUniform->ps.registerSet == D3DXRS_FLOAT4) + { + mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, vector, targetUniform->ps.registerCount); + } + else if (targetUniform->ps.registerSet == D3DXRS_BOOL) + { + mDevice->SetPixelShaderConstantB(targetUniform->ps.registerIndex, boolVector, targetUniform->ps.registerCount); + } + else UNREACHABLE(); } - if (constantVS) + if (targetUniform->vs.registerCount) { - mConstantTableVS->SetVectorArray(device, constantVS, (D3DXVECTOR4*)v, count); + if (targetUniform->vs.registerSet == D3DXRS_FLOAT4) + { + mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, vector, targetUniform->vs.registerCount); + } + else if (targetUniform->vs.registerSet == D3DXRS_BOOL) + { + mDevice->SetVertexShaderConstantB(targetUniform->vs.registerIndex, boolVector, targetUniform->vs.registerCount); + } + else UNREACHABLE(); } - - return true; } -bool Program::applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value) +bool Program::applyUniformnfv(Uniform *targetUniform, const GLfloat *v) { - D3DXMATRIX *matrix = new D3DXMATRIX[count]; - - for (int i = 0; i < count; i++) + if (targetUniform->ps.registerCount) { - matrix[i] = D3DXMATRIX(value[0], value[2], 0, 0, - value[1], value[3], 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1); - - value += 4; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetMatrixTransposeArray(device, constantPS, matrix, count); + mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, v, targetUniform->ps.registerCount); } - if (constantVS) + if (targetUniform->vs.registerCount) { - mConstantTableVS->SetMatrixTransposeArray(device, constantVS, matrix, count); + mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, v, targetUniform->vs.registerCount); } - delete[] matrix; - return true; } -bool Program::applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value) +bool Program::applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v) { - D3DXMATRIX *matrix = new D3DXMATRIX[count]; + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; for (int i = 0; i < count; i++) { - matrix[i] = D3DXMATRIX(value[0], value[3], value[6], 0, - value[1], value[4], value[7], 0, - value[2], value[5], value[8], 0, - 0, 0, 0, 1); - - value += 9; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetMatrixTransposeArray(device, constantPS, matrix, count); + vector[i] = D3DXVECTOR4((float)v[i], 0, 0, 0); } - if (constantVS) + if (targetUniform->ps.registerCount) { - mConstantTableVS->SetMatrixTransposeArray(device, constantVS, matrix, count); - } - - delete[] matrix; - - return true; -} - -bool Program::applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value) -{ - D3DXMATRIX *matrix = new D3DXMATRIX[count]; - - for (int i = 0; i < count; i++) - { - matrix[i] = D3DXMATRIX(value[0], value[4], value[8], value[12], - value[1], value[5], value[9], value[13], - value[2], value[6], value[10], value[14], - value[3], value[7], value[11], value[15]); - - value += 16; - } - - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetMatrixTransposeArray(device, constantPS, matrix, count); - } - - if (constantVS) - { - mConstantTableVS->SetMatrixTransposeArray(device, constantVS, matrix, count); - } - - delete[] matrix; - - return true; -} - -bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) -{ - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - D3DXCONSTANT_DESC constantDescription; - UINT descriptionCount = 1; - HRESULT result = mConstantTablePS->GetConstantDesc(constantPS, &constantDescription, &descriptionCount); - - if (FAILED(result)) - { - return false; - } - - if (constantDescription.RegisterSet == D3DXRS_SAMPLER) + if (targetUniform->ps.registerSet == D3DXRS_SAMPLER) { - unsigned int firstIndex = mConstantTablePS->GetSamplerIndex(constantPS); + unsigned int firstIndex = targetUniform->ps.registerIndex; for (int i = 0; i < count; i++) { @@ -2232,32 +2145,49 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) { - ASSERT(mSamplers[samplerIndex].active); - mSamplers[samplerIndex].logicalTextureUnit = v[i]; - mSamplers[samplerIndex].dirty = true; + ASSERT(mSamplersPS[samplerIndex].active); + mSamplersPS[samplerIndex].logicalTextureUnit = v[i]; } } - - return true; + } + else + { + ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4); + mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float*)vector, targetUniform->ps.registerCount); } } - if (constantPS) + if (targetUniform->vs.registerCount) { - mConstantTablePS->SetIntArray(device, constantPS, v, count); - } + if (targetUniform->vs.registerSet == D3DXRS_SAMPLER) + { + unsigned int firstIndex = targetUniform->vs.registerIndex; - if (constantVS) - { - mConstantTableVS->SetIntArray(device, constantVS, v, count); + for (int i = 0; i < count; i++) + { + unsigned int samplerIndex = firstIndex + i; + + if (samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF) + { + ASSERT(mSamplersVS[samplerIndex].active); + mSamplersVS[samplerIndex].logicalTextureUnit = v[i]; + } + } + } + else + { + ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4); + mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount); + } } return true; } -bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v) +bool Program::applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v) { - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; for (int i = 0; i < count; i++) { @@ -2266,31 +2196,15 @@ bool Program::applyUniform2iv(GLint location, GLsizei count, const GLint *v) v += 2; } - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); - } - - delete[] vector; + applyUniformniv(targetUniform, count, vector); return true; } -bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v) +bool Program::applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v) { - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; for (int i = 0; i < count; i++) { @@ -2299,31 +2213,15 @@ bool Program::applyUniform3iv(GLint location, GLsizei count, const GLint *v) v += 3; } - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; - - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); - - if (constantPS) - { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); - } - - if (constantVS) - { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); - } - - delete[] vector; + applyUniformniv(targetUniform, count, vector); return true; } -bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v) +bool Program::applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v) { - D3DXVECTOR4 *vector = new D3DXVECTOR4[count]; + ASSERT(count <= D3D9_MAX_FLOAT_CONSTANTS); + D3DXVECTOR4 vector[D3D9_MAX_FLOAT_CONSTANTS]; for (int i = 0; i < count; i++) { @@ -2332,26 +2230,45 @@ bool Program::applyUniform4iv(GLint location, GLsizei count, const GLint *v) v += 4; } - Uniform *targetUniform = mUniforms[mUniformIndex[location].index]; + applyUniformniv(targetUniform, count, vector); - D3DXHANDLE constantPS; - D3DXHANDLE constantVS; - getConstantHandles(targetUniform, &constantPS, &constantVS); - IDirect3DDevice9 *device = getDevice(); + return true; +} - if (constantPS) +void Program::applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector) +{ + if (targetUniform->ps.registerCount) { - mConstantTablePS->SetVectorArray(device, constantPS, vector, count); + ASSERT(targetUniform->ps.registerSet == D3DXRS_FLOAT4); + mDevice->SetPixelShaderConstantF(targetUniform->ps.registerIndex, (const float *)vector, targetUniform->ps.registerCount); } - if (constantVS) + if (targetUniform->vs.registerCount) { - mConstantTableVS->SetVectorArray(device, constantVS, vector, count); + ASSERT(targetUniform->vs.registerSet == D3DXRS_FLOAT4); + mDevice->SetVertexShaderConstantF(targetUniform->vs.registerIndex, (const float *)vector, targetUniform->vs.registerCount); } +} - delete [] vector; +// append a santized message to the program info log. +// The D3D compiler includes a fake file path in some of the warning or error +// messages, so lets remove all occurrences of this fake file path from the log. +void Program::appendToInfoLogSanitized(const char *message) +{ + std::string msg(message); - return true; + size_t found; + do + { + found = msg.find(fakepath); + if (found != std::string::npos) + { + msg.erase(found, strlen(fakepath)); + } + } + while (found != std::string::npos); + + appendToInfoLog("%s\n", msg.c_str()); } void Program::appendToInfoLog(const char *format, ...) @@ -2396,7 +2313,7 @@ void Program::resetInfoLog() } } -// Returns the program object to an unlinked state, after detaching a shader, before re-linking, or at destruction +// Returns the program object to an unlinked state, before re-linking, or at destruction void Program::unlink(bool destroy) { if (destroy) // Object being destructed @@ -2446,10 +2363,17 @@ void Program::unlink(bool destroy) for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) { - mSamplers[index].active = false; - mSamplers[index].dirty = true; + mSamplersPS[index].active = false; } + for (int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF; index++) + { + mSamplersVS[index].active = false; + } + + mUsedVertexSamplerRange = 0; + mUsedPixelSamplerRange = 0; + while (!mUniforms.empty()) { delete mUniforms.back(); @@ -2458,7 +2382,7 @@ void Program::unlink(bool destroy) mDxDepthRangeLocation = -1; mDxDepthLocation = -1; - mDxViewportLocation = -1; + mDxCoordLocation = -1; mDxHalfPixelSizeLocation = -1; mDxFrontCCWLocation = -1; mDxPointsOrLinesLocation = -1; @@ -2532,11 +2456,8 @@ void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) if (mInfoLog) { - while (index < bufSize - 1 && index < (int)strlen(mInfoLog)) - { - infoLog[index] = mInfoLog[index]; - index++; - } + index = std::min(bufSize - 1, (int)strlen(mInfoLog)); + memcpy(infoLog, mInfoLog, index); } if (bufSize) @@ -2655,7 +2576,7 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G unsigned int uniform; for (uniform = 0; uniform < mUniforms.size(); uniform++) { - if (mUniforms[uniform]->name.substr(0, 3) == "dx_") + if (mUniforms[uniform]->name.compare(0, 3, "dx_") == 0) { continue; } @@ -2672,9 +2593,9 @@ void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, G if (bufsize > 0) { - std::string string = undecorate(mUniforms[uniform]->name); + std::string string = mUniforms[uniform]->name; - if (mUniforms[uniform]->arraySize != 1) + if (mUniforms[uniform]->isArray()) { string += "[0]"; } @@ -2700,7 +2621,7 @@ GLint Program::getActiveUniformCount() unsigned int numUniforms = mUniforms.size(); for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) { - if (mUniforms[uniformIndex]->name.substr(0, 3) != "dx_") + if (mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) { count++; } @@ -2716,9 +2637,14 @@ GLint Program::getActiveUniformMaxLength() unsigned int numUniforms = mUniforms.size(); for (unsigned int uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++) { - if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.substr(0, 3) != "dx_") + if (!mUniforms[uniformIndex]->name.empty() && mUniforms[uniformIndex]->name.compare(0, 3, "dx_") != 0) { - maxLength = std::max((int)(undecorate(mUniforms[uniformIndex]->name).length() + 1), maxLength); + int length = (int)(mUniforms[uniformIndex]->name.length() + 1); + if (mUniforms[uniformIndex]->isArray()) + { + length += 3; // Counting in "[0]". + } + maxLength = std::max(length, maxLength); } } @@ -2747,9 +2673,8 @@ void Program::validate() else { applyUniforms(); - if (!validateSamplers()) + if (!validateSamplers(true)) { - appendToInfoLog("Samplers of conflicting types refer to the same texture image unit."); mValidated = false; } else @@ -2759,24 +2684,86 @@ void Program::validate() } } -bool Program::validateSamplers() const +bool Program::validateSamplers(bool logErrors) { // if any two active samplers in a program are of different types, but refer to the same // texture image unit, and this is the current program, then ValidateProgram will fail, and // DrawArrays and DrawElements will issue the INVALID_OPERATION error. - std::map<int, SamplerType> samplerMap; - for (unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; ++i) + + const unsigned int maxCombinedTextureImageUnits = getContext()->getMaximumCombinedTextureImageUnits(); + TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF]; + + for (unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS_VTF; ++i) + { + textureUnitType[i] = TEXTURE_UNKNOWN; + } + + for (unsigned int i = 0; i < mUsedPixelSamplerRange; ++i) { - if (mSamplers[i].active) + if (mSamplersPS[i].active) { - if (samplerMap.find(mSamplers[i].logicalTextureUnit) != samplerMap.end()) + unsigned int unit = mSamplersPS[i].logicalTextureUnit; + + if (unit >= maxCombinedTextureImageUnits) { - if (mSamplers[i].type != samplerMap[mSamplers[i].logicalTextureUnit]) + if (logErrors) + { + appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); + } + + return false; + } + + if (textureUnitType[unit] != TEXTURE_UNKNOWN) + { + if (mSamplersPS[i].textureType != textureUnitType[unit]) + { + if (logErrors) + { + appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + return false; + } } else { - samplerMap[mSamplers[i].logicalTextureUnit] = mSamplers[i].type; + textureUnitType[unit] = mSamplersPS[i].textureType; + } + } + } + + for (unsigned int i = 0; i < mUsedVertexSamplerRange; ++i) + { + if (mSamplersVS[i].active) + { + unsigned int unit = mSamplersVS[i].logicalTextureUnit; + + if (unit >= maxCombinedTextureImageUnits) + { + if (logErrors) + { + appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, maxCombinedTextureImageUnits); + } + + return false; + } + + if (textureUnitType[unit] != TEXTURE_UNKNOWN) + { + if (mSamplersVS[i].textureType != textureUnitType[unit]) + { + if (logErrors) + { + appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit); + } + + return false; + } + } + else + { + textureUnitType[unit] = mSamplersVS[i].textureType; } } } @@ -2784,17 +2771,23 @@ bool Program::validateSamplers() const return true; } -void Program::getConstantHandles(Uniform *targetUniform, D3DXHANDLE *constantPS, D3DXHANDLE *constantVS) +void Program::initializeConstantHandles(Uniform *targetUniform, Uniform::RegisterInfo *ri, ID3DXConstantTable *constantTable) { - if (!targetUniform->handlesSet) + D3DXHANDLE handle = constantTable->GetConstantByName(0, targetUniform->_name.c_str()); + if (handle) + { + UINT descriptionCount = 1; + D3DXCONSTANT_DESC constantDescription; + HRESULT result = constantTable->GetConstantDesc(handle, &constantDescription, &descriptionCount); + ASSERT(SUCCEEDED(result)); + ri->registerIndex = constantDescription.RegisterIndex; + ri->registerCount = constantDescription.RegisterCount; + ri->registerSet = constantDescription.RegisterSet; + } + else { - targetUniform->psHandle = mConstantTablePS->GetConstantByName(0, targetUniform->name.c_str()); - targetUniform->vsHandle = mConstantTableVS->GetConstantByName(0, targetUniform->name.c_str()); - targetUniform->handlesSet = true; + ri->registerCount = 0; } - - *constantPS = targetUniform->psHandle; - *constantVS = targetUniform->vsHandle; } GLint Program::getDxDepthRangeLocation() const @@ -2807,9 +2800,9 @@ GLint Program::getDxDepthLocation() const return mDxDepthLocation; } -GLint Program::getDxViewportLocation() const +GLint Program::getDxCoordLocation() const { - return mDxViewportLocation; + return mDxCoordLocation; } GLint Program::getDxHalfPixelSizeLocation() const diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h index e9c149e..61830c6 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Program.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -11,6 +11,7 @@ #define LIBGLESV2_PROGRAM_H_ #include <d3dx9.h> +#include <d3dcompiler.h> #include <string> #include <vector> #include <set> @@ -27,26 +28,35 @@ class VertexShader; // Helper struct representing a single shader uniform struct Uniform { - Uniform(GLenum type, const std::string &name, unsigned int arraySize); + Uniform(GLenum type, const std::string &_name, unsigned int arraySize); ~Uniform(); + bool isArray(); + const GLenum type; - const std::string name; + const std::string _name; // Decorated name + const std::string name; // Undecorated name const unsigned int arraySize; unsigned char *data; bool dirty; - D3DXHANDLE vsHandle; - D3DXHANDLE psHandle; - bool handlesSet; + struct RegisterInfo + { + int registerSet; + int registerIndex; + int registerCount; + }; + + RegisterInfo ps; + RegisterInfo vs; }; // Struct used for correlating uniforms/elements of uniform arrays to handles struct UniformLocation { - UniformLocation(const std::string &name, unsigned int element, unsigned int index); + UniformLocation(const std::string &_name, unsigned int element, unsigned int index); std::string name; unsigned int element; @@ -71,14 +81,11 @@ class Program GLuint getAttributeLocation(const char *name); int getSemanticIndex(int attributeIndex); - void dirtyAllSamplers(); + GLint getSamplerMapping(SamplerType type, unsigned int samplerIndex); + TextureType getSamplerTextureType(SamplerType type, unsigned int samplerIndex); + GLint getUsedSamplerRange(SamplerType type); - GLint getSamplerMapping(unsigned int samplerIndex); - SamplerType getSamplerType(unsigned int samplerIndex); - bool isSamplerDirty(unsigned int samplerIndex) const; - void setSamplerDirty(unsigned int samplerIndex, bool dirty); - - GLint getUniformLocation(const char *name, bool decorated); + GLint getUniformLocation(std::string name); bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform3fv(GLint location, GLsizei count, const GLfloat *v); @@ -91,12 +98,12 @@ class Program bool setUniform3iv(GLint location, GLsizei count, const GLint *v); bool setUniform4iv(GLint location, GLsizei count, const GLint *v); - bool getUniformfv(GLint location, GLfloat *params); - bool getUniformiv(GLint location, GLint *params); + bool getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params); + bool getUniformiv(GLint location, GLsizei *bufSize, GLint *params); GLint getDxDepthRangeLocation() const; GLint getDxDepthLocation() const; - GLint getDxViewportLocation() const; + GLint getDxCoordLocation() const; GLint getDxHalfPixelSizeLocation() const; GLint getDxFrontCCWLocation() const; GLint getDxPointsOrLinesLocation() const; @@ -125,15 +132,18 @@ class Program bool isFlaggedForDeletion() const; void validate(); - bool validateSamplers() const; + bool validateSamplers(bool logErrors); bool isValidated() const; unsigned int getSerial() const; + static std::string decorateAttribute(const std::string &name); // Prepend an underscore + static std::string undecorateUniform(const std::string &_name); // Remove leading underscore + private: DISALLOW_COPY_AND_ASSIGN(Program); - ID3DXBuffer *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); + ID3D10Blob *compileToBinary(const char *hlsl, const char *profile, ID3DXConstantTable **constantTable); void unlink(bool destroy = false); int packVaryings(const Varying *packing[][4]); @@ -144,34 +154,25 @@ class Program bool linkUniforms(ID3DXConstantTable *constantTable); bool defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name = ""); - bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name); - Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, std::string &name); - bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v); - bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v); - bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v); - bool applyUniform4bv(GLint location, GLsizei count, const GLboolean *v); - bool applyUniform1fv(GLint location, GLsizei count, const GLfloat *v); - bool applyUniform2fv(GLint location, GLsizei count, const GLfloat *v); - bool applyUniform3fv(GLint location, GLsizei count, const GLfloat *v); - bool applyUniform4fv(GLint location, GLsizei count, const GLfloat *v); - bool applyUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *value); - bool applyUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *value); - bool applyUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *value); - bool applyUniform1iv(GLint location, GLsizei count, const GLint *v); - bool applyUniform2iv(GLint location, GLsizei count, const GLint *v); - bool applyUniform3iv(GLint location, GLsizei count, const GLint *v); - bool applyUniform4iv(GLint location, GLsizei count, const GLint *v); - - void getConstantHandles(Uniform *targetUniform, D3DXHANDLE *constantPS, D3DXHANDLE *constantVS); - + bool defineUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); + Uniform *createUniform(const D3DXCONSTANT_DESC &constantDescription, const std::string &name); + bool applyUniformnfv(Uniform *targetUniform, const GLfloat *v); + bool applyUniform1iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform2iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform3iv(Uniform *targetUniform, GLsizei count, const GLint *v); + bool applyUniform4iv(Uniform *targetUniform, GLsizei count, const GLint *v); + void applyUniformniv(Uniform *targetUniform, GLsizei count, const D3DXVECTOR4 *vector); + void applyUniformnbv(Uniform *targetUniform, GLsizei count, int width, const GLboolean *v); + + void initializeConstantHandles(Uniform *targetUniform, Uniform::RegisterInfo *rs, ID3DXConstantTable *constantTable); + + void appendToInfoLogSanitized(const char *message); void appendToInfoLog(const char *info, ...); void resetInfoLog(); - static std::string decorate(const std::string &string); // Prepend an underscore - static std::string undecorate(const std::string &string); // Remove leading underscore - static unsigned int issueSerial(); + IDirect3DDevice9 *mDevice; FragmentShader *mFragmentShader; VertexShader *mVertexShader; @@ -191,11 +192,13 @@ class Program { bool active; GLint logicalTextureUnit; - SamplerType type; - bool dirty; + TextureType textureType; }; - Sampler mSamplers[MAX_TEXTURE_IMAGE_UNITS]; + Sampler mSamplersPS[MAX_TEXTURE_IMAGE_UNITS]; + Sampler mSamplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS_VTF]; + GLuint mUsedVertexSamplerRange; + GLuint mUsedPixelSamplerRange; typedef std::vector<Uniform*> UniformArray; UniformArray mUniforms; @@ -204,7 +207,7 @@ class Program GLint mDxDepthRangeLocation; GLint mDxDepthLocation; - GLint mDxViewportLocation; + GLint mDxCoordLocation; GLint mDxHalfPixelSizeLocation; GLint mDxFrontCCWLocation; GLint mDxPointsOrLinesLocation; diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Query.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Query.cpp new file mode 100644 index 0000000..10edda5 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Query.cpp @@ -0,0 +1,128 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query.cpp: Implements the gl::Query class + +#include "libGLESv2/Query.h" + +#include "libGLESv2/main.h" + +namespace gl +{ + +Query::Query(GLuint id, GLenum type) : RefCountObject(id) +{ + mQuery = NULL; + mStatus = GL_FALSE; + mResult = GL_FALSE; + mType = type; +} + +Query::~Query() +{ + if (mQuery != NULL) + { + mQuery->Release(); + mQuery = NULL; + } +} + +void Query::begin() +{ + if (mQuery == NULL) + { + if (FAILED(getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) + { + return error(GL_OUT_OF_MEMORY); + } + } + + HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + ASSERT(SUCCEEDED(result)); +} + +void Query::end() +{ + if (mQuery == NULL) + { + return error(GL_INVALID_OPERATION); + } + + HRESULT result = mQuery->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + mStatus = GL_FALSE; + mResult = GL_FALSE; +} + +GLuint Query::getResult() +{ + if (mQuery != NULL) + { + while (!testQuery()) + { + Sleep(0); + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (gl::getDisplay()->testDeviceLost()) + { + gl::getDisplay()->notifyDeviceLost(); + return error(GL_OUT_OF_MEMORY, 0); + } + } + } + + return (GLuint)mResult; +} + +GLboolean Query::isResultAvailable() +{ + if (mQuery != NULL) + { + testQuery(); + } + + return mStatus; +} + +GLenum Query::getType() const +{ + return mType; +} + +GLboolean Query::testQuery() +{ + if (mQuery != NULL && mStatus != GL_TRUE) + { + DWORD numPixels = 0; + + HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); + if (hres == S_OK) + { + mStatus = GL_TRUE; + + switch (mType) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + break; + default: + ASSERT(false); + } + } + else if (checkDeviceLost(hres)) + { + return error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + return mStatus; + } + + return GL_TRUE; // prevent blocking when query is null +} +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Query.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Query.h new file mode 100644 index 0000000..79357a0 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Query.h @@ -0,0 +1,48 @@ +// +// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// Query.h: Defines the gl::Query class + +#ifndef LIBGLESV2_QUERY_H_ +#define LIBGLESV2_QUERY_H_ + +#define GL_APICALL +#include <GLES2/gl2.h> +#include <d3d9.h> + +#include "common/angleutils.h" +#include "common/RefCountObject.h" + +namespace gl +{ + +class Query : public RefCountObject +{ + public: + Query(GLuint id, GLenum type); + virtual ~Query(); + + void begin(); + void end(); + GLuint getResult(); + GLboolean isResultAvailable(); + + GLenum getType() const; + + private: + DISALLOW_COPY_AND_ASSIGN(Query); + + GLboolean testQuery(); + + IDirect3DQuery9* mQuery; + GLenum mType; + GLboolean mStatus; + GLint mResult; +}; + +} + +#endif // LIBGLESV2_QUERY_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp index 6e4494b..6004255 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.cpp @@ -18,137 +18,254 @@ namespace gl { unsigned int RenderbufferStorage::mCurrentSerial = 1; -Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id) +RenderbufferInterface::RenderbufferInterface() { - ASSERT(storage != NULL); - mStorage = storage; } -Renderbuffer::~Renderbuffer() +// The default case for classes inherited from RenderbufferInterface is not to +// need to do anything upon the reference count to the parent Renderbuffer incrementing +// or decrementing. +void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy) +{ +} + +void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy) +{ +} + +GLuint RenderbufferInterface::getRedSize() const +{ + return dx2es::GetRedSize(getD3DFormat()); +} + +GLuint RenderbufferInterface::getGreenSize() const +{ + return dx2es::GetGreenSize(getD3DFormat()); +} + +GLuint RenderbufferInterface::getBlueSize() const +{ + return dx2es::GetBlueSize(getD3DFormat()); +} + +GLuint RenderbufferInterface::getAlphaSize() const +{ + return dx2es::GetAlphaSize(getD3DFormat()); +} + +GLuint RenderbufferInterface::getDepthSize() const +{ + return dx2es::GetDepthSize(getD3DFormat()); +} + +GLuint RenderbufferInterface::getStencilSize() const +{ + return dx2es::GetStencilSize(getD3DFormat()); +} + +RenderbufferTexture::RenderbufferTexture(Texture *texture, GLenum target) : mTarget(target) +{ + mTexture.set(texture); +} + +RenderbufferTexture::~RenderbufferTexture() +{ + mTexture.set(NULL); +} + +// Textures need to maintain their own reference count for references via +// Renderbuffers acting as proxies. Here, we notify the texture of a reference. +void RenderbufferTexture::addProxyRef(const Renderbuffer *proxy) +{ + mTexture->addProxyRef(proxy); +} + +void RenderbufferTexture::releaseProxy(const Renderbuffer *proxy) +{ + mTexture->releaseProxy(proxy); +} + +IDirect3DSurface9 *RenderbufferTexture::getRenderTarget() +{ + return mTexture->getRenderTarget(mTarget); +} + +IDirect3DSurface9 *RenderbufferTexture::getDepthStencil() +{ + return NULL; +} + +GLsizei RenderbufferTexture::getWidth() const +{ + return mTexture->getWidth(0); +} + +GLsizei RenderbufferTexture::getHeight() const +{ + return mTexture->getHeight(0); +} + +GLenum RenderbufferTexture::getInternalFormat() const +{ + return mTexture->getInternalFormat(); +} + +D3DFORMAT RenderbufferTexture::getD3DFormat() const +{ + return mTexture->getD3DFormat(); +} + +GLsizei RenderbufferTexture::getSamples() const +{ + return 0; +} + +unsigned int RenderbufferTexture::getSerial() const +{ + return mTexture->getRenderTargetSerial(mTarget); +} + +Renderbuffer::Renderbuffer(GLuint id, RenderbufferInterface *instance) : RefCountObject(id) { - delete mStorage; + ASSERT(instance != NULL); + mInstance = instance; } -bool Renderbuffer::isColorbuffer() const +Renderbuffer::~Renderbuffer() { - return mStorage->isColorbuffer(); + delete mInstance; } -bool Renderbuffer::isDepthbuffer() const +// The RenderbufferInterface contained in this Renderbuffer may need to maintain +// its own reference count, so we pass it on here. +void Renderbuffer::addRef() const { - return mStorage->isDepthbuffer(); + mInstance->addProxyRef(this); + + RefCountObject::addRef(); } -bool Renderbuffer::isStencilbuffer() const +void Renderbuffer::release() const { - return mStorage->isStencilbuffer(); + mInstance->releaseProxy(this); + + RefCountObject::release(); } IDirect3DSurface9 *Renderbuffer::getRenderTarget() { - return mStorage->getRenderTarget(); + return mInstance->getRenderTarget(); } IDirect3DSurface9 *Renderbuffer::getDepthStencil() { - return mStorage->getDepthStencil(); + return mInstance->getDepthStencil(); } -int Renderbuffer::getWidth() const +GLsizei Renderbuffer::getWidth() const { - return mStorage->getWidth(); + return mInstance->getWidth(); } -int Renderbuffer::getHeight() const +GLsizei Renderbuffer::getHeight() const { - return mStorage->getHeight(); + return mInstance->getHeight(); } -GLenum Renderbuffer::getFormat() const +GLenum Renderbuffer::getInternalFormat() const { - return mStorage->getFormat(); + return mInstance->getInternalFormat(); } D3DFORMAT Renderbuffer::getD3DFormat() const { - return mStorage->getD3DFormat(); + return mInstance->getD3DFormat(); } -unsigned int Renderbuffer::getSerial() const +GLuint Renderbuffer::getRedSize() const { - return mStorage->getSerial(); + return mInstance->getRedSize(); } -void Renderbuffer::setStorage(RenderbufferStorage *newStorage) +GLuint Renderbuffer::getGreenSize() const { - ASSERT(newStorage != NULL); + return mInstance->getGreenSize(); +} - delete mStorage; - mStorage = newStorage; +GLuint Renderbuffer::getBlueSize() const +{ + return mInstance->getBlueSize(); } -RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) +GLuint Renderbuffer::getAlphaSize() const { - mWidth = 0; - mHeight = 0; - mFormat = GL_RGBA4; - mD3DFormat = D3DFMT_A8R8G8B8; - mSamples = 0; + return mInstance->getAlphaSize(); } -RenderbufferStorage::~RenderbufferStorage() +GLuint Renderbuffer::getDepthSize() const { + return mInstance->getDepthSize(); } -bool RenderbufferStorage::isColorbuffer() const +GLuint Renderbuffer::getStencilSize() const { - return false; + return mInstance->getStencilSize(); } -bool RenderbufferStorage::isDepthbuffer() const +GLsizei Renderbuffer::getSamples() const { - return false; + return mInstance->getSamples(); } -bool RenderbufferStorage::isStencilbuffer() const +unsigned int Renderbuffer::getSerial() const { - return false; + return mInstance->getSerial(); } -IDirect3DSurface9 *RenderbufferStorage::getRenderTarget() +void Renderbuffer::setStorage(RenderbufferStorage *newStorage) { - return NULL; + ASSERT(newStorage != NULL); + + delete mInstance; + mInstance = newStorage; } -IDirect3DSurface9 *RenderbufferStorage::getDepthStencil() +RenderbufferStorage::RenderbufferStorage() : mSerial(issueSerial()) { - return NULL; + mWidth = 0; + mHeight = 0; + mInternalFormat = GL_RGBA4; + mD3DFormat = D3DFMT_A8R8G8B8; + mSamples = 0; } -int RenderbufferStorage::getWidth() const +RenderbufferStorage::~RenderbufferStorage() { - return mWidth; } -int RenderbufferStorage::getHeight() const +IDirect3DSurface9 *RenderbufferStorage::getRenderTarget() { - return mHeight; + return NULL; } -void RenderbufferStorage::setSize(int width, int height) +IDirect3DSurface9 *RenderbufferStorage::getDepthStencil() { - mWidth = width; - mHeight = height; + return NULL; } -GLenum RenderbufferStorage::getFormat() const +GLsizei RenderbufferStorage::getWidth() const { - return mFormat; + return mWidth; } -bool RenderbufferStorage::isFloatingPoint() const +GLsizei RenderbufferStorage::getHeight() const { - return false; // no floating point renderbuffers + return mHeight; +} + +GLenum RenderbufferStorage::getInternalFormat() const +{ + return mInternalFormat; } D3DFORMAT RenderbufferStorage::getD3DFormat() const @@ -171,6 +288,13 @@ unsigned int RenderbufferStorage::issueSerial() return mCurrentSerial++; } +unsigned int RenderbufferStorage::issueCubeSerials() +{ + unsigned int firstSerial = mCurrentSerial; + mCurrentSerial += 6; + return firstSerial; +} + Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(renderTarget) { if (renderTarget) @@ -180,25 +304,18 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render D3DSURFACE_DESC description; renderTarget->GetDesc(&description); - setSize(description.Width, description.Height); - mFormat = dx2es::ConvertBackBufferFormat(description.Format); + mWidth = description.Width; + mHeight = description.Height; + mInternalFormat = dx2es::ConvertBackBufferFormat(description.Format); mD3DFormat = description.Format; - mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); + mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType); } } -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) +Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) : mRenderTarget(NULL) { IDirect3DDevice9 *device = getDevice(); - mRenderTarget = NULL; D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format); int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples); @@ -224,13 +341,11 @@ Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples) ASSERT(SUCCEEDED(result)); } - if (mRenderTarget) - { - setSize(width, height); - mFormat = format; - mD3DFormat = requestedFormat; - mSamples = supportedSamples; - } + mWidth = width; + mHeight = height; + mInternalFormat = format; + mD3DFormat = requestedFormat; + mSamples = supportedSamples; } Colorbuffer::~Colorbuffer() @@ -241,65 +356,13 @@ Colorbuffer::~Colorbuffer() } } -bool Colorbuffer::isColorbuffer() const -{ - return true; -} - -GLuint Colorbuffer::getRedSize() const -{ - if (mRenderTarget) - { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - return es2dx::GetRedSize(description.Format); - } - - return 0; -} - -GLuint Colorbuffer::getGreenSize() const -{ - if (mRenderTarget) - { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - return es2dx::GetGreenSize(description.Format); - } - - return 0; -} - -GLuint Colorbuffer::getBlueSize() const -{ - if (mRenderTarget) - { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - return es2dx::GetBlueSize(description.Format); - } - - return 0; -} - -GLuint Colorbuffer::getAlphaSize() const +IDirect3DSurface9 *Colorbuffer::getRenderTarget() { if (mRenderTarget) { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - return es2dx::GetAlphaSize(description.Format); + mRenderTarget->AddRef(); } - return 0; -} - -IDirect3DSurface9 *Colorbuffer::getRenderTarget() -{ return mRenderTarget; } @@ -312,9 +375,10 @@ DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepth D3DSURFACE_DESC description; depthStencil->GetDesc(&description); - setSize(description.Width, description.Height); - mFormat = dx2es::ConvertDepthStencilFormat(description.Format); - mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType); + mWidth = description.Width; + mHeight = description.Height; + mInternalFormat = dx2es::ConvertDepthStencilFormat(description.Format); + mSamples = dx2es::GetSamplesFromMultisampleType(description.MultiSampleType); mD3DFormat = description.Format; } } @@ -334,25 +398,26 @@ DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples) return; } - HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples), - 0, FALSE, &mDepthStencil, 0); - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + if (width > 0 && height > 0) { - error(GL_OUT_OF_MEMORY); + HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples), + 0, FALSE, &mDepthStencil, 0); - return; - } + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + error(GL_OUT_OF_MEMORY); - ASSERT(SUCCEEDED(result)); + return; + } - if (mDepthStencil) - { - setSize(width, height); - mFormat = GL_DEPTH24_STENCIL8_OES; - mD3DFormat = D3DFMT_D24S8; - mSamples = supportedSamples; + ASSERT(SUCCEEDED(result)); } + + mWidth = width; + mHeight = height; + mInternalFormat = GL_DEPTH24_STENCIL8_OES; + mD3DFormat = D3DFMT_D24S8; + mSamples = supportedSamples; } DepthStencilbuffer::~DepthStencilbuffer() @@ -363,42 +428,6 @@ DepthStencilbuffer::~DepthStencilbuffer() } } -bool DepthStencilbuffer::isDepthbuffer() const -{ - return true; -} - -bool DepthStencilbuffer::isStencilbuffer() const -{ - return true; -} - -GLuint DepthStencilbuffer::getDepthSize() const -{ - if (mDepthStencil) - { - D3DSURFACE_DESC description; - mDepthStencil->GetDesc(&description); - - return es2dx::GetDepthSize(description.Format); - } - - return 0; -} - -GLuint DepthStencilbuffer::getStencilSize() const -{ - if (mDepthStencil) - { - D3DSURFACE_DESC description; - mDepthStencil->GetDesc(&description); - - return es2dx::GetStencilSize(description.Format); - } - - return 0; -} - IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil() { return mDepthStencil; @@ -408,19 +437,19 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(d { if (depthStencil) { - mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage + mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage } } Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) { - if (getDepthStencil()) + if (mDepthStencil) { - mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage + mInternalFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage } } @@ -428,37 +457,23 @@ Depthbuffer::~Depthbuffer() { } -bool Depthbuffer::isDepthbuffer() const -{ - return true; -} - -bool Depthbuffer::isStencilbuffer() const -{ - return false; -} - Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil) { if (depthStencil) { - mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage - } - else - { - mFormat = GL_RGBA4; //default format + mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage } } Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples) { - if (getDepthStencil()) + if (mDepthStencil) { - mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function - // will expect one of the valid renderbuffer formats for use in - // glRenderbufferStorage + mInternalFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function + // will expect one of the valid renderbuffer formats for use in + // glRenderbufferStorage } } @@ -466,13 +481,4 @@ Stencilbuffer::~Stencilbuffer() { } -bool Stencilbuffer::isDepthbuffer() const -{ - return false; -} - -bool Stencilbuffer::isStencilbuffer() const -{ - return true; -} } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h index 98510c2..60ec058 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Renderbuffer.h @@ -17,143 +17,196 @@ #include <d3d9.h> #include "common/angleutils.h" -#include "libGLESv2/RefCountObject.h" +#include "common/RefCountObject.h" namespace gl { - class Texture; +class Texture; +class Renderbuffer; +class Colorbuffer; +class DepthStencilbuffer; + +class RenderbufferInterface +{ + public: + RenderbufferInterface(); + + virtual ~RenderbufferInterface() {}; + + virtual void addProxyRef(const Renderbuffer *proxy); + virtual void releaseProxy(const Renderbuffer *proxy); + + virtual IDirect3DSurface9 *getRenderTarget() = 0; + virtual IDirect3DSurface9 *getDepthStencil() = 0; + + virtual GLsizei getWidth() const = 0; + virtual GLsizei getHeight() const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual D3DFORMAT getD3DFormat() const = 0; + virtual GLsizei getSamples() const = 0; + + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + + virtual unsigned int getSerial() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferInterface); +}; + +class RenderbufferTexture : public RenderbufferInterface +{ + public: + RenderbufferTexture(Texture *texture, GLenum target); + + virtual ~RenderbufferTexture(); + + void addProxyRef(const Renderbuffer *proxy); + void releaseProxy(const Renderbuffer *proxy); + + IDirect3DSurface9 *getRenderTarget(); + IDirect3DSurface9 *getDepthStencil(); + + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual D3DFORMAT getD3DFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture); + + BindingPointer <Texture> mTexture; + GLenum mTarget; +}; // A class derived from RenderbufferStorage is created whenever glRenderbufferStorage // is called. The specific concrete type depends on whether the internal format is // colour depth, stencil or packed depth/stencil. -class RenderbufferStorage +class RenderbufferStorage : public RenderbufferInterface { public: RenderbufferStorage(); virtual ~RenderbufferStorage() = 0; - virtual bool isColorbuffer() const; - virtual bool isDepthbuffer() const; - virtual bool isStencilbuffer() const; - virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); - 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; + virtual GLsizei getWidth() const; + virtual GLsizei getHeight() const; + virtual GLenum getInternalFormat() const; + virtual D3DFORMAT getD3DFormat() const; + virtual GLsizei getSamples() const; + + virtual unsigned int getSerial() const; static unsigned int issueSerial(); + static unsigned int issueCubeSerials(); protected: - void setSize(int width, int height); - GLenum mFormat; + GLsizei mWidth; + GLsizei mHeight; + GLenum mInternalFormat; D3DFORMAT mD3DFormat; GLsizei mSamples; - const unsigned int mSerial; private: DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage); - static unsigned int mCurrentSerial; + const unsigned int mSerial; - int mWidth; - int mHeight; + static unsigned int mCurrentSerial; }; // Renderbuffer implements the GL renderbuffer object. -// It's only a wrapper for a RenderbufferStorage, but the internal object +// It's only a proxy for a RenderbufferInterface instance; the internal object // can change whenever glRenderbufferStorage is called. class Renderbuffer : public RefCountObject { public: - Renderbuffer(GLuint id, RenderbufferStorage *storage); + Renderbuffer(GLuint id, RenderbufferInterface *storage); - ~Renderbuffer(); + virtual ~Renderbuffer(); - bool isColorbuffer() const; - bool isDepthbuffer() const; - bool isStencilbuffer() const; + // These functions from RefCountObject are overloaded here because + // Textures need to maintain their own count of references to them via + // Renderbuffers/RenderbufferTextures. These functions invoke those + // reference counting functions on the RenderbufferInterface. + void addRef() const; + void release() const; IDirect3DSurface9 *getRenderTarget(); IDirect3DSurface9 *getDepthStencil(); - int getWidth() const; - int getHeight() const; - GLenum getFormat() const; + GLsizei getWidth() const; + GLsizei getHeight() const; + GLenum getInternalFormat() const; D3DFORMAT getD3DFormat() const; + GLuint getRedSize() const; + GLuint getGreenSize() const; + GLuint getBlueSize() const; + GLuint getAlphaSize() const; + GLuint getDepthSize() const; + GLuint getStencilSize() const; + GLsizei getSamples() const; + unsigned int getSerial() const; void setStorage(RenderbufferStorage *newStorage); - RenderbufferStorage *getStorage() { return mStorage; } private: DISALLOW_COPY_AND_ASSIGN(Renderbuffer); - RenderbufferStorage *mStorage; + RenderbufferInterface *mInstance; }; class Colorbuffer : public RenderbufferStorage { public: explicit Colorbuffer(IDirect3DSurface9 *renderTarget); - explicit Colorbuffer(const Texture* texture); - Colorbuffer(int width, int height, GLenum format, GLsizei samples); - - ~Colorbuffer(); - - bool isColorbuffer() const; - - GLuint getRedSize() const; - GLuint getGreenSize() const; - GLuint getBlueSize() const; - GLuint getAlphaSize() const; + Colorbuffer(GLsizei width, GLsizei height, GLenum format, GLsizei samples); - IDirect3DSurface9 *getRenderTarget(); + virtual ~Colorbuffer(); - protected: - IDirect3DSurface9 *mRenderTarget; + virtual IDirect3DSurface9 *getRenderTarget(); private: DISALLOW_COPY_AND_ASSIGN(Colorbuffer); + + IDirect3DSurface9 *mRenderTarget; }; class DepthStencilbuffer : public RenderbufferStorage { public: explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil); - DepthStencilbuffer(int width, int height, GLsizei samples); + DepthStencilbuffer(GLsizei width, GLsizei height, GLsizei samples); ~DepthStencilbuffer(); - virtual bool isDepthbuffer() const; - virtual bool isStencilbuffer() const; - - GLuint getDepthSize() const; - GLuint getStencilSize() const; + virtual IDirect3DSurface9 *getDepthStencil(); - IDirect3DSurface9 *getDepthStencil(); + protected: + IDirect3DSurface9 *mDepthStencil; private: DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer); - IDirect3DSurface9 *mDepthStencil; }; class Depthbuffer : public DepthStencilbuffer { public: explicit Depthbuffer(IDirect3DSurface9 *depthStencil); - Depthbuffer(int width, int height, GLsizei samples); + Depthbuffer(GLsizei width, GLsizei height, GLsizei samples); - ~Depthbuffer(); - - bool isDepthbuffer() const; - bool isStencilbuffer() const; + virtual ~Depthbuffer(); private: DISALLOW_COPY_AND_ASSIGN(Depthbuffer); @@ -163,12 +216,9 @@ class Stencilbuffer : public DepthStencilbuffer { public: explicit Stencilbuffer(IDirect3DSurface9 *depthStencil); - Stencilbuffer(int width, int height, GLsizei samples); - - ~Stencilbuffer(); + Stencilbuffer(GLsizei width, GLsizei height, GLsizei samples); - bool isDepthbuffer() const; - bool isStencilbuffer() const; + virtual ~Stencilbuffer(); private: DISALLOW_COPY_AND_ASSIGN(Stencilbuffer); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.cpp index 12a86c1..ae26352 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.cpp @@ -66,12 +66,7 @@ void ResourceManager::release() // Returns an unused buffer name GLuint ResourceManager::createBuffer() { - unsigned int handle = 1; - - while (mBufferMap.find(handle) != mBufferMap.end()) - { - handle++; - } + GLuint handle = mBufferHandleAllocator.allocate(); mBufferMap[handle] = NULL; @@ -81,12 +76,7 @@ GLuint ResourceManager::createBuffer() // Returns an unused shader/program name GLuint ResourceManager::createShader(GLenum type) { - unsigned int handle = 1; - - while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space - { - handle++; - } + GLuint handle = mProgramShaderHandleAllocator.allocate(); if (type == GL_VERTEX_SHADER) { @@ -104,12 +94,7 @@ GLuint ResourceManager::createShader(GLenum type) // Returns an unused program/shader name GLuint ResourceManager::createProgram() { - unsigned int handle = 1; - - while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space - { - handle++; - } + GLuint handle = mProgramShaderHandleAllocator.allocate(); mProgramMap[handle] = new Program(this, handle); @@ -119,12 +104,7 @@ GLuint ResourceManager::createProgram() // Returns an unused texture name GLuint ResourceManager::createTexture() { - unsigned int handle = 1; - - while (mTextureMap.find(handle) != mTextureMap.end()) - { - handle++; - } + GLuint handle = mTextureHandleAllocator.allocate(); mTextureMap[handle] = NULL; @@ -134,12 +114,7 @@ GLuint ResourceManager::createTexture() // Returns an unused renderbuffer name GLuint ResourceManager::createRenderbuffer() { - unsigned int handle = 1; - - while (mRenderbufferMap.find(handle) != mRenderbufferMap.end()) - { - handle++; - } + GLuint handle = mRenderbufferHandleAllocator.allocate(); mRenderbufferMap[handle] = NULL; @@ -152,6 +127,7 @@ void ResourceManager::deleteBuffer(GLuint buffer) if (bufferObject != mBufferMap.end()) { + mBufferHandleAllocator.release(bufferObject->first); if (bufferObject->second) bufferObject->second->release(); mBufferMap.erase(bufferObject); } @@ -165,6 +141,7 @@ void ResourceManager::deleteShader(GLuint shader) { if (shaderObject->second->getRefCount() == 0) { + mProgramShaderHandleAllocator.release(shaderObject->first); delete shaderObject->second; mShaderMap.erase(shaderObject); } @@ -183,6 +160,7 @@ void ResourceManager::deleteProgram(GLuint program) { if (programObject->second->getRefCount() == 0) { + mProgramShaderHandleAllocator.release(programObject->first); delete programObject->second; mProgramMap.erase(programObject); } @@ -199,6 +177,7 @@ void ResourceManager::deleteTexture(GLuint texture) if (textureObject != mTextureMap.end()) { + mTextureHandleAllocator.release(textureObject->first); if (textureObject->second) textureObject->second->release(); mTextureMap.erase(textureObject); } @@ -210,6 +189,7 @@ void ResourceManager::deleteRenderbuffer(GLuint renderbuffer) if (renderbufferObject != mRenderbufferMap.end()) { + mRenderbufferHandleAllocator.release(renderbufferObject->first); if (renderbufferObject->second) renderbufferObject->second->release(); mRenderbufferMap.erase(renderbufferObject); } @@ -302,17 +282,17 @@ void ResourceManager::checkBufferAllocation(unsigned int buffer) } } -void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type) +void ResourceManager::checkTextureAllocation(GLuint texture, TextureType type) { if (!getTexture(texture) && texture != 0) { Texture *textureObject; - if (type == SAMPLER_2D) + if (type == TEXTURE_2D) { textureObject = new Texture2D(texture); } - else if (type == SAMPLER_CUBE) + else if (type == TEXTURE_CUBE) { textureObject = new TextureCubeMap(texture); } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.h index 346e51f..5185fc9 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/ResourceManager.h @@ -13,9 +13,10 @@ #define GL_APICALL #include <GLES2/gl2.h> -#include <map> +#include <hash_map> #include "common/angleutils.h" +#include "libGLESv2/HandleAllocator.h" namespace gl { @@ -25,12 +26,19 @@ class Program; class Texture; class Renderbuffer; -enum SamplerType +enum TextureType { - SAMPLER_2D, - SAMPLER_CUBE, + TEXTURE_2D, + TEXTURE_CUBE, + + TEXTURE_TYPE_COUNT, + TEXTURE_UNKNOWN +}; - SAMPLER_TYPE_COUNT +enum SamplerType +{ + SAMPLER_PIXEL, + SAMPLER_VERTEX }; class ResourceManager @@ -63,7 +71,7 @@ class ResourceManager void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer); void checkBufferAllocation(unsigned int buffer); - void checkTextureAllocation(GLuint texture, SamplerType type); + void checkTextureAllocation(GLuint texture, TextureType type); void checkRenderbufferAllocation(GLuint renderbuffer); private: @@ -71,20 +79,24 @@ class ResourceManager std::size_t mRefCount; - typedef std::map<GLuint, Buffer*> BufferMap; + typedef stdext::hash_map<GLuint, Buffer*> BufferMap; BufferMap mBufferMap; + HandleAllocator mBufferHandleAllocator; - typedef std::map<GLuint, Shader*> ShaderMap; + typedef stdext::hash_map<GLuint, Shader*> ShaderMap; ShaderMap mShaderMap; - typedef std::map<GLuint, Program*> ProgramMap; + typedef stdext::hash_map<GLuint, Program*> ProgramMap; ProgramMap mProgramMap; + HandleAllocator mProgramShaderHandleAllocator; - typedef std::map<GLuint, Texture*> TextureMap; + typedef stdext::hash_map<GLuint, Texture*> TextureMap; TextureMap mTextureMap; + HandleAllocator mTextureHandleAllocator; - typedef std::map<GLuint, Renderbuffer*> RenderbufferMap; + typedef stdext::hash_map<GLuint, Renderbuffer*> RenderbufferMap; RenderbufferMap mRenderbufferMap; + HandleAllocator mRenderbufferHandleAllocator; }; } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp index 4c969d6..ac58abe 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -27,31 +27,8 @@ Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mReso mHlsl = NULL; mInfoLog = NULL; - // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) - if (!mFragmentCompiler) - { - int result = ShInitialize(); - - if (result) - { - ShBuiltInResources resources; - ShInitBuiltInResources(&resources); - Context *context = getContext(); - - resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; - resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_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 = context->getMaximumFragmentUniformVectors(); - resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; - resources.OES_standard_derivatives = 1; - - mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources); - mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources); - } - } + uncompile(); + initializeCompiler(); mRefCount = 0; mDeleteStatus = false; @@ -127,11 +104,8 @@ void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) if (mInfoLog) { - while (index < bufSize - 1 && index < (int)strlen(mInfoLog)) - { - infoLog[index] = mInfoLog[index]; - index++; - } + index = std::min(bufSize - 1, (int)strlen(mInfoLog)); + memcpy(infoLog, mInfoLog, index); } if (bufSize) @@ -157,22 +131,31 @@ int Shader::getSourceLength() const } } -void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source) +int Shader::getTranslatedSourceLength() const +{ + if (!mHlsl) + { + return 0; + } + else + { + return strlen(mHlsl) + 1; + } +} + +void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer) { int index = 0; - if (mSource) + if (source) { - while (index < bufSize - 1 && index < (int)strlen(mSource)) - { - source[index] = mSource[index]; - index++; - } + index = std::min(bufSize - 1, (int)strlen(source)); + memcpy(buffer, source, index); } if (bufSize) { - source[index] = '\0'; + buffer[index] = '\0'; } if (length) @@ -181,6 +164,16 @@ void Shader::getSource(GLsizei bufSize, GLsizei *length, char *source) } } +void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) +{ + getSourceImpl(mSource, bufSize, length, buffer); +} + +void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) +{ + getSourceImpl(mHlsl, bufSize, length, buffer); +} + bool Shader::isCompiled() { return mHlsl != NULL; @@ -221,6 +214,36 @@ void Shader::flagForDeletion() mDeleteStatus = true; } +// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) +void Shader::initializeCompiler() +{ + if (!mFragmentCompiler) + { + int result = ShInitialize(); + + if (result) + { + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + Context *context = getContext(); + + resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; + resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS; + resources.MaxVaryingVectors = context->getMaximumVaryingVectors(); + resources.MaxVertexTextureImageUnits = context->getMaximumVertexTextureImageUnits(); + resources.MaxCombinedTextureImageUnits = context->getMaximumCombinedTextureImageUnits(); + resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + resources.MaxFragmentUniformVectors = context->getMaximumFragmentUniformVectors(); + resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; + resources.OES_standard_derivatives = 1; + // resources.OES_EGL_image_external = getDisplay()->isD3d9ExDevice() ? 1 : 0; // TODO: commented out until the extension is actually supported. + + mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources); + mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, SH_HLSL_OUTPUT, &resources); + } + } +} + void Shader::releaseCompiler() { ShDestruct(mFragmentCompiler); @@ -259,7 +282,7 @@ void Shader::parseVaryings() *array = '\0'; } - varyings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL)); + mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL)); input = strstr(input, ";") + 2; } @@ -271,19 +294,60 @@ void Shader::parseVaryings() } } +// initialize/clean up previous state +void Shader::uncompile() +{ + // set by compileToHLSL + delete[] mHlsl; + mHlsl = NULL; + delete[] mInfoLog; + mInfoLog = NULL; + + // set by parseVaryings + mVaryings.clear(); + + mUsesFragCoord = false; + mUsesFrontFacing = false; + mUsesPointSize = false; + mUsesPointCoord = false; +} + void Shader::compileToHLSL(void *compiler) { - if (isCompiled() || !mSource) + // ensure we don't pass a NULL source to the compiler + char *source = "\0"; + if (mSource) { - return; + source = mSource; } - TRACE("\n%s", mSource); + // ensure the compiler is loaded + initializeCompiler(); - delete[] mInfoLog; - mInfoLog = NULL; + int compileOptions = SH_OBJECT_CODE; + std::string sourcePath; + if (perfActive()) + { + sourcePath = getTempPath(); + writeFile(sourcePath.c_str(), source, strlen(source)); + compileOptions |= SH_LINE_DIRECTIVES; + } + + int result; + if (sourcePath.empty()) + { + result = ShCompile(compiler, &source, 1, compileOptions); + } + else + { + const char* sourceStrings[2] = + { + sourcePath.c_str(), + source + }; - int result = ShCompile(compiler, &mSource, 1, SH_OBJECT_CODE); + result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH); + } if (result) { @@ -291,8 +355,6 @@ void Shader::compileToHLSL(void *compiler) ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen); mHlsl = new char[objCodeLen]; ShGetObjectCode(compiler, mHlsl); - - TRACE("\n%s", mHlsl); } else { @@ -436,8 +498,18 @@ GLenum VertexShader::getType() return GL_VERTEX_SHADER; } +void VertexShader::uncompile() +{ + Shader::uncompile(); + + // set by ParseAttributes + mAttributes.clear(); +}; + void VertexShader::compile() { + uncompile(); + compileToHLSL(mVertexCompiler); parseAttributes(); parseVaryings(); @@ -464,9 +536,10 @@ int VertexShader::getSemanticIndex(const std::string &attributeName) void VertexShader::parseAttributes() { - if (mHlsl) + const char *hlsl = getHLSL(); + if (hlsl) { - const char *input = strstr(mHlsl, "// Attributes") + 14; + const char *input = strstr(hlsl, "// Attributes") + 14; while(true) { @@ -502,8 +575,10 @@ GLenum FragmentShader::getType() void FragmentShader::compile() { + uncompile(); + compileToHLSL(mFragmentCompiler); parseVaryings(); - varyings.sort(compareVarying); + mVaryings.sort(compareVarying); } } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h index 5eaa053..9c7c0df 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Shader.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -57,9 +57,12 @@ class Shader int getInfoLogLength() const; void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); int getSourceLength() const; - void getSource(GLsizei bufSize, GLsizei *length, char *source); + void getSource(GLsizei bufSize, GLsizei *length, char *buffer); + int getTranslatedSourceLength() const; + void getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer); virtual void compile() = 0; + virtual void uncompile(); bool isCompiled(); const char *getHLSL(); @@ -72,15 +75,30 @@ class Shader static void releaseCompiler(); protected: - DISALLOW_COPY_AND_ASSIGN(Shader); - void parseVaryings(); void compileToHLSL(void *compiler); + void getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer); + static GLenum parseType(const std::string &type); static bool compareVarying(const Varying &x, const Varying &y); + VaryingList mVaryings; + + bool mUsesFragCoord; + bool mUsesFrontFacing; + bool mUsesPointSize; + bool mUsesPointCoord; + + static void *mFragmentCompiler; + static void *mVertexCompiler; + + private: + DISALLOW_COPY_AND_ASSIGN(Shader); + + void initializeCompiler(); + const GLuint mHandle; unsigned int mRefCount; // Number of program objects this shader is attached to bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use @@ -89,17 +107,7 @@ class Shader char *mHlsl; char *mInfoLog; - VaryingList varyings; - - bool mUsesFragCoord; - bool mUsesFrontFacing; - bool mUsesPointSize; - bool mUsesPointCoord; - ResourceManager *mResourceManager; - - static void *mFragmentCompiler; - static void *mVertexCompiler; }; struct Attribute @@ -127,8 +135,9 @@ class VertexShader : public Shader ~VertexShader(); - GLenum getType(); - void compile(); + virtual GLenum getType(); + virtual void compile(); + virtual void uncompile(); int getSemanticIndex(const std::string &attributeName); private: @@ -146,8 +155,8 @@ class FragmentShader : public Shader ~FragmentShader(); - GLenum getType(); - void compile(); + virtual GLenum getType(); + virtual void compile(); private: DISALLOW_COPY_AND_ASSIGN(FragmentShader); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp index 7c040f8..29177d2 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.cpp @@ -13,334 +13,384 @@ #include <d3dx9tex.h> #include <algorithm> +#include <intrin.h> #include "common/debug.h" +#include "libEGL/Display.h" + #include "libGLESv2/main.h" #include "libGLESv2/mathutil.h" #include "libGLESv2/utilities.h" #include "libGLESv2/Blit.h" +#include "libGLESv2/Framebuffer.h" namespace gl { +unsigned int TextureStorage::mCurrentTextureSerial = 1; -Texture::Image::Image() - : width(0), height(0), dirty(false), surface(NULL), format(GL_NONE) +static D3DFORMAT ConvertTextureFormatType(GLenum format, GLenum type) { + if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || + format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + { + return D3DFMT_DXT1; + } + else if (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE) + { + return D3DFMT_DXT3; + } + else if (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE) + { + return D3DFMT_DXT5; + } + 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; + } + + return D3DFMT_A8R8G8B8; } -Texture::Image::~Image() +static bool IsTextureFormatRenderable(D3DFORMAT format) { - if (surface) surface->Release(); + switch(format) + { + case D3DFMT_L8: + case D3DFMT_A8L8: + case D3DFMT_DXT1: + case D3DFMT_DXT3: + case D3DFMT_DXT5: + return false; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + return true; + default: + UNREACHABLE(); + } + + return false; } -Texture::Texture(GLuint id) : RefCountObject(id) +Image::Image() { - mMinFilter = GL_NEAREST_MIPMAP_LINEAR; - mMagFilter = GL_LINEAR; - mWrapS = GL_REPEAT; - mWrapT = GL_REPEAT; - - mWidth = 0; + mWidth = 0; mHeight = 0; - - mDirtyMetaData = true; - mDirty = true; - mIsRenderable = false; + mFormat = GL_NONE; mType = GL_UNSIGNED_BYTE; - mBaseTexture = NULL; -} -Texture::~Texture() -{ -} + mSurface = NULL; -Blit *Texture::getBlitter() -{ - Context *context = getContext(); - return context->getBlitter(); + mDirty = false; + + mD3DPool = D3DPOOL_SYSTEMMEM; + mD3DFormat = D3DFMT_UNKNOWN; } -// Returns true on successful filter state update (valid enum parameter) -bool Texture::setMinFilter(GLenum filter) +Image::~Image() { - switch (filter) + if (mSurface) { - case GL_NEAREST: - case GL_LINEAR: - case GL_NEAREST_MIPMAP_NEAREST: - case GL_LINEAR_MIPMAP_NEAREST: - case GL_NEAREST_MIPMAP_LINEAR: - case GL_LINEAR_MIPMAP_LINEAR: - { - if (mMinFilter != filter) - { - mMinFilter = filter; - mDirty = true; - } - return true; - } - default: - return false; + mSurface->Release(); } } -// Returns true on successful filter state update (valid enum parameter) -bool Texture::setMagFilter(GLenum filter) +bool Image::redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease) { - switch (filter) + if (mWidth != width || + mHeight != height || + mFormat != format || + mType != type || + forceRelease) { - case GL_NEAREST: - case GL_LINEAR: + mWidth = width; + mHeight = height; + mFormat = format; + mType = type; + // compute the d3d format that will be used + mD3DFormat = ConvertTextureFormatType(mFormat, mType); + + if (mSurface) { - if (mMagFilter != filter) - { - mMagFilter = filter; - mDirty = true; - } - return true; + mSurface->Release(); + mSurface = NULL; } - default: - return false; + + return true; } + + return false; } -// Returns true on successful wrap state update (valid enum parameter) -bool Texture::setWrapS(GLenum wrap) +void Image::createSurface() { - switch (wrap) + if(mSurface) { - case GL_REPEAT: - case GL_CLAMP_TO_EDGE: - case GL_MIRRORED_REPEAT: - { - if (mWrapS != wrap) - { - mWrapS = wrap; - mDirty = true; - } - return true; - } - default: - return false; + return; } -} -// Returns true on successful wrap state update (valid enum parameter) -bool Texture::setWrapT(GLenum wrap) -{ - switch (wrap) + IDirect3DTexture9 *newTexture = NULL; + IDirect3DSurface9 *newSurface = NULL; + const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; + + if (mWidth != 0 && mHeight != 0) { - case GL_REPEAT: - case GL_CLAMP_TO_EDGE: - case GL_MIRRORED_REPEAT: + int levelToFetch = 0; + GLsizei requestWidth = mWidth; + GLsizei requestHeight = mHeight; + if (IsCompressed(mFormat) && (mWidth % 4 != 0 || mHeight % 4 != 0)) { - if (mWrapT != wrap) + bool isMult4 = false; + int upsampleCount = 0; + while (!isMult4) { - mWrapT = wrap; - mDirty = true; + requestWidth <<= 1; + requestHeight <<= 1; + upsampleCount++; + if (requestWidth % 4 == 0 && requestHeight % 4 == 0) + { + isMult4 = true; + } } - return true; + levelToFetch = upsampleCount; } - default: - return false; + + HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, getD3DFormat(), + poolToUse, &newTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + ERR("Creating image surface failed."); + return error(GL_OUT_OF_MEMORY); + } + + newTexture->GetSurfaceLevel(levelToFetch, &newSurface); + newTexture->Release(); } -} -GLenum Texture::getMinFilter() const -{ - return mMinFilter; + mSurface = newSurface; + mDirty = false; + mD3DPool = poolToUse; } -GLenum Texture::getMagFilter() const +HRESULT Image::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect) { - return mMagFilter; -} + createSurface(); -GLenum Texture::getWrapS() const -{ - return mWrapS; + HRESULT result = D3DERR_INVALIDCALL; + + if (mSurface) + { + result = mSurface->LockRect(lockedRect, rect, 0); + ASSERT(SUCCEEDED(result)); + + mDirty = true; + } + + return result; } -GLenum Texture::getWrapT() const +void Image::unlock() { - return mWrapT; + if (mSurface) + { + HRESULT result = mSurface->UnlockRect(); + ASSERT(SUCCEEDED(result)); + } } -GLuint Texture::getWidth() const -{ - return mWidth; +bool Image::isRenderableFormat() const +{ + return IsTextureFormatRenderable(getD3DFormat()); } -GLuint Texture::getHeight() const +D3DFORMAT Image::getD3DFormat() const { - return mHeight; + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mD3DFormat != D3DFMT_UNKNOWN); + + return mD3DFormat; } -bool Texture::isFloatingPoint() const +IDirect3DSurface9 *Image::getSurface() { - return (mType == GL_FLOAT || mType == GL_HALF_FLOAT_OES); + createSurface(); + + return mSurface; } -bool Texture::isRenderableFormat() const +void Image::setManagedSurface(IDirect3DSurface9 *surface) { - D3DFORMAT format = getD3DFormat(); - - switch(format) + if (mSurface) { - 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(); + D3DXLoadSurfaceFromSurface(surface, NULL, NULL, mSurface, NULL, NULL, D3DX_FILTER_BOX, 0); + mSurface->Release(); } - return false; + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + ASSERT(desc.Pool == D3DPOOL_MANAGED); + + mSurface = surface; + mD3DPool = desc.Pool; } -// Selects an internal Direct3D 9 format for storing an Image -D3DFORMAT Texture::selectFormat(GLenum format, GLenum type) +void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) - { - return D3DFMT_DXT1; - } - else if (type == GL_FLOAT) - { - return D3DFMT_A32B32G32R32F; - } - else if (type == GL_HALF_FLOAT_OES) - { - return D3DFMT_A16B16G16R16F; - } - else if (type == GL_UNSIGNED_BYTE) + IDirect3DSurface9 *sourceSurface = getSurface(); + + if (sourceSurface != destSurface) { - if (format == GL_LUMINANCE && getContext()->supportsLuminanceTextures()) - { - return D3DFMT_L8; - } - else if (format == GL_LUMINANCE_ALPHA && getContext()->supportsLuminanceAlphaTextures()) + RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight); + + if (mD3DPool == D3DPOOL_MANAGED) { - return D3DFMT_A8L8; + HRESULT result = D3DXLoadSurfaceFromSurface(destSurface, NULL, &rect, sourceSurface, NULL, &rect, D3DX_FILTER_BOX, 0); + ASSERT(SUCCEEDED(result)); } - else if (format == GL_RGB) + else { - return D3DFMT_X8R8G8B8; + // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + POINT point = {rect.left, rect.top}; + HRESULT result = getDevice()->UpdateSurface(sourceSurface, &rect, destSurface, &point); + ASSERT(SUCCEEDED(result)); } - - return D3DFMT_A8R8G8B8; } - - return D3DFMT_A8R8G8B8; } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // 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, D3DSURFACE_DESC *description) const +void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, + GLint unpackAlignment, const void *input, size_t outputPitch, void *output) const { - GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment); + GLsizei inputPitch = -ComputePitch(width, mFormat, type, unpackAlignment); + input = ((char*)input) - inputPitch * (height - 1); switch (type) { case GL_UNSIGNED_BYTE: - switch (format) + switch (mFormat) { case GL_ALPHA: - loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadAlphaData(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); + loadLuminanceData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_L8); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, description->Format == D3DFMT_A8L8); + loadLuminanceAlphaData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output, getD3DFormat() == D3DFMT_A8L8); break; case GL_RGB: - loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_RGBA: - loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + if (supportsSSE2()) + { + loadRGBAUByteDataSSE2(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + } + else + { + loadRGBAUByteData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + } break; case GL_BGRA_EXT: - loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadBGRAData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } break; case GL_UNSIGNED_SHORT_5_6_5: - switch (format) + switch (mFormat) { case GL_RGB: - loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGB565Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } break; case GL_UNSIGNED_SHORT_4_4_4_4: - switch (format) + switch (mFormat) { case GL_RGBA: - loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBA4444Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } break; case GL_UNSIGNED_SHORT_5_5_5_1: - switch (format) + switch (mFormat) { case GL_RGBA: - loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBA5551Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } break; case GL_FLOAT: - switch (format) + switch (mFormat) { // 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); + loadAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_LUMINANCE: - loadLuminanceFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceAlphaFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_RGB: - loadRGBFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_RGBA: - loadRGBAFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } break; case GL_HALF_FLOAT_OES: - switch (format) + switch (mFormat) { // 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); + loadAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_LUMINANCE: - loadLuminanceHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_LUMINANCE_ALPHA: - loadLuminanceAlphaHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadLuminanceAlphaHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_RGB: - loadRGBHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; case GL_RGBA: - loadRGBAHalfFloatImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + loadRGBAHalfFloatData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); break; default: UNREACHABLE(); } @@ -349,8 +399,8 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei } } -void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; unsigned char *dest = NULL; @@ -369,8 +419,8 @@ 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 +void Image::loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; float *dest = NULL; @@ -389,8 +439,8 @@ void Texture::loadAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei widt } } -void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned short *dest = NULL; @@ -409,8 +459,8 @@ void Texture::loadAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei } } -void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const +void Image::loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const { const int destBytesPerPixel = native? 1: 4; const unsigned char *source = NULL; @@ -438,8 +488,8 @@ void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width } } -void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; float *dest = NULL; @@ -458,8 +508,8 @@ void Texture::loadLuminanceFloatImageData(GLint xoffset, GLint yoffset, GLsizei } } -void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned short *dest = NULL; @@ -478,8 +528,8 @@ void Texture::loadLuminanceHalfFloatImageData(GLint xoffset, GLint yoffset, GLsi } } -void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output, bool native) const +void Image::loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const { const int destBytesPerPixel = native? 2: 4; const unsigned char *source = NULL; @@ -507,8 +557,8 @@ void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei } } -void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; float *dest = NULL; @@ -527,8 +577,8 @@ void Texture::loadLuminanceAlphaFloatImageData(GLint xoffset, GLint yoffset, GLs } } -void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned short *dest = NULL; @@ -547,8 +597,8 @@ void Texture::loadLuminanceAlphaHalfFloatImageData(GLint xoffset, GLint yoffset, } } -void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; unsigned char *dest = NULL; @@ -567,8 +617,8 @@ void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned char *dest = NULL; @@ -588,8 +638,8 @@ 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 +void Image::loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; float *dest = NULL; @@ -608,8 +658,8 @@ void Texture::loadRGBFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned short *dest = NULL; @@ -628,28 +678,68 @@ void Texture::loadRGBHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei wi } } -void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { - const unsigned char *source = NULL; - unsigned char *dest = NULL; + const unsigned int *source = NULL; + unsigned int *dest = NULL; + __m128i brMask = _mm_set1_epi32(0x00ff00ff); 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; + source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4); + int x = 0; + + // Make output writes aligned + for (x = 0; ((reinterpret_cast<intptr_t>(&dest[x]) & 15) != 0) && x < width; x++) + { + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + + for (; x + 3 < width; x += 4) + { + __m128i sourceData = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&source[x])); + // Mask out g and a, which don't change + __m128i gaComponents = _mm_andnot_si128(brMask, sourceData); + // Mask out b and r + __m128i brComponents = _mm_and_si128(sourceData, brMask); + // Swap b and r + __m128i brSwapped = _mm_shufflehi_epi16(_mm_shufflelo_epi16(brComponents, _MM_SHUFFLE(2, 3, 0, 1)), _MM_SHUFFLE(2, 3, 0, 1)); + __m128i result = _mm_or_si128(gaComponents, brSwapped); + _mm_store_si128(reinterpret_cast<__m128i*>(&dest[x]), result); + } + + // Perform leftover writes + for (; x < width; x++) + { + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); + } + } +} + +void Image::loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const +{ + const unsigned int *source = NULL; + unsigned int *dest = NULL; + for (int y = 0; y < height; y++) + { + source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); + dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4); + for (int x = 0; x < width; x++) { - dest[4 * x + 0] = source[x * 4 + 2]; - dest[4 * x + 1] = source[x * 4 + 1]; - dest[4 * x + 2] = source[x * 4 + 0]; - dest[4 * x + 3] = source[x * 4 + 3]; + unsigned int rgba = source[x]; + dest[x] = (_rotl(rgba, 16) & 0x00ff00ff) | (rgba & 0xff00ff00); } } } -void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned char *dest = NULL; @@ -669,8 +759,8 @@ void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, } } -void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned short *source = NULL; unsigned char *dest = NULL; @@ -690,8 +780,8 @@ 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 +void Image::loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const float *source = NULL; float *dest = NULL; @@ -704,8 +794,8 @@ void Texture::loadRGBAFloatImageData(GLint xoffset, GLint yoffset, GLsizei width } } -void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; unsigned char *dest = NULL; @@ -718,8 +808,8 @@ void Texture::loadRGBAHalfFloatImageData(GLint xoffset, GLint yoffset, GLsizei w } } -void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - size_t inputPitch, const void *input, size_t outputPitch, void *output) const +void Image::loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { const unsigned char *source = NULL; unsigned char *dest = NULL; @@ -732,158 +822,718 @@ void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLs } } -void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, GLenum type, Image *img) +void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { + switch (getD3DFormat()) + { + case D3DFMT_DXT1: + loadDXT1Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + break; + case D3DFMT_DXT3: + loadDXT3Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + break; + case D3DFMT_DXT5: + loadDXT5Data(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output); + break; + } +} + +static void FlipCopyDXT1BlockFull(const unsigned int* source, unsigned int* dest) { + // A DXT1 block layout is: + // [0-1] color0. + // [2-3] color1. + // [4-7] color bitmap, 2 bits per pixel. + // So each of the 4-7 bytes represents one line, flipping a block is just + // flipping those bytes. + + // First 32-bits is two RGB565 colors shared by tile and does not need to be modified. + dest[0] = source[0]; + + // Second 32-bits contains 4 rows of 4 2-bit interpolants between the colors. All rows should be flipped. + dest[1] = (source[1] >> 24) | + ((source[1] << 8) & 0x00FF0000) | + ((source[1] >> 8) & 0x0000FF00) | + (source[1] << 24); +} + +// Flips the first 2 lines of a DXT1 block in the y direction. +static void FlipCopyDXT1BlockHalf(const unsigned int* source, unsigned int* dest) { + // See layout above. + dest[0] = source[0]; + dest[1] = ((source[1] << 8) & 0x0000FF00) | + ((source[1] >> 8) & 0x000000FF); +} + +// Flips a full DXT3 block in the y direction. +static void FlipCopyDXT3BlockFull(const unsigned int* source, unsigned int* dest) { + // A DXT3 block layout is: + // [0-7] alpha bitmap, 4 bits per pixel. + // [8-15] a DXT1 block. + + // First and Second 32 bits are 4bit per pixel alpha and need to be flipped. + dest[0] = (source[1] >> 16) | (source[1] << 16); + dest[1] = (source[0] >> 16) | (source[0] << 16); + + // And flip the DXT1 block using the above function. + FlipCopyDXT1BlockFull(source + 2, dest + 2); +} + +// Flips the first 2 lines of a DXT3 block in the y direction. +static void FlipCopyDXT3BlockHalf(const unsigned int* source, unsigned int* dest) { + // See layout above. + dest[0] = (source[1] >> 16) | (source[1] << 16); + FlipCopyDXT1BlockHalf(source + 2, dest + 2); +} + +// Flips a full DXT5 block in the y direction. +static void FlipCopyDXT5BlockFull(const unsigned int* source, unsigned int* dest) { + // A DXT5 block layout is: + // [0] alpha0. + // [1] alpha1. + // [2-7] alpha bitmap, 3 bits per pixel. + // [8-15] a DXT1 block. + + // The alpha bitmap doesn't easily map lines to bytes, so we have to + // interpret it correctly. Extracted from + // http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt : + // + // The 6 "bits" bytes of the block are decoded into one 48-bit integer: + // + // bits = bits_0 + 256 * (bits_1 + 256 * (bits_2 + 256 * (bits_3 + + // 256 * (bits_4 + 256 * bits_5)))) + // + // bits is a 48-bit unsigned integer, from which a three-bit control code + // is extracted for a texel at location (x,y) in the block using: + // + // code(x,y) = bits[3*(4*y+x)+1..3*(4*y+x)+0] + // + // where bit 47 is the most significant and bit 0 is the least + // significant bit. + const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source)); + unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest)); + unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]); + unsigned int line_2_3 = sourceBytes[5] + 256 * (sourceBytes[6] + 256 * sourceBytes[7]); + // swap lines 0 and 1 in line_0_1. + unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | + ((line_0_1 & 0xfff000) >> 12); + // swap lines 2 and 3 in line_2_3. + unsigned int line_3_2 = ((line_2_3 & 0x000fff) << 12) | + ((line_2_3 & 0xfff000) >> 12); + destBytes[0] = sourceBytes[0]; + destBytes[1] = sourceBytes[1]; + destBytes[2] = line_3_2 & 0xff; + destBytes[3] = (line_3_2 & 0xff00) >> 8; + destBytes[4] = (line_3_2 & 0xff0000) >> 16; + destBytes[5] = line_1_0 & 0xff; + destBytes[6] = (line_1_0 & 0xff00) >> 8; + destBytes[7] = (line_1_0 & 0xff0000) >> 16; + + // And flip the DXT1 block using the above function. + FlipCopyDXT1BlockFull(source + 2, dest + 2); +} + +// Flips the first 2 lines of a DXT5 block in the y direction. +static void FlipCopyDXT5BlockHalf(const unsigned int* source, unsigned int* dest) { + // See layout above. + const unsigned char* sourceBytes = static_cast<const unsigned char*>(static_cast<const void*>(source)); + unsigned char* destBytes = static_cast<unsigned char*>(static_cast<void*>(dest)); + unsigned int line_0_1 = sourceBytes[2] + 256 * (sourceBytes[3] + 256 * sourceBytes[4]); + unsigned int line_1_0 = ((line_0_1 & 0x000fff) << 12) | + ((line_0_1 & 0xfff000) >> 12); + destBytes[0] = sourceBytes[0]; + destBytes[1] = sourceBytes[1]; + destBytes[2] = line_1_0 & 0xff; + destBytes[3] = (line_1_0 & 0xff00) >> 8; + destBytes[4] = (line_1_0 & 0xff0000) >> 16; + FlipCopyDXT1BlockHalf(source + 2, dest + 2); +} + +void Image::loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const +{ + ASSERT(xoffset % 4 == 0); + ASSERT(yoffset % 4 == 0); + ASSERT(width % 4 == 0 || width == 2 || width == 1); + ASSERT(inputPitch % 8 == 0); + ASSERT(outputPitch % 8 == 0); + + const unsigned int *source = reinterpret_cast<const unsigned int*>(input); + unsigned int *dest = reinterpret_cast<unsigned int*>(output); + + // Round width up in case it is less than 4. + int blocksAcross = (width + 3) / 4; + int intsAcross = blocksAcross * 2; + + switch (height) + { + case 1: + for (int x = 0; x < intsAcross; x += 2) + { + // just copy the block + dest[x] = source[x]; + dest[x + 1] = source[x + 1]; + } + break; + case 2: + for (int x = 0; x < intsAcross; x += 2) + { + FlipCopyDXT1BlockHalf(source + x, dest + x); + } + break; + default: + ASSERT(height % 4 == 0); + for (int y = 0; y < height / 4; ++y) + { + const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); + unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 8); + + for (int x = 0; x < intsAcross; x += 2) + { + FlipCopyDXT1BlockFull(source + x, dest + x); + } + } + break; + } +} + +void Image::loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const { - IDirect3DTexture9 *newTexture = NULL; - IDirect3DSurface9 *newSurface = NULL; + ASSERT(xoffset % 4 == 0); + ASSERT(yoffset % 4 == 0); + ASSERT(width % 4 == 0 || width == 2 || width == 1); + ASSERT(inputPitch % 16 == 0); + ASSERT(outputPitch % 16 == 0); + + const unsigned int *source = reinterpret_cast<const unsigned int*>(input); + unsigned int *dest = reinterpret_cast<unsigned int*>(output); + + // Round width up in case it is less than 4. + int blocksAcross = (width + 3) / 4; + int intsAcross = blocksAcross * 4; - if (width != 0 && height != 0) + switch (height) { - int levelToFetch = 0; - GLsizei requestWidth = width; - GLsizei requestHeight = height; - if (IsCompressed(format) && (width % 4 != 0 || height % 4 != 0)) - { - bool isMult4 = false; - int upsampleCount = 0; - while (!isMult4) + case 1: + for (int x = 0; x < intsAcross; x += 4) { - requestWidth <<= 1; - requestHeight <<= 1; - upsampleCount++; - if (requestWidth % 4 == 0 && requestHeight % 4 == 0) + // just copy the block + dest[x] = source[x]; + dest[x + 1] = source[x + 1]; + dest[x + 2] = source[x + 2]; + dest[x + 3] = source[x + 3]; + } + break; + case 2: + for (int x = 0; x < intsAcross; x += 4) + { + FlipCopyDXT3BlockHalf(source + x, dest + x); + } + break; + default: + ASSERT(height % 4 == 0); + for (int y = 0; y < height / 4; ++y) + { + const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); + unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + + for (int x = 0; x < intsAcross; x += 4) { - isMult4 = true; + FlipCopyDXT3BlockFull(source + x, dest + x); } } - levelToFetch = upsampleCount; + break; + } +} + +void Image::loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const +{ + ASSERT(xoffset % 4 == 0); + ASSERT(yoffset % 4 == 0); + ASSERT(width % 4 == 0 || width == 2 || width == 1); + ASSERT(inputPitch % 16 == 0); + ASSERT(outputPitch % 16 == 0); + + const unsigned int *source = reinterpret_cast<const unsigned int*>(input); + unsigned int *dest = reinterpret_cast<unsigned int*>(output); + + // Round width up in case it is less than 4. + int blocksAcross = (width + 3) / 4; + int intsAcross = blocksAcross * 4; + + switch (height) + { + case 1: + for (int x = 0; x < intsAcross; x += 4) + { + // just copy the block + dest[x] = source[x]; + dest[x + 1] = source[x + 1]; + dest[x + 2] = source[x + 2]; + dest[x + 3] = source[x + 3]; + } + break; + case 2: + for (int x = 0; x < intsAcross; x += 4) + { + FlipCopyDXT5BlockHalf(source + x, dest + x); + } + break; + default: + ASSERT(height % 4 == 0); + for (int y = 0; y < height / 4; ++y) + { + const unsigned int *source = reinterpret_cast<const unsigned int*>(static_cast<const unsigned char*>(input) + y * inputPitch); + unsigned int *dest = reinterpret_cast<unsigned int*>(static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 16); + + for (int x = 0; x < intsAcross; x += 4) + { + FlipCopyDXT5BlockFull(source + x, dest + x); + } + } + break; + } +} + +// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures +void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget) +{ + IDirect3DDevice9 *device = getDevice(); + IDirect3DSurface9 *renderTargetData = NULL; + D3DSURFACE_DESC description; + renderTarget->GetDesc(&description); + + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); + + if (FAILED(result)) + { + ERR("Could not create matching destination surface."); + return error(GL_OUT_OF_MEMORY); + } + + result = device->GetRenderTargetData(renderTarget, renderTargetData); + + if (FAILED(result)) + { + ERR("GetRenderTargetData unexpectedly failed."); + renderTargetData->Release(); + return error(GL_OUT_OF_MEMORY); + } + + RECT sourceRect = transformPixelRect(x, y, width, height, description.Height); + int destYOffset = transformPixelYOffset(yoffset, height, mHeight); + RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height}; + + if (isRenderableFormat()) + { + result = D3DXLoadSurfaceFromSurface(getSurface(), NULL, &destRect, renderTargetData, NULL, &sourceRect, D3DX_FILTER_BOX, 0); + + if (FAILED(result)) + { + ERR("Copying surfaces unexpectedly failed."); + renderTargetData->Release(); + return error(GL_OUT_OF_MEMORY); } + } + else + { + D3DLOCKED_RECT sourceLock = {0}; + result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0); - HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format, type), - D3DPOOL_SYSTEMMEM, &newTexture, NULL); + if (FAILED(result)) + { + ERR("Failed to lock the source surface (rectangle might be invalid)."); + renderTargetData->Release(); + return error(GL_OUT_OF_MEMORY); + } + D3DLOCKED_RECT destLock = {0}; + result = lock(&destLock, &destRect); + if (FAILED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + ERR("Failed to lock the destination surface (rectangle might be invalid)."); + renderTargetData->UnlockRect(); + renderTargetData->Release(); return error(GL_OUT_OF_MEMORY); } - newTexture->GetSurfaceLevel(levelToFetch, &newSurface); - newTexture->Release(); + 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(); + } + } + + unlock(); + renderTargetData->UnlockRect(); } - if (img->surface) img->surface->Release(); - img->surface = newSurface; + renderTargetData->Release(); + + mDirty = true; +} + +TextureStorage::TextureStorage(bool renderTarget) + : mRenderTarget(renderTarget), + mD3DPool(getDisplay()->getTexturePool(mRenderTarget)), + mTextureSerial(issueTextureSerial()) +{ +} + +TextureStorage::~TextureStorage() +{ +} + +bool TextureStorage::isRenderTarget() const +{ + return mRenderTarget; +} + +bool TextureStorage::isManaged() const +{ + return (mD3DPool == D3DPOOL_MANAGED); +} + +D3DPOOL TextureStorage::getPool() const +{ + return mD3DPool; +} - img->width = width; - img->height = height; - img->format = format; +unsigned int TextureStorage::getTextureSerial() const +{ + return mTextureSerial; } -void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img) +unsigned int TextureStorage::issueTextureSerial() { - createSurface(width, height, format, type, img); + return mCurrentTextureSerial++; +} - if (pixels != NULL && img->surface != NULL) +Texture::Texture(GLuint id) : RefCountObject(id) +{ + mMinFilter = GL_NEAREST_MIPMAP_LINEAR; + mMagFilter = GL_LINEAR; + mWrapS = GL_REPEAT; + mWrapT = GL_REPEAT; + mDirtyParameters = true; + mUsage = GL_NONE; + + mDirtyImages = true; + + mImmutable = false; +} + +Texture::~Texture() +{ +} + +// Returns true on successful filter state update (valid enum parameter) +bool Texture::setMinFilter(GLenum filter) +{ + switch (filter) { - D3DSURFACE_DESC description; - img->surface->GetDesc(&description); + case GL_NEAREST: + case GL_LINEAR: + case GL_NEAREST_MIPMAP_NEAREST: + case GL_LINEAR_MIPMAP_NEAREST: + case GL_NEAREST_MIPMAP_LINEAR: + case GL_LINEAR_MIPMAP_LINEAR: + { + if (mMinFilter != filter) + { + mMinFilter = filter; + mDirtyParameters = true; + } + return true; + } + default: + return false; + } +} - D3DLOCKED_RECT locked; - HRESULT result = img->surface->LockRect(&locked, NULL, 0); +// Returns true on successful filter state update (valid enum parameter) +bool Texture::setMagFilter(GLenum filter) +{ + switch (filter) + { + case GL_NEAREST: + case GL_LINEAR: + { + if (mMagFilter != filter) + { + mMagFilter = filter; + mDirtyParameters = true; + } + return true; + } + default: + return false; + } +} - ASSERT(SUCCEEDED(result)); +// Returns true on successful wrap state update (valid enum parameter) +bool Texture::setWrapS(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: + case GL_CLAMP_TO_EDGE: + case GL_MIRRORED_REPEAT: + { + if (mWrapS != wrap) + { + mWrapS = wrap; + mDirtyParameters = true; + } + return true; + } + default: + return false; + } +} - if (SUCCEEDED(result)) +// Returns true on successful wrap state update (valid enum parameter) +bool Texture::setWrapT(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: + case GL_CLAMP_TO_EDGE: + case GL_MIRRORED_REPEAT: { - loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description); - img->surface->UnlockRect(); + if (mWrapT != wrap) + { + mWrapT = wrap; + mDirtyParameters = true; + } + return true; } + default: + return false; + } +} - img->dirty = true; +// Returns true on successful usage state update (valid enum parameter) +bool Texture::setUsage(GLenum usage) +{ + switch (usage) + { + case GL_NONE: + case GL_FRAMEBUFFER_ATTACHMENT_ANGLE: + mUsage = usage; + return true; + default: + return false; } +} - mDirtyMetaData = true; +GLenum Texture::getMinFilter() const +{ + return mMinFilter; } -void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img) +GLenum Texture::getMagFilter() const +{ + return mMagFilter; +} + +GLenum Texture::getWrapS() const { - createSurface(width, height, format, GL_UNSIGNED_BYTE, img); + return mWrapS; +} - if (pixels != NULL && img->surface != NULL) +GLenum Texture::getWrapT() const +{ + return mWrapT; +} + +GLenum Texture::getUsage() const +{ + return mUsage; +} + +void Texture::setImage(GLint unpackAlignment, const void *pixels, Image *image) +{ + if (pixels != NULL) { D3DLOCKED_RECT locked; - HRESULT result = img->surface->LockRect(&locked, NULL, 0); - - ASSERT(SUCCEEDED(result)); + HRESULT result = image->lock(&locked, NULL); if (SUCCEEDED(result)) { - memcpy(locked.pBits, pixels, imageSize); - img->surface->UnlockRect(); + image->loadData(0, 0, image->getWidth(), image->getHeight(), image->getType(), unpackAlignment, pixels, locked.Pitch, locked.pBits); + image->unlock(); } - img->dirty = true; + mDirtyImages = true; } +} + +void Texture::setCompressedImage(GLsizei imageSize, const void *pixels, Image *image) +{ + if (pixels != NULL) + { + D3DLOCKED_RECT locked; + HRESULT result = image->lock(&locked, NULL); - mDirtyMetaData = true; + if (SUCCEEDED(result)) + { + int inputPitch = ComputeCompressedPitch(image->getWidth(), image->getFormat()); + int inputSize = ComputeCompressedSize(image->getWidth(), image->getHeight(), image->getFormat()); + image->loadCompressedData(0, 0, image->getWidth(), image->getHeight(), -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits); + image->unlock(); + } + + mDirtyImages = true; + } } -bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img) +bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image) { - if (width + xoffset > img->width || height + yoffset > img->height) + if (width + xoffset > image->getWidth() || height + yoffset > image->getHeight()) { error(GL_INVALID_VALUE); return false; } - if (!img->surface) + if (IsCompressed(image->getFormat())) { - createSurface(img->width, img->height, format, type, img); + error(GL_INVALID_OPERATION); + return false; } - if (pixels != NULL && img->surface != NULL) + if (format != image->getFormat()) { - D3DSURFACE_DESC description; - img->surface->GetDesc(&description); + error(GL_INVALID_OPERATION); + return false; + } + if (pixels != NULL) + { D3DLOCKED_RECT locked; - HRESULT result = img->surface->LockRect(&locked, NULL, 0); - - ASSERT(SUCCEEDED(result)); + HRESULT result = image->lock(&locked, NULL); if (SUCCEEDED(result)) { - loadImageData(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits, &description); - img->surface->UnlockRect(); + image->loadData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, type, unpackAlignment, pixels, locked.Pitch, locked.pBits); + image->unlock(); } - img->dirty = true; + mDirtyImages = true; } return true; } -bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img) +bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image) { - if (width + xoffset > img->width || height + yoffset > img->height) + if (width + xoffset > image->getWidth() || height + yoffset > image->getHeight()) { error(GL_INVALID_VALUE); return false; } - if (format != getFormat()) + if (format != getInternalFormat()) { error(GL_INVALID_OPERATION); return false; } - if (!img->surface) - { - createSurface(img->width, img->height, format, GL_UNSIGNED_BYTE, img); - } - - if (pixels != NULL && img->surface != NULL) + if (pixels != NULL) { RECT updateRegion; updateRegion.left = xoffset; @@ -892,419 +1542,354 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL updateRegion.top = yoffset; D3DLOCKED_RECT locked; - HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0); - - ASSERT(SUCCEEDED(result)); + HRESULT result = image->lock(&locked, &updateRegion); if (SUCCEEDED(result)) { - 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(); + int inputPitch = ComputeCompressedPitch(width, format); + int inputSize = ComputeCompressedSize(width, height, format); + image->loadCompressedData(xoffset, transformPixelYOffset(yoffset, height, image->getHeight()), width, height, -inputPitch, static_cast<const char*>(pixels) + inputSize - inputPitch, locked.Pitch, locked.pBits); + image->unlock(); } - img->dirty = true; + mDirtyImages = 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) +IDirect3DBaseTexture9 *Texture::getTexture() { - 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)) + if (!isSamplerComplete()) { - ERR("Could not create matching destination surface."); - return error(GL_OUT_OF_MEMORY); + return NULL; } - result = device->GetRenderTargetData(renderTarget, surface); - - if (!SUCCEEDED(result)) + // ensure the underlying texture is created + if (getStorage(false) == NULL) { - ERR("GetRenderTargetData unexpectedly failed."); - surface->Release(); - return error(GL_OUT_OF_MEMORY); + return NULL; } - D3DLOCKED_RECT sourceLock = {0}; - RECT sourceRect = {x, y, x + width, y + height}; - result = surface->LockRect(&sourceLock, &sourceRect, 0); + updateTexture(); - if (FAILED(result)) - { - ERR("Failed to lock the source surface (rectangle might be invalid)."); - surface->UnlockRect(); - surface->Release(); - return error(GL_OUT_OF_MEMORY); - } + return getBaseTexture(); +} - if (!image->surface) - { - createSurface(width, height, internalFormat, mType, image); - } +bool Texture::hasDirtyParameters() const +{ + return mDirtyParameters; +} - if (image->surface == NULL) - { - ERR("Failed to create an image surface."); - surface->UnlockRect(); - surface->Release(); - return error(GL_OUT_OF_MEMORY); - } +bool Texture::hasDirtyImages() const +{ + return mDirtyImages; +} - D3DLOCKED_RECT destLock = {0}; - RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; - result = image->surface->LockRect(&destLock, &destRect, 0); - - if (FAILED(result)) +void Texture::resetDirty() +{ + mDirtyParameters = false; + mDirtyImages = false; +} + +unsigned int Texture::getTextureSerial() +{ + TextureStorage *texture = getStorage(false); + return texture ? texture->getTextureSerial() : 0; +} + +unsigned int Texture::getRenderTargetSerial(GLenum target) +{ + TextureStorage *texture = getStorage(true); + return texture ? texture->getRenderTargetSerial(target) : 0; +} + +bool Texture::isImmutable() const +{ + return mImmutable; +} + +GLint Texture::creationLevels(GLsizei width, GLsizei height) const +{ + if ((isPow2(width) && isPow2(height)) || getContext()->supportsNonPower2Texture()) { - ERR("Failed to lock the destination surface (rectangle might be invalid)."); - surface->UnlockRect(); - surface->Release(); - return error(GL_OUT_OF_MEMORY); + return 0; // Maximum number of levels } - - if (destLock.pBits && sourceLock.pBits) + else { - unsigned char *source = (unsigned char*)sourceLock.pBits; - unsigned char *dest = (unsigned char*)destLock.pBits; + // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps. + return 1; + } +} - 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]; - } +GLint Texture::creationLevels(GLsizei size) const +{ + return creationLevels(size, size); +} - 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]; - } +int Texture::levelCount() const +{ + return getBaseTexture() ? getBaseTexture()->GetLevelCount() : 0; +} - 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); - } +Blit *Texture::getBlitter() +{ + Context *context = getContext(); + return context->getBlitter(); +} - 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); - } +bool Texture::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +{ + if (source && dest) + { + HRESULT result; - 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; - } + if (fromManaged) + { + result = D3DXLoadSurfaceFromSurface(dest, NULL, NULL, source, NULL, NULL, D3DX_FILTER_BOX, 0); + } + else + { + egl::Display *display = getDisplay(); + IDirect3DDevice9 *device = display->getDevice(); - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); - } - break; - default: - UNREACHABLE(); + display->endScene(); + result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); } - image->dirty = true; - mDirtyMetaData = true; + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return false; + } } - image->surface->UnlockRect(); - surface->UnlockRect(); - surface->Release(); + return true; } -D3DFORMAT Texture::getD3DFormat() const +TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(true), mRenderTargetSerial(RenderbufferStorage::issueSerial()) { - return selectFormat(getFormat(), mType); + mTexture = surfaceTexture; } -IDirect3DBaseTexture9 *Texture::getTexture() +TextureStorage2D::TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderTarget) + : TextureStorage(renderTarget), mRenderTargetSerial(RenderbufferStorage::issueSerial()) { - if (!isComplete()) + IDirect3DDevice9 *device = getDevice(); + + mTexture = NULL; + HRESULT result = device->CreateTexture(width, height, levels, isRenderTarget() ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL); + + if (FAILED(result)) { - return NULL; + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + error(GL_OUT_OF_MEMORY); } +} - if (mDirtyMetaData) +TextureStorage2D::~TextureStorage2D() +{ + if (mTexture) { - mBaseTexture = createTexture(); - mIsRenderable = false; + mTexture->Release(); } +} + +IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level) +{ + IDirect3DSurface9 *surface = NULL; - if (mDirtyMetaData || dirtyImageData()) + if (mTexture) { - updateTexture(); + HRESULT result = mTexture->GetSurfaceLevel(level, &surface); + ASSERT(SUCCEEDED(result)); } - mDirtyMetaData = false; - ASSERT(!dirtyImageData()); + return surface; +} - return mBaseTexture; +IDirect3DBaseTexture9 *TextureStorage2D::getBaseTexture() const +{ + return mTexture; } -bool Texture::isDirty() const +unsigned int TextureStorage2D::getRenderTargetSerial(GLenum target) const { - return (mDirty || mDirtyMetaData || dirtyImageData()); + return mRenderTargetSerial; } -// Returns the top-level texture surface as a render target -void Texture::needRenderTarget() +Texture2D::Texture2D(GLuint id) : Texture(id) { - if (!mIsRenderable) - { - mBaseTexture = convertToRenderTarget(); - mIsRenderable = true; - } + mTexStorage = NULL; + mSurface = NULL; + mColorbufferProxy = NULL; + mProxyRefs = 0; +} - if (dirtyImageData()) +Texture2D::~Texture2D() +{ + mColorbufferProxy = NULL; + + delete mTexStorage; + mTexStorage = NULL; + + if (mSurface) { - updateTexture(); + mSurface->setBoundTexture(NULL); + mSurface = NULL; } +} - mDirtyMetaData = false; +// We need to maintain a count of references to renderbuffers acting as +// proxies for this texture, so that we do not attempt to use a pointer +// to a renderbuffer proxy which has been deleted. +void Texture2D::addProxyRef(const Renderbuffer *proxy) +{ + mProxyRefs++; } -void Texture::dropTexture() +void Texture2D::releaseProxy(const Renderbuffer *proxy) { - if (mBaseTexture) - { - mBaseTexture = NULL; - } + if (mProxyRefs > 0) + mProxyRefs--; - mIsRenderable = false; + if (mProxyRefs == 0) + mColorbufferProxy = NULL; } -void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable) +GLenum Texture2D::getTarget() const { - mBaseTexture = newTexture; - mDirtyMetaData = false; - mIsRenderable = renderable; - mDirty = true; + return GL_TEXTURE_2D; } - -GLint Texture::creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const +GLsizei Texture2D::getWidth(GLint level) const { - if (isPow2(width) && isPow2(height)) - { - return maxlevel; - } + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level].getWidth(); else - { - // OpenGL ES 2.0 without GL_OES_texture_npot does not permit NPOT mipmaps. - return 1; - } + return 0; } -GLint Texture::creationLevels(GLsizei size, GLint maxlevel) const +GLsizei Texture2D::getHeight(GLint level) const { - return creationLevels(size, size, maxlevel); + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[level].getHeight(); + else + return 0; } -int Texture::levelCount() const +GLenum Texture2D::getInternalFormat() const { - return mBaseTexture ? mBaseTexture->GetLevelCount() : 0; + return mImageArray[0].getFormat(); } -bool Texture::isRenderable() const +GLenum Texture2D::getType() const { - return mIsRenderable; + return mImageArray[0].getType(); } -Texture2D::Texture2D(GLuint id) : Texture(id) +D3DFORMAT Texture2D::getD3DFormat() const { - mTexture = NULL; + return mImageArray[0].getD3DFormat(); } -Texture2D::~Texture2D() +void Texture2D::redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) { - mColorbufferProxy.set(NULL); + releaseTexImage(); - if (mTexture) + bool redefined = mImageArray[level].redefine(format, width, height, type, false); + + if (mTexStorage && redefined) { - mTexture->Release(); - mTexture = NULL; + for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mImageArray[i].markDirty(); + } + + delete mTexStorage; + mTexStorage = NULL; + mDirtyImages = true; } } -GLenum Texture2D::getTarget() const +void Texture2D::setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - return GL_TEXTURE_2D; -} + redefineImage(level, format, width, height, type); -GLenum Texture2D::getFormat() const -{ - return mImageArray[0].format; + Texture::setImage(unpackAlignment, pixels, &mImageArray[level]); } -// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture -// 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 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, GLenum type) +void Texture2D::bindTexImage(egl::Surface *surface) { - bool widthOkay = (mWidth >> level == width); - bool heightOkay = (mHeight >> level == height); + releaseTexImage(); - bool sizeOkay = ((widthOkay && heightOkay) - || (widthOkay && mHeight >> level == 0 && height == 1) - || (heightOkay && mWidth >> level == 0 && width == 1)); + GLenum format; - bool typeOkay = (type == mType); + switch(surface->getFormat()) + { + case D3DFMT_A8R8G8B8: + format = GL_RGBA; + break; + case D3DFMT_X8R8G8B8: + format = GL_RGB; + break; + default: + UNIMPLEMENTED(); + return; + } - bool textureOkay = (sizeOkay && typeOkay && internalFormat == mImageArray[0].format); + mImageArray[0].redefine(format, surface->getWidth(), surface->getHeight(), GL_UNSIGNED_BYTE, true); - if (!textureOkay) - { - TRACE("Redefining 2D texture (%d, 0x%04X, %d, %d => 0x%04X, %d, %d).", level, - mImageArray[0].format, mWidth, mHeight, - internalFormat, width, height); + delete mTexStorage; + mTexStorage = new TextureStorage2D(surface->getOffscreenTexture()); - // Purge all the levels and the texture. + mDirtyImages = true; + mSurface = surface; + mSurface->setBoundTexture(this); +} - for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - if (mImageArray[i].surface != NULL) - { - mImageArray[i].dirty = false; +void Texture2D::releaseTexImage() +{ + if (mSurface) + { + mSurface->setBoundTexture(NULL); + mSurface = NULL; - mImageArray[i].surface->Release(); - mImageArray[i].surface = NULL; - } + if (mTexStorage) + { + delete mTexStorage; + mTexStorage = NULL; } - if (mTexture != NULL) + for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { - mTexture->Release(); - mTexture = NULL; - dropTexture(); + mImageArray[i].redefine(GL_RGBA, 0, 0, GL_UNSIGNED_BYTE, true); } - - mWidth = width << level; - mHeight = height << level; - mImageArray[0].format = internalFormat; - mType = type; } - - return !textureOkay; } -void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void Texture2D::setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) { - redefineTexture(level, internalFormat, width, height, type); + redefineImage(level, format, width, height, GL_UNSIGNED_BYTE); - 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, GL_UNSIGNED_BYTE); - - Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]); + Texture::setCompressedImage(imageSize, pixels, &mImageArray[level]); } void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) { - ASSERT(mImageArray[level].surface != NULL); + ASSERT(mImageArray[level].getSurface() != NULL); if (level < levelCount()) { - IDirect3DSurface9 *destLevel = NULL; - HRESULT result = mTexture->GetSurfaceLevel(level, &destLevel); + IDirect3DSurface9 *destLevel = mTexStorage->getSurfaceLevel(level); - ASSERT(SUCCEEDED(result)); - - if (SUCCEEDED(result)) + if (destLevel) { - Image *img = &mImageArray[level]; - - RECT sourceRect; - sourceRect.left = xoffset; - sourceRect.top = yoffset; - sourceRect.right = xoffset + width; - sourceRect.bottom = yoffset + height; - - POINT destPoint; - destPoint.x = xoffset; - destPoint.y = yoffset; - - result = getDevice()->UpdateSurface(img->surface, &sourceRect, destLevel, &destPoint); - ASSERT(SUCCEEDED(result)); + Image *image = &mImageArray[level]; + image->updateSurface(destLevel, xoffset, yoffset, width, height); destLevel->Release(); - - img->dirty = false; + image->markClean(); } } } @@ -1325,7 +1910,7 @@ 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) +void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { IDirect3DSurface9 *renderTarget = source->getRenderTarget(); @@ -1335,48 +1920,48 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, return error(GL_OUT_OF_MEMORY); } - bool redefined = redefineTexture(level, internalFormat, width, height, mType); + redefineImage(level, format, width, height, GL_UNSIGNED_BYTE); - if (!isRenderableFormat()) + if (!mImageArray[level].isRenderableFormat()) { - copyNonRenderable(&mImageArray[level], internalFormat, 0, 0, x, y, width, height, renderTarget); + mImageArray[level].copy(0, 0, x, y, width, height, renderTarget); + mDirtyImages = true; } else { - if (redefined) + if (!mTexStorage || !mTexStorage->isRenderTarget()) { convertToRenderTarget(); - pushTexture(mTexture, true); - } - else - { - needRenderTarget(); } + + mImageArray[level].markClean(); if (width != 0 && height != 0 && level < levelCount()) { - RECT sourceRect; - sourceRect.left = x; - sourceRect.right = x + width; - sourceRect.top = y; - sourceRect.bottom = y + height; + RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); + sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); + sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); + sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); + sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); - IDirect3DSurface9 *dest; - HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); + GLint destYOffset = transformPixelYOffset(0, height, mImageArray[level].getHeight()); + + IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); - getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest); - dest->Release(); + if (dest) + { + getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); + dest->Release(); + } } } - mImageArray[level].width = width; - mImageArray[level].height = height; - mImageArray[level].format = internalFormat; + renderTarget->Release(); } -void Texture2D::copySubImage(GLenum target, 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, Framebuffer *source) { - if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height) + if (xoffset + width > mImageArray[level].getWidth() || yoffset + height > mImageArray[level].getHeight()) { return error(GL_INVALID_VALUE); } @@ -1389,46 +1974,83 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo return error(GL_OUT_OF_MEMORY); } - bool redefined = redefineTexture(0, mImageArray[0].format, mImageArray[0].width, mImageArray[0].height, mType); - - if (!isRenderableFormat()) + if (!mImageArray[level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete())) { - copyNonRenderable(&mImageArray[level], getFormat(), xoffset, yoffset, x, y, width, height, renderTarget); + mImageArray[level].copy(xoffset, yoffset, x, y, width, height, renderTarget); + mDirtyImages = true; } else { - if (redefined) + if (!mTexStorage || !mTexStorage->isRenderTarget()) { convertToRenderTarget(); - pushTexture(mTexture, true); - } - else - { - needRenderTarget(); } + + updateTexture(); if (level < levelCount()) { - RECT sourceRect; - sourceRect.left = x; - sourceRect.right = x + width; - sourceRect.top = y; - sourceRect.bottom = y + height; + RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); + sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); + sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); + sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); + sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); + + GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[level].getHeight()); - IDirect3DSurface9 *dest; - HRESULT hr = mTexture->GetSurfaceLevel(level, &dest); + IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level); - getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0].format, xoffset, yoffset, dest); - dest->Release(); + if (dest) + { + getBlitter()->copy(renderTarget, sourceRect, mImageArray[0].getFormat(), xoffset, destYOffset, dest); + dest->Release(); + } } } + + renderTarget->Release(); } -// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. -bool Texture2D::isComplete() const +void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - GLsizei width = mImageArray[0].width; - GLsizei height = mImageArray[0].height; + GLenum format = gl::ExtractFormat(internalformat); + GLenum type = gl::ExtractType(internalformat); + D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type); + const bool renderTarget = IsTextureFormatRenderable(d3dfmt) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + + delete mTexStorage; + mTexStorage = new TextureStorage2D(levels, d3dfmt, width, height, renderTarget); + mImmutable = true; + + for (int level = 0; level < levels; level++) + { + mImageArray[level].redefine(format, width, height, type, true); + width = std::max(1, width >> 1); + height = std::max(1, height >> 1); + } + + for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) + { + mImageArray[level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true); + } + + if (mTexStorage->isManaged()) + { + int levels = levelCount(); + + for (int level = 0; level < levels; level++) + { + IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level); + mImageArray[level].setManagedSurface(surface); + } + } +} + +// Tests for 2D texture sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 85. +bool Texture2D::isSamplerComplete() const +{ + GLsizei width = mImageArray[0].getWidth(); + GLsizei height = mImageArray[0].getHeight(); if (width <= 0 || height <= 0) { @@ -1449,11 +2071,11 @@ bool Texture2D::isComplete() const case GL_LINEAR_MIPMAP_LINEAR: mipmapping = true; break; - default: UNREACHABLE(); + default: UNREACHABLE(); } - if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) || - (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter())) + if ((getInternalFormat() == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || + (getInternalFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) { if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) { @@ -1461,38 +2083,74 @@ bool Texture2D::isComplete() const } } + bool npotSupport = getContext()->supportsNonPower2Texture(); - if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width)) - || (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height))) + if (!npotSupport) { - return false; + if ((getWrapS() != GL_CLAMP_TO_EDGE && !isPow2(width)) || + (getWrapT() != GL_CLAMP_TO_EDGE && !isPow2(height))) + { + return false; + } } if (mipmapping) { - if (!isPow2(width) || !isPow2(height)) + if (!npotSupport) + { + if (!isPow2(width) || !isPow2(height)) + { + return false; + } + } + + if (!isMipmapComplete()) { return false; } + } - int q = log2(std::max(width, height)); + return true; +} - for (int level = 1; level <= q; level++) +// Tests for 2D texture (mipmap) completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. +bool Texture2D::isMipmapComplete() const +{ + if (isImmutable()) + { + return true; + } + + GLsizei width = mImageArray[0].getWidth(); + GLsizei height = mImageArray[0].getHeight(); + + if (width <= 0 || height <= 0) + { + return false; + } + + int q = log2(std::max(width, height)); + + for (int level = 1; level <= q; level++) + { + if (mImageArray[level].getFormat() != mImageArray[0].getFormat()) { - if (mImageArray[level].format != mImageArray[0].format) - { - return false; - } + return false; + } - if (mImageArray[level].width != std::max(1, width >> level)) - { - return false; - } + if (mImageArray[level].getType() != mImageArray[0].getType()) + { + return false; + } - if (mImageArray[level].height != std::max(1, height >> level)) - { - return false; - } + if (mImageArray[level].getWidth() != std::max(1, width >> level)) + { + return false; + } + + if (mImageArray[level].getHeight() != std::max(1, height >> level)) + { + return false; } } @@ -1501,186 +2159,122 @@ bool Texture2D::isComplete() const bool Texture2D::isCompressed() const { - return IsCompressed(getFormat()); + return IsCompressed(getInternalFormat()); } -// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one -IDirect3DBaseTexture9 *Texture2D::createTexture() +IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const { - IDirect3DTexture9 *texture; - - IDirect3DDevice9 *device = getDevice(); - D3DFORMAT format = selectFormat(mImageArray[0].format, mType); + return mTexStorage ? mTexStorage->getBaseTexture() : NULL; +} - HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL); +// Constructs a Direct3D 9 texture resource from the texture images +void Texture2D::createTexture() +{ + GLsizei width = mImageArray[0].getWidth(); + GLsizei height = mImageArray[0].getHeight(); + GLint levels = creationLevels(width, height); + D3DFORMAT format = mImageArray[0].getD3DFormat(); + const bool renderTarget = IsTextureFormatRenderable(format) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); - if (FAILED(result)) + delete mTexStorage; + mTexStorage = new TextureStorage2D(levels, format, width, height, renderTarget); + + if (mTexStorage->isManaged()) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); + int levels = levelCount(); + + for (int level = 0; level < levels; level++) + { + IDirect3DSurface9 *surface = mTexStorage->getSurfaceLevel(level); + mImageArray[level].setManagedSurface(surface); + } } - if (mTexture) mTexture->Release(); - mTexture = texture; - return texture; + mDirtyImages = true; } void Texture2D::updateTexture() { - IDirect3DDevice9 *device = getDevice(); - int levels = levelCount(); for (int level = 0; level < levels; level++) { - if (mImageArray[level].dirty) - { - IDirect3DSurface9 *levelSurface = NULL; - HRESULT result = mTexture->GetSurfaceLevel(level, &levelSurface); - - ASSERT(SUCCEEDED(result)); - - if (SUCCEEDED(result)) - { - result = device->UpdateSurface(mImageArray[level].surface, NULL, levelSurface, NULL); - ASSERT(SUCCEEDED(result)); + Image *image = &mImageArray[level]; - levelSurface->Release(); - - mImageArray[level].dirty = false; - } + if (image->isDirty()) + { + commitRect(level, 0, 0, mImageArray[level].getWidth(), mImageArray[level].getHeight()); } } } -IDirect3DBaseTexture9 *Texture2D::convertToRenderTarget() +void Texture2D::convertToRenderTarget() { - IDirect3DTexture9 *texture = NULL; + TextureStorage2D *newTexStorage = NULL; - if (mWidth != 0 && mHeight != 0) + if (mImageArray[0].getWidth() != 0 && mImageArray[0].getHeight() != 0) { - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); - D3DFORMAT format = selectFormat(mImageArray[0].format, mType); - - HRESULT result = device->CreateTexture(mWidth, mHeight, creationLevels(mWidth, mHeight, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); + GLsizei width = mImageArray[0].getWidth(); + GLsizei height = mImageArray[0].getHeight(); + GLint levels = creationLevels(width, height); + D3DFORMAT format = mImageArray[0].getD3DFormat(); - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } + newTexStorage = new TextureStorage2D(levels, format, width, height, true); - if (mTexture != NULL) + if (mTexStorage != NULL) { int levels = levelCount(); for (int i = 0; i < levels; i++) { - IDirect3DSurface9 *source; - result = mTexture->GetSurfaceLevel(i, &source); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } - - IDirect3DSurface9 *dest; - result = texture->GetSurfaceLevel(i, &dest); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - source->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); + IDirect3DSurface9 *source = mTexStorage->getSurfaceLevel(i); + IDirect3DSurface9 *dest = newTexStorage->getSurfaceLevel(i); + + if (!copyToRenderTarget(dest, source, mTexStorage->isManaged())) + { + delete newTexStorage; + source->Release(); + dest->Release(); + return error(GL_OUT_OF_MEMORY); } - display->endScene(); - result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - source->Release(); - dest->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } - - source->Release(); - dest->Release(); + if (source) source->Release(); + if (dest) dest->Release(); } } } - if (mTexture != NULL) - { - mTexture->Release(); - } - - mTexture = texture; - return mTexture; -} - -bool Texture2D::dirtyImageData() const -{ - int q = log2(std::max(mWidth, mHeight)); + delete mTexStorage; + mTexStorage = newTexStorage; - for (int i = 0; i <= q; i++) - { - if (mImageArray[i].dirty) return true; - } - - return false; + mDirtyImages = true; } void Texture2D::generateMipmaps() { - if (!isPow2(mImageArray[0].width) || !isPow2(mImageArray[0].height)) + if (!getContext()->supportsNonPower2Texture()) { - return error(GL_INVALID_OPERATION); + if (!isPow2(mImageArray[0].getWidth()) || !isPow2(mImageArray[0].getHeight())) + { + return error(GL_INVALID_OPERATION); + } } // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - unsigned int q = log2(std::max(mWidth, mHeight)); + unsigned int q = log2(std::max(mImageArray[0].getWidth(), mImageArray[0].getHeight())); for (unsigned int i = 1; i <= q; i++) { - if (mImageArray[i].surface != NULL) - { - mImageArray[i].surface->Release(); - mImageArray[i].surface = NULL; - } - - mImageArray[i].dirty = false; - - mImageArray[i].format = mImageArray[0].format; - mImageArray[i].width = std::max(mImageArray[0].width >> i, 1); - mImageArray[i].height = std::max(mImageArray[0].height >> i, 1); + redefineImage(i, mImageArray[0].getFormat(), + std::max(mImageArray[0].getWidth() >> i, 1), + std::max(mImageArray[0].getHeight() >> i, 1), + mImageArray[0].getType()); } - if (isRenderable()) + if (mTexStorage && mTexStorage->isRenderTarget()) { - if (mTexture == NULL) - { - ERR(" failed because mTexture was null."); - return; - } - for (unsigned int i = 1; i <= q; i++) { - IDirect3DSurface9 *upper = NULL; - IDirect3DSurface9 *lower = NULL; - - mTexture->GetSurfaceLevel(i-1, &upper); - mTexture->GetSurfaceLevel(i, &lower); + IDirect3DSurface9 *upper = mTexStorage->getSurfaceLevel(i - 1); + IDirect3DSurface9 *lower = mTexStorage->getSurfaceLevel(i); if (upper != NULL && lower != NULL) { @@ -1689,78 +2283,169 @@ void Texture2D::generateMipmaps() if (upper != NULL) upper->Release(); if (lower != NULL) lower->Release(); + + mImageArray[i].markClean(); } } else { for (unsigned int i = 1; i <= q; i++) { - createSurface(mImageArray[i].width, mImageArray[i].height, mImageArray[i].format, mType, &mImageArray[i]); - if (mImageArray[i].surface == NULL) + if (mImageArray[i].getSurface() == 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))) + if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[i].getSurface(), NULL, NULL, mImageArray[i - 1].getSurface(), NULL, NULL, D3DX_FILTER_BOX, 0))) { ERR(" failed to load filter %d to %d.", i - 1, i); } - mImageArray[i].dirty = true; + mImageArray[i].markDirty(); } - - mDirtyMetaData = true; } } -Renderbuffer *Texture2D::getColorbuffer(GLenum target) +Renderbuffer *Texture2D::getRenderbuffer(GLenum target) { if (target != GL_TEXTURE_2D) { return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL); } - if (mColorbufferProxy.get() == NULL) + if (mColorbufferProxy == NULL) { - mColorbufferProxy.set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target))); + mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture(this, target)); } - return mColorbufferProxy.get(); + return mColorbufferProxy; } IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target) { ASSERT(target == GL_TEXTURE_2D); - needRenderTarget(); - - if (mTexture == NULL) + // ensure the underlying texture is created + if (getStorage(true) == NULL) { return NULL; } + + updateTexture(); - IDirect3DSurface9 *renderTarget = NULL; - mTexture->GetSurfaceLevel(0, &renderTarget); + return mTexStorage->getSurfaceLevel(0); +} - return renderTarget; +TextureStorage *Texture2D::getStorage(bool renderTarget) +{ + if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) + { + if (renderTarget) + { + convertToRenderTarget(); + } + else + { + createTexture(); + } + } + + return mTexStorage; } -TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id) +TextureStorageCubeMap::TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderTarget) + : TextureStorage(renderTarget), mFirstRenderTargetSerial(RenderbufferStorage::issueCubeSerials()) { + IDirect3DDevice9 *device = getDevice(); + mTexture = NULL; + HRESULT result = device->CreateCubeTexture(size, levels, isRenderTarget() ? D3DUSAGE_RENDERTARGET : 0, format, getPool(), &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + error(GL_OUT_OF_MEMORY); + } +} + +TextureStorageCubeMap::~TextureStorageCubeMap() +{ + if (mTexture) + { + mTexture->Release(); + } +} + +IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level) +{ + IDirect3DSurface9 *surface = NULL; + + if (mTexture) + { + HRESULT result = mTexture->GetCubeMapSurface(es2dx::ConvertCubeFace(faceTarget), level, &surface); + ASSERT(SUCCEEDED(result)); + } + + return surface; +} + +IDirect3DBaseTexture9 *TextureStorageCubeMap::getBaseTexture() const +{ + return mTexture; +} + +unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const +{ + return mFirstRenderTargetSerial + TextureCubeMap::faceIndex(target); +} + +TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id) +{ + mTexStorage = NULL; + for (int i = 0; i < 6; i++) + { + mFaceProxies[i] = NULL; + mFaceProxyRefs[i] = 0; + } } TextureCubeMap::~TextureCubeMap() { for (int i = 0; i < 6; i++) { - mFaceProxies[i].set(NULL); + mFaceProxies[i] = NULL; } - if (mTexture) + delete mTexStorage; + mTexStorage = NULL; +} + +// We need to maintain a count of references to renderbuffers acting as +// proxies for this texture, so that the texture is not deleted while +// proxy references still exist. If the reference count drops to zero, +// we set our proxy pointer NULL, so that a new attempt at referencing +// will cause recreation. +void TextureCubeMap::addProxyRef(const Renderbuffer *proxy) +{ + for (int i = 0; i < 6; i++) { - mTexture->Release(); - mTexture = NULL; + if (mFaceProxies[i] == proxy) + mFaceProxyRefs[i]++; + } +} + +void TextureCubeMap::releaseProxy(const Renderbuffer *proxy) +{ + for (int i = 0; i < 6; i++) + { + if (mFaceProxies[i] == proxy) + { + if (mFaceProxyRefs[i] > 0) + mFaceProxyRefs[i]--; + + if (mFaceProxyRefs[i] == 0) + mFaceProxies[i] = NULL; + } } } @@ -1769,79 +2454,90 @@ GLenum TextureCubeMap::getTarget() const return GL_TEXTURE_CUBE_MAP; } -GLenum TextureCubeMap::getFormat() const +GLsizei TextureCubeMap::getWidth(GLint level) const +{ + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[0][level].getWidth(); + else + return 0; +} + +GLsizei TextureCubeMap::getHeight(GLint level) const +{ + if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) + return mImageArray[0][level].getHeight(); + else + return 0; +} + +GLenum TextureCubeMap::getInternalFormat() const { - return mImageArray[0][0].format; + return mImageArray[0][0].getFormat(); } -void TextureCubeMap::setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +GLenum TextureCubeMap::getType() const { - setImage(0, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + return mImageArray[0][0].getType(); } -void TextureCubeMap::setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +D3DFORMAT TextureCubeMap::getD3DFormat() const { - setImage(1, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + return mImageArray[0][0].getD3DFormat(); } -void TextureCubeMap::setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - setImage(2, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + setImage(0, level, width, height, format, type, unpackAlignment, pixels); } -void TextureCubeMap::setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - setImage(3, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + setImage(1, level, width, height, format, type, unpackAlignment, pixels); } -void TextureCubeMap::setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - setImage(4, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + setImage(2, level, width, height, format, type, unpackAlignment, pixels); } -void TextureCubeMap::setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - setImage(5, level, internalFormat, width, height, format, type, unpackAlignment, pixels); + setImage(3, level, width, height, format, type, unpackAlignment, pixels); } -void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) +void TextureCubeMap::setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - redefineTexture(level, internalFormat, width); + setImage(4, level, width, height, format, type, unpackAlignment, pixels); +} - Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[faceIndex(face)][level]); +void TextureCubeMap::setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +{ + setImage(5, level, width, height, format, type, unpackAlignment, pixels); } -void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels) { - int face = faceIndex(faceTarget); + redefineImage(faceIndex(face), level, format, width, height, GL_UNSIGNED_BYTE); + + Texture::setCompressedImage(imageSize, pixels, &mImageArray[faceIndex(face)][level]); +} - ASSERT(mImageArray[face][level].surface != NULL); +void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + ASSERT(mImageArray[face][level].getSurface() != NULL); if (level < levelCount()) { - IDirect3DSurface9 *destLevel = getCubeMapSurface(face, level); + IDirect3DSurface9 *destLevel = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); ASSERT(destLevel != NULL); if (destLevel != NULL) { - Image *img = &mImageArray[face][level]; - - RECT sourceRect; - sourceRect.left = xoffset; - sourceRect.top = yoffset; - sourceRect.right = xoffset + width; - sourceRect.bottom = yoffset + height; - - POINT destPoint; - destPoint.x = xoffset; - destPoint.y = yoffset; - - HRESULT result = getDevice()->UpdateSurface(img->surface, &sourceRect, destLevel, &destPoint); - ASSERT(SUCCEEDED(result)); + Image *image = &mImageArray[face][level]; + image->updateSurface(destLevel, xoffset, yoffset, width, height); destLevel->Release(); - - img->dirty = false; + image->markClean(); } } } @@ -1850,7 +2546,7 @@ void TextureCubeMap::subImage(GLenum target, GLint level, GLint xoffset, GLint y { if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(target)][level])) { - commitRect(target, level, xoffset, yoffset, width, height); + commitRect(faceIndex(target), level, xoffset, yoffset, width, height); } } @@ -1858,19 +2554,14 @@ void TextureCubeMap::subImageCompressed(GLenum target, GLint level, GLint xoffse { if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(target)][level])) { - commitRect(target, level, xoffset, yoffset, width, height); + commitRect(faceIndex(target), level, xoffset, yoffset, width, height); } } -// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. -bool TextureCubeMap::isComplete() const +// Tests for cube map sampling completeness. [OpenGL ES 2.0.24] section 3.8.2 page 86. +bool TextureCubeMap::isSamplerComplete() const { - int size = mImageArray[0][0].width; - - if (size <= 0) - { - return false; - } + int size = mImageArray[0][0].getWidth(); bool mipmapping; @@ -1886,50 +2577,101 @@ bool TextureCubeMap::isComplete() const case GL_LINEAR_MIPMAP_LINEAR: mipmapping = true; break; - default: UNREACHABLE(); + default: + UNREACHABLE(); + return false; } - for (int face = 0; face < 6; face++) + if ((getInternalFormat() == GL_FLOAT && !getContext()->supportsFloat32LinearFilter()) || + (getInternalFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsFloat16LinearFilter())) { - if (mImageArray[face][0].width != size || mImageArray[face][0].height != size) + if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) { return false; } } - if ((getFormat() == GL_FLOAT && !getContext()->supportsFloatLinearFilter()) || - (getFormat() == GL_HALF_FLOAT_OES && !getContext()->supportsHalfFloatLinearFilter())) + if (!isPow2(size) && !getContext()->supportsNonPower2Texture()) { - if (mMagFilter != GL_NEAREST || (mMinFilter != GL_NEAREST && mMinFilter != GL_NEAREST_MIPMAP_NEAREST)) + if (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE || mipmapping) { return false; } } - if (mipmapping) + if (!mipmapping) + { + if (!isCubeComplete()) + { + return false; + } + } + else { - if (!isPow2(size) && (getWrapS() != GL_CLAMP_TO_EDGE || getWrapT() != GL_CLAMP_TO_EDGE)) + if (!isMipmapCubeComplete()) // Also tests for isCubeComplete() { return false; } + } - int q = log2(size); + return true; +} - for (int face = 0; face < 6; face++) +// Tests for cube texture completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81. +bool TextureCubeMap::isCubeComplete() const +{ + if (mImageArray[0][0].getWidth() <= 0 || mImageArray[0][0].getHeight() != mImageArray[0][0].getWidth()) + { + return false; + } + + for (unsigned int face = 1; face < 6; face++) + { + if (mImageArray[face][0].getWidth() != mImageArray[0][0].getWidth() || + mImageArray[face][0].getWidth() != mImageArray[0][0].getHeight() || + mImageArray[face][0].getFormat() != mImageArray[0][0].getFormat() || + mImageArray[face][0].getType() != mImageArray[0][0].getType()) { - for (int level = 1; level <= q; level++) + return false; + } + } + + return true; +} + +bool TextureCubeMap::isMipmapCubeComplete() const +{ + if (isImmutable()) + { + return true; + } + + if (!isCubeComplete()) + { + return false; + } + + GLsizei size = mImageArray[0][0].getWidth(); + + int q = log2(size); + + for (int face = 0; face < 6; face++) + { + for (int level = 1; level <= q; level++) + { + if (mImageArray[face][level].getFormat() != mImageArray[0][0].getFormat()) { - if (mImageArray[face][level].format != mImageArray[0][0].format) - { - return false; - } + return false; + } - if (mImageArray[face][level].width != std::max(1, size >> level)) - { - return false; - } + if (mImageArray[face][level].getType() != mImageArray[0][0].getType()) + { + return false; + } - ASSERT(mImageArray[face][level].height == mImageArray[face][level].width); + if (mImageArray[face][level].getWidth() != std::max(1, size >> level)) + { + return false; } } } @@ -1939,143 +2681,107 @@ bool TextureCubeMap::isComplete() const bool TextureCubeMap::isCompressed() const { - return IsCompressed(getFormat()); + return IsCompressed(getInternalFormat()); } -// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one -IDirect3DBaseTexture9 *TextureCubeMap::createTexture() +IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const { - IDirect3DDevice9 *device = getDevice(); - D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType); + return mTexStorage ? mTexStorage->getBaseTexture() : NULL; +} - IDirect3DCubeTexture9 *texture; +// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one +void TextureCubeMap::createTexture() +{ + GLsizei size = mImageArray[0][0].getWidth(); + GLint levels = creationLevels(size, 0); + D3DFORMAT format = mImageArray[0][0].getD3DFormat(); + const bool renderTarget = IsTextureFormatRenderable(format) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); - HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), 0, format, D3DPOOL_DEFAULT, &texture, NULL); + delete mTexStorage; + mTexStorage = new TextureStorageCubeMap(levels, format, size, renderTarget); - if (FAILED(result)) + if (mTexStorage->isManaged()) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } + int levels = levelCount(); - if (mTexture) mTexture->Release(); + for (int face = 0; face < 6; face++) + { + for (int level = 0; level < levels; level++) + { + IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); + mImageArray[face][level].setManagedSurface(surface); + } + } + } - mTexture = texture; - return mTexture; + mDirtyImages = true; } void TextureCubeMap::updateTexture() { - IDirect3DDevice9 *device = getDevice(); - for (int face = 0; face < 6; face++) { int levels = levelCount(); for (int level = 0; level < levels; level++) { - Image *img = &mImageArray[face][level]; + Image *image = &mImageArray[face][level]; - if (img->dirty) + if (image->isDirty()) { - IDirect3DSurface9 *levelSurface = getCubeMapSurface(face, level); - ASSERT(levelSurface != NULL); - - if (levelSurface != NULL) - { - HRESULT result = device->UpdateSurface(img->surface, NULL, levelSurface, NULL); - ASSERT(SUCCEEDED(result)); - - levelSurface->Release(); - - img->dirty = false; - } + commitRect(face, level, 0, 0, image->getWidth(), image->getHeight()); } } } } -IDirect3DBaseTexture9 *TextureCubeMap::convertToRenderTarget() +void TextureCubeMap::convertToRenderTarget() { - IDirect3DCubeTexture9 *texture = NULL; + TextureStorageCubeMap *newTexStorage = NULL; - if (mWidth != 0) + if (mImageArray[0][0].getWidth() != 0) { - egl::Display *display = getDisplay(); - IDirect3DDevice9 *device = getDevice(); - D3DFORMAT format = selectFormat(mImageArray[0][0].format, mType); - - HRESULT result = device->CreateCubeTexture(mWidth, creationLevels(mWidth, 0), D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &texture, NULL); + GLsizei size = mImageArray[0][0].getWidth(); + GLint levels = creationLevels(size, 0); + D3DFORMAT format = mImageArray[0][0].getD3DFormat(); - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } + newTexStorage = new TextureStorageCubeMap(levels, format, size, true); - if (mTexture != NULL) + if (mTexStorage != NULL) { int levels = levelCount(); for (int f = 0; f < 6; f++) { for (int i = 0; i < levels; i++) { - IDirect3DSurface9 *source; - result = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &source); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } - - IDirect3DSurface9 *dest; - result = texture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(f), i, &dest); + IDirect3DSurface9 *source = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i); + IDirect3DSurface9 *dest = newTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i); - if (FAILED(result)) + if (!copyToRenderTarget(dest, source, mTexStorage->isManaged())) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - source->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); + delete newTexStorage; + source->Release(); + dest->Release(); + return error(GL_OUT_OF_MEMORY); } - display->endScene(); - result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - - texture->Release(); - source->Release(); - dest->Release(); - - return error(GL_OUT_OF_MEMORY, (IDirect3DBaseTexture9*)NULL); - } + if (source) source->Release(); + if (dest) dest->Release(); } } } } - if (mTexture != NULL) - { - mTexture->Release(); - } + delete mTexStorage; + mTexStorage = newTexStorage; - mTexture = texture; - return mTexture; + mDirtyImages = true; } -void TextureCubeMap::setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) +void TextureCubeMap::setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels) { - redefineTexture(level, internalFormat, width); + redefineImage(faceIndex, level, format, width, height, type); - Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[face][level]); + Texture::setImage(unpackAlignment, pixels, &mImageArray[faceIndex][level]); } unsigned int TextureCubeMap::faceIndex(GLenum face) @@ -2089,74 +2795,28 @@ unsigned int TextureCubeMap::faceIndex(GLenum face) return face - GL_TEXTURE_CUBE_MAP_POSITIVE_X; } -bool TextureCubeMap::dirtyImageData() const +void TextureCubeMap::redefineImage(int face, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type) { - int q = log2(mWidth); + bool redefined = mImageArray[face][level].redefine(format, width, height, type, false); - for (int f = 0; f < 6; f++) + if (mTexStorage && redefined) { - for (int i = 0; i <= q; i++) - { - if (mImageArray[f][i].dirty) return true; - } - } - - return false; -} - -// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture -// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels & faces. -// 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 -// a new size for the texture by working backwards from the given size. -bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei width) -{ - // Are these settings compatible with level 0? - bool sizeOkay = (mImageArray[0][0].width >> level == width); - - bool textureOkay = (sizeOkay && internalFormat == mImageArray[0][0].format); - - if (!textureOkay) - { - TRACE("Redefining cube texture (%d, 0x%04X, %d => 0x%04X, %d).", level, - mImageArray[0][0].format, mImageArray[0][0].width, - internalFormat, width); - - // Purge all the levels and the texture. for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) { for (int f = 0; f < 6; f++) { - if (mImageArray[f][i].surface != NULL) - { - mImageArray[f][i].dirty = false; - - mImageArray[f][i].surface->Release(); - mImageArray[f][i].surface = NULL; - } + mImageArray[f][i].markDirty(); } } - if (mTexture != NULL) - { - mTexture->Release(); - mTexture = NULL; - dropTexture(); - } - - mWidth = width << level; - mImageArray[0][0].width = width << level; - mHeight = width << level; - mImageArray[0][0].height = width << level; + delete mTexStorage; + mTexStorage = NULL; - mImageArray[0][0].format = internalFormat; + mDirtyImages = true; } - - return !textureOkay; } -void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source) +void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) { IDirect3DSurface9 *renderTarget = source->getRenderTarget(); @@ -2167,80 +2827,50 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum internalFormat } unsigned int faceindex = faceIndex(target); - bool redefined = redefineTexture(level, internalFormat, width); + redefineImage(faceindex, level, format, width, height, GL_UNSIGNED_BYTE); - if (!isRenderableFormat()) + if (!mImageArray[faceindex][level].isRenderableFormat()) { - copyNonRenderable(&mImageArray[faceindex][level], internalFormat, 0, 0, x, y, width, height, renderTarget); + mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget); + mDirtyImages = true; } else { - if (redefined) + if (!mTexStorage || !mTexStorage->isRenderTarget()) { convertToRenderTarget(); - pushTexture(mTexture, true); - } - else - { - needRenderTarget(); } + + mImageArray[faceindex][level].markClean(); ASSERT(width == height); if (width > 0 && level < levelCount()) { - RECT sourceRect; - sourceRect.left = x; - sourceRect.right = x + width; - sourceRect.top = y; - sourceRect.bottom = y + height; + RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); + sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); + sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); + sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); + sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); - IDirect3DSurface9 *dest = getCubeMapSurface(target, level); + GLint destYOffset = transformPixelYOffset(0, height, mImageArray[faceindex][level].getWidth()); - getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, internalFormat, 0, 0, dest); - dest->Release(); - } - } - - mImageArray[faceindex][level].width = width; - mImageArray[faceindex][level].height = height; - mImageArray[faceindex][level].format = internalFormat; -} - -IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier, unsigned int level) -{ - unsigned int faceIndex; - - if (faceIdentifier < 6) - { - faceIndex = faceIdentifier; - } - else if (faceIdentifier >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && faceIdentifier <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) - { - faceIndex = faceIdentifier - GL_TEXTURE_CUBE_MAP_POSITIVE_X; - } - else - { - UNREACHABLE(); - faceIndex = 0; - } + IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); - if (mTexture == NULL) - { - UNREACHABLE(); - return NULL; + if (dest) + { + getBlitter()->copy(renderTarget, sourceRect, format, 0, destYOffset, dest); + dest->Release(); + } + } } - IDirect3DSurface9 *surface = NULL; - - HRESULT hr = mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex), level, &surface); - - return (SUCCEEDED(hr)) ? surface : NULL; + renderTarget->Release(); } -void TextureCubeMap::copySubImage(GLenum target, 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, Framebuffer *source) { - GLsizei size = mImageArray[faceIndex(target)][level].width; + GLsizei size = mImageArray[faceIndex(target)][level].getWidth(); if (xoffset + width > size || yoffset + height > size) { @@ -2256,99 +2886,123 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi } unsigned int faceindex = faceIndex(target); - bool redefined = redefineTexture(0, mImageArray[0][0].format, mImageArray[0][0].width); - - if (!isRenderableFormat()) + + if (!mImageArray[faceindex][level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete())) { - copyNonRenderable(&mImageArray[faceindex][level], getFormat(), 0, 0, x, y, width, height, renderTarget); + mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget); + mDirtyImages = true; } else { - if (redefined) + if (!mTexStorage || !mTexStorage->isRenderTarget()) { convertToRenderTarget(); - pushTexture(mTexture, true); - } - else - { - needRenderTarget(); } + + updateTexture(); if (level < levelCount()) { - RECT sourceRect; - sourceRect.left = x; - sourceRect.right = x + width; - sourceRect.top = y; - sourceRect.bottom = y + height; + RECT sourceRect = transformPixelRect(x, y, width, height, source->getColorbuffer()->getHeight()); + sourceRect.left = clamp(sourceRect.left, 0, source->getColorbuffer()->getWidth()); + sourceRect.top = clamp(sourceRect.top, 0, source->getColorbuffer()->getHeight()); + sourceRect.right = clamp(sourceRect.right, 0, source->getColorbuffer()->getWidth()); + sourceRect.bottom = clamp(sourceRect.bottom, 0, source->getColorbuffer()->getHeight()); + + GLint destYOffset = transformPixelYOffset(yoffset, height, mImageArray[faceindex][level].getWidth()); - IDirect3DSurface9 *dest = getCubeMapSurface(target, level); + IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level); - getBlitter()->formatConvert(source->getRenderTarget(), sourceRect, mImageArray[0][0].format, xoffset, yoffset, dest); - dest->Release(); + if (dest) + { + getBlitter()->copy(renderTarget, sourceRect, mImageArray[0][0].getFormat(), xoffset, destYOffset, dest); + dest->Release(); + } } } + + renderTarget->Release(); } -bool TextureCubeMap::isCubeComplete() const +void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size) { - if (mImageArray[0][0].width == 0) + GLenum format = gl::ExtractFormat(internalformat); + GLenum type = gl::ExtractType(internalformat); + D3DFORMAT d3dfmt = ConvertTextureFormatType(format, type); + const bool renderTarget = IsTextureFormatRenderable(d3dfmt) && (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); + + delete mTexStorage; + mTexStorage = new TextureStorageCubeMap(levels, d3dfmt, size, renderTarget); + mImmutable = true; + + for (int level = 0; level < levels; level++) { - return false; + for (int face = 0; face < 6; face++) + { + mImageArray[face][level].redefine(format, size, size, type, true); + size = std::max(1, size >> 1); + } } - for (unsigned int f = 1; f < 6; f++) + for (int level = levels; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) { - if (mImageArray[f][0].width != mImageArray[0][0].width - || mImageArray[f][0].format != mImageArray[0][0].format) + for (int face = 0; face < 6; face++) { - return false; + mImageArray[face][level].redefine(GL_NONE, 0, 0, GL_UNSIGNED_BYTE, true); } } - return true; + if (mTexStorage->isManaged()) + { + int levels = levelCount(); + + for (int face = 0; face < 6; face++) + { + for (int level = 0; level < levels; level++) + { + IDirect3DSurface9 *surface = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level); + mImageArray[face][level].setManagedSurface(surface); + } + } + } } void TextureCubeMap::generateMipmaps() { - if (!isPow2(mImageArray[0][0].width) || !isCubeComplete()) + if (!isCubeComplete()) { return error(GL_INVALID_OPERATION); } - // Purge array levels 1 through q and reset them to represent the generated mipmap levels. - unsigned int q = log2(mImageArray[0][0].width); - for (unsigned int f = 0; f < 6; f++) + if (!getContext()->supportsNonPower2Texture()) { - for (unsigned int i = 1; i <= q; i++) + if (!isPow2(mImageArray[0][0].getWidth())) { - if (mImageArray[f][i].surface != NULL) - { - mImageArray[f][i].surface->Release(); - mImageArray[f][i].surface = NULL; - } - - mImageArray[f][i].dirty = false; - - mImageArray[f][i].format = mImageArray[f][0].format; - mImageArray[f][i].width = std::max(mImageArray[f][0].width >> i, 1); - mImageArray[f][i].height = mImageArray[f][i].width; + return error(GL_INVALID_OPERATION); } } - if (isRenderable()) + // Purge array levels 1 through q and reset them to represent the generated mipmap levels. + unsigned int q = log2(mImageArray[0][0].getWidth()); + for (unsigned int f = 0; f < 6; f++) { - if (mTexture == NULL) + for (unsigned int i = 1; i <= q; i++) { - return; + redefineImage(f, i, mImageArray[f][0].getFormat(), + std::max(mImageArray[f][0].getWidth() >> i, 1), + std::max(mImageArray[f][0].getWidth() >> i, 1), + mImageArray[f][0].getType()); } + } + if (mTexStorage && mTexStorage->isRenderTarget()) + { for (unsigned int f = 0; f < 6; f++) { for (unsigned int i = 1; i <= q; i++) { - IDirect3DSurface9 *upper = getCubeMapSurface(f, i-1); - IDirect3DSurface9 *lower = getCubeMapSurface(f, i); + IDirect3DSurface9 *upper = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i-1); + IDirect3DSurface9 *lower = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i); if (upper != NULL && lower != NULL) { @@ -2357,6 +3011,8 @@ void TextureCubeMap::generateMipmaps() if (upper != NULL) upper->Release(); if (lower != NULL) lower->Release(); + + mImageArray[f][i].markClean(); } } } @@ -2366,26 +3022,23 @@ void TextureCubeMap::generateMipmaps() { 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) + if (mImageArray[f][i].getSurface() == NULL) { return error(GL_OUT_OF_MEMORY); } - if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[f][i].surface, NULL, NULL, mImageArray[f][i - 1].surface, NULL, NULL, D3DX_FILTER_BOX, 0))) + if (FAILED(D3DXLoadSurfaceFromSurface(mImageArray[f][i].getSurface(), NULL, NULL, mImageArray[f][i - 1].getSurface(), NULL, NULL, D3DX_FILTER_BOX, 0))) { ERR(" failed to load filter %d to %d.", i - 1, i); } - mImageArray[f][i].dirty = true; + mImageArray[f][i].markDirty(); } } - - mDirtyMetaData = true; } } -Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target) +Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target) { if (!IsCubemapTextureTarget(target)) { @@ -2394,74 +3047,44 @@ Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target) unsigned int face = faceIndex(target); - if (mFaceProxies[face].get() == NULL) + if (mFaceProxies[face] == NULL) { - mFaceProxies[face].set(new Renderbuffer(id(), new TextureColorbufferProxy(this, target))); + mFaceProxies[face] = new Renderbuffer(id(), new RenderbufferTexture(this, target)); } - return mFaceProxies[face].get(); + return mFaceProxies[face]; } IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target) { ASSERT(IsCubemapTextureTarget(target)); - needRenderTarget(); - - if (mTexture == NULL) + // ensure the underlying texture is created + if (getStorage(true) == NULL) { return NULL; } - - IDirect3DSurface9 *renderTarget = NULL; - mTexture->GetCubeMapSurface(static_cast<D3DCUBEMAP_FACES>(faceIndex(target)), 0, &renderTarget); - - return renderTarget; -} - -Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLenum target) - : Colorbuffer(texture), mTexture(texture), mTarget(target) -{ - ASSERT(IsTextureTarget(target)); -} - -void Texture::TextureColorbufferProxy::addRef() const -{ - mTexture->addRef(); -} - -void Texture::TextureColorbufferProxy::release() const -{ - mTexture->release(); -} - -IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget() -{ - if (mRenderTarget) mRenderTarget->Release(); - - mRenderTarget = mTexture->getRenderTarget(mTarget); - return mRenderTarget; -} - -int Texture::TextureColorbufferProxy::getWidth() const -{ - return mTexture->getWidth(); -} - -int Texture::TextureColorbufferProxy::getHeight() const -{ - return mTexture->getHeight(); + updateTexture(); + + return mTexStorage->getCubeMapSurface(target, 0); } -GLenum Texture::TextureColorbufferProxy::getFormat() const +TextureStorage *TextureCubeMap::getStorage(bool renderTarget) { - return mTexture->getFormat(); -} + if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) + { + if (renderTarget) + { + convertToRenderTarget(); + } + else + { + createTexture(); + } + } -bool Texture::TextureColorbufferProxy::isFloatingPoint() const -{ - return mTexture->isFloatingPoint(); + return mTexStorage; } -} +}
\ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h index ca7aec7..19a6eb5 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/Texture.h @@ -17,14 +17,20 @@ #include <GLES2/gl2.h> #include <d3d9.h> +#include "common/debug.h" +#include "common/RefCountObject.h" #include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/RefCountObject.h" #include "libGLESv2/utilities.h" -#include "common/debug.h" + +namespace egl +{ +class Surface; +} namespace gl { class Blit; +class Framebuffer; enum { @@ -37,6 +43,129 @@ enum IMPLEMENTATION_MAX_TEXTURE_LEVELS = 15 // 1+log2 of MAX_TEXTURE_SIZE }; +class Image +{ + public: + Image(); + ~Image(); + + bool redefine(GLenum format, GLsizei width, GLsizei height, GLenum type, bool forceRelease); + void markDirty() {mDirty = true;} + void markClean() {mDirty = false;} + + HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); + void unlock(); + + bool isRenderableFormat() const; + D3DFORMAT getD3DFormat() const; + + GLsizei getWidth() const {return mWidth;} + GLsizei getHeight() const {return mHeight;} + GLenum getFormat() const {return mFormat;} + GLenum getType() const {return mType;} + bool isDirty() const {return mSurface && mDirty;} + IDirect3DSurface9 *getSurface(); + + void setManagedSurface(IDirect3DSurface9 *surface); + void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, + GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; + + void loadAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadLuminanceData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; + void loadLuminanceFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadLuminanceHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadLuminanceAlphaData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output, bool native) const; + void loadLuminanceAlphaFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadLuminanceAlphaHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGB565Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBAUByteDataSSE2(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBAUByteData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBA4444Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBA5551Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBAFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadRGBAHalfFloatData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadBGRAData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadDXT1Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadDXT3Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + void loadDXT5Data(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + int inputPitch, const void *input, size_t outputPitch, void *output) const; + + void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget); + + private: + DISALLOW_COPY_AND_ASSIGN(Image); + + void createSurface(); + + GLsizei mWidth; + GLsizei mHeight; + GLenum mFormat; + GLenum mType; + + bool mDirty; + + D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. + D3DFORMAT mD3DFormat; + + IDirect3DSurface9 *mSurface; +}; + +class TextureStorage +{ + public: + explicit TextureStorage(bool renderTarget); + + virtual ~TextureStorage(); + + bool isRenderTarget() const; + bool isManaged() const; + D3DPOOL getPool() const; + unsigned int getTextureSerial() const; + virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage); + + const bool mRenderTarget; + const D3DPOOL mD3DPool; + + const unsigned int mTextureSerial; + static unsigned int issueTextureSerial(); + + static unsigned int mCurrentTextureSerial; +}; + class Texture : public RefCountObject { public: @@ -44,167 +173,105 @@ class Texture : public RefCountObject virtual ~Texture(); + virtual void addProxyRef(const Renderbuffer *proxy) = 0; + virtual void releaseProxy(const Renderbuffer *proxy) = 0; + virtual GLenum getTarget() const = 0; bool setMinFilter(GLenum filter); bool setMagFilter(GLenum filter); bool setWrapS(GLenum wrap); bool setWrapT(GLenum wrap); + bool setUsage(GLenum usage); GLenum getMinFilter() const; GLenum getMagFilter() const; GLenum getWrapS() const; GLenum getWrapT() const; + GLenum getUsage() const; - GLuint getWidth() const; - GLuint getHeight() const; + virtual GLsizei getWidth(GLint level) const = 0; + virtual GLsizei getHeight(GLint level) const = 0; + virtual GLenum getInternalFormat() const = 0; + virtual GLenum getType() const = 0; + virtual D3DFORMAT getD3DFormat() const = 0; - virtual GLenum getFormat() const = 0; - virtual bool isComplete() const = 0; + virtual bool isSamplerComplete() 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 Renderbuffer *getRenderbuffer(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; - - static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. - - protected: - class TextureColorbufferProxy; - friend class TextureColorbufferProxy; - class TextureColorbufferProxy : public Colorbuffer - { - public: - TextureColorbufferProxy(Texture *texture, GLenum target); - // target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets) - - virtual void addRef() const; - virtual void release() const; - - virtual IDirect3DSurface9 *getRenderTarget(); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; - virtual int getWidth() const; - virtual int getHeight() const; - virtual GLenum getFormat() const; - virtual bool isFloatingPoint() const; + bool hasDirtyParameters() const; + bool hasDirtyImages() const; + void resetDirty(); + unsigned int getTextureSerial(); + unsigned int getRenderTargetSerial(GLenum target); - private: - Texture *mTexture; - GLenum mTarget; - }; + bool isImmutable() const; - // Helper structure representing a single image layer - struct Image - { - Image(); - ~Image(); + static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. - GLsizei width; - GLsizei height; - GLenum format; - - bool dirty; - - IDirect3DSurface9 *surface; - }; - - 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); + protected: + friend class RenderbufferTexture; - void needRenderTarget(); + void setImage(GLint unpackAlignment, const void *pixels, Image *image); + bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); + void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); + bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image); - GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const; - GLint creationLevels(GLsizei size, GLint maxlevel) const; + GLint creationLevels(GLsizei width, GLsizei height) const; + GLint creationLevels(GLsizei size) const; - // The pointer returned is weak and it is assumed the derived class will keep a strong pointer until the next createTexture() call. - virtual IDirect3DBaseTexture9 *createTexture() = 0; + virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; + virtual void createTexture() = 0; virtual void updateTexture() = 0; - virtual IDirect3DBaseTexture9 *convertToRenderTarget() = 0; + virtual void convertToRenderTarget() = 0; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0; - virtual bool dirtyImageData() const = 0; - - 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; + static Blit *getBlitter(); + static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); - unsigned int mWidth; - unsigned int mHeight; GLenum mMinFilter; GLenum mMagFilter; GLenum mWrapS; GLenum mWrapT; - GLenum mType; + bool mDirtyParameters; + GLenum mUsage; - bool mDirtyMetaData; + bool mDirtyImages; + + bool mImmutable; 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, 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, 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. + virtual TextureStorage *getStorage(bool renderTarget) = 0; +}; + +class TextureStorage2D : public TextureStorage +{ + public: + explicit TextureStorage2D(IDirect3DTexture9 *surfaceTexture); + TextureStorage2D(int levels, D3DFORMAT format, int width, int height, bool renderTarget); + + virtual ~TextureStorage2D(); - bool mDirty; - bool mIsRenderable; + IDirect3DSurface9 *getSurfaceLevel(int level); + IDirect3DBaseTexture9 *getBaseTexture() const; + + virtual unsigned int getRenderTargetSerial(GLenum target) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage2D); + + IDirect3DTexture9 *mTexture; + const unsigned int mRenderTargetSerial; }; class Texture2D : public Texture @@ -214,41 +281,80 @@ class Texture2D : public Texture ~Texture2D(); - GLenum getTarget() const; - GLenum getFormat() const; + void addProxyRef(const Renderbuffer *proxy); + void releaseProxy(const Renderbuffer *proxy); + + virtual GLenum getTarget() const; - void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); + virtual GLsizei getWidth(GLint level) const; + virtual GLsizei getHeight(GLint level) const; + virtual GLenum getInternalFormat() const; + virtual GLenum getType() const; + virtual D3DFORMAT getD3DFormat() const; + + void setImage(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setCompressedImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, 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(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source); + void copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + void storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); - bool isComplete() const; - bool isCompressed() const; + virtual bool isSamplerComplete() const; + virtual bool isCompressed() const; + virtual void bindTexImage(egl::Surface *surface); + virtual void releaseTexImage(); virtual void generateMipmaps(); - virtual Renderbuffer *getColorbuffer(GLenum target); + virtual Renderbuffer *getRenderbuffer(GLenum target); private: DISALLOW_COPY_AND_ASSIGN(Texture2D); - virtual IDirect3DBaseTexture9 *createTexture(); + virtual IDirect3DBaseTexture9 *getBaseTexture() const; + virtual void createTexture(); virtual void updateTexture(); - virtual IDirect3DBaseTexture9 *convertToRenderTarget(); + virtual void convertToRenderTarget(); virtual IDirect3DSurface9 *getRenderTarget(GLenum target); + virtual TextureStorage *getStorage(bool renderTarget); - virtual bool dirtyImageData() const; + bool isMipmapComplete() const; - bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum type); + void redefineImage(GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); Image mImageArray[IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - IDirect3DTexture9 *mTexture; + TextureStorage2D *mTexStorage; + egl::Surface *mSurface; - BindingPointer<Renderbuffer> mColorbufferProxy; + // A specific internal reference count is kept for colorbuffer proxy references, + // because, as the renderbuffer acting as proxy will maintain a binding pointer + // back to this texture, there would be a circular reference if we used a binding + // pointer here. This reference count will cause the pointer to be set to NULL if + // the count drops to zero, but will not cause deletion of the Renderbuffer. + Renderbuffer *mColorbufferProxy; + unsigned int mProxyRefs; +}; + +class TextureStorageCubeMap : public TextureStorage +{ + public: + TextureStorageCubeMap(int levels, D3DFORMAT format, int size, bool renderTarget); + + virtual ~TextureStorageCubeMap(); + + IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level); + IDirect3DBaseTexture9 *getBaseTexture() const; + + virtual unsigned int getRenderTargetSerial(GLenum target) const; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorageCubeMap); + + IDirect3DCubeTexture9 *mTexture; + const unsigned int mFirstRenderTargetSerial; }; class TextureCubeMap : public Texture @@ -258,58 +364,70 @@ class TextureCubeMap : public Texture ~TextureCubeMap(); - GLenum getTarget() const; - GLenum getFormat() const; + void addProxyRef(const Renderbuffer *proxy); + void releaseProxy(const Renderbuffer *proxy); + + virtual GLenum getTarget() const; + + virtual GLsizei getWidth(GLint level) const; + virtual GLsizei getHeight(GLint level) const; + virtual GLenum getInternalFormat() const; + virtual GLenum getType() const; + virtual D3DFORMAT getD3DFormat() const; - void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImagePosY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegY(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImagePosX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImageNegX(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImagePosY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImageNegY(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImagePosZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void setImageNegZ(GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); + void setCompressedImage(GLenum face, GLint level, GLenum format, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); void subImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, 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); + void copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source); + void storage(GLsizei levels, GLenum internalformat, GLsizei size); - bool isComplete() const; - bool isCompressed() const; + virtual bool isSamplerComplete() const; + virtual bool isCompressed() const; virtual void generateMipmaps(); - virtual Renderbuffer *getColorbuffer(GLenum target); + virtual Renderbuffer *getRenderbuffer(GLenum target); + + static unsigned int faceIndex(GLenum face); private: DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); - virtual IDirect3DBaseTexture9 *createTexture(); + virtual IDirect3DBaseTexture9 *getBaseTexture() const; + virtual void createTexture(); virtual void updateTexture(); - virtual IDirect3DBaseTexture9 *convertToRenderTarget(); + virtual void convertToRenderTarget(); virtual IDirect3DSurface9 *getRenderTarget(GLenum target); - - virtual bool dirtyImageData() const; - - // faceIdentifier is 0-5 or one of the GL_TEXTURE_CUBE_MAP_* enumerants. - // Returns NULL if the call underlying Direct3D call fails. - IDirect3DSurface9 *getCubeMapSurface(unsigned int faceIdentifier, unsigned int level); - - static unsigned int faceIndex(GLenum face); + virtual TextureStorage *getStorage(bool renderTarget); bool isCubeComplete() const; + bool isMipmapCubeComplete() const; - void setImage(int face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); - void commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width); + void setImage(int faceIndex, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels); + void commitRect(int faceIndex, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + void redefineImage(int faceIndex, GLint level, GLenum format, GLsizei width, GLsizei height, GLenum type); Image mImageArray[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS]; - IDirect3DCubeTexture9 *mTexture; + TextureStorageCubeMap *mTexStorage; - BindingPointer<Renderbuffer> mFaceProxies[6]; + // A specific internal reference count is kept for colorbuffer proxy references, + // because, as the renderbuffer acting as proxy will maintain a binding pointer + // back to this texture, there would be a circular reference if we used a binding + // pointer here. This reference count will cause the pointer to be set to NULL if + // the count drops to zero, but will not cause deletion of the Renderbuffer. + Renderbuffer *mFaceProxies[6]; + unsigned int *mFaceProxyRefs[6]; }; } -#endif // LIBGLESV2_TEXTURE_H_ +#endif // LIBGLESV2_TEXTURE_H_
\ No newline at end of file diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp new file mode 100644 index 0000000..95bc3fb --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.cpp @@ -0,0 +1,782 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDataManager.h: Defines the VertexDataManager, a class that +// runs the Buffer translation process. + +#include "libGLESv2/VertexDataManager.h" + +#include "common/debug.h" + +#include "libGLESv2/Buffer.h" +#include "libGLESv2/Program.h" +#include "libGLESv2/main.h" + +#include "libGLESv2/vertexconversion.h" +#include "libGLESv2/IndexDataManager.h" + +namespace +{ + enum { INITIAL_STREAM_BUFFER_SIZE = 1024*1024 }; + // This has to be at least 4k or else it fails on ATI cards. + enum { CONSTANT_VERTEX_BUFFER_SIZE = 4096 }; +} + +namespace gl +{ +unsigned int VertexBuffer::mCurrentSerial = 1; + +int elementsInBuffer(const VertexAttribute &attribute, int size) +{ + int stride = attribute.stride(); + return (size - attribute.mOffset % stride + (stride - attribute.typeSize())) / stride; +} + +VertexDataManager::VertexDataManager(Context *context, IDirect3DDevice9 *device) : mContext(context), mDevice(device) +{ + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + mDirtyCurrentValue[i] = true; + mCurrentValueBuffer[i] = NULL; + mCurrentValueOffsets[i] = 0; + } + + const D3DCAPS9 &caps = context->getDeviceCaps(); + checkVertexCaps(caps.DeclTypes); + + mStreamingBuffer = new StreamingVertexBuffer(mDevice, INITIAL_STREAM_BUFFER_SIZE); + + if (!mStreamingBuffer) + { + ERR("Failed to allocate the streaming vertex buffer."); + } +} + +VertexDataManager::~VertexDataManager() +{ + delete mStreamingBuffer; + + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + delete mCurrentValueBuffer[i]; + } +} + +std::size_t VertexDataManager::writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances) +{ + Buffer *buffer = attribute.mBoundBuffer.get(); + + int inputStride = attribute.stride(); + int elementSize = attribute.typeSize(); + const FormatConverter &converter = formatConverter(attribute); + std::size_t streamOffset = 0; + + void *output = NULL; + + if (vertexBuffer) + { + output = vertexBuffer->map(attribute, spaceRequired(attribute, count, instances), &streamOffset); + } + + if (output == NULL) + { + ERR("Failed to map vertex buffer."); + return -1; + } + + const char *input = NULL; + + if (buffer) + { + int offset = attribute.mOffset; + + input = static_cast<const char*>(buffer->data()) + offset; + } + else + { + input = static_cast<const char*>(attribute.mPointer); + } + + if (instances == 0 || attribute.mDivisor == 0) + { + input += inputStride * start; + } + + if (converter.identity && inputStride == elementSize) + { + memcpy(output, input, count * inputStride); + } + else + { + converter.convertArray(input, inputStride, count, output); + } + + vertexBuffer->unmap(); + + return streamOffset; +} + +GLenum VertexDataManager::prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *translated, GLsizei instances) +{ + if (!mStreamingBuffer) + { + return GL_OUT_OF_MEMORY; + } + + const VertexAttributeArray &attribs = mContext->getVertexAttributes(); + 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, and invalidate static buffers that don't contain matching attributes + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (translated[i].active && attribs[i].mArrayEnabled) + { + Buffer *buffer = attribs[i].mBoundBuffer.get(); + StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; + + if (staticBuffer) + { + if (staticBuffer->size() == 0) + { + int totalCount = elementsInBuffer(attribs[i], buffer->size()); + staticBuffer->addRequiredSpace(spaceRequired(attribs[i], totalCount, 0)); + } + else if (staticBuffer->lookupAttribute(attribs[i]) == -1) + { + // This static buffer doesn't have matching attributes, so fall back to using the streaming buffer + // Add the space of all previous attributes belonging to the invalidated static buffer to the streaming buffer + for (int previous = 0; previous < i; previous++) + { + if (translated[previous].active && attribs[previous].mArrayEnabled) + { + Buffer *previousBuffer = attribs[previous].mBoundBuffer.get(); + StaticVertexBuffer *previousStaticBuffer = previousBuffer ? previousBuffer->getStaticVertexBuffer() : NULL; + + if (staticBuffer == previousStaticBuffer) + { + mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[previous], count, instances)); + } + } + } + + mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); + + buffer->invalidateStaticData(); + } + } + else + { + mStreamingBuffer->addRequiredSpace(spaceRequired(attribs[i], count, instances)); + } + } + } + + // Reserve the required space per used buffer + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (translated[i].active && attribs[i].mArrayEnabled) + { + Buffer *buffer = attribs[i].mBoundBuffer.get(); + ArrayVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; + ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : mStreamingBuffer; + + if (vertexBuffer) + { + vertexBuffer->reserveRequiredSpace(); + } + } + } + + // Perform the vertex data translations + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (translated[i].active) + { + if (attribs[i].mArrayEnabled) + { + Buffer *buffer = attribs[i].mBoundBuffer.get(); + + if (!buffer && attribs[i].mPointer == NULL) + { + // This is an application error that would normally result in a crash, but we catch it and return an error + ERR("An enabled vertex array has no buffer and no pointer."); + return GL_INVALID_OPERATION; + } + + const FormatConverter &converter = formatConverter(attribs[i]); + + StaticVertexBuffer *staticBuffer = buffer ? buffer->getStaticVertexBuffer() : NULL; + ArrayVertexBuffer *vertexBuffer = staticBuffer ? staticBuffer : static_cast<ArrayVertexBuffer*>(mStreamingBuffer); + + std::size_t streamOffset = -1; + + if (staticBuffer) + { + streamOffset = staticBuffer->lookupAttribute(attribs[i]); + + if (streamOffset == -1) + { + // Convert the entire buffer + int totalCount = elementsInBuffer(attribs[i], buffer->size()); + int startIndex = attribs[i].mOffset / attribs[i].stride(); + + streamOffset = writeAttributeData(staticBuffer, -startIndex, totalCount, attribs[i], 0); + } + + if (streamOffset != -1) + { + streamOffset += (attribs[i].mOffset / attribs[i].stride()) * converter.outputElementSize; + + if (instances == 0 || attribs[i].mDivisor == 0) + { + streamOffset += start * converter.outputElementSize; + } + } + } + else + { + streamOffset = writeAttributeData(mStreamingBuffer, start, count, attribs[i], instances); + } + + if (streamOffset == -1) + { + return GL_OUT_OF_MEMORY; + } + + translated[i].vertexBuffer = vertexBuffer->getBuffer(); + translated[i].serial = vertexBuffer->getSerial(); + translated[i].divisor = attribs[i].mDivisor; + + translated[i].type = converter.d3dDeclType; + translated[i].stride = converter.outputElementSize; + translated[i].offset = streamOffset; + } + else + { + if (!mCurrentValueBuffer[i]) + { + mCurrentValueBuffer[i] = new StreamingVertexBuffer(mDevice, CONSTANT_VERTEX_BUFFER_SIZE); + } + + StreamingVertexBuffer *buffer = mCurrentValueBuffer[i]; + + if (mDirtyCurrentValue[i]) + { + const int requiredSpace = 4 * sizeof(float); + buffer->addRequiredSpace(requiredSpace); + buffer->reserveRequiredSpace(); + float *data = static_cast<float*>(buffer->map(VertexAttribute(), requiredSpace, &mCurrentValueOffsets[i])); + if (data) + { + data[0] = attribs[i].mCurrentValue[0]; + data[1] = attribs[i].mCurrentValue[1]; + data[2] = attribs[i].mCurrentValue[2]; + data[3] = attribs[i].mCurrentValue[3]; + buffer->unmap(); + mDirtyCurrentValue[i] = false; + } + } + + translated[i].vertexBuffer = mCurrentValueBuffer[i]->getBuffer(); + translated[i].serial = mCurrentValueBuffer[i]->getSerial(); + translated[i].divisor = 0; + + translated[i].type = D3DDECLTYPE_FLOAT4; + translated[i].stride = 0; + translated[i].offset = mCurrentValueOffsets[i]; + } + } + } + + for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) + { + if (translated[i].active && attribs[i].mArrayEnabled) + { + Buffer *buffer = attribs[i].mBoundBuffer.get(); + + if (buffer) + { + buffer->promoteStaticUsage(count * attribs[i].typeSize()); + } + } + } + + return GL_NO_ERROR; +} + +std::size_t VertexDataManager::spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const +{ + size_t elementSize = formatConverter(attrib).outputElementSize; + + if (instances == 0 || attrib.mDivisor == 0) + { + return elementSize * count; + } + else + { + return elementSize * ((instances + attrib.mDivisor - 1) / attrib.mDivisor); + } +} + +// Mapping from OpenGL-ES vertex attrib type to D3D decl type: +// +// BYTE SHORT (Cast) +// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) +// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) +// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) +// SHORT SHORT (Identity) +// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) +// UNSIGNED_SHORT FLOAT (Cast) +// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) +// FIXED (not in WebGL) FLOAT (FixedToFloat) +// FLOAT FLOAT (Identity) + +// GLToCType maps from GL type (as GLenum) to the C typedef. +template <GLenum GLType> struct GLToCType { }; + +template <> struct GLToCType<GL_BYTE> { typedef GLbyte type; }; +template <> struct GLToCType<GL_UNSIGNED_BYTE> { typedef GLubyte type; }; +template <> struct GLToCType<GL_SHORT> { typedef GLshort type; }; +template <> struct GLToCType<GL_UNSIGNED_SHORT> { typedef GLushort type; }; +template <> struct GLToCType<GL_FIXED> { typedef GLuint type; }; +template <> struct GLToCType<GL_FLOAT> { typedef GLfloat type; }; + +// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) +enum D3DVertexType +{ + D3DVT_FLOAT, + D3DVT_SHORT, + D3DVT_SHORT_NORM, + D3DVT_UBYTE, + D3DVT_UBYTE_NORM, + D3DVT_USHORT_NORM +}; + +// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. +template <unsigned int D3DType> struct D3DToCType { }; + +template <> struct D3DToCType<D3DVT_FLOAT> { typedef float type; }; +template <> struct D3DToCType<D3DVT_SHORT> { typedef short type; }; +template <> struct D3DToCType<D3DVT_SHORT_NORM> { typedef short type; }; +template <> struct D3DToCType<D3DVT_UBYTE> { typedef unsigned char type; }; +template <> struct D3DToCType<D3DVT_UBYTE_NORM> { typedef unsigned char type; }; +template <> struct D3DToCType<D3DVT_USHORT_NORM> { typedef unsigned short type; }; + +// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. +template <unsigned int type, int size> +struct WidenRule +{ +}; + +template <int size> struct WidenRule<D3DVT_FLOAT, size> : gl::NoWiden<size> { }; +template <int size> struct WidenRule<D3DVT_SHORT, size> : gl::WidenToEven<size> { }; +template <int size> struct WidenRule<D3DVT_SHORT_NORM, size> : gl::WidenToEven<size> { }; +template <int size> struct WidenRule<D3DVT_UBYTE, size> : gl::WidenToFour<size> { }; +template <int size> struct WidenRule<D3DVT_UBYTE_NORM, size> : gl::WidenToFour<size> { }; +template <int size> struct WidenRule<D3DVT_USHORT_NORM, size> : gl::WidenToEven<size> { }; + +// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. +template <unsigned int d3dtype, int size> +struct VertexTypeFlags +{ +}; + +template <unsigned int capflag, unsigned int declflag> +struct VertexTypeFlagsHelper +{ + enum { capflag = capflag }; + enum { declflag = declflag }; +}; + +template <> struct VertexTypeFlags<D3DVT_FLOAT, 1> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 3> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; +template <> struct VertexTypeFlags<D3DVT_FLOAT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT, 2> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT, 4> : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N> { }; +template <> struct VertexTypeFlags<D3DVT_SHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N> { }; +template <> struct VertexTypeFlags<D3DVT_UBYTE, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4> { }; +template <> struct VertexTypeFlags<D3DVT_UBYTE_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N> { }; +template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 2> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N> { }; +template <> struct VertexTypeFlags<D3DVT_USHORT_NORM, 4> : VertexTypeFlagsHelper<D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N> { }; + + +// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). +template <GLenum GLtype, bool normalized> +struct VertexTypeMapping +{ +}; + +template <D3DVertexType Preferred, D3DVertexType Fallback = Preferred> +struct VertexTypeMappingBase +{ + enum { preferred = Preferred }; + enum { fallback = Fallback }; +}; + +template <> struct VertexTypeMapping<GL_BYTE, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Cast +template <> struct VertexTypeMapping<GL_BYTE, true> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Normalize +template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, false> : VertexTypeMappingBase<D3DVT_UBYTE, D3DVT_FLOAT> { }; // Identity, Cast +template <> struct VertexTypeMapping<GL_UNSIGNED_BYTE, true> : VertexTypeMappingBase<D3DVT_UBYTE_NORM, D3DVT_FLOAT> { }; // Identity, Normalize +template <> struct VertexTypeMapping<GL_SHORT, false> : VertexTypeMappingBase<D3DVT_SHORT> { }; // Identity +template <> struct VertexTypeMapping<GL_SHORT, true> : VertexTypeMappingBase<D3DVT_SHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize +template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, false> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Cast +template <> struct VertexTypeMapping<GL_UNSIGNED_SHORT, true> : VertexTypeMappingBase<D3DVT_USHORT_NORM, D3DVT_FLOAT> { }; // Cast, Normalize +template <bool normalized> struct VertexTypeMapping<GL_FIXED, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // FixedToFloat +template <bool normalized> struct VertexTypeMapping<GL_FLOAT, normalized> : VertexTypeMappingBase<D3DVT_FLOAT> { }; // Identity + + +// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). +// The conversion rules themselves are defined in vertexconversion.h. + +// Almost all cases are covered by Cast (including those that are actually Identity since Cast<T,T> knows it's an identity mapping). +template <GLenum fromType, bool normalized, unsigned int toType> +struct ConversionRule : gl::Cast<typename GLToCType<fromType>::type, typename D3DToCType<toType>::type> +{ +}; + +// All conversions from normalized types to float use the Normalize operator. +template <GLenum fromType> struct ConversionRule<fromType, true, D3DVT_FLOAT> : gl::Normalize<typename GLToCType<fromType>::type> { }; + +// Use a full specialisation for this so that it preferentially matches ahead of the generic normalize-to-float rules. +template <> struct ConversionRule<GL_FIXED, true, D3DVT_FLOAT> : gl::FixedToFloat<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) }, \ + } + +#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ + { \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + } + +const VertexDataManager::TranslationDescription VertexDataManager::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] +{ + TRANSLATIONS_FOR_TYPE(GL_BYTE), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), + TRANSLATIONS_FOR_TYPE(GL_SHORT), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) +}; + +void VertexDataManager::checkVertexCaps(DWORD declTypes) +{ + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 4; k++) + { + if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) + { + mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; + } + else + { + mAttributeTypes[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; + } + } + } + } +} + +// This is used to index mAttributeTypes and mPossibleTranslations. +unsigned int VertexDataManager::typeIndex(GLenum type) const +{ + switch (type) + { + case GL_BYTE: return 0; + case GL_UNSIGNED_BYTE: return 1; + case GL_SHORT: return 2; + case GL_UNSIGNED_SHORT: return 3; + case GL_FIXED: return 4; + case GL_FLOAT: return 5; + + default: UNREACHABLE(); return 5; + } +} + +VertexBuffer::VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : mDevice(device), mVertexBuffer(NULL) +{ + if (size > 0) + { + D3DPOOL pool = getDisplay()->getBufferPool(usageFlags); + HRESULT result = device->CreateVertexBuffer(size, usageFlags, 0, pool, &mVertexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", size); + } + } +} + +VertexBuffer::~VertexBuffer() +{ + if (mVertexBuffer) + { + mVertexBuffer->Release(); + } +} + +void VertexBuffer::unmap() +{ + if (mVertexBuffer) + { + mVertexBuffer->Unlock(); + } +} + +IDirect3DVertexBuffer9 *VertexBuffer::getBuffer() const +{ + return mVertexBuffer; +} + +unsigned int VertexBuffer::getSerial() const +{ + return mSerial; +} + +unsigned int VertexBuffer::issueSerial() +{ + return mCurrentSerial++; +} + +ArrayVertexBuffer::ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags) : VertexBuffer(device, size, usageFlags) +{ + mBufferSize = size; + mWritePosition = 0; + mRequiredSpace = 0; +} + +ArrayVertexBuffer::~ArrayVertexBuffer() +{ +} + +void ArrayVertexBuffer::addRequiredSpace(UINT requiredSpace) +{ + mRequiredSpace += requiredSpace; +} + +StreamingVertexBuffer::StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize) : ArrayVertexBuffer(device, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY) +{ +} + +StreamingVertexBuffer::~StreamingVertexBuffer() +{ +} + +void *StreamingVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset) +{ + void *mapPtr = NULL; + + if (mVertexBuffer) + { + HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE); + + if (FAILED(result)) + { + ERR("Lock failed with error 0x%08x", result); + return NULL; + } + + *offset = mWritePosition; + mWritePosition += requiredSpace; + } + + return mapPtr; +} + +void StreamingVertexBuffer::reserveRequiredSpace() +{ + if (mRequiredSpace > mBufferSize) + { + if (mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } + + mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2); // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations. + + D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY); + HRESULT result = mDevice->CreateVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize); + } + + mWritePosition = 0; + } + else if (mWritePosition + mRequiredSpace > mBufferSize) // Recycle + { + if (mVertexBuffer) + { + void *dummy; + mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + mVertexBuffer->Unlock(); + } + + mWritePosition = 0; + } + + mRequiredSpace = 0; +} + +StaticVertexBuffer::StaticVertexBuffer(IDirect3DDevice9 *device) : ArrayVertexBuffer(device, 0, D3DUSAGE_WRITEONLY) +{ +} + +StaticVertexBuffer::~StaticVertexBuffer() +{ +} + +void *StaticVertexBuffer::map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) +{ + void *mapPtr = NULL; + + if (mVertexBuffer) + { + HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0); + + if (FAILED(result)) + { + ERR("Lock failed with error 0x%08x", result); + return NULL; + } + + int attributeOffset = attribute.mOffset % attribute.stride(); + VertexElement element = {attribute.mType, attribute.mSize, attribute.stride(), attribute.mNormalized, attributeOffset, mWritePosition}; + mCache.push_back(element); + + *streamOffset = mWritePosition; + mWritePosition += requiredSpace; + } + + return mapPtr; +} + +void StaticVertexBuffer::reserveRequiredSpace() +{ + if (!mVertexBuffer && mBufferSize == 0) + { + D3DPOOL pool = getDisplay()->getBufferPool(D3DUSAGE_WRITEONLY); + HRESULT result = mDevice->CreateVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, 0, pool, &mVertexBuffer, NULL); + mSerial = issueSerial(); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace); + } + + mBufferSize = mRequiredSpace; + } + else if (mVertexBuffer && mBufferSize >= mRequiredSpace) + { + // Already allocated + } + else UNREACHABLE(); // Static vertex buffers can't be resized + + mRequiredSpace = 0; +} + +std::size_t StaticVertexBuffer::lookupAttribute(const VertexAttribute &attribute) +{ + for (unsigned int element = 0; element < mCache.size(); element++) + { + if (mCache[element].type == attribute.mType && + mCache[element].size == attribute.mSize && + mCache[element].stride == attribute.stride() && + mCache[element].normalized == attribute.mNormalized) + { + if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride()) + { + return mCache[element].streamOffset; + } + } + } + + return -1; +} + +const VertexDataManager::FormatConverter &VertexDataManager::formatConverter(const VertexAttribute &attribute) const +{ + return mAttributeTypes[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1]; +} +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.h b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.h new file mode 100644 index 0000000..857591a --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/VertexDataManager.h @@ -0,0 +1,169 @@ +// +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// VertexDataManager.h: Defines the VertexDataManager, a class that +// runs the Buffer translation process. + +#ifndef LIBGLESV2_VERTEXDATAMANAGER_H_ +#define LIBGLESV2_VERTEXDATAMANAGER_H_ + +#include <vector> +#include <cstddef> + +#define GL_APICALL +#include <GLES2/gl2.h> + +#include "libGLESv2/Context.h" + +namespace gl +{ + +struct TranslatedAttribute +{ + bool active; + + D3DDECLTYPE type; + UINT offset; + UINT stride; // 0 means not to advance the read pointer at all + + IDirect3DVertexBuffer9 *vertexBuffer; + unsigned int serial; + unsigned int divisor; +}; + +class VertexBuffer +{ + public: + VertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags); + virtual ~VertexBuffer(); + + void unmap(); + + IDirect3DVertexBuffer9 *getBuffer() const; + unsigned int getSerial() const; + + protected: + IDirect3DDevice9 *const mDevice; + IDirect3DVertexBuffer9 *mVertexBuffer; + + unsigned int mSerial; + static unsigned int issueSerial(); + static unsigned int mCurrentSerial; + + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer); +}; + +class ArrayVertexBuffer : public VertexBuffer +{ + public: + ArrayVertexBuffer(IDirect3DDevice9 *device, std::size_t size, DWORD usageFlags); + ~ArrayVertexBuffer(); + + std::size_t size() const { return mBufferSize; } + virtual void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset) = 0; + virtual void reserveRequiredSpace() = 0; + void addRequiredSpace(UINT requiredSpace); + + protected: + std::size_t mBufferSize; + std::size_t mWritePosition; + std::size_t mRequiredSpace; +}; + +class StreamingVertexBuffer : public ArrayVertexBuffer +{ + public: + StreamingVertexBuffer(IDirect3DDevice9 *device, std::size_t initialSize); + ~StreamingVertexBuffer(); + + void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset); + void reserveRequiredSpace(); +}; + +class StaticVertexBuffer : public ArrayVertexBuffer +{ + public: + explicit StaticVertexBuffer(IDirect3DDevice9 *device); + ~StaticVertexBuffer(); + + void *map(const VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset); + void reserveRequiredSpace(); + + std::size_t lookupAttribute(const VertexAttribute &attribute); // Returns the offset into the vertex buffer, or -1 if not found + + private: + struct VertexElement + { + GLenum type; + GLint size; + GLsizei stride; + bool normalized; + int attributeOffset; + + std::size_t streamOffset; + }; + + std::vector<VertexElement> mCache; +}; + +class VertexDataManager +{ + public: + VertexDataManager(Context *context, IDirect3DDevice9 *backend); + virtual ~VertexDataManager(); + + void dirtyCurrentValue(int index) { mDirtyCurrentValue[index] = true; } + + GLenum prepareVertexData(GLint start, GLsizei count, TranslatedAttribute *outAttribs, GLsizei instances); + + private: + DISALLOW_COPY_AND_ASSIGN(VertexDataManager); + + std::size_t spaceRequired(const VertexAttribute &attrib, std::size_t count, GLsizei instances) const; + std::size_t writeAttributeData(ArrayVertexBuffer *vertexBuffer, GLint start, GLsizei count, const VertexAttribute &attribute, GLsizei instances); + + Context *const mContext; + IDirect3DDevice9 *const mDevice; + + StreamingVertexBuffer *mStreamingBuffer; + + bool mDirtyCurrentValue[MAX_VERTEX_ATTRIBS]; + StreamingVertexBuffer *mCurrentValueBuffer[MAX_VERTEX_ATTRIBS]; + std::size_t mCurrentValueOffsets[MAX_VERTEX_ATTRIBS]; + + // Attribute format conversion + struct FormatConverter + { + bool identity; + std::size_t outputElementSize; + void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); + D3DDECLTYPE d3dDeclType; + }; + + enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; + + FormatConverter mAttributeTypes[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1] + + struct TranslationDescription + { + DWORD capsFlag; + FormatConverter preferredConversion; + FormatConverter fallbackConversion; + }; + + // This table is used to generate mAttributeTypes. + static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1] + + void checkVertexCaps(DWORD declTypes); + + unsigned int typeIndex(GLenum type) const; + const FormatConverter &formatConverter(const VertexAttribute &attribute) const; +}; + +} + +#endif // LIBGLESV2_VERTEXDATAMANAGER_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp index 543c0d2..ee8eca9 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.cpp @@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // @@ -14,6 +14,7 @@ #include <limits> #include "common/debug.h" +#include "common/version.h" #include "libGLESv2/main.h" #include "libGLESv2/mathutil.h" @@ -26,25 +27,126 @@ #include "libGLESv2/Renderbuffer.h" #include "libGLESv2/Shader.h" #include "libGLESv2/Texture.h" +#include "libGLESv2/Query.h" -extern "C" +bool validImageSize(GLint level, GLsizei width, GLsizei height) { + if (level < 0 || width < 0 || height < 0) + { + return false; + } -void __stdcall glActiveTexture(GLenum texture) + if (gl::getContext() && gl::getContext()->supportsNonPower2Texture()) + { + return true; + } + + if (level == 0) + { + return true; + } + + if (gl::isPow2(width) && gl::isPow2(height)) + { + return true; + } + + return false; +} + +bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLint level, GLenum format, gl::Texture *texture) { - TRACE("(GLenum texture = 0x%X)", texture); + if (!texture) + { + return error(GL_INVALID_OPERATION, false); + } - try + if (compressed != texture->isCompressed()) { - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1) + return error(GL_INVALID_OPERATION, false); + } + + if (format != GL_NONE && format != texture->getInternalFormat()) + { + return error(GL_INVALID_OPERATION, false); + } + + if (compressed) + { + if ((width % 4 != 0 && width != texture->getWidth(0)) || + (height % 4 != 0 && height != texture->getHeight(0))) { - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION, false); } + } - gl::Context *context = gl::getContext(); + if (xoffset + width > texture->getWidth(level) || + yoffset + height > texture->getHeight(level)) + { + return error(GL_INVALID_VALUE, false); + } + + return true; +} + +// check for combinations of format and type that are valid for ReadPixels +bool validReadFormatType(GLenum format, GLenum type) +{ + switch (format) + { + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + break; + default: + return false; + } + break; + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + break; + default: + return false; + } + break; + case gl::IMPLEMENTATION_COLOR_READ_FORMAT: + switch (type) + { + case gl::IMPLEMENTATION_COLOR_READ_TYPE: + break; + default: + return false; + } + break; + default: + return false; + } + return true; +} + +extern "C" +{ + +void __stdcall glActiveTexture(GLenum texture) +{ + EVENT("(GLenum texture = 0x%X)", texture); + + try + { + gl::Context *context = gl::getNonLostContext(); if (context) { + if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1) + { + return error(GL_INVALID_ENUM); + } + context->setActiveSampler(texture - GL_TEXTURE0); } } @@ -56,11 +158,11 @@ void __stdcall glActiveTexture(GLenum texture) void __stdcall glAttachShader(GLuint program, GLuint shader) { - TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader); + EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -103,9 +205,42 @@ void __stdcall glAttachShader(GLuint program, GLuint shader) } } +void __stdcall glBeginQueryEXT(GLenum target, GLuint id) +{ + EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); + + try + { + switch (target) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + break; + default: + return error(GL_INVALID_ENUM); + } + + if (id == 0) + { + return error(GL_INVALID_OPERATION); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->beginQuery(target, id); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) { - TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); + EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); try { @@ -114,7 +249,7 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -148,11 +283,11 @@ void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* void __stdcall glBindBuffer(GLenum target, GLuint buffer) { - TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); + EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -177,7 +312,7 @@ void __stdcall glBindBuffer(GLenum target, GLuint buffer) void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) { - TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); + EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); try { @@ -186,7 +321,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -209,7 +344,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) { - TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); + EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); try { @@ -218,7 +353,7 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -233,11 +368,11 @@ void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) void __stdcall glBindTexture(GLenum target, GLuint texture) { - TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); + EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -269,12 +404,12 @@ void __stdcall glBindTexture(GLenum target, GLuint texture) void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", + EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); try { - gl::Context* context = gl::getContext(); + gl::Context* context = gl::getNonLostContext(); if (context) { @@ -294,7 +429,7 @@ void __stdcall glBlendEquation(GLenum mode) void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) { - TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); + EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); try { @@ -318,7 +453,7 @@ void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -338,7 +473,7 @@ void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { - TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", + EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", srcRGB, dstRGB, srcAlpha, dstAlpha); try @@ -441,7 +576,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha return error(GL_INVALID_OPERATION); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -456,7 +591,7 @@ void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { - TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", + EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", target, size, data, usage); try @@ -476,7 +611,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -510,7 +645,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) { - TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", + EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", target, offset, size, data); try @@ -525,7 +660,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -564,7 +699,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLenum __stdcall glCheckFramebufferStatus(GLenum target) { - TRACE("(GLenum target = 0x%X)", target); + EVENT("(GLenum target = 0x%X)", target); try { @@ -573,7 +708,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) return error(GL_INVALID_ENUM, 0); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -600,11 +735,11 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target) void __stdcall glClear(GLbitfield mask) { - TRACE("(GLbitfield mask = %X)", mask); + EVENT("(GLbitfield mask = %X)", mask); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -619,12 +754,12 @@ void __stdcall glClear(GLbitfield mask) void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { - TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", + EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", red, green, blue, alpha); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -639,11 +774,11 @@ void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclamp void __stdcall glClearDepthf(GLclampf depth) { - TRACE("(GLclampf depth = %f)", depth); + EVENT("(GLclampf depth = %f)", depth); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -658,11 +793,11 @@ void __stdcall glClearDepthf(GLclampf depth) void __stdcall glClearStencil(GLint s) { - TRACE("(GLint s = %d)", s); + EVENT("(GLint s = %d)", s); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -677,12 +812,12 @@ void __stdcall glClearStencil(GLint s) void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", + EVENT("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", red, green, blue, alpha); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -697,11 +832,11 @@ void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboo void __stdcall glCompileShader(GLuint shader) { - TRACE("(GLuint shader = %d)", shader); + EVENT("(GLuint shader = %d)", shader); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -731,18 +866,13 @@ void __stdcall glCompileShader(GLuint shader) void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", target, level, internalformat, width, height, border, imageSize, data); try { - if (level < 0) - { - return error(GL_INVALID_VALUE); - } - - if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0) + if (!validImageSize(level, width, height) || border != 0 || imageSize < 0) { return error(GL_INVALID_VALUE); } @@ -751,6 +881,8 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: break; default: return error(GL_INVALID_ENUM); @@ -761,7 +893,7 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -800,9 +932,27 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna 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 + switch (internalformat) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->supportsDXT1Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->supportsDXT3Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->supportsDXT5Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + default: UNREACHABLE(); } if (imageSize != gl::ComputeCompressedSize(width, height, internalformat)) @@ -819,6 +969,11 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna return error(GL_INVALID_OPERATION); } + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + texture->setCompressedImage(level, internalformat, width, height, imageSize, data); } else @@ -830,6 +985,11 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna return error(GL_INVALID_OPERATION); } + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: @@ -855,25 +1015,19 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", target, level, xoffset, yoffset, width, height, format, imageSize, data); try { - if (!gl::IsTextureTarget(target)) + if (!gl::IsInternalTextureTarget(target)) { return error(GL_INVALID_ENUM); } - if (level < 0) - { - return error(GL_INVALID_VALUE); - } - - if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || - (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0) + if (xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) { return error(GL_INVALID_VALUE); } @@ -882,6 +1036,8 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: break; default: return error(GL_INVALID_ENUM); @@ -892,7 +1048,7 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -901,9 +1057,27 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs 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. + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->supportsDXT1Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->supportsDXT3Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->supportsDXT5Textures()) + { + return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed + } + break; + default: UNREACHABLE(); } if (imageSize != gl::ComputeCompressedSize(width, height, format)) @@ -914,52 +1088,24 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs if (xoffset % 4 != 0 || yoffset % 4 != 0) { return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction - // does not exist unless DXT1 textures are supported. + // does not exist unless DXT textures are supported. } if (target == GL_TEXTURE_2D) { gl::Texture2D *texture = context->getTexture2D(); - - if (!texture) - { - return error(GL_INVALID_OPERATION); - } - - if (!texture->isCompressed()) + if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture)) { - return error(GL_INVALID_OPERATION); + texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); } - - if ((width % 4 != 0 && width != texture->getWidth()) || - (height % 4 != 0 && height != texture->getHeight())) - { - return error(GL_INVALID_OPERATION); - } - - texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); } else if (gl::IsCubemapTextureTarget(target)) { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - - if (!texture) - { - return error(GL_INVALID_OPERATION); - } - - if (!texture->isCompressed()) - { - return error(GL_INVALID_OPERATION); - } - - if ((width % 4 != 0 && width != texture->getWidth()) || - (height % 4 != 0 && height != texture->getHeight())) + if (validateSubImageParams(true, width, height, xoffset, yoffset, level, GL_NONE, texture)) { - return error(GL_INVALID_OPERATION); + texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); } - - texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); } else { @@ -975,18 +1121,13 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", target, level, internalformat, x, y, width, height, border); try { - if (level < 0 || width < 0 || height < 0) - { - return error(GL_INVALID_VALUE); - } - - if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height))) + if (!validImageSize(level, width, height)) { return error(GL_INVALID_VALUE); } @@ -996,10 +1137,15 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { + if (level > context->getMaximumTextureLevel()) + { + return error(GL_INVALID_VALUE); + } + switch (target) { case GL_TEXTURE_2D: @@ -1042,8 +1188,8 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma return error(GL_INVALID_OPERATION); } - gl::Colorbuffer *source = framebuffer->getColorbuffer(); - GLenum colorbufferFormat = source->getFormat(); + gl::Renderbuffer *source = framebuffer->getColorbuffer(); + GLenum colorbufferFormat = source->getInternalFormat(); // [OpenGL ES 2.0.24] table 3.9 switch (internalformat) @@ -1083,7 +1229,27 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - if (context->supportsCompressedTextures()) + if (context->supportsDXT1Textures()) + { + return error(GL_INVALID_OPERATION); + } + else + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->supportsDXT3Textures()) + { + return error(GL_INVALID_OPERATION); + } + else + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->supportsDXT5Textures()) { return error(GL_INVALID_OPERATION); } @@ -1105,7 +1271,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma return error(GL_INVALID_OPERATION); } - texture->copyImage(level, internalformat, x, y, width, height, source); + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + + texture->copyImage(level, internalformat, x, y, width, height, framebuffer); } else if (gl::IsCubemapTextureTarget(target)) { @@ -1116,7 +1287,12 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma return error(GL_INVALID_OPERATION); } - texture->copyImage(target, level, internalformat, x, y, width, height, source); + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + + texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); } else UNREACHABLE(); } @@ -1129,13 +1305,13 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", target, level, xoffset, yoffset, x, y, width, height); try { - if (!gl::IsTextureTarget(target)) + if (!gl::IsInternalTextureTarget(target)) { return error(GL_INVALID_ENUM); } @@ -1155,7 +1331,7 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1176,8 +1352,8 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL return error(GL_INVALID_OPERATION); } - gl::Colorbuffer *source = framebuffer->getColorbuffer(); - GLenum colorbufferFormat = source->getFormat(); + gl::Renderbuffer *source = framebuffer->getColorbuffer(); + GLenum colorbufferFormat = source->getInternalFormat(); gl::Texture *texture = NULL; if (target == GL_TEXTURE_2D) @@ -1190,12 +1366,12 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL } else UNREACHABLE(); - if (!texture) + if (!validateSubImageParams(false, width, height, xoffset, yoffset, level, GL_NONE, texture)) { - return error(GL_INVALID_OPERATION); + return; // error already registered by validateSubImageParams } - GLenum textureFormat = texture->getFormat(); + GLenum textureFormat = texture->getInternalFormat(); // [OpenGL ES 2.0.24] table 3.9 switch (textureFormat) @@ -1235,12 +1411,14 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return error(GL_INVALID_OPERATION); default: return error(GL_INVALID_OPERATION); } - texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source); + texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); } } @@ -1252,11 +1430,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL GLuint __stdcall glCreateProgram(void) { - TRACE("()"); + EVENT("()"); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1273,11 +1451,11 @@ GLuint __stdcall glCreateProgram(void) GLuint __stdcall glCreateShader(GLenum type) { - TRACE("(GLenum type = 0x%X)", type); + EVENT("(GLenum type = 0x%X)", type); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1301,7 +1479,7 @@ GLuint __stdcall glCreateShader(GLenum type) void __stdcall glCullFace(GLenum mode) { - TRACE("(GLenum mode = 0x%X)", mode); + EVENT("(GLenum mode = 0x%X)", mode); try { @@ -1311,7 +1489,7 @@ void __stdcall glCullFace(GLenum mode) case GL_BACK: case GL_FRONT_AND_BACK: { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1331,7 +1509,7 @@ void __stdcall glCullFace(GLenum mode) void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) { - TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); + EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); try { @@ -1340,7 +1518,7 @@ void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1358,7 +1536,7 @@ 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); + EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); try { @@ -1367,7 +1545,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1385,7 +1563,7 @@ void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) { - TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); + EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); try { @@ -1394,7 +1572,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1415,7 +1593,7 @@ void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) void __stdcall glDeleteProgram(GLuint program) { - TRACE("(GLuint program = %d)", program); + EVENT("(GLuint program = %d)", program); try { @@ -1424,7 +1602,7 @@ void __stdcall glDeleteProgram(GLuint program) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1449,9 +1627,36 @@ void __stdcall glDeleteProgram(GLuint program) } } +void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) +{ + EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); + + try + { + if (n < 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + for (int i = 0; i < n; i++) + { + context->deleteQuery(ids[i]); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) { - TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); + EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); try { @@ -1460,7 +1665,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1478,7 +1683,7 @@ void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) void __stdcall glDeleteShader(GLuint shader) { - TRACE("(GLuint shader = %d)", shader); + EVENT("(GLuint shader = %d)", shader); try { @@ -1487,7 +1692,7 @@ void __stdcall glDeleteShader(GLuint shader) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1514,7 +1719,7 @@ void __stdcall glDeleteShader(GLuint shader) void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) { - TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); + EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); try { @@ -1523,7 +1728,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1544,7 +1749,7 @@ void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) void __stdcall glDepthFunc(GLenum func) { - TRACE("(GLenum func = 0x%X)", func); + EVENT("(GLenum func = 0x%X)", func); try { @@ -1563,7 +1768,7 @@ void __stdcall glDepthFunc(GLenum func) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1578,11 +1783,11 @@ void __stdcall glDepthFunc(GLenum func) void __stdcall glDepthMask(GLboolean flag) { - TRACE("(GLboolean flag = %d)", flag); + EVENT("(GLboolean flag = %d)", flag); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1597,11 +1802,11 @@ void __stdcall glDepthMask(GLboolean flag) void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) { - TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); + EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1616,11 +1821,11 @@ void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) void __stdcall glDetachShader(GLuint program, GLuint shader) { - TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader); + EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1669,11 +1874,11 @@ void __stdcall glDetachShader(GLuint program, GLuint shader) void __stdcall glDisable(GLenum cap) { - TRACE("(GLenum cap = 0x%X)", cap); + EVENT("(GLenum cap = 0x%X)", cap); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1701,7 +1906,7 @@ void __stdcall glDisable(GLenum cap) void __stdcall glDisableVertexAttribArray(GLuint index) { - TRACE("(GLuint index = %d)", index); + EVENT("(GLuint index = %d)", index); try { @@ -1710,7 +1915,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1725,7 +1930,7 @@ void __stdcall glDisableVertexAttribArray(GLuint index) void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) { - TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); try { @@ -1734,11 +1939,38 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { - context->drawArrays(mode, first, count); + context->drawArrays(mode, first, count, 0); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +{ + EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); + + try + { + if (count < 0 || first < 0 || primcount < 0) + { + return error(GL_INVALID_VALUE); + } + + if (primcount > 0) + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->drawArrays(mode, first, count, primcount); + } } } catch(std::bad_alloc&) @@ -1749,7 +1981,7 @@ void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { - TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", + EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", mode, count, type, indices); try @@ -1759,7 +1991,7 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1778,7 +2010,50 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv return error(GL_INVALID_ENUM); } - context->drawElements(mode, count, type, indices); + context->drawElements(mode, count, type, indices, 0); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) +{ + EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", + mode, count, type, indices, primcount); + + try + { + if (count < 0 || primcount < 0) + { + return error(GL_INVALID_VALUE); + } + + if (primcount > 0) + { + gl::Context *context = gl::getNonLostContext(); + + 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, primcount); + } } } catch(std::bad_alloc&) @@ -1789,11 +2064,11 @@ void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLv void __stdcall glEnable(GLenum cap) { - TRACE("(GLenum cap = 0x%X)", cap); + EVENT("(GLenum cap = 0x%X)", cap); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1821,7 +2096,7 @@ void __stdcall glEnable(GLenum cap) void __stdcall glEnableVertexAttribArray(GLuint index) { - TRACE("(GLuint index = %d)", index); + EVENT("(GLuint index = %d)", index); try { @@ -1830,7 +2105,7 @@ void __stdcall glEnableVertexAttribArray(GLuint index) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1843,13 +2118,41 @@ void __stdcall glEnableVertexAttribArray(GLuint index) } } +void __stdcall glEndQueryEXT(GLenum target) +{ + EVENT("GLenum target = 0x%X)", target); + + try + { + switch (target) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + break; + default: + return error(GL_INVALID_ENUM); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->endQuery(target); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glFinishFenceNV(GLuint fence) { - TRACE("(GLuint fence = %d)", fence); + EVENT("(GLuint fence = %d)", fence); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1871,15 +2174,15 @@ void __stdcall glFinishFenceNV(GLuint fence) void __stdcall glFinish(void) { - TRACE("()"); + EVENT("()"); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { - context->finish(); + context->sync(true); } } catch(std::bad_alloc&) @@ -1890,15 +2193,15 @@ void __stdcall glFinish(void) void __stdcall glFlush(void) { - TRACE("()"); + EVENT("()"); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { - context->flush(); + context->sync(false); } } catch(std::bad_alloc&) @@ -1909,18 +2212,18 @@ void __stdcall glFlush(void) void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " + EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); try { if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) - || renderbuffertarget != GL_RENDERBUFFER) + || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) { return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -1931,13 +2234,13 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu framebuffer = context->getReadFramebuffer(); framebufferHandle = context->getReadFramebufferHandle(); } - else + else { framebuffer = context->getDrawFramebuffer(); framebufferHandle = context->getDrawFramebufferHandle(); } - if (framebufferHandle == 0 || !framebuffer) + if (!framebuffer || (framebufferHandle == 0 && renderbuffer != 0)) { return error(GL_INVALID_OPERATION); } @@ -1966,7 +2269,7 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " + EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); try @@ -1986,7 +2289,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2073,7 +2376,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t void __stdcall glFrontFace(GLenum mode) { - TRACE("(GLenum mode = 0x%X)", mode); + EVENT("(GLenum mode = 0x%X)", mode); try { @@ -2082,7 +2385,7 @@ void __stdcall glFrontFace(GLenum mode) case GL_CW: case GL_CCW: { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2102,7 +2405,7 @@ void __stdcall glFrontFace(GLenum mode) void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) { - TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); + EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); try { @@ -2111,7 +2414,7 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2129,11 +2432,11 @@ void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) void __stdcall glGenerateMipmap(GLenum target) { - TRACE("(GLenum target = 0x%X)", target); + EVENT("(GLenum target = 0x%X)", target); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2169,7 +2472,7 @@ void __stdcall glGenerateMipmap(GLenum target) void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) { - TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); + EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); try { @@ -2178,7 +2481,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2196,7 +2499,7 @@ void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) { - TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); + EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); try { @@ -2205,7 +2508,7 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2221,9 +2524,36 @@ void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) } } +void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) +{ + EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); + + try + { + if (n < 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + for (int i = 0; i < n; i++) + { + ids[i] = context->createQuery(); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) { - TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); + EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); try { @@ -2232,7 +2562,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2250,7 +2580,7 @@ void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) void __stdcall glGenTextures(GLsizei n, GLuint* textures) { - TRACE("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); + EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); try { @@ -2259,7 +2589,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2277,7 +2607,7 @@ void __stdcall glGenTextures(GLsizei n, GLuint* textures) void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) { - TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " + EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", program, index, bufsize, length, size, type, name); @@ -2288,7 +2618,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2322,7 +2652,7 @@ void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { - TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " + EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", program, index, bufsize, length, size, type, name); @@ -2333,7 +2663,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2367,7 +2697,7 @@ void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) { - TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", + EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", program, maxcount, count, shaders); try @@ -2377,7 +2707,7 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2406,11 +2736,11 @@ void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* c int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) { - TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name); + EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2447,11 +2777,11 @@ int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) { - TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); + EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2510,11 +2840,11 @@ void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) { - TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2557,7 +2887,7 @@ void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params GLenum __stdcall glGetError(void) { - TRACE("()"); + EVENT("()"); gl::Context *context = gl::getContext(); @@ -2571,12 +2901,12 @@ GLenum __stdcall glGetError(void) 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); + EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2598,11 +2928,11 @@ void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) void __stdcall glGetFloatv(GLenum pname, GLfloat* params) { - TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); + EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2658,12 +2988,12 @@ void __stdcall glGetFloatv(GLenum pname, GLfloat* params) void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) { - TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", + EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, attachment, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2716,11 +3046,15 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac { attachmentObjectType = attachmentType; } - else if (gl::IsTextureTarget(attachmentType)) + else if (gl::IsInternalTextureTarget(attachmentType)) { attachmentObjectType = GL_TEXTURE; } - else UNREACHABLE(); + else + { + UNREACHABLE(); + return; + } switch (pname) { @@ -2775,9 +3109,9 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac } } -void __stdcall glGetIntegerv(GLenum pname, GLint* params) +GLenum __stdcall glGetGraphicsResetStatusEXT(void) { - TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); + EVENT("()"); try { @@ -2785,6 +3119,27 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params) if (context) { + return context->getResetStatus(); + } + + return GL_NO_ERROR; + } + catch(std::bad_alloc&) + { + return GL_OUT_OF_MEMORY; + } +} + +void __stdcall glGetIntegerv(GLenum pname, GLint* params) +{ + EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { if (!(context->getIntegerv(pname, params))) { GLenum nativeType; @@ -2842,11 +3197,11 @@ void __stdcall glGetIntegerv(GLenum pname, GLint* params) void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) { - TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); + EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2899,7 +3254,7 @@ void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) { - TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", + EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", program, bufsize, length, infolog); try @@ -2909,7 +3264,7 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2929,13 +3284,89 @@ void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* len } } +void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) +{ + EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); + + try + { + switch (pname) + { + case GL_CURRENT_QUERY_EXT: + break; + default: + return error(GL_INVALID_ENUM); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + params[0] = context->getActiveQuery(target); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) +{ + EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); + + try + { + switch (pname) + { + case GL_QUERY_RESULT_EXT: + case GL_QUERY_RESULT_AVAILABLE_EXT: + break; + default: + return error(GL_INVALID_ENUM); + } + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Query *queryObject = context->getQuery(id, false, GL_NONE); + + if (!queryObject) + { + return error(GL_INVALID_OPERATION); + } + + if (context->getActiveQuery(queryObject->getType()) == id) + { + return error(GL_INVALID_OPERATION); + } + + switch(pname) + { + case GL_QUERY_RESULT_EXT: + params[0] = queryObject->getResult(); + break; + case GL_QUERY_RESULT_AVAILABLE_EXT: + params[0] = queryObject->isResultAvailable(); + break; + default: + ASSERT(false); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) { - TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -2953,85 +3384,23 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* switch (pname) { - case GL_RENDERBUFFER_WIDTH: - *params = renderbuffer->getWidth(); - break; - case GL_RENDERBUFFER_HEIGHT: - *params = renderbuffer->getHeight(); - break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: - *params = renderbuffer->getFormat(); - break; - case GL_RENDERBUFFER_RED_SIZE: - if (renderbuffer->isColorbuffer()) - { - *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize(); - } - else - { - *params = 0; - } - break; - case GL_RENDERBUFFER_GREEN_SIZE: - if (renderbuffer->isColorbuffer()) - { - *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize(); - } - else - { - *params = 0; - } - break; - case GL_RENDERBUFFER_BLUE_SIZE: - if (renderbuffer->isColorbuffer()) - { - *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize(); - } - else - { - *params = 0; - } - break; - case GL_RENDERBUFFER_ALPHA_SIZE: - if (renderbuffer->isColorbuffer()) - { - *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize(); - } - else - { - *params = 0; - } - break; - case GL_RENDERBUFFER_DEPTH_SIZE: - if (renderbuffer->isDepthbuffer()) - { - *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize(); - } - else - { - *params = 0; - } - break; - case GL_RENDERBUFFER_STENCIL_SIZE: - if (renderbuffer->isStencilbuffer()) + case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; + case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getInternalFormat(); break; + case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; + case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; + case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; + case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; + case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; + case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; + case GL_RENDERBUFFER_SAMPLES_ANGLE: + if (context->getMaxSupportedSamples() != 0) { - *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize(); + *params = renderbuffer->getSamples(); } else { - *params = 0; - } - break; - case GL_RENDERBUFFER_SAMPLES_ANGLE: - { - if (context->getMaxSupportedSamples() != 0) - { - *params = renderbuffer->getStorage()->getSamples(); - } - else - { - return error(GL_INVALID_ENUM); - } + return error(GL_INVALID_ENUM); } break; default: @@ -3047,11 +3416,11 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) { - TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); + EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3079,6 +3448,9 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) case GL_SHADER_SOURCE_LENGTH: *params = shaderObject->getSourceLength(); return; + case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: + *params = shaderObject->getTranslatedSourceLength(); + return; default: return error(GL_INVALID_ENUM); } @@ -3092,7 +3464,7 @@ void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) { - TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", + EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", shader, bufsize, length, infolog); try @@ -3102,7 +3474,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3124,7 +3496,7 @@ void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* lengt void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { - TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", + EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", shadertype, precisiontype, range, precision); try @@ -3169,7 +3541,7 @@ void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontyp void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) { - TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", + EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", shader, bufsize, length, source); try @@ -3179,7 +3551,7 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3199,24 +3571,56 @@ void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length } } +void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +{ + EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", + shader, bufsize, length, source); + + try + { + if (bufsize < 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Shader *shaderObject = context->getShader(shader); + + if (!shaderObject) + { + return error(GL_INVALID_OPERATION); + } + + shaderObject->getTranslatedSource(bufsize, length, source); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + const GLubyte* __stdcall glGetString(GLenum name) { - TRACE("(GLenum name = 0x%X)", name); + EVENT("(GLenum name = 0x%X)", name); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); switch (name) { case GL_VENDOR: - return (GLubyte*)"TransGaming Inc."; + return (GLubyte*)"Google Inc."; case GL_RENDERER: - return (GLubyte*)"ANGLE"; + return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); case GL_VERSION: - return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")"; + return (GLubyte*)"OpenGL ES 2.0 (ANGLE "VERSION_STRING")"; case GL_SHADING_LANGUAGE_VERSION: - return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")"; + return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE "VERSION_STRING")"; case GL_EXTENSIONS: return (GLubyte*)((context != NULL) ? context->getExtensionString() : ""); default: @@ -3227,17 +3631,15 @@ const GLubyte* __stdcall glGetString(GLenum name) { return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL); } - - return NULL; } void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) { - TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3269,6 +3671,12 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) case GL_TEXTURE_WRAP_T: *params = (GLfloat)texture->getWrapT(); break; + case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: + *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); + break; + case GL_TEXTURE_USAGE_ANGLE: + *params = (GLfloat)texture->getUsage(); + break; default: return error(GL_INVALID_ENUM); } @@ -3282,11 +3690,11 @@ void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) { - TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3318,6 +3726,12 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) case GL_TEXTURE_WRAP_T: *params = texture->getWrapT(); break; + case GL_TEXTURE_IMMUTABLE_FORMAT_EXT: + *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_USAGE_ANGLE: + *params = texture->getUsage(); + break; default: return error(GL_INVALID_ENUM); } @@ -3329,13 +3743,93 @@ void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) } } +void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) +{ + EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", + program, location, bufSize, params); + + try + { + if (bufSize < 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (program == 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject || !programObject->isLinked()) + { + return error(GL_INVALID_OPERATION); + } + + if (!programObject->getUniformfv(location, &bufSize, params)) + { + return error(GL_INVALID_OPERATION); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) { - TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); + EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (program == 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Program *programObject = context->getProgram(program); + + if (!programObject || !programObject->isLinked()) + { + return error(GL_INVALID_OPERATION); + } + + if (!programObject->getUniformfv(location, NULL, params)) + { + return error(GL_INVALID_OPERATION); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) +{ + EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", + program, location, bufSize, params); + + try + { + if (bufSize < 0) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3351,7 +3845,12 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformfv(location, params)) + if (!programObject) + { + return error(GL_INVALID_OPERATION); + } + + if (!programObject->getUniformiv(location, &bufSize, params)) { return error(GL_INVALID_OPERATION); } @@ -3365,11 +3864,11 @@ void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) { - TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); + EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3390,7 +3889,7 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) return error(GL_INVALID_OPERATION); } - if (!programObject->getUniformiv(location, params)) + if (!programObject->getUniformiv(location, NULL, params)) { return error(GL_INVALID_OPERATION); } @@ -3404,11 +3903,11 @@ void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) { - TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); + EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (strstr(name, "gl_") == name) { @@ -3436,7 +3935,7 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) return error(GL_INVALID_OPERATION, -1); } - return programObject->getUniformLocation(name, false); + return programObject->getUniformLocation(name); } } catch(std::bad_alloc&) @@ -3449,11 +3948,11 @@ int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) { - TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); + EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3490,6 +3989,9 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) params[i] = attribState.mCurrentValue[i]; } break; + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: + *params = (GLfloat)attribState.mDivisor; + break; default: return error(GL_INVALID_ENUM); } } @@ -3502,11 +4004,11 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) { - TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); + EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3544,6 +4046,9 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f)); } break; + case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: + *params = (GLint)attribState.mDivisor; + break; default: return error(GL_INVALID_ENUM); } } @@ -3556,11 +4061,11 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) { - TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); + EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3585,7 +4090,7 @@ void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** po void __stdcall glHint(GLenum target, GLenum mode) { - TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); + EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); try { @@ -3599,7 +4104,7 @@ void __stdcall glHint(GLenum target, GLenum mode) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); switch (target) { case GL_GENERATE_MIPMAP_HINT: @@ -3620,11 +4125,11 @@ void __stdcall glHint(GLenum target, GLenum mode) GLboolean __stdcall glIsBuffer(GLuint buffer) { - TRACE("(GLuint buffer = %d)", buffer); + EVENT("(GLuint buffer = %d)", buffer); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && buffer) { @@ -3646,11 +4151,11 @@ GLboolean __stdcall glIsBuffer(GLuint buffer) GLboolean __stdcall glIsEnabled(GLenum cap) { - TRACE("(GLenum cap = 0x%X)", cap); + EVENT("(GLenum cap = 0x%X)", cap); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3680,11 +4185,11 @@ GLboolean __stdcall glIsEnabled(GLenum cap) GLboolean __stdcall glIsFenceNV(GLuint fence) { - TRACE("(GLuint fence = %d)", fence); + EVENT("(GLuint fence = %d)", fence); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3708,11 +4213,11 @@ GLboolean __stdcall glIsFenceNV(GLuint fence) GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) { - TRACE("(GLuint framebuffer = %d)", framebuffer); + EVENT("(GLuint framebuffer = %d)", framebuffer); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && framebuffer) { @@ -3734,11 +4239,11 @@ GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) GLboolean __stdcall glIsProgram(GLuint program) { - TRACE("(GLuint program = %d)", program); + EVENT("(GLuint program = %d)", program); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && program) { @@ -3758,13 +4263,44 @@ GLboolean __stdcall glIsProgram(GLuint program) return GL_FALSE; } +GLboolean __stdcall glIsQueryEXT(GLuint id) +{ + EVENT("(GLuint id = %d)", id); + + try + { + if (id == 0) + { + return GL_FALSE; + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Query *queryObject = context->getQuery(id, false, GL_NONE); + + if (queryObject) + { + return GL_TRUE; + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY, GL_FALSE); + } + + return GL_FALSE; +} + GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) { - TRACE("(GLuint renderbuffer = %d)", renderbuffer); + EVENT("(GLuint renderbuffer = %d)", renderbuffer); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && renderbuffer) { @@ -3786,11 +4322,11 @@ GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) GLboolean __stdcall glIsShader(GLuint shader) { - TRACE("(GLuint shader = %d)", shader); + EVENT("(GLuint shader = %d)", shader); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && shader) { @@ -3812,11 +4348,11 @@ GLboolean __stdcall glIsShader(GLuint shader) GLboolean __stdcall glIsTexture(GLuint texture) { - TRACE("(GLuint texture = %d)", texture); + EVENT("(GLuint texture = %d)", texture); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context && texture) { @@ -3838,7 +4374,7 @@ GLboolean __stdcall glIsTexture(GLuint texture) void __stdcall glLineWidth(GLfloat width) { - TRACE("(GLfloat width = %f)", width); + EVENT("(GLfloat width = %f)", width); try { @@ -3847,7 +4383,7 @@ void __stdcall glLineWidth(GLfloat width) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3862,11 +4398,11 @@ void __stdcall glLineWidth(GLfloat width) void __stdcall glLinkProgram(GLuint program) { - TRACE("(GLuint program = %d)", program); + EVENT("(GLuint program = %d)", program); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3895,11 +4431,11 @@ void __stdcall glLinkProgram(GLuint program) void __stdcall glPixelStorei(GLenum pname, GLint param) { - TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param); + EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3923,6 +4459,10 @@ void __stdcall glPixelStorei(GLenum pname, GLint param) context->setPackAlignment(param); break; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + context->setPackReverseRowOrder(param != 0); + break; + default: return error(GL_INVALID_ENUM); } @@ -3936,11 +4476,11 @@ void __stdcall glPixelStorei(GLenum pname, GLint param) void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) { - TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units); + EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -3953,9 +4493,43 @@ void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) } } -void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) +void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLsizei bufSize, + GLvoid *data) +{ + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)", + x, y, width, height, format, type, bufSize, data); + + try + { + if (width < 0 || height < 0 || bufSize < 0) + { + return error(GL_INVALID_VALUE); + } + + if (!validReadFormatType(format, type)) + { + return error(GL_INVALID_OPERATION); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->readPixels(x, y, width, height, format, type, &bufSize, data); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, GLvoid* pixels) { - TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", x, y, width, height, format, type, pixels); @@ -3966,46 +4540,16 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe return error(GL_INVALID_VALUE); } - switch (format) + if (!validReadFormatType(format, type)) { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - break; - default: - return error(GL_INVALID_OPERATION); - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - break; - default: - return error(GL_INVALID_OPERATION); - } - break; - case gl::IMPLEMENTATION_COLOR_READ_FORMAT: - switch (type) - { - case gl::IMPLEMENTATION_COLOR_READ_TYPE: - break; - default: - return error(GL_INVALID_OPERATION); - } - break; - default: return error(GL_INVALID_OPERATION); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { - context->readPixels(x, y, width, height, format, type, pixels); + context->readPixels(x, y, width, height, format, type, NULL, pixels); } } catch(std::bad_alloc&) @@ -4016,7 +4560,7 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe void __stdcall glReleaseShaderCompiler(void) { - TRACE("()"); + EVENT("()"); try { @@ -4030,7 +4574,7 @@ void __stdcall glReleaseShaderCompiler(void) void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", target, samples, internalformat, width, height); try @@ -4053,7 +4597,7 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4106,11 +4650,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) { - TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert); + EVENT("(GLclampf value = %f, GLboolean invert = %d)", value, invert); try { - gl::Context* context = gl::getContext(); + gl::Context* context = gl::getNonLostContext(); if (context) { @@ -4125,7 +4669,7 @@ void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) void __stdcall glSetFenceNV(GLuint fence, GLenum condition) { - TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); + EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); try { @@ -4134,7 +4678,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4156,7 +4700,7 @@ void __stdcall glSetFenceNV(GLuint fence, GLenum condition) 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); + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); try { @@ -4165,7 +4709,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) return error(GL_INVALID_VALUE); } - gl::Context* context = gl::getContext(); + gl::Context* context = gl::getNonLostContext(); if (context) { @@ -4180,7 +4724,7 @@ void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) { - TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " + EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", n, shaders, binaryformat, binary, length); @@ -4197,7 +4741,7 @@ void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryfor void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) { - TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", + EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", shader, count, string, length); try @@ -4207,7 +4751,7 @@ void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** strin return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4241,7 +4785,7 @@ void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { - TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); + EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); try { @@ -4270,7 +4814,7 @@ void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4298,7 +4842,7 @@ void __stdcall glStencilMask(GLuint mask) void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) { - TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); + EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); try { @@ -4312,7 +4856,7 @@ void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4340,7 +4884,7 @@ void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { - TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", + EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", face, fail, zfail, zpass); try @@ -4400,7 +4944,7 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4423,11 +4967,11 @@ void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenu GLboolean __stdcall glTestFenceNV(GLuint fence) { - TRACE("(GLuint fence = %d)", fence); + EVENT("(GLuint fence = %d)", fence); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4452,28 +4996,23 @@ GLboolean __stdcall glTestFenceNV(GLuint fence) void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", target, level, internalformat, width, height, border, format, type, pixels); try { - if (level < 0 || width < 0 || height < 0) - { - return error(GL_INVALID_VALUE); - } - - if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height))) + if (!validImageSize(level, width, height)) { return error(GL_INVALID_VALUE); } - if (internalformat != format) + if (internalformat != GLint(format)) { return error(GL_INVALID_OPERATION); } - switch (internalformat) + switch (format) { case GL_ALPHA: case GL_LUMINANCE: @@ -4524,6 +5063,8 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL break; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: break; default: return error(GL_INVALID_VALUE); @@ -4534,10 +5075,15 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { + if (level > context->getMaximumTextureLevel()) + { + return error(GL_INVALID_VALUE); + } + switch (target) { case GL_TEXTURE_2D: @@ -4568,10 +5114,30 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_ENUM); } - if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) - { - if (context->supportsCompressedTextures()) + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (context->supportsDXT1Textures()) + { + return error(GL_INVALID_OPERATION); + } + else + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (context->supportsDXT3Textures()) + { + return error(GL_INVALID_OPERATION); + } + else + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (context->supportsDXT5Textures()) { return error(GL_INVALID_OPERATION); } @@ -4579,18 +5145,21 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL { return error(GL_INVALID_ENUM); } + break; + default: + break; } if (type == GL_FLOAT) { - if (!context->supportsFloatTextures()) + if (!context->supportsFloat32Textures()) { return error(GL_INVALID_ENUM); } } else if (type == GL_HALF_FLOAT_OES) { - if (!context->supportsHalfFloatTextures()) + if (!context->supportsFloat16Textures()) { return error(GL_INVALID_ENUM); } @@ -4605,7 +5174,12 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_OPERATION); } - texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + + texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels); } else { @@ -4616,25 +5190,30 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL return error(GL_INVALID_OPERATION); } + if (texture->isImmutable()) + { + return error(GL_INVALID_OPERATION); + } + switch (target) { case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImagePosX(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImageNegX(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImagePosY(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImageNegY(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImagePosZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->setImageNegZ(level, width, height, format, type, context->getUnpackAlignment(), pixels); break; default: UNREACHABLE(); } @@ -4659,11 +5238,11 @@ void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* para void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) { - TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); + EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4707,6 +5286,12 @@ void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) return error(GL_INVALID_ENUM); } break; + case GL_TEXTURE_USAGE_ANGLE: + if (!texture->setUsage((GLenum)param)) + { + return error(GL_INVALID_ENUM); + } + break; default: return error(GL_INVALID_ENUM); } @@ -4723,106 +5308,231 @@ void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params glTexParameteri(target, pname, *params); } -void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid* pixels) +void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " - "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " - "const GLvoid* pixels = 0x%0.8p)", - target, level, xoffset, yoffset, width, height, format, type, pixels); + EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", + target, levels, internalformat, width, height); try { - if (!gl::IsTextureTarget(target)) + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) { return error(GL_INVALID_ENUM); } - if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) + if (width < 1 || height < 1 || levels < 1) { return error(GL_INVALID_VALUE); } - if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) + if (target == GL_TEXTURE_CUBE_MAP && width != height) { return error(GL_INVALID_VALUE); } - if (!gl::CheckTextureFormatType(format, type)) + if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1) { - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } - if (width == 0 || height == 0 || pixels == NULL) + GLenum format = gl::ExtractFormat(internalformat); + GLenum type = gl::ExtractType(internalformat); + + if (format == GL_NONE || type == GL_NONE) { - return; + return error(GL_INVALID_ENUM); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { - if (level > context->getMaximumTextureLevel()) + switch (target) { - return error(GL_INVALID_VALUE); + case GL_TEXTURE_2D: + if (width > context->getMaximumTextureDimension() || + height > context->getMaximumTextureDimension()) + { + return error(GL_INVALID_VALUE); + } + break; + case GL_TEXTURE_CUBE_MAP: + if (width > context->getMaximumCubeTextureDimension() || + height > context->getMaximumCubeTextureDimension()) + { + return error(GL_INVALID_VALUE); + } + break; + default: + return error(GL_INVALID_ENUM); } - if (format == GL_FLOAT) + if (levels != 1 && !context->supportsNonPower2Texture()) { - if (!context->supportsFloatTextures()) + if (!gl::isPow2(width) || !gl::isPow2(height)) { - return error(GL_INVALID_ENUM); + return error(GL_INVALID_OPERATION); } } - else if (format == GL_HALF_FLOAT_OES) + + switch (internalformat) { - if (!context->supportsHalfFloatTextures()) + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + if (!context->supportsDXT1Textures()) + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + if (!context->supportsDXT3Textures()) + { + return error(GL_INVALID_ENUM); + } + break; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + if (!context->supportsDXT5Textures()) + { + return error(GL_INVALID_ENUM); + } + break; + case GL_RGBA32F_EXT: + case GL_RGB32F_EXT: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + if (!context->supportsFloat32Textures()) + { + return error(GL_INVALID_ENUM); + } + break; + case GL_RGBA16F_EXT: + case GL_RGB16F_EXT: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + if (!context->supportsFloat16Textures()) { return error(GL_INVALID_ENUM); } + break; } if (target == GL_TEXTURE_2D) { gl::Texture2D *texture = context->getTexture2D(); - if (!texture) - { - return error(GL_INVALID_OPERATION); - } - - if (texture->isCompressed()) + if (!texture || texture->id() == 0) { return error(GL_INVALID_OPERATION); } - if (format != texture->getFormat()) + if (texture->isImmutable()) { return error(GL_INVALID_OPERATION); } - texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); + texture->storage(levels, internalformat, width, height); } - else if (gl::IsCubemapTextureTarget(target)) + else if (target == GL_TEXTURE_CUBE_MAP) { gl::TextureCubeMap *texture = context->getTextureCubeMap(); - if (!texture) + if (!texture || texture->id() == 0) { return error(GL_INVALID_OPERATION); } - if (texture->isCompressed()) + if (texture->isImmutable()) { return error(GL_INVALID_OPERATION); } - if (format != texture->getFormat()) + texture->storage(levels, internalformat, width); + } + else UNREACHABLE(); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + +void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLenum format, GLenum type, const GLvoid* pixels) +{ + EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " + "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " + "const GLvoid* pixels = 0x%0.8p)", + target, level, xoffset, yoffset, width, height, format, type, pixels); + + try + { + if (!gl::IsInternalTextureTarget(target)) + { + return error(GL_INVALID_ENUM); + } + + if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0) + { + return error(GL_INVALID_VALUE); + } + + if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) + { + return error(GL_INVALID_VALUE); + } + + if (!gl::CheckTextureFormatType(format, type)) + { + return error(GL_INVALID_ENUM); + } + + if (width == 0 || height == 0 || pixels == NULL) + { + return; + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + if (level > context->getMaximumTextureLevel()) + { + return error(GL_INVALID_VALUE); + } + + if (format == GL_FLOAT) + { + if (!context->supportsFloat32Textures()) { - return error(GL_INVALID_OPERATION); + return error(GL_INVALID_ENUM); } + } + else if (format == GL_HALF_FLOAT_OES) + { + if (!context->supportsFloat16Textures()) + { + return error(GL_INVALID_ENUM); + } + } - texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); + if (target == GL_TEXTURE_2D) + { + gl::Texture2D *texture = context->getTexture2D(); + if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture)) + { + texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); + } + } + else if (gl::IsCubemapTextureTarget(target)) + { + gl::TextureCubeMap *texture = context->getTextureCubeMap(); + if (validateSubImageParams(false, width, height, xoffset, yoffset, level, format, texture)) + { + texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); + } } else { @@ -4843,7 +5553,7 @@ void __stdcall glUniform1f(GLint location, GLfloat x) void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); try { @@ -4857,7 +5567,7 @@ void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4887,7 +5597,7 @@ void __stdcall glUniform1i(GLint location, GLint x) void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); try { @@ -4901,7 +5611,7 @@ void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4933,7 +5643,7 @@ void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); try { @@ -4947,7 +5657,7 @@ void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -4979,7 +5689,7 @@ void __stdcall glUniform2i(GLint location, GLint x, GLint y) void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); try { @@ -4993,7 +5703,7 @@ void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5025,7 +5735,7 @@ void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); try { @@ -5039,7 +5749,7 @@ void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5071,7 +5781,7 @@ void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); try { @@ -5085,7 +5795,7 @@ void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5117,7 +5827,7 @@ void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfl void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); try { @@ -5131,7 +5841,7 @@ void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5163,7 +5873,7 @@ void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) { - TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); + EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); try { @@ -5177,7 +5887,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5202,7 +5912,7 @@ void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); try @@ -5217,7 +5927,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5242,7 +5952,7 @@ void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean trans void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); try @@ -5257,7 +5967,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5282,7 +5992,7 @@ void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean trans void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", + EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)", location, count, transpose, value); try @@ -5297,7 +6007,7 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans return; } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5322,11 +6032,11 @@ void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean trans void __stdcall glUseProgram(GLuint program) { - TRACE("(GLuint program = %d)", program); + EVENT("(GLuint program = %d)", program); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5360,11 +6070,11 @@ void __stdcall glUseProgram(GLuint program) void __stdcall glValidateProgram(GLuint program) { - TRACE("(GLuint program = %d)", program); + EVENT("(GLuint program = %d)", program); try { - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5393,7 +6103,7 @@ void __stdcall glValidateProgram(GLuint program) void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) { - TRACE("(GLuint index = %d, GLfloat x = %f)", index, x); + EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); try { @@ -5402,7 +6112,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5418,7 +6128,7 @@ void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) { - TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); try { @@ -5427,7 +6137,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5443,7 +6153,7 @@ void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) { - TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); try { @@ -5452,7 +6162,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5468,7 +6178,7 @@ void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) { - TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); try { @@ -5477,7 +6187,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5493,7 +6203,7 @@ void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); try { @@ -5502,7 +6212,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5518,7 +6228,7 @@ void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) { - TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); try { @@ -5527,7 +6237,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5543,7 +6253,7 @@ void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); + EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); try { @@ -5552,7 +6262,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5568,7 +6278,7 @@ void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, G void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) { - TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); + EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); try { @@ -5577,7 +6287,7 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5590,9 +6300,33 @@ void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) } } +void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) +{ + EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); + + try + { + if (index >= gl::MAX_VERTEX_ATTRIBS) + { + return error(GL_INVALID_VALUE); + } + + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + context->setVertexAttribDivisor(index, divisor); + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY); + } +} + void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) { - TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " + EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", index, size, type, normalized, stride, ptr); @@ -5626,7 +6360,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5641,7 +6375,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo void __stdcall glViewport(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); + EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); try { @@ -5650,7 +6384,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) return error(GL_INVALID_VALUE); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5666,7 +6400,7 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " + EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); @@ -5692,7 +6426,7 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi return error(GL_INVALID_OPERATION); } - gl::Context *context = gl::getContext(); + gl::Context *context = gl::getNonLostContext(); if (context) { @@ -5714,7 +6448,7 @@ void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLi void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) { - TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " + EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)", target, level, internalformat, width, height, depth, border, format, type, pixels); @@ -5749,6 +6483,22 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV}, {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV}, {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV}, + {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE}, + {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT}, + {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT}, + {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT}, + {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT}, + {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT}, + {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT}, + {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT}, + {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT}, + {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT}, + {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT}, + {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT}, + {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT}, + {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE}, + {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, + {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, }; for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++) @@ -5762,4 +6512,38 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char * return NULL; } +// Non-public functions used by EGL + +bool __stdcall glBindTexImage(egl::Surface *surface) +{ + EVENT("(egl::Surface* surface = 0x%0.8p)", + surface); + + try + { + gl::Context *context = gl::getNonLostContext(); + + if (context) + { + gl::Texture2D *textureObject = context->getTexture2D(); + + if (textureObject->isImmutable()) + { + return false; + } + + if (textureObject) + { + textureObject->bindTexImage(surface); + } + } + } + catch(std::bad_alloc&) + { + return error(GL_OUT_OF_MEMORY, false); + } + + return true; +} + } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def index b2dc23c..ea7769b 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.def @@ -154,10 +154,27 @@ EXPORTS glIsFenceNV @155 glSetFenceNV @156 glTestFenceNV @157 + glGetTranslatedShaderSourceANGLE @159 + glTexStorage2DEXT @160 + glGetGraphicsResetStatusEXT @161 + glReadnPixelsEXT @162 + glGetnUniformfvEXT @163 + glGetnUniformivEXT @164 + glGenQueriesEXT @165 + glDeleteQueriesEXT @166 + glIsQueryEXT @167 + glBeginQueryEXT @168 + glEndQueryEXT @169 + glGetQueryivEXT @170 + glGetQueryObjectuivEXT @171 + glVertexAttribDivisorANGLE @172 + glDrawArraysInstancedANGLE @173 + glDrawElementsInstancedANGLE @174 ; EGL dependencies glCreateContext @144 NONAME glDestroyContext @145 NONAME glMakeCurrent @146 NONAME glGetCurrentContext @147 NONAME - glGetProcAddress @148 NONAME
\ No newline at end of file + glGetProcAddress @148 NONAME + glBindTexImage @158 NONAME diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc new file mode 100644 index 0000000..0ad21e4 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.rc @@ -0,0 +1,102 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include <windows.h> +#include "../common/version.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "#include ""../common/version.h""\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library" + VALUE "FileVersion", VERSION_STRING + VALUE "InternalName", "libGLESv2" + VALUE "LegalCopyright", "Copyright (C) 2011 Google Inc." + VALUE "OriginalFilename", "libGLESv2.dll" + VALUE "PrivateBuild", VERSION_STRING + VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library" + VALUE "ProductVersion", VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj index 0d95080..7d2b649 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/libGLESv2.vcproj @@ -12,6 +12,9 @@ <Platform Name="Win32" /> + <Platform + Name="x64" + /> </Platforms> <ToolFiles> </ToolFiles> @@ -47,9 +50,11 @@ BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702" Detect64BitPortabilityProblems="false" DebugInformationFormat="4" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -62,7 +67,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="D3dx9.lib" + AdditionalDependencies="d3d9.lib D3dx9.lib d3dcompiler.lib" LinkIncremental="2" ModuleDefinitionFile="libGLESv2.def" GenerateDebugInformation="true" @@ -125,9 +130,11 @@ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" RuntimeLibrary="0" UsePrecompiledHeader="0" - WarningLevel="3" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702;4718" Detect64BitPortabilityProblems="false" DebugInformationFormat="3" + WarnAsError="true" /> <Tool Name="VCManagedResourceCompilerTool" @@ -140,7 +147,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="D3dx9.lib" + AdditionalDependencies="d3d9.lib D3dx9.lib d3dcompiler.lib" LinkIncremental="1" IgnoreAllDefaultLibraries="false" ModuleDefinitionFile="libGLESv2.def" @@ -175,6 +182,171 @@ CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" /> </Configuration> + <Configuration + Name="Debug|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702;4718" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib D3dx9.lib d3dcompiler.lib" + LinkIncremental="2" + ModuleDefinitionFile="libGLESv2.def" + GenerateDebugInformation="true" + SubSystem="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> + <Configuration + Name="Release|x64" + OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" + IntermediateDirectory="$(PlatformName)\$(ConfigurationName)" + ConfigurationType="2" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + TargetEnvironment="3" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="$(ProjectDir)/..; $(ProjectDir)/../../include" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBGLESV2_EXPORTS;_CRT_SECURE_NO_DEPRECATE;NOMINMAX;_SECURE_SCL=0" + RuntimeLibrary="0" + UsePrecompiledHeader="0" + WarningLevel="4" + DisableSpecificWarnings="4100;4127;4189;4239;4244;4245;4512;4702;4718" + Detect64BitPortabilityProblems="false" + DebugInformationFormat="3" + WarnAsError="true" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="d3d9.lib D3dx9.lib d3dcompiler.lib" + LinkIncremental="1" + IgnoreAllDefaultLibraries="false" + ModuleDefinitionFile="libGLESv2.def" + GenerateDebugInformation="true" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" + TargetMachine="17" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="@echo on
mkdir "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.dll" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
copy "$(OutDir)\libGLESv2.lib" "$(ProjectDir)..\..\lib\$(ConfigurationName)\"
@echo off
" + /> + </Configuration> </Configurations> <References> </References> @@ -209,6 +381,14 @@ > </File> <File + RelativePath=".\HandleAllocator.cpp" + > + </File> + <File + RelativePath=".\IndexDataManager.cpp" + > + </File> + <File RelativePath=".\libGLESv2.cpp" > </File> @@ -221,7 +401,11 @@ > </File> <File - RelativePath=".\RefCountObject.cpp" + RelativePath=".\Query.cpp" + > + </File> + <File + RelativePath="..\common\RefCountObject.cpp" > </File> <File @@ -244,18 +428,10 @@ RelativePath=".\utilities.cpp" > </File> - <Filter - Name="Geometry" + <File + RelativePath=".\VertexDataManager.cpp" > - <File - RelativePath=".\geometry\IndexDataManager.cpp" - > - </File> - <File - RelativePath=".\geometry\VertexDataManager.cpp" - > - </File> - </Filter> + </File> </Filter> <Filter Name="Header Files" @@ -295,6 +471,14 @@ > </File> <File + RelativePath=".\HandleAllocator.h" + > + </File> + <File + RelativePath=".\IndexDataManager.h" + > + </File> + <File RelativePath=".\main.h" > </File> @@ -307,7 +491,11 @@ > </File> <File - RelativePath=".\RefCountObject.h" + RelativePath=".\Query.h" + > + </File> + <File + RelativePath="..\common\RefCountObject.h" > </File> <File @@ -315,6 +503,10 @@ > </File> <File + RelativePath=".\resource.h" + > + </File> + <File RelativePath=".\ResourceManager.h" > </File> @@ -330,27 +522,27 @@ RelativePath=".\utilities.h" > </File> - <Filter - Name="Geometry" - > - <File - RelativePath=".\geometry\IndexDataManager.h" - > - </File> - <File - RelativePath=".\geometry\vertexconversion.h" - > - </File> - <File - RelativePath=".\geometry\VertexDataManager.h" - > - </File> - </Filter> + <File + RelativePath="..\common\version.h" + > + </File> + <File + RelativePath=".\vertexconversion.h" + > + </File> + <File + RelativePath=".\VertexDataManager.h" + > + </File> </Filter> <File RelativePath=".\libGLESv2.def" > </File> + <File + RelativePath=".\libGLESv2.rc" + > + </File> </Files> <Globals> </Globals> diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/main.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/main.cpp index a99ec44..154d277 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/main.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/main.cpp @@ -7,6 +7,7 @@ // main.cpp: DLL entry point and management of thread-local data. #include "libGLESv2/main.h" +#include "libGLESv2/utilities.h" #include "common/debug.h" #include "libEGL/Surface.h" @@ -93,6 +94,25 @@ Context *getContext() return current->context; } +Context *getNonLostContext() +{ + Context *context = getContext(); + + if (context) + { + if (context->isContextLost()) + { + error(GL_OUT_OF_MEMORY); + return NULL; + } + else + { + return context; + } + } + return NULL; +} + egl::Display *getDisplay() { Current *current = (Current*)TlsGetValue(currentTLS); @@ -106,6 +126,19 @@ IDirect3DDevice9 *getDevice() return display->getDevice(); } + +bool checkDeviceLost(HRESULT errorCode) +{ + egl::Display *display = NULL; + + if (isDeviceLostError(errorCode)) + { + display = gl::getDisplay(); + display->notifyDeviceLost(); + return true; + } + return false; +} } // Records an error code @@ -119,23 +152,23 @@ void error(GLenum errorCode) { case GL_INVALID_ENUM: context->recordInvalidEnum(); - gl::trace("\t! Error generated: invalid enum\n"); + TRACE("\t! Error generated: invalid enum\n"); break; case GL_INVALID_VALUE: context->recordInvalidValue(); - gl::trace("\t! Error generated: invalid value\n"); + TRACE("\t! Error generated: invalid value\n"); break; case GL_INVALID_OPERATION: context->recordInvalidOperation(); - gl::trace("\t! Error generated: invalid operation\n"); + TRACE("\t! Error generated: invalid operation\n"); break; case GL_OUT_OF_MEMORY: context->recordOutOfMemory(); - gl::trace("\t! Error generated: out of memory\n"); + TRACE("\t! Error generated: out of memory\n"); break; case GL_INVALID_FRAMEBUFFER_OPERATION: context->recordInvalidFramebufferOperation(); - gl::trace("\t! Error generated: invalid framebuffer operation\n"); + TRACE("\t! Error generated: invalid framebuffer operation\n"); break; default: UNREACHABLE(); } diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/main.h b/Source/ThirdParty/ANGLE/src/libGLESv2/main.h index 7f9c880..504848a 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/main.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/main.h @@ -29,9 +29,12 @@ struct Current void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface); Context *getContext(); +Context *getNonLostContext(); egl::Display *getDisplay(); IDirect3DDevice9 *getDevice(); + +bool checkDeviceLost(HRESULT errorCode); } void error(GLenum errorCode); diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h b/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h index 31fa16f..7ca2d9f 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/mathutil.h @@ -9,7 +9,9 @@ #ifndef LIBGLESV2_MATHUTIL_H_ #define LIBGLESV2_MATHUTIL_H_ +#include <intrin.h> #include <math.h> +#include <windows.h> namespace gl { @@ -38,9 +40,15 @@ inline unsigned int ceilPow2(unsigned int x) return x; } +template<typename T, typename MIN, typename MAX> +inline T clamp(T x, MIN min, MAX max) +{ + return x < min ? min : (x > max ? max : x); +} + inline float clamp01(float x) { - return x < 0 ? 0 : (x > 1 ? 1 : x); + return clamp(x, 0.0f, 1.0f); } template<const int n> @@ -61,6 +69,51 @@ inline unsigned int unorm(float x) return (unsigned int)(max * x + 0.5f); } } + +inline RECT transformPixelRect(GLint x, GLint y, GLint w, GLint h, GLint surfaceHeight) +{ + RECT rect = {x, + surfaceHeight - y - h, + x + w, + surfaceHeight - y}; + return rect; +} + +inline int transformPixelYOffset(GLint yoffset, GLint h, GLint surfaceHeight) +{ + return surfaceHeight - yoffset - h; +} + +inline GLenum adjustWinding(GLenum winding) +{ + ASSERT(winding == GL_CW || winding == GL_CCW); + return winding == GL_CW ? GL_CCW : GL_CW; +} + +inline bool supportsSSE2() +{ + static bool checked = false; + static bool supports = false; + + if (checked) + { + return supports; + } + + int info[4]; + __cpuid(info, 0); + + if (info[0] >= 1) + { + __cpuid(info, 1); + + supports = (info[3] >> 26) & 1; + } + + checked = true; + + return supports; +} } #endif // LIBGLESV2_MATHUTIL_H_ diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/resource.h b/Source/ThirdParty/ANGLE/src/libGLESv2/resource.h new file mode 100644 index 0000000..39adaad --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by libGLESv2.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp index a3f5243..6589eb1 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.cpp @@ -9,6 +9,8 @@ #include "libGLESv2/utilities.h" #include <limits> +#include <stdio.h> +#include <windows.h> #include "common/debug.h" @@ -18,7 +20,8 @@ namespace gl { -int UniformComponentCount(GLenum type) +// This is how much data the application expects for a uniform +int UniformExternalComponentCount(GLenum type) { switch (type) { @@ -52,6 +55,42 @@ int UniformComponentCount(GLenum type) return 0; } +// This is how much data we actually store for a uniform +int UniformInternalComponentCount(GLenum type) +{ + switch (type) + { + case GL_BOOL: + case GL_INT: + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + return 1; + case GL_BOOL_VEC2: + case GL_INT_VEC2: + return 2; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + return 3; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_BOOL_VEC4: + case GL_FLOAT_VEC4: + case GL_INT_VEC4: + return 4; + case GL_FLOAT_MAT2: + return 8; + case GL_FLOAT_MAT3: + return 12; + case GL_FLOAT_MAT4: + return 16; + default: + UNREACHABLE(); + } + + return 0; +} + GLenum UniformComponentType(GLenum type) { switch(type) @@ -83,16 +122,27 @@ GLenum UniformComponentType(GLenum type) return GL_NONE; } -size_t UniformTypeSize(GLenum type) +size_t UniformComponentSize(GLenum type) { switch(type) { - case GL_BOOL: return sizeof(GLboolean); + case GL_BOOL: return sizeof(GLint); case GL_FLOAT: return sizeof(GLfloat); case GL_INT: return sizeof(GLint); + default: UNREACHABLE(); } - return UniformTypeSize(UniformComponentType(type)) * UniformComponentCount(type); + return 0; +} + +size_t UniformInternalSize(GLenum type) +{ + return UniformComponentSize(UniformComponentType(type)) * UniformInternalComponentCount(type); +} + +size_t UniformExternalSize(GLenum type) +{ + return UniformComponentSize(UniformComponentType(type)) * UniformExternalComponentCount(type); } int VariableRowCount(GLenum type) @@ -189,18 +239,7 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment) GLsizei ComputeCompressedPitch(GLsizei width, GLenum format) { - switch (format) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - break; - default: - return 0; - } - - ASSERT(width % 4 == 0); - - return 8 * width / 4; + return ComputeCompressedSize(width, 1, format); } GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format) @@ -209,18 +248,23 @@ GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f); break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return 16 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f); default: return 0; } - return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f); } bool IsCompressed(GLenum format) { if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) + format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || + format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE || + format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE) { return true; } @@ -284,7 +328,7 @@ bool IsCubemapTextureTarget(GLenum target) return (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z); } -bool IsTextureTarget(GLenum target) +bool IsInternalTextureTarget(GLenum target) { return target == GL_TEXTURE_2D || IsCubemapTextureTarget(target); } @@ -336,6 +380,68 @@ bool CheckTextureFormatType(GLenum format, GLenum type) } } +GLenum ExtractFormat(GLenum internalformat) +{ + switch (internalformat) + { + case GL_RGB565: return GL_RGB; + case GL_RGBA4: return GL_RGBA; + case GL_RGB5_A1: return GL_RGBA; + case GL_RGB8_OES: return GL_RGB; + case GL_RGBA8_OES: return GL_RGBA; + case GL_LUMINANCE8_ALPHA8_EXT: return GL_LUMINANCE_ALPHA; + case GL_LUMINANCE8_EXT: return GL_LUMINANCE; + case GL_ALPHA8_EXT: return GL_ALPHA; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + case GL_RGBA32F_EXT: return GL_RGBA; + case GL_RGB32F_EXT: return GL_RGB; + case GL_ALPHA32F_EXT: return GL_ALPHA; + case GL_LUMINANCE32F_EXT: return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA32F_EXT: return GL_LUMINANCE_ALPHA; + case GL_RGBA16F_EXT: return GL_RGBA; + case GL_RGB16F_EXT: return GL_RGB; + case GL_ALPHA16F_EXT: return GL_ALPHA; + case GL_LUMINANCE16F_EXT: return GL_LUMINANCE; + case GL_LUMINANCE_ALPHA16F_EXT: return GL_LUMINANCE_ALPHA; + case GL_BGRA8_EXT: return GL_BGRA_EXT; + default: return GL_NONE; // Unsupported + } +} + +GLenum ExtractType(GLenum internalformat) +{ + switch (internalformat) + { + case GL_RGB565: return GL_UNSIGNED_SHORT_5_6_5; + case GL_RGBA4: return GL_UNSIGNED_SHORT_4_4_4_4; + case GL_RGB5_A1: return GL_UNSIGNED_SHORT_5_5_5_1; + case GL_RGB8_OES: return GL_UNSIGNED_BYTE; + case GL_RGBA8_OES: return GL_UNSIGNED_BYTE; + case GL_LUMINANCE8_ALPHA8_EXT: return GL_UNSIGNED_BYTE; + case GL_LUMINANCE8_EXT: return GL_UNSIGNED_BYTE; + case GL_ALPHA8_EXT: return GL_UNSIGNED_BYTE; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: return GL_UNSIGNED_BYTE; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: return GL_UNSIGNED_BYTE; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: return GL_UNSIGNED_BYTE; + case GL_RGBA32F_EXT: return GL_FLOAT; + case GL_RGB32F_EXT: return GL_FLOAT; + case GL_ALPHA32F_EXT: return GL_FLOAT; + case GL_LUMINANCE32F_EXT: return GL_FLOAT; + case GL_LUMINANCE_ALPHA32F_EXT: return GL_FLOAT; + case GL_RGBA16F_EXT: return GL_HALF_FLOAT_OES; + case GL_RGB16F_EXT: return GL_HALF_FLOAT_OES; + case GL_ALPHA16F_EXT: return GL_HALF_FLOAT_OES; + case GL_LUMINANCE16F_EXT: return GL_HALF_FLOAT_OES; + case GL_LUMINANCE_ALPHA16F_EXT: return GL_HALF_FLOAT_OES; + case GL_BGRA8_EXT: return GL_UNSIGNED_BYTE; + default: return GL_NONE; // Unsupported + } +} + bool IsColorRenderable(GLenum internalformat) { switch (internalformat) @@ -528,6 +634,39 @@ D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) return cull; } +D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) +{ + D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; + + // Map a cube map texture target to the corresponding D3D surface index. Note that the + // Y faces are swapped because the Y coordinate to the texture lookup intrinsic functions + // are negated in the pixel shader. + switch (cubeFace) + { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + face = D3DCUBEMAP_FACE_POSITIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + face = D3DCUBEMAP_FACE_NEGATIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + face = D3DCUBEMAP_FACE_NEGATIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + face = D3DCUBEMAP_FACE_POSITIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + face = D3DCUBEMAP_FACE_POSITIVE_Z; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = D3DCUBEMAP_FACE_NEGATIVE_Z; + break; + default: UNREACHABLE(); + } + + return face; +} + DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) { return (red ? D3DCOLORWRITEENABLE_RED : 0) | @@ -584,6 +723,75 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } +bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, + D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount) +{ + switch (primitiveType) + { + case GL_POINTS: + *d3dPrimitiveType = D3DPT_POINTLIST; + *d3dPrimitiveCount = elementCount; + break; + case GL_LINES: + *d3dPrimitiveType = D3DPT_LINELIST; + *d3dPrimitiveCount = elementCount / 2; + break; + case GL_LINE_LOOP: + *d3dPrimitiveType = D3DPT_LINESTRIP; + *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately + break; + case GL_LINE_STRIP: + *d3dPrimitiveType = D3DPT_LINESTRIP; + *d3dPrimitiveCount = elementCount - 1; + break; + case GL_TRIANGLES: + *d3dPrimitiveType = D3DPT_TRIANGLELIST; + *d3dPrimitiveCount = elementCount / 3; + break; + case GL_TRIANGLE_STRIP: + *d3dPrimitiveType = D3DPT_TRIANGLESTRIP; + *d3dPrimitiveCount = elementCount - 2; + break; + case GL_TRIANGLE_FAN: + *d3dPrimitiveType = D3DPT_TRIANGLEFAN; + *d3dPrimitiveCount = elementCount - 2; + break; + default: + return false; + } + + return true; +} + +D3DFORMAT ConvertRenderbufferFormat(GLenum format) +{ + switch (format) + { + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; + case GL_RGB565: return D3DFMT_R5G6B5; + case GL_RGB8_OES: return D3DFMT_X8R8G8B8; + case GL_DEPTH_COMPONENT16: + case GL_STENCIL_INDEX8: + case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; + default: UNREACHABLE(); return D3DFMT_A8R8G8B8; + } +} + +D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) +{ + if (samples <= 1) + return D3DMULTISAMPLE_NONE; + else + return (D3DMULTISAMPLE_TYPE)samples; +} + +} + +namespace dx2es +{ + unsigned int GetStencilSize(D3DFORMAT stencilFormat) { switch(stencilFormat) @@ -601,11 +809,11 @@ unsigned int GetStencilSize(D3DFORMAT stencilFormat) case D3DFMT_D32F_LOCKABLE: case D3DFMT_D16: return 0; -// case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only -// case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only - default: UNREACHABLE(); + //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only + //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only + default: + return 0; } - return 0; } unsigned int GetAlphaSize(D3DFORMAT colorFormat) @@ -625,9 +833,9 @@ unsigned int GetAlphaSize(D3DFORMAT colorFormat) case D3DFMT_X8R8G8B8: case D3DFMT_R5G6B5: return 0; - default: UNREACHABLE(); + default: + return 0; } - return 0; } unsigned int GetRedSize(D3DFORMAT colorFormat) @@ -646,9 +854,9 @@ unsigned int GetRedSize(D3DFORMAT colorFormat) case D3DFMT_A1R5G5B5: case D3DFMT_R5G6B5: return 5; - default: UNREACHABLE(); + default: + return 0; } - return 0; } unsigned int GetGreenSize(D3DFORMAT colorFormat) @@ -668,9 +876,9 @@ unsigned int GetGreenSize(D3DFORMAT colorFormat) return 5; case D3DFMT_R5G6B5: return 6; - default: UNREACHABLE(); + default: + return 0; } - return 0; } unsigned int GetBlueSize(D3DFORMAT colorFormat) @@ -689,9 +897,9 @@ unsigned int GetBlueSize(D3DFORMAT colorFormat) case D3DFMT_A1R5G5B5: case D3DFMT_R5G6B5: return 5; - default: UNREACHABLE(); + default: + return 0; } - return 0; } unsigned int GetDepthSize(D3DFORMAT depthFormat) @@ -709,66 +917,52 @@ unsigned int GetDepthSize(D3DFORMAT depthFormat) case D3DFMT_D24FS8: return 24; //case D3DFMT_D32_LOCKABLE: return 32; // D3D9Ex only //case D3DFMT_S8_LOCKABLE: return 0; // D3D9Ex only - default: - UNREACHABLE(); + default: return 0; } - return 0; } -bool ConvertPrimitiveType(GLenum primitiveType, GLsizei elementCount, - D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount) +bool IsFloat32Format(D3DFORMAT surfaceFormat) { - switch (primitiveType) + switch(surfaceFormat) { - case GL_POINTS: - *d3dPrimitiveType = D3DPT_POINTLIST; - *d3dPrimitiveCount = elementCount; - break; - case GL_LINES: - *d3dPrimitiveType = D3DPT_LINELIST; - *d3dPrimitiveCount = elementCount / 2; - break; - case GL_LINE_LOOP: - *d3dPrimitiveType = D3DPT_LINESTRIP; - *d3dPrimitiveCount = elementCount - 1; // D3D doesn't support line loops, so we draw the last line separately - break; - case GL_LINE_STRIP: - *d3dPrimitiveType = D3DPT_LINESTRIP; - *d3dPrimitiveCount = elementCount - 1; - break; - case GL_TRIANGLES: - *d3dPrimitiveType = D3DPT_TRIANGLELIST; - *d3dPrimitiveCount = elementCount / 3; - break; - case GL_TRIANGLE_STRIP: - *d3dPrimitiveType = D3DPT_TRIANGLESTRIP; - *d3dPrimitiveCount = elementCount - 2; - break; - case GL_TRIANGLE_FAN: - *d3dPrimitiveType = D3DPT_TRIANGLEFAN; - *d3dPrimitiveCount = elementCount - 2; - break; - default: + case D3DFMT_R16F: + case D3DFMT_G16R16F: + case D3DFMT_A16B16G16R16F: + return false; + case D3DFMT_R32F: + case D3DFMT_G32R32F: + case D3DFMT_A32B32G32R32F: + return true; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A1R5G5B5: + case D3DFMT_R5G6B5: return false; + default: UNREACHABLE(); } - - return true; + return false; } -D3DFORMAT ConvertRenderbufferFormat(GLenum format) +bool IsFloat16Format(D3DFORMAT surfaceFormat) { - switch (format) + switch(surfaceFormat) { - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; - case GL_RGB565: return D3DFMT_R5G6B5; - case GL_RGB8_OES: return D3DFMT_X8R8G8B8; - case GL_DEPTH_COMPONENT16: - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; - default: UNREACHABLE(); return D3DFMT_A8R8G8B8; + case D3DFMT_R16F: + case D3DFMT_G16R16F: + case D3DFMT_A16B16G16R16F: + return true; + case D3DFMT_R32F: + case D3DFMT_G32R32F: + case D3DFMT_A32B32G32R32F: + return false; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A1R5G5B5: + case D3DFMT_R5G6B5: + return false; + default: UNREACHABLE(); } + return false; } GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) @@ -779,19 +973,6 @@ GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) return type; } -D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) -{ - if (samples <= 1) - return D3DMULTISAMPLE_NONE; - else - return (D3DMULTISAMPLE_TYPE)samples; -} - -} - -namespace dx2es -{ - GLenum ConvertBackBufferFormat(D3DFORMAT format) { switch (format) @@ -825,3 +1006,36 @@ GLenum ConvertDepthStencilFormat(D3DFORMAT format) } } + +std::string getTempPath() +{ + char path[MAX_PATH]; + DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); + if (pathLen == 0) + { + UNREACHABLE(); + return std::string(); + } + + UINT unique = GetTempFileNameA(path, "sh", 0, path); + if (unique == 0) + { + UNREACHABLE(); + return std::string(); + } + + return path; +} + +void writeFile(const char* path, const void* content, size_t size) +{ + FILE* file = fopen(path, "w"); + if (!file) + { + UNREACHABLE(); + return; + } + + fwrite(content, sizeof(char), size, file); + fclose(file); +} diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h index 85e8f26..88238dc 100644 --- a/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/utilities.h @@ -14,14 +14,18 @@ #include <GLES2/gl2ext.h> #include <d3d9.h> +#include <string> + namespace gl { struct Color; -int UniformComponentCount(GLenum type); +int UniformExternalComponentCount(GLenum type); +int UniformInternalComponentCount(GLenum type); GLenum UniformComponentType(GLenum type); -size_t UniformTypeSize(GLenum type); +size_t UniformInternalSize(GLenum type); +size_t UniformExternalSize(GLenum type); int VariableRowCount(GLenum type); int VariableColumnCount(GLenum type); @@ -33,8 +37,10 @@ GLsizei ComputeCompressedPitch(GLsizei width, GLenum format); GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format); bool IsCompressed(GLenum format); bool IsCubemapTextureTarget(GLenum target); -bool IsTextureTarget(GLenum target); +bool IsInternalTextureTarget(GLenum target); bool CheckTextureFormatType(GLenum format, GLenum type); +GLenum ExtractFormat(GLenum internalformat); +GLenum ExtractType(GLenum internalformat); bool IsColorRenderable(GLenum internalformat); bool IsDepthRenderable(GLenum internalformat); @@ -52,29 +58,50 @@ D3DBLENDOP ConvertBlendOp(GLenum blendOp); D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); +D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter); -unsigned int GetAlphaSize(D3DFORMAT colorFormat); -unsigned int GetRedSize(D3DFORMAT colorFormat); -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 elementCount, D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount); D3DFORMAT ConvertRenderbufferFormat(GLenum format); D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples); -GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); } namespace dx2es { +GLuint GetAlphaSize(D3DFORMAT colorFormat); +GLuint GetRedSize(D3DFORMAT colorFormat); +GLuint GetGreenSize(D3DFORMAT colorFormat); +GLuint GetBlueSize(D3DFORMAT colorFormat); +GLuint GetDepthSize(D3DFORMAT depthFormat); +GLuint GetStencilSize(D3DFORMAT stencilFormat); +bool IsFloat32Format(D3DFORMAT surfaceFormat); +bool IsFloat16Format(D3DFORMAT surfaceFormat); + +GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); GLenum ConvertBackBufferFormat(D3DFORMAT format); GLenum ConvertDepthStencilFormat(D3DFORMAT format); } +std::string getTempPath(); +void writeFile(const char* path, const void* data, size_t size); + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case D3DERR_DRIVERINTERNALERROR: + case D3DERR_DEVICELOST: + case D3DERR_DEVICEHUNG: + case D3DERR_DEVICEREMOVED: + return true; + default: + return false; + } +}; + #endif // LIBGLESV2_UTILITIES_H diff --git a/Source/ThirdParty/ANGLE/src/libGLESv2/vertexconversion.h b/Source/ThirdParty/ANGLE/src/libGLESv2/vertexconversion.h new file mode 100644 index 0000000..5bb8b89 --- /dev/null +++ b/Source/ThirdParty/ANGLE/src/libGLESv2/vertexconversion.h @@ -0,0 +1,208 @@ +// +// 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. +// + +// vertexconversion.h: A library of vertex conversion classes that can be used to build +// the FormatConverter objects used by the buffer conversion system. + +#ifndef LIBGLESV2_VERTEXCONVERSION_H_ +#define LIBGLESV2_VERTEXCONVERSION_H_ + +#include <cstddef> +#include <limits> + +#include "libGLESv2/Context.h" // Defines Index + +namespace gl +{ + +// Conversion types: +// static const bool identity: true if this is an identity transform, false otherwise +// static U convert(T): convert a single element from the input type to the output type +// typedef ... OutputType: the type produced by this conversion + +template <class T> +struct Identity +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) + { + return x; + } +}; + +template <class FromT, class ToT> +struct Cast +{ + static const bool identity = false; + + typedef ToT OutputType; + + static ToT convert(FromT x) + { + return static_cast<ToT>(x); + } +}; + +template <class T> +struct Cast<T, T> +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) + { + return static_cast<T>(x); + } +}; + +template <class T> +struct Normalize +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(T x) + { + typedef std::numeric_limits<T> NL; + float f = static_cast<float>(x); + + if (NL::is_signed) + { + // const float => VC2008 computes it at compile time + // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that. + const float divisor = 1.0f/(2*static_cast<float>(NL::max())+1); + return (2*f+1)*divisor; + } + else + { + return f/NL::max(); + } + } +}; + +template <class FromType, std::size_t ScaleBits> +struct FixedToFloat +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(FromType x) + { + const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits); + return static_cast<float>(x) * divisor; + } +}; + +// Widen types: +// static const unsigned int initialWidth: number of components before conversion +// static const unsigned int finalWidth: number of components after conversion + +// Float is supported at any size. +template <std::size_t N> +struct NoWiden +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N; +}; + +// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components +template <std::size_t N> +struct WidenToEven +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N+(N&1); +}; + +template <std::size_t N> +struct WidenToFour +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = 4; +}; + +// Most types have 0 and 1 that are just that. +template <class T> +struct SimpleDefaultValues +{ + static T zero() { return static_cast<T>(0); } + static T one() { return static_cast<T>(1); } +}; + +// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. +template <class T> +struct NormalizedDefaultValues +{ + static T zero() { return static_cast<T>(0); } + static T one() { return std::numeric_limits<T>::max(); } +}; + +// Converter: +// static const bool identity: true if this is an identity transform (with no widening) +// static const std::size_t finalSize: number of bytes per output vertex +// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided. + +template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> > +struct VertexDataConverter +{ + typedef typename Converter::OutputType OutputType; + typedef InT InputType; + + static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; + static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); + + static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out) + { + for (std::size_t i = 0; i < n; i++) + { + const InputType *ein = pointerAddBytes(in, i * stride); + + copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero())); + copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero())); + copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero())); + copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one())); + + out += WidenRule::finalWidth; + } + } + + static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out) + { + return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out)); + } + + private: + // Advance the given pointer by a number of bytes (not pointed-to elements). + template <class T> + static T *pointerAddBytes(T *basePtr, std::size_t numBytes) + { + return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes); + } + + static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) + { + if (WidenRule::finalWidth > elementindex) + { + if (WidenRule::initialWidth > elementindex) + { + out[elementindex] = Converter::convert(in[elementindex]); + } + else + { + out[elementindex] = defaultvalue; + } + } + } +}; + +} + +#endif // LIBGLESV2_VERTEXCONVERSION_H_ |