<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[164567] trunk/Source/ThirdParty/ANGLE</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/164567">164567</a></dd>
<dt>Author</dt> <dd>dino@apple.com</dd>
<dt>Date</dt> <dd>2014-02-23 16:58:19 -0800 (Sun, 23 Feb 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Missing files from previous commit.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceThirdPartyANGLEChangeLog">trunk/Source/ThirdParty/ANGLE/ChangeLog</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/Source/ThirdParty/ANGLE/src/compiler/translator/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorBaseTypesh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorBuiltInFunctionEmulatorcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorBuiltInFunctionEmulatorh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorCodeGencpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorCommonh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorCompilercpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorConstantUnionh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ConstantUnion.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDetectCallDepthcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDetectCallDepthh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDetectDiscontinuitycpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDetectDiscontinuityh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDiagnosticscpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDiagnosticsh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDirectiveHandlercpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorDirectiveHandlerh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorExtensionBehaviorh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorForLoopUnrollcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorForLoopUnrollh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorHashNamesh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/HashNames.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInfoSinkcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInfoSinkh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeDllcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeDllh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeGlobalsh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeGlobals.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeParseContextcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeParseContexth">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeVariablescpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeVariablesh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorIntermTraversecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorIntermediatecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorMMaph">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MMap.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorMapLongVariableNamescpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorMapLongVariableNamesh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorNodeSearchh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputESSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputESSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLBasecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLBaseh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputHLSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorOutputHLSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorParseContextcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorParseContexth">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorPoolAlloccpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorPoolAlloch">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorPragmah">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Pragma.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorQualifierAlivecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorQualifierAliveh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorRemoveTreecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorRemoveTreeh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorRenameFunctionh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorRewriteElseBlockscpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorRewriteElseBlocksh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorSearchSymbolcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorSearchSymbolh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorShHandleh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShHandle.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorShaderLangcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorSymbolTablecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorSymbolTableh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorESSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorESSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorGLSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorGLSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorHLSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorHLSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorTypesh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuith">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitASTcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitASTh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUniformcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorUniformh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorValidateLimitationscpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorValidateLimitationsh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVariableInfocpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVariableInfoh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVariablePackercpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVariablePackerh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVersionGLSLcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorVersionGLSLh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorcompilerdebugcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorcompilerdebugh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.h</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphBuildercpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphBuilderh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphOutputcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphOutputh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphTraversecpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorgenerate_parsersh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslangh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslangl">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslangy">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_lexcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_tabcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_tabh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorintermOutcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorintermediateh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorlocalintermediateh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/localintermediate.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorosincludeh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/osinclude.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorossource_posixcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_posix.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorossource_wincpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_win.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorparseConstcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictFragmentShaderTimingcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictFragmentShaderTimingh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictVertexShaderTimingcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictVertexShaderTimingh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorutilcpp">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrccompilertranslatorutilh">trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.h</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11BufferStorage11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11BufferStorage11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Fence11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Fence11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Image11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Image11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11IndexBuffer11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11IndexBuffer11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11InputLayoutCachecpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11InputLayoutCacheh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Query11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Query11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderStateCachecpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderStateCacheh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderTarget11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderTarget11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Renderer11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Renderer11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11ShaderExecutable11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11ShaderExecutable11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11SwapChain11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11SwapChain11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11TextureStorage11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11TextureStorage11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11VertexBuffer11cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11VertexBuffer11h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11renderer11_utilscpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11renderer11_utilsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.h</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersClear11hlsl">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersPassthrough11hlsl">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclear11vsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclearmultiple11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclearsingle11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthrough11vsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughlum11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughlumalpha11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughrgb11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughrgba11psh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersgenerate_shadersbat">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Blitcpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Blith">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9BufferStorage9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9BufferStorage9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Fence9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Fence9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Image9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Image9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9IndexBuffer9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9IndexBuffer9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Query9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Query9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9RenderTarget9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9RenderTarget9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Renderer9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Renderer9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9ShaderExecutable9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9ShaderExecutable9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9SwapChain9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9SwapChain9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9TextureStorage9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9TextureStorage9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexBuffer9cpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexBuffer9h">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexDeclarationCachecpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexDeclarationCacheh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9renderer9_utilscpp">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9renderer9_utilsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.h</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersBlitps">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.ps</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersBlitvs">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.vs</a></li>
<li>trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/</li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledcomponentmaskpsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledflipyvsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledluminancepsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledpassthroughpsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledstandardvsh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersgenerate_shadersbat">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat</a></li>
<li><a href="#trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9vertexconversionh">trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/vertexconversion.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceThirdPartyANGLEChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/ThirdParty/ANGLE/ChangeLog (164566 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/ChangeLog        2014-02-24 00:51:05 UTC (rev 164566)
+++ trunk/Source/ThirdParty/ANGLE/ChangeLog        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -1,5 +1,9 @@
</span><span class="cx"> 2014-02-23  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Missing files from previous commit.
+
+2014-02-23  Dean Jackson  &lt;dino@apple.com&gt;
+
</ins><span class="cx">         Update ANGLE to 836bd2176e5607b14846cf1fbc5932dbc91318f4
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=129232
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorBaseTypesh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,149 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _BASICTYPES_INCLUDED_
+#define _BASICTYPES_INCLUDED_
+
+//
+// Precision qualifiers
+//
+enum TPrecision
+{
+    // These need to be kept sorted
+    EbpUndefined,
+    EbpLow,
+    EbpMedium,
+    EbpHigh
+};
+
+inline const char* getPrecisionString(TPrecision p)
+{
+    switch(p)
+    {
+    case EbpHigh:   return &quot;highp&quot;;   break;
+    case EbpMedium:   return &quot;mediump&quot;; break;
+    case EbpLow:    return &quot;lowp&quot;;    break;
+    default:      return &quot;mediump&quot;;   break;   // Safest fallback
+    }
+}
+
+//
+// Basic type.  Arrays, vectors, etc., are orthogonal to this.
+//
+enum TBasicType
+{
+    EbtVoid,
+    EbtFloat,
+    EbtInt,
+    EbtBool,
+    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)
+{
+    switch (t)
+    {
+    case EbtVoid:              return &quot;void&quot;;              break;
+    case EbtFloat:             return &quot;float&quot;;             break;
+    case EbtInt:               return &quot;int&quot;;               break;
+    case EbtBool:              return &quot;bool&quot;;              break;
+    case EbtSampler2D:         return &quot;sampler2D&quot;;         break;
+    case EbtSamplerCube:       return &quot;samplerCube&quot;;       break;
+    case EbtSamplerExternalOES: return &quot;samplerExternalOES&quot;; break;
+    case EbtSampler2DRect:     return &quot;sampler2DRect&quot;;     break;
+    case EbtStruct:            return &quot;structure&quot;;         break;
+    default:                   return &quot;unknown type&quot;;
+    }
+}
+
+inline bool IsSampler(TBasicType type)
+{
+    return type &gt; EbtGuardSamplerBegin &amp;&amp; type &lt; EbtGuardSamplerEnd;
+}
+
+//
+// Qualifiers and built-ins.  These are mainly used to see what can be read
+// or written, and by the machine dependent translator to know which registers
+// to allocate variables in.  Since built-ins tend to go to different registers
+// than varying or uniform, it makes sense they are peers, not sub-classes.
+//
+enum TQualifier
+{
+    EvqTemporary,     // For temporaries (within a function), read/write
+    EvqGlobal,        // For globals read/write
+    EvqInternal,      // For internal use, not visible to the user
+    EvqConst,         // User defined constants and non-output parameters in functions
+    EvqAttribute,     // Readonly
+    EvqVaryingIn,     // readonly, fragment shaders only
+    EvqVaryingOut,    // vertex shaders only  read/write
+    EvqInvariantVaryingIn,     // readonly, fragment shaders only
+    EvqInvariantVaryingOut,    // vertex shaders only  read/write
+    EvqUniform,       // Readonly, vertex and fragment
+
+    // parameters
+    EvqIn,
+    EvqOut,
+    EvqInOut,
+    EvqConstReadOnly,
+
+    // built-ins written by vertex shader
+    EvqPosition,
+    EvqPointSize,
+
+    // built-ins read by fragment shader
+    EvqFragCoord,
+    EvqFrontFacing,
+    EvqPointCoord,
+
+    // built-ins written by fragment shader
+    EvqFragColor,
+    EvqFragData,
+    EvqFragDepth,
+
+    // end of list
+    EvqLast
+};
+
+//
+// This is just for debug print out, carried along with the definitions above.
+//
+inline const char* getQualifierString(TQualifier q)
+{
+    switch(q)
+    {
+    case EvqTemporary:      return &quot;Temporary&quot;;      break;
+    case EvqGlobal:         return &quot;Global&quot;;         break;
+    case EvqConst:          return &quot;const&quot;;          break;
+    case EvqConstReadOnly:  return &quot;const&quot;;          break;
+    case EvqAttribute:      return &quot;attribute&quot;;      break;
+    case EvqVaryingIn:      return &quot;varying&quot;;        break;
+    case EvqVaryingOut:     return &quot;varying&quot;;        break;
+    case EvqInvariantVaryingIn: return &quot;invariant varying&quot;; break;
+    case EvqInvariantVaryingOut:return &quot;invariant varying&quot;; break;
+    case EvqUniform:        return &quot;uniform&quot;;        break;
+    case EvqIn:             return &quot;in&quot;;             break;
+    case EvqOut:            return &quot;out&quot;;            break;
+    case EvqInOut:          return &quot;inout&quot;;          break;
+    case EvqPosition:       return &quot;Position&quot;;       break;
+    case EvqPointSize:      return &quot;PointSize&quot;;      break;
+    case EvqFragCoord:      return &quot;FragCoord&quot;;      break;
+    case EvqFrontFacing:    return &quot;FrontFacing&quot;;    break;
+    case EvqFragColor:      return &quot;FragColor&quot;;      break;
+    case EvqFragData:       return &quot;FragData&quot;;      break;
+    case EvqFragDepth:      return &quot;FragDepth&quot;;     break;
+    default:                return &quot;unknown qualifier&quot;;
+    }
+}
+
+#endif // _BASICTYPES_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BaseTypes.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorBuiltInFunctionEmulatorcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,406 @@
</span><ins>+//
+// 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 &quot;compiler/translator/BuiltInFunctionEmulator.h&quot;
+
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+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[] = {
+    &quot;#error no emulation for cos(float)&quot;,
+    &quot;#error no emulation for cos(vec2)&quot;,
+    &quot;#error no emulation for cos(vec3)&quot;,
+    &quot;#error no emulation for cos(vec4)&quot;,
+
+    &quot;#define webgl_distance_emu(x, y) ((x) &gt;= (y) ? (x) - (y) : (y) - (x))&quot;,
+    &quot;#error no emulation for distance(vec2, vec2)&quot;,
+    &quot;#error no emulation for distance(vec3, vec3)&quot;,
+    &quot;#error no emulation for distance(vec4, vec4)&quot;,
+
+    &quot;#define webgl_dot_emu(x, y) ((x) * (y))&quot;,
+    &quot;#error no emulation for dot(vec2, vec2)&quot;,
+    &quot;#error no emulation for dot(vec3, vec3)&quot;,
+    &quot;#error no emulation for dot(vec4, vec4)&quot;,
+
+    &quot;#define webgl_length_emu(x) ((x) &gt;= 0.0 ? (x) : -(x))&quot;,
+    &quot;#error no emulation for length(vec2)&quot;,
+    &quot;#error no emulation for length(vec3)&quot;,
+    &quot;#error no emulation for length(vec4)&quot;,
+
+    &quot;#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) &gt; 0.0 ? 1.0 : -1.0))&quot;,
+    &quot;#error no emulation for normalize(vec2)&quot;,
+    &quot;#error no emulation for normalize(vec3)&quot;,
+    &quot;#error no emulation for normalize(vec4)&quot;,
+
+    &quot;#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))&quot;,
+    &quot;#error no emulation for reflect(vec2, vec2)&quot;,
+    &quot;#error no emulation for reflect(vec3, vec3)&quot;,
+    &quot;#error no emulation for reflect(vec4, vec4)&quot;
+};
+
+const char* kFunctionEmulationFragmentSource[] = {
+    &quot;webgl_emu_precision float webgl_cos_emu(webgl_emu_precision float a) { return cos(a); }&quot;,
+    &quot;webgl_emu_precision vec2 webgl_cos_emu(webgl_emu_precision vec2 a) { return cos(a); }&quot;,
+    &quot;webgl_emu_precision vec3 webgl_cos_emu(webgl_emu_precision vec3 a) { return cos(a); }&quot;,
+    &quot;webgl_emu_precision vec4 webgl_cos_emu(webgl_emu_precision vec4 a) { return cos(a); }&quot;,
+
+    &quot;#define webgl_distance_emu(x, y) ((x) &gt;= (y) ? (x) - (y) : (y) - (x))&quot;,
+    &quot;#error no emulation for distance(vec2, vec2)&quot;,
+    &quot;#error no emulation for distance(vec3, vec3)&quot;,
+    &quot;#error no emulation for distance(vec4, vec4)&quot;,
+
+    &quot;#define webgl_dot_emu(x, y) ((x) * (y))&quot;,
+    &quot;#error no emulation for dot(vec2, vec2)&quot;,
+    &quot;#error no emulation for dot(vec3, vec3)&quot;,
+    &quot;#error no emulation for dot(vec4, vec4)&quot;,
+
+    &quot;#define webgl_length_emu(x) ((x) &gt;= 0.0 ? (x) : -(x))&quot;,
+    &quot;#error no emulation for length(vec2)&quot;,
+    &quot;#error no emulation for length(vec3)&quot;,
+    &quot;#error no emulation for length(vec4)&quot;,
+
+    &quot;#define webgl_normalize_emu(x) ((x) == 0.0 ? 0.0 : ((x) &gt; 0.0 ? 1.0 : -1.0))&quot;,
+    &quot;#error no emulation for normalize(vec2)&quot;,
+    &quot;#error no emulation for normalize(vec3)&quot;,
+    &quot;#error no emulation for normalize(vec4)&quot;,
+
+    &quot;#define webgl_reflect_emu(I, N) ((I) - 2.0 * (N) * (I) * (N))&quot;,
+    &quot;#error no emulation for reflect(vec2, vec2)&quot;,
+    &quot;#error no emulation for reflect(vec3, vec3)&quot;,
+    &quot;#error no emulation for reflect(vec4, vec4)&quot;
+};
+
+const bool kFunctionEmulationVertexMask[] = {
+#if defined(__APPLE__)
+    // Work around ATI driver bugs in Mac.
+    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
+    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, // 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, // 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[] = {
+#if defined(__APPLE__)
+    // Work around ATI driver bugs in Mac.
+    true,  // TFunctionCos1
+    true,  // TFunctionCos2
+    true,  // TFunctionCos3
+    true,  // 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
+    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, // 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, // TFunctionNormalize1
+    false, // TFunctionNormalize2
+    false, // TFunctionNormalize3
+    false, // TFunctionNormalize4
+    false, // TFunctionReflect1_1
+    false, // TFunctionReflect2_2
+    false, // TFunctionReflect3_3
+    false, // TFunctionReflect4_4
+#endif
+    false  // TFunctionUnknown
+};
+
+class BuiltInFunctionEmulationMarker : public TIntermTraverser {
+public:
+    BuiltInFunctionEmulationMarker(BuiltInFunctionEmulator&amp; emulator)
+        : mEmulator(emulator)
+    {
+    }
+
+    virtual bool visitUnary(Visit visit, TIntermUnary* node)
+    {
+        if (visit == PreVisit) {
+            bool needToEmulate = mEmulator.SetFunctionCalled(
+                node-&gt;getOp(), node-&gt;getOperand()-&gt;getType());
+            if (needToEmulate)
+                node-&gt;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-&gt;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&amp; sequence = node-&gt;getSequence();
+            // Right now we only handle built-in functions with two parameters.
+            if (sequence.size() != 2)
+                return true;
+            TIntermTyped* param1 = sequence[0]-&gt;getAsTyped();
+            TIntermTyped* param2 = sequence[1]-&gt;getAsTyped();
+            if (!param1 || !param2)
+                return true;
+            bool needToEmulate = mEmulator.SetFunctionCalled(
+                node-&gt;getOp(), param1-&gt;getType(), param2-&gt;getType());
+            if (needToEmulate)
+                node-&gt;setUseEmulatedFunction();
+        }
+        return true;
+    }
+
+private:
+    BuiltInFunctionEmulator&amp; 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&amp; param)
+{
+    TBuiltInFunction function = IdentifyFunction(op, param);
+    return SetFunctionCalled(function);
+}
+
+bool BuiltInFunctionEmulator::SetFunctionCalled(
+    TOperator op, const TType&amp; param1, const TType&amp; 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 &lt; mFunctions.size(); ++i) {
+        if (mFunctions[i] == function)
+            return true;
+    }
+    mFunctions.push_back(function);
+    return true;
+}
+
+void BuiltInFunctionEmulator::OutputEmulatedFunctionDefinition(
+    TInfoSinkBase&amp; out, bool withPrecision) const
+{
+    if (mFunctions.size() == 0)
+        return;
+    out &lt;&lt; &quot;// BEGIN: Generated code for built-in function emulation\n\n&quot;;
+    if (withPrecision) {
+        out &lt;&lt; &quot;#if defined(GL_FRAGMENT_PRECISION_HIGH)\n&quot;
+            &lt;&lt; &quot;#define webgl_emu_precision highp\n&quot;
+            &lt;&lt; &quot;#else\n&quot;
+            &lt;&lt; &quot;#define webgl_emu_precision mediump\n&quot;
+            &lt;&lt; &quot;#endif\n\n&quot;;
+    } else {
+        out &lt;&lt; &quot;#define webgl_emu_precision\n\n&quot;;
+    }
+    for (size_t i = 0; i &lt; mFunctions.size(); ++i) {
+        out &lt;&lt; mFunctionSource[mFunctions[i]] &lt;&lt; &quot;\n\n&quot;;
+    }
+    out &lt;&lt; &quot;// END: Generated code for built-in function emulation\n\n&quot;;
+}
+
+BuiltInFunctionEmulator::TBuiltInFunction
+BuiltInFunctionEmulator::IdentifyFunction(
+    TOperator op, const TType&amp; param)
+{
+    if (param.getNominalSize() &gt; 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&lt;TBuiltInFunction&gt;(function);
+}
+
+BuiltInFunctionEmulator::TBuiltInFunction
+BuiltInFunctionEmulator::IdentifyFunction(
+    TOperator op, const TType&amp; param1, const TType&amp; 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() &gt; 4)
+        return TFunctionUnknown;
+
+    unsigned int function = TFunctionUnknown;
+    switch (op) {
+        case EOpDistance:
+            function = TFunctionDistance1_1;
+            break;
+        case EOpDot:
+            function = TFunctionDot1_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&lt;TBuiltInFunction&gt;(function);
+}
+
+void BuiltInFunctionEmulator::MarkBuiltInFunctionsForEmulation(
+    TIntermNode* root)
+{
+    ASSERT(root);
+
+    BuiltInFunctionEmulationMarker marker(*this);
+    root-&gt;traverse(&amp;marker);
+}
+
+void BuiltInFunctionEmulator::Cleanup()
+{
+    mFunctions.clear();
+}
+
+//static
+TString BuiltInFunctionEmulator::GetEmulatedFunctionName(
+    const TString&amp; name)
+{
+    ASSERT(name[name.length() - 1] == '(');
+    return &quot;webgl_&quot; + name.substr(0, name.length() - 1) + &quot;_emu(&quot;;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorBuiltInFunctionEmulatorh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,93 @@
</span><ins>+//
+// 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 &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+//
+// 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&amp; param);
+    bool SetFunctionCalled(
+        TOperator op, const TType&amp; param1, const TType&amp; param2);
+
+    // Output function emulation definition.  This should be before any other
+    // shader source.
+    void OutputEmulatedFunctionDefinition(TInfoSinkBase&amp; out, bool withPrecision) const;
+
+    void MarkBuiltInFunctionsForEmulation(TIntermNode* root);
+
+    void Cleanup();
+
+    // &quot;name(&quot; becomes &quot;webgl_name_emu(&quot;.
+    static TString GetEmulatedFunctionName(const TString&amp; name);
+
+private:
+    //
+    // Built-in functions.
+    //
+    enum TBuiltInFunction {
+        TFunctionCos1 = 0,  // 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);
+
+        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&amp; param);
+    TBuiltInFunction IdentifyFunction(
+        TOperator op, const TType&amp; param1, const TType&amp; param2);
+
+    bool SetFunctionCalled(TBuiltInFunction function);
+
+    std::vector&lt;TBuiltInFunction&gt; mFunctions;
+
+    const bool* mFunctionMask;  // a boolean flag for each function.
+    const char** mFunctionSource;
+};
+
+#endif  // COMPILIER_BUILT_IN_FUNCTION_EMULATOR_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/BuiltInFunctionEmulator.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorCodeGencpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/TranslatorESSL.h&quot;
+#include &quot;compiler/translator/TranslatorGLSL.h&quot;
+#include &quot;compiler/translator/TranslatorHLSL.h&quot;
+
+//
+// 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, ShShaderOutput output)
+{
+    switch (output) {
+      case SH_ESSL_OUTPUT:
+        return new TranslatorESSL(type, spec);
+      case SH_GLSL_OUTPUT:
+        return new TranslatorGLSL(type, spec);
+      case SH_HLSL9_OUTPUT:
+      case SH_HLSL11_OUTPUT:
+        return new TranslatorHLSL(type, spec, output);
+      default:
+        return NULL;
+    }
+}
+
+//
+// Delete the compiler made by ConstructCompiler
+//
+void DeleteCompiler(TCompiler* compiler)
+{
+    delete compiler;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/CodeGen.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorCommonh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _COMMON_INCLUDED_
+#define _COMMON_INCLUDED_
+
+#include &lt;map&gt;
+#include &lt;sstream&gt;
+#include &lt;string&gt;
+#include &lt;vector&gt;
+#include &lt;limits&gt;
+#include &lt;stdio.h&gt;
+
+#include &quot;compiler/translator/PoolAlloc.h&quot;
+#include &quot;compiler/translator/compilerdebug.h&quot;
+#include &quot;common/angleutils.h&quot;
+
+struct TSourceLoc {
+    int first_file;
+    int first_line;
+    int last_file;
+    int last_line;
+};
+
+//
+// Put POOL_ALLOCATOR_NEW_DELETE in base classes to make them use this scheme.
+//
+#define POOL_ALLOCATOR_NEW_DELETE()                                                  \
+    void* operator new(size_t s) { return GetGlobalPoolAllocator()-&gt;allocate(s); }   \
+    void* operator new(size_t, void *_Where) { return (_Where); }                    \
+    void operator delete(void*) { }                                                  \
+    void operator delete(void *, void *) { }                                         \
+    void* operator new[](size_t s) { return GetGlobalPoolAllocator()-&gt;allocate(s); } \
+    void* operator new[](size_t, void *_Where) { return (_Where); }                  \
+    void operator delete[](void*) { }                                                \
+    void operator delete[](void *, void *) { }
+
+//
+// Pool version of string.
+//
+typedef pool_allocator&lt;char&gt; TStringAllocator;
+typedef std::basic_string &lt;char, std::char_traits&lt;char&gt;, TStringAllocator&gt; TString;
+typedef std::basic_ostringstream&lt;char, std::char_traits&lt;char&gt;, TStringAllocator&gt; TStringStream;
+inline TString* NewPoolTString(const char* s)
+{
+  void* memory = GetGlobalPoolAllocator()-&gt;allocate(sizeof(TString));
+  return new(memory) TString(s);
+}
+
+//
+// Persistent string memory.  Should only be used for strings that survive
+// across compiles.
+//
+#define TPersistString std::string
+#define TPersistStringStream std::ostringstream
+
+//
+// Pool allocator versions of vectors, lists, and maps
+//
+template &lt;class T&gt; class TVector : public std::vector&lt;T, pool_allocator&lt;T&gt; &gt; {
+public:
+    typedef typename std::vector&lt;T, pool_allocator&lt;T&gt; &gt;::size_type size_type;
+    TVector() : std::vector&lt;T, pool_allocator&lt;T&gt; &gt;() {}
+    TVector(const pool_allocator&lt;T&gt;&amp; a) : std::vector&lt;T, pool_allocator&lt;T&gt; &gt;(a) {}
+    TVector(size_type i): std::vector&lt;T, pool_allocator&lt;T&gt; &gt;(i) {}
+};
+
+template &lt;class K, class D, class CMP = std::less&lt;K&gt; &gt; 
+class TMap : public std::map&lt;K, D, CMP, pool_allocator&lt;std::pair&lt;const K, D&gt; &gt; &gt; {
+public:
+    typedef pool_allocator&lt;std::pair&lt;const K, D&gt; &gt; tAllocator;
+
+    TMap() : std::map&lt;K, D, CMP, tAllocator&gt;() {}
+    // use correct two-stage name lookup supported in gcc 3.4 and above
+    TMap(const tAllocator&amp; a) : std::map&lt;K, D, CMP, tAllocator&gt;(std::map&lt;K, D, CMP, tAllocator&gt;::key_compare(), a) {}
+};
+
+// Integer to TString conversion
+template &lt;typename T&gt;
+inline TString str(T i)
+{
+    ASSERT(std::numeric_limits&lt;T&gt;::is_integer);
+    char buffer[((8 * sizeof(T)) / 3) + 3];
+    const char *formatStr = std::numeric_limits&lt;T&gt;::is_signed ? &quot;%d&quot; : &quot;%u&quot;;
+    snprintf(buffer, sizeof(buffer), formatStr, i);
+    return buffer;
+}
+
+#endif // _COMMON_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Common.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorCompilercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,538 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/BuiltInFunctionEmulator.h&quot;
+#include &quot;compiler/translator/DetectCallDepth.h&quot;
+#include &quot;compiler/translator/ForLoopUnroll.h&quot;
+#include &quot;compiler/translator/Initialize.h&quot;
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+#include &quot;compiler/translator/InitializeVariables.h&quot;
+#include &quot;compiler/translator/MapLongVariableNames.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;compiler/translator/RenameFunction.h&quot;
+#include &quot;compiler/translator/ShHandle.h&quot;
+#include &quot;compiler/translator/UnfoldShortCircuitAST.h&quot;
+#include &quot;compiler/translator/ValidateLimitations.h&quot;
+#include &quot;compiler/translator/VariablePacker.h&quot;
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+#include &quot;compiler/translator/depgraph/DependencyGraphOutput.h&quot;
+#include &quot;compiler/translator/timing/RestrictFragmentShaderTiming.h&quot;
+#include &quot;compiler/translator/timing/RestrictVertexShaderTiming.h&quot;
+#include &quot;third_party/compiler/ArrayBoundsClamper.h&quot;
+
+bool isWebGLBasedSpec(ShShaderSpec spec)
+{
+     return spec == SH_WEBGL_SPEC || spec == SH_CSS_SHADERS_SPEC;
+}
+
+namespace {
+class TScopedPoolAllocator
+{
+  public:
+    TScopedPoolAllocator(TPoolAllocator* allocator) : mAllocator(allocator)
+    {
+        mAllocator-&gt;push();
+        SetGlobalPoolAllocator(mAllocator);
+    }
+    ~TScopedPoolAllocator()
+    {
+        SetGlobalPoolAllocator(NULL);
+        mAllocator-&gt;pop();
+    }
+
+  private:
+    TPoolAllocator* mAllocator;
+};
+
+class TScopedSymbolTableLevel
+{
+  public:
+    TScopedSymbolTableLevel(TSymbolTable* table) : mTable(table)
+    {
+        ASSERT(mTable-&gt;atBuiltInLevel());
+        mTable-&gt;push();
+    }
+    ~TScopedSymbolTableLevel()
+    {
+        while (!mTable-&gt;atBuiltInLevel())
+            mTable-&gt;pop();
+    }
+
+  private:
+    TSymbolTable* mTable;
+};
+}  // namespace
+
+TShHandleBase::TShHandleBase()
+{
+    allocator.push();
+    SetGlobalPoolAllocator(&amp;allocator);
+}
+
+TShHandleBase::~TShHandleBase()
+{
+    SetGlobalPoolAllocator(NULL);
+    allocator.popAll();
+}
+
+TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
+    : shaderType(type),
+      shaderSpec(spec),
+      maxUniformVectors(0),
+      maxVaryingVectors(0),
+      maxExpressionComplexity(0),
+      maxCallStackDepth(0),
+      fragmentPrecisionHigh(false),
+      clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
+      builtInFunctionEmulator(type)
+{
+    longNameMap = LongNameMap::GetInstance();
+}
+
+TCompiler::~TCompiler()
+{
+    ASSERT(longNameMap);
+    longNameMap-&gt;Release();
+}
+
+bool TCompiler::Init(const ShBuiltInResources&amp; resources)
+{
+    maxUniformVectors = (shaderType == SH_VERTEX_SHADER) ?
+        resources.MaxVertexUniformVectors :
+        resources.MaxFragmentUniformVectors;
+    maxVaryingVectors = resources.MaxVaryingVectors;
+    maxExpressionComplexity = resources.MaxExpressionComplexity;
+    maxCallStackDepth = resources.MaxCallStackDepth;
+
+    SetGlobalPoolAllocator(&amp;allocator);
+
+    // Generate built-in symbol table.
+    if (!InitBuiltInSymbolTable(resources))
+        return false;
+    InitExtensionBehavior(resources, extensionBehavior);
+    fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
+
+    arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
+    clampingStrategy = resources.ArrayIndexClampingStrategy;
+
+    hashFunction = resources.HashFunction;
+
+    return true;
+}
+
+bool TCompiler::compile(const char* const shaderStrings[],
+                        size_t numStrings,
+                        int compileOptions)
+{
+    TScopedPoolAllocator scopedAlloc(&amp;allocator);
+    clearResults();
+
+    if (numStrings == 0)
+        return true;
+
+    // If compiling for WebGL, validate loop and indexing as well.
+    if (isWebGLBasedSpec(shaderSpec))
+        compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+
+    // First string is path of source file if flag is set. The actual source follows.
+    const char* sourcePath = NULL;
+    size_t firstSource = 0;
+    if (compileOptions &amp; SH_SOURCE_PATH)
+    {
+        sourcePath = shaderStrings[0];
+        ++firstSource;
+    }
+
+    TIntermediate intermediate(infoSink);
+    TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
+                               shaderType, shaderSpec, compileOptions, true,
+                               sourcePath, infoSink);
+    parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
+    SetGlobalParseContext(&amp;parseContext);
+
+    // We preserve symbols at the built-in level from compile-to-compile.
+    // Start pushing the user-defined symbols at global level.
+    TScopedSymbolTableLevel scopedSymbolLevel(&amp;symbolTable);
+
+    // Parse shader.
+    bool success =
+        (PaParseStrings(numStrings - firstSource, &amp;shaderStrings[firstSource], NULL, &amp;parseContext) == 0) &amp;&amp;
+        (parseContext.treeRoot != NULL);
+    if (success)
+    {
+        TIntermNode* root = parseContext.treeRoot;
+        success = intermediate.postProcess(root);
+
+        if (success)
+            success = detectCallDepth(root, infoSink, (compileOptions &amp; SH_LIMIT_CALL_STACK_DEPTH) != 0);
+
+        if (success &amp;&amp; (compileOptions &amp; SH_VALIDATE_LOOP_INDEXING))
+            success = validateLimitations(root);
+
+        if (success &amp;&amp; (compileOptions &amp; SH_TIMING_RESTRICTIONS))
+            success = enforceTimingRestrictions(root, (compileOptions &amp; SH_DEPENDENCY_GRAPH) != 0);
+
+        if (success &amp;&amp; shaderSpec == SH_CSS_SHADERS_SPEC)
+            rewriteCSSShader(root);
+
+        // Unroll for-loop markup needs to happen after validateLimitations pass.
+        if (success &amp;&amp; (compileOptions &amp; SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
+            ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
+
+        // Built-in function emulation needs to happen after validateLimitations pass.
+        if (success &amp;&amp; (compileOptions &amp; SH_EMULATE_BUILT_IN_FUNCTIONS))
+            builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
+
+        // Clamping uniform array bounds needs to happen after validateLimitations pass.
+        if (success &amp;&amp; (compileOptions &amp; SH_CLAMP_INDIRECT_ARRAY_BOUNDS))
+            arrayBoundsClamper.MarkIndirectArrayBoundsForClamping(root);
+
+        // Disallow expressions deemed too complex.
+        if (success &amp;&amp; (compileOptions &amp; SH_LIMIT_EXPRESSION_COMPLEXITY))
+            success = limitExpressionComplexity(root);
+
+        // Call mapLongVariableNames() before collectAttribsUniforms() so in
+        // collectAttribsUniforms() we already have the mapped symbol names and
+        // we could composite mapped and original variable names.
+        // Also, if we hash all the names, then no need to do this for long names.
+        if (success &amp;&amp; (compileOptions &amp; SH_MAP_LONG_VARIABLE_NAMES) &amp;&amp; hashFunction == NULL)
+            mapLongVariableNames(root);
+
+        if (success &amp;&amp; shaderType == SH_VERTEX_SHADER &amp;&amp; (compileOptions &amp; SH_INIT_GL_POSITION))
+            initializeGLPosition(root);
+
+        if (success &amp;&amp; (compileOptions &amp; SH_UNFOLD_SHORT_CIRCUIT))
+        {
+            UnfoldShortCircuitAST unfoldShortCircuit;
+            root-&gt;traverse(&amp;unfoldShortCircuit);
+            unfoldShortCircuit.updateTree();
+        }
+
+        if (success &amp;&amp; (compileOptions &amp; SH_VARIABLES))
+        {
+            collectVariables(root);
+            if (compileOptions &amp; SH_ENFORCE_PACKING_RESTRICTIONS)
+                success = enforcePackingRestrictions();
+
+            if (success &amp;&amp; shaderType == SH_VERTEX_SHADER &amp;&amp;
+                (compileOptions &amp; SH_INIT_VARYINGS_WITHOUT_STATIC_USE))
+                initializeVaryingsWithoutStaticUse(root);
+        }
+
+        if (success &amp;&amp; (compileOptions &amp; SH_INTERMEDIATE_TREE))
+            intermediate.outputTree(root);
+
+        if (success &amp;&amp; (compileOptions &amp; SH_OBJECT_CODE))
+            translate(root);
+    }
+
+    // Cleanup memory.
+    intermediate.remove(parseContext.treeRoot);
+
+    return success;
+}
+
+bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &amp;resources)
+{
+    compileResources = resources;
+
+    assert(symbolTable.isEmpty());
+    symbolTable.push();
+
+    TPublicType integer;
+    integer.type = EbtInt;
+    integer.size = 1;
+    integer.matrix = false;
+    integer.array = false;
+
+    TPublicType floatingPoint;
+    floatingPoint.type = EbtFloat;
+    floatingPoint.size = 1;
+    floatingPoint.matrix = false;
+    floatingPoint.array = false;
+
+    TPublicType sampler;
+    sampler.size = 1;
+    sampler.matrix = false;
+    sampler.array = false;
+
+    switch(shaderType)
+    {
+      case SH_FRAGMENT_SHADER:
+        symbolTable.setDefaultPrecision(integer, EbpMedium);
+        break;
+      case SH_VERTEX_SHADER:
+        symbolTable.setDefaultPrecision(integer, EbpHigh);
+        symbolTable.setDefaultPrecision(floatingPoint, EbpHigh);
+        break;
+      default:
+        assert(false &amp;&amp; &quot;Language not supported&quot;);
+    }
+    // We set defaults for all the sampler types, even those that are
+    // only available if an extension exists.
+    for (int samplerType = EbtGuardSamplerBegin + 1;
+         samplerType &lt; EbtGuardSamplerEnd; ++samplerType)
+    {
+        sampler.type = static_cast&lt;TBasicType&gt;(samplerType);
+        symbolTable.setDefaultPrecision(sampler, EbpLow);
+    }
+
+    InsertBuiltInFunctions(shaderType, shaderSpec, resources, symbolTable);
+
+    IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable);
+
+    return true;
+}
+
+void TCompiler::clearResults()
+{
+    arrayBoundsClamper.Cleanup();
+    infoSink.info.erase();
+    infoSink.obj.erase();
+    infoSink.debug.erase();
+
+    attribs.clear();
+    uniforms.clear();
+    varyings.clear();
+
+    builtInFunctionEmulator.Cleanup();
+
+    nameMap.clear();
+}
+
+bool TCompiler::detectCallDepth(TIntermNode* root, TInfoSink&amp; infoSink, bool limitCallStackDepth)
+{
+    DetectCallDepth detect(infoSink, limitCallStackDepth, maxCallStackDepth);
+    root-&gt;traverse(&amp;detect);
+    switch (detect.detectCallDepth())
+    {
+      case DetectCallDepth::kErrorNone:
+        return true;
+      case DetectCallDepth::kErrorMissingMain:
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info &lt;&lt; &quot;Missing main()&quot;;
+        return false;
+      case DetectCallDepth::kErrorRecursion:
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info &lt;&lt; &quot;Function recursion detected&quot;;
+        return false;
+      case DetectCallDepth::kErrorMaxDepthExceeded:
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info &lt;&lt; &quot;Function call stack too deep&quot;;
+        return false;
+      default:
+        UNREACHABLE();
+        return false;
+    }
+}
+
+void TCompiler::rewriteCSSShader(TIntermNode* root)
+{
+    RenameFunction renamer(&quot;main(&quot;, &quot;css_main(&quot;);
+    root-&gt;traverse(&amp;renamer);
+}
+
+bool TCompiler::validateLimitations(TIntermNode* root)
+{
+    ValidateLimitations validate(shaderType, infoSink.info);
+    root-&gt;traverse(&amp;validate);
+    return validate.numErrors() == 0;
+}
+
+bool TCompiler::enforceTimingRestrictions(TIntermNode* root, bool outputGraph)
+{
+    if (shaderSpec != SH_WEBGL_SPEC)
+    {
+        infoSink.info &lt;&lt; &quot;Timing restrictions must be enforced under the WebGL spec.&quot;;
+        return false;
+    }
+
+    if (shaderType == SH_FRAGMENT_SHADER)
+    {
+        TDependencyGraph graph(root);
+
+        // Output any errors first.
+        bool success = enforceFragmentShaderTimingRestrictions(graph);
+        
+        // Then, output the dependency graph.
+        if (outputGraph)
+        {
+            TDependencyGraphOutput output(infoSink.info);
+            output.outputAllSpanningTrees(graph);
+        }
+        
+        return success;
+    }
+    else
+    {
+        return enforceVertexShaderTimingRestrictions(root);
+    }
+}
+
+bool TCompiler::limitExpressionComplexity(TIntermNode* root)
+{
+    TIntermTraverser traverser;
+    root-&gt;traverse(&amp;traverser);
+    TDependencyGraph graph(root);
+
+    for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
+         iter != graph.endUserDefinedFunctionCalls();
+         ++iter)
+    {
+        TGraphFunctionCall* samplerSymbol = *iter;
+        TDependencyGraphTraverser graphTraverser;
+        samplerSymbol-&gt;traverse(&amp;graphTraverser);
+    }
+
+    if (traverser.getMaxDepth() &gt; maxExpressionComplexity)
+    {
+        infoSink.info &lt;&lt; &quot;Expression too complex.&quot;;
+        return false;
+    }
+    return true;
+}
+
+bool TCompiler::enforceFragmentShaderTimingRestrictions(const TDependencyGraph&amp; graph)
+{
+    RestrictFragmentShaderTiming restrictor(infoSink.info);
+    restrictor.enforceRestrictions(graph);
+    return restrictor.numErrors() == 0;
+}
+
+bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
+{
+    RestrictVertexShaderTiming restrictor(infoSink.info);
+    restrictor.enforceRestrictions(root);
+    return restrictor.numErrors() == 0;
+}
+
+void TCompiler::collectVariables(TIntermNode* root)
+{
+    CollectVariables collect(attribs, uniforms, varyings, hashFunction);
+    root-&gt;traverse(&amp;collect);
+}
+
+bool TCompiler::enforcePackingRestrictions()
+{
+    VariablePacker packer;
+    bool success = packer.CheckVariablesWithinPackingLimits(maxUniformVectors, uniforms);
+    if (!success) {
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info &lt;&lt; &quot;too many uniforms&quot;;
+        return false;
+    }
+
+    success = packer.CheckVariablesWithinPackingLimits(maxVaryingVectors, varyings);
+
+    if (!success) {
+        infoSink.info.prefix(EPrefixError);
+        infoSink.info &lt;&lt; &quot;too many varyings&quot;;
+        return false;
+    }
+
+    return true;
+}
+
+void TCompiler::initializeGLPosition(TIntermNode* root)
+{
+    InitializeVariables::InitVariableInfoList variables;
+    InitializeVariables::InitVariableInfo var(
+        &quot;gl_Position&quot;, TType(EbtFloat, EbpUndefined, EvqPosition, 4));
+    variables.push_back(var);
+    InitializeVariables initializer(variables);
+    root-&gt;traverse(&amp;initializer);
+}
+
+void TCompiler::initializeVaryingsWithoutStaticUse(TIntermNode* root)
+{
+    InitializeVariables::InitVariableInfoList variables;
+    for (size_t ii = 0; ii &lt; varyings.size(); ++ii)
+    {
+        const TVariableInfo&amp; varying = varyings[ii];
+        if (varying.staticUse)
+            continue;
+        unsigned char size = 0;
+        bool matrix = false;
+        switch (varying.type)
+        {
+          case SH_FLOAT:
+            size = 1;
+            break;
+          case SH_FLOAT_VEC2:
+            size = 2;
+            break;
+          case SH_FLOAT_VEC3:
+            size = 3;
+            break;
+          case SH_FLOAT_VEC4:
+            size = 4;
+            break;
+          case SH_FLOAT_MAT2:
+            size = 2;
+            matrix = true;
+            break;
+          case SH_FLOAT_MAT3:
+            size = 3;
+            matrix = true;
+            break;
+          case SH_FLOAT_MAT4:
+            size = 4;
+            matrix = true;
+            break;
+          default:
+            ASSERT(false);
+        }
+        TType type(EbtFloat, EbpUndefined, EvqVaryingOut, size, matrix, varying.isArray);
+        TString name = varying.name.c_str();
+        if (varying.isArray)
+        {
+            type.setArraySize(varying.size);
+            name = name.substr(0, name.find_first_of('['));
+        }
+
+        InitializeVariables::InitVariableInfo var(name, type);
+        variables.push_back(var);
+    }
+    InitializeVariables initializer(variables);
+    root-&gt;traverse(&amp;initializer);
+}
+
+void TCompiler::mapLongVariableNames(TIntermNode* root)
+{
+    ASSERT(longNameMap);
+    MapLongVariableNames map(longNameMap);
+    root-&gt;traverse(&amp;map);
+}
+
+int TCompiler::getMappedNameMaxLength() const
+{
+    return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
+}
+
+const TExtensionBehavior&amp; TCompiler::getExtensionBehavior() const
+{
+    return extensionBehavior;
+}
+
+const ShBuiltInResources&amp; TCompiler::getResources() const
+{
+    return compileResources;
+}
+
+const ArrayBoundsClamper&amp; TCompiler::getArrayBoundsClamper() const
+{
+    return arrayBoundsClamper;
+}
+
+ShArrayIndexClampingStrategy TCompiler::getArrayIndexClampingStrategy() const
+{
+    return clampingStrategy;
+}
+
+const BuiltInFunctionEmulator&amp; TCompiler::getBuiltInFunctionEmulator() const
+{
+    return builtInFunctionEmulator;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Compiler.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorConstantUnionh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ConstantUnion.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ConstantUnion.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ConstantUnion.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,257 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _CONSTANT_UNION_INCLUDED_
+#define _CONSTANT_UNION_INCLUDED_
+
+#include &lt;assert.h&gt;
+
+class ConstantUnion {
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    ConstantUnion()
+    {
+        iConst = 0;
+        type = EbtVoid;
+    }
+
+    void setIConst(int i) {iConst = i; type = EbtInt; }
+    void setFConst(float f) {fConst = f; type = EbtFloat; }
+    void setBConst(bool b) {bConst = b; type = EbtBool; }
+
+    int getIConst() { return iConst; }
+    float getFConst() { return fConst; }
+    bool getBConst() { return bConst; }
+    int getIConst() const { return iConst; }
+    float getFConst() const { return fConst; }
+    bool getBConst() const { return bConst; }
+
+    bool operator==(const int i) const
+    {
+        return i == iConst;
+    }
+
+    bool operator==(const float f) const
+    {
+        return f == fConst;
+    }
+
+    bool operator==(const bool b) const
+    {
+        return b == bConst;
+    }
+
+    bool operator==(const ConstantUnion&amp; constant) const
+    {
+        if (constant.type != type)
+            return false;
+
+        switch (type) {
+        case EbtInt:
+            return constant.iConst == iConst;
+        case EbtFloat:
+            return constant.fConst == fConst;
+        case EbtBool:
+            return constant.bConst == bConst;
+        default:
+            return false;
+        }
+    }
+
+    bool operator!=(const int i) const
+    {
+        return !operator==(i);
+    }
+
+    bool operator!=(const float f) const
+    {
+        return !operator==(f);
+    }
+
+    bool operator!=(const bool b) const
+    {
+        return !operator==(b);
+    }
+
+    bool operator!=(const ConstantUnion&amp; constant) const
+    {
+        return !operator==(constant);
+    }
+
+    bool operator&gt;(const ConstantUnion&amp; constant) const
+    { 
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:
+            return iConst &gt; constant.iConst;
+        case EbtFloat:
+            return fConst &gt; constant.fConst;
+        default:
+            return false;   // Invalid operation, handled at semantic analysis
+        }
+    }
+
+    bool operator&lt;(const ConstantUnion&amp; constant) const
+    { 
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:
+            return iConst &lt; constant.iConst;
+        case EbtFloat:
+            return fConst &lt; constant.fConst;
+        default:
+            return false;   // Invalid operation, handled at semantic analysis
+        }
+    }
+
+    ConstantUnion operator+(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break;
+        default: assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator-(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break;
+        default: assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator*(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
+        case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; 
+        default: assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator%(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator&gt;&gt;(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst &gt;&gt; constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator&lt;&lt;(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt: returnValue.setIConst(iConst &lt;&lt; constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator&amp;(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst &amp; constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator|(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst | constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator^(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtInt:  returnValue.setIConst(iConst ^ constant.iConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator&amp;&amp;(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtBool: returnValue.setBConst(bConst &amp;&amp; constant.bConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    ConstantUnion operator||(const ConstantUnion&amp; constant) const
+    { 
+        ConstantUnion returnValue;
+        assert(type == constant.type);
+        switch (type) {
+        case EbtBool: returnValue.setBConst(bConst || constant.bConst); break;
+        default:     assert(false &amp;&amp; &quot;Default missing&quot;);
+        }
+
+        return returnValue;
+    }
+
+    TBasicType getType() const { return type; }
+private:
+
+    union  {
+        int iConst;  // used for ivec, scalar ints
+        bool bConst; // used for bvec, scalar bools
+        float fConst;   // used for vec, mat, scalar floats
+    } ;
+
+    TBasicType type;
+};
+
+#endif // _CONSTANT_UNION_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ConstantUnion.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDetectCallDepthcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,185 @@
</span><ins>+//
+// 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 &quot;compiler/translator/DetectCallDepth.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+
+DetectCallDepth::FunctionNode::FunctionNode(const TString&amp; fname)
+    : name(fname),
+      visit(PreVisit)
+{
+}
+
+const TString&amp; DetectCallDepth::FunctionNode::getName() const
+{
+    return name;
+}
+
+void DetectCallDepth::FunctionNode::addCallee(
+    DetectCallDepth::FunctionNode* callee)
+{
+    for (size_t i = 0; i &lt; callees.size(); ++i) {
+        if (callees[i] == callee)
+            return;
+    }
+    callees.push_back(callee);
+}
+
+int DetectCallDepth::FunctionNode::detectCallDepth(DetectCallDepth* detectCallDepth, int depth)
+{
+    ASSERT(visit == PreVisit);
+    ASSERT(detectCallDepth);
+
+    int maxDepth = depth;
+    visit = InVisit;
+    for (size_t i = 0; i &lt; callees.size(); ++i) {
+        switch (callees[i]-&gt;visit) {
+            case InVisit:
+                // cycle detected, i.e., recursion detected.
+                return kInfiniteCallDepth;
+            case PostVisit:
+                break;
+            case PreVisit: {
+                // Check before we recurse so we don't go too depth
+                if (detectCallDepth-&gt;checkExceedsMaxDepth(depth))
+                    return depth;
+                int callDepth = callees[i]-&gt;detectCallDepth(detectCallDepth, depth + 1);
+                // Check after we recurse so we can exit immediately and provide info.
+                if (detectCallDepth-&gt;checkExceedsMaxDepth(callDepth)) {
+                    detectCallDepth-&gt;getInfoSink().info &lt;&lt; &quot;&lt;-&quot; &lt;&lt; callees[i]-&gt;getName();
+                    return callDepth;
+                }
+                maxDepth = std::max(callDepth, maxDepth);
+                break;
+            }
+            default:
+                UNREACHABLE();
+                break;
+        }
+    }
+    visit = PostVisit;
+    return maxDepth;
+}
+
+void DetectCallDepth::FunctionNode::reset()
+{
+    visit = PreVisit;
+}
+
+DetectCallDepth::DetectCallDepth(TInfoSink&amp; infoSink, bool limitCallStackDepth, int maxCallStackDepth)
+    : TIntermTraverser(true, false, true, false),
+      currentFunction(NULL),
+      infoSink(infoSink),
+      maxDepth(limitCallStackDepth ? maxCallStackDepth : FunctionNode::kInfiniteCallDepth)
+{
+}
+
+DetectCallDepth::~DetectCallDepth()
+{
+    for (size_t i = 0; i &lt; functions.size(); ++i)
+        delete functions[i];
+}
+
+bool DetectCallDepth::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    switch (node-&gt;getOp())
+    {
+        case EOpPrototype:
+            // Function declaration.
+            // Don't add FunctionNode here because node-&gt;getName() is the
+            // unmangled function name.
+            break;
+        case EOpFunction: {
+            // Function definition.
+            if (visit == PreVisit) {
+                currentFunction = findFunctionByName(node-&gt;getName());
+                if (currentFunction == NULL) {
+                    currentFunction = new FunctionNode(node-&gt;getName());
+                    functions.push_back(currentFunction);
+                }
+            } else if (visit == PostVisit) {
+                currentFunction = NULL;
+            }
+            break;
+        }
+        case EOpFunctionCall: {
+            // Function call.
+            if (visit == PreVisit) {
+                FunctionNode* func = findFunctionByName(node-&gt;getName());
+                if (func == NULL) {
+                    func = new FunctionNode(node-&gt;getName());
+                    functions.push_back(func);
+                }
+                if (currentFunction)
+                    currentFunction-&gt;addCallee(func);
+            }
+            break;
+        }
+        default:
+            break;
+    }
+    return true;
+}
+
+bool DetectCallDepth::checkExceedsMaxDepth(int depth)
+{
+    return depth &gt;= maxDepth;
+}
+
+void DetectCallDepth::resetFunctionNodes()
+{
+    for (size_t i = 0; i &lt; functions.size(); ++i) {
+        functions[i]-&gt;reset();
+    }
+}
+
+DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepthForFunction(FunctionNode* func)
+{
+    currentFunction = NULL;
+    resetFunctionNodes();
+
+    int maxCallDepth = func-&gt;detectCallDepth(this, 1);
+
+    if (maxCallDepth == FunctionNode::kInfiniteCallDepth)
+        return kErrorRecursion;
+
+    if (maxCallDepth &gt;= maxDepth)
+        return kErrorMaxDepthExceeded;
+
+    return kErrorNone;
+}
+
+DetectCallDepth::ErrorCode DetectCallDepth::detectCallDepth()
+{
+    if (maxDepth != FunctionNode::kInfiniteCallDepth) {
+        // Check all functions because the driver may fail on them
+        // TODO: Before detectingRecursion, strip unused functions.
+        for (size_t i = 0; i &lt; functions.size(); ++i) {
+            ErrorCode error = detectCallDepthForFunction(functions[i]);
+            if (error != kErrorNone)
+                return error;
+        }
+    } else {
+        FunctionNode* main = findFunctionByName(&quot;main(&quot;);
+        if (main == NULL)
+            return kErrorMissingMain;
+
+        return detectCallDepthForFunction(main);
+    }
+
+    return kErrorNone;
+}
+
+DetectCallDepth::FunctionNode* DetectCallDepth::findFunctionByName(
+    const TString&amp; name)
+{
+    for (size_t i = 0; i &lt; functions.size(); ++i) {
+        if (functions[i]-&gt;getName() == name)
+            return functions[i];
+    }
+    return NULL;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDetectCallDepthh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+//
+// 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 &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &lt;limits.h&gt;
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/VariableInfo.h&quot;
+
+class TInfoSink;
+
+// Traverses intermediate tree to detect function recursion.
+class DetectCallDepth : public TIntermTraverser {
+public:
+    enum ErrorCode {
+        kErrorMissingMain,
+        kErrorRecursion,
+        kErrorMaxDepthExceeded,
+        kErrorNone
+    };
+
+    DetectCallDepth(TInfoSink&amp; infoSync, bool limitCallStackDepth, int maxCallStackDepth);
+    ~DetectCallDepth();
+
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+
+    bool checkExceedsMaxDepth(int depth);
+
+    ErrorCode detectCallDepth();
+
+private:
+    class FunctionNode {
+    public:
+        static const int kInfiniteCallDepth = INT_MAX;
+
+        FunctionNode(const TString&amp; fname);
+
+        const TString&amp; getName() const;
+
+        // If a function is already in the callee list, this becomes a no-op.
+        void addCallee(FunctionNode* callee);
+
+        // Returns kInifinityCallDepth if recursive function calls are detected.
+        int detectCallDepth(DetectCallDepth* detectCallDepth, int depth);
+
+        // Reset state.
+        void reset();
+
+    private:
+        // mangled function name is unique.
+        TString name;
+
+        // functions that are directly called by this function.
+        TVector&lt;FunctionNode*&gt; callees;
+
+        Visit visit;
+    };
+
+    ErrorCode detectCallDepthForFunction(FunctionNode* func);
+    FunctionNode* findFunctionByName(const TString&amp; name);
+    void resetFunctionNodes();
+
+    TInfoSink&amp; getInfoSink() { return infoSink; }
+
+    TVector&lt;FunctionNode*&gt; functions;
+    FunctionNode* currentFunction;
+    TInfoSink&amp; infoSink;
+    int maxDepth;
+
+    DetectCallDepth(const DetectCallDepth&amp;);
+    void operator=(const DetectCallDepth&amp;);
+};
+
+#endif  // COMPILER_DETECT_RECURSION_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectCallDepth.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDetectDiscontinuitycpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,139 @@
</span><ins>+//
+// 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.
+//
+// Contains analysis utilities for dealing with HLSL's lack of support for
+// the use of intrinsic functions which (implicitly or explicitly) compute
+// gradients of functions with discontinuities. 
+//
+
+#include &quot;compiler/translator/DetectDiscontinuity.h&quot;
+
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+namespace sh
+{
+bool DetectLoopDiscontinuity::traverse(TIntermNode *node)
+{
+    mLoopDepth = 0;
+    mLoopDiscontinuity = false;
+    node-&gt;traverse(this);
+    return mLoopDiscontinuity;
+}
+
+bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop)
+{
+    if (visit == PreVisit)
+    {
+        ++mLoopDepth;
+    }
+    else if (visit == PostVisit)
+    {
+        --mLoopDepth;
+    }
+
+    return true;
+}
+
+bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node)
+{
+    if (mLoopDiscontinuity)
+    {
+        return false;
+    }
+
+    if (!mLoopDepth)
+    {
+        return true;
+    }
+
+    switch (node-&gt;getFlowOp())
+    {
+      case EOpKill:
+        break;
+      case EOpBreak:
+      case EOpContinue:
+      case EOpReturn:
+        mLoopDiscontinuity = true;
+        break;
+      default: UNREACHABLE();
+    }
+
+    return !mLoopDiscontinuity;
+}
+
+bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    return !mLoopDiscontinuity;
+}
+
+bool containsLoopDiscontinuity(TIntermNode *node)
+{
+    DetectLoopDiscontinuity detectLoopDiscontinuity;
+    return detectLoopDiscontinuity.traverse(node);
+}
+
+bool DetectGradientOperation::traverse(TIntermNode *node)
+{
+    mGradientOperation = false;
+    node-&gt;traverse(this);
+    return mGradientOperation;
+}
+
+bool DetectGradientOperation::visitUnary(Visit visit, TIntermUnary *node)
+{
+    if (mGradientOperation)
+    {
+        return false;
+    }
+
+    switch (node-&gt;getOp())
+    {
+      case EOpDFdx:
+      case EOpDFdy:
+        mGradientOperation = true;
+      default:
+        break;
+    }
+
+    return !mGradientOperation;
+}
+
+bool DetectGradientOperation::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    if (mGradientOperation)
+    {
+        return false;
+    }
+
+    if (node-&gt;getOp() == EOpFunctionCall)
+    {
+        if (!node-&gt;isUserDefined())
+        {
+            TString name = TFunction::unmangleName(node-&gt;getName());
+
+            if (name == &quot;texture2D&quot; ||
+                name == &quot;texture2DProj&quot; ||
+                name == &quot;textureCube&quot;)
+            {
+                mGradientOperation = true;
+            }
+        }
+        else
+        {
+            // When a user defined function is called, we have to
+            // conservatively assume it to contain gradient operations
+            mGradientOperation = true;
+        }
+    }
+
+    return !mGradientOperation;
+}
+
+bool containsGradientOperation(TIntermNode *node)
+{
+    DetectGradientOperation detectGradientOperation;
+    return detectGradientOperation.traverse(node);
+}
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDetectDiscontinuityh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+//
+// 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.
+//
+// Contains analysis utilities for dealing with HLSL's lack of support for
+// the use of intrinsic functions which (implicitly or explicitly) compute
+// gradients of functions with discontinuities. 
+//
+
+#ifndef COMPILER_DETECTDISCONTINUITY_H_
+#define COMPILER_DETECTDISCONTINUITY_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+namespace sh
+{
+// Checks whether a loop can run for a variable number of iterations
+class DetectLoopDiscontinuity : public TIntermTraverser
+{
+  public:
+    bool traverse(TIntermNode *node);
+
+  protected:
+    bool visitBranch(Visit visit, TIntermBranch *node);
+    bool visitLoop(Visit visit, TIntermLoop *loop);
+    bool visitAggregate(Visit visit, TIntermAggregate *node);
+
+    int mLoopDepth;
+    bool mLoopDiscontinuity;
+};
+
+bool containsLoopDiscontinuity(TIntermNode *node);
+
+// Checks for intrinsic functions which compute gradients
+class DetectGradientOperation : public TIntermTraverser
+{
+  public:
+    bool traverse(TIntermNode *node);
+
+  protected:
+    bool visitUnary(Visit visit, TIntermUnary *node);
+    bool visitAggregate(Visit visit, TIntermAggregate *node);
+
+    bool mGradientOperation;
+};
+
+bool containsGradientOperation(TIntermNode *node);
+
+}
+
+#endif   // COMPILER_DETECTDISCONTINUITY_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DetectDiscontinuity.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDiagnosticscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,63 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/Diagnostics.h&quot;
+
+#include &quot;compiler/translator/compilerdebug.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/preprocessor/SourceLocation.h&quot;
+
+TDiagnostics::TDiagnostics(TInfoSink&amp; infoSink) :
+    mInfoSink(infoSink),
+    mNumErrors(0),
+    mNumWarnings(0)
+{
+}
+
+TDiagnostics::~TDiagnostics()
+{
+}
+
+void TDiagnostics::writeInfo(Severity severity,
+                             const pp::SourceLocation&amp; loc,
+                             const std::string&amp; reason,
+                             const std::string&amp; token,
+                             const std::string&amp; extra)
+{
+    TPrefixType prefix = EPrefixNone;
+    switch (severity)
+    {
+      case PP_ERROR:
+        ++mNumErrors;
+        prefix = EPrefixError;
+        break;
+      case PP_WARNING:
+        ++mNumWarnings;
+        prefix = EPrefixWarning;
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+
+    TInfoSinkBase&amp; sink = mInfoSink.info;
+    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
+    sink.prefix(prefix);
+    sink.location(loc.file, loc.line);
+    sink &lt;&lt; &quot;'&quot; &lt;&lt; token &lt;&lt;  &quot;' : &quot; &lt;&lt; reason &lt;&lt; &quot; &quot; &lt;&lt; extra &lt;&lt; &quot;\n&quot;;
+}
+
+void TDiagnostics::writeDebug(const std::string&amp; str)
+{
+    mInfoSink.debug &lt;&lt; str;
+}
+
+void TDiagnostics::print(ID id,
+                         const pp::SourceLocation&amp; loc,
+                         const std::string&amp; text)
+{
+    writeInfo(severity(id), loc, message(id), text, &quot;&quot;);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDiagnosticsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_DIAGNOSTICS_H_
+#define COMPILER_DIAGNOSTICS_H_
+
+#include &quot;compiler/preprocessor/DiagnosticsBase.h&quot;
+
+class TInfoSink;
+
+class TDiagnostics : public pp::Diagnostics
+{
+  public:
+    TDiagnostics(TInfoSink&amp; infoSink);
+    virtual ~TDiagnostics();
+
+    TInfoSink&amp; infoSink() { return mInfoSink; }
+
+    int numErrors() const { return mNumErrors; }
+    int numWarnings() const { return mNumWarnings; }
+
+    void writeInfo(Severity severity,
+                   const pp::SourceLocation&amp; loc,
+                   const std::string&amp; reason,
+                   const std::string&amp; token,
+                   const std::string&amp; extra);
+
+    void writeDebug(const std::string&amp; str);
+
+  protected:
+    virtual void print(ID id,
+                       const pp::SourceLocation&amp; loc,
+                       const std::string&amp; text);
+
+  private:
+    TInfoSink&amp; mInfoSink;
+    int mNumErrors;
+    int mNumWarnings;
+};
+
+#endif  // COMPILER_DIAGNOSTICS_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Diagnostics.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDirectiveHandlercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,161 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/DirectiveHandler.h&quot;
+
+#include &lt;sstream&gt;
+
+#include &quot;compiler/translator/compilerdebug.h&quot;
+#include &quot;compiler/translator/Diagnostics.h&quot;
+
+static TBehavior getBehavior(const std::string&amp; str)
+{
+    static const std::string kRequire(&quot;require&quot;);
+    static const std::string kEnable(&quot;enable&quot;);
+    static const std::string kDisable(&quot;disable&quot;);
+    static const std::string kWarn(&quot;warn&quot;);
+
+    if (str == kRequire) return EBhRequire;
+    else if (str == kEnable) return EBhEnable;
+    else if (str == kDisable) return EBhDisable;
+    else if (str == kWarn) return EBhWarn;
+    return EBhUndefined;
+}
+
+TDirectiveHandler::TDirectiveHandler(TExtensionBehavior&amp; extBehavior,
+                                     TDiagnostics&amp; diagnostics)
+    : mExtensionBehavior(extBehavior),
+      mDiagnostics(diagnostics)
+{
+}
+
+TDirectiveHandler::~TDirectiveHandler()
+{
+}
+
+void TDirectiveHandler::handleError(const pp::SourceLocation&amp; loc,
+                                    const std::string&amp; msg)
+{
+    mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, &quot;&quot;, &quot;&quot;);
+}
+
+void TDirectiveHandler::handlePragma(const pp::SourceLocation&amp; loc,
+                                     const std::string&amp; name,
+                                     const std::string&amp; value)
+{
+    static const std::string kSTDGL(&quot;STDGL&quot;);
+    static const std::string kOptimize(&quot;optimize&quot;);
+    static const std::string kDebug(&quot;debug&quot;);
+    static const std::string kOn(&quot;on&quot;);
+    static const std::string kOff(&quot;off&quot;);
+
+    bool invalidValue = false;
+    if (name == kSTDGL)
+    {
+        // The STDGL pragma is used to reserve pragmas for use by future
+        // revisions of GLSL. Ignore it.
+        return;
+    }
+    else if (name == kOptimize)
+    {
+        if (value == kOn) mPragma.optimize = true;
+        else if (value == kOff) mPragma.optimize = false;
+        else invalidValue = true;
+    }
+    else if (name == kDebug)
+    {
+        if (value == kOn) mPragma.debug = true;
+        else if (value == kOff) mPragma.debug = false;
+        else invalidValue = true;
+    }
+    else
+    {
+        mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
+        return;
+    }
+
+    if (invalidValue)
+      mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                             &quot;invalid pragma value&quot;, value,
+                             &quot;'on' or 'off' expected&quot;);
+}
+
+void TDirectiveHandler::handleExtension(const pp::SourceLocation&amp; loc,
+                                        const std::string&amp; name,
+                                        const std::string&amp; behavior)
+{
+    static const std::string kExtAll(&quot;all&quot;);
+
+    TBehavior behaviorVal = getBehavior(behavior);
+    if (behaviorVal == EBhUndefined)
+    {
+        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                               &quot;behavior&quot;, name, &quot;invalid&quot;);
+        return;
+    }
+
+    if (name == kExtAll)
+    {
+        if (behaviorVal == EBhRequire)
+        {
+            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                                   &quot;extension&quot;, name,
+                                   &quot;cannot have 'require' behavior&quot;);
+        }
+        else if (behaviorVal == EBhEnable)
+        {
+            mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                                   &quot;extension&quot;, name,
+                                   &quot;cannot have 'enable' behavior&quot;);
+        }
+        else
+        {
+            for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
+                 iter != mExtensionBehavior.end(); ++iter)
+                iter-&gt;second = behaviorVal;
+        }
+        return;
+    }
+
+    TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
+    if (iter != mExtensionBehavior.end())
+    {
+        iter-&gt;second = behaviorVal;
+        return;
+    }
+
+    pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
+    switch (behaviorVal) {
+      case EBhRequire:
+        severity = pp::Diagnostics::PP_ERROR;
+        break;
+      case EBhEnable:
+      case EBhWarn:
+      case EBhDisable:
+        severity = pp::Diagnostics::PP_WARNING;
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+    mDiagnostics.writeInfo(severity, loc,
+                           &quot;extension&quot;, name, &quot;is not supported&quot;);
+}
+
+void TDirectiveHandler::handleVersion(const pp::SourceLocation&amp; loc,
+                                      int version)
+{
+    static const int kVersion = 100;
+
+    if (version != kVersion)
+    {
+        std::stringstream stream;
+        stream &lt;&lt; version;
+        std::string str = stream.str();
+        mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
+                               &quot;version number&quot;, str, &quot;not supported&quot;);
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorDirectiveHandlerh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,46 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_DIRECTIVE_HANDLER_H_
+#define COMPILER_DIRECTIVE_HANDLER_H_
+
+#include &quot;compiler/translator/ExtensionBehavior.h&quot;
+#include &quot;compiler/translator/Pragma.h&quot;
+#include &quot;compiler/preprocessor/DirectiveHandlerBase.h&quot;
+
+class TDiagnostics;
+
+class TDirectiveHandler : public pp::DirectiveHandler
+{
+  public:
+    TDirectiveHandler(TExtensionBehavior&amp; extBehavior,
+                      TDiagnostics&amp; diagnostics);
+    virtual ~TDirectiveHandler();
+
+    const TPragma&amp; pragma() const { return mPragma; }
+    const TExtensionBehavior&amp; extensionBehavior() const { return mExtensionBehavior; }
+
+    virtual void handleError(const pp::SourceLocation&amp; loc,
+                             const std::string&amp; msg);
+
+    virtual void handlePragma(const pp::SourceLocation&amp; loc,
+                              const std::string&amp; name,
+                              const std::string&amp; value);
+
+    virtual void handleExtension(const pp::SourceLocation&amp; loc,
+                                 const std::string&amp; name,
+                                 const std::string&amp; behavior);
+
+    virtual void handleVersion(const pp::SourceLocation&amp; loc,
+                               int version);
+
+  private:
+    TPragma mPragma;
+    TExtensionBehavior&amp; mExtensionBehavior;
+    TDiagnostics&amp; mDiagnostics;
+};
+
+#endif  // COMPILER_DIRECTIVE_HANDLER_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/DirectiveHandler.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorExtensionBehaviorh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _EXTENSION_BEHAVIOR_INCLUDED_
+#define _EXTENSION_BEHAVIOR_INCLUDED_
+
+#include &lt;map&gt;
+#include &lt;string&gt;
+
+typedef enum
+{
+    EBhRequire,
+    EBhEnable,
+    EBhWarn,
+    EBhDisable,
+    EBhUndefined
+} TBehavior;
+
+inline const char* getBehaviorString(TBehavior b)
+{
+    switch(b)
+    {
+      case EBhRequire: return &quot;require&quot;;
+      case EBhEnable: return &quot;enable&quot;;
+      case EBhWarn: return &quot;warn&quot;;
+      case EBhDisable: return &quot;disable&quot;;
+      default: return NULL;
+    }
+}
+
+// Mapping between extension name and behavior.
+typedef std::map&lt;std::string, TBehavior&gt; TExtensionBehavior;
+
+#endif // _EXTENSION_TABLE_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ExtensionBehavior.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorForLoopUnrollcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,215 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/ForLoopUnroll.h&quot;
+
+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-&gt;getType() == ELoopFor);
+        ASSERT(node-&gt;getInit());
+        TIntermAggregate* decl = node-&gt;getInit()-&gt;getAsAggregate();
+        ASSERT(decl &amp;&amp; decl-&gt;getOp() == EOpDeclaration);
+        TIntermSequence&amp; declSeq = decl-&gt;getSequence();
+        ASSERT(declSeq.size() == 1);
+        TIntermBinary* declInit = declSeq[0]-&gt;getAsBinaryNode();
+        ASSERT(declInit &amp;&amp; declInit-&gt;getOp() == EOpInitialize);
+        ASSERT(declInit-&gt;getLeft());
+        TIntermSymbol* symbol = declInit-&gt;getLeft()-&gt;getAsSymbolNode();
+        ASSERT(symbol);
+        TBasicType type = symbol-&gt;getBasicType();
+        ASSERT(type == EbtInt || type == EbtFloat);
+        if (type == EbtInt)
+            node-&gt;setUnrollFlag(true);
+        return true;
+    }
+
+};
+
+}  // anonymous namepsace
+
+void ForLoopUnroll::FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo&amp; info)
+{
+    ASSERT(node-&gt;getType() == ELoopFor);
+    ASSERT(node-&gt;getUnrollFlag());
+
+    TIntermNode* init = node-&gt;getInit();
+    ASSERT(init != NULL);
+    TIntermAggregate* decl = init-&gt;getAsAggregate();
+    ASSERT((decl != NULL) &amp;&amp; (decl-&gt;getOp() == EOpDeclaration));
+    TIntermSequence&amp; declSeq = decl-&gt;getSequence();
+    ASSERT(declSeq.size() == 1);
+    TIntermBinary* declInit = declSeq[0]-&gt;getAsBinaryNode();
+    ASSERT((declInit != NULL) &amp;&amp; (declInit-&gt;getOp() == EOpInitialize));
+    TIntermSymbol* symbol = declInit-&gt;getLeft()-&gt;getAsSymbolNode();
+    ASSERT(symbol != NULL);
+    ASSERT(symbol-&gt;getBasicType() == EbtInt);
+
+    info.id = symbol-&gt;getId();
+
+    ASSERT(declInit-&gt;getRight() != NULL);
+    TIntermConstantUnion* initNode = declInit-&gt;getRight()-&gt;getAsConstantUnion();
+    ASSERT(initNode != NULL);
+
+    info.initValue = evaluateIntConstant(initNode);
+    info.currentValue = info.initValue;
+
+    TIntermNode* cond = node-&gt;getCondition();
+    ASSERT(cond != NULL);
+    TIntermBinary* binOp = cond-&gt;getAsBinaryNode();
+    ASSERT(binOp != NULL);
+    ASSERT(binOp-&gt;getRight() != NULL);
+    ASSERT(binOp-&gt;getRight()-&gt;getAsConstantUnion() != NULL);
+
+    info.incrementValue = getLoopIncrement(node);
+    info.stopValue = evaluateIntConstant(
+        binOp-&gt;getRight()-&gt;getAsConstantUnion());
+    info.op = binOp-&gt;getOp();
+}
+
+void ForLoopUnroll::Step()
+{
+    ASSERT(mLoopIndexStack.size() &gt; 0);
+    TLoopIndexInfo&amp; info = mLoopIndexStack[mLoopIndexStack.size() - 1];
+    info.currentValue += info.incrementValue;
+}
+
+bool ForLoopUnroll::SatisfiesLoopCondition()
+{
+    ASSERT(mLoopIndexStack.size() &gt; 0);
+    TLoopIndexInfo&amp; info = mLoopIndexStack[mLoopIndexStack.size() - 1];
+    // Relational operator is one of: &gt; &gt;= &lt; &lt;= == or !=.
+    switch (info.op) {
+      case EOpEqual:
+        return (info.currentValue == info.stopValue);
+      case EOpNotEqual:
+        return (info.currentValue != info.stopValue);
+      case EOpLessThan:
+        return (info.currentValue &lt; info.stopValue);
+      case EOpGreaterThan:
+        return (info.currentValue &gt; info.stopValue);
+      case EOpLessThanEqual:
+        return (info.currentValue &lt;= info.stopValue);
+      case EOpGreaterThanEqual:
+        return (info.currentValue &gt;= info.stopValue);
+      default:
+        UNREACHABLE();
+    }
+    return false;
+}
+
+bool ForLoopUnroll::NeedsToReplaceSymbolWithValue(TIntermSymbol* symbol)
+{
+    for (TVector&lt;TLoopIndexInfo&gt;::iterator i = mLoopIndexStack.begin();
+         i != mLoopIndexStack.end();
+         ++i) {
+        if (i-&gt;id == symbol-&gt;getId())
+            return true;
+    }
+    return false;
+}
+
+int ForLoopUnroll::GetLoopIndexValue(TIntermSymbol* symbol)
+{
+    for (TVector&lt;TLoopIndexInfo&gt;::iterator i = mLoopIndexStack.begin();
+         i != mLoopIndexStack.end();
+         ++i) {
+        if (i-&gt;id == symbol-&gt;getId())
+            return i-&gt;currentValue;
+    }
+    UNREACHABLE();
+    return false;
+}
+
+void ForLoopUnroll::Push(TLoopIndexInfo&amp; info)
+{
+    mLoopIndexStack.push_back(info);
+}
+
+void ForLoopUnroll::Pop()
+{
+    mLoopIndexStack.pop_back();
+}
+
+// static
+void ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(
+    TIntermNode* root)
+{
+    ASSERT(root);
+
+    IntegerForLoopUnrollMarker marker;
+    root-&gt;traverse(&amp;marker);
+}
+
+int ForLoopUnroll::getLoopIncrement(TIntermLoop* node)
+{
+    TIntermNode* expr = node-&gt;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-&gt;getAsUnaryNode();
+    TIntermBinary* binOp = unOp ? NULL : expr-&gt;getAsBinaryNode();
+
+    TOperator op = EOpNull;
+    TIntermConstantUnion* incrementNode = NULL;
+    if (unOp != NULL) {
+        op = unOp-&gt;getOp();
+    } else if (binOp != NULL) {
+        op = binOp-&gt;getOp();
+        ASSERT(binOp-&gt;getRight() != NULL);
+        incrementNode = binOp-&gt;getRight()-&gt;getAsConstantUnion();
+        ASSERT(incrementNode != NULL);
+    }
+
+    int increment = 0;
+    // The operator is one of: ++ -- += -=.
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPreIncrement:
+            ASSERT((unOp != NULL) &amp;&amp; (binOp == NULL));
+            increment = 1;
+            break;
+        case EOpPostDecrement:
+        case EOpPreDecrement:
+            ASSERT((unOp != NULL) &amp;&amp; (binOp == NULL));
+            increment = -1;
+            break;
+        case EOpAddAssign:
+            ASSERT((unOp == NULL) &amp;&amp; (binOp != NULL));
+            increment = evaluateIntConstant(incrementNode);
+            break;
+        case EOpSubAssign:
+            ASSERT((unOp == NULL) &amp;&amp; (binOp != NULL));
+            increment = - evaluateIntConstant(incrementNode);
+            break;
+        default:
+            ASSERT(false);
+    }
+
+    return increment;
+}
+
+int ForLoopUnroll::evaluateIntConstant(TIntermConstantUnion* node)
+{
+    ASSERT((node != NULL) &amp;&amp; (node-&gt;getUnionArrayPointer() != NULL));
+    return node-&gt;getIConst(0);
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorForLoopUnrollh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+//
+// 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_FORLOOPUNROLL_H_
+#define COMPILER_FORLOOPUNROLL_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+struct TLoopIndexInfo {
+    int id;
+    int initValue;
+    int stopValue;
+    int incrementValue;
+    TOperator op;
+    int currentValue;
+};
+
+class ForLoopUnroll {
+public:
+    ForLoopUnroll() { }
+
+    void FillLoopIndexInfo(TIntermLoop* node, TLoopIndexInfo&amp; 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&amp; info);
+    void Pop();
+
+    static void MarkForLoopsWithIntegerIndicesForUnrolling(TIntermNode* root);
+
+private:
+    int getLoopIncrement(TIntermLoop* node);
+
+    int evaluateIntConstant(TIntermConstantUnion* node);
+
+    TVector&lt;TLoopIndexInfo&gt; mLoopIndexStack;
+};
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ForLoopUnroll.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorHashNamesh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/HashNames.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/HashNames.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/HashNames.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_HASH_NAMES_H_
+#define COMPILER_HASH_NAMES_H_
+
+#include &lt;map&gt;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#define HASHED_NAME_PREFIX &quot;webgl_&quot;
+
+typedef std::map&lt;TPersistString, TPersistString&gt; NameMap;
+
+#endif  // COMPILER_HASH_NAMES_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/HashNames.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInfoSinkcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/InfoSink.h&quot;
+
+void TInfoSinkBase::prefix(TPrefixType p) {
+    switch(p) {
+        case EPrefixNone:
+            break;
+        case EPrefixWarning:
+            sink.append(&quot;WARNING: &quot;);
+            break;
+        case EPrefixError:
+            sink.append(&quot;ERROR: &quot;);
+            break;
+        case EPrefixInternalError:
+            sink.append(&quot;INTERNAL ERROR: &quot;);
+            break;
+        case EPrefixUnimplemented:
+            sink.append(&quot;UNIMPLEMENTED: &quot;);
+            break;
+        case EPrefixNote:
+            sink.append(&quot;NOTE: &quot;);
+            break;
+        default:
+            sink.append(&quot;UNKOWN ERROR: &quot;);
+            break;
+    }
+}
+
+void TInfoSinkBase::location(int file, int line) {
+    TPersistStringStream stream;
+    if (line)
+        stream &lt;&lt; file &lt;&lt; &quot;:&quot; &lt;&lt; line;
+    else
+        stream &lt;&lt; file &lt;&lt; &quot;:? &quot;;
+    stream &lt;&lt; &quot;: &quot;;
+
+    sink.append(stream.str());
+}
+
+void TInfoSinkBase::location(const TSourceLoc&amp; loc) {
+    location(loc.first_file, loc.first_line);
+}
+
+void TInfoSinkBase::message(TPrefixType p, const TSourceLoc&amp; loc, const char* m) {
+    prefix(p);
+    location(loc);
+    sink.append(m);
+    sink.append(&quot;\n&quot;);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInfoSinkh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,116 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _INFOSINK_INCLUDED_
+#define _INFOSINK_INCLUDED_
+
+#include &lt;math.h&gt;
+#include &lt;stdlib.h&gt;
+#include &quot;compiler/translator/Common.h&quot;
+
+// Returns the fractional part of the given floating-point number.
+inline float fractionalPart(float f) {
+  float intPart = 0.0f;
+  return modff(f, &amp;intPart);
+}
+
+//
+// TPrefixType is used to centralize how info log messages start.
+// See below.
+//
+enum TPrefixType {
+    EPrefixNone,
+    EPrefixWarning,
+    EPrefixError,
+    EPrefixInternalError,
+    EPrefixUnimplemented,
+    EPrefixNote
+};
+
+//
+// Encapsulate info logs for all objects that have them.
+//
+// The methods are a general set of tools for getting a variety of
+// messages and types inserted into the log.
+//
+class TInfoSinkBase {
+public:
+    TInfoSinkBase() {}
+
+    template &lt;typename T&gt;
+    TInfoSinkBase&amp; operator&lt;&lt;(const T&amp; t) {
+        TPersistStringStream stream;
+        stream &lt;&lt; t;
+        sink.append(stream.str());
+        return *this;
+    }
+    // Override &lt;&lt; operator for specific types. It is faster to append strings
+    // and characters directly to the sink.
+    TInfoSinkBase&amp; operator&lt;&lt;(char c) {
+        sink.append(1, c);
+        return *this;
+    }
+    TInfoSinkBase&amp; operator&lt;&lt;(const char* str) {
+        sink.append(str);
+        return *this;
+    }
+    TInfoSinkBase&amp; operator&lt;&lt;(const TPersistString&amp; str) {
+        sink.append(str);
+        return *this;
+    }
+    TInfoSinkBase&amp; operator&lt;&lt;(const TString&amp; str) {
+        sink.append(str.c_str());
+        return *this;
+    }
+    // Make sure floats are written with correct precision.
+    TInfoSinkBase&amp; operator&lt;&lt;(float f) {
+        // Make sure that at least one decimal point is written. If a number
+        // does not have a fractional part, the default precision format does
+        // not write the decimal portion which gets interpreted as integer by
+        // the compiler.
+        TPersistStringStream stream;
+        if (fractionalPart(f) == 0.0f) {
+            stream.precision(1);
+            stream &lt;&lt; std::showpoint &lt;&lt; std::fixed &lt;&lt; f;
+        } else {
+            stream.unsetf(std::ios::fixed);
+            stream.unsetf(std::ios::scientific);
+            stream.precision(8);
+            stream &lt;&lt; f;
+        }
+        sink.append(stream.str());
+        return *this;
+    }
+    // Write boolean values as their names instead of integral value.
+    TInfoSinkBase&amp; operator&lt;&lt;(bool b) {
+        const char* str = b ? &quot;true&quot; : &quot;false&quot;;
+        sink.append(str);
+        return *this;
+    }
+
+    void erase() { sink.clear(); }
+    int size() { return static_cast&lt;int&gt;(sink.size()); }
+
+    const TPersistString&amp; str() const { return sink; }
+    const char* c_str() const { return sink.c_str(); }
+
+    void prefix(TPrefixType p);
+    void location(int file, int line);
+    void location(const TSourceLoc&amp; loc);
+    void message(TPrefixType p, const TSourceLoc&amp; loc, const char* m);
+
+private:
+    TPersistString sink;
+};
+
+class TInfoSink {
+public:
+    TInfoSinkBase info;
+    TInfoSinkBase debug;
+    TInfoSinkBase obj;
+};
+
+#endif // _INFOSINK_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InfoSink.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,564 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Create strings that declare built-in definitions, add built-ins that
+// cannot be expressed in the files, and establish mappings between 
+// built-in functions and operators.
+//
+
+#include &quot;compiler/translator/Initialize.h&quot;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &amp;resources, TSymbolTable &amp;symbolTable)
+{
+    TType *float1 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 1);
+    TType *float2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2);
+    TType *float3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3);
+    TType *float4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4);
+
+    TType *int2 = new TType(EbtInt, EbpUndefined, EvqGlobal, 2);
+    TType *int3 = new TType(EbtInt, EbpUndefined, EvqGlobal, 3);
+    TType *int4 = new TType(EbtInt, EbpUndefined, EvqGlobal, 4);
+
+    //
+    // Angle and Trigonometric Functions.
+    //
+    symbolTable.insertBuiltIn(float1, &quot;radians&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;radians&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;radians&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;radians&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;degrees&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;degrees&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;degrees&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;degrees&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;sin&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;sin&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;sin&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;sin&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;cos&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;cos&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;cos&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;cos&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;tan&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;tan&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;tan&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;tan&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;asin&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;asin&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;asin&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;asin&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;acos&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;acos&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;acos&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;acos&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;atan&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;atan&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;atan&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;atan&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;atan&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;atan&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;atan&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;atan&quot;, float4);
+
+    //
+    // Exponential Functions.
+    //
+    symbolTable.insertBuiltIn(float1, &quot;pow&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;pow&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;pow&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;pow&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;exp&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;exp&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;exp&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;exp&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;log&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;log&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;log&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;log&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;exp2&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;exp2&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;exp2&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;exp2&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;log2&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;log2&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;log2&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;log2&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;sqrt&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;sqrt&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;sqrt&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;sqrt&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;inversesqrt&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;inversesqrt&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;inversesqrt&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;inversesqrt&quot;, float4);
+
+    //
+    // Common Functions.
+    //
+    symbolTable.insertBuiltIn(float1, &quot;abs&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;abs&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;abs&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;abs&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;sign&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;sign&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;sign&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;sign&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;floor&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;floor&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;floor&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;floor&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;ceil&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;ceil&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;ceil&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;ceil&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;fract&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;fract&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;fract&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;fract&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;mod&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;mod&quot;, float2, float1);
+    symbolTable.insertBuiltIn(float3, &quot;mod&quot;, float3, float1);
+    symbolTable.insertBuiltIn(float4, &quot;mod&quot;, float4, float1);
+    symbolTable.insertBuiltIn(float2, &quot;mod&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;mod&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;mod&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;min&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;min&quot;, float2, float1);
+    symbolTable.insertBuiltIn(float3, &quot;min&quot;, float3, float1);
+    symbolTable.insertBuiltIn(float4, &quot;min&quot;, float4, float1);
+    symbolTable.insertBuiltIn(float2, &quot;min&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;min&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;min&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;max&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;max&quot;, float2, float1);
+    symbolTable.insertBuiltIn(float3, &quot;max&quot;, float3, float1);
+    symbolTable.insertBuiltIn(float4, &quot;max&quot;, float4, float1);
+    symbolTable.insertBuiltIn(float2, &quot;max&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;max&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;max&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;clamp&quot;, float1, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;clamp&quot;, float2, float1, float1);
+    symbolTable.insertBuiltIn(float3, &quot;clamp&quot;, float3, float1, float1);
+    symbolTable.insertBuiltIn(float4, &quot;clamp&quot;, float4, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;clamp&quot;, float2, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;clamp&quot;, float3, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;clamp&quot;, float4, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;mix&quot;, float1, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;mix&quot;, float2, float2, float1);
+    symbolTable.insertBuiltIn(float3, &quot;mix&quot;, float3, float3, float1);
+    symbolTable.insertBuiltIn(float4, &quot;mix&quot;, float4, float4, float1);
+    symbolTable.insertBuiltIn(float2, &quot;mix&quot;, float2, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;mix&quot;, float3, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;mix&quot;, float4, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;step&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;step&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;step&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;step&quot;, float4, float4);
+    symbolTable.insertBuiltIn(float2, &quot;step&quot;, float1, float2);
+    symbolTable.insertBuiltIn(float3, &quot;step&quot;, float1, float3);
+    symbolTable.insertBuiltIn(float4, &quot;step&quot;, float1, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;smoothstep&quot;, float1, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;smoothstep&quot;, float2, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;smoothstep&quot;, float3, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;smoothstep&quot;, float4, float4, float4);
+    symbolTable.insertBuiltIn(float2, &quot;smoothstep&quot;, float1, float1, float2);
+    symbolTable.insertBuiltIn(float3, &quot;smoothstep&quot;, float1, float1, float3);
+    symbolTable.insertBuiltIn(float4, &quot;smoothstep&quot;, float1, float1, float4);
+
+    //
+    // Geometric Functions.
+    //
+    symbolTable.insertBuiltIn(float1, &quot;length&quot;, float1);
+    symbolTable.insertBuiltIn(float1, &quot;length&quot;, float2);
+    symbolTable.insertBuiltIn(float1, &quot;length&quot;, float3);
+    symbolTable.insertBuiltIn(float1, &quot;length&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;distance&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float1, &quot;distance&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float1, &quot;distance&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float1, &quot;distance&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;dot&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float1, &quot;dot&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float1, &quot;dot&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float1, &quot;dot&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float3, &quot;cross&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float1, &quot;normalize&quot;, float1);
+    symbolTable.insertBuiltIn(float2, &quot;normalize&quot;, float2);
+    symbolTable.insertBuiltIn(float3, &quot;normalize&quot;, float3);
+    symbolTable.insertBuiltIn(float4, &quot;normalize&quot;, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;faceforward&quot;, float1, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;faceforward&quot;, float2, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;faceforward&quot;, float3, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;faceforward&quot;, float4, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;reflect&quot;, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;reflect&quot;, float2, float2);
+    symbolTable.insertBuiltIn(float3, &quot;reflect&quot;, float3, float3);
+    symbolTable.insertBuiltIn(float4, &quot;reflect&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(float1, &quot;refract&quot;, float1, float1, float1);
+    symbolTable.insertBuiltIn(float2, &quot;refract&quot;, float2, float2, float1);
+    symbolTable.insertBuiltIn(float3, &quot;refract&quot;, float3, float3, float1);
+    symbolTable.insertBuiltIn(float4, &quot;refract&quot;, float4, float4, float1);
+
+    TType *mat2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2, true);
+    TType *mat3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3, true);
+    TType *mat4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4, true);
+
+    //
+    // Matrix Functions.
+    //
+    symbolTable.insertBuiltIn(mat2, &quot;matrixCompMult&quot;, mat2, mat2);
+    symbolTable.insertBuiltIn(mat3, &quot;matrixCompMult&quot;, mat3, mat3);
+    symbolTable.insertBuiltIn(mat4, &quot;matrixCompMult&quot;, mat4, mat4);
+
+    TType *bool1 = new TType(EbtBool, EbpUndefined, EvqGlobal, 1);
+    TType *bool2 = new TType(EbtBool, EbpUndefined, EvqGlobal, 2);
+    TType *bool3 = new TType(EbtBool, EbpUndefined, EvqGlobal, 3);
+    TType *bool4 = new TType(EbtBool, EbpUndefined, EvqGlobal, 4);
+
+    //
+    // Vector relational functions.
+    //
+    symbolTable.insertBuiltIn(bool2, &quot;lessThan&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;lessThan&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;lessThan&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;lessThan&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;lessThan&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;lessThan&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;lessThanEqual&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;lessThanEqual&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;lessThanEqual&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;lessThanEqual&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;lessThanEqual&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;lessThanEqual&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;greaterThan&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;greaterThan&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;greaterThan&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;greaterThan&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;greaterThan&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;greaterThan&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;greaterThanEqual&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;greaterThanEqual&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;greaterThanEqual&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;greaterThanEqual&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;greaterThanEqual&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;greaterThanEqual&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;equal&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;equal&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;equal&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;equal&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;equal&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;equal&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;equal&quot;, bool2, bool2);
+    symbolTable.insertBuiltIn(bool3, &quot;equal&quot;, bool3, bool3);
+    symbolTable.insertBuiltIn(bool4, &quot;equal&quot;, bool4, bool4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;notEqual&quot;, float2, float2);
+    symbolTable.insertBuiltIn(bool3, &quot;notEqual&quot;, float3, float3);
+    symbolTable.insertBuiltIn(bool4, &quot;notEqual&quot;, float4, float4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;notEqual&quot;, int2, int2);
+    symbolTable.insertBuiltIn(bool3, &quot;notEqual&quot;, int3, int3);
+    symbolTable.insertBuiltIn(bool4, &quot;notEqual&quot;, int4, int4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;notEqual&quot;, bool2, bool2);
+    symbolTable.insertBuiltIn(bool3, &quot;notEqual&quot;, bool3, bool3);
+    symbolTable.insertBuiltIn(bool4, &quot;notEqual&quot;, bool4, bool4);
+
+    symbolTable.insertBuiltIn(bool1, &quot;any&quot;, bool2);
+    symbolTable.insertBuiltIn(bool1, &quot;any&quot;, bool3);
+    symbolTable.insertBuiltIn(bool1, &quot;any&quot;, bool4);
+
+    symbolTable.insertBuiltIn(bool1, &quot;all&quot;, bool2);
+    symbolTable.insertBuiltIn(bool1, &quot;all&quot;, bool3);
+    symbolTable.insertBuiltIn(bool1, &quot;all&quot;, bool4);
+
+    symbolTable.insertBuiltIn(bool2, &quot;not&quot;, bool2);
+    symbolTable.insertBuiltIn(bool3, &quot;not&quot;, bool3);
+    symbolTable.insertBuiltIn(bool4, &quot;not&quot;, bool4);
+
+    TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1);
+    TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1);
+
+    //
+    // Texture Functions for GLSL ES 1.0
+    //
+    symbolTable.insertBuiltIn(float4, &quot;texture2D&quot;, sampler2D, float2);
+    symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, sampler2D, float3);
+    symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, sampler2D, float4);
+    symbolTable.insertBuiltIn(float4, &quot;textureCube&quot;, samplerCube, float3);
+
+    if (resources.OES_EGL_image_external)
+    {
+        TType *samplerExternalOES = new TType(EbtSamplerExternalOES, EbpUndefined, EvqGlobal, 1);
+
+        symbolTable.insertBuiltIn(float4, &quot;texture2D&quot;, samplerExternalOES, float2);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, samplerExternalOES, float3);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, samplerExternalOES, float4);
+    }
+
+    if (resources.ARB_texture_rectangle)
+    {
+        TType *sampler2DRect = new TType(EbtSampler2DRect, EbpUndefined, EvqGlobal, 1);
+
+        symbolTable.insertBuiltIn(float4, &quot;texture2DRect&quot;, sampler2DRect, float2);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DRectProj&quot;, sampler2DRect, float3);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DRectProj&quot;, sampler2DRect, float4);
+    }
+
+    if (type == SH_FRAGMENT_SHADER)
+    {
+        symbolTable.insertBuiltIn(float4, &quot;texture2D&quot;, sampler2D, float2, float1);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, sampler2D, float3, float1);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProj&quot;, sampler2D, float4, float1);
+        symbolTable.insertBuiltIn(float4, &quot;textureCube&quot;, samplerCube, float3, float1);
+
+        if (resources.OES_standard_derivatives)
+        {
+            symbolTable.insertBuiltIn(float1, &quot;dFdx&quot;, float1);
+            symbolTable.insertBuiltIn(float2, &quot;dFdx&quot;, float2);
+            symbolTable.insertBuiltIn(float3, &quot;dFdx&quot;, float3);
+            symbolTable.insertBuiltIn(float4, &quot;dFdx&quot;, float4);
+            
+            symbolTable.insertBuiltIn(float1, &quot;dFdy&quot;, float1);
+            symbolTable.insertBuiltIn(float2, &quot;dFdy&quot;, float2);
+            symbolTable.insertBuiltIn(float3, &quot;dFdy&quot;, float3);
+            symbolTable.insertBuiltIn(float4, &quot;dFdy&quot;, float4);
+
+            symbolTable.insertBuiltIn(float1, &quot;fwidth&quot;, float1);
+            symbolTable.insertBuiltIn(float2, &quot;fwidth&quot;, float2);
+            symbolTable.insertBuiltIn(float3, &quot;fwidth&quot;, float3);
+            symbolTable.insertBuiltIn(float4, &quot;fwidth&quot;, float4);
+        }
+    }
+
+    if(type == SH_VERTEX_SHADER)
+    {
+        symbolTable.insertBuiltIn(float4, &quot;texture2DLod&quot;, sampler2D, float2, float1);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProjLod&quot;, sampler2D, float3, float1);
+        symbolTable.insertBuiltIn(float4, &quot;texture2DProjLod&quot;, sampler2D, float4, float1);
+        symbolTable.insertBuiltIn(float4, &quot;textureCubeLod&quot;, samplerCube, float3, float1);
+    }
+
+    //
+    // Depth range in window coordinates
+    //
+    TFieldList *fields = NewPoolTFieldList();
+    TField *near = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString(&quot;near&quot;));
+    TField *far = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString(&quot;far&quot;));
+    TField *diff = new TField(new TType(EbtFloat, EbpHigh, EvqGlobal, 1), NewPoolTString(&quot;diff&quot;));
+    fields-&gt;push_back(near);
+    fields-&gt;push_back(far);
+    fields-&gt;push_back(diff);
+    TStructure *depthRangeStruct = new TStructure(NewPoolTString(&quot;gl_DepthRangeParameters&quot;), fields);
+    TVariable *depthRangeParameters = new TVariable(&amp;depthRangeStruct-&gt;name(), depthRangeStruct, true);
+    symbolTable.insert(*depthRangeParameters);
+    TVariable *depthRange = new TVariable(NewPoolTString(&quot;gl_DepthRange&quot;), TType(depthRangeStruct));
+    depthRange-&gt;setQualifier(EvqUniform);
+    symbolTable.insert(*depthRange);
+
+    //
+    // Implementation dependent built-in constants.
+    //
+    symbolTable.insertConstInt(&quot;gl_MaxVertexAttribs&quot;, resources.MaxVertexAttribs);
+    symbolTable.insertConstInt(&quot;gl_MaxVertexUniformVectors&quot;, resources.MaxVertexUniformVectors);
+    symbolTable.insertConstInt(&quot;gl_MaxVaryingVectors&quot;, resources.MaxVaryingVectors);
+    symbolTable.insertConstInt(&quot;gl_MaxVertexTextureImageUnits&quot;, resources.MaxVertexTextureImageUnits);
+    symbolTable.insertConstInt(&quot;gl_MaxCombinedTextureImageUnits&quot;, resources.MaxCombinedTextureImageUnits);
+    symbolTable.insertConstInt(&quot;gl_MaxTextureImageUnits&quot;, resources.MaxTextureImageUnits);
+    symbolTable.insertConstInt(&quot;gl_MaxFragmentUniformVectors&quot;, resources.MaxFragmentUniformVectors);
+
+    if (spec != SH_CSS_SHADERS_SPEC)
+    {
+        symbolTable.insertConstInt(&quot;gl_MaxDrawBuffers&quot;, resources.MaxDrawBuffers);
+    }
+}
+
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+                      const ShBuiltInResources &amp;resources,
+                      TSymbolTable &amp;symbolTable)
+{
+    //
+    // First, insert some special built-in variables that are not in 
+    // the built-in header files.
+    //
+    switch(type) {
+    case SH_FRAGMENT_SHADER:
+        symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FragCoord&quot;),                       TType(EbtFloat, EbpMedium, EvqFragCoord,   4)));
+        symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FrontFacing&quot;),                     TType(EbtBool,  EbpUndefined, EvqFrontFacing, 1)));
+        symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_PointCoord&quot;),                      TType(EbtFloat, EbpMedium, EvqPointCoord,  2)));
+
+        //
+        // In CSS Shaders, gl_FragColor, gl_FragData, and gl_MaxDrawBuffers are not available.
+        // Instead, css_MixColor and css_ColorMatrix are available.
+        //
+        if (spec != SH_CSS_SHADERS_SPEC) {
+            symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FragColor&quot;),                   TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
+            symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FragData[gl_MaxDrawBuffers]&quot;), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+            if (resources.EXT_frag_depth) {
+                symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FragDepthEXT&quot;),            TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
+                symbolTable.relateToExtension(&quot;gl_FragDepthEXT&quot;, &quot;GL_EXT_frag_depth&quot;);
+            }
+        } else {
+            symbolTable.insert(*new TVariable(NewPoolTString(&quot;css_MixColor&quot;),                   TType(EbtFloat, EbpMedium, EvqGlobal,      4)));
+            symbolTable.insert(*new TVariable(NewPoolTString(&quot;css_ColorMatrix&quot;),                TType(EbtFloat, EbpMedium, EvqGlobal,      4, true)));
+        }
+
+        break;
+
+    case SH_VERTEX_SHADER:
+        symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_Position&quot;),    TType(EbtFloat, EbpHigh, EvqPosition,    4)));
+        symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_PointSize&quot;),   TType(EbtFloat, EbpMedium, EvqPointSize,   1)));
+        break;
+
+    default: assert(false &amp;&amp; &quot;Language not supported&quot;);
+    }
+
+    //
+    // Next, identify which built-ins from the already loaded headers have
+    // a mapping to an operator.  Those that are not identified as such are
+    // expected to be resolved through a library of functions, versus as
+    // operations.
+    //
+    symbolTable.relateToOperator(&quot;matrixCompMult&quot;,   EOpMul);
+
+    symbolTable.relateToOperator(&quot;equal&quot;,            EOpVectorEqual);
+    symbolTable.relateToOperator(&quot;notEqual&quot;,         EOpVectorNotEqual);
+    symbolTable.relateToOperator(&quot;lessThan&quot;,         EOpLessThan);
+    symbolTable.relateToOperator(&quot;greaterThan&quot;,      EOpGreaterThan);
+    symbolTable.relateToOperator(&quot;lessThanEqual&quot;,    EOpLessThanEqual);
+    symbolTable.relateToOperator(&quot;greaterThanEqual&quot;, EOpGreaterThanEqual);
+    
+    symbolTable.relateToOperator(&quot;radians&quot;,      EOpRadians);
+    symbolTable.relateToOperator(&quot;degrees&quot;,      EOpDegrees);
+    symbolTable.relateToOperator(&quot;sin&quot;,          EOpSin);
+    symbolTable.relateToOperator(&quot;cos&quot;,          EOpCos);
+    symbolTable.relateToOperator(&quot;tan&quot;,          EOpTan);
+    symbolTable.relateToOperator(&quot;asin&quot;,         EOpAsin);
+    symbolTable.relateToOperator(&quot;acos&quot;,         EOpAcos);
+    symbolTable.relateToOperator(&quot;atan&quot;,         EOpAtan);
+
+    symbolTable.relateToOperator(&quot;pow&quot;,          EOpPow);
+    symbolTable.relateToOperator(&quot;exp2&quot;,         EOpExp2);
+    symbolTable.relateToOperator(&quot;log&quot;,          EOpLog);
+    symbolTable.relateToOperator(&quot;exp&quot;,          EOpExp);
+    symbolTable.relateToOperator(&quot;log2&quot;,         EOpLog2);
+    symbolTable.relateToOperator(&quot;sqrt&quot;,         EOpSqrt);
+    symbolTable.relateToOperator(&quot;inversesqrt&quot;,  EOpInverseSqrt);
+
+    symbolTable.relateToOperator(&quot;abs&quot;,          EOpAbs);
+    symbolTable.relateToOperator(&quot;sign&quot;,         EOpSign);
+    symbolTable.relateToOperator(&quot;floor&quot;,        EOpFloor);
+    symbolTable.relateToOperator(&quot;ceil&quot;,         EOpCeil);
+    symbolTable.relateToOperator(&quot;fract&quot;,        EOpFract);
+    symbolTable.relateToOperator(&quot;mod&quot;,          EOpMod);
+    symbolTable.relateToOperator(&quot;min&quot;,          EOpMin);
+    symbolTable.relateToOperator(&quot;max&quot;,          EOpMax);
+    symbolTable.relateToOperator(&quot;clamp&quot;,        EOpClamp);
+    symbolTable.relateToOperator(&quot;mix&quot;,          EOpMix);
+    symbolTable.relateToOperator(&quot;step&quot;,         EOpStep);
+    symbolTable.relateToOperator(&quot;smoothstep&quot;,   EOpSmoothStep);
+
+    symbolTable.relateToOperator(&quot;length&quot;,       EOpLength);
+    symbolTable.relateToOperator(&quot;distance&quot;,     EOpDistance);
+    symbolTable.relateToOperator(&quot;dot&quot;,          EOpDot);
+    symbolTable.relateToOperator(&quot;cross&quot;,        EOpCross);
+    symbolTable.relateToOperator(&quot;normalize&quot;,    EOpNormalize);
+    symbolTable.relateToOperator(&quot;faceforward&quot;,  EOpFaceForward);
+    symbolTable.relateToOperator(&quot;reflect&quot;,      EOpReflect);
+    symbolTable.relateToOperator(&quot;refract&quot;,      EOpRefract);
+    
+    symbolTable.relateToOperator(&quot;any&quot;,          EOpAny);
+    symbolTable.relateToOperator(&quot;all&quot;,          EOpAll);
+    symbolTable.relateToOperator(&quot;not&quot;,          EOpVectorLogicalNot);
+
+    // Map language-specific operators.
+    switch(type) {
+    case SH_VERTEX_SHADER:
+        break;
+    case SH_FRAGMENT_SHADER:
+        if (resources.OES_standard_derivatives) {
+            symbolTable.relateToOperator(&quot;dFdx&quot;,   EOpDFdx);
+            symbolTable.relateToOperator(&quot;dFdy&quot;,   EOpDFdy);
+            symbolTable.relateToOperator(&quot;fwidth&quot;, EOpFwidth);
+
+            symbolTable.relateToExtension(&quot;dFdx&quot;, &quot;GL_OES_standard_derivatives&quot;);
+            symbolTable.relateToExtension(&quot;dFdy&quot;, &quot;GL_OES_standard_derivatives&quot;);
+            symbolTable.relateToExtension(&quot;fwidth&quot;, &quot;GL_OES_standard_derivatives&quot;);
+        }
+        break;
+    default: break;
+    }
+
+    // Finally add resource-specific variables.
+    switch(type) {
+    case SH_FRAGMENT_SHADER:
+        if (spec != SH_CSS_SHADERS_SPEC) {
+            // Set up gl_FragData.  The array size.
+            TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, false, true);
+            fragData.setArraySize(resources.MaxDrawBuffers);
+            symbolTable.insert(*new TVariable(NewPoolTString(&quot;gl_FragData&quot;),    fragData));
+        }
+        break;
+    default: break;
+    }
+}
+
+void InitExtensionBehavior(const ShBuiltInResources&amp; resources,
+                           TExtensionBehavior&amp; extBehavior)
+{
+    if (resources.OES_standard_derivatives)
+        extBehavior[&quot;GL_OES_standard_derivatives&quot;] = EBhUndefined;
+    if (resources.OES_EGL_image_external)
+        extBehavior[&quot;GL_OES_EGL_image_external&quot;] = EBhUndefined;
+    if (resources.ARB_texture_rectangle)
+        extBehavior[&quot;GL_ARB_texture_rectangle&quot;] = EBhUndefined;
+    if (resources.EXT_draw_buffers)
+        extBehavior[&quot;GL_EXT_draw_buffers&quot;] = EBhUndefined;
+    if (resources.EXT_frag_depth)
+        extBehavior[&quot;GL_EXT_frag_depth&quot;] = EBhUndefined;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _INITIALIZE_INCLUDED_
+#define _INITIALIZE_INCLUDED_
+
+#include &quot;compiler/translator/Common.h&quot;
+#include &quot;compiler/translator/ShHandle.h&quot;
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+void InsertBuiltInFunctions(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources &amp;resources, TSymbolTable &amp;table);
+
+void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec,
+                      const ShBuiltInResources&amp; resources,
+                      TSymbolTable&amp; symbolTable);
+
+void InitExtensionBehavior(const ShBuiltInResources&amp; resources,
+                           TExtensionBehavior&amp; extensionBehavior);
+
+#endif // _INITIALIZE_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Initialize.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeDllcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/InitializeDll.h&quot;
+
+#include &quot;compiler/translator/InitializeGlobals.h&quot;
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+#include &quot;compiler/translator/osinclude.h&quot;
+
+bool InitProcess()
+{
+    if (!InitializePoolIndex()) {
+        assert(0 &amp;&amp; &quot;InitProcess(): Failed to initalize global pool&quot;);
+        return false;
+    }
+
+    if (!InitializeParseContextIndex()) {
+        assert(0 &amp;&amp; &quot;InitProcess(): Failed to initalize parse context&quot;);
+        return false;
+    }
+
+    return true;
+}
+
+void DetachProcess()
+{
+    FreeParseContextIndex();
+    FreePoolIndex();
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeDllh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#ifndef __INITIALIZEDLL_H
+#define __INITIALIZEDLL_H
+
+bool InitProcess();
+void DetachProcess();
+
+#endif // __INITIALIZEDLL_H
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeDll.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeGlobalsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeGlobals.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeGlobals.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeGlobals.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,13 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef __INITIALIZE_GLOBALS_INCLUDED_
+#define __INITIALIZE_GLOBALS_INCLUDED_
+
+bool InitializePoolIndex();
+void FreePoolIndex();
+
+#endif // __INITIALIZE_GLOBALS_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeGlobals.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeParseContextcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+
+#include &quot;compiler/translator/osinclude.h&quot;
+
+OS_TLSIndex GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+bool InitializeParseContextIndex()
+{
+    assert(GlobalParseContextIndex == OS_INVALID_TLS_INDEX);
+
+    GlobalParseContextIndex = OS_AllocTLSIndex();
+    return GlobalParseContextIndex != OS_INVALID_TLS_INDEX;
+}
+
+void FreeParseContextIndex()
+{
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+
+    OS_FreeTLSIndex(GlobalParseContextIndex);
+    GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+}
+
+void SetGlobalParseContext(TParseContext* context)
+{
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(GlobalParseContextIndex, context);
+}
+
+TParseContext* GetGlobalParseContext()
+{
+    assert(GlobalParseContextIndex != OS_INVALID_TLS_INDEX);
+    return static_cast&lt;TParseContext*&gt;(OS_GetTLSValue(GlobalParseContextIndex));
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeParseContexth"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
+
+bool InitializeParseContextIndex();
+void FreeParseContextIndex();
+
+struct TParseContext;
+extern void SetGlobalParseContext(TParseContext* context);
+extern TParseContext* GetGlobalParseContext();
+
+#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeParseContext.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeVariablescpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,116 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/InitializeVariables.h&quot;
+#include &quot;compiler/translator/compilerdebug.h&quot;
+
+namespace
+{
+
+TIntermConstantUnion* constructFloatConstUnionNode(const TType&amp; type)
+{
+    TType myType = type;
+    unsigned char size = myType.getNominalSize();
+    if (myType.isMatrix())
+        size *= size;
+    ConstantUnion *u = new ConstantUnion[size];
+    for (int ii = 0; ii &lt; size; ++ii)
+        u[ii].setFConst(0.0f);
+
+    myType.clearArrayness();
+    myType.setQualifier(EvqConst);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, myType);
+    return node;
+}
+
+TIntermConstantUnion* constructIndexNode(int index)
+{
+    ConstantUnion *u = new ConstantUnion[1];
+    u[0].setIConst(index);
+
+    TType type(EbtInt, EbpUndefined, EvqConst, 1);
+    TIntermConstantUnion *node = new TIntermConstantUnion(u, type);
+    return node;
+}
+
+}  // namespace anonymous
+
+bool InitializeVariables::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    bool visitChildren = !mCodeInserted;
+    switch (node-&gt;getOp())
+    {
+      case EOpSequence:
+        break;
+      case EOpFunction:
+      {
+        // Function definition.
+        ASSERT(visit == PreVisit);
+        if (node-&gt;getName() == &quot;main(&quot;)
+        {
+            TIntermSequence &amp;sequence = node-&gt;getSequence();
+            ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+            TIntermAggregate *body = NULL;
+            if (sequence.size() == 1)
+            {
+                body = new TIntermAggregate(EOpSequence);
+                sequence.push_back(body);
+            }
+            else
+            {
+                body = sequence[1]-&gt;getAsAggregate();
+            }
+            ASSERT(body);
+            insertInitCode(body-&gt;getSequence());
+            mCodeInserted = true;
+        }
+        break;
+      }
+      default:
+        visitChildren = false;
+        break;
+    }
+    return visitChildren;
+}
+
+void InitializeVariables::insertInitCode(TIntermSequence&amp; sequence)
+{
+    for (size_t ii = 0; ii &lt; mVariables.size(); ++ii)
+    {
+        const InitVariableInfo&amp; varInfo = mVariables[ii];
+
+        if (varInfo.type.isArray())
+        {
+            for (int index = varInfo.type.getArraySize() - 1; index &gt;= 0; --index)
+            {
+                TIntermBinary *assign = new TIntermBinary(EOpAssign);
+                sequence.insert(sequence.begin(), assign);
+
+                TIntermBinary *indexDirect = new TIntermBinary(EOpIndexDirect);
+                TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
+                indexDirect-&gt;setLeft(symbol);
+                TIntermConstantUnion *indexNode = constructIndexNode(index);
+                indexDirect-&gt;setRight(indexNode);
+
+                assign-&gt;setLeft(indexDirect);
+
+                TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
+                assign-&gt;setRight(zeroConst);
+            }
+        }
+        else
+        {
+            TIntermBinary *assign = new TIntermBinary(EOpAssign);
+            sequence.insert(sequence.begin(), assign);
+            TIntermSymbol *symbol = new TIntermSymbol(0, varInfo.name, varInfo.type);
+            assign-&gt;setLeft(symbol);
+            TIntermConstantUnion *zeroConst = constructFloatConstUnionNode(varInfo.type);
+            assign-&gt;setRight(zeroConst);
+        }
+
+    }
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorInitializeVariablesh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,50 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_INITIALIZE_VARIABLES_H_
+#define COMPILER_INITIALIZE_VARIABLES_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+class InitializeVariables : public TIntermTraverser
+{
+  public:
+    struct InitVariableInfo
+    {
+        TString name;
+        TType type;
+
+        InitVariableInfo(const TString&amp; _name, const TType&amp; _type)
+            : name(_name),
+              type(_type)
+        {
+        }
+    };
+    typedef TVector&lt;InitVariableInfo&gt; InitVariableInfoList;
+
+    InitializeVariables(const InitVariableInfoList&amp; vars)
+        : mCodeInserted(false),
+          mVariables(vars)
+    {
+    }
+
+  protected:
+    virtual bool visitBinary(Visit visit, TIntermBinary* node) { return false; }
+    virtual bool visitUnary(Visit visit, TIntermUnary* node) { return false; }
+    virtual bool visitSelection(Visit visit, TIntermSelection* node) { return false; }
+    virtual bool visitLoop(Visit visit, TIntermLoop* node) { return false; }
+    virtual bool visitBranch(Visit visit, TIntermBranch* node) { return false; }
+
+    virtual bool visitAggregate(Visit visit, TIntermAggregate* node);
+
+  private:
+    void insertInitCode(TIntermSequence&amp; sequence);
+
+    InitVariableInfoList mVariables;
+    bool mCodeInserted;
+};
+
+#endif  // COMPILER_INITIALIZE_VARIABLES_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/InitializeVariables.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorIntermTraversecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,259 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+//
+// Traverse the intermediate representation tree, and
+// call a node type specific function for each node.
+// Done recursively through the member function Traverse().
+// Node types can be skipped if their function to call is 0,
+// but their subtree will still be traversed.
+// Nodes with children can have their whole subtree skipped
+// if preVisit is turned on and the type specific function
+// returns false.
+//
+// preVisit, postVisit, and rightToLeft control what order
+// nodes are visited in.
+//
+
+//
+// Traversal functions for terminals are straighforward....
+//
+void TIntermSymbol::traverse(TIntermTraverser *it)
+{
+    it-&gt;visitSymbol(this);
+}
+
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
+{
+    it-&gt;visitConstantUnion(this);
+}
+
+//
+// Traverse a binary node.
+//
+void TIntermBinary::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+
+    //
+    // visit the node before children if pre-visiting.
+    //
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitBinary(PreVisit, this);
+    
+    //
+    // Visit the children, in the right order.
+    //
+    if (visit)
+    {
+        it-&gt;incrementDepth(this);
+
+        if (it-&gt;rightToLeft) 
+        {
+            if (right)
+                right-&gt;traverse(it);
+            
+            if (it-&gt;inVisit)
+                visit = it-&gt;visitBinary(InVisit, this);
+
+            if (visit &amp;&amp; left)
+                left-&gt;traverse(it);
+        }
+        else
+        {
+            if (left)
+                left-&gt;traverse(it);
+            
+            if (it-&gt;inVisit)
+                visit = it-&gt;visitBinary(InVisit, this);
+
+            if (visit &amp;&amp; right)
+                right-&gt;traverse(it);
+        }
+
+        it-&gt;decrementDepth();
+    }
+
+    //
+    // Visit the node after the children, if requested and the traversal
+    // hasn't been cancelled yet.
+    //
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitBinary(PostVisit, this);
+}
+
+//
+// Traverse a unary node.  Same comments in binary node apply here.
+//
+void TIntermUnary::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitUnary(PreVisit, this);
+
+    if (visit) {
+        it-&gt;incrementDepth(this);
+        operand-&gt;traverse(it);
+        it-&gt;decrementDepth();
+    }
+    
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitUnary(PostVisit, this);
+}
+
+//
+// Traverse an aggregate node.  Same comments in binary node apply here.
+//
+void TIntermAggregate::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+    
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitAggregate(PreVisit, this);
+    
+    if (visit)
+    {
+        it-&gt;incrementDepth(this);
+
+        if (it-&gt;rightToLeft)
+        {
+            for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++)
+            {
+                (*sit)-&gt;traverse(it);
+
+                if (visit &amp;&amp; it-&gt;inVisit)
+                {
+                    if (*sit != sequence.front())
+                        visit = it-&gt;visitAggregate(InVisit, this);
+                }
+            }
+        }
+        else
+        {
+            for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+            {
+                (*sit)-&gt;traverse(it);
+
+                if (visit &amp;&amp; it-&gt;inVisit)
+                {
+                    if (*sit != sequence.back())
+                        visit = it-&gt;visitAggregate(InVisit, this);
+                }
+            }
+        }
+        
+        it-&gt;decrementDepth();
+    }
+
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitAggregate(PostVisit, this);
+}
+
+//
+// Traverse a selection node.  Same comments in binary node apply here.
+//
+void TIntermSelection::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitSelection(PreVisit, this);
+    
+    if (visit) {
+        it-&gt;incrementDepth(this);
+        if (it-&gt;rightToLeft) {
+            if (falseBlock)
+                falseBlock-&gt;traverse(it);
+            if (trueBlock)
+                trueBlock-&gt;traverse(it);
+            condition-&gt;traverse(it);
+        } else {
+            condition-&gt;traverse(it);
+            if (trueBlock)
+                trueBlock-&gt;traverse(it);
+            if (falseBlock)
+                falseBlock-&gt;traverse(it);
+        }
+        it-&gt;decrementDepth();
+    }
+
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitSelection(PostVisit, this);
+}
+
+//
+// Traverse a loop node.  Same comments in binary node apply here.
+//
+void TIntermLoop::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitLoop(PreVisit, this);
+    
+    if (visit)
+    {
+        it-&gt;incrementDepth(this);
+
+        if (it-&gt;rightToLeft)
+        {
+            if (expr)
+                expr-&gt;traverse(it);
+
+            if (body)
+                body-&gt;traverse(it);
+
+            if (cond)
+                cond-&gt;traverse(it);
+
+            if (init)
+                init-&gt;traverse(it);
+        }
+        else
+        {
+            if (init)
+                init-&gt;traverse(it);
+
+            if (cond)
+                cond-&gt;traverse(it);
+
+            if (body)
+                body-&gt;traverse(it);
+
+            if (expr)
+                expr-&gt;traverse(it);
+        }
+
+        it-&gt;decrementDepth();
+    }
+
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitLoop(PostVisit, this);
+}
+
+//
+// Traverse a branch node.  Same comments in binary node apply here.
+//
+void TIntermBranch::traverse(TIntermTraverser *it)
+{
+    bool visit = true;
+
+    if (it-&gt;preVisit)
+        visit = it-&gt;visitBranch(PreVisit, this);
+    
+    if (visit &amp;&amp; expression) {
+        it-&gt;incrementDepth(this);
+        expression-&gt;traverse(it);
+        it-&gt;decrementDepth();
+    }
+
+    if (visit &amp;&amp; it-&gt;postVisit)
+        it-&gt;visitBranch(PostVisit, this);
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/IntermTraverse.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorIntermediatecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,1500 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Build the intermediate representation.
+//
+
+#include &lt;float.h&gt;
+#include &lt;limits.h&gt;
+#include &lt;algorithm&gt;
+
+#include &quot;compiler/translator/HashNames.h&quot;
+#include &quot;compiler/translator/localintermediate.h&quot;
+#include &quot;compiler/translator/QualifierAlive.h&quot;
+#include &quot;compiler/translator/RemoveTree.h&quot;
+
+bool CompareStructure(const TType&amp; leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
+
+static TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
+{
+    return left &gt; right ? left : right;
+}
+
+const char* getOperatorString(TOperator op)
+{
+    switch (op) {
+      case EOpInitialize: return &quot;=&quot;;
+      case EOpAssign: return &quot;=&quot;;
+      case EOpAddAssign: return &quot;+=&quot;;
+      case EOpSubAssign: return &quot;-=&quot;;
+      case EOpDivAssign: return &quot;/=&quot;;
+
+      // Fall-through.
+      case EOpMulAssign: 
+      case EOpVectorTimesMatrixAssign:
+      case EOpVectorTimesScalarAssign:
+      case EOpMatrixTimesScalarAssign:
+      case EOpMatrixTimesMatrixAssign: return &quot;*=&quot;;
+
+      // Fall-through.
+      case EOpIndexDirect:
+      case EOpIndexIndirect: return &quot;[]&quot;;
+
+      case EOpIndexDirectStruct: return &quot;.&quot;;
+      case EOpVectorSwizzle: return &quot;.&quot;;
+      case EOpAdd: return &quot;+&quot;;
+      case EOpSub: return &quot;-&quot;;
+      case EOpMul: return &quot;*&quot;;
+      case EOpDiv: return &quot;/&quot;;
+      case EOpMod: UNIMPLEMENTED(); break;
+      case EOpEqual: return &quot;==&quot;;
+      case EOpNotEqual: return &quot;!=&quot;;
+      case EOpLessThan: return &quot;&lt;&quot;;
+      case EOpGreaterThan: return &quot;&gt;&quot;;
+      case EOpLessThanEqual: return &quot;&lt;=&quot;;
+      case EOpGreaterThanEqual: return &quot;&gt;=&quot;;
+
+      // Fall-through.
+      case EOpVectorTimesScalar:
+      case EOpVectorTimesMatrix:
+      case EOpMatrixTimesVector:
+      case EOpMatrixTimesScalar:
+      case EOpMatrixTimesMatrix: return &quot;*&quot;;
+
+      case EOpLogicalOr: return &quot;||&quot;;
+      case EOpLogicalXor: return &quot;^^&quot;;
+      case EOpLogicalAnd: return &quot;&amp;&amp;&quot;;
+      case EOpNegative: return &quot;-&quot;;
+      case EOpVectorLogicalNot: return &quot;not&quot;;
+      case EOpLogicalNot: return &quot;!&quot;;
+      case EOpPostIncrement: return &quot;++&quot;;
+      case EOpPostDecrement: return &quot;--&quot;;
+      case EOpPreIncrement: return &quot;++&quot;;
+      case EOpPreDecrement: return &quot;--&quot;;
+
+      // Fall-through.
+      case EOpConvIntToBool:
+      case EOpConvFloatToBool: return &quot;bool&quot;;

+      // Fall-through.
+      case EOpConvBoolToFloat:
+      case EOpConvIntToFloat: return &quot;float&quot;;

+      // Fall-through.
+      case EOpConvFloatToInt:
+      case EOpConvBoolToInt: return &quot;int&quot;;
+
+      case EOpRadians: return &quot;radians&quot;;
+      case EOpDegrees: return &quot;degrees&quot;;
+      case EOpSin: return &quot;sin&quot;;
+      case EOpCos: return &quot;cos&quot;;
+      case EOpTan: return &quot;tan&quot;;
+      case EOpAsin: return &quot;asin&quot;;
+      case EOpAcos: return &quot;acos&quot;;
+      case EOpAtan: return &quot;atan&quot;;
+      case EOpExp: return &quot;exp&quot;;
+      case EOpLog: return &quot;log&quot;;
+      case EOpExp2: return &quot;exp2&quot;;
+      case EOpLog2: return &quot;log2&quot;;
+      case EOpSqrt: return &quot;sqrt&quot;;
+      case EOpInverseSqrt: return &quot;inversesqrt&quot;;
+      case EOpAbs: return &quot;abs&quot;;
+      case EOpSign: return &quot;sign&quot;;
+      case EOpFloor: return &quot;floor&quot;;
+      case EOpCeil: return &quot;ceil&quot;;
+      case EOpFract: return &quot;fract&quot;;
+      case EOpLength: return &quot;length&quot;;
+      case EOpNormalize: return &quot;normalize&quot;;
+      case EOpDFdx: return &quot;dFdx&quot;;
+      case EOpDFdy: return &quot;dFdy&quot;;
+      case EOpFwidth: return &quot;fwidth&quot;;
+      case EOpAny: return &quot;any&quot;;
+      case EOpAll: return &quot;all&quot;;
+
+      default: break;
+    }
+    return &quot;&quot;;
+}
+
+////////////////////////////////////////////////////////////////////////////
+//
+// First set of functions are to help build the intermediate representation.
+// These functions are not member functions of the nodes.
+// They are called from parser productions.
+//
+/////////////////////////////////////////////////////////////////////////////
+
+//
+// Add a terminal node for an identifier in an expression.
+//
+// Returns the added node.
+//
+TIntermSymbol* TIntermediate::addSymbol(int id, const TString&amp; name, const TType&amp; type, const TSourceLoc&amp; line)
+{
+    TIntermSymbol* node = new TIntermSymbol(id, name, type);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+//
+// Connect two nodes with a new parent that does a binary operation on the nodes.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp; line, TSymbolTable&amp; symbolTable)
+{
+    switch (op) {
+        case EOpEqual:
+        case EOpNotEqual:
+            if (left-&gt;isArray())
+                return 0;
+            break;
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+            if (left-&gt;isMatrix() || left-&gt;isArray() || left-&gt;isVector() || left-&gt;getBasicType() == EbtStruct) {
+                return 0;
+            }
+            break;
+        case EOpLogicalOr:
+        case EOpLogicalXor:
+        case EOpLogicalAnd:
+            if (left-&gt;getBasicType() != EbtBool || left-&gt;isMatrix() || left-&gt;isArray() || left-&gt;isVector()) {
+                return 0;
+            }
+            break;
+        case EOpAdd:
+        case EOpSub:
+        case EOpDiv:
+        case EOpMul:
+            if (left-&gt;getBasicType() == EbtStruct || left-&gt;getBasicType() == EbtBool)
+                return 0;
+        default: break;
+    }
+
+    //
+    // First try converting the children to compatible types.
+    //
+    if (left-&gt;getType().getStruct() &amp;&amp; right-&gt;getType().getStruct()) {
+        if (left-&gt;getType() != right-&gt;getType())
+            return 0;
+    } else {
+        TIntermTyped* child = addConversion(op, left-&gt;getType(), right);
+        if (child)
+            right = child;
+        else {
+            child = addConversion(op, right-&gt;getType(), left);
+            if (child)
+                left = child;
+            else
+                return 0;
+        }
+    }
+
+    //
+    // Need a new node holding things together then.  Make
+    // one and promote it to the right type.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    node-&gt;setLine(line);
+
+    node-&gt;setLeft(left);
+    node-&gt;setRight(right);
+    if (!node-&gt;promote(infoSink))
+        return 0;
+
+    //
+    // See if we can fold constants.
+    //
+    TIntermTyped* typedReturnNode = 0;
+    TIntermConstantUnion *leftTempConstant = left-&gt;getAsConstantUnion();
+    TIntermConstantUnion *rightTempConstant = right-&gt;getAsConstantUnion();
+    if (leftTempConstant &amp;&amp; rightTempConstant) {
+        typedReturnNode = leftTempConstant-&gt;fold(node-&gt;getOp(), rightTempConstant, infoSink);
+
+        if (typedReturnNode)
+            return typedReturnNode;
+    }
+
+    return node;
+}
+
+//
+// Connect two nodes through an assignment.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp; line)
+{
+    //
+    // Like adding binary math, except the conversion can only go
+    // from right to left.
+    //
+    TIntermBinary* node = new TIntermBinary(op);
+    node-&gt;setLine(line);
+
+    TIntermTyped* child = addConversion(op, left-&gt;getType(), right);
+    if (child == 0)
+        return 0;
+
+    node-&gt;setLeft(left);
+    node-&gt;setRight(child);
+    if (! node-&gt;promote(infoSink))
+        return 0;
+
+    return node;
+}
+
+//
+// Connect two nodes through an index operator, where the left node is the base
+// of an array or struct, and the right node is a direct or indirect offset.
+//
+// Returns the added node.
+// The caller should set the type of the returned node.
+//
+TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&amp; line)
+{
+    TIntermBinary* node = new TIntermBinary(op);
+    node-&gt;setLine(line);
+    node-&gt;setLeft(base);
+    node-&gt;setRight(index);
+
+    // caller should set the type
+
+    return node;
+}
+
+//
+// Add one node as the parent of another that it operates on.
+//
+// Returns the added node.
+//
+TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, const TSourceLoc&amp; line, TSymbolTable&amp; symbolTable)
+{
+    TIntermUnary* node;
+    TIntermTyped* child = childNode-&gt;getAsTyped();
+
+    if (child == 0) {
+        infoSink.info.message(EPrefixInternalError, line, &quot;Bad type in AddUnaryMath&quot;);
+        return 0;
+    }
+
+    switch (op) {
+        case EOpLogicalNot:
+            if (child-&gt;getType().getBasicType() != EbtBool || child-&gt;getType().isMatrix() || child-&gt;getType().isArray() || child-&gt;getType().isVector()) {
+                return 0;
+            }
+            break;
+
+        case EOpPostIncrement:
+        case EOpPreIncrement:
+        case EOpPostDecrement:
+        case EOpPreDecrement:
+        case EOpNegative:
+            if (child-&gt;getType().getBasicType() == EbtStruct || child-&gt;getType().isArray())
+                return 0;
+        default: break;
+    }
+
+    //
+    // Do we need to promote the operand?
+    //
+    // Note: Implicit promotions were removed from the language.
+    //
+    TBasicType newType = EbtVoid;
+    switch (op) {
+        case EOpConstructInt:   newType = EbtInt;   break;
+        case EOpConstructBool:  newType = EbtBool;  break;
+        case EOpConstructFloat: newType = EbtFloat; break;
+        default: break;
+    }
+
+    if (newType != EbtVoid) {
+        child = addConversion(op, TType(newType, child-&gt;getPrecision(), EvqTemporary,
+            child-&gt;getNominalSize(),
+            child-&gt;isMatrix(),
+            child-&gt;isArray()),
+            child);
+        if (child == 0)
+            return 0;
+    }
+
+    //
+    // For constructors, we are now done, it's all in the conversion.
+    //
+    switch (op) {
+        case EOpConstructInt:
+        case EOpConstructBool:
+        case EOpConstructFloat:
+            return child;
+        default: break;
+    }
+
+    TIntermConstantUnion *childTempConstant = 0;
+    if (child-&gt;getAsConstantUnion())
+        childTempConstant = child-&gt;getAsConstantUnion();
+
+    //
+    // Make a new node for the operator.
+    //
+    node = new TIntermUnary(op);
+    node-&gt;setLine(line);
+    node-&gt;setOperand(child);
+
+    if (! node-&gt;promote(infoSink))
+        return 0;
+
+    if (childTempConstant)  {
+        TIntermTyped* newChild = childTempConstant-&gt;fold(op, 0, infoSink);
+
+        if (newChild)
+            return newChild;
+    }
+
+    return node;
+}
+
+//
+// This is the safe way to change the operator on an aggregate, as it
+// does lots of error checking and fixing.  Especially for establishing
+// a function call's operation on it's set of parameters.  Sequences
+// of instructions are also aggregates, but they just direnctly set
+// their operator to EOpSequence.
+//
+// Returns an aggregate node, which could be the one passed in if
+// it was already an aggregate but no operator was set.
+//
+TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperator op, const TSourceLoc&amp; line)
+{
+    TIntermAggregate* aggNode;
+
+    //
+    // Make sure we have an aggregate.  If not turn it into one.
+    //
+    if (node) {
+        aggNode = node-&gt;getAsAggregate();
+        if (aggNode == 0 || aggNode-&gt;getOp() != EOpNull) {
+            //
+            // Make an aggregate containing this node.
+            //
+            aggNode = new TIntermAggregate();
+            aggNode-&gt;getSequence().push_back(node);
+        }
+    } else
+        aggNode = new TIntermAggregate();
+
+    //
+    // Set the operator.
+    //
+    aggNode-&gt;setOp(op);
+    aggNode-&gt;setLine(line);
+
+    return aggNode;
+}
+
+//
+// Convert one type to another.
+//
+// Returns the node representing the conversion, which could be the same
+// node passed in if no conversion was needed.
+//
+// Return 0 if a conversion can't be done.
+//
+TIntermTyped* TIntermediate::addConversion(TOperator op, const TType&amp; type, TIntermTyped* node)
+{
+    //
+    // Does the base type allow operation?
+    //
+    switch (node-&gt;getBasicType()) {
+        case EbtVoid:
+        case EbtSampler2D:
+        case EbtSamplerCube:
+            return 0;
+        default: break;
+    }
+
+    //
+    // Otherwise, if types are identical, no problem
+    //
+    if (type == node-&gt;getType())
+        return node;
+
+    //
+    // If one's a structure, then no conversions.
+    //
+    if (type.getStruct() || node-&gt;getType().getStruct())
+        return 0;
+
+    //
+    // If one's an array, then no conversions.
+    //
+    if (type.isArray() || node-&gt;getType().isArray())
+        return 0;
+
+    TBasicType promoteTo;
+
+    switch (op) {
+        //
+        // Explicit conversions
+        //
+        case EOpConstructBool:
+            promoteTo = EbtBool;
+            break;
+        case EOpConstructFloat:
+            promoteTo = EbtFloat;
+            break;
+        case EOpConstructInt:
+            promoteTo = EbtInt;
+            break;
+        default:
+            //
+            // implicit conversions were removed from the language.
+            //
+            if (type.getBasicType() != node-&gt;getType().getBasicType())
+                return 0;
+            //
+            // Size and structure could still differ, but that's
+            // handled by operator promotion.
+            //
+            return node;
+    }
+
+    if (node-&gt;getAsConstantUnion()) {
+
+        return (promoteConstantUnion(promoteTo, node-&gt;getAsConstantUnion()));
+    } else {
+
+        //
+        // Add a new newNode for the conversion.
+        //
+        TIntermUnary* newNode = 0;
+
+        TOperator newOp = EOpNull;
+        switch (promoteTo) {
+            case EbtFloat:
+                switch (node-&gt;getBasicType()) {
+                    case EbtInt:   newOp = EOpConvIntToFloat;  break;
+                    case EbtBool:  newOp = EOpConvBoolToFloat; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Bad promotion node&quot;);
+                        return 0;
+                }
+                break;
+            case EbtBool:
+                switch (node-&gt;getBasicType()) {
+                    case EbtInt:   newOp = EOpConvIntToBool;   break;
+                    case EbtFloat: newOp = EOpConvFloatToBool; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Bad promotion node&quot;);
+                        return 0;
+                }
+                break;
+            case EbtInt:
+                switch (node-&gt;getBasicType()) {
+                    case EbtBool:   newOp = EOpConvBoolToInt;  break;
+                    case EbtFloat:  newOp = EOpConvFloatToInt; break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Bad promotion node&quot;);
+                        return 0;
+                }
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Bad promotion type&quot;);
+                return 0;
+        }
+
+        TType type(promoteTo, node-&gt;getPrecision(), EvqTemporary, node-&gt;getNominalSize(), node-&gt;isMatrix(), node-&gt;isArray());
+        newNode = new TIntermUnary(newOp, type);
+        newNode-&gt;setLine(node-&gt;getLine());
+        newNode-&gt;setOperand(node);
+
+        return newNode;
+    }
+}
+
+//
+// Safe way to combine two nodes into an aggregate.  Works with null pointers,
+// a node that's not a aggregate yet, etc.
+//
+// Returns the resulting aggregate, unless 0 was passed in for
+// both existing nodes.
+//
+TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&amp; line)
+{
+    if (left == 0 &amp;&amp; right == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = 0;
+    if (left)
+        aggNode = left-&gt;getAsAggregate();
+    if (!aggNode || aggNode-&gt;getOp() != EOpNull) {
+        aggNode = new TIntermAggregate;
+        if (left)
+            aggNode-&gt;getSequence().push_back(left);
+    }
+
+    if (right)
+        aggNode-&gt;getSequence().push_back(right);
+
+    aggNode-&gt;setLine(line);
+
+    return aggNode;
+}
+
+//
+// Turn an existing node into an aggregate.
+//
+// Returns an aggregate, unless 0 was passed in for the existing node.
+//
+TIntermAggregate* TIntermediate::makeAggregate(TIntermNode* node, const TSourceLoc&amp; line)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggNode = new TIntermAggregate;
+    aggNode-&gt;getSequence().push_back(node);
+    aggNode-&gt;setLine(line);
+
+    return aggNode;
+}
+
+//
+// For &quot;if&quot; test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are in the
+// nodePair.
+//
+// Returns the selection node created.
+//
+TIntermNode* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc&amp; line)
+{
+    //
+    // For compile time constant selections, prune the code and
+    // test now.
+    //
+
+    if (cond-&gt;getAsTyped() &amp;&amp; cond-&gt;getAsTyped()-&gt;getAsConstantUnion()) {
+        if (cond-&gt;getAsConstantUnion()-&gt;getBConst(0) == true)
+            return nodePair.node1 ? setAggregateOperator(nodePair.node1, EOpSequence, nodePair.node1-&gt;getLine()) : NULL;
+        else
+            return nodePair.node2 ? setAggregateOperator(nodePair.node2, EOpSequence, nodePair.node2-&gt;getLine()) : NULL;
+    }
+
+    TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+
+TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp; line)
+{
+    if (left-&gt;getType().getQualifier() == EvqConst &amp;&amp; right-&gt;getType().getQualifier() == EvqConst) {
+        return right;
+    } else {
+        TIntermTyped *commaAggregate = growAggregate(left, right, line);
+        commaAggregate-&gt;getAsAggregate()-&gt;setOp(EOpComma);
+        commaAggregate-&gt;setType(right-&gt;getType());
+        commaAggregate-&gt;getTypePointer()-&gt;setQualifier(EvqTemporary);
+        return commaAggregate;
+    }
+}
+
+//
+// For &quot;?:&quot; test nodes.  There are three children; a condition,
+// a true path, and a false path.  The two paths are specified
+// as separate parameters.
+//
+// Returns the selection node created, or 0 if one could not be.
+//
+TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&amp; line)
+{
+    //
+    // Get compatible types.
+    //
+    TIntermTyped* child = addConversion(EOpSequence, trueBlock-&gt;getType(), falseBlock);
+    if (child)
+        falseBlock = child;
+    else {
+        child = addConversion(EOpSequence, falseBlock-&gt;getType(), trueBlock);
+        if (child)
+            trueBlock = child;
+        else
+            return 0;
+    }
+
+    //
+    // See if all the operands are constant, then fold it otherwise not.
+    //
+
+    if (cond-&gt;getAsConstantUnion() &amp;&amp; trueBlock-&gt;getAsConstantUnion() &amp;&amp; falseBlock-&gt;getAsConstantUnion()) {
+        if (cond-&gt;getAsConstantUnion()-&gt;getBConst(0))
+            return trueBlock;
+        else
+            return falseBlock;
+    }
+
+    //
+    // Make a selection node.
+    //
+    TIntermSelection* node = new TIntermSelection(cond, trueBlock, falseBlock, trueBlock-&gt;getType());
+    node-&gt;getTypePointer()-&gt;setQualifier(EvqTemporary);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+//
+// Constant terminal nodes.  Has a union that contains bool, float or int constants
+//
+// Returns the constant union node created.
+//
+
+TIntermConstantUnion* TIntermediate::addConstantUnion(ConstantUnion* unionArrayPointer, const TType&amp; t, const TSourceLoc&amp; line)
+{
+    TIntermConstantUnion* node = new TIntermConstantUnion(unionArrayPointer, t);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+TIntermTyped* TIntermediate::addSwizzle(TVectorFields&amp; fields, const TSourceLoc&amp; line)
+{
+
+    TIntermAggregate* node = new TIntermAggregate(EOpSequence);
+
+    node-&gt;setLine(line);
+    TIntermConstantUnion* constIntNode;
+    TIntermSequence &amp;sequenceVector = node-&gt;getSequence();
+    ConstantUnion* unionArray;
+
+    for (int i = 0; i &lt; fields.num; i++) {
+        unionArray = new ConstantUnion[1];
+        unionArray-&gt;setIConst(fields.offsets[i]);
+        constIntNode = addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), line);
+        sequenceVector.push_back(constIntNode);
+    }
+
+    return node;
+}
+
+//
+// Create loop nodes.
+//
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, const TSourceLoc&amp; line)
+{
+    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+//
+// Add branches.
+//
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, const TSourceLoc&amp; line)
+{
+    return addBranch(branchOp, 0, line);
+}
+
+TIntermBranch* TIntermediate::addBranch(TOperator branchOp, TIntermTyped* expression, const TSourceLoc&amp; line)
+{
+    TIntermBranch* node = new TIntermBranch(branchOp, expression);
+    node-&gt;setLine(line);
+
+    return node;
+}
+
+//
+// This is to be executed once the final root is put on top by the parsing
+// process.
+//
+bool TIntermediate::postProcess(TIntermNode* root)
+{
+    if (root == 0)
+        return true;
+
+    //
+    // First, finish off the top level sequence, if any
+    //
+    TIntermAggregate* aggRoot = root-&gt;getAsAggregate();
+    if (aggRoot &amp;&amp; aggRoot-&gt;getOp() == EOpNull)
+        aggRoot-&gt;setOp(EOpSequence);
+
+    return true;
+}
+
+//
+// This deletes the tree.
+//
+void TIntermediate::remove(TIntermNode* root)
+{
+    if (root)
+        RemoveAllTreeNodes(root);
+}
+
+////////////////////////////////////////////////////////////////
+//
+// Member functions of the nodes used for building the tree.
+//
+////////////////////////////////////////////////////////////////
+
+#define REPLACE_IF_IS(node, type, original, replacement) \
+    if (node == original) { \
+        node = static_cast&lt;type *&gt;(replacement); \
+        return true; \
+    }
+
+bool TIntermLoop::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(init, TIntermNode, original, replacement);
+    REPLACE_IF_IS(cond, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(expr, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(body, TIntermNode, original, replacement);
+    return false;
+}
+
+bool TIntermBranch::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(expression, TIntermTyped, original, replacement);
+    return false;
+}
+
+bool TIntermBinary::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(left, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(right, TIntermTyped, original, replacement);
+    return false;
+}
+
+bool TIntermUnary::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(operand, TIntermTyped, original, replacement);
+    return false;
+}
+
+bool TIntermAggregate::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    for (size_t ii = 0; ii &lt; sequence.size(); ++ii)
+    {
+        REPLACE_IF_IS(sequence[ii], TIntermNode, original, replacement);
+    }
+    return false;
+}
+
+bool TIntermSelection::replaceChildNode(
+    TIntermNode *original, TIntermNode *replacement)
+{
+    REPLACE_IF_IS(condition, TIntermTyped, original, replacement);
+    REPLACE_IF_IS(trueBlock, TIntermNode, original, replacement);
+    REPLACE_IF_IS(falseBlock, TIntermNode, original, replacement);
+    return false;
+}
+
+//
+// Say whether or not an operation node changes the value of a variable.
+//
+bool TIntermOperator::isAssignment() const
+{
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+        case EOpAssign:
+        case EOpAddAssign:
+        case EOpSubAssign:
+        case EOpMulAssign:
+        case EOpVectorTimesMatrixAssign:
+        case EOpVectorTimesScalarAssign:
+        case EOpMatrixTimesScalarAssign:
+        case EOpMatrixTimesMatrixAssign:
+        case EOpDivAssign:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//
+// returns true if the operator is for one of the constructors
+//
+bool TIntermOperator::isConstructor() const
+{
+    switch (op) {
+        case EOpConstructVec2:
+        case EOpConstructVec3:
+        case EOpConstructVec4:
+        case EOpConstructMat2:
+        case EOpConstructMat3:
+        case EOpConstructMat4:
+        case EOpConstructFloat:
+        case EOpConstructIVec2:
+        case EOpConstructIVec3:
+        case EOpConstructIVec4:
+        case EOpConstructInt:
+        case EOpConstructBVec2:
+        case EOpConstructBVec3:
+        case EOpConstructBVec4:
+        case EOpConstructBool:
+        case EOpConstructStruct:
+            return true;
+        default:
+            return false;
+    }
+}
+
+//
+// Make sure the type of a unary operator is appropriate for its
+// combination of operation and operand type.
+//
+// Returns false in nothing makes sense.
+//
+bool TIntermUnary::promote(TInfoSink&amp;)
+{
+    switch (op) {
+        case EOpLogicalNot:
+            if (operand-&gt;getBasicType() != EbtBool)
+                return false;
+            break;
+        case EOpNegative:
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+            if (operand-&gt;getBasicType() == EbtBool)
+                return false;
+            break;
+
+            // operators for built-ins are already type checked against their prototype
+        case EOpAny:
+        case EOpAll:
+        case EOpVectorLogicalNot:
+            return true;
+
+        default:
+            if (operand-&gt;getBasicType() != EbtFloat)
+                return false;
+    }
+
+    setType(operand-&gt;getType());
+    type.setQualifier(EvqTemporary);
+
+    return true;
+}
+
+//
+// Establishes the type of the resultant operation, as well as
+// makes the operator the correct one for the operands.
+//
+// Returns false if operator can't work on operands.
+//
+bool TIntermBinary::promote(TInfoSink&amp; infoSink)
+{
+    // This function only handles scalars, vectors, and matrices.
+    if (left-&gt;isArray() || right-&gt;isArray()) {
+        infoSink.info.message(EPrefixInternalError, getLine(), &quot;Invalid operation for arrays&quot;);
+        return false;
+    }
+
+    // GLSL ES 2.0 does not support implicit type casting.
+    // So the basic type should always match.
+    if (left-&gt;getBasicType() != right-&gt;getBasicType())
+        return false;
+
+    //
+    // Base assumption:  just make the type the same as the left
+    // operand.  Then only deviations from this need be coded.
+    //
+    setType(left-&gt;getType());
+
+    // The result gets promoted to the highest precision.
+    TPrecision higherPrecision = GetHigherPrecision(left-&gt;getPrecision(), right-&gt;getPrecision());
+    getTypePointer()-&gt;setPrecision(higherPrecision);
+
+    // Binary operations results in temporary variables unless both
+    // operands are const.
+    if (left-&gt;getQualifier() != EvqConst || right-&gt;getQualifier() != EvqConst) {
+        getTypePointer()-&gt;setQualifier(EvqTemporary);
+    }
+
+    int size = std::max(left-&gt;getNominalSize(), right-&gt;getNominalSize());
+
+    //
+    // All scalars. Code after this test assumes this case is removed!
+    //
+    if (size == 1) {
+        switch (op) {
+            //
+            // Promote to conditional
+            //
+            case EOpEqual:
+            case EOpNotEqual:
+            case EOpLessThan:
+            case EOpGreaterThan:
+            case EOpLessThanEqual:
+            case EOpGreaterThanEqual:
+                setType(TType(EbtBool, EbpUndefined));
+                break;
+
+            //
+            // And and Or operate on conditionals
+            //
+            case EOpLogicalAnd:
+            case EOpLogicalOr:
+                // Both operands must be of type bool.
+                if (left-&gt;getBasicType() != EbtBool || right-&gt;getBasicType() != EbtBool)
+                    return false;
+                setType(TType(EbtBool, EbpUndefined));
+                break;
+
+            default:
+                break;
+        }
+        return true;
+    }
+
+    // If we reach here, at least one of the operands is vector or matrix.
+    // The other operand could be a scalar, vector, or matrix.
+    // Are the sizes compatible?
+    //
+    if (left-&gt;getNominalSize() != right-&gt;getNominalSize()) {
+        // If the nominal size of operands do not match:
+        // One of them must be scalar.
+        if (left-&gt;getNominalSize() != 1 &amp;&amp; right-&gt;getNominalSize() != 1)
+            return false;
+        // Operator cannot be of type pure assignment.
+        if (op == EOpAssign || op == EOpInitialize)
+            return false;
+    }
+
+    //
+    // Can these two operands be combined?
+    //
+    TBasicType basicType = left-&gt;getBasicType();
+    switch (op) {
+        case EOpMul:
+            if (!left-&gt;isMatrix() &amp;&amp; right-&gt;isMatrix()) {
+                if (left-&gt;isVector())
+                    op = EOpVectorTimesMatrix;
+                else {
+                    op = EOpMatrixTimesScalar;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, true));
+                }
+            } else if (left-&gt;isMatrix() &amp;&amp; !right-&gt;isMatrix()) {
+                if (right-&gt;isVector()) {
+                    op = EOpMatrixTimesVector;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                } else {
+                    op = EOpMatrixTimesScalar;
+                }
+            } else if (left-&gt;isMatrix() &amp;&amp; right-&gt;isMatrix()) {
+                op = EOpMatrixTimesMatrix;
+            } else if (!left-&gt;isMatrix() &amp;&amp; !right-&gt;isMatrix()) {
+                if (left-&gt;isVector() &amp;&amp; right-&gt;isVector()) {
+                    // leave as component product
+                } else if (left-&gt;isVector() || right-&gt;isVector()) {
+                    op = EOpVectorTimesScalar;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                }
+            } else {
+                infoSink.info.message(EPrefixInternalError, getLine(), &quot;Missing elses&quot;);
+                return false;
+            }
+            break;
+        case EOpMulAssign:
+            if (!left-&gt;isMatrix() &amp;&amp; right-&gt;isMatrix()) {
+                if (left-&gt;isVector())
+                    op = EOpVectorTimesMatrixAssign;
+                else {
+                    return false;
+                }
+            } else if (left-&gt;isMatrix() &amp;&amp; !right-&gt;isMatrix()) {
+                if (right-&gt;isVector()) {
+                    return false;
+                } else {
+                    op = EOpMatrixTimesScalarAssign;
+                }
+            } else if (left-&gt;isMatrix() &amp;&amp; right-&gt;isMatrix()) {
+                op = EOpMatrixTimesMatrixAssign;
+            } else if (!left-&gt;isMatrix() &amp;&amp; !right-&gt;isMatrix()) {
+                if (left-&gt;isVector() &amp;&amp; right-&gt;isVector()) {
+                    // leave as component product
+                } else if (left-&gt;isVector() || right-&gt;isVector()) {
+                    if (! left-&gt;isVector())
+                        return false;
+                    op = EOpVectorTimesScalarAssign;
+                    setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
+                }
+            } else {
+                infoSink.info.message(EPrefixInternalError, getLine(), &quot;Missing elses&quot;);
+                return false;
+            }
+            break;
+
+        case EOpAssign:
+        case EOpInitialize:
+        case EOpAdd:
+        case EOpSub:
+        case EOpDiv:
+        case EOpAddAssign:
+        case EOpSubAssign:
+        case EOpDivAssign:
+            if ((left-&gt;isMatrix() &amp;&amp; right-&gt;isVector()) ||
+                (left-&gt;isVector() &amp;&amp; right-&gt;isMatrix()))
+                return false;
+            setType(TType(basicType, higherPrecision, EvqTemporary, size, left-&gt;isMatrix() || right-&gt;isMatrix()));
+            break;
+
+        case EOpEqual:
+        case EOpNotEqual:
+        case EOpLessThan:
+        case EOpGreaterThan:
+        case EOpLessThanEqual:
+        case EOpGreaterThanEqual:
+            if ((left-&gt;isMatrix() &amp;&amp; right-&gt;isVector()) ||
+                (left-&gt;isVector() &amp;&amp; right-&gt;isMatrix()))
+                return false;
+            setType(TType(EbtBool, EbpUndefined));
+            break;
+
+        default:
+            return false;
+    }
+    
+    return true;
+}
+
+bool CompareStruct(const TType&amp; leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
+{
+    const TFieldList&amp; fields = leftNodeType.getStruct()-&gt;fields();
+
+    size_t structSize = fields.size();
+    size_t index = 0;
+
+    for (size_t j = 0; j &lt; structSize; j++) {
+        size_t size = fields[j]-&gt;type()-&gt;getObjectSize();
+        for (size_t i = 0; i &lt; size; i++) {
+            if (fields[j]-&gt;type()-&gt;getBasicType() == EbtStruct) {
+                if (!CompareStructure(*(fields[j]-&gt;type()), &amp;rightUnionArray[index], &amp;leftUnionArray[index]))
+                    return false;
+            } else {
+                if (leftUnionArray[index] != rightUnionArray[index])
+                    return false;
+                index++;
+            }
+        }
+    }
+    return true;
+}
+
+bool CompareStructure(const TType&amp; leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
+{
+    if (leftNodeType.isArray()) {
+        TType typeWithoutArrayness = leftNodeType;
+        typeWithoutArrayness.clearArrayness();
+
+        size_t arraySize = leftNodeType.getArraySize();
+
+        for (size_t i = 0; i &lt; arraySize; ++i) {
+            size_t offset = typeWithoutArrayness.getObjectSize() * i;
+            if (!CompareStruct(typeWithoutArrayness, &amp;rightUnionArray[offset], &amp;leftUnionArray[offset]))
+                return false;
+        }
+    } else
+        return CompareStruct(leftNodeType, rightUnionArray, leftUnionArray);
+
+    return true;
+}
+
+//
+// The fold functions see if an operation on a constant can be done in place,
+// without generating run-time code.
+//
+// Returns the node to keep using, which may or may not be the node passed in.
+//
+
+TIntermTyped* TIntermConstantUnion::fold(TOperator op, TIntermTyped* constantNode, TInfoSink&amp; infoSink)
+{
+    ConstantUnion *unionArray = getUnionArrayPointer();
+    size_t objectSize = getType().getObjectSize();
+
+    if (constantNode) {  // binary operations
+        TIntermConstantUnion *node = constantNode-&gt;getAsConstantUnion();
+        ConstantUnion *rightUnionArray = node-&gt;getUnionArrayPointer();
+        TType returnType = getType();
+
+        // for a case like float f = 1.2 + vec4(2,3,4,5);
+        if (constantNode-&gt;getType().getObjectSize() == 1 &amp;&amp; objectSize &gt; 1) {
+            rightUnionArray = new ConstantUnion[objectSize];
+            for (size_t i = 0; i &lt; objectSize; ++i)
+                rightUnionArray[i] = *node-&gt;getUnionArrayPointer();
+            returnType = getType();
+        } else if (constantNode-&gt;getType().getObjectSize() &gt; 1 &amp;&amp; objectSize == 1) {
+            // for a case like float f = vec4(2,3,4,5) + 1.2;
+            unionArray = new ConstantUnion[constantNode-&gt;getType().getObjectSize()];
+            for (size_t i = 0; i &lt; constantNode-&gt;getType().getObjectSize(); ++i)
+                unionArray[i] = *getUnionArrayPointer();
+            returnType = node-&gt;getType();
+            objectSize = constantNode-&gt;getType().getObjectSize();
+        }
+
+        ConstantUnion* tempConstArray = 0;
+        TIntermConstantUnion *tempNode;
+
+        bool boolNodeFlag = false;
+        switch(op) {
+            case EOpAdd:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        tempConstArray[i] = unionArray[i] + rightUnionArray[i];
+                }
+                break;
+            case EOpSub:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        tempConstArray[i] = unionArray[i] - rightUnionArray[i];
+                }
+                break;
+
+            case EOpMul:
+            case EOpVectorTimesScalar:
+            case EOpMatrixTimesScalar:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        tempConstArray[i] = unionArray[i] * rightUnionArray[i];
+                }
+                break;
+            case EOpMatrixTimesMatrix:
+                if (getType().getBasicType() != EbtFloat || node-&gt;getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, getLine(), &quot;Constant Folding cannot be done for matrix multiply&quot;);
+                    return 0;
+                }
+                {// support MSVC++6.0
+                    int size = getNominalSize();
+                    tempConstArray = new ConstantUnion[size*size];
+                    for (int row = 0; row &lt; size; row++) {
+                        for (int column = 0; column &lt; size; column++) {
+                            tempConstArray[size * column + row].setFConst(0.0f);
+                            for (int i = 0; i &lt; size; i++) {
+                                tempConstArray[size * column + row].setFConst(tempConstArray[size * column + row].getFConst() + unionArray[i * size + row].getFConst() * (rightUnionArray[column * size + i].getFConst()));
+                            }
+                        }
+                    }
+                }
+                break;
+            case EOpDiv:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++) {
+                        switch (getType().getBasicType()) {
+            case EbtFloat:
+                if (rightUnionArray[i] == 0.0f) {
+                    infoSink.info.message(EPrefixWarning, getLine(), &quot;Divide by zero error during constant folding&quot;);
+                    tempConstArray[i].setFConst(unionArray[i].getFConst() &lt; 0 ? -FLT_MAX : FLT_MAX);
+                } else
+                    tempConstArray[i].setFConst(unionArray[i].getFConst() / rightUnionArray[i].getFConst());
+                break;
+
+            case EbtInt:
+                if (rightUnionArray[i] == 0) {
+                    infoSink.info.message(EPrefixWarning, getLine(), &quot;Divide by zero error during constant folding&quot;);
+                    tempConstArray[i].setIConst(INT_MAX);
+                } else
+                    tempConstArray[i].setIConst(unionArray[i].getIConst() / rightUnionArray[i].getIConst());
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, getLine(), &quot;Constant folding cannot be done for \&quot;/\&quot;&quot;);
+                return 0;
+                        }
+                    }
+                }
+                break;
+
+            case EOpMatrixTimesVector:
+                if (node-&gt;getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, getLine(), &quot;Constant Folding cannot be done for matrix times vector&quot;);
+                    return 0;
+                }
+                tempConstArray = new ConstantUnion[getNominalSize()];
+
+                {// support MSVC++6.0
+                    for (int size = getNominalSize(), i = 0; i &lt; size; i++) {
+                        tempConstArray[i].setFConst(0.0f);
+                        for (int j = 0; j &lt; size; j++) {
+                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j*size + i].getFConst()) * rightUnionArray[j].getFConst()));
+                        }
+                    }
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, node-&gt;getType());
+                tempNode-&gt;setLine(getLine());
+
+                return tempNode;
+
+            case EOpVectorTimesMatrix:
+                if (getType().getBasicType() != EbtFloat) {
+                    infoSink.info.message(EPrefixInternalError, getLine(), &quot;Constant Folding cannot be done for vector times matrix&quot;);
+                    return 0;
+                }
+
+                tempConstArray = new ConstantUnion[getNominalSize()];
+                {// support MSVC++6.0
+                    for (int size = getNominalSize(), i = 0; i &lt; size; i++) {
+                        tempConstArray[i].setFConst(0.0f);
+                        for (int j = 0; j &lt; size; j++) {
+                            tempConstArray[i].setFConst(tempConstArray[i].getFConst() + ((unionArray[j].getFConst()) * rightUnionArray[i*size + j].getFConst()));
+                        }
+                    }
+                }
+                break;
+
+            case EOpLogicalAnd: // this code is written for possible future use, will not get executed currently
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        tempConstArray[i] = unionArray[i] &amp;&amp; rightUnionArray[i];
+                }
+                break;
+
+            case EOpLogicalOr: // this code is written for possible future use, will not get executed currently
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        tempConstArray[i] = unionArray[i] || rightUnionArray[i];
+                }
+                break;
+
+            case EOpLogicalXor:
+                tempConstArray = new ConstantUnion[objectSize];
+                {// support MSVC++6.0
+                    for (size_t i = 0; i &lt; objectSize; i++)
+                        switch (getType().getBasicType()) {
+            case EbtBool: tempConstArray[i].setBConst((unionArray[i] == rightUnionArray[i]) ? false : true); break;
+            default: assert(false &amp;&amp; &quot;Default missing&quot;);
+                    }
+                }
+                break;
+
+            case EOpLessThan:
+                assert(objectSize == 1);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray-&gt;setBConst(*unionArray &lt; *rightUnionArray);
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            case EOpGreaterThan:
+                assert(objectSize == 1);
+                tempConstArray = new ConstantUnion[1];
+                tempConstArray-&gt;setBConst(*unionArray &gt; *rightUnionArray);
+                returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                break;
+            case EOpLessThanEqual:
+                {
+                    assert(objectSize == 1);
+                    ConstantUnion constant;
+                    constant.setBConst(*unionArray &gt; *rightUnionArray);
+                    tempConstArray = new ConstantUnion[1];
+                    tempConstArray-&gt;setBConst(!constant.getBConst());
+                    returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                    break;
+                }
+            case EOpGreaterThanEqual:
+                {
+                    assert(objectSize == 1);
+                    ConstantUnion constant;
+                    constant.setBConst(*unionArray &lt; *rightUnionArray);
+                    tempConstArray = new ConstantUnion[1];
+                    tempConstArray-&gt;setBConst(!constant.getBConst());
+                    returnType = TType(EbtBool, EbpUndefined, EvqConst);
+                    break;
+                }
+
+            case EOpEqual:
+                if (getType().getBasicType() == EbtStruct) {
+                    if (!CompareStructure(node-&gt;getType(), node-&gt;getUnionArrayPointer(), unionArray))
+                        boolNodeFlag = true;
+                } else {
+                    for (size_t i = 0; i &lt; objectSize; i++) {
+                        if (unionArray[i] != rightUnionArray[i]) {
+                            boolNodeFlag = true;
+                            break;  // break out of for loop
+                        }
+                    }
+                }
+
+                tempConstArray = new ConstantUnion[1];
+                if (!boolNodeFlag) {
+                    tempConstArray-&gt;setBConst(true);
+                }
+                else {
+                    tempConstArray-&gt;setBConst(false);
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+                tempNode-&gt;setLine(getLine());
+
+                return tempNode;
+
+            case EOpNotEqual:
+                if (getType().getBasicType() == EbtStruct) {
+                    if (CompareStructure(node-&gt;getType(), node-&gt;getUnionArrayPointer(), unionArray))
+                        boolNodeFlag = true;
+                } else {
+                    for (size_t i = 0; i &lt; objectSize; i++) {
+                        if (unionArray[i] == rightUnionArray[i]) {
+                            boolNodeFlag = true;
+                            break;  // break out of for loop
+                        }
+                    }
+                }
+
+                tempConstArray = new ConstantUnion[1];
+                if (!boolNodeFlag) {
+                    tempConstArray-&gt;setBConst(true);
+                }
+                else {
+                    tempConstArray-&gt;setBConst(false);
+                }
+
+                tempNode = new TIntermConstantUnion(tempConstArray, TType(EbtBool, EbpUndefined, EvqConst));
+                tempNode-&gt;setLine(getLine());
+
+                return tempNode;
+
+            default:
+                infoSink.info.message(EPrefixInternalError, getLine(), &quot;Invalid operator for constant folding&quot;);
+                return 0;
+        }
+        tempNode = new TIntermConstantUnion(tempConstArray, returnType);
+        tempNode-&gt;setLine(getLine());
+
+        return tempNode;
+    } else {
+        //
+        // Do unary operations
+        //
+        TIntermConstantUnion *newNode = 0;
+        ConstantUnion* tempConstArray = new ConstantUnion[objectSize];
+        for (size_t i = 0; i &lt; objectSize; i++) {
+            switch(op) {
+                case EOpNegative:
+                    switch (getType().getBasicType()) {
+                        case EbtFloat: tempConstArray[i].setFConst(-unionArray[i].getFConst()); break;
+                        case EbtInt:   tempConstArray[i].setIConst(-unionArray[i].getIConst()); break;
+                        default:
+                            infoSink.info.message(EPrefixInternalError, getLine(), &quot;Unary operation not folded into constant&quot;);
+                            return 0;
+                    }
+                    break;
+                case EOpLogicalNot: // this code is written for possible future use, will not get executed currently
+                    switch (getType().getBasicType()) {
+                        case EbtBool:  tempConstArray[i].setBConst(!unionArray[i].getBConst()); break;
+                        default:
+                            infoSink.info.message(EPrefixInternalError, getLine(), &quot;Unary operation not folded into constant&quot;);
+                            return 0;
+                    }
+                    break;
+                default:
+                    return 0;
+            }
+        }
+        newNode = new TIntermConstantUnion(tempConstArray, getType());
+        newNode-&gt;setLine(getLine());
+        return newNode;
+    }
+}
+
+TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermConstantUnion* node)
+{
+    size_t size = node-&gt;getType().getObjectSize();
+
+    ConstantUnion *leftUnionArray = new ConstantUnion[size];
+
+    for (size_t i = 0; i &lt; size; i++) {
+
+        switch (promoteTo) {
+            case EbtFloat:
+                switch (node-&gt;getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i].setFConst(static_cast&lt;float&gt;(node-&gt;getIConst(i)));
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i].setFConst(static_cast&lt;float&gt;(node-&gt;getBConst(i)));
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i].setFConst(static_cast&lt;float&gt;(node-&gt;getFConst(i)));
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Cannot promote&quot;);
+                        return 0;
+                }
+                break;
+            case EbtInt:
+                switch (node-&gt;getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i].setIConst(static_cast&lt;int&gt;(node-&gt;getIConst(i)));
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i].setIConst(static_cast&lt;int&gt;(node-&gt;getBConst(i)));
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i].setIConst(static_cast&lt;int&gt;(node-&gt;getFConst(i)));
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Cannot promote&quot;);
+                        return 0;
+                }
+                break;
+            case EbtBool:
+                switch (node-&gt;getType().getBasicType()) {
+                    case EbtInt:
+                        leftUnionArray[i].setBConst(node-&gt;getIConst(i) != 0);
+                        break;
+                    case EbtBool:
+                        leftUnionArray[i].setBConst(node-&gt;getBConst(i));
+                        break;
+                    case EbtFloat:
+                        leftUnionArray[i].setBConst(node-&gt;getFConst(i) != 0.0f);
+                        break;
+                    default:
+                        infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Cannot promote&quot;);
+                        return 0;
+                }
+
+                break;
+            default:
+                infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Incorrect data type found&quot;);
+                return 0;
+        }
+
+    }
+
+    const TType&amp; t = node-&gt;getType();
+
+    return addConstantUnion(leftUnionArray, TType(promoteTo, t.getPrecision(), t.getQualifier(), t.getNominalSize(), t.isMatrix(), t.isArray()), node-&gt;getLine());
+}
+
+// static
+TString TIntermTraverser::hash(const TString&amp; name, ShHashFunction64 hashFunction)
+{
+    if (hashFunction == NULL || name.empty())
+        return name;
+    khronos_uint64_t number = (*hashFunction)(name.c_str(), name.length());
+    TStringStream stream;
+    stream &lt;&lt; HASHED_NAME_PREFIX &lt;&lt; std::hex &lt;&lt; number;
+    TString hashedName = stream.str();
+    return hashedName;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Intermediate.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorMMaph"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MMap.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MMap.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MMap.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _MMAP_INCLUDED_
+#define _MMAP_INCLUDED_
+
+//
+// Encapsulate memory mapped files
+//
+
+class TMMap {
+public:
+    TMMap(const char* fileName) : 
+        fSize(-1), // -1 is the error value returned by GetFileSize()
+        fp(NULL),
+        fBuff(0)   // 0 is the error value returned by MapViewOfFile()
+    {
+        if ((fp = fopen(fileName, &quot;r&quot;)) == NULL)
+            return;
+        char c = getc(fp);
+        fSize = 0;
+        while (c != EOF) {
+            fSize++;
+            c = getc(fp);
+        }
+        if (c == EOF)
+            fSize++;
+        rewind(fp);
+        fBuff = (char*)malloc(sizeof(char) * fSize);
+        int count = 0;
+        c = getc(fp);
+        while (c != EOF) {
+            fBuff[count++] = c;
+            c = getc(fp);
+        }
+        fBuff[count++] = c;
+    }
+
+    char* getData() { return fBuff; }
+    int   getSize() { return fSize; }
+
+    ~TMMap() {
+        if (fp != NULL)
+            fclose(fp);
+    }
+    
+private:
+    int             fSize;      // size of file to map in
+    FILE *fp;
+    char*           fBuff;      // the actual data;
+};
+
+#endif // _MMAP_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MMap.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorMapLongVariableNamescpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,115 @@
</span><ins>+//
+// 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 &quot;compiler/translator/MapLongVariableNames.h&quot;
+
+namespace {
+
+TString mapLongName(size_t id, const TString&amp; name, bool isGlobal)
+{
+    ASSERT(name.size() &gt; MAX_SHORTENED_IDENTIFIER_SIZE);
+    TStringStream stream;
+    stream &lt;&lt; &quot;webgl_&quot;;
+    if (isGlobal)
+        stream &lt;&lt; &quot;g&quot;;
+    stream &lt;&lt; id;
+    if (name[0] != '_')
+        stream &lt;&lt; &quot;_&quot;;
+    stream &lt;&lt; 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-&gt;refCount++;
+    return gLongNameMapInstance;
+}
+
+void LongNameMap::Release()
+{
+    ASSERT(gLongNameMapInstance == this);
+    ASSERT(refCount &gt; 0);
+    refCount--;
+    if (refCount == 0) {
+        delete gLongNameMapInstance;
+        gLongNameMapInstance = NULL;
+    }
+}
+
+const char* LongNameMap::Find(const char* originalName) const
+{
+    std::map&lt;std::string, std::string&gt;::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&lt;std::string, std::string&gt;::value_type(
+        originalName, mappedName));
+}
+
+size_t LongNameMap::Size() const
+{
+    return mLongNameMap.size();
+}
+
+MapLongVariableNames::MapLongVariableNames(LongNameMap* globalMap)
+{
+    ASSERT(globalMap);
+    mGlobalMap = globalMap;
+}
+
+void MapLongVariableNames::visitSymbol(TIntermSymbol* symbol)
+{
+    ASSERT(symbol != NULL);
+    if (symbol-&gt;getSymbol().size() &gt; MAX_SHORTENED_IDENTIFIER_SIZE) {
+        switch (symbol-&gt;getQualifier()) {
+          case EvqVaryingIn:
+          case EvqVaryingOut:
+          case EvqInvariantVaryingIn:
+          case EvqInvariantVaryingOut:
+          case EvqUniform:
+            symbol-&gt;setSymbol(
+                mapGlobalLongName(symbol-&gt;getSymbol()));
+            break;
+          default:
+            symbol-&gt;setSymbol(
+                mapLongName(symbol-&gt;getId(), symbol-&gt;getSymbol(), false));
+            break;
+        };
+    }
+}
+
+TString MapLongVariableNames::mapGlobalLongName(const TString&amp; name)
+{
+    ASSERT(mGlobalMap);
+    const char* mappedName = mGlobalMap-&gt;Find(name.c_str());
+    if (mappedName != NULL)
+        return mappedName;
+    size_t id = mGlobalMap-&gt;Size();
+    TString rt = mapLongName(id, name, true);
+    mGlobalMap-&gt;Insert(name.c_str(), rt.c_str());
+    return rt;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorMapLongVariableNamesh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+//
+// 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 &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/VariableInfo.h&quot;
+
+// 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 &lt;originalName, mappedName&gt; 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.
+    size_t Size() const;
+
+private:
+    LongNameMap();
+    ~LongNameMap();
+
+    size_t refCount;
+    std::map&lt;std::string, std::string&gt; 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 void visitSymbol(TIntermSymbol*);
+
+private:
+    TString mapGlobalLongName(const TString&amp; name);
+
+    LongNameMap* mGlobalMap;
+};
+
+#endif  // COMPILER_MAP_LONG_VARIABLE_NAMES_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/MapLongVariableNames.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorNodeSearchh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,80 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// NodeSearch.h: Utilities for searching translator node graphs
+//
+
+#ifndef TRANSLATOR_NODESEARCH_H_
+#define TRANSLATOR_NODESEARCH_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+namespace sh
+{
+
+template &lt;class Parent&gt;
+class NodeSearchTraverser : public TIntermTraverser
+{
+  public:
+    NodeSearchTraverser()
+        : mFound(false)
+    {}
+
+    bool found() const { return mFound; }
+
+    static bool search(TIntermNode *node)
+    {
+        Parent searchTraverser;
+        node-&gt;traverse(&amp;searchTraverser);
+        return searchTraverser.found();
+    }
+
+  protected:
+    bool mFound;
+};
+
+class FindDiscard : public NodeSearchTraverser&lt;FindDiscard&gt;
+{
+  public:
+    virtual bool visitBranch(Visit visit, TIntermBranch *node)
+    {
+        switch (node-&gt;getFlowOp())
+        {
+          case EOpKill:
+            mFound = true;
+            break;
+
+          default: break;
+        }
+
+        return !mFound;
+    }
+};
+
+class FindSideEffectRewriting : public NodeSearchTraverser&lt;FindSideEffectRewriting&gt;
+{
+  public:
+    virtual bool visitBinary(Visit visit, TIntermBinary *node)
+    {
+        switch (node-&gt;getOp())
+        {
+          case EOpLogicalOr:
+          case EOpLogicalAnd:
+            if (node-&gt;getRight()-&gt;hasSideEffects())
+            {
+                mFound = true;
+            }
+            break;
+
+          default: break;
+        }
+
+        return !mFound;
+    }
+};
+
+}
+
+#endif // TRANSLATOR_NODESEARCH_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/NodeSearch.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputESSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+//
+// 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 &quot;compiler/translator/OutputESSL.h&quot;
+
+TOutputESSL::TOutputESSL(TInfoSinkBase&amp; objSink,
+                         ShArrayIndexClampingStrategy clampingStrategy,
+                         ShHashFunction64 hashFunction,
+                         NameMap&amp; nameMap,
+                         TSymbolTable&amp; symbolTable)
+    : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
+{
+}
+
+bool TOutputESSL::writeVariablePrecision(TPrecision precision)
+{
+    if (precision == EbpUndefined)
+        return false;
+
+    TInfoSinkBase&amp; out = objSink();
+    out &lt;&lt; getPrecisionString(precision);
+    return true;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputESSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+//
+// 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 &quot;compiler/translator/OutputGLSLBase.h&quot;
+
+class TOutputESSL : public TOutputGLSLBase
+{
+public:
+    TOutputESSL(TInfoSinkBase&amp; objSink,
+                ShArrayIndexClampingStrategy clampingStrategy,
+                ShHashFunction64 hashFunction,
+                NameMap&amp; nameMap,
+                TSymbolTable&amp; symbolTable);
+
+protected:
+    virtual bool writeVariablePrecision(TPrecision precision);
+};
+
+#endif  // CROSSCOMPILERGLSL_OUTPUTESSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputESSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+//
+// 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 &quot;compiler/translator/OutputGLSL.h&quot;
+
+TOutputGLSL::TOutputGLSL(TInfoSinkBase&amp; objSink,
+                         ShArrayIndexClampingStrategy clampingStrategy,
+                         ShHashFunction64 hashFunction,
+                         NameMap&amp; nameMap,
+                         TSymbolTable&amp; symbolTable)
+    : TOutputGLSLBase(objSink, clampingStrategy, hashFunction, nameMap, symbolTable)
+{
+}
+
+bool TOutputGLSL::writeVariablePrecision(TPrecision)
+{
+    return false;
+}
+
+void TOutputGLSL::visitSymbol(TIntermSymbol* node)
+{
+    TInfoSinkBase&amp; out = objSink();
+
+    if (node-&gt;getSymbol() == &quot;gl_FragDepthEXT&quot;)
+    {
+        out &lt;&lt; &quot;gl_FragDepth&quot;;
+    }
+    else
+    {
+        TOutputGLSLBase::visitSymbol(node);
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+//
+// 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_OUTPUTGLSL_H_
+#define CROSSCOMPILERGLSL_OUTPUTGLSL_H_
+
+#include &quot;compiler/translator/OutputGLSLBase.h&quot;
+
+class TOutputGLSL : public TOutputGLSLBase
+{
+public:
+    TOutputGLSL(TInfoSinkBase&amp; objSink,
+                ShArrayIndexClampingStrategy clampingStrategy,
+                ShHashFunction64 hashFunction,
+                NameMap&amp; nameMap,
+                TSymbolTable&amp; symbolTable);
+
+protected:
+    virtual bool writeVariablePrecision(TPrecision);
+    virtual void visitSymbol(TIntermSymbol* node);
+};
+
+#endif  // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLBasecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,817 @@
</span><ins>+//
+// 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 &quot;compiler/translator/OutputGLSLBase.h&quot;
+#include &quot;compiler/translator/compilerdebug.h&quot;
+
+#include &lt;cfloat&gt;
+
+namespace
+{
+TString arrayBrackets(const TType&amp; type)
+{
+    ASSERT(type.isArray());
+    TInfoSinkBase out;
+    out &lt;&lt; &quot;[&quot; &lt;&lt; type.getArraySize() &lt;&lt; &quot;]&quot;;
+    return TString(out.c_str());
+}
+
+bool isSingleStatement(TIntermNode* node) {
+    if (const TIntermAggregate* aggregate = node-&gt;getAsAggregate())
+    {
+        return (aggregate-&gt;getOp() != EOpFunction) &amp;&amp;
+               (aggregate-&gt;getOp() != EOpSequence);
+    }
+    else if (const TIntermSelection* selection = node-&gt;getAsSelectionNode())
+    {
+        // Ternary operators are usually part of an assignment operator.
+        // This handles those rare cases in which they are all by themselves.
+        return selection-&gt;usesTernaryOperator();
+    }
+    else if (node-&gt;getAsLoopNode())
+    {
+        return false;
+    }
+    return true;
+}
+}  // namespace
+
+TOutputGLSLBase::TOutputGLSLBase(TInfoSinkBase&amp; objSink,
+                                 ShArrayIndexClampingStrategy clampingStrategy,
+                                 ShHashFunction64 hashFunction,
+                                 NameMap&amp; nameMap,
+                                 TSymbolTable&amp; symbolTable)
+    : TIntermTraverser(true, true, true),
+      mObjSink(objSink),
+      mDeclaringVariables(false),
+      mClampingStrategy(clampingStrategy),
+      mHashFunction(hashFunction),
+      mNameMap(nameMap),
+      mSymbolTable(symbolTable)
+{
+}
+
+void TOutputGLSLBase::writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr)
+{
+    TInfoSinkBase&amp; out = objSink();
+    if (visit == PreVisit &amp;&amp; preStr)
+    {
+        out &lt;&lt; preStr;
+    }
+    else if (visit == InVisit &amp;&amp; inStr)
+    {
+        out &lt;&lt; inStr;
+    }
+    else if (visit == PostVisit &amp;&amp; postStr)
+    {
+        out &lt;&lt; postStr;
+    }
+}
+
+void TOutputGLSLBase::writeVariableType(const TType&amp; type)
+{
+    TInfoSinkBase&amp; out = objSink();
+    TQualifier qualifier = type.getQualifier();
+    // TODO(alokp): Validate qualifier for variable declarations.
+    if ((qualifier != EvqTemporary) &amp;&amp; (qualifier != EvqGlobal))
+        out &lt;&lt; type.getQualifierString() &lt;&lt; &quot; &quot;;
+    // Declare the struct if we have not done so already.
+    if ((type.getBasicType() == EbtStruct) &amp;&amp; !structDeclared(type.getStruct()))
+    {
+        declareStruct(type.getStruct());
+    }
+    else
+    {
+        if (writeVariablePrecision(type.getPrecision()))
+            out &lt;&lt; &quot; &quot;;
+        out &lt;&lt; getTypeName(type);
+    }
+}
+
+void TOutputGLSLBase::writeFunctionParameters(const TIntermSequence&amp; args)
+{
+    TInfoSinkBase&amp; out = objSink();
+    for (TIntermSequence::const_iterator iter = args.begin();
+         iter != args.end(); ++iter)
+    {
+        const TIntermSymbol* arg = (*iter)-&gt;getAsSymbolNode();
+        ASSERT(arg != NULL);
+
+        const TType&amp; type = arg-&gt;getType();
+        writeVariableType(type);
+
+        const TString&amp; name = arg-&gt;getSymbol();
+        if (!name.empty())
+            out &lt;&lt; &quot; &quot; &lt;&lt; hashName(name);
+        if (type.isArray())
+            out &lt;&lt; arrayBrackets(type);
+
+        // Put a comma if this is not the last argument.
+        if (iter != args.end() - 1)
+            out &lt;&lt; &quot;, &quot;;
+    }
+}
+
+const ConstantUnion* TOutputGLSLBase::writeConstantUnion(const TType&amp; type,
+                                                         const ConstantUnion* pConstUnion)
+{
+    TInfoSinkBase&amp; out = objSink();
+
+    if (type.getBasicType() == EbtStruct)
+    {
+        const TStructure* structure = type.getStruct();
+        out &lt;&lt; hashName(structure-&gt;name()) &lt;&lt; &quot;(&quot;;
+
+        const TFieldList&amp; fields = structure-&gt;fields();
+        for (size_t i = 0; i &lt; fields.size(); ++i)
+        {
+            const TType* fieldType = fields[i]-&gt;type();
+            ASSERT(fieldType != NULL);
+            pConstUnion = writeConstantUnion(*fieldType, pConstUnion);
+            if (i != fields.size() - 1) out &lt;&lt; &quot;, &quot;;
+        }
+        out &lt;&lt; &quot;)&quot;;
+    }
+    else
+    {
+        size_t size = type.getObjectSize();
+        bool writeType = size &gt; 1;
+        if (writeType) out &lt;&lt; getTypeName(type) &lt;&lt; &quot;(&quot;;
+        for (size_t i = 0; i &lt; size; ++i, ++pConstUnion)
+        {
+            switch (pConstUnion-&gt;getType())
+            {
+                case EbtFloat: out &lt;&lt; std::min(FLT_MAX, std::max(-FLT_MAX, pConstUnion-&gt;getFConst())); break;
+                case EbtInt: out &lt;&lt; pConstUnion-&gt;getIConst(); break;
+                case EbtBool: out &lt;&lt; pConstUnion-&gt;getBConst(); break;
+                default: UNREACHABLE();
+            }
+            if (i != size - 1) out &lt;&lt; &quot;, &quot;;
+        }
+        if (writeType) out &lt;&lt; &quot;)&quot;;
+    }
+    return pConstUnion;
+}
+
+void TOutputGLSLBase::visitSymbol(TIntermSymbol* node)
+{
+    TInfoSinkBase&amp; out = objSink();
+    if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
+        out &lt;&lt; mLoopUnroll.GetLoopIndexValue(node);
+    else
+        out &lt;&lt; hashVariableName(node-&gt;getSymbol());
+
+    if (mDeclaringVariables &amp;&amp; node-&gt;getType().isArray())
+        out &lt;&lt; arrayBrackets(node-&gt;getType());
+}
+
+void TOutputGLSLBase::visitConstantUnion(TIntermConstantUnion* node)
+{
+    writeConstantUnion(node-&gt;getType(), node-&gt;getUnionArrayPointer());
+}
+
+bool TOutputGLSLBase::visitBinary(Visit visit, TIntermBinary* node)
+{
+    bool visitChildren = true;
+    TInfoSinkBase&amp; out = objSink();
+    switch (node-&gt;getOp())
+    {
+        case EOpInitialize:
+            if (visit == InVisit)
+            {
+                out &lt;&lt; &quot; = &quot;;
+                // RHS of initialize is not being declared.
+                mDeclaringVariables = false;
+            }
+            break;
+        case EOpAssign: writeTriplet(visit, &quot;(&quot;, &quot; = &quot;, &quot;)&quot;); break;
+        case EOpAddAssign: writeTriplet(visit, &quot;(&quot;, &quot; += &quot;, &quot;)&quot;); break;
+        case EOpSubAssign: writeTriplet(visit, &quot;(&quot;, &quot; -= &quot;, &quot;)&quot;); break;
+        case EOpDivAssign: writeTriplet(visit, &quot;(&quot;, &quot; /= &quot;, &quot;)&quot;); break;
+        // Notice the fall-through.
+        case EOpMulAssign: 
+        case EOpVectorTimesMatrixAssign:
+        case EOpVectorTimesScalarAssign:
+        case EOpMatrixTimesScalarAssign:
+        case EOpMatrixTimesMatrixAssign:
+            writeTriplet(visit, &quot;(&quot;, &quot; *= &quot;, &quot;)&quot;);
+            break;
+
+        case EOpIndexDirect:
+            writeTriplet(visit, NULL, &quot;[&quot;, &quot;]&quot;);
+            break;
+        case EOpIndexIndirect:
+            if (node-&gt;getAddIndexClamp())
+            {
+                if (visit == InVisit)
+                {
+                    if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+                        out &lt;&lt; &quot;[int(clamp(float(&quot;;
+                    } else {
+                        out &lt;&lt; &quot;[webgl_int_clamp(&quot;;
+                    }
+                }
+                else if (visit == PostVisit)
+                {
+                    int maxSize;
+                    TIntermTyped *left = node-&gt;getLeft();
+                    TType leftType = left-&gt;getType();
+
+                    if (left-&gt;isArray())
+                    {
+                        // The shader will fail validation if the array length is not &gt; 0.
+                        maxSize = leftType.getArraySize() - 1;
+                    }
+                    else
+                    {
+                        maxSize = leftType.getNominalSize() - 1;
+                    }
+
+                    if (mClampingStrategy == SH_CLAMP_WITH_CLAMP_INTRINSIC) {
+                        out &lt;&lt; &quot;), 0.0, float(&quot; &lt;&lt; maxSize &lt;&lt; &quot;)))]&quot;;
+                    } else {
+                        out &lt;&lt; &quot;, 0, &quot; &lt;&lt; maxSize &lt;&lt; &quot;)]&quot;;
+                    }
+                }
+            }
+            else
+            {
+                writeTriplet(visit, NULL, &quot;[&quot;, &quot;]&quot;);
+            }
+            break;
+        case EOpIndexDirectStruct:
+            if (visit == InVisit)
+            {
+                // Here we are writing out &quot;foo.bar&quot;, where &quot;foo&quot; is struct
+                // and &quot;bar&quot; is field. In AST, it is represented as a binary
+                // node, where left child represents &quot;foo&quot; and right child &quot;bar&quot;.
+                // The node itself represents &quot;.&quot;. The struct field &quot;bar&quot; is
+                // actually stored as an index into TStructure::fields.
+                out &lt;&lt; &quot;.&quot;;
+                const TStructure* structure = node-&gt;getLeft()-&gt;getType().getStruct();
+                const TIntermConstantUnion* index = node-&gt;getRight()-&gt;getAsConstantUnion();
+                const TField* field = structure-&gt;fields()[index-&gt;getIConst(0)];
+
+                TString fieldName = field-&gt;name();
+                if (!mSymbolTable.findBuiltIn(structure-&gt;name()))
+                    fieldName = hashName(fieldName);
+
+                out &lt;&lt; fieldName;
+                visitChildren = false;
+            }
+            break;
+        case EOpVectorSwizzle:
+            if (visit == InVisit)
+            {
+                out &lt;&lt; &quot;.&quot;;
+                TIntermAggregate* rightChild = node-&gt;getRight()-&gt;getAsAggregate();
+                TIntermSequence&amp; sequence = rightChild-&gt;getSequence();
+                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); ++sit)
+                {
+                    TIntermConstantUnion* element = (*sit)-&gt;getAsConstantUnion();
+                    ASSERT(element-&gt;getBasicType() == EbtInt);
+                    ASSERT(element-&gt;getNominalSize() == 1);
+                    const ConstantUnion&amp; data = element-&gt;getUnionArrayPointer()[0];
+                    ASSERT(data.getType() == EbtInt);
+                    switch (data.getIConst())
+                    {
+                        case 0: out &lt;&lt; &quot;x&quot;; break;
+                        case 1: out &lt;&lt; &quot;y&quot;; break;
+                        case 2: out &lt;&lt; &quot;z&quot;; break;
+                        case 3: out &lt;&lt; &quot;w&quot;; break;
+                        default: UNREACHABLE(); break;
+                    }
+                }
+                visitChildren = false;
+            }
+            break;
+
+        case EOpAdd: writeTriplet(visit, &quot;(&quot;, &quot; + &quot;, &quot;)&quot;); break;
+        case EOpSub: writeTriplet(visit, &quot;(&quot;, &quot; - &quot;, &quot;)&quot;); break;
+        case EOpMul: writeTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;); break;
+        case EOpDiv: writeTriplet(visit, &quot;(&quot;, &quot; / &quot;, &quot;)&quot;); break;
+        case EOpMod: UNIMPLEMENTED(); break;
+        case EOpEqual: writeTriplet(visit, &quot;(&quot;, &quot; == &quot;, &quot;)&quot;); break;
+        case EOpNotEqual: writeTriplet(visit, &quot;(&quot;, &quot; != &quot;, &quot;)&quot;); break;
+        case EOpLessThan: writeTriplet(visit, &quot;(&quot;, &quot; &lt; &quot;, &quot;)&quot;); break;
+        case EOpGreaterThan: writeTriplet(visit, &quot;(&quot;, &quot; &gt; &quot;, &quot;)&quot;); break;
+        case EOpLessThanEqual: writeTriplet(visit, &quot;(&quot;, &quot; &lt;= &quot;, &quot;)&quot;); break;
+        case EOpGreaterThanEqual: writeTriplet(visit, &quot;(&quot;, &quot; &gt;= &quot;, &quot;)&quot;); break;
+
+        // Notice the fall-through.
+        case EOpVectorTimesScalar:
+        case EOpVectorTimesMatrix:
+        case EOpMatrixTimesVector:
+        case EOpMatrixTimesScalar:
+        case EOpMatrixTimesMatrix:
+            writeTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;);
+            break;
+
+        case EOpLogicalOr: writeTriplet(visit, &quot;(&quot;, &quot; || &quot;, &quot;)&quot;); break;
+        case EOpLogicalXor: writeTriplet(visit, &quot;(&quot;, &quot; ^^ &quot;, &quot;)&quot;); break;
+        case EOpLogicalAnd: writeTriplet(visit, &quot;(&quot;, &quot; &amp;&amp; &quot;, &quot;)&quot;); break;
+        default: UNREACHABLE(); break;
+    }
+
+    return visitChildren;
+}
+
+bool TOutputGLSLBase::visitUnary(Visit visit, TIntermUnary* node)
+{
+    TString preString;
+    TString postString = &quot;)&quot;;
+
+    switch (node-&gt;getOp())
+    {
+        case EOpNegative: preString = &quot;(-&quot;; break;
+        case EOpVectorLogicalNot: preString = &quot;not(&quot;; break;
+        case EOpLogicalNot: preString = &quot;(!&quot;; break;
+
+        case EOpPostIncrement: preString = &quot;(&quot;; postString = &quot;++)&quot;; break;
+        case EOpPostDecrement: preString = &quot;(&quot;; postString = &quot;--)&quot;; break;
+        case EOpPreIncrement: preString = &quot;(++&quot;; break;
+        case EOpPreDecrement: preString = &quot;(--&quot;; break;
+
+        case EOpConvIntToBool:
+        case EOpConvFloatToBool:
+            switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+            {
+                case 1: preString =  &quot;bool(&quot;;  break;
+                case 2: preString = &quot;bvec2(&quot;; break;
+                case 3: preString = &quot;bvec3(&quot;; break;
+                case 4: preString = &quot;bvec4(&quot;; break;
+                default: UNREACHABLE();
+            }
+            break;
+        case EOpConvBoolToFloat:
+        case EOpConvIntToFloat:
+            switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+            {
+                case 1: preString = &quot;float(&quot;;  break;
+                case 2: preString = &quot;vec2(&quot;; break;
+                case 3: preString = &quot;vec3(&quot;; break;
+                case 4: preString = &quot;vec4(&quot;; break;
+                default: UNREACHABLE();
+            }
+            break;
+        case EOpConvFloatToInt:
+        case EOpConvBoolToInt:
+            switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+            {
+                case 1: preString = &quot;int(&quot;;  break;
+                case 2: preString = &quot;ivec2(&quot;; break;
+                case 3: preString = &quot;ivec3(&quot;; break;
+                case 4: preString = &quot;ivec4(&quot;; break;
+                default: UNREACHABLE();
+            }
+            break;
+
+        case EOpRadians: preString = &quot;radians(&quot;; break;
+        case EOpDegrees: preString = &quot;degrees(&quot;; break;
+        case EOpSin: preString = &quot;sin(&quot;; break;
+        case EOpCos: preString = &quot;cos(&quot;; break;
+        case EOpTan: preString = &quot;tan(&quot;; break;
+        case EOpAsin: preString = &quot;asin(&quot;; break;
+        case EOpAcos: preString = &quot;acos(&quot;; break;
+        case EOpAtan: preString = &quot;atan(&quot;; break;
+
+        case EOpExp: preString = &quot;exp(&quot;; break;
+        case EOpLog: preString = &quot;log(&quot;; break;
+        case EOpExp2: preString = &quot;exp2(&quot;; break;
+        case EOpLog2: preString = &quot;log2(&quot;; break;
+        case EOpSqrt: preString = &quot;sqrt(&quot;; break;
+        case EOpInverseSqrt: preString = &quot;inversesqrt(&quot;; break;
+
+        case EOpAbs: preString = &quot;abs(&quot;; break;
+        case EOpSign: preString = &quot;sign(&quot;; break;
+        case EOpFloor: preString = &quot;floor(&quot;; break;
+        case EOpCeil: preString = &quot;ceil(&quot;; break;
+        case EOpFract: preString = &quot;fract(&quot;; break;
+
+        case EOpLength: preString = &quot;length(&quot;; break;
+        case EOpNormalize: preString = &quot;normalize(&quot;; break;
+
+        case EOpDFdx: preString = &quot;dFdx(&quot;; break;
+        case EOpDFdy: preString = &quot;dFdy(&quot;; break;
+        case EOpFwidth: preString = &quot;fwidth(&quot;; break;
+
+        case EOpAny: preString = &quot;any(&quot;; break;
+        case EOpAll: preString = &quot;all(&quot;; break;
+
+        default: UNREACHABLE(); break;
+    }
+
+    if (visit == PreVisit &amp;&amp; node-&gt;getUseEmulatedFunction())
+        preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
+    writeTriplet(visit, preString.c_str(), NULL, postString.c_str());
+
+    return true;
+}
+
+bool TOutputGLSLBase::visitSelection(Visit visit, TIntermSelection* node)
+{
+    TInfoSinkBase&amp; out = objSink();
+
+    if (node-&gt;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 &lt; b ? 1 : 2).
+        out &lt;&lt; &quot;((&quot;;
+        node-&gt;getCondition()-&gt;traverse(this);
+        out &lt;&lt; &quot;) ? (&quot;;
+        node-&gt;getTrueBlock()-&gt;traverse(this);
+        out &lt;&lt; &quot;) : (&quot;;
+        node-&gt;getFalseBlock()-&gt;traverse(this);
+        out &lt;&lt; &quot;))&quot;;
+    }
+    else
+    {
+        out &lt;&lt; &quot;if (&quot;;
+        node-&gt;getCondition()-&gt;traverse(this);
+        out &lt;&lt; &quot;)\n&quot;;
+
+        incrementDepth(node);
+        visitCodeBlock(node-&gt;getTrueBlock());
+
+        if (node-&gt;getFalseBlock())
+        {
+            out &lt;&lt; &quot;else\n&quot;;
+            visitCodeBlock(node-&gt;getFalseBlock());
+        }
+        decrementDepth();
+    }
+    return false;
+}
+
+bool TOutputGLSLBase::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    bool visitChildren = true;
+    TInfoSinkBase&amp; out = objSink();
+    TString preString;
+    bool delayedWrite = false;
+    switch (node-&gt;getOp())
+    {
+        case EOpSequence: {
+            // Scope the sequences except when at the global scope.
+            if (depth &gt; 0) out &lt;&lt; &quot;{\n&quot;;
+
+            incrementDepth(node);
+            const TIntermSequence&amp; sequence = node-&gt;getSequence();
+            for (TIntermSequence::const_iterator iter = sequence.begin();
+                 iter != sequence.end(); ++iter)
+            {
+                TIntermNode* node = *iter;
+                ASSERT(node != NULL);
+                node-&gt;traverse(this);
+
+                if (isSingleStatement(node))
+                    out &lt;&lt; &quot;;\n&quot;;
+            }
+            decrementDepth();
+
+            // Scope the sequences except when at the global scope.
+            if (depth &gt; 0) out &lt;&lt; &quot;}\n&quot;;
+            visitChildren = false;
+            break;
+        }
+        case EOpPrototype: {
+            // Function declaration.
+            ASSERT(visit == PreVisit);
+            writeVariableType(node-&gt;getType());
+            out &lt;&lt; &quot; &quot; &lt;&lt; hashName(node-&gt;getName());
+
+            out &lt;&lt; &quot;(&quot;;
+            writeFunctionParameters(node-&gt;getSequence());
+            out &lt;&lt; &quot;)&quot;;
+
+            visitChildren = false;
+            break;
+        }
+        case EOpFunction: {
+            // Function definition.
+            ASSERT(visit == PreVisit);
+            writeVariableType(node-&gt;getType());
+            out &lt;&lt; &quot; &quot; &lt;&lt; hashFunctionName(node-&gt;getName());
+
+            incrementDepth(node);
+            // 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&amp; sequence = node-&gt;getSequence();
+            ASSERT((sequence.size() == 1) || (sequence.size() == 2));
+            TIntermSequence::const_iterator seqIter = sequence.begin();
+
+            // Traverse function parameters.
+            TIntermAggregate* params = (*seqIter)-&gt;getAsAggregate();
+            ASSERT(params != NULL);
+            ASSERT(params-&gt;getOp() == EOpParameters);
+            params-&gt;traverse(this);
+
+            // Traverse function body.
+            TIntermAggregate* body = ++seqIter != sequence.end() ?
+                (*seqIter)-&gt;getAsAggregate() : NULL;
+            visitCodeBlock(body);
+            decrementDepth();

+            // Fully processed; no need to visit children.
+            visitChildren = false;
+            break;
+        }
+        case EOpFunctionCall:
+            // Function call.
+            if (visit == PreVisit)
+            {
+                out &lt;&lt; hashFunctionName(node-&gt;getName()) &lt;&lt; &quot;(&quot;;
+            }
+            else if (visit == InVisit)
+            {
+                out &lt;&lt; &quot;, &quot;;
+            }
+            else
+            {
+                out &lt;&lt; &quot;)&quot;;
+            }
+            break;
+        case EOpParameters: {
+            // Function parameters.
+            ASSERT(visit == PreVisit);
+            out &lt;&lt; &quot;(&quot;;
+            writeFunctionParameters(node-&gt;getSequence());
+            out &lt;&lt; &quot;)&quot;;
+            visitChildren = false;
+            break;
+        }
+        case EOpDeclaration: {
+            // Variable declaration.
+            if (visit == PreVisit)
+            {
+                const TIntermSequence&amp; sequence = node-&gt;getSequence();
+                const TIntermTyped* variable = sequence.front()-&gt;getAsTyped();
+                writeVariableType(variable-&gt;getType());
+                out &lt;&lt; &quot; &quot;;
+                mDeclaringVariables = true;
+            }
+            else if (visit == InVisit)
+            {
+                out &lt;&lt; &quot;, &quot;;
+                mDeclaringVariables = true;
+            }
+            else
+            {
+                mDeclaringVariables = false;
+            }
+            break;
+        }
+        case EOpConstructFloat: writeTriplet(visit, &quot;float(&quot;, NULL, &quot;)&quot;); break;
+        case EOpConstructVec2: writeTriplet(visit, &quot;vec2(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructVec3: writeTriplet(visit, &quot;vec3(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructVec4: writeTriplet(visit, &quot;vec4(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructBool: writeTriplet(visit, &quot;bool(&quot;, NULL, &quot;)&quot;); break;
+        case EOpConstructBVec2: writeTriplet(visit, &quot;bvec2(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructBVec3: writeTriplet(visit, &quot;bvec3(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructBVec4: writeTriplet(visit, &quot;bvec4(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructInt: writeTriplet(visit, &quot;int(&quot;, NULL, &quot;)&quot;); break;
+        case EOpConstructIVec2: writeTriplet(visit, &quot;ivec2(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructIVec3: writeTriplet(visit, &quot;ivec3(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructIVec4: writeTriplet(visit, &quot;ivec4(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructMat2: writeTriplet(visit, &quot;mat2(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructMat3: writeTriplet(visit, &quot;mat3(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructMat4: writeTriplet(visit, &quot;mat4(&quot;, &quot;, &quot;, &quot;)&quot;); break;
+        case EOpConstructStruct:
+            if (visit == PreVisit)
+            {
+                const TType&amp; type = node-&gt;getType();
+                ASSERT(type.getBasicType() == EbtStruct);
+                out &lt;&lt; hashName(type.getStruct()-&gt;name()) &lt;&lt; &quot;(&quot;;
+            }
+            else if (visit == InVisit)
+            {
+                out &lt;&lt; &quot;, &quot;;
+            }
+            else
+            {
+                out &lt;&lt; &quot;)&quot;;
+            }
+            break;
+
+        case EOpLessThan: preString = &quot;lessThan(&quot;; delayedWrite = true; break;
+        case EOpGreaterThan: preString = &quot;greaterThan(&quot;; delayedWrite = true; break;
+        case EOpLessThanEqual: preString = &quot;lessThanEqual(&quot;; delayedWrite = true; break;
+        case EOpGreaterThanEqual: preString = &quot;greaterThanEqual(&quot;; delayedWrite = true; break;
+        case EOpVectorEqual: preString = &quot;equal(&quot;; delayedWrite = true; break;
+        case EOpVectorNotEqual: preString = &quot;notEqual(&quot;; delayedWrite = true; break;
+        case EOpComma: writeTriplet(visit, NULL, &quot;, &quot;, NULL); break;
+
+        case EOpMod: preString = &quot;mod(&quot;; delayedWrite = true; break;
+        case EOpPow: preString = &quot;pow(&quot;; delayedWrite = true; break;
+        case EOpAtan: preString = &quot;atan(&quot;; delayedWrite = true; break;
+        case EOpMin: preString = &quot;min(&quot;; delayedWrite = true; break;
+        case EOpMax: preString = &quot;max(&quot;; delayedWrite = true; break;
+        case EOpClamp: preString = &quot;clamp(&quot;; delayedWrite = true; break;
+        case EOpMix: preString = &quot;mix(&quot;; delayedWrite = true; break;
+        case EOpStep: preString = &quot;step(&quot;; delayedWrite = true; break;
+        case EOpSmoothStep: preString = &quot;smoothstep(&quot;; delayedWrite = true; break;
+
+        case EOpDistance: preString = &quot;distance(&quot;; delayedWrite = true; break;
+        case EOpDot: preString = &quot;dot(&quot;; delayedWrite = true; break;
+        case EOpCross: preString = &quot;cross(&quot;; delayedWrite = true; break;
+        case EOpFaceForward: preString = &quot;faceforward(&quot;; delayedWrite = true; break;
+        case EOpReflect: preString = &quot;reflect(&quot;; delayedWrite = true; break;
+        case EOpRefract: preString = &quot;refract(&quot;; delayedWrite = true; break;
+        case EOpMul: preString = &quot;matrixCompMult(&quot;; delayedWrite = true; break;
+
+        default: UNREACHABLE(); break;
+    }
+    if (delayedWrite &amp;&amp; visit == PreVisit &amp;&amp; node-&gt;getUseEmulatedFunction())
+        preString = BuiltInFunctionEmulator::GetEmulatedFunctionName(preString);
+    if (delayedWrite)
+        writeTriplet(visit, preString.c_str(), &quot;, &quot;, &quot;)&quot;);
+    return visitChildren;
+}
+
+bool TOutputGLSLBase::visitLoop(Visit visit, TIntermLoop* node)
+{
+    TInfoSinkBase&amp; out = objSink();
+
+    incrementDepth(node);
+    // Loop header.
+    TLoopType loopType = node-&gt;getType();
+    if (loopType == ELoopFor)  // for loop
+    {
+        if (!node-&gt;getUnrollFlag()) {
+            out &lt;&lt; &quot;for (&quot;;
+            if (node-&gt;getInit())
+                node-&gt;getInit()-&gt;traverse(this);
+            out &lt;&lt; &quot;; &quot;;
+
+            if (node-&gt;getCondition())
+                node-&gt;getCondition()-&gt;traverse(this);
+            out &lt;&lt; &quot;; &quot;;
+
+            if (node-&gt;getExpression())
+                node-&gt;getExpression()-&gt;traverse(this);
+            out &lt;&lt; &quot;)\n&quot;;
+        }
+    }
+    else if (loopType == ELoopWhile)  // while loop
+    {
+        out &lt;&lt; &quot;while (&quot;;
+        ASSERT(node-&gt;getCondition() != NULL);
+        node-&gt;getCondition()-&gt;traverse(this);
+        out &lt;&lt; &quot;)\n&quot;;
+    }
+    else  // do-while loop
+    {
+        ASSERT(loopType == ELoopDoWhile);
+        out &lt;&lt; &quot;do\n&quot;;
+    }
+
+    // Loop body.
+    if (node-&gt;getUnrollFlag())
+    {
+        TLoopIndexInfo indexInfo;
+        mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
+        mLoopUnroll.Push(indexInfo);
+        while (mLoopUnroll.SatisfiesLoopCondition())
+        {
+            visitCodeBlock(node-&gt;getBody());
+            mLoopUnroll.Step();
+        }
+        mLoopUnroll.Pop();
+    }
+    else
+    {
+        visitCodeBlock(node-&gt;getBody());
+    }
+
+    // Loop footer.
+    if (loopType == ELoopDoWhile)  // do-while loop
+    {
+        out &lt;&lt; &quot;while (&quot;;
+        ASSERT(node-&gt;getCondition() != NULL);
+        node-&gt;getCondition()-&gt;traverse(this);
+        out &lt;&lt; &quot;);\n&quot;;
+    }
+    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-&gt;getFlowOp())
+    {
+        case EOpKill: writeTriplet(visit, &quot;discard&quot;, NULL, NULL); break;
+        case EOpBreak: writeTriplet(visit, &quot;break&quot;, NULL, NULL); break;
+        case EOpContinue: writeTriplet(visit, &quot;continue&quot;, NULL, NULL); break;
+        case EOpReturn: writeTriplet(visit, &quot;return &quot;, NULL, NULL); break;
+        default: UNREACHABLE(); break;
+    }
+
+    return true;
+}
+
+void TOutputGLSLBase::visitCodeBlock(TIntermNode* node) {
+    TInfoSinkBase &amp;out = objSink();
+    if (node != NULL)
+    {
+        node-&gt;traverse(this);
+        // Single statements not part of a sequence need to be terminated
+        // with semi-colon.
+        if (isSingleStatement(node))
+            out &lt;&lt; &quot;;\n&quot;;
+    }
+    else
+    {
+        out &lt;&lt; &quot;{\n}\n&quot;;  // Empty code block.
+    }
+}
+
+TString TOutputGLSLBase::getTypeName(const TType&amp; type)
+{
+    TInfoSinkBase out;
+    if (type.isMatrix())
+    {
+        out &lt;&lt; &quot;mat&quot;;
+        out &lt;&lt; type.getNominalSize();
+    }
+    else if (type.isVector())
+    {
+        switch (type.getBasicType())
+        {
+            case EbtFloat: out &lt;&lt; &quot;vec&quot;; break;
+            case EbtInt: out &lt;&lt; &quot;ivec&quot;; break;
+            case EbtBool: out &lt;&lt; &quot;bvec&quot;; break;
+            default: UNREACHABLE(); break;
+        }
+        out &lt;&lt; type.getNominalSize();
+    }
+    else
+    {
+        if (type.getBasicType() == EbtStruct)
+            out &lt;&lt; hashName(type.getStruct()-&gt;name());
+        else
+            out &lt;&lt; type.getBasicString();
+    }
+    return TString(out.c_str());
+}
+
+TString TOutputGLSLBase::hashName(const TString&amp; name)
+{
+    if (mHashFunction == NULL || name.empty())
+        return name;
+    NameMap::const_iterator it = mNameMap.find(name.c_str());
+    if (it != mNameMap.end())
+        return it-&gt;second.c_str();
+    TString hashedName = TIntermTraverser::hash(name, mHashFunction);
+    mNameMap[name.c_str()] = hashedName.c_str();
+    return hashedName;
+}
+
+TString TOutputGLSLBase::hashVariableName(const TString&amp; name)
+{
+    if (mSymbolTable.findBuiltIn(name) != NULL)
+        return name;
+    return hashName(name);
+}
+
+TString TOutputGLSLBase::hashFunctionName(const TString&amp; mangled_name)
+{
+    TString name = TFunction::unmangleName(mangled_name);
+    if (mSymbolTable.findBuiltIn(mangled_name) != NULL || name == &quot;main&quot;)
+        return name;
+    return hashName(name);
+}
+
+bool TOutputGLSLBase::structDeclared(const TStructure* structure) const
+{
+    return mDeclaredStructs.find(structure-&gt;name()) != mDeclaredStructs.end();
+}
+
+void TOutputGLSLBase::declareStruct(const TStructure* structure)
+{
+    TInfoSinkBase&amp; out = objSink();
+
+    out &lt;&lt; &quot;struct &quot; &lt;&lt; hashName(structure-&gt;name()) &lt;&lt; &quot;{\n&quot;;
+    const TFieldList&amp; fields = structure-&gt;fields();
+    for (size_t i = 0; i &lt; fields.size(); ++i)
+    {
+        const TField* field = fields[i];
+        if (writeVariablePrecision(field-&gt;type()-&gt;getPrecision()))
+            out &lt;&lt; &quot; &quot;;
+        out &lt;&lt; getTypeName(*field-&gt;type()) &lt;&lt; &quot; &quot; &lt;&lt; hashName(field-&gt;name());
+        if (field-&gt;type()-&gt;isArray())
+            out &lt;&lt; arrayBrackets(*field-&gt;type());
+        out &lt;&lt; &quot;;\n&quot;;
+    }
+    out &lt;&lt; &quot;}&quot;;
+
+    mDeclaredStructs.insert(structure-&gt;name());
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputGLSLBaseh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+//
+// 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 &lt;set&gt;
+
+#include &quot;compiler/translator/ForLoopUnroll.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+class TOutputGLSLBase : public TIntermTraverser
+{
+public:
+    TOutputGLSLBase(TInfoSinkBase&amp; objSink,
+                    ShArrayIndexClampingStrategy clampingStrategy,
+                    ShHashFunction64 hashFunction,
+                    NameMap&amp; nameMap,
+                    TSymbolTable&amp; symbolTable);
+
+protected:
+    TInfoSinkBase&amp; objSink() { return mObjSink; }
+    void writeTriplet(Visit visit, const char* preStr, const char* inStr, const char* postStr);
+    void writeVariableType(const TType&amp; type);
+    virtual bool writeVariablePrecision(TPrecision precision) = 0;
+    void writeFunctionParameters(const TIntermSequence&amp; args);
+    const ConstantUnion* writeConstantUnion(const TType&amp; type, const ConstantUnion* pConstUnion);
+    TString getTypeName(const TType&amp; type);
+
+    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);
+
+
+    // Return the original name if hash function pointer is NULL;
+    // otherwise return the hashed name.
+    TString hashName(const TString&amp; name);
+    // Same as hashName(), but without hashing built-in variables.
+    TString hashVariableName(const TString&amp; name);
+    // Same as hashName(), but without hashing built-in functions.
+    TString hashFunctionName(const TString&amp; mangled_name);
+
+private:
+    bool structDeclared(const TStructure* structure) const;
+    void declareStruct(const TStructure* structure);
+
+    TInfoSinkBase&amp; 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&lt;TString&gt; DeclaredStructs;
+    DeclaredStructs mDeclaredStructs;
+
+    ForLoopUnroll mLoopUnroll;
+
+    ShArrayIndexClampingStrategy mClampingStrategy;
+
+    // name hashing.
+    ShHashFunction64 mHashFunction;
+
+    NameMap&amp; mNameMap;
+
+    TSymbolTable&amp; mSymbolTable;
+};
+
+#endif  // CROSSCOMPILERGLSL_OUTPUTGLSLBASE_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputGLSLBase.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputHLSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,3138 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/OutputHLSL.h&quot;
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;compiler/translator/compilerdebug.h&quot;
+#include &quot;compiler/translator/DetectDiscontinuity.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/SearchSymbol.h&quot;
+#include &quot;compiler/translator/UnfoldShortCircuit.h&quot;
+#include &quot;compiler/translator/NodeSearch.h&quot;
+#include &quot;compiler/translator/RewriteElseBlocks.h&quot;
+
+#include &lt;algorithm&gt;
+#include &lt;cfloat&gt;
+#include &lt;stdio.h&gt;
+
+namespace sh
+{
+
+OutputHLSL::OutputHLSL(TParseContext &amp;context, const ShBuiltInResources&amp; resources, ShShaderOutput outputType)
+    : TIntermTraverser(true, true, true), mContext(context), mOutputType(outputType)
+{
+    mUnfoldShortCircuit = new UnfoldShortCircuit(context, this);
+    mInsideFunction = false;
+
+    mUsesTexture2D = false;
+    mUsesTexture2D_bias = false;
+    mUsesTexture2DProj = false;
+    mUsesTexture2DProj_bias = false;
+    mUsesTexture2DProjLod = false;
+    mUsesTexture2DLod = false;
+    mUsesTextureCube = false;
+    mUsesTextureCube_bias = false;
+    mUsesTextureCubeLod = false;
+    mUsesTexture2DLod0 = false;
+    mUsesTexture2DLod0_bias = false;
+    mUsesTexture2DProjLod0 = false;
+    mUsesTexture2DProjLod0_bias = false;
+    mUsesTextureCubeLod0 = false;
+    mUsesTextureCubeLod0_bias = false;
+    mUsesFragColor = false;
+    mUsesFragData = false;
+    mUsesDepthRange = false;
+    mUsesFragCoord = false;
+    mUsesPointCoord = false;
+    mUsesFrontFacing = false;
+    mUsesPointSize = false;
+    mUsesFragDepth = false;
+    mUsesXor = false;
+    mUsesMod1 = false;
+    mUsesMod2v = false;
+    mUsesMod2f = false;
+    mUsesMod3v = false;
+    mUsesMod3f = false;
+    mUsesMod4v = false;
+    mUsesMod4f = false;
+    mUsesFaceforward1 = false;
+    mUsesFaceforward2 = false;
+    mUsesFaceforward3 = false;
+    mUsesFaceforward4 = false;
+    mUsesAtan2_1 = false;
+    mUsesAtan2_2 = false;
+    mUsesAtan2_3 = false;
+    mUsesAtan2_4 = false;
+    mUsesDiscardRewriting = false;
+
+    mNumRenderTargets = resources.EXT_draw_buffers ? resources.MaxDrawBuffers : 1;
+
+    mScopeDepth = 0;
+
+    mUniqueIndex = 0;
+
+    mContainsLoopDiscontinuity = false;
+    mOutputLod0Function = false;
+    mInsideDiscontinuousLoop = false;
+
+    mExcessiveLoopIndex = NULL;
+
+    if (mOutputType == SH_HLSL9_OUTPUT)
+    {
+        if (mContext.shaderType == SH_FRAGMENT_SHADER)
+        {
+            mUniformRegister = 3;   // Reserve registers for dx_DepthRange, dx_ViewCoords and dx_DepthFront
+        }
+        else
+        {
+            mUniformRegister = 2;   // Reserve registers for dx_DepthRange and dx_ViewAdjust
+        }
+    }
+    else
+    {
+        mUniformRegister = 0;
+    }
+
+    mSamplerRegister = 0;
+}
+
+OutputHLSL::~OutputHLSL()
+{
+    delete mUnfoldShortCircuit;
+}
+
+void OutputHLSL::output()
+{
+    mContainsLoopDiscontinuity = mContext.shaderType == SH_FRAGMENT_SHADER &amp;&amp; containsLoopDiscontinuity(mContext.treeRoot);
+
+    // Work around D3D9 bug that would manifest in vertex shaders with selection blocks which
+    // use a vertex attribute as a condition, and some related computation in the else block.
+    if (mOutputType == SH_HLSL9_OUTPUT &amp;&amp; mContext.shaderType == SH_VERTEX_SHADER)
+    {
+        RewriteElseBlocks(mContext.treeRoot);
+    }
+
+    mContext.treeRoot-&gt;traverse(this);   // Output the body first to determine what has to go in the header
+    header();
+
+    mContext.infoSink().obj &lt;&lt; mHeader.c_str();
+    mContext.infoSink().obj &lt;&lt; mBody.c_str();
+}
+
+TInfoSinkBase &amp;OutputHLSL::getBodyStream()
+{
+    return mBody;
+}
+
+const ActiveUniforms &amp;OutputHLSL::getUniforms()
+{
+    return mActiveUniforms;
+}
+
+int OutputHLSL::vectorSize(const TType &amp;type) const
+{
+    int elementSize = type.isMatrix() ? type.getNominalSize() : 1;
+    int arraySize = type.isArray() ? type.getArraySize() : 1;
+
+    return elementSize * arraySize;
+}
+
+void OutputHLSL::header()
+{
+    ShShaderType shaderType = mContext.shaderType;
+    TInfoSinkBase &amp;out = mHeader;
+
+    for (StructDeclarations::iterator structDeclaration = mStructDeclarations.begin(); structDeclaration != mStructDeclarations.end(); structDeclaration++)
+    {
+        out &lt;&lt; *structDeclaration;
+    }
+
+    for (Constructors::iterator constructor = mConstructors.begin(); constructor != mConstructors.end(); constructor++)
+    {
+        out &lt;&lt; *constructor;
+    }
+
+    TString uniforms;
+    TString varyings;
+    TString attributes;
+
+    for (ReferencedSymbols::const_iterator uniform = mReferencedUniforms.begin(); uniform != mReferencedUniforms.end(); uniform++)
+    {
+        const TType &amp;type = uniform-&gt;second-&gt;getType();
+        const TString &amp;name = uniform-&gt;second-&gt;getSymbol();
+
+        if (mOutputType == SH_HLSL11_OUTPUT &amp;&amp; IsSampler(type.getBasicType()))   // Also declare the texture
+        {
+            int index = samplerRegister(mReferencedUniforms[name]);
+
+            uniforms += &quot;uniform SamplerState sampler_&quot; + decorateUniform(name, type) + arrayString(type) + 
+                        &quot; : register(s&quot; + str(index) + &quot;);\n&quot;;
+
+            uniforms += &quot;uniform &quot; + textureString(type) + &quot; texture_&quot; + decorateUniform(name, type) + arrayString(type) + 
+                        &quot; : register(t&quot; + str(index) + &quot;);\n&quot;;
+        }
+        else
+        {
+            uniforms += &quot;uniform &quot; + typeString(type) + &quot; &quot; + decorateUniform(name, type) + arrayString(type) + 
+                        &quot; : register(&quot; + registerString(mReferencedUniforms[name]) + &quot;);\n&quot;;
+        }
+    }
+
+    for (ReferencedSymbols::const_iterator varying = mReferencedVaryings.begin(); varying != mReferencedVaryings.end(); varying++)
+    {
+        const TType &amp;type = varying-&gt;second-&gt;getType();
+        const TString &amp;name = varying-&gt;second-&gt;getSymbol();
+
+        // Program linking depends on this exact format
+        varyings += &quot;static &quot; + typeString(type) + &quot; &quot; + decorate(name) + arrayString(type) + &quot; = &quot; + initializer(type) + &quot;;\n&quot;;
+    }
+
+    for (ReferencedSymbols::const_iterator attribute = mReferencedAttributes.begin(); attribute != mReferencedAttributes.end(); attribute++)
+    {
+        const TType &amp;type = attribute-&gt;second-&gt;getType();
+        const TString &amp;name = attribute-&gt;second-&gt;getSymbol();
+
+        attributes += &quot;static &quot; + typeString(type) + &quot; &quot; + decorate(name) + arrayString(type) + &quot; = &quot; + initializer(type) + &quot;;\n&quot;;
+    }
+
+    if (mUsesDiscardRewriting)
+    {
+        out &lt;&lt; &quot;#define ANGLE_USES_DISCARD_REWRITING&quot; &lt;&lt; &quot;\n&quot;;
+    }
+
+    if (shaderType == SH_FRAGMENT_SHADER)
+    {
+        TExtensionBehavior::const_iterator iter = mContext.extensionBehavior().find(&quot;GL_EXT_draw_buffers&quot;);
+        const bool usingMRTExtension = (iter != mContext.extensionBehavior().end() &amp;&amp; (iter-&gt;second == EBhEnable || iter-&gt;second == EBhRequire));
+
+        const unsigned int numColorValues = usingMRTExtension ? mNumRenderTargets : 1;
+
+        out &lt;&lt; &quot;// Varyings\n&quot;;
+        out &lt;&lt;  varyings;
+        out &lt;&lt; &quot;\n&quot;
+               &quot;static float4 gl_Color[&quot; &lt;&lt; numColorValues &lt;&lt; &quot;] =\n&quot;
+               &quot;{\n&quot;;
+        for (unsigned int i = 0; i &lt; numColorValues; i++)
+        {
+            out &lt;&lt; &quot;    float4(0, 0, 0, 0)&quot;;
+            if (i + 1 != numColorValues)
+            {
+                out &lt;&lt; &quot;,&quot;;
+            }
+            out &lt;&lt; &quot;\n&quot;;
+        }
+        out &lt;&lt; &quot;};\n&quot;;
+
+        if (mUsesFragDepth)
+        {
+            out &lt;&lt; &quot;static float gl_Depth = 0.0;\n&quot;;
+        }
+
+        if (mUsesFragCoord)
+        {
+            out &lt;&lt; &quot;static float4 gl_FragCoord = float4(0, 0, 0, 0);\n&quot;;
+        }
+
+        if (mUsesPointCoord)
+        {
+            out &lt;&lt; &quot;static float2 gl_PointCoord = float2(0.5, 0.5);\n&quot;;
+        }
+
+        if (mUsesFrontFacing)
+        {
+            out &lt;&lt; &quot;static bool gl_FrontFacing = false;\n&quot;;
+        }
+
+        out &lt;&lt; &quot;\n&quot;;
+
+        if (mUsesDepthRange)
+        {
+            out &lt;&lt; &quot;struct gl_DepthRangeParameters\n&quot;
+                   &quot;{\n&quot;
+                   &quot;    float near;\n&quot;
+                   &quot;    float far;\n&quot;
+                   &quot;    float diff;\n&quot;
+                   &quot;};\n&quot;
+                   &quot;\n&quot;;
+        }
+
+        if (mOutputType == SH_HLSL11_OUTPUT)
+        {
+            out &lt;&lt; &quot;cbuffer DriverConstants : register(b1)\n&quot;
+                   &quot;{\n&quot;;
+
+            if (mUsesDepthRange)
+            {
+                out &lt;&lt; &quot;    float3 dx_DepthRange : packoffset(c0);\n&quot;;
+            }
+
+            if (mUsesFragCoord)
+            {
+                out &lt;&lt; &quot;    float4 dx_ViewCoords : packoffset(c1);\n&quot;;
+            }
+
+            if (mUsesFragCoord || mUsesFrontFacing)
+            {
+                out &lt;&lt; &quot;    float3 dx_DepthFront : packoffset(c2);\n&quot;;
+            }
+
+            out &lt;&lt; &quot;};\n&quot;;
+        }
+        else
+        {
+            if (mUsesDepthRange)
+            {
+                out &lt;&lt; &quot;uniform float3 dx_DepthRange : register(c0);&quot;;
+            }
+
+            if (mUsesFragCoord)
+            {
+                out &lt;&lt; &quot;uniform float4 dx_ViewCoords : register(c1);\n&quot;;
+            }
+
+            if (mUsesFragCoord || mUsesFrontFacing)
+            {
+                out &lt;&lt; &quot;uniform float3 dx_DepthFront : register(c2);\n&quot;;
+            }
+        }
+
+        out &lt;&lt; &quot;\n&quot;;
+
+        if (mUsesDepthRange)
+        {
+            out &lt;&lt; &quot;static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n&quot;
+                   &quot;\n&quot;;
+        }
+        
+        out &lt;&lt;  uniforms;
+        out &lt;&lt; &quot;\n&quot;;
+
+        if (mUsesTexture2D)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(sampler2D s, float2 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2D(s, t);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.Sample(s, uv);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2D_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(sampler2D s, float2 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dbias(s, float4(t.x, t.y, 0, bias));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleBias(s, uv, bias);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProj)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(sampler2D s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dproj(s, float4(t.x, t.y, 0, t.z));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(sampler2D s, float4 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dproj(s, t);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.Sample(s, float2(uvw.x / uvw.z, uvw.y / uvw.z));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.Sample(s, float2(uvw.x / uvw.w, uvw.y / uvw.w));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProj_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(sampler2D s, float3 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dbias(s, float4(t.x / t.z, t.y / t.z, 0, bias));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(sampler2D s, float4 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dbias(s, float4(t.x / t.w, t.y / t.w, 0, bias));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleBias(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), bias);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleBias(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), bias);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCube)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(samplerCUBE s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBE(s, t);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.Sample(s, uvw);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCube_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(samplerCUBE s, float3 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBEbias(s, float4(t.x, t.y, t.z, bias));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleBias(s, uvw, bias);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        // These *Lod0 intrinsics are not available in GL fragment shaders.
+        // They are used to sample using discontinuous texture coordinates.
+        if (mUsesTexture2DLod0)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod0(sampler2D s, float2 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uv, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DLod0_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod0(sampler2D s, float2 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod0(Texture2D t, SamplerState s, float2 uv, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uv, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProjLod0)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod0(sampler2D s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod(sampler2D s, float4 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod0(Texture2D t, SamplerState s, float4 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProjLod0_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod0_bias(sampler2D s, float3 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod_bias(sampler2D s, float4 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float3 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod_bias(Texture2D t, SamplerState s, float4 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCubeLod0)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod0(samplerCUBE s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uvw, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCubeLod0_bias)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod0(samplerCUBE s, float3 t, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod0(TextureCube t, SamplerState s, float3 uvw, float bias)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uvw, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (usingMRTExtension &amp;&amp; mNumRenderTargets &gt; 1)
+        {
+            out &lt;&lt; &quot;#define GL_USES_MRT\n&quot;;
+        }
+
+        if (mUsesFragColor)
+        {
+            out &lt;&lt; &quot;#define GL_USES_FRAG_COLOR\n&quot;;
+        }
+
+        if (mUsesFragData)
+        {
+            out &lt;&lt; &quot;#define GL_USES_FRAG_DATA\n&quot;;
+        }
+    }
+    else   // Vertex shader
+    {
+        out &lt;&lt; &quot;// Attributes\n&quot;;
+        out &lt;&lt;  attributes;
+        out &lt;&lt; &quot;\n&quot;
+               &quot;static float4 gl_Position = float4(0, 0, 0, 0);\n&quot;;
+        
+        if (mUsesPointSize)
+        {
+            out &lt;&lt; &quot;static float gl_PointSize = float(1);\n&quot;;
+        }
+
+        out &lt;&lt; &quot;\n&quot;
+               &quot;// Varyings\n&quot;;
+        out &lt;&lt;  varyings;
+        out &lt;&lt; &quot;\n&quot;;
+
+        if (mUsesDepthRange)
+        {
+            out &lt;&lt; &quot;struct gl_DepthRangeParameters\n&quot;
+                   &quot;{\n&quot;
+                   &quot;    float near;\n&quot;
+                   &quot;    float far;\n&quot;
+                   &quot;    float diff;\n&quot;
+                   &quot;};\n&quot;
+                   &quot;\n&quot;;
+        }
+
+        if (mOutputType == SH_HLSL11_OUTPUT)
+        {
+            if (mUsesDepthRange)
+            {
+                out &lt;&lt; &quot;cbuffer DriverConstants : register(b1)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    float3 dx_DepthRange : packoffset(c0);\n&quot;
+                       &quot;};\n&quot;
+                       &quot;\n&quot;;
+            }
+        }
+        else
+        {
+            if (mUsesDepthRange)
+            {
+                out &lt;&lt; &quot;uniform float3 dx_DepthRange : register(c0);\n&quot;;
+            }
+
+            out &lt;&lt; &quot;uniform float4 dx_ViewAdjust : register(c1);\n&quot;
+                   &quot;\n&quot;;
+        }
+
+        if (mUsesDepthRange)
+        {
+            out &lt;&lt; &quot;static gl_DepthRangeParameters gl_DepthRange = {dx_DepthRange.x, dx_DepthRange.y, dx_DepthRange.z};\n&quot;
+                   &quot;\n&quot;;
+        }
+
+        out &lt;&lt; uniforms;
+        out &lt;&lt; &quot;\n&quot;;
+        
+        if (mUsesTexture2D)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(sampler2D s, float2 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x, t.y, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2D(Texture2D t, SamplerState s, float2 uv)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uv, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DLod)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod(sampler2D s, float2 t, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x, t.y, 0, lod));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DLod(Texture2D t, SamplerState s, float2 uv, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uv, lod);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProj)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(sampler2D s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(sampler2D s, float4 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProj(Texture2D t, SamplerState s, float4 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTexture2DProjLod)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod(sampler2D s, float3 t, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.z, t.y / t.z, 0, lod));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod(sampler2D s, float4 t, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return tex2Dlod(s, float4(t.x / t.w, t.y / t.w, 0, lod));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_texture2DProjLod(Texture2D t, SamplerState s, float3 uvw, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.z, uvw.y / uvw.z), lod);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;
+                       &quot;float4 gl_texture2DProjLod(Texture2D t, SamplerState s, float4 uvw, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, float2(uvw.x / uvw.w, uvw.y / uvw.w), lod);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCube)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(samplerCUBE s, float3 t)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBElod(s, float4(t.x, t.y, t.z, 0));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCube(TextureCube t, SamplerState s, float3 uvw)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uvw, 0);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+
+        if (mUsesTextureCubeLod)
+        {
+            if (mOutputType == SH_HLSL9_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod(samplerCUBE s, float3 t, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return texCUBElod(s, float4(t.x, t.y, t.z, lod));\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else if (mOutputType == SH_HLSL11_OUTPUT)
+            {
+                out &lt;&lt; &quot;float4 gl_textureCubeLod(TextureCube t, SamplerState s, float3 uvw, float lod)\n&quot;
+                       &quot;{\n&quot;
+                       &quot;    return t.SampleLevel(s, uvw, lod);\n&quot;
+                       &quot;}\n&quot;
+                       &quot;\n&quot;;
+            }
+            else UNREACHABLE();
+        }
+    }
+
+    if (mUsesFragCoord)
+    {
+        out &lt;&lt; &quot;#define GL_USES_FRAG_COORD\n&quot;;
+    }
+
+    if (mUsesPointCoord)
+    {
+        out &lt;&lt; &quot;#define GL_USES_POINT_COORD\n&quot;;
+    }
+
+    if (mUsesFrontFacing)
+    {
+        out &lt;&lt; &quot;#define GL_USES_FRONT_FACING\n&quot;;
+    }
+
+    if (mUsesPointSize)
+    {
+        out &lt;&lt; &quot;#define GL_USES_POINT_SIZE\n&quot;;
+    }
+
+    if (mUsesFragDepth)
+    {
+        out &lt;&lt; &quot;#define GL_USES_FRAG_DEPTH\n&quot;;
+    }
+
+    if (mUsesDepthRange)
+    {
+        out &lt;&lt; &quot;#define GL_USES_DEPTH_RANGE\n&quot;;
+    }
+
+    if (mUsesXor)
+    {
+        out &lt;&lt; &quot;bool xor(bool p, bool q)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return (p || q) &amp;&amp; !(p &amp;&amp; q);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod1)
+    {
+        out &lt;&lt; &quot;float mod(float x, float y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod2v)
+    {
+        out &lt;&lt; &quot;float2 mod(float2 x, float2 y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod2f)
+    {
+        out &lt;&lt; &quot;float2 mod(float2 x, float y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+    
+    if (mUsesMod3v)
+    {
+        out &lt;&lt; &quot;float3 mod(float3 x, float3 y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod3f)
+    {
+        out &lt;&lt; &quot;float3 mod(float3 x, float y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod4v)
+    {
+        out &lt;&lt; &quot;float4 mod(float4 x, float4 y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesMod4f)
+    {
+        out &lt;&lt; &quot;float4 mod(float4 x, float y)\n&quot;
+               &quot;{\n&quot;
+               &quot;    return x - y * floor(x / y);\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesFaceforward1)
+    {
+        out &lt;&lt; &quot;float faceforward(float N, float I, float Nref)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(dot(Nref, I) &gt;= 0)\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return -N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;    else\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesFaceforward2)
+    {
+        out &lt;&lt; &quot;float2 faceforward(float2 N, float2 I, float2 Nref)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(dot(Nref, I) &gt;= 0)\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return -N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;    else\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesFaceforward3)
+    {
+        out &lt;&lt; &quot;float3 faceforward(float3 N, float3 I, float3 Nref)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(dot(Nref, I) &gt;= 0)\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return -N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;    else\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesFaceforward4)
+    {
+        out &lt;&lt; &quot;float4 faceforward(float4 N, float4 I, float4 Nref)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(dot(Nref, I) &gt;= 0)\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return -N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;    else\n&quot;
+               &quot;    {\n&quot;
+               &quot;        return N;\n&quot;
+               &quot;    }\n&quot;
+               &quot;}\n&quot;
+               &quot;\n&quot;;
+    }
+
+    if (mUsesAtan2_1)
+    {
+        out &lt;&lt; &quot;float atanyx(float y, float x)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(x == 0 &amp;&amp; y == 0) x = 1;\n&quot;   // Avoid producing a NaN
+               &quot;    return atan2(y, x);\n&quot;
+               &quot;}\n&quot;;
+    }
+
+    if (mUsesAtan2_2)
+    {
+        out &lt;&lt; &quot;float2 atanyx(float2 y, float2 x)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(x[0] == 0 &amp;&amp; y[0] == 0) x[0] = 1;\n&quot;
+               &quot;    if(x[1] == 0 &amp;&amp; y[1] == 0) x[1] = 1;\n&quot;
+               &quot;    return float2(atan2(y[0], x[0]), atan2(y[1], x[1]));\n&quot;
+               &quot;}\n&quot;;
+    }
+
+    if (mUsesAtan2_3)
+    {
+        out &lt;&lt; &quot;float3 atanyx(float3 y, float3 x)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(x[0] == 0 &amp;&amp; y[0] == 0) x[0] = 1;\n&quot;
+               &quot;    if(x[1] == 0 &amp;&amp; y[1] == 0) x[1] = 1;\n&quot;
+               &quot;    if(x[2] == 0 &amp;&amp; y[2] == 0) x[2] = 1;\n&quot;
+               &quot;    return float3(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]));\n&quot;
+               &quot;}\n&quot;;
+    }
+
+    if (mUsesAtan2_4)
+    {
+        out &lt;&lt; &quot;float4 atanyx(float4 y, float4 x)\n&quot;
+               &quot;{\n&quot;
+               &quot;    if(x[0] == 0 &amp;&amp; y[0] == 0) x[0] = 1;\n&quot;
+               &quot;    if(x[1] == 0 &amp;&amp; y[1] == 0) x[1] = 1;\n&quot;
+               &quot;    if(x[2] == 0 &amp;&amp; y[2] == 0) x[2] = 1;\n&quot;
+               &quot;    if(x[3] == 0 &amp;&amp; y[3] == 0) x[3] = 1;\n&quot;
+               &quot;    return float4(atan2(y[0], x[0]), atan2(y[1], x[1]), atan2(y[2], x[2]), atan2(y[3], x[3]));\n&quot;
+               &quot;}\n&quot;;
+    }
+}
+
+void OutputHLSL::visitSymbol(TIntermSymbol *node)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    TString name = node-&gt;getSymbol();
+
+    if (name == &quot;gl_FragColor&quot;)
+    {
+        out &lt;&lt; &quot;gl_Color[0]&quot;;
+        mUsesFragColor = true;
+    }
+    else if (name == &quot;gl_FragData&quot;)
+    {
+        out &lt;&lt; &quot;gl_Color&quot;;
+        mUsesFragData = true;
+    }
+    else if (name == &quot;gl_DepthRange&quot;)
+    {
+        mUsesDepthRange = true;
+        out &lt;&lt; name;
+    }
+    else if (name == &quot;gl_FragCoord&quot;)
+    {
+        mUsesFragCoord = true;
+        out &lt;&lt; name;
+    }
+    else if (name == &quot;gl_PointCoord&quot;)
+    {
+        mUsesPointCoord = true;
+        out &lt;&lt; name;
+    }
+    else if (name == &quot;gl_FrontFacing&quot;)
+    {
+        mUsesFrontFacing = true;
+        out &lt;&lt; name;
+    }
+    else if (name == &quot;gl_PointSize&quot;)
+    {
+        mUsesPointSize = true;
+        out &lt;&lt; name;
+    }
+    else if (name == &quot;gl_FragDepthEXT&quot;)
+    {
+        mUsesFragDepth = true;
+        out &lt;&lt; &quot;gl_Depth&quot;;
+    }
+    else
+    {
+        TQualifier qualifier = node-&gt;getQualifier();
+
+        if (qualifier == EvqUniform)
+        {
+            mReferencedUniforms[name] = node;
+            out &lt;&lt; decorateUniform(name, node-&gt;getType());
+        }
+        else if (qualifier == EvqAttribute)
+        {
+            mReferencedAttributes[name] = node;
+            out &lt;&lt; decorate(name);
+        }
+        else if (qualifier == EvqVaryingOut || qualifier == EvqInvariantVaryingOut || qualifier == EvqVaryingIn || qualifier == EvqInvariantVaryingIn)
+        {
+            mReferencedVaryings[name] = node;
+            out &lt;&lt; decorate(name);
+        }
+        else if (qualifier == EvqInternal)
+        {
+            out &lt;&lt; name;
+        }
+        else
+        {
+            out &lt;&lt; decorate(name);
+        }
+    }
+}
+
+bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    switch (node-&gt;getOp())
+    {
+      case EOpAssign:                  outputTriplet(visit, &quot;(&quot;, &quot; = &quot;, &quot;)&quot;);           break;
+      case EOpInitialize:
+        if (visit == PreVisit)
+        {
+            // GLSL allows to write things like &quot;float x = x;&quot; where a new variable x is defined
+            // and the value of an existing variable x is assigned. HLSL uses C semantics (the
+            // new variable is created before the assignment is evaluated), so we need to convert
+            // this to &quot;float t = x, x = t;&quot;.
+
+            TIntermSymbol *symbolNode = node-&gt;getLeft()-&gt;getAsSymbolNode();
+            TIntermTyped *expression = node-&gt;getRight();
+
+            sh::SearchSymbol searchSymbol(symbolNode-&gt;getSymbol());
+            expression-&gt;traverse(&amp;searchSymbol);
+            bool sameSymbol = searchSymbol.foundMatch();
+
+            if (sameSymbol)
+            {
+                // Type already printed
+                out &lt;&lt; &quot;t&quot; + str(mUniqueIndex) + &quot; = &quot;;
+                expression-&gt;traverse(this);
+                out &lt;&lt; &quot;, &quot;;
+                symbolNode-&gt;traverse(this);
+                out &lt;&lt; &quot; = t&quot; + str(mUniqueIndex);
+
+                mUniqueIndex++;
+                return false;
+            }
+        }
+        else if (visit == InVisit)
+        {
+            out &lt;&lt; &quot; = &quot;;
+        }
+        break;
+      case EOpAddAssign:               outputTriplet(visit, &quot;(&quot;, &quot; += &quot;, &quot;)&quot;);          break;
+      case EOpSubAssign:               outputTriplet(visit, &quot;(&quot;, &quot; -= &quot;, &quot;)&quot;);          break;
+      case EOpMulAssign:               outputTriplet(visit, &quot;(&quot;, &quot; *= &quot;, &quot;)&quot;);          break;
+      case EOpVectorTimesScalarAssign: outputTriplet(visit, &quot;(&quot;, &quot; *= &quot;, &quot;)&quot;);          break;
+      case EOpMatrixTimesScalarAssign: outputTriplet(visit, &quot;(&quot;, &quot; *= &quot;, &quot;)&quot;);          break;
+      case EOpVectorTimesMatrixAssign:
+        if (visit == PreVisit)
+        {
+            out &lt;&lt; &quot;(&quot;;
+        }
+        else if (visit == InVisit)
+        {
+            out &lt;&lt; &quot; = mul(&quot;;
+            node-&gt;getLeft()-&gt;traverse(this);
+            out &lt;&lt; &quot;, transpose(&quot;;   
+        }
+        else
+        {
+            out &lt;&lt; &quot;)))&quot;;
+        }
+        break;
+      case EOpMatrixTimesMatrixAssign:
+        if (visit == PreVisit)
+        {
+            out &lt;&lt; &quot;(&quot;;
+        }
+        else if (visit == InVisit)
+        {
+            out &lt;&lt; &quot; = mul(&quot;;
+            node-&gt;getLeft()-&gt;traverse(this);
+            out &lt;&lt; &quot;, &quot;;   
+        }
+        else
+        {
+            out &lt;&lt; &quot;))&quot;;
+        }
+        break;
+      case EOpDivAssign:               outputTriplet(visit, &quot;(&quot;, &quot; /= &quot;, &quot;)&quot;);          break;
+      case EOpIndexDirect:             outputTriplet(visit, &quot;&quot;, &quot;[&quot;, &quot;]&quot;);              break;
+      case EOpIndexIndirect:           outputTriplet(visit, &quot;&quot;, &quot;[&quot;, &quot;]&quot;);              break;
+      case EOpIndexDirectStruct:
+        if (visit == InVisit)
+        {
+            const TStructure* structure = node-&gt;getLeft()-&gt;getType().getStruct();
+            const TIntermConstantUnion* index = node-&gt;getRight()-&gt;getAsConstantUnion();
+            const TField* field = structure-&gt;fields()[index-&gt;getIConst(0)];
+            out &lt;&lt; &quot;.&quot; + decorateField(field-&gt;name(), node-&gt;getLeft()-&gt;getType());
+
+            return false;
+        }
+        break;
+      case EOpVectorSwizzle:
+        if (visit == InVisit)
+        {
+            out &lt;&lt; &quot;.&quot;;
+
+            TIntermAggregate *swizzle = node-&gt;getRight()-&gt;getAsAggregate();
+
+            if (swizzle)
+            {
+                TIntermSequence &amp;sequence = swizzle-&gt;getSequence();
+
+                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                {
+                    TIntermConstantUnion *element = (*sit)-&gt;getAsConstantUnion();
+
+                    if (element)
+                    {
+                        int i = element-&gt;getIConst(0);
+
+                        switch (i)
+                        {
+                        case 0: out &lt;&lt; &quot;x&quot;; break;
+                        case 1: out &lt;&lt; &quot;y&quot;; break;
+                        case 2: out &lt;&lt; &quot;z&quot;; break;
+                        case 3: out &lt;&lt; &quot;w&quot;; break;
+                        default: UNREACHABLE();
+                        }
+                    }
+                    else UNREACHABLE();
+                }
+            }
+            else UNREACHABLE();
+
+            return false;   // Fully processed
+        }
+        break;
+      case EOpAdd:               outputTriplet(visit, &quot;(&quot;, &quot; + &quot;, &quot;)&quot;); break;
+      case EOpSub:               outputTriplet(visit, &quot;(&quot;, &quot; - &quot;, &quot;)&quot;); break;
+      case EOpMul:               outputTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;); break;
+      case EOpDiv:               outputTriplet(visit, &quot;(&quot;, &quot; / &quot;, &quot;)&quot;); break;
+      case EOpEqual:
+      case EOpNotEqual:
+        if (node-&gt;getLeft()-&gt;isScalar())
+        {
+            if (node-&gt;getOp() == EOpEqual)
+            {
+                outputTriplet(visit, &quot;(&quot;, &quot; == &quot;, &quot;)&quot;);
+            }
+            else
+            {
+                outputTriplet(visit, &quot;(&quot;, &quot; != &quot;, &quot;)&quot;);
+            }
+        }
+        else if (node-&gt;getLeft()-&gt;getBasicType() == EbtStruct)
+        {
+            if (node-&gt;getOp() == EOpEqual)
+            {
+                out &lt;&lt; &quot;(&quot;;
+            }
+            else
+            {
+                out &lt;&lt; &quot;!(&quot;;
+            }
+
+            const TFieldList &amp;fields = node-&gt;getLeft()-&gt;getType().getStruct()-&gt;fields();
+
+            for (size_t i = 0; i &lt; fields.size(); i++)
+            {
+                const TField *field = fields[i];
+
+                node-&gt;getLeft()-&gt;traverse(this);
+                out &lt;&lt; &quot;.&quot; + decorateField(field-&gt;name(), node-&gt;getLeft()-&gt;getType()) + &quot; == &quot;;
+                node-&gt;getRight()-&gt;traverse(this);
+                out &lt;&lt; &quot;.&quot; + decorateField(field-&gt;name(), node-&gt;getLeft()-&gt;getType());
+
+                if (i &lt; fields.size() - 1)
+                {
+                    out &lt;&lt; &quot; &amp;&amp; &quot;;
+                }
+            }
+
+            out &lt;&lt; &quot;)&quot;;
+
+            return false;
+        }
+        else
+        {
+            ASSERT(node-&gt;getLeft()-&gt;isMatrix() || node-&gt;getLeft()-&gt;isVector());
+
+            if (node-&gt;getOp() == EOpEqual)
+            {
+                outputTriplet(visit, &quot;all(&quot;, &quot; == &quot;, &quot;)&quot;);
+            }
+            else
+            {
+                outputTriplet(visit, &quot;!all(&quot;, &quot; == &quot;, &quot;)&quot;);
+            }
+        }
+        break;
+      case EOpLessThan:          outputTriplet(visit, &quot;(&quot;, &quot; &lt; &quot;, &quot;)&quot;);   break;
+      case EOpGreaterThan:       outputTriplet(visit, &quot;(&quot;, &quot; &gt; &quot;, &quot;)&quot;);   break;
+      case EOpLessThanEqual:     outputTriplet(visit, &quot;(&quot;, &quot; &lt;= &quot;, &quot;)&quot;);  break;
+      case EOpGreaterThanEqual:  outputTriplet(visit, &quot;(&quot;, &quot; &gt;= &quot;, &quot;)&quot;);  break;
+      case EOpVectorTimesScalar: outputTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;);   break;
+      case EOpMatrixTimesScalar: outputTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;);   break;
+      case EOpVectorTimesMatrix: outputTriplet(visit, &quot;mul(&quot;, &quot;, transpose(&quot;, &quot;))&quot;); break;
+      case EOpMatrixTimesVector: outputTriplet(visit, &quot;mul(transpose(&quot;, &quot;), &quot;, &quot;)&quot;); break;
+      case EOpMatrixTimesMatrix: outputTriplet(visit, &quot;transpose(mul(transpose(&quot;, &quot;), transpose(&quot;, &quot;)))&quot;); break;
+      case EOpLogicalOr:
+        if (node-&gt;getRight()-&gt;hasSideEffects())
+        {
+            out &lt;&lt; &quot;s&quot; &lt;&lt; mUnfoldShortCircuit-&gt;getNextTemporaryIndex();
+            return false;
+        }
+        else
+        {
+           outputTriplet(visit, &quot;(&quot;, &quot; || &quot;, &quot;)&quot;);
+           return true;
+        }
+      case EOpLogicalXor:
+        mUsesXor = true;
+        outputTriplet(visit, &quot;xor(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpLogicalAnd:
+        if (node-&gt;getRight()-&gt;hasSideEffects())
+        {
+            out &lt;&lt; &quot;s&quot; &lt;&lt; mUnfoldShortCircuit-&gt;getNextTemporaryIndex();
+            return false;
+        }
+        else
+        {
+           outputTriplet(visit, &quot;(&quot;, &quot; &amp;&amp; &quot;, &quot;)&quot;);
+           return true;
+        }
+      default: UNREACHABLE();
+    }
+
+    return true;
+}
+
+bool OutputHLSL::visitUnary(Visit visit, TIntermUnary *node)
+{
+    switch (node-&gt;getOp())
+    {
+      case EOpNegative:         outputTriplet(visit, &quot;(-&quot;, &quot;&quot;, &quot;)&quot;);  break;
+      case EOpVectorLogicalNot: outputTriplet(visit, &quot;(!&quot;, &quot;&quot;, &quot;)&quot;);  break;
+      case EOpLogicalNot:       outputTriplet(visit, &quot;(!&quot;, &quot;&quot;, &quot;)&quot;);  break;
+      case EOpPostIncrement:    outputTriplet(visit, &quot;(&quot;, &quot;&quot;, &quot;++)&quot;); break;
+      case EOpPostDecrement:    outputTriplet(visit, &quot;(&quot;, &quot;&quot;, &quot;--)&quot;); break;
+      case EOpPreIncrement:     outputTriplet(visit, &quot;(++&quot;, &quot;&quot;, &quot;)&quot;); break;
+      case EOpPreDecrement:     outputTriplet(visit, &quot;(--&quot;, &quot;&quot;, &quot;)&quot;); break;
+      case EOpConvIntToBool:
+      case EOpConvFloatToBool:
+        switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+        {
+          case 1:    outputTriplet(visit, &quot;bool(&quot;, &quot;&quot;, &quot;)&quot;);  break;
+          case 2:    outputTriplet(visit, &quot;bool2(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 3:    outputTriplet(visit, &quot;bool3(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 4:    outputTriplet(visit, &quot;bool4(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          default: UNREACHABLE();
+        }
+        break;
+      case EOpConvBoolToFloat:
+      case EOpConvIntToFloat:
+        switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+        {
+          case 1:    outputTriplet(visit, &quot;float(&quot;, &quot;&quot;, &quot;)&quot;);  break;
+          case 2:    outputTriplet(visit, &quot;float2(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 3:    outputTriplet(visit, &quot;float3(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 4:    outputTriplet(visit, &quot;float4(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          default: UNREACHABLE();
+        }
+        break;
+      case EOpConvFloatToInt:
+      case EOpConvBoolToInt:
+        switch (node-&gt;getOperand()-&gt;getType().getNominalSize())
+        {
+          case 1:    outputTriplet(visit, &quot;int(&quot;, &quot;&quot;, &quot;)&quot;);  break;
+          case 2:    outputTriplet(visit, &quot;int2(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 3:    outputTriplet(visit, &quot;int3(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          case 4:    outputTriplet(visit, &quot;int4(&quot;, &quot;&quot;, &quot;)&quot;); break;
+          default: UNREACHABLE();
+        }
+        break;
+      case EOpRadians:          outputTriplet(visit, &quot;radians(&quot;, &quot;&quot;, &quot;)&quot;);   break;
+      case EOpDegrees:          outputTriplet(visit, &quot;degrees(&quot;, &quot;&quot;, &quot;)&quot;);   break;
+      case EOpSin:              outputTriplet(visit, &quot;sin(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpCos:              outputTriplet(visit, &quot;cos(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpTan:              outputTriplet(visit, &quot;tan(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpAsin:             outputTriplet(visit, &quot;asin(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpAcos:             outputTriplet(visit, &quot;acos(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpAtan:             outputTriplet(visit, &quot;atan(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpExp:              outputTriplet(visit, &quot;exp(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpLog:              outputTriplet(visit, &quot;log(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpExp2:             outputTriplet(visit, &quot;exp2(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpLog2:             outputTriplet(visit, &quot;log2(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpSqrt:             outputTriplet(visit, &quot;sqrt(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpInverseSqrt:      outputTriplet(visit, &quot;rsqrt(&quot;, &quot;&quot;, &quot;)&quot;);     break;
+      case EOpAbs:              outputTriplet(visit, &quot;abs(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpSign:             outputTriplet(visit, &quot;sign(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpFloor:            outputTriplet(visit, &quot;floor(&quot;, &quot;&quot;, &quot;)&quot;);     break;
+      case EOpCeil:             outputTriplet(visit, &quot;ceil(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpFract:            outputTriplet(visit, &quot;frac(&quot;, &quot;&quot;, &quot;)&quot;);      break;
+      case EOpLength:           outputTriplet(visit, &quot;length(&quot;, &quot;&quot;, &quot;)&quot;);    break;
+      case EOpNormalize:        outputTriplet(visit, &quot;normalize(&quot;, &quot;&quot;, &quot;)&quot;); break;
+      case EOpDFdx:
+        if(mInsideDiscontinuousLoop || mOutputLod0Function)
+        {
+            outputTriplet(visit, &quot;(&quot;, &quot;&quot;, &quot;, 0.0)&quot;);
+        }
+        else
+        {
+            outputTriplet(visit, &quot;ddx(&quot;, &quot;&quot;, &quot;)&quot;);
+        }
+        break;
+      case EOpDFdy:
+        if(mInsideDiscontinuousLoop || mOutputLod0Function)
+        {
+            outputTriplet(visit, &quot;(&quot;, &quot;&quot;, &quot;, 0.0)&quot;);
+        }
+        else
+        {
+           outputTriplet(visit, &quot;ddy(&quot;, &quot;&quot;, &quot;)&quot;);
+        }
+        break;
+      case EOpFwidth:
+        if(mInsideDiscontinuousLoop || mOutputLod0Function)
+        {
+            outputTriplet(visit, &quot;(&quot;, &quot;&quot;, &quot;, 0.0)&quot;);
+        }
+        else
+        {
+            outputTriplet(visit, &quot;fwidth(&quot;, &quot;&quot;, &quot;)&quot;);
+        }
+        break;
+      case EOpAny:              outputTriplet(visit, &quot;any(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      case EOpAll:              outputTriplet(visit, &quot;all(&quot;, &quot;&quot;, &quot;)&quot;);       break;
+      default: UNREACHABLE();
+    }
+
+    return true;
+}
+
+bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    switch (node-&gt;getOp())
+    {
+      case EOpSequence:
+        {
+            if (mInsideFunction)
+            {
+                outputLineDirective(node-&gt;getLine().first_line);
+                out &lt;&lt; &quot;{\n&quot;;
+
+                mScopeDepth++;
+
+                if (mScopeBracket.size() &lt; mScopeDepth)
+                {
+                    mScopeBracket.push_back(0);   // New scope level
+                }
+                else
+                {
+                    mScopeBracket[mScopeDepth - 1]++;   // New scope at existing level
+                }
+            }
+
+            for (TIntermSequence::iterator sit = node-&gt;getSequence().begin(); sit != node-&gt;getSequence().end(); sit++)
+            {
+                outputLineDirective((*sit)-&gt;getLine().first_line);
+
+                traverseStatements(*sit);
+
+                out &lt;&lt; &quot;;\n&quot;;
+            }
+
+            if (mInsideFunction)
+            {
+                outputLineDirective(node-&gt;getLine().last_line);
+                out &lt;&lt; &quot;}\n&quot;;
+
+                mScopeDepth--;
+            }
+
+            return false;
+        }
+      case EOpDeclaration:
+        if (visit == PreVisit)
+        {
+            TIntermSequence &amp;sequence = node-&gt;getSequence();
+            TIntermTyped *variable = sequence[0]-&gt;getAsTyped();
+
+            if (variable &amp;&amp; (variable-&gt;getQualifier() == EvqTemporary || variable-&gt;getQualifier() == EvqGlobal))
+            {
+                if (variable-&gt;getType().getStruct())
+                {
+                    addConstructor(variable-&gt;getType(), scopedStruct(variable-&gt;getType().getStruct()-&gt;name()), NULL);
+                }
+
+                if (!variable-&gt;getAsSymbolNode() || variable-&gt;getAsSymbolNode()-&gt;getSymbol() != &quot;&quot;)   // Variable declaration
+                {
+                    if (!mInsideFunction)
+                    {
+                        out &lt;&lt; &quot;static &quot;;
+                    }
+
+                    out &lt;&lt; typeString(variable-&gt;getType()) + &quot; &quot;;
+
+                    for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                    {
+                        TIntermSymbol *symbol = (*sit)-&gt;getAsSymbolNode();
+
+                        if (symbol)
+                        {
+                            symbol-&gt;traverse(this);
+                            out &lt;&lt; arrayString(symbol-&gt;getType());
+                            out &lt;&lt; &quot; = &quot; + initializer(symbol-&gt;getType());
+                        }
+                        else
+                        {
+                            (*sit)-&gt;traverse(this);
+                        }
+
+                        if (*sit != sequence.back())
+                        {
+                            out &lt;&lt; &quot;, &quot;;
+                        }
+                    }
+                }
+                else if (variable-&gt;getAsSymbolNode() &amp;&amp; variable-&gt;getAsSymbolNode()-&gt;getSymbol() == &quot;&quot;)   // Type (struct) declaration
+                {
+                    // Already added to constructor map
+                }
+                else UNREACHABLE();
+            }
+            else if (variable &amp;&amp; (variable-&gt;getQualifier() == EvqVaryingOut || variable-&gt;getQualifier() == EvqInvariantVaryingOut))
+            {
+                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
+                {
+                    TIntermSymbol *symbol = (*sit)-&gt;getAsSymbolNode();
+
+                    if (symbol)
+                    {
+                        // Vertex (output) varyings which are declared but not written to should still be declared to allow successful linking
+                        mReferencedVaryings[symbol-&gt;getSymbol()] = symbol;
+                    }
+                    else
+                    {
+                        (*sit)-&gt;traverse(this);
+                    }
+                }
+            }
+
+            return false;
+        }
+        else if (visit == InVisit)
+        {
+            out &lt;&lt; &quot;, &quot;;
+        }
+        break;
+      case EOpPrototype:
+        if (visit == PreVisit)
+        {
+            out &lt;&lt; typeString(node-&gt;getType()) &lt;&lt; &quot; &quot; &lt;&lt; decorate(node-&gt;getName()) &lt;&lt; (mOutputLod0Function ? &quot;Lod0(&quot; : &quot;(&quot;);
+
+            TIntermSequence &amp;arguments = node-&gt;getSequence();
+
+            for (unsigned int i = 0; i &lt; arguments.size(); i++)
+            {
+                TIntermSymbol *symbol = arguments[i]-&gt;getAsSymbolNode();
+
+                if (symbol)
+                {
+                    out &lt;&lt; argumentString(symbol);
+
+                    if (i &lt; arguments.size() - 1)
+                    {
+                        out &lt;&lt; &quot;, &quot;;
+                    }
+                }
+                else UNREACHABLE();
+            }
+
+            out &lt;&lt; &quot;);\n&quot;;
+
+            // Also prototype the Lod0 variant if needed
+            if (mContainsLoopDiscontinuity &amp;&amp; !mOutputLod0Function)
+            {
+                mOutputLod0Function = true;
+                node-&gt;traverse(this);
+                mOutputLod0Function = false;
+            }
+
+            return false;
+        }
+        break;
+      case EOpComma:            outputTriplet(visit, &quot;(&quot;, &quot;, &quot;, &quot;)&quot;);                break;
+      case EOpFunction:
+        {
+            TString name = TFunction::unmangleName(node-&gt;getName());
+
+            out &lt;&lt; typeString(node-&gt;getType()) &lt;&lt; &quot; &quot;;
+
+            if (name == &quot;main&quot;)
+            {
+                out &lt;&lt; &quot;gl_main(&quot;;
+            }
+            else
+            {
+                out &lt;&lt; decorate(name) &lt;&lt; (mOutputLod0Function ? &quot;Lod0(&quot; : &quot;(&quot;);
+            }
+
+            TIntermSequence &amp;sequence = node-&gt;getSequence();
+            TIntermSequence &amp;arguments = sequence[0]-&gt;getAsAggregate()-&gt;getSequence();
+
+            for (unsigned int i = 0; i &lt; arguments.size(); i++)
+            {
+                TIntermSymbol *symbol = arguments[i]-&gt;getAsSymbolNode();
+
+                if (symbol)
+                {
+                    if (symbol-&gt;getType().getStruct())
+                    {
+                        addConstructor(symbol-&gt;getType(), scopedStruct(symbol-&gt;getType().getStruct()-&gt;name()), NULL);
+                    }
+
+                    out &lt;&lt; argumentString(symbol);
+
+                    if (i &lt; arguments.size() - 1)
+                    {
+                        out &lt;&lt; &quot;, &quot;;
+                    }
+                }
+                else UNREACHABLE();
+            }
+
+            out &lt;&lt; &quot;)\n&quot;
+                &quot;{\n&quot;;
+            
+            if (sequence.size() &gt; 1)
+            {
+                mInsideFunction = true;
+                sequence[1]-&gt;traverse(this);
+                mInsideFunction = false;
+            }
+            
+            out &lt;&lt; &quot;}\n&quot;;
+
+            if (mContainsLoopDiscontinuity &amp;&amp; !mOutputLod0Function)
+            {
+                if (name != &quot;main&quot;)
+                {
+                    mOutputLod0Function = true;
+                    node-&gt;traverse(this);
+                    mOutputLod0Function = false;
+                }
+            }
+
+            return false;
+        }
+        break;
+      case EOpFunctionCall:
+        {
+            TString name = TFunction::unmangleName(node-&gt;getName());
+            bool lod0 = mInsideDiscontinuousLoop || mOutputLod0Function;
+
+            if (node-&gt;isUserDefined())
+            {
+                out &lt;&lt; decorate(name) &lt;&lt; (lod0 ? &quot;Lod0(&quot; : &quot;(&quot;);
+            }
+            else
+            {
+                if (name == &quot;texture2D&quot;)
+                {
+                    if (!lod0)
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTexture2D = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTexture2D_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_texture2D(&quot;;
+                    }
+                    else
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTexture2DLod0 = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTexture2DLod0_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_texture2DLod0(&quot;;
+                    }
+                }
+                else if (name == &quot;texture2DProj&quot;)
+                {
+                    if (!lod0)
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTexture2DProj = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTexture2DProj_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_texture2DProj(&quot;;
+                    }
+                    else
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTexture2DProjLod0 = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTexture2DProjLod0_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_texture2DProjLod0(&quot;;
+                    }
+                }
+                else if (name == &quot;textureCube&quot;)
+                {
+                    if (!lod0)
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTextureCube = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTextureCube_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_textureCube(&quot;;
+                    }
+                    else
+                    {
+                        if (node-&gt;getSequence().size() == 2)
+                        {
+                            mUsesTextureCubeLod0 = true;
+                        }
+                        else if (node-&gt;getSequence().size() == 3)
+                        {
+                            mUsesTextureCubeLod0_bias = true;
+                        }
+                        else UNREACHABLE();
+
+                        out &lt;&lt; &quot;gl_textureCubeLod0(&quot;;
+                    }
+                }
+                else if (name == &quot;texture2DLod&quot;)
+                {
+                    if (node-&gt;getSequence().size() == 3)
+                    {
+                        mUsesTexture2DLod = true;
+                    }
+                    else UNREACHABLE();
+
+                    out &lt;&lt; &quot;gl_texture2DLod(&quot;;
+                }
+                else if (name == &quot;texture2DProjLod&quot;)
+                {
+                    if (node-&gt;getSequence().size() == 3)
+                    {
+                        mUsesTexture2DProjLod = true;
+                    }
+                    else UNREACHABLE();
+
+                    out &lt;&lt; &quot;gl_texture2DProjLod(&quot;;
+                }
+                else if (name == &quot;textureCubeLod&quot;)
+                {
+                    if (node-&gt;getSequence().size() == 3)
+                    {
+                        mUsesTextureCubeLod = true;
+                    }
+                    else UNREACHABLE();
+
+                    out &lt;&lt; &quot;gl_textureCubeLod(&quot;;
+                }
+                else UNREACHABLE();
+            }
+
+            TIntermSequence &amp;arguments = node-&gt;getSequence();
+
+            for (TIntermSequence::iterator arg = arguments.begin(); arg != arguments.end(); arg++)
+            {
+                if (mOutputType == SH_HLSL11_OUTPUT &amp;&amp; IsSampler((*arg)-&gt;getAsTyped()-&gt;getBasicType()))
+                {
+                    out &lt;&lt; &quot;texture_&quot;;
+                    (*arg)-&gt;traverse(this);
+                    out &lt;&lt; &quot;, sampler_&quot;;
+                }
+
+                (*arg)-&gt;traverse(this);
+
+                if (arg &lt; arguments.end() - 1)
+                {
+                    out &lt;&lt; &quot;, &quot;;
+                }
+            }
+
+            out &lt;&lt; &quot;)&quot;;
+
+            return false;
+        }
+        break;
+      case EOpParameters:       outputTriplet(visit, &quot;(&quot;, &quot;, &quot;, &quot;)\n{\n&quot;);             break;
+      case EOpConstructFloat:
+        addConstructor(node-&gt;getType(), &quot;vec1&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;vec1(&quot;, &quot;&quot;, &quot;)&quot;);
+        break;
+      case EOpConstructVec2:
+        addConstructor(node-&gt;getType(), &quot;vec2&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;vec2(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructVec3:
+        addConstructor(node-&gt;getType(), &quot;vec3&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;vec3(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructVec4:
+        addConstructor(node-&gt;getType(), &quot;vec4&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;vec4(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructBool:
+        addConstructor(node-&gt;getType(), &quot;bvec1&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;bvec1(&quot;, &quot;&quot;, &quot;)&quot;);
+        break;
+      case EOpConstructBVec2:
+        addConstructor(node-&gt;getType(), &quot;bvec2&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;bvec2(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructBVec3:
+        addConstructor(node-&gt;getType(), &quot;bvec3&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;bvec3(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructBVec4:
+        addConstructor(node-&gt;getType(), &quot;bvec4&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;bvec4(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructInt:
+        addConstructor(node-&gt;getType(), &quot;ivec1&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;ivec1(&quot;, &quot;&quot;, &quot;)&quot;);
+        break;
+      case EOpConstructIVec2:
+        addConstructor(node-&gt;getType(), &quot;ivec2&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;ivec2(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructIVec3:
+        addConstructor(node-&gt;getType(), &quot;ivec3&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;ivec3(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructIVec4:
+        addConstructor(node-&gt;getType(), &quot;ivec4&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;ivec4(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructMat2:
+        addConstructor(node-&gt;getType(), &quot;mat2&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;mat2(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructMat3:
+        addConstructor(node-&gt;getType(), &quot;mat3&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;mat3(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructMat4: 
+        addConstructor(node-&gt;getType(), &quot;mat4&quot;, &amp;node-&gt;getSequence());
+        outputTriplet(visit, &quot;mat4(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpConstructStruct:
+        addConstructor(node-&gt;getType(), scopedStruct(node-&gt;getType().getStruct()-&gt;name()), &amp;node-&gt;getSequence());
+        outputTriplet(visit, structLookup(node-&gt;getType().getStruct()-&gt;name()) + &quot;_ctor(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpLessThan:         outputTriplet(visit, &quot;(&quot;, &quot; &lt; &quot;, &quot;)&quot;);                 break;
+      case EOpGreaterThan:      outputTriplet(visit, &quot;(&quot;, &quot; &gt; &quot;, &quot;)&quot;);                 break;
+      case EOpLessThanEqual:    outputTriplet(visit, &quot;(&quot;, &quot; &lt;= &quot;, &quot;)&quot;);                break;
+      case EOpGreaterThanEqual: outputTriplet(visit, &quot;(&quot;, &quot; &gt;= &quot;, &quot;)&quot;);                break;
+      case EOpVectorEqual:      outputTriplet(visit, &quot;(&quot;, &quot; == &quot;, &quot;)&quot;);                break;
+      case EOpVectorNotEqual:   outputTriplet(visit, &quot;(&quot;, &quot; != &quot;, &quot;)&quot;);                break;
+      case EOpMod:
+        {
+            // We need to look at the number of components in both arguments
+            switch (node-&gt;getSequence()[0]-&gt;getAsTyped()-&gt;getNominalSize() * 10
+                     + node-&gt;getSequence()[1]-&gt;getAsTyped()-&gt;getNominalSize())
+            {
+              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();
+            }
+
+            outputTriplet(visit, &quot;mod(&quot;, &quot;, &quot;, &quot;)&quot;);
+        }
+        break;
+      case EOpPow:              outputTriplet(visit, &quot;pow(&quot;, &quot;, &quot;, &quot;)&quot;);               break;
+      case EOpAtan:
+        ASSERT(node-&gt;getSequence().size() == 2);   // atan(x) is a unary operator
+        switch (node-&gt;getSequence()[0]-&gt;getAsTyped()-&gt;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, &quot;atanyx(&quot;, &quot;, &quot;, &quot;)&quot;);
+        break;
+      case EOpMin:           outputTriplet(visit, &quot;min(&quot;, &quot;, &quot;, &quot;)&quot;);           break;
+      case EOpMax:           outputTriplet(visit, &quot;max(&quot;, &quot;, &quot;, &quot;)&quot;);           break;
+      case EOpClamp:         outputTriplet(visit, &quot;clamp(&quot;, &quot;, &quot;, &quot;)&quot;);         break;
+      case EOpMix:           outputTriplet(visit, &quot;lerp(&quot;, &quot;, &quot;, &quot;)&quot;);          break;
+      case EOpStep:          outputTriplet(visit, &quot;step(&quot;, &quot;, &quot;, &quot;)&quot;);          break;
+      case EOpSmoothStep:    outputTriplet(visit, &quot;smoothstep(&quot;, &quot;, &quot;, &quot;)&quot;);    break;
+      case EOpDistance:      outputTriplet(visit, &quot;distance(&quot;, &quot;, &quot;, &quot;)&quot;);      break;
+      case EOpDot:           outputTriplet(visit, &quot;dot(&quot;, &quot;, &quot;, &quot;)&quot;);           break;
+      case EOpCross:         outputTriplet(visit, &quot;cross(&quot;, &quot;, &quot;, &quot;)&quot;);         break;
+      case EOpFaceForward:
+        {
+            switch (node-&gt;getSequence()[0]-&gt;getAsTyped()-&gt;getNominalSize())   // Number of components in the first argument
+            {
+            case 1: mUsesFaceforward1 = true; break;
+            case 2: mUsesFaceforward2 = true; break;
+            case 3: mUsesFaceforward3 = true; break;
+            case 4: mUsesFaceforward4 = true; break;
+            default: UNREACHABLE();
+            }
+            
+            outputTriplet(visit, &quot;faceforward(&quot;, &quot;, &quot;, &quot;)&quot;);
+        }
+        break;
+      case EOpReflect:       outputTriplet(visit, &quot;reflect(&quot;, &quot;, &quot;, &quot;)&quot;);       break;
+      case EOpRefract:       outputTriplet(visit, &quot;refract(&quot;, &quot;, &quot;, &quot;)&quot;);       break;
+      case EOpMul:           outputTriplet(visit, &quot;(&quot;, &quot; * &quot;, &quot;)&quot;);             break;
+      default: UNREACHABLE();
+    }
+
+    return true;
+}
+
+bool OutputHLSL::visitSelection(Visit visit, TIntermSelection *node)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    if (node-&gt;usesTernaryOperator())
+    {
+        out &lt;&lt; &quot;s&quot; &lt;&lt; mUnfoldShortCircuit-&gt;getNextTemporaryIndex();
+    }
+    else  // if/else statement
+    {
+        mUnfoldShortCircuit-&gt;traverse(node-&gt;getCondition());
+
+        out &lt;&lt; &quot;if (&quot;;
+
+        node-&gt;getCondition()-&gt;traverse(this);
+
+        out &lt;&lt; &quot;)\n&quot;;
+        
+        outputLineDirective(node-&gt;getLine().first_line);
+        out &lt;&lt; &quot;{\n&quot;;
+
+        bool discard = false;
+
+        if (node-&gt;getTrueBlock())
+        {
+            traverseStatements(node-&gt;getTrueBlock());
+
+            // Detect true discard
+            discard = (discard || FindDiscard::search(node-&gt;getTrueBlock()));
+        }
+
+        outputLineDirective(node-&gt;getLine().first_line);
+        out &lt;&lt; &quot;;\n}\n&quot;;
+
+        if (node-&gt;getFalseBlock())
+        {
+            out &lt;&lt; &quot;else\n&quot;;
+
+            outputLineDirective(node-&gt;getFalseBlock()-&gt;getLine().first_line);
+            out &lt;&lt; &quot;{\n&quot;;
+
+            outputLineDirective(node-&gt;getFalseBlock()-&gt;getLine().first_line);
+            traverseStatements(node-&gt;getFalseBlock());
+
+            outputLineDirective(node-&gt;getFalseBlock()-&gt;getLine().first_line);
+            out &lt;&lt; &quot;;\n}\n&quot;;
+
+            // Detect false discard
+            discard = (discard || FindDiscard::search(node-&gt;getFalseBlock()));
+        }
+
+        // ANGLE issue 486: Detect problematic conditional discard
+        if (discard &amp;&amp; FindSideEffectRewriting::search(node))
+        {
+            mUsesDiscardRewriting = true;
+        }
+    }
+
+    return false;
+}
+
+void OutputHLSL::visitConstantUnion(TIntermConstantUnion *node)
+{
+    writeConstantUnion(node-&gt;getType(), node-&gt;getUnionArrayPointer());
+}
+
+bool OutputHLSL::visitLoop(Visit visit, TIntermLoop *node)
+{
+    bool wasDiscontinuous = mInsideDiscontinuousLoop;
+
+    if (mContainsLoopDiscontinuity &amp;&amp; !mInsideDiscontinuousLoop)
+    {
+        mInsideDiscontinuousLoop = containsLoopDiscontinuity(node);
+    }
+
+    if (mOutputType == SH_HLSL9_OUTPUT)
+    {
+        if (handleExcessiveLoop(node))
+        {
+            return false;
+        }
+    }
+
+    TInfoSinkBase &amp;out = mBody;
+
+    if (node-&gt;getType() == ELoopDoWhile)
+    {
+        out &lt;&lt; &quot;{do\n&quot;;
+
+        outputLineDirective(node-&gt;getLine().first_line);
+        out &lt;&lt; &quot;{\n&quot;;
+    }
+    else
+    {
+        out &lt;&lt; &quot;{for(&quot;;
+        
+        if (node-&gt;getInit())
+        {
+            node-&gt;getInit()-&gt;traverse(this);
+        }
+
+        out &lt;&lt; &quot;; &quot;;
+
+        if (node-&gt;getCondition())
+        {
+            node-&gt;getCondition()-&gt;traverse(this);
+        }
+
+        out &lt;&lt; &quot;; &quot;;
+
+        if (node-&gt;getExpression())
+        {
+            node-&gt;getExpression()-&gt;traverse(this);
+        }
+
+        out &lt;&lt; &quot;)\n&quot;;
+        
+        outputLineDirective(node-&gt;getLine().first_line);
+        out &lt;&lt; &quot;{\n&quot;;
+    }
+
+    if (node-&gt;getBody())
+    {
+        traverseStatements(node-&gt;getBody());
+    }
+
+    outputLineDirective(node-&gt;getLine().first_line);
+    out &lt;&lt; &quot;;}\n&quot;;
+
+    if (node-&gt;getType() == ELoopDoWhile)
+    {
+        outputLineDirective(node-&gt;getCondition()-&gt;getLine().first_line);
+        out &lt;&lt; &quot;while(\n&quot;;
+
+        node-&gt;getCondition()-&gt;traverse(this);
+
+        out &lt;&lt; &quot;);&quot;;
+    }
+
+    out &lt;&lt; &quot;}\n&quot;;
+
+    mInsideDiscontinuousLoop = wasDiscontinuous;
+
+    return false;
+}
+
+bool OutputHLSL::visitBranch(Visit visit, TIntermBranch *node)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    switch (node-&gt;getFlowOp())
+    {
+      case EOpKill:
+        outputTriplet(visit, &quot;discard;\n&quot;, &quot;&quot;, &quot;&quot;);
+        break;
+      case EOpBreak:
+        if (visit == PreVisit)
+        {
+            if (mExcessiveLoopIndex)
+            {
+                out &lt;&lt; &quot;{Break&quot;;
+                mExcessiveLoopIndex-&gt;traverse(this);
+                out &lt;&lt; &quot; = true; break;}\n&quot;;
+            }
+            else
+            {
+                out &lt;&lt; &quot;break;\n&quot;;
+            }
+        }
+        break;
+      case EOpContinue: outputTriplet(visit, &quot;continue;\n&quot;, &quot;&quot;, &quot;&quot;); break;
+      case EOpReturn:
+        if (visit == PreVisit)
+        {
+            if (node-&gt;getExpression())
+            {
+                out &lt;&lt; &quot;return &quot;;
+            }
+            else
+            {
+                out &lt;&lt; &quot;return;\n&quot;;
+            }
+        }
+        else if (visit == PostVisit)
+        {
+            if (node-&gt;getExpression())
+            {
+                out &lt;&lt; &quot;;\n&quot;;
+            }
+        }
+        break;
+      default: UNREACHABLE();
+    }
+
+    return true;
+}
+
+void OutputHLSL::traverseStatements(TIntermNode *node)
+{
+    if (isSingleStatement(node))
+    {
+        mUnfoldShortCircuit-&gt;traverse(node);
+    }
+
+    node-&gt;traverse(this);
+}
+
+bool OutputHLSL::isSingleStatement(TIntermNode *node)
+{
+    TIntermAggregate *aggregate = node-&gt;getAsAggregate();
+
+    if (aggregate)
+    {
+        if (aggregate-&gt;getOp() == EOpSequence)
+        {
+            return false;
+        }
+        else
+        {
+            for (TIntermSequence::iterator sit = aggregate-&gt;getSequence().begin(); sit != aggregate-&gt;getSequence().end(); sit++)
+            {
+                if (!isSingleStatement(*sit))
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+
+    return true;
+}
+
+// Handle loops with more than 254 iterations (unsupported by D3D9) by splitting them
+// (The D3D documentation says 255 iterations, but the compiler complains at anything more than 254).
+bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
+{
+    const int MAX_LOOP_ITERATIONS = 254;
+    TInfoSinkBase &amp;out = mBody;
+
+    // Parse loops of the form:
+    // for(int index = initial; index [comparator] limit; index += increment)
+    TIntermSymbol *index = NULL;
+    TOperator comparator = EOpNull;
+    int initial = 0;
+    int limit = 0;
+    int increment = 0;
+
+    // Parse index name and intial value
+    if (node-&gt;getInit())
+    {
+        TIntermAggregate *init = node-&gt;getInit()-&gt;getAsAggregate();
+
+        if (init)
+        {
+            TIntermSequence &amp;sequence = init-&gt;getSequence();
+            TIntermTyped *variable = sequence[0]-&gt;getAsTyped();
+
+            if (variable &amp;&amp; variable-&gt;getQualifier() == EvqTemporary)
+            {
+                TIntermBinary *assign = variable-&gt;getAsBinaryNode();
+
+                if (assign-&gt;getOp() == EOpInitialize)
+                {
+                    TIntermSymbol *symbol = assign-&gt;getLeft()-&gt;getAsSymbolNode();
+                    TIntermConstantUnion *constant = assign-&gt;getRight()-&gt;getAsConstantUnion();
+
+                    if (symbol &amp;&amp; constant)
+                    {
+                        if (constant-&gt;getBasicType() == EbtInt &amp;&amp; constant-&gt;getNominalSize() == 1)
+                        {
+                            index = symbol;
+                            initial = constant-&gt;getIConst(0);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Parse comparator and limit value
+    if (index != NULL &amp;&amp; node-&gt;getCondition())
+    {
+        TIntermBinary *test = node-&gt;getCondition()-&gt;getAsBinaryNode();
+        
+        if (test &amp;&amp; test-&gt;getLeft()-&gt;getAsSymbolNode()-&gt;getId() == index-&gt;getId())
+        {
+            TIntermConstantUnion *constant = test-&gt;getRight()-&gt;getAsConstantUnion();
+
+            if (constant)
+            {
+                if (constant-&gt;getBasicType() == EbtInt &amp;&amp; constant-&gt;getNominalSize() == 1)
+                {
+                    comparator = test-&gt;getOp();
+                    limit = constant-&gt;getIConst(0);
+                }
+            }
+        }
+    }
+
+    // Parse increment
+    if (index != NULL &amp;&amp; comparator != EOpNull &amp;&amp; node-&gt;getExpression())
+    {
+        TIntermBinary *binaryTerminal = node-&gt;getExpression()-&gt;getAsBinaryNode();
+        TIntermUnary *unaryTerminal = node-&gt;getExpression()-&gt;getAsUnaryNode();
+        
+        if (binaryTerminal)
+        {
+            TOperator op = binaryTerminal-&gt;getOp();
+            TIntermConstantUnion *constant = binaryTerminal-&gt;getRight()-&gt;getAsConstantUnion();
+
+            if (constant)
+            {
+                if (constant-&gt;getBasicType() == EbtInt &amp;&amp; constant-&gt;getNominalSize() == 1)
+                {
+                    int value = constant-&gt;getIConst(0);
+
+                    switch (op)
+                    {
+                      case EOpAddAssign: increment = value;  break;
+                      case EOpSubAssign: increment = -value; break;
+                      default: UNIMPLEMENTED();
+                    }
+                }
+            }
+        }
+        else if (unaryTerminal)
+        {
+            TOperator op = unaryTerminal-&gt;getOp();
+
+            switch (op)
+            {
+              case EOpPostIncrement: increment = 1;  break;
+              case EOpPostDecrement: increment = -1; break;
+              case EOpPreIncrement:  increment = 1;  break;
+              case EOpPreDecrement:  increment = -1; break;
+              default: UNIMPLEMENTED();
+            }
+        }
+    }
+
+    if (index != NULL &amp;&amp; comparator != EOpNull &amp;&amp; increment != 0)
+    {
+        if (comparator == EOpLessThanEqual)
+        {
+            comparator = EOpLessThan;
+            limit += 1;
+        }
+
+        if (comparator == EOpLessThan)
+        {
+            int iterations = (limit - initial) / increment;
+
+            if (iterations &lt;= MAX_LOOP_ITERATIONS)
+            {
+                return false;   // Not an excessive loop
+            }
+
+            TIntermSymbol *restoreIndex = mExcessiveLoopIndex;
+            mExcessiveLoopIndex = index;
+
+            out &lt;&lt; &quot;{int &quot;;
+            index-&gt;traverse(this);
+            out &lt;&lt; &quot;;\n&quot;
+                   &quot;bool Break&quot;;
+            index-&gt;traverse(this);
+            out &lt;&lt; &quot; = false;\n&quot;;
+
+            bool firstLoopFragment = true;
+
+            while (iterations &gt; 0)
+            {
+                int clampedLimit = initial + increment * std::min(MAX_LOOP_ITERATIONS, iterations);
+
+                if (!firstLoopFragment)
+                {
+                    out &lt;&lt; &quot;if (!Break&quot;;
+                    index-&gt;traverse(this);
+                    out &lt;&lt; &quot;) {\n&quot;;
+                }
+
+                if (iterations &lt;= MAX_LOOP_ITERATIONS)   // Last loop fragment
+                {
+                    mExcessiveLoopIndex = NULL;   // Stops setting the Break flag
+                }
+                
+                // for(int index = initial; index &lt; clampedLimit; index += increment)
+
+                out &lt;&lt; &quot;for(&quot;;
+                index-&gt;traverse(this);
+                out &lt;&lt; &quot; = &quot;;
+                out &lt;&lt; initial;
+
+                out &lt;&lt; &quot;; &quot;;
+                index-&gt;traverse(this);
+                out &lt;&lt; &quot; &lt; &quot;;
+                out &lt;&lt; clampedLimit;
+
+                out &lt;&lt; &quot;; &quot;;
+                index-&gt;traverse(this);
+                out &lt;&lt; &quot; += &quot;;
+                out &lt;&lt; increment;
+                out &lt;&lt; &quot;)\n&quot;;
+                
+                outputLineDirective(node-&gt;getLine().first_line);
+                out &lt;&lt; &quot;{\n&quot;;
+
+                if (node-&gt;getBody())
+                {
+                    node-&gt;getBody()-&gt;traverse(this);
+                }
+
+                outputLineDirective(node-&gt;getLine().first_line);
+                out &lt;&lt; &quot;;}\n&quot;;
+
+                if (!firstLoopFragment)
+                {
+                    out &lt;&lt; &quot;}\n&quot;;
+                }
+
+                firstLoopFragment = false;
+
+                initial += MAX_LOOP_ITERATIONS * increment;
+                iterations -= MAX_LOOP_ITERATIONS;
+            }
+            
+            out &lt;&lt; &quot;}&quot;;
+
+            mExcessiveLoopIndex = restoreIndex;
+
+            return true;
+        }
+        else UNIMPLEMENTED();
+    }
+
+    return false;   // Not handled as an excessive loop
+}
+
+void OutputHLSL::outputTriplet(Visit visit, const TString &amp;preString, const TString &amp;inString, const TString &amp;postString)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    if (visit == PreVisit)
+    {
+        out &lt;&lt; preString;
+    }
+    else if (visit == InVisit)
+    {
+        out &lt;&lt; inString;
+    }
+    else if (visit == PostVisit)
+    {
+        out &lt;&lt; postString;
+    }
+}
+
+void OutputHLSL::outputLineDirective(int line)
+{
+    if ((mContext.compileOptions &amp; SH_LINE_DIRECTIVES) &amp;&amp; (line &gt; 0))
+    {
+        mBody &lt;&lt; &quot;\n&quot;;
+        mBody &lt;&lt; &quot;#line &quot; &lt;&lt; line;
+
+        if (mContext.sourcePath)
+        {
+            mBody &lt;&lt; &quot; \&quot;&quot; &lt;&lt; mContext.sourcePath &lt;&lt; &quot;\&quot;&quot;;
+        }
+        
+        mBody &lt;&lt; &quot;\n&quot;;
+    }
+}
+
+TString OutputHLSL::argumentString(const TIntermSymbol *symbol)
+{
+    TQualifier qualifier = symbol-&gt;getQualifier();
+    const TType &amp;type = symbol-&gt;getType();
+    TString name = symbol-&gt;getSymbol();
+
+    if (name.empty())   // HLSL demands named arguments, also for prototypes
+    {
+        name = &quot;x&quot; + str(mUniqueIndex++);
+    }
+    else
+    {
+        name = decorate(name);
+    }
+
+    if (mOutputType == SH_HLSL11_OUTPUT &amp;&amp; IsSampler(type.getBasicType()))
+    {
+       return qualifierString(qualifier) + &quot; &quot; + textureString(type) + &quot; texture_&quot; + name + arrayString(type) + &quot;, &quot; +
+              qualifierString(qualifier) + &quot; SamplerState sampler_&quot; + name + arrayString(type);
+    }
+
+    return qualifierString(qualifier) + &quot; &quot; + typeString(type) + &quot; &quot; + name + arrayString(type);
+}
+
+TString OutputHLSL::qualifierString(TQualifier qualifier)
+{
+    switch(qualifier)
+    {
+      case EvqIn:            return &quot;in&quot;;
+      case EvqOut:           return &quot;out&quot;;
+      case EvqInOut:         return &quot;inout&quot;;
+      case EvqConstReadOnly: return &quot;const&quot;;
+      default: UNREACHABLE();
+    }
+
+    return &quot;&quot;;
+}
+
+TString OutputHLSL::typeString(const TType &amp;type)
+{
+    if (type.getBasicType() == EbtStruct)
+    {
+        const TString&amp; typeName = type.getStruct()-&gt;name();
+        if (typeName != &quot;&quot;)
+        {
+            return structLookup(typeName);
+        }
+        else   // Nameless structure, define in place
+        {
+            const TFieldList &amp;fields = type.getStruct()-&gt;fields();
+
+            TString string = &quot;struct\n&quot;
+                             &quot;{\n&quot;;
+
+            for (unsigned int i = 0; i &lt; fields.size(); i++)
+            {
+                const TField *field = fields[i];
+
+                string += &quot;    &quot; + typeString(*field-&gt;type()) + &quot; &quot; + decorate(field-&gt;name()) + arrayString(*field-&gt;type()) + &quot;;\n&quot;;
+            }
+
+            string += &quot;} &quot;;
+
+            return string;
+        }
+    }
+    else if (type.isMatrix())
+    {
+        switch (type.getNominalSize())
+        {
+          case 2: return &quot;float2x2&quot;;
+          case 3: return &quot;float3x3&quot;;
+          case 4: return &quot;float4x4&quot;;
+        }
+    }
+    else
+    {
+        switch (type.getBasicType())
+        {
+          case EbtFloat:
+            switch (type.getNominalSize())
+            {
+              case 1: return &quot;float&quot;;
+              case 2: return &quot;float2&quot;;
+              case 3: return &quot;float3&quot;;
+              case 4: return &quot;float4&quot;;
+            }
+          case EbtInt:
+            switch (type.getNominalSize())
+            {
+              case 1: return &quot;int&quot;;
+              case 2: return &quot;int2&quot;;
+              case 3: return &quot;int3&quot;;
+              case 4: return &quot;int4&quot;;
+            }
+          case EbtBool:
+            switch (type.getNominalSize())
+            {
+              case 1: return &quot;bool&quot;;
+              case 2: return &quot;bool2&quot;;
+              case 3: return &quot;bool3&quot;;
+              case 4: return &quot;bool4&quot;;
+            }
+          case EbtVoid:
+            return &quot;void&quot;;
+          case EbtSampler2D:
+            return &quot;sampler2D&quot;;
+          case EbtSamplerCube:
+            return &quot;samplerCUBE&quot;;
+          case EbtSamplerExternalOES:
+            return &quot;sampler2D&quot;;
+          default:
+            break;
+        }
+    }
+
+    UNREACHABLE();
+    return &quot;&lt;unknown type&gt;&quot;;
+}
+
+TString OutputHLSL::textureString(const TType &amp;type)
+{
+    switch (type.getBasicType())
+    {
+      case EbtSampler2D:
+        return &quot;Texture2D&quot;;
+      case EbtSamplerCube:
+        return &quot;TextureCube&quot;;
+      case EbtSamplerExternalOES:
+        return &quot;Texture2D&quot;;
+      default:
+        break;
+    }
+
+    UNREACHABLE();
+    return &quot;&lt;unknown texture type&gt;&quot;;
+}
+
+TString OutputHLSL::arrayString(const TType &amp;type)
+{
+    if (!type.isArray())
+    {
+        return &quot;&quot;;
+    }
+
+    return &quot;[&quot; + str(type.getArraySize()) + &quot;]&quot;;
+}
+
+TString OutputHLSL::initializer(const TType &amp;type)
+{
+    TString string;
+
+    size_t size = type.getObjectSize();
+    for (size_t component = 0; component &lt; size; component++)
+    {
+        string += &quot;0&quot;;
+
+        if (component + 1 &lt; size)
+        {
+            string += &quot;, &quot;;
+        }
+    }
+
+    return &quot;{&quot; + string + &quot;}&quot;;
+}
+
+void OutputHLSL::addConstructor(const TType &amp;type, const TString &amp;name, const TIntermSequence *parameters)
+{
+    if (name == &quot;&quot;)
+    {
+        return;   // Nameless structures don't have constructors
+    }
+
+    if (type.getStruct() &amp;&amp; mStructNames.find(decorate(name)) != mStructNames.end())
+    {
+        return;   // Already added
+    }
+
+    TType ctorType = type;
+    ctorType.clearArrayness();
+    ctorType.setPrecision(EbpHigh);
+    ctorType.setQualifier(EvqTemporary);
+
+    TString ctorName = type.getStruct() ? decorate(name) : name;
+
+    typedef std::vector&lt;TType&gt; ParameterArray;
+    ParameterArray ctorParameters;
+
+    if (type.getStruct())
+    {
+        mStructNames.insert(decorate(name));
+
+        TString structure;
+        structure += &quot;struct &quot; + decorate(name) + &quot;\n&quot;
+                     &quot;{\n&quot;;
+
+        const TFieldList &amp;fields = type.getStruct()-&gt;fields();
+
+        for (unsigned int i = 0; i &lt; fields.size(); i++)
+        {
+            const TField *field = fields[i];
+
+            structure += &quot;    &quot; + typeString(*field-&gt;type()) + &quot; &quot; + decorateField(field-&gt;name(), type) + arrayString(*field-&gt;type()) + &quot;;\n&quot;;
+        }
+
+        structure += &quot;};\n&quot;;
+
+        if (std::find(mStructDeclarations.begin(), mStructDeclarations.end(), structure) == mStructDeclarations.end())
+        {
+            mStructDeclarations.push_back(structure);
+        }
+
+        for (unsigned int i = 0; i &lt; fields.size(); i++)
+        {
+            ctorParameters.push_back(*fields[i]-&gt;type());
+        }
+    }
+    else if (parameters)
+    {
+        for (TIntermSequence::const_iterator parameter = parameters-&gt;begin(); parameter != parameters-&gt;end(); parameter++)
+        {
+            ctorParameters.push_back((*parameter)-&gt;getAsTyped()-&gt;getType());
+        }
+    }
+    else UNREACHABLE();
+
+    TString constructor;
+
+    if (ctorType.getStruct())
+    {
+        constructor += ctorName + &quot; &quot; + ctorName + &quot;_ctor(&quot;;
+    }
+    else   // Built-in type
+    {
+        constructor += typeString(ctorType) + &quot; &quot; + ctorName + &quot;(&quot;;
+    }
+
+    for (unsigned int parameter = 0; parameter &lt; ctorParameters.size(); parameter++)
+    {
+        const TType &amp;type = ctorParameters[parameter];
+
+        constructor += typeString(type) + &quot; x&quot; + str(parameter) + arrayString(type);
+
+        if (parameter &lt; ctorParameters.size() - 1)
+        {
+            constructor += &quot;, &quot;;
+        }
+    }
+
+    constructor += &quot;)\n&quot;
+                   &quot;{\n&quot;;
+
+    if (ctorType.getStruct())
+    {
+        constructor += &quot;    &quot; + ctorName + &quot; structure = {&quot;;
+    }
+    else
+    {
+        constructor += &quot;    return &quot; + typeString(ctorType) + &quot;(&quot;;
+    }
+
+    if (ctorType.isMatrix() &amp;&amp; ctorParameters.size() == 1)
+    {
+        int dim = ctorType.getNominalSize();
+        const TType &amp;parameter = ctorParameters[0];
+
+        if (parameter.isScalar())
+        {
+            for (int row = 0; row &lt; dim; row++)
+            {
+                for (int col = 0; col &lt; dim; col++)
+                {
+                    constructor += TString((row == col) ? &quot;x0&quot; : &quot;0.0&quot;);
+                    
+                    if (row &lt; dim - 1 || col &lt; dim - 1)
+                    {
+                        constructor += &quot;, &quot;;
+                    }
+                }
+            }
+        }
+        else if (parameter.isMatrix())
+        {
+            for (int row = 0; row &lt; dim; row++)
+            {
+                for (int col = 0; col &lt; dim; col++)
+                {
+                    if (row &lt; parameter.getNominalSize() &amp;&amp; col &lt; parameter.getNominalSize())
+                    {
+                        constructor += TString(&quot;x0&quot;) + &quot;[&quot; + str(row) + &quot;]&quot; + &quot;[&quot; + str(col) + &quot;]&quot;;
+                    }
+                    else
+                    {
+                        constructor += TString((row == col) ? &quot;1.0&quot; : &quot;0.0&quot;);
+                    }
+
+                    if (row &lt; dim - 1 || col &lt; dim - 1)
+                    {
+                        constructor += &quot;, &quot;;
+                    }
+                }
+            }
+        }
+        else UNREACHABLE();
+    }
+    else
+    {
+        size_t remainingComponents = ctorType.getObjectSize();
+        size_t parameterIndex = 0;
+
+        while (remainingComponents &gt; 0)
+        {
+            const TType &amp;parameter = ctorParameters[parameterIndex];
+            const size_t parameterSize = parameter.getObjectSize();
+            bool moreParameters = parameterIndex + 1 &lt; ctorParameters.size();
+
+            constructor += &quot;x&quot; + str(parameterIndex);
+
+            if (parameter.isScalar())
+            {
+                ASSERT(parameterSize &lt;= remainingComponents);
+                remainingComponents -= parameterSize;
+            }
+            else if (parameter.isVector())
+            {
+                if (remainingComponents == parameterSize || moreParameters)
+                {
+                    ASSERT(parameterSize &lt;= remainingComponents);
+                    remainingComponents -= parameterSize;
+                }
+                else if (remainingComponents &lt; static_cast&lt;size_t&gt;(parameter.getNominalSize()))
+                {
+                    switch (remainingComponents)
+                    {
+                      case 1: constructor += &quot;.x&quot;;    break;
+                      case 2: constructor += &quot;.xy&quot;;   break;
+                      case 3: constructor += &quot;.xyz&quot;;  break;
+                      case 4: constructor += &quot;.xyzw&quot;; break;
+                      default: UNREACHABLE();
+                    }
+
+                    remainingComponents = 0;
+                }
+                else UNREACHABLE();
+            }
+            else if (parameter.isMatrix() || parameter.getStruct())
+            {
+                ASSERT(remainingComponents == parameterSize || moreParameters);
+                ASSERT(parameterSize &lt;= remainingComponents);
+                
+                remainingComponents -= parameterSize;
+            }
+            else UNREACHABLE();
+
+            if (moreParameters)
+            {
+                parameterIndex++;
+            }
+
+            if (remainingComponents)
+            {
+                constructor += &quot;, &quot;;
+            }
+        }
+    }
+
+    if (ctorType.getStruct())
+    {
+        constructor += &quot;};\n&quot;
+                       &quot;    return structure;\n&quot;
+                       &quot;}\n&quot;;
+    }
+    else
+    {
+        constructor += &quot;);\n&quot;
+                       &quot;}\n&quot;;
+    }
+
+    mConstructors.insert(constructor);
+}
+
+const ConstantUnion *OutputHLSL::writeConstantUnion(const TType &amp;type, const ConstantUnion *constUnion)
+{
+    TInfoSinkBase &amp;out = mBody;
+
+    if (type.getBasicType() == EbtStruct)
+    {
+        out &lt;&lt; structLookup(type.getStruct()-&gt;name()) + &quot;_ctor(&quot;;
+        
+        const TFieldList &amp;fields = type.getStruct()-&gt;fields();
+
+        for (size_t i = 0; i &lt; fields.size(); i++)
+        {
+            const TType *fieldType = fields[i]-&gt;type();
+
+            constUnion = writeConstantUnion(*fieldType, constUnion);
+
+            if (i != fields.size() - 1)
+            {
+                out &lt;&lt; &quot;, &quot;;
+            }
+        }
+
+        out &lt;&lt; &quot;)&quot;;
+    }
+    else
+    {
+        size_t size = type.getObjectSize();
+        bool writeType = size &gt; 1;
+        
+        if (writeType)
+        {
+            out &lt;&lt; typeString(type) &lt;&lt; &quot;(&quot;;
+        }
+
+        for (size_t i = 0; i &lt; size; i++, constUnion++)
+        {
+            switch (constUnion-&gt;getType())
+            {
+              case EbtFloat: out &lt;&lt; std::min(FLT_MAX, std::max(-FLT_MAX, constUnion-&gt;getFConst())); break;
+              case EbtInt:   out &lt;&lt; constUnion-&gt;getIConst(); break;
+              case EbtBool:  out &lt;&lt; constUnion-&gt;getBConst(); break;
+              default: UNREACHABLE();
+            }
+
+            if (i != size - 1)
+            {
+                out &lt;&lt; &quot;, &quot;;
+            }
+        }
+
+        if (writeType)
+        {
+            out &lt;&lt; &quot;)&quot;;
+        }
+    }
+
+    return constUnion;
+}
+
+TString OutputHLSL::scopeString(unsigned int depthLimit)
+{
+    TString string;
+
+    for (unsigned int i = 0; i &lt; mScopeBracket.size() &amp;&amp; i &lt; depthLimit; i++)
+    {
+        string += &quot;_&quot; + str(i);
+    }
+
+    return string;
+}
+
+TString OutputHLSL::scopedStruct(const TString &amp;typeName)
+{
+    if (typeName == &quot;&quot;)
+    {
+        return typeName;
+    }
+
+    return typeName + scopeString(mScopeDepth);
+}
+
+TString OutputHLSL::structLookup(const TString &amp;typeName)
+{
+    for (int depth = mScopeDepth; depth &gt;= 0; depth--)
+    {
+        TString scopedName = decorate(typeName + scopeString(depth));
+
+        for (StructNames::iterator structName = mStructNames.begin(); structName != mStructNames.end(); structName++)
+        {
+            if (*structName == scopedName)
+            {
+                return scopedName;
+            }
+        }
+    }
+
+    UNREACHABLE();   // Should have found a matching constructor
+
+    return typeName;
+}
+
+TString OutputHLSL::decorate(const TString &amp;string)
+{
+    if (string.compare(0, 3, &quot;gl_&quot;) != 0 &amp;&amp; string.compare(0, 3, &quot;dx_&quot;) != 0)
+    {
+        return &quot;_&quot; + string;
+    }
+    
+    return string;
+}
+
+TString OutputHLSL::decorateUniform(const TString &amp;string, const TType &amp;type)
+{
+    if (type.getBasicType() == EbtSamplerExternalOES)
+    {
+        return &quot;ex_&quot; + string;
+    }
+    
+    return decorate(string);
+}
+
+TString OutputHLSL::decorateField(const TString &amp;string, const TType &amp;structure)
+{
+    if (structure.getStruct()-&gt;name().compare(0, 3, &quot;gl_&quot;) != 0)
+    {
+        return decorate(string);
+    }
+
+    return string;
+}
+
+TString OutputHLSL::registerString(TIntermSymbol *operand)
+{
+    ASSERT(operand-&gt;getQualifier() == EvqUniform);
+
+    if (IsSampler(operand-&gt;getBasicType()))
+    {
+        return &quot;s&quot; + str(samplerRegister(operand));
+    }
+
+    return &quot;c&quot; + str(uniformRegister(operand));
+}
+
+int OutputHLSL::samplerRegister(TIntermSymbol *sampler)
+{
+    const TType &amp;type = sampler-&gt;getType();
+    ASSERT(IsSampler(type.getBasicType()));
+
+    int index = mSamplerRegister;
+    mSamplerRegister += sampler-&gt;totalRegisterCount();
+
+    declareUniform(type, sampler-&gt;getSymbol(), index);
+
+    return index;
+}
+
+int OutputHLSL::uniformRegister(TIntermSymbol *uniform)
+{
+    const TType &amp;type = uniform-&gt;getType();
+    ASSERT(!IsSampler(type.getBasicType()));
+
+    int index = mUniformRegister;
+    mUniformRegister += uniform-&gt;totalRegisterCount();
+
+    declareUniform(type, uniform-&gt;getSymbol(), index);
+
+    return index;
+}
+
+void OutputHLSL::declareUniform(const TType &amp;type, const TString &amp;name, int index)
+{
+    TStructure *structure = type.getStruct();
+
+    if (!structure)
+    {
+        mActiveUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index));
+    }
+    else
+    {
+        const TFieldList &amp;fields = structure-&gt;fields();
+
+        if (type.isArray())
+        {
+            int elementIndex = index;
+
+            for (int i = 0; i &lt; type.getArraySize(); i++)
+            {
+                for (size_t j = 0; j &lt; fields.size(); j++)
+                {
+                    const TType &amp;fieldType = *fields[j]-&gt;type();
+                    const TString uniformName = name + &quot;[&quot; + str(i) + &quot;].&quot; + fields[j]-&gt;name();
+                    declareUniform(fieldType, uniformName, elementIndex);
+                    elementIndex += fieldType.totalRegisterCount();
+                }
+            }
+        }
+        else
+        {
+            int fieldIndex = index;
+
+            for (size_t i = 0; i &lt; fields.size(); i++)
+            {
+                const TType &amp;fieldType = *fields[i]-&gt;type();
+                const TString uniformName = name + &quot;.&quot; + fields[i]-&gt;name();
+                declareUniform(fieldType, uniformName, fieldIndex);
+                fieldIndex += fieldType.totalRegisterCount();
+            }
+        }
+    }
+}
+
+GLenum OutputHLSL::glVariableType(const TType &amp;type)
+{
+    if (type.getBasicType() == EbtFloat)
+    {
+        if (type.isScalar())
+        {
+            return GL_FLOAT;
+        }
+        else if (type.isVector())
+        {
+            switch(type.getNominalSize())
+            {
+              case 2: return GL_FLOAT_VEC2;
+              case 3: return GL_FLOAT_VEC3;
+              case 4: return GL_FLOAT_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else if (type.isMatrix())
+        {
+            switch(type.getNominalSize())
+            {
+              case 2: return GL_FLOAT_MAT2;
+              case 3: return GL_FLOAT_MAT3;
+              case 4: return GL_FLOAT_MAT4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtInt)
+    {
+        if (type.isScalar())
+        {
+            return GL_INT;
+        }
+        else if (type.isVector())
+        {
+            switch(type.getNominalSize())
+            {
+              case 2: return GL_INT_VEC2;
+              case 3: return GL_INT_VEC3;
+              case 4: return GL_INT_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtBool)
+    {
+        if (type.isScalar())
+        {
+            return GL_BOOL;
+        }
+        else if (type.isVector())
+        {
+            switch(type.getNominalSize())
+            {
+              case 2: return GL_BOOL_VEC2;
+              case 3: return GL_BOOL_VEC3;
+              case 4: return GL_BOOL_VEC4;
+              default: UNREACHABLE();
+            }
+        }
+        else UNREACHABLE();
+    }
+    else if (type.getBasicType() == EbtSampler2D)
+    {
+        return GL_SAMPLER_2D;
+    }
+    else if (type.getBasicType() == EbtSamplerCube)
+    {
+        return GL_SAMPLER_CUBE;
+    }
+    else UNREACHABLE();
+
+    return GL_NONE;
+}
+
+GLenum OutputHLSL::glVariablePrecision(const TType &amp;type)
+{
+    if (type.getBasicType() == EbtFloat)
+    {
+        switch (type.getPrecision())
+        {
+          case EbpHigh:   return GL_HIGH_FLOAT;
+          case EbpMedium: return GL_MEDIUM_FLOAT;
+          case EbpLow:    return GL_LOW_FLOAT;
+          case EbpUndefined:
+            // Should be defined as the default precision by the parser
+          default: UNREACHABLE();
+        }
+    }
+    else if (type.getBasicType() == EbtInt)
+    {
+        switch (type.getPrecision())
+        {
+          case EbpHigh:   return GL_HIGH_INT;
+          case EbpMedium: return GL_MEDIUM_INT;
+          case EbpLow:    return GL_LOW_INT;
+          case EbpUndefined:
+            // Should be defined as the default precision by the parser
+          default: UNREACHABLE();
+        }
+    }
+
+    // Other types (boolean, sampler) don't have a precision
+    return GL_NONE;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorOutputHLSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,167 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_OUTPUTHLSL_H_
+#define COMPILER_OUTPUTHLSL_H_
+
+#include &lt;list&gt;
+#include &lt;set&gt;
+#include &lt;map&gt;
+
+#define GL_APICALL
+#include &lt;GLES2/gl2.h&gt;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;compiler/translator/Uniform.h&quot;
+
+namespace sh
+{
+class UnfoldShortCircuit;
+
+class OutputHLSL : public TIntermTraverser
+{
+  public:
+    OutputHLSL(TParseContext &amp;context, const ShBuiltInResources&amp; resources, ShShaderOutput outputType);
+    ~OutputHLSL();
+
+    void output();
+
+    TInfoSinkBase &amp;getBodyStream();
+    const ActiveUniforms &amp;getUniforms();
+
+    TString typeString(const TType &amp;type);
+    TString textureString(const TType &amp;type);
+    static TString qualifierString(TQualifier qualifier);
+    static TString arrayString(const TType &amp;type);
+    static TString initializer(const TType &amp;type);
+    static TString decorate(const TString &amp;string);                      // Prepends an underscore to avoid naming clashes
+    static TString decorateUniform(const TString &amp;string, const TType &amp;type);
+    static TString decorateField(const TString &amp;string, const TType &amp;structure);
+
+  protected:
+    void header();
+
+    // Visit AST nodes and output their code to the body stream
+    void visitSymbol(TIntermSymbol*);
+    void visitConstantUnion(TIntermConstantUnion*);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitUnary(Visit visit, TIntermUnary*);
+    bool visitSelection(Visit visit, TIntermSelection*);
+    bool visitAggregate(Visit visit, TIntermAggregate*);
+    bool visitLoop(Visit visit, TIntermLoop*);
+    bool visitBranch(Visit visit, TIntermBranch*);
+
+    void traverseStatements(TIntermNode *node);
+    bool isSingleStatement(TIntermNode *node);
+    bool handleExcessiveLoop(TIntermLoop *node);
+    void outputTriplet(Visit visit, const TString &amp;preString, const TString &amp;inString, const TString &amp;postString);
+    void outputLineDirective(int line);
+    TString argumentString(const TIntermSymbol *symbol);
+    int vectorSize(const TType &amp;type) const;
+
+    void addConstructor(const TType &amp;type, const TString &amp;name, const TIntermSequence *parameters);
+    const ConstantUnion *writeConstantUnion(const TType &amp;type, const ConstantUnion *constUnion);
+
+    TString scopeString(unsigned int depthLimit);
+    TString scopedStruct(const TString &amp;typeName);
+    TString structLookup(const TString &amp;typeName);
+
+    TParseContext &amp;mContext;
+    const ShShaderOutput mOutputType;
+    UnfoldShortCircuit *mUnfoldShortCircuit;
+    bool mInsideFunction;
+
+    // Output streams
+    TInfoSinkBase mHeader;
+    TInfoSinkBase mBody;
+    TInfoSinkBase mFooter;
+
+    typedef std::map&lt;TString, TIntermSymbol*&gt; ReferencedSymbols;
+    ReferencedSymbols mReferencedUniforms;
+    ReferencedSymbols mReferencedAttributes;
+    ReferencedSymbols mReferencedVaryings;
+
+    // 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 mUsesTexture2DLod0;
+    bool mUsesTexture2DLod0_bias;
+    bool mUsesTexture2DProjLod0;
+    bool mUsesTexture2DProjLod0_bias;
+    bool mUsesTextureCubeLod0;
+    bool mUsesTextureCubeLod0_bias;
+    bool mUsesFragColor;
+    bool mUsesFragData;
+    bool mUsesDepthRange;
+    bool mUsesFragCoord;
+    bool mUsesPointCoord;
+    bool mUsesFrontFacing;
+    bool mUsesPointSize;
+    bool mUsesFragDepth;
+    bool mUsesXor;
+    bool mUsesMod1;
+    bool mUsesMod2v;
+    bool mUsesMod2f;
+    bool mUsesMod3v;
+    bool mUsesMod3f;
+    bool mUsesMod4v;
+    bool mUsesMod4f;
+    bool mUsesFaceforward1;
+    bool mUsesFaceforward2;
+    bool mUsesFaceforward3;
+    bool mUsesFaceforward4;
+    bool mUsesAtan2_1;
+    bool mUsesAtan2_2;
+    bool mUsesAtan2_3;
+    bool mUsesAtan2_4;
+    bool mUsesDiscardRewriting;
+
+    int mNumRenderTargets;
+
+    typedef std::set&lt;TString&gt; Constructors;
+    Constructors mConstructors;
+
+    typedef std::set&lt;TString&gt; StructNames;
+    StructNames mStructNames;
+
+    typedef std::list&lt;TString&gt; StructDeclarations;
+    StructDeclarations mStructDeclarations;
+
+    typedef std::vector&lt;int&gt; ScopeBracket;
+    ScopeBracket mScopeBracket;
+    unsigned int mScopeDepth;
+
+    int mUniqueIndex;   // For creating unique names
+
+    bool mContainsLoopDiscontinuity;
+    bool mOutputLod0Function;
+    bool mInsideDiscontinuousLoop;
+
+    TIntermSymbol *mExcessiveLoopIndex;
+
+    int mUniformRegister;
+    int mSamplerRegister;
+
+    TString registerString(TIntermSymbol *operand);
+    int samplerRegister(TIntermSymbol *sampler);
+    int uniformRegister(TIntermSymbol *uniform);
+    void declareUniform(const TType &amp;type, const TString &amp;name, int index);
+    static GLenum glVariableType(const TType &amp;type);
+    static GLenum glVariablePrecision(const TType &amp;type);
+
+    ActiveUniforms mActiveUniforms;
+};
+}
+
+#endif   // COMPILER_OUTPUTHLSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/OutputHLSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorParseContextcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,1602 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+#include &lt;stdarg.h&gt;
+#include &lt;stdio.h&gt;
+
+#include &quot;compiler/translator/glslang.h&quot;
+#include &quot;compiler/preprocessor/SourceLocation.h&quot;
+
+///////////////////////////////////////////////////////////////////////
+//
+// Sub- vector and matrix fields
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Look at a '.' field selector string and change it into offsets
+// for a vector.
+//
+bool TParseContext::parseVectorFields(const TString&amp; compString, int vecSize, TVectorFields&amp; fields, const TSourceLoc&amp; line)
+{
+    fields.num = (int) compString.size();
+    if (fields.num &gt; 4) {
+        error(line, &quot;illegal vector field selection&quot;, compString.c_str());
+        return false;
+    }
+
+    enum {
+        exyzw,
+        ergba,
+        estpq
+    } fieldSet[4];
+
+    for (int i = 0; i &lt; fields.num; ++i) {
+        switch (compString[i])  {
+        case 'x': 
+            fields.offsets[i] = 0;
+            fieldSet[i] = exyzw;
+            break;
+        case 'r': 
+            fields.offsets[i] = 0;
+            fieldSet[i] = ergba;
+            break;
+        case 's':
+            fields.offsets[i] = 0;
+            fieldSet[i] = estpq;
+            break;
+        case 'y': 
+            fields.offsets[i] = 1;
+            fieldSet[i] = exyzw;
+            break;
+        case 'g': 
+            fields.offsets[i] = 1;
+            fieldSet[i] = ergba;
+            break;
+        case 't':
+            fields.offsets[i] = 1;
+            fieldSet[i] = estpq;
+            break;
+        case 'z': 
+            fields.offsets[i] = 2;
+            fieldSet[i] = exyzw;
+            break;
+        case 'b': 
+            fields.offsets[i] = 2;
+            fieldSet[i] = ergba;
+            break;
+        case 'p':
+            fields.offsets[i] = 2;
+            fieldSet[i] = estpq;
+            break;
+        
+        case 'w': 
+            fields.offsets[i] = 3;
+            fieldSet[i] = exyzw;
+            break;
+        case 'a': 
+            fields.offsets[i] = 3;
+            fieldSet[i] = ergba;
+            break;
+        case 'q':
+            fields.offsets[i] = 3;
+            fieldSet[i] = estpq;
+            break;
+        default:
+            error(line, &quot;illegal vector field selection&quot;, compString.c_str());
+            return false;
+        }
+    }
+
+    for (int i = 0; i &lt; fields.num; ++i) {
+        if (fields.offsets[i] &gt;= vecSize) {
+            error(line, &quot;vector field selection out of range&quot;,  compString.c_str());
+            return false;
+        }
+
+        if (i &gt; 0) {
+            if (fieldSet[i] != fieldSet[i-1]) {
+                error(line, &quot;illegal - vector component fields not from the same set&quot;, compString.c_str());
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+
+//
+// Look at a '.' field selector string and change it into offsets
+// for a matrix.
+//
+bool TParseContext::parseMatrixFields(const TString&amp; compString, int matSize, TMatrixFields&amp; fields, const TSourceLoc&amp; line)
+{
+    fields.wholeRow = false;
+    fields.wholeCol = false;
+    fields.row = -1;
+    fields.col = -1;
+
+    if (compString.size() != 2) {
+        error(line, &quot;illegal length of matrix field selection&quot;, compString.c_str());
+        return false;
+    }
+
+    if (compString[0] == '_') {
+        if (compString[1] &lt; '0' || compString[1] &gt; '3') {
+            error(line, &quot;illegal matrix field selection&quot;, compString.c_str());
+            return false;
+        }
+        fields.wholeCol = true;
+        fields.col = compString[1] - '0';
+    } else if (compString[1] == '_') {
+        if (compString[0] &lt; '0' || compString[0] &gt; '3') {
+            error(line, &quot;illegal matrix field selection&quot;, compString.c_str());
+            return false;
+        }
+        fields.wholeRow = true;
+        fields.row = compString[0] - '0';
+    } else {
+        if (compString[0] &lt; '0' || compString[0] &gt; '3' ||
+            compString[1] &lt; '0' || compString[1] &gt; '3') {
+            error(line, &quot;illegal matrix field selection&quot;, compString.c_str());
+            return false;
+        }
+        fields.row = compString[0] - '0';
+        fields.col = compString[1] - '0';
+    }
+
+    if (fields.row &gt;= matSize || fields.col &gt;= matSize) {
+        error(line, &quot;matrix field selection out of range&quot;, compString.c_str());
+        return false;
+    }
+
+    return true;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
+// Errors
+//
+////////////////////////////////////////////////////////////////////////
+
+//
+// Track whether errors have occurred.
+//
+void TParseContext::recover()
+{
+}
+
+//
+// Used by flex/bison to output all syntax and parsing errors.
+//
+void TParseContext::error(const TSourceLoc&amp; loc,
+                          const char* reason, const char* token, 
+                          const char* extraInfo)
+{
+    pp::SourceLocation srcLoc;
+    srcLoc.file = loc.first_file;
+    srcLoc.line = loc.first_line;
+    diagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
+                          srcLoc, reason, token, extraInfo);
+
+}
+
+void TParseContext::warning(const TSourceLoc&amp; loc,
+                            const char* reason, const char* token,
+                            const char* extraInfo) {
+    pp::SourceLocation srcLoc;
+    srcLoc.file = loc.first_file;
+    srcLoc.line = loc.first_line;
+    diagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
+                          srcLoc, reason, token, extraInfo);
+}
+
+void TParseContext::trace(const char* str)
+{
+    diagnostics.writeDebug(str);
+}
+
+//
+// Same error message for all places assignments don't work.
+//
+void TParseContext::assignError(const TSourceLoc&amp; line, const char* op, TString left, TString right)
+{
+    std::stringstream extraInfoStream;
+    extraInfoStream &lt;&lt; &quot;cannot convert from '&quot; &lt;&lt; right &lt;&lt; &quot;' to '&quot; &lt;&lt; left &lt;&lt; &quot;'&quot;;
+    std::string extraInfo = extraInfoStream.str();
+    error(line, &quot;&quot;, op, extraInfo.c_str());
+}
+
+//
+// Same error message for all places unary operations don't work.
+//
+void TParseContext::unaryOpError(const TSourceLoc&amp; line, const char* op, TString operand)
+{
+    std::stringstream extraInfoStream;
+    extraInfoStream &lt;&lt; &quot;no operation '&quot; &lt;&lt; op &lt;&lt; &quot;' exists that takes an operand of type &quot; &lt;&lt; operand 
+                    &lt;&lt; &quot; (or there is no acceptable conversion)&quot;;
+    std::string extraInfo = extraInfoStream.str();
+    error(line, &quot; wrong operand type&quot;, op, extraInfo.c_str());
+}
+
+//
+// Same error message for all binary operations don't work.
+//
+void TParseContext::binaryOpError(const TSourceLoc&amp; line, const char* op, TString left, TString right)
+{
+    std::stringstream extraInfoStream;
+    extraInfoStream &lt;&lt; &quot;no operation '&quot; &lt;&lt; op &lt;&lt; &quot;' exists that takes a left-hand operand of type '&quot; &lt;&lt; left 
+                    &lt;&lt; &quot;' and a right operand of type '&quot; &lt;&lt; right &lt;&lt; &quot;' (or there is no acceptable conversion)&quot;;
+    std::string extraInfo = extraInfoStream.str();
+    error(line, &quot; wrong operand types &quot;, op, extraInfo.c_str()); 
+}
+
+bool TParseContext::precisionErrorCheck(const TSourceLoc&amp; line, TPrecision precision, TBasicType type){
+    if (!checksPrecisionErrors)
+        return false;
+    switch( type ){
+    case EbtFloat:
+        if( precision == EbpUndefined ){
+            error( line, &quot;No precision specified for (float)&quot;, &quot;&quot; );
+            return true;
+        }
+        break;
+    case EbtInt:
+        if( precision == EbpUndefined ){
+            error( line, &quot;No precision specified (int)&quot;, &quot;&quot; );
+            return true;
+        }
+        break;
+    default:
+        return false;
+    }
+    return false;
+}
+
+//
+// Both test and if necessary, spit out an error, to see if the node is really
+// an l-value that can be operated on this way.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::lValueErrorCheck(const TSourceLoc&amp; line, const char* op, TIntermTyped* node)
+{
+    TIntermSymbol* symNode = node-&gt;getAsSymbolNode();
+    TIntermBinary* binaryNode = node-&gt;getAsBinaryNode();
+
+    if (binaryNode) {
+        bool errorReturn;
+
+        switch(binaryNode-&gt;getOp()) {
+        case EOpIndexDirect:
+        case EOpIndexIndirect:
+        case EOpIndexDirectStruct:
+            return lValueErrorCheck(line, op, binaryNode-&gt;getLeft());
+        case EOpVectorSwizzle:
+            errorReturn = lValueErrorCheck(line, op, binaryNode-&gt;getLeft());
+            if (!errorReturn) {
+                int offset[4] = {0,0,0,0};
+
+                TIntermTyped* rightNode = binaryNode-&gt;getRight();
+                TIntermAggregate *aggrNode = rightNode-&gt;getAsAggregate();
+                
+                for (TIntermSequence::iterator p = aggrNode-&gt;getSequence().begin(); 
+                                               p != aggrNode-&gt;getSequence().end(); p++) {
+                    int value = (*p)-&gt;getAsTyped()-&gt;getAsConstantUnion()-&gt;getIConst(0);
+                    offset[value]++;     
+                    if (offset[value] &gt; 1) {
+                        error(line, &quot; l-value of swizzle cannot have duplicate components&quot;, op);
+
+                        return true;
+                    }
+                }
+            } 
+
+            return errorReturn;
+        default: 
+            break;
+        }
+        error(line, &quot; l-value required&quot;, op);
+
+        return true;
+    }
+
+
+    const char* symbol = 0;
+    if (symNode != 0)
+        symbol = symNode-&gt;getSymbol().c_str();
+
+    const char* message = 0;
+    switch (node-&gt;getQualifier()) {
+    case EvqConst:          message = &quot;can't modify a const&quot;;        break;
+    case EvqConstReadOnly:  message = &quot;can't modify a const&quot;;        break;
+    case EvqAttribute:      message = &quot;can't modify an attribute&quot;;   break;
+    case EvqUniform:        message = &quot;can't modify a uniform&quot;;      break;
+    case EvqVaryingIn:      message = &quot;can't modify a varying&quot;;      break;
+    case EvqFragCoord:      message = &quot;can't modify gl_FragCoord&quot;;   break;
+    case EvqFrontFacing:    message = &quot;can't modify gl_FrontFacing&quot;; break;
+    case EvqPointCoord:     message = &quot;can't modify gl_PointCoord&quot;;  break;
+    default:
+
+        //
+        // Type that can't be written to?
+        //
+        switch (node-&gt;getBasicType()) {
+        case EbtSampler2D:
+        case EbtSamplerCube:
+            message = &quot;can't modify a sampler&quot;;
+            break;
+        case EbtVoid:
+            message = &quot;can't modify void&quot;;
+            break;
+        default: 
+            break;
+        }
+    }
+
+    if (message == 0 &amp;&amp; binaryNode == 0 &amp;&amp; symNode == 0) {
+        error(line, &quot; l-value required&quot;, op);
+
+        return true;
+    }
+
+
+    //
+    // Everything else is okay, no error.
+    //
+    if (message == 0)
+        return false;
+
+    //
+    // If we get here, we have an error and a message.
+    //
+    if (symNode) {
+        std::stringstream extraInfoStream;
+        extraInfoStream &lt;&lt; &quot;\&quot;&quot; &lt;&lt; symbol &lt;&lt; &quot;\&quot; (&quot; &lt;&lt; message &lt;&lt; &quot;)&quot;;
+        std::string extraInfo = extraInfoStream.str();
+        error(line, &quot; l-value required&quot;, op, extraInfo.c_str());
+    }
+    else {
+        std::stringstream extraInfoStream;
+        extraInfoStream &lt;&lt; &quot;(&quot; &lt;&lt; message &lt;&lt; &quot;)&quot;;
+        std::string extraInfo = extraInfoStream.str();
+        error(line, &quot; l-value required&quot;, op, extraInfo.c_str());
+    }
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if the node is really
+// a constant.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::constErrorCheck(TIntermTyped* node)
+{
+    if (node-&gt;getQualifier() == EvqConst)
+        return false;
+
+    error(node-&gt;getLine(), &quot;constant expression required&quot;, &quot;&quot;);
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if the node is really
+// an integer.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
+{
+    if (node-&gt;getBasicType() == EbtInt &amp;&amp; node-&gt;getNominalSize() == 1)
+        return false;
+
+    error(node-&gt;getLine(), &quot;integer expression required&quot;, token);
+
+    return true;
+}
+
+//
+// Both test, and if necessary spit out an error, to see if we are currently
+// globally scoped.
+//
+// Returns true if the was an error.
+//
+bool TParseContext::globalErrorCheck(const TSourceLoc&amp; line, bool global, const char* token)
+{
+    if (global)
+        return false;
+
+    error(line, &quot;only allowed at global scope&quot;, token);
+
+    return true;
+}
+
+//
+// For now, keep it simple:  if it starts &quot;gl_&quot;, it's reserved, independent
+// of scope.  Except, if the symbol table is at the built-in push-level,
+// which is when we are parsing built-ins.
+// Also checks for &quot;webgl_&quot; and &quot;_webgl_&quot; reserved identifiers if parsing a
+// webgl shader.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::reservedErrorCheck(const TSourceLoc&amp; line, const TString&amp; identifier)
+{
+    static const char* reservedErrMsg = &quot;reserved built-in name&quot;;
+    if (!symbolTable.atBuiltInLevel()) {
+        if (identifier.compare(0, 3, &quot;gl_&quot;) == 0) {
+            error(line, reservedErrMsg, &quot;gl_&quot;);
+            return true;
+        }
+        if (isWebGLBasedSpec(shaderSpec)) {
+            if (identifier.compare(0, 6, &quot;webgl_&quot;) == 0) {
+                error(line, reservedErrMsg, &quot;webgl_&quot;);
+                return true;
+            }
+            if (identifier.compare(0, 7, &quot;_webgl_&quot;) == 0) {
+                error(line, reservedErrMsg, &quot;_webgl_&quot;);
+                return true;
+            }
+            if (shaderSpec == SH_CSS_SHADERS_SPEC &amp;&amp; identifier.compare(0, 4, &quot;css_&quot;) == 0) {
+                error(line, reservedErrMsg, &quot;css_&quot;);
+                return true;
+            }
+        }
+        if (identifier.find(&quot;__&quot;) != TString::npos) {
+            error(line, &quot;identifiers containing two consecutive underscores (__) are reserved as possible future keywords&quot;, identifier.c_str());
+            return true;
+        }
+    }
+
+    return false;
+}
+
+//
+// Make sure there is enough data provided to the constructor to build
+// something of the type of the constructor.  Also returns the type of
+// the constructor.
+//
+// Returns true if there was an error in construction.
+//
+bool TParseContext::constructorErrorCheck(const TSourceLoc&amp; line, TIntermNode* node, TFunction&amp; function, TOperator op, TType* type)
+{
+    *type = function.getReturnType();
+
+    bool constructingMatrix = false;
+    switch(op) {
+    case EOpConstructMat2:
+    case EOpConstructMat3:
+    case EOpConstructMat4:
+        constructingMatrix = true;
+        break;
+    default: 
+        break;
+    }
+
+    //
+    // Note: It's okay to have too many components available, but not okay to have unused
+    // arguments.  'full' will go to true when enough args have been seen.  If we loop
+    // again, there is an extra argument, so 'overfull' will become true.
+    //
+
+    size_t size = 0;
+    bool constType = true;
+    bool full = false;
+    bool overFull = false;
+    bool matrixInMatrix = false;
+    bool arrayArg = false;
+    for (size_t i = 0; i &lt; function.getParamCount(); ++i) {
+        const TParameter&amp; param = function.getParam(i);
+        size += param.type-&gt;getObjectSize();
+        
+        if (constructingMatrix &amp;&amp; param.type-&gt;isMatrix())
+            matrixInMatrix = true;
+        if (full)
+            overFull = true;
+        if (op != EOpConstructStruct &amp;&amp; !type-&gt;isArray() &amp;&amp; size &gt;= type-&gt;getObjectSize())
+            full = true;
+        if (param.type-&gt;getQualifier() != EvqConst)
+            constType = false;
+        if (param.type-&gt;isArray())
+            arrayArg = true;
+    }
+    
+    if (constType)
+        type-&gt;setQualifier(EvqConst);
+
+    if (type-&gt;isArray() &amp;&amp; static_cast&lt;size_t&gt;(type-&gt;getArraySize()) != function.getParamCount()) {
+        error(line, &quot;array constructor needs one argument per array element&quot;, &quot;constructor&quot;);
+        return true;
+    }
+
+    if (arrayArg &amp;&amp; op != EOpConstructStruct) {
+        error(line, &quot;constructing from a non-dereferenced array&quot;, &quot;constructor&quot;);
+        return true;
+    }
+
+    if (matrixInMatrix &amp;&amp; !type-&gt;isArray()) {
+        if (function.getParamCount() != 1) {
+          error(line, &quot;constructing matrix from matrix can only take one argument&quot;, &quot;constructor&quot;);
+          return true;
+        }
+    }
+
+    if (overFull) {
+        error(line, &quot;too many arguments&quot;, &quot;constructor&quot;);
+        return true;
+    }
+    
+    if (op == EOpConstructStruct &amp;&amp; !type-&gt;isArray() &amp;&amp; type-&gt;getStruct()-&gt;fields().size() != function.getParamCount()) {
+        error(line, &quot;Number of constructor parameters does not match the number of structure fields&quot;, &quot;constructor&quot;);
+        return true;
+    }
+
+    if (!type-&gt;isMatrix() || !matrixInMatrix) {
+        if ((op != EOpConstructStruct &amp;&amp; size != 1 &amp;&amp; size &lt; type-&gt;getObjectSize()) ||
+            (op == EOpConstructStruct &amp;&amp; size &lt; type-&gt;getObjectSize())) {
+            error(line, &quot;not enough data provided for construction&quot;, &quot;constructor&quot;);
+            return true;
+        }
+    }
+
+    TIntermTyped *typed = node ? node-&gt;getAsTyped() : 0;
+    if (typed == 0) {
+        error(line, &quot;constructor argument does not have a type&quot;, &quot;constructor&quot;);
+        return true;
+    }
+    if (op != EOpConstructStruct &amp;&amp; IsSampler(typed-&gt;getBasicType())) {
+        error(line, &quot;cannot convert a sampler&quot;, &quot;constructor&quot;);
+        return true;
+    }
+    if (typed-&gt;getBasicType() == EbtVoid) {
+        error(line, &quot;cannot convert a void&quot;, &quot;constructor&quot;);
+        return true;
+    }
+
+    return false;
+}
+
+// This function checks to see if a void variable has been declared and raise an error message for such a case
+//
+// returns true in case of an error
+//
+bool TParseContext::voidErrorCheck(const TSourceLoc&amp; line, const TString&amp; identifier, const TPublicType&amp; pubType)
+{
+    if (pubType.type == EbtVoid) {
+        error(line, &quot;illegal use of type 'void'&quot;, identifier.c_str());
+        return true;
+    } 
+
+    return false;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
+//
+// returns true in case of an error
+//
+bool TParseContext::boolErrorCheck(const TSourceLoc&amp; line, const TIntermTyped* type)
+{
+    if (type-&gt;getBasicType() != EbtBool || type-&gt;isArray() || type-&gt;isMatrix() || type-&gt;isVector()) {
+        error(line, &quot;boolean expression expected&quot;, &quot;&quot;);
+        return true;
+    } 
+
+    return false;
+}
+
+// This function checks to see if the node (for the expression) contains a scalar boolean expression or not
+//
+// returns true in case of an error
+//
+bool TParseContext::boolErrorCheck(const TSourceLoc&amp; line, const TPublicType&amp; pType)
+{
+    if (pType.type != EbtBool || pType.array || pType.matrix || (pType.size &gt; 1)) {
+        error(line, &quot;boolean expression expected&quot;, &quot;&quot;);
+        return true;
+    } 
+
+    return false;
+}
+
+bool TParseContext::samplerErrorCheck(const TSourceLoc&amp; line, const TPublicType&amp; pType, const char* reason)
+{
+    if (pType.type == EbtStruct) {
+        if (containsSampler(*pType.userDef)) {
+            error(line, reason, getBasicString(pType.type), &quot;(structure contains a sampler)&quot;);
+        
+            return true;
+        }
+        
+        return false;
+    } else if (IsSampler(pType.type)) {
+        error(line, reason, getBasicString(pType.type));
+
+        return true;
+    }
+
+    return false;
+}
+
+bool TParseContext::structQualifierErrorCheck(const TSourceLoc&amp; line, const TPublicType&amp; pType)
+{
+    if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &amp;&amp;
+        pType.type == EbtStruct) {
+        error(line, &quot;cannot be used with a structure&quot;, getQualifierString(pType.qualifier));
+        
+        return true;
+    }
+
+    if (pType.qualifier != EvqUniform &amp;&amp; samplerErrorCheck(line, pType, &quot;samplers must be uniform&quot;))
+        return true;
+
+    return false;
+}
+
+bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc&amp; line, TQualifier qualifier, const TType&amp; type)
+{
+    if ((qualifier == EvqOut || qualifier == EvqInOut) &amp;&amp; 
+             type.getBasicType() != EbtStruct &amp;&amp; IsSampler(type.getBasicType())) {
+        error(line, &quot;samplers cannot be output parameters&quot;, type.getBasicString());
+        return true;
+    }
+
+    return false;
+}
+
+bool TParseContext::containsSampler(TType&amp; type)
+{
+    if (IsSampler(type.getBasicType()))
+        return true;
+
+    if (type.getBasicType() == EbtStruct) {
+        const TFieldList&amp; fields = type.getStruct()-&gt;fields();
+        for (unsigned int i = 0; i &lt; fields.size(); ++i) {
+            if (containsSampler(*fields[i]-&gt;type()))
+                return true;
+        }
+    }
+
+    return false;
+}
+
+//
+// Do size checking for an array type's size.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::arraySizeErrorCheck(const TSourceLoc&amp; line, TIntermTyped* expr, int&amp; size)
+{
+    TIntermConstantUnion* constant = expr-&gt;getAsConstantUnion();
+    if (constant == 0 || constant-&gt;getBasicType() != EbtInt) {
+        error(line, &quot;array size must be a constant integer expression&quot;, &quot;&quot;);
+        return true;
+    }
+
+    size = constant-&gt;getIConst(0);
+
+    if (size &lt;= 0) {
+        error(line, &quot;array size must be a positive integer&quot;, &quot;&quot;);
+        size = 1;
+        return true;
+    }
+
+    return false;
+}
+
+//
+// See if this qualifier can be an array.
+//
+// Returns true if there is an error.
+//
+bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc&amp; line, TPublicType type)
+{
+    if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqConst)) {
+        error(line, &quot;cannot declare arrays of this qualifier&quot;, TType(type).getCompleteString().c_str());
+        return true;
+    }
+
+    return false;
+}
+
+//
+// See if this type can be an array.
+//
+// Returns true if there is an error.
+//
+bool TParseContext::arrayTypeErrorCheck(const TSourceLoc&amp; line, TPublicType type)
+{
+    //
+    // Can the type be an array?
+    //
+    if (type.array) {
+        error(line, &quot;cannot declare arrays of arrays&quot;, TType(type).getCompleteString().c_str());
+        return true;
+    }
+
+    return false;
+}
+
+//
+// Do all the semantic checking for declaring an array, with and 
+// without a size, and make the right changes to the symbol table.
+//
+// size == 0 means no specified size.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::arrayErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType type, TVariable*&amp; variable)
+{
+    //
+    // Don't check for reserved word use until after we know it's not in the symbol table,
+    // because reserved arrays can be redeclared.
+    //
+
+    bool builtIn = false; 
+    bool sameScope = false;
+    TSymbol* symbol = symbolTable.find(identifier, &amp;builtIn, &amp;sameScope);
+    if (symbol == 0 || !sameScope) {
+        if (reservedErrorCheck(line, identifier))
+            return true;
+        
+        variable = new TVariable(&amp;identifier, TType(type));
+
+        if (type.arraySize)
+            variable-&gt;getType().setArraySize(type.arraySize);
+
+        if (! symbolTable.insert(*variable)) {
+            delete variable;
+            error(line, &quot;INTERNAL ERROR inserting new symbol&quot;, identifier.c_str());
+            return true;
+        }
+    } else {
+        if (! symbol-&gt;isVariable()) {
+            error(line, &quot;variable expected&quot;, identifier.c_str());
+            return true;
+        }
+
+        variable = static_cast&lt;TVariable*&gt;(symbol);
+        if (! variable-&gt;getType().isArray()) {
+            error(line, &quot;redeclaring non-array as array&quot;, identifier.c_str());
+            return true;
+        }
+        if (variable-&gt;getType().getArraySize() &gt; 0) {
+            error(line, &quot;redeclaration of array with size&quot;, identifier.c_str());
+            return true;
+        }
+        
+        if (! variable-&gt;getType().sameElementType(TType(type))) {
+            error(line, &quot;redeclaration of array with a different type&quot;, identifier.c_str());
+            return true;
+        }
+
+        if (type.arraySize)
+            variable-&gt;getType().setArraySize(type.arraySize);
+    } 
+
+    if (voidErrorCheck(line, identifier, type))
+        return true;
+
+    return false;
+}
+
+//
+// Enforce non-initializer type/qualifier rules.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::nonInitConstErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; type, bool array)
+{
+    if (type.qualifier == EvqConst)
+    {
+        // Make the qualifier make sense.
+        type.qualifier = EvqTemporary;
+        
+        if (array)
+        {
+            error(line, &quot;arrays may not be declared constant since they cannot be initialized&quot;, identifier.c_str());
+        }
+        else if (type.isStructureContainingArrays())
+        {
+            error(line, &quot;structures containing arrays may not be declared constant since they cannot be initialized&quot;, identifier.c_str());
+        }
+        else
+        {
+            error(line, &quot;variables with qualifier 'const' must be initialized&quot;, identifier.c_str());
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+//
+// Do semantic checking for a variable declaration that has no initializer,
+// and update the symbol table.
+//
+// Returns true if there was an error.
+//
+bool TParseContext::nonInitErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; type, TVariable*&amp; variable)
+{
+    if (reservedErrorCheck(line, identifier))
+        recover();
+
+    variable = new TVariable(&amp;identifier, TType(type));
+
+    if (! symbolTable.insert(*variable)) {
+        error(line, &quot;redefinition&quot;, variable-&gt;getName().c_str());
+        delete variable;
+        variable = 0;
+        return true;
+    }
+
+    if (voidErrorCheck(line, identifier, type))
+        return true;
+
+    return false;
+}
+
+bool TParseContext::paramErrorCheck(const TSourceLoc&amp; line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
+{    
+    if (qualifier != EvqConst &amp;&amp; qualifier != EvqTemporary) {
+        error(line, &quot;qualifier not allowed on function parameter&quot;, getQualifierString(qualifier));
+        return true;
+    }
+    if (qualifier == EvqConst &amp;&amp; paramQualifier != EvqIn) {
+        error(line, &quot;qualifier not allowed with &quot;, getQualifierString(qualifier), getQualifierString(paramQualifier));
+        return true;
+    }
+
+    if (qualifier == EvqConst)
+        type-&gt;setQualifier(EvqConstReadOnly);
+    else
+        type-&gt;setQualifier(paramQualifier);
+
+    return false;
+}
+
+bool TParseContext::extensionErrorCheck(const TSourceLoc&amp; line, const TString&amp; extension)
+{
+    const TExtensionBehavior&amp; extBehavior = extensionBehavior();
+    TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
+    if (iter == extBehavior.end()) {
+        error(line, &quot;extension&quot;, extension.c_str(), &quot;is not supported&quot;);
+        return true;
+    }
+    // In GLSL ES, an extension's default behavior is &quot;disable&quot;.
+    if (iter-&gt;second == EBhDisable || iter-&gt;second == EBhUndefined) {
+        error(line, &quot;extension&quot;, extension.c_str(), &quot;is disabled&quot;);
+        return true;
+    }
+    if (iter-&gt;second == EBhWarn) {
+        warning(line, &quot;extension&quot;, extension.c_str(), &quot;is being used&quot;);
+        return false;
+    }
+
+    return false;
+}
+
+bool TParseContext::supportsExtension(const char* extension)
+{
+    const TExtensionBehavior&amp; extbehavior = extensionBehavior();
+    TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
+    return (iter != extbehavior.end());
+}
+
+bool TParseContext::isExtensionEnabled(const char* extension) const
+{
+    const TExtensionBehavior&amp; extbehavior = extensionBehavior();
+    TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
+
+    if (iter == extbehavior.end())
+    {
+        return false;
+    }
+
+    return (iter-&gt;second == EBhEnable || iter-&gt;second == EBhRequire);
+}
+
+/////////////////////////////////////////////////////////////////////////////////
+//
+// Non-Errors.
+//
+/////////////////////////////////////////////////////////////////////////////////
+
+//
+// Look up a function name in the symbol table, and make sure it is a function.
+//
+// Return the function symbol if found, otherwise 0.
+//
+const TFunction* TParseContext::findFunction(const TSourceLoc&amp; line, TFunction* call, bool *builtIn)
+{
+    // First find by unmangled name to check whether the function name has been
+    // hidden by a variable name or struct typename.
+    // If a function is found, check for one with a matching argument list.
+    const TSymbol* symbol = symbolTable.find(call-&gt;getName(), builtIn);
+    if (symbol == 0 || symbol-&gt;isFunction()) {
+        symbol = symbolTable.find(call-&gt;getMangledName(), builtIn);
+    }
+
+    if (symbol == 0) {
+        error(line, &quot;no matching overloaded function found&quot;, call-&gt;getName().c_str());
+        return 0;
+    }
+
+    if (!symbol-&gt;isFunction()) {
+        error(line, &quot;function name expected&quot;, call-&gt;getName().c_str());
+        return 0;
+    }
+
+    return static_cast&lt;const TFunction*&gt;(symbol);
+}
+
+//
+// Initializers show up in several places in the grammar.  Have one set of
+// code to handle them here.
+//
+bool TParseContext::executeInitializer(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; pType, 
+                                       TIntermTyped* initializer, TIntermNode*&amp; intermNode, TVariable* variable)
+{
+    TType type = TType(pType);
+
+    if (variable == 0) {
+        if (reservedErrorCheck(line, identifier))
+            return true;
+
+        if (voidErrorCheck(line, identifier, pType))
+            return true;
+
+        //
+        // add variable to symbol table
+        //
+        variable = new TVariable(&amp;identifier, type);
+        if (! symbolTable.insert(*variable)) {
+            error(line, &quot;redefinition&quot;, variable-&gt;getName().c_str());
+            return true;
+            // don't delete variable, it's used by error recovery, and the pool 
+            // pop will take care of the memory
+        }
+    }
+
+    //
+    // identifier must be of type constant, a global, or a temporary
+    //
+    TQualifier qualifier = variable-&gt;getType().getQualifier();
+    if ((qualifier != EvqTemporary) &amp;&amp; (qualifier != EvqGlobal) &amp;&amp; (qualifier != EvqConst)) {
+        error(line, &quot; cannot initialize this type of qualifier &quot;, variable-&gt;getType().getQualifierString());
+        return true;
+    }
+    //
+    // test for and propagate constant
+    //
+
+    if (qualifier == EvqConst) {
+        if (qualifier != initializer-&gt;getType().getQualifier()) {
+            std::stringstream extraInfoStream;
+            extraInfoStream &lt;&lt; &quot;'&quot; &lt;&lt; variable-&gt;getType().getCompleteString() &lt;&lt; &quot;'&quot;;
+            std::string extraInfo = extraInfoStream.str();
+            error(line, &quot; assigning non-constant to&quot;, &quot;=&quot;, extraInfo.c_str());
+            variable-&gt;getType().setQualifier(EvqTemporary);
+            return true;
+        }
+        if (type != initializer-&gt;getType()) {
+            error(line, &quot; non-matching types for const initializer &quot;, 
+                variable-&gt;getType().getQualifierString());
+            variable-&gt;getType().setQualifier(EvqTemporary);
+            return true;
+        }
+        if (initializer-&gt;getAsConstantUnion()) { 
+            variable-&gt;shareConstPointer(initializer-&gt;getAsConstantUnion()-&gt;getUnionArrayPointer());
+        } else if (initializer-&gt;getAsSymbolNode()) {
+            const TSymbol* symbol = symbolTable.find(initializer-&gt;getAsSymbolNode()-&gt;getSymbol());
+            const TVariable* tVar = static_cast&lt;const TVariable*&gt;(symbol);
+
+            ConstantUnion* constArray = tVar-&gt;getConstPointer();
+            variable-&gt;shareConstPointer(constArray);
+        } else {
+            std::stringstream extraInfoStream;
+            extraInfoStream &lt;&lt; &quot;'&quot; &lt;&lt; variable-&gt;getType().getCompleteString() &lt;&lt; &quot;'&quot;;
+            std::string extraInfo = extraInfoStream.str();
+            error(line, &quot; cannot assign to&quot;, &quot;=&quot;, extraInfo.c_str());
+            variable-&gt;getType().setQualifier(EvqTemporary);
+            return true;
+        }
+    }

+    if (qualifier != EvqConst) {
+        TIntermSymbol* intermSymbol = intermediate.addSymbol(variable-&gt;getUniqueId(), variable-&gt;getName(), variable-&gt;getType(), line);
+        intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
+        if (intermNode == 0) {
+            assignError(line, &quot;=&quot;, intermSymbol-&gt;getCompleteString(), initializer-&gt;getCompleteString());
+            return true;
+        }
+    } else 
+        intermNode = 0;
+
+    return false;
+}
+
+bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
+{
+    ASSERT(aggrNode != NULL);
+    if (!aggrNode-&gt;isConstructor())
+        return false;
+
+    bool allConstant = true;
+
+    // check if all the child nodes are constants so that they can be inserted into 
+    // the parent node
+    TIntermSequence &amp;sequence = aggrNode-&gt;getSequence() ;
+    for (TIntermSequence::iterator p = sequence.begin(); p != sequence.end(); ++p) {
+        if (!(*p)-&gt;getAsTyped()-&gt;getAsConstantUnion())
+            return false;
+    }
+
+    return allConstant;
+}
+
+// This function is used to test for the correctness of the parameters passed to various constructor functions
+// and also convert them to the right datatype if it is allowed and required. 
+//
+// Returns 0 for an error or the constructed node (aggregate or typed) for no error.
+//
+TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type, TOperator op, TFunction* fnCall, const TSourceLoc&amp; line)
+{
+    if (node == 0)
+        return 0;
+
+    TIntermAggregate* aggrNode = node-&gt;getAsAggregate();
+    
+    TFieldList::const_iterator memberFields;
+    if (op == EOpConstructStruct)
+        memberFields = type-&gt;getStruct()-&gt;fields().begin();
+    
+    TType elementType = *type;
+    if (type-&gt;isArray())
+        elementType.clearArrayness();
+
+    bool singleArg;
+    if (aggrNode) {
+        if (aggrNode-&gt;getOp() != EOpNull || aggrNode-&gt;getSequence().size() == 1)
+            singleArg = true;
+        else
+            singleArg = false;
+    } else
+        singleArg = true;
+
+    TIntermTyped *newNode;
+    if (singleArg) {
+        // If structure constructor or array constructor is being called 
+        // for only one parameter inside the structure, we need to call constructStruct function once.
+        if (type-&gt;isArray())
+            newNode = constructStruct(node, &amp;elementType, 1, node-&gt;getLine(), false);
+        else if (op == EOpConstructStruct)
+            newNode = constructStruct(node, (*memberFields)-&gt;type(), 1, node-&gt;getLine(), false);
+        else
+            newNode = constructBuiltIn(type, op, node, node-&gt;getLine(), false);
+
+        if (newNode &amp;&amp; newNode-&gt;getAsAggregate()) {
+            TIntermTyped* constConstructor = foldConstConstructor(newNode-&gt;getAsAggregate(), *type);
+            if (constConstructor)
+                return constConstructor;
+        }
+
+        return newNode;
+    }
+    
+    //
+    // Handle list of arguments.
+    //
+    TIntermSequence &amp;sequenceVector = aggrNode-&gt;getSequence() ;    // Stores the information about the parameter to the constructor
+    // if the structure constructor contains more than one parameter, then construct
+    // each parameter
+    
+    int paramCount = 0;  // keeps a track of the constructor parameter number being checked    
+    
+    // for each parameter to the constructor call, check to see if the right type is passed or convert them 
+    // to the right type if possible (and allowed).
+    // for structure constructors, just check if the right type is passed, no conversion is allowed.
+    
+    for (TIntermSequence::iterator p = sequenceVector.begin(); 
+                                   p != sequenceVector.end(); p++, paramCount++) {
+        if (type-&gt;isArray())
+            newNode = constructStruct(*p, &amp;elementType, paramCount+1, node-&gt;getLine(), true);
+        else if (op == EOpConstructStruct)
+            newNode = constructStruct(*p, memberFields[paramCount]-&gt;type(), paramCount+1, node-&gt;getLine(), true);
+        else
+            newNode = constructBuiltIn(type, op, *p, node-&gt;getLine(), true);
+        
+        if (newNode) {
+            *p = newNode;
+        }
+    }
+
+    TIntermTyped* constructor = intermediate.setAggregateOperator(aggrNode, op, line);
+    TIntermTyped* constConstructor = foldConstConstructor(constructor-&gt;getAsAggregate(), *type);
+    if (constConstructor)
+        return constConstructor;
+
+    return constructor;
+}
+
+TIntermTyped* TParseContext::foldConstConstructor(TIntermAggregate* aggrNode, const TType&amp; type)
+{
+    bool canBeFolded = areAllChildConst(aggrNode);
+    aggrNode-&gt;setType(type);
+    if (canBeFolded) {
+        bool returnVal = false;
+        ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()];
+        if (aggrNode-&gt;getSequence().size() == 1)  {
+            returnVal = intermediate.parseConstTree(aggrNode-&gt;getLine(), aggrNode, unionArray, aggrNode-&gt;getOp(), symbolTable,  type, true);
+        }
+        else {
+            returnVal = intermediate.parseConstTree(aggrNode-&gt;getLine(), aggrNode, unionArray, aggrNode-&gt;getOp(), symbolTable,  type);
+        }
+        if (returnVal)
+            return 0;
+
+        return intermediate.addConstantUnion(unionArray, type, aggrNode-&gt;getLine());
+    }
+
+    return 0;
+}
+
+// Function for constructor implementation. Calls addUnaryMath with appropriate EOp value
+// for the parameter to the constructor (passed to this function). Essentially, it converts
+// the parameter types correctly. If a constructor expects an int (like ivec2) and is passed a 
+// float, then float is converted to int.
+//
+// Returns 0 for an error or the constructed node.
+//
+TIntermTyped* TParseContext::constructBuiltIn(const TType* type, TOperator op, TIntermNode* node, const TSourceLoc&amp; line, bool subset)
+{
+    TIntermTyped* newNode;
+    TOperator basicOp;
+
+    //
+    // First, convert types as needed.
+    //
+    switch (op) {
+    case EOpConstructVec2:
+    case EOpConstructVec3:
+    case EOpConstructVec4:
+    case EOpConstructMat2:
+    case EOpConstructMat3:
+    case EOpConstructMat4:
+    case EOpConstructFloat:
+        basicOp = EOpConstructFloat;
+        break;
+
+    case EOpConstructIVec2:
+    case EOpConstructIVec3:
+    case EOpConstructIVec4:
+    case EOpConstructInt:
+        basicOp = EOpConstructInt;
+        break;
+
+    case EOpConstructBVec2:
+    case EOpConstructBVec3:
+    case EOpConstructBVec4:
+    case EOpConstructBool:
+        basicOp = EOpConstructBool;
+        break;
+
+    default:
+        error(line, &quot;unsupported construction&quot;, &quot;&quot;);
+        recover();
+
+        return 0;
+    }
+    newNode = intermediate.addUnaryMath(basicOp, node, node-&gt;getLine(), symbolTable);
+    if (newNode == 0) {
+        error(line, &quot;can't convert&quot;, &quot;constructor&quot;);
+        return 0;
+    }
+
+    //
+    // Now, if there still isn't an operation to do the construction, and we need one, add one.
+    //
+    
+    // Otherwise, skip out early.
+    if (subset || (newNode != node &amp;&amp; newNode-&gt;getType() == *type))
+        return newNode;
+
+    // setAggregateOperator will insert a new node for the constructor, as needed.
+    return intermediate.setAggregateOperator(newNode, op, line);
+}
+
+// This function tests for the type of the parameters to the structures constructors. Raises
+// an error message if the expected type does not match the parameter passed to the constructor.
+//
+// Returns 0 for an error or the input node itself if the expected and the given parameter types match.
+//
+TIntermTyped* TParseContext::constructStruct(TIntermNode* node, TType* type, int paramCount, const TSourceLoc&amp; line, bool subset)
+{
+    if (*type == node-&gt;getAsTyped()-&gt;getType()) {
+        if (subset)
+            return node-&gt;getAsTyped();
+        else
+            return intermediate.setAggregateOperator(node-&gt;getAsTyped(), EOpConstructStruct, line);
+    } else {
+        std::stringstream extraInfoStream;
+        extraInfoStream &lt;&lt; &quot;cannot convert parameter &quot; &lt;&lt; paramCount 
+                        &lt;&lt; &quot; from '&quot; &lt;&lt; node-&gt;getAsTyped()-&gt;getType().getBasicString()
+                        &lt;&lt; &quot;' to '&quot; &lt;&lt; type-&gt;getBasicString() &lt;&lt; &quot;'&quot;;
+        std::string extraInfo = extraInfoStream.str();
+        error(line, &quot;&quot;, &quot;constructor&quot;, extraInfo.c_str());
+        recover();
+    }
+
+    return 0;
+}
+
+//
+// This function returns the tree representation for the vector field(s) being accessed from contant vector.
+// If only one component of vector is accessed (v.x or v[0] where v is a contant vector), then a contant node is
+// returned, else an aggregate node is returned (for v.xy). The input to this function could either be the symbol
+// node or it could be the intermediate tree representation of accessing fields in a constant structure or column of 
+// a constant matrix.
+//
+TIntermTyped* TParseContext::addConstVectorNode(TVectorFields&amp; fields, TIntermTyped* node, const TSourceLoc&amp; line)
+{
+    TIntermTyped* typedNode;
+    TIntermConstantUnion* tempConstantNode = node-&gt;getAsConstantUnion();
+
+    ConstantUnion *unionArray;
+    if (tempConstantNode) {
+        unionArray = tempConstantNode-&gt;getUnionArrayPointer();
+
+        if (!unionArray) {
+            return node;
+        }
+    } else { // The node has to be either a symbol node or an aggregate node or a tempConstant node, else, its an error
+        error(line, &quot;Cannot offset into the vector&quot;, &quot;Error&quot;);
+        recover();
+
+        return 0;
+    }
+
+    ConstantUnion* constArray = new ConstantUnion[fields.num];
+
+    for (int i = 0; i &lt; fields.num; i++) {
+        if (fields.offsets[i] &gt;= node-&gt;getType().getNominalSize()) {
+            std::stringstream extraInfoStream;
+            extraInfoStream &lt;&lt; &quot;vector field selection out of range '&quot; &lt;&lt; fields.offsets[i] &lt;&lt; &quot;'&quot;;
+            std::string extraInfo = extraInfoStream.str();
+            error(line, &quot;&quot;, &quot;[&quot;, extraInfo.c_str());
+            recover();
+            fields.offsets[i] = 0;
+        }
+        
+        constArray[i] = unionArray[fields.offsets[i]];
+
+    } 
+    typedNode = intermediate.addConstantUnion(constArray, node-&gt;getType(), line);
+    return typedNode;
+}
+
+//
+// This function returns the column being accessed from a constant matrix. The values are retrieved from
+// the symbol table and parse-tree is built for a vector (each column of a matrix is a vector). The input 
+// to the function could either be a symbol node (m[0] where m is a constant matrix)that represents a 
+// constant matrix or it could be the tree representation of the constant matrix (s.m1[0] where s is a constant structure)
+//
+TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, const TSourceLoc&amp; line)
+{
+    TIntermTyped* typedNode;
+    TIntermConstantUnion* tempConstantNode = node-&gt;getAsConstantUnion();
+
+    if (index &gt;= node-&gt;getType().getNominalSize()) {
+        std::stringstream extraInfoStream;
+        extraInfoStream &lt;&lt; &quot;matrix field selection out of range '&quot; &lt;&lt; index &lt;&lt; &quot;'&quot;;
+        std::string extraInfo = extraInfoStream.str();
+        error(line, &quot;&quot;, &quot;[&quot;, extraInfo.c_str());
+        recover();
+        index = 0;
+    }
+
+    if (tempConstantNode) {
+         ConstantUnion* unionArray = tempConstantNode-&gt;getUnionArrayPointer();
+         int size = tempConstantNode-&gt;getType().getNominalSize();
+         typedNode = intermediate.addConstantUnion(&amp;unionArray[size*index], tempConstantNode-&gt;getType(), line);
+    } else {
+        error(line, &quot;Cannot offset into the matrix&quot;, &quot;Error&quot;);
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+
+//
+// This function returns an element of an array accessed from a constant array. The values are retrieved from
+// the symbol table and parse-tree is built for the type of the element. The input 
+// to the function could either be a symbol node (a[0] where a is a constant array)that represents a 
+// constant array or it could be the tree representation of the constant array (s.a1[0] where s is a constant structure)
+//
+TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc&amp; line)
+{
+    TIntermTyped* typedNode;
+    TIntermConstantUnion* tempConstantNode = node-&gt;getAsConstantUnion();
+    TType arrayElementType = node-&gt;getType();
+    arrayElementType.clearArrayness();
+
+    if (index &gt;= node-&gt;getType().getArraySize()) {
+        std::stringstream extraInfoStream;
+        extraInfoStream &lt;&lt; &quot;array field selection out of range '&quot; &lt;&lt; index &lt;&lt; &quot;'&quot;;
+        std::string extraInfo = extraInfoStream.str();
+        error(line, &quot;&quot;, &quot;[&quot;, extraInfo.c_str());
+        recover();
+        index = 0;
+    }
+
+    if (tempConstantNode) {
+         size_t arrayElementSize = arrayElementType.getObjectSize();
+         ConstantUnion* unionArray = tempConstantNode-&gt;getUnionArrayPointer();
+         typedNode = intermediate.addConstantUnion(&amp;unionArray[arrayElementSize * index], tempConstantNode-&gt;getType(), line);
+    } else {
+        error(line, &quot;Cannot offset into the array&quot;, &quot;Error&quot;);
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+
+//
+// This function returns the value of a particular field inside a constant structure from the symbol table. 
+// If there is an embedded/nested struct, it appropriately calls addConstStructNested or addConstStructFromAggr
+// function and returns the parse-tree with the values of the embedded/nested struct.
+//
+TIntermTyped* TParseContext::addConstStruct(TString&amp; identifier, TIntermTyped* node, const TSourceLoc&amp; line)
+{
+    const TFieldList&amp; fields = node-&gt;getType().getStruct()-&gt;fields();
+
+    size_t instanceSize = 0;
+    for (size_t index = 0; index &lt; fields.size(); ++index) {
+        if (fields[index]-&gt;name() == identifier) {
+            break;
+        } else {
+            instanceSize += fields[index]-&gt;type()-&gt;getObjectSize();
+        }
+    }
+
+    TIntermTyped* typedNode = 0;
+    TIntermConstantUnion* tempConstantNode = node-&gt;getAsConstantUnion();
+    if (tempConstantNode) {
+         ConstantUnion* constArray = tempConstantNode-&gt;getUnionArrayPointer();
+
+         typedNode = intermediate.addConstantUnion(constArray+instanceSize, tempConstantNode-&gt;getType(), line); // type will be changed in the calling function
+    } else {
+        error(line, &quot;Cannot offset into the structure&quot;, &quot;Error&quot;);
+        recover();
+
+        return 0;
+    }
+
+    return typedNode;
+}
+
+bool TParseContext::enterStructDeclaration(const TSourceLoc&amp; line, const TString&amp; 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 &gt; 1) {
+        error(line, &quot;&quot;, &quot;Embedded struct definitions are not allowed&quot;);
+        return true;
+    }
+
+    return false;
+}
+
+void TParseContext::exitStructDeclaration()
+{
+    --structNestingLevel;
+}
+
+namespace {
+
+const int kWebGLMaxStructNesting = 4;
+
+}  // namespace
+
+bool TParseContext::structNestingErrorCheck(const TSourceLoc&amp; line, const TField&amp; field)
+{
+    if (!isWebGLBasedSpec(shaderSpec)) {
+        return false;
+    }
+
+    if (field.type()-&gt;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 + field.type()-&gt;getDeepestStructNesting() &gt; kWebGLMaxStructNesting) {
+        std::stringstream reasonStream;
+        reasonStream &lt;&lt; &quot;Reference of struct type &quot;
+                     &lt;&lt; field.type()-&gt;getStruct()-&gt;name().c_str()
+                     &lt;&lt; &quot; exceeds maximum allowed nesting level of &quot;
+                     &lt;&lt; kWebGLMaxStructNesting;
+        std::string reason = reasonStream.str();
+        error(line, reason.c_str(), field.name().c_str(), &quot;&quot;);
+        return true;
+    }
+
+    return false;
+}
+
+//
+// Parse an array index expression
+//
+TIntermTyped* TParseContext::addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc&amp; location, TIntermTyped *indexExpression)
+{
+    TIntermTyped *indexedExpression = NULL;
+
+    if (!baseExpression-&gt;isArray() &amp;&amp; !baseExpression-&gt;isMatrix() &amp;&amp; !baseExpression-&gt;isVector())
+    {
+        if (baseExpression-&gt;getAsSymbolNode())
+        {
+            error(location, &quot; left of '[' is not of type array, matrix, or vector &quot;, baseExpression-&gt;getAsSymbolNode()-&gt;getSymbol().c_str());
+        }
+        else
+        {
+            error(location, &quot; left of '[' is not of type array, matrix, or vector &quot;, &quot;expression&quot;);
+        }
+        recover();
+    }
+
+    if (indexExpression-&gt;getQualifier() == EvqConst)
+    {
+        int index = indexExpression-&gt;getAsConstantUnion()-&gt;getIConst(0);
+        if (index &lt; 0)
+        {
+            std::stringstream infoStream;
+            infoStream &lt;&lt; index;
+            std::string info = infoStream.str();
+            error(location, &quot;negative index&quot;, info.c_str());
+            recover();
+            index = 0;
+        }
+        if (baseExpression-&gt;getType().getQualifier() == EvqConst)
+        {
+            if (baseExpression-&gt;isArray())
+            {
+                // constant folding for arrays
+                indexedExpression = addConstArrayNode(index, baseExpression, location);
+            }
+            else if (baseExpression-&gt;isVector())
+            {
+                // constant folding for vectors
+                TVectorFields fields;
+                fields.num = 1;
+                fields.offsets[0] = index; // need to do it this way because v.xy sends fields integer array
+                indexedExpression = addConstVectorNode(fields, baseExpression, location);
+            }
+            else if (baseExpression-&gt;isMatrix())
+            {
+                // constant folding for matrices
+                indexedExpression = addConstMatrixNode(index, baseExpression, location);
+            }
+        }
+        else
+        {
+            if (baseExpression-&gt;isArray())
+            {
+                if (index &gt;= baseExpression-&gt;getType().getArraySize())
+                {
+                    std::stringstream extraInfoStream;
+                    extraInfoStream &lt;&lt; &quot;array index out of range '&quot; &lt;&lt; index &lt;&lt; &quot;'&quot;;
+                    std::string extraInfo = extraInfoStream.str();
+                    error(location, &quot;&quot;, &quot;[&quot;, extraInfo.c_str());
+                    recover();
+                    index = baseExpression-&gt;getType().getArraySize() - 1;
+                }
+                else if (baseExpression-&gt;getQualifier() == EvqFragData &amp;&amp; index &gt; 0 &amp;&amp; !isExtensionEnabled(&quot;GL_EXT_draw_buffers&quot;))
+                {
+                    error(location, &quot;&quot;, &quot;[&quot;, &quot;array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled&quot;);
+                    recover();
+                    index = 0;
+                }
+            }
+            else if ((baseExpression-&gt;isVector() || baseExpression-&gt;isMatrix()) &amp;&amp; baseExpression-&gt;getType().getNominalSize() &lt;= index)
+            {
+                std::stringstream extraInfoStream;
+                extraInfoStream &lt;&lt; &quot;field selection out of range '&quot; &lt;&lt; index &lt;&lt; &quot;'&quot;;
+                std::string extraInfo = extraInfoStream.str();
+                error(location, &quot;&quot;, &quot;[&quot;, extraInfo.c_str());
+                recover();
+                index = baseExpression-&gt;getType().getNominalSize() - 1;
+            }
+
+            indexExpression-&gt;getAsConstantUnion()-&gt;getUnionArrayPointer()-&gt;setIConst(index);
+            indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
+        }
+    }
+    else
+    {
+        indexedExpression = intermediate.addIndex(EOpIndexIndirect, baseExpression, indexExpression, location);
+    }
+
+    if (indexedExpression == 0)
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setFConst(0.0f);
+        indexedExpression = intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpHigh, EvqConst), location);
+    }
+    else if (baseExpression-&gt;isArray())
+    {
+        const TType &amp;baseType = baseExpression-&gt;getType();
+        if (baseType.getStruct())
+        {
+            TType copyOfType(baseType.getStruct());
+            indexedExpression-&gt;setType(copyOfType);
+        }
+        else
+        {
+            indexedExpression-&gt;setType(TType(baseExpression-&gt;getBasicType(), baseExpression-&gt;getPrecision(), EvqTemporary, baseExpression-&gt;getNominalSize(), baseExpression-&gt;isMatrix()));
+        }
+
+        if (baseExpression-&gt;getType().getQualifier() == EvqConst)
+        {
+            indexedExpression-&gt;getTypePointer()-&gt;setQualifier(EvqConst);
+        }
+    }
+    else if (baseExpression-&gt;isMatrix())
+    {
+        TQualifier qualifier = baseExpression-&gt;getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
+        indexedExpression-&gt;setType(TType(baseExpression-&gt;getBasicType(), baseExpression-&gt;getPrecision(), qualifier, baseExpression-&gt;getNominalSize()));
+    }
+    else if (baseExpression-&gt;isVector())
+    {
+        TQualifier qualifier = baseExpression-&gt;getType().getQualifier() == EvqConst ? EvqConst : EvqTemporary;
+        indexedExpression-&gt;setType(TType(baseExpression-&gt;getBasicType(), baseExpression-&gt;getPrecision(), qualifier));
+    }
+    else
+    {
+        indexedExpression-&gt;setType(baseExpression-&gt;getType());
+    }
+
+    return indexedExpression;
+}
+
+//
+// Parse an array of strings using yyparse.
+//
+// Returns 0 for success.
+//
+int PaParseStrings(size_t count, const char* const string[], const int length[],
+                   TParseContext* context) {
+    if ((count == 0) || (string == NULL))
+        return 1;
+
+    if (glslang_initialize(context))
+        return 1;
+
+    int error = glslang_scan(count, string, length, context);
+    if (!error)
+        error = glslang_parse(context);
+
+    glslang_finalize(context);
+
+    return (error == 0) &amp;&amp; (context-&gt;numErrors() == 0) ? 0 : 1;
+}
+
+
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorParseContexth"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,134 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+#ifndef _PARSER_HELPER_INCLUDED_
+#define _PARSER_HELPER_INCLUDED_
+
+#include &quot;compiler/translator/Diagnostics.h&quot;
+#include &quot;compiler/translator/DirectiveHandler.h&quot;
+#include &quot;compiler/translator/localintermediate.h&quot;
+#include &quot;compiler/preprocessor/Preprocessor.h&quot;
+#include &quot;compiler/translator/ShHandle.h&quot;
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+struct TMatrixFields {
+    bool wholeRow;
+    bool wholeCol;
+    int row;
+    int col;
+};
+
+//
+// The following are extra variables needed during parsing, grouped together so
+// they can be passed to the parser without needing a global.
+//
+struct TParseContext {
+    TParseContext(TSymbolTable&amp; symt, TExtensionBehavior&amp; ext, TIntermediate&amp; interm, ShShaderType type, ShShaderSpec spec, int options, bool checksPrecErrors, const char* sourcePath, TInfoSink&amp; is) :
+            intermediate(interm),
+            symbolTable(symt),
+            shaderType(type),
+            shaderSpec(spec),
+            compileOptions(options),
+            sourcePath(sourcePath),
+            treeRoot(0),
+            loopNestingLevel(0),
+            structNestingLevel(0),
+            currentFunctionType(NULL),
+            functionReturnsValue(false),
+            checksPrecisionErrors(checksPrecErrors),
+            diagnostics(is),
+            directiveHandler(ext, diagnostics),
+            preprocessor(&amp;diagnostics, &amp;directiveHandler),
+            scanner(NULL) {  }
+    TIntermediate&amp; intermediate; // to hold and build a parse tree
+    TSymbolTable&amp; symbolTable;   // symbol table that goes with the language currently being parsed
+    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
+    int loopNestingLevel;        // 0 if outside all loops
+    int structNestingLevel;      // incremented while parsing a struct declaration
+    const TType* currentFunctionType;  // the return type of the function that's currently being parsed
+    bool functionReturnsValue;   // true if a non-void function has a return
+    bool checksPrecisionErrors;  // true if an error will be generated when a variable is declared without precision, explicit or implicit.
+    bool fragmentPrecisionHigh;  // true if highp precision is supported in the fragment language.
+    TString HashErrMsg;
+    TDiagnostics diagnostics;
+    TDirectiveHandler directiveHandler;
+    pp::Preprocessor preprocessor;
+    void* scanner;
+
+    int numErrors() const { return diagnostics.numErrors(); }
+    TInfoSink&amp; infoSink() { return diagnostics.infoSink(); }
+    void error(const TSourceLoc&amp; loc, const char *reason, const char* token,
+               const char* extraInfo=&quot;&quot;);
+    void warning(const TSourceLoc&amp; loc, const char* reason, const char* token,
+                 const char* extraInfo=&quot;&quot;);
+    void trace(const char* str);
+    void recover();
+
+    bool parseVectorFields(const TString&amp;, int vecSize, TVectorFields&amp;, const TSourceLoc&amp; line);
+    bool parseMatrixFields(const TString&amp;, int matSize, TMatrixFields&amp;, const TSourceLoc&amp; line);
+
+    bool reservedErrorCheck(const TSourceLoc&amp; line, const TString&amp; identifier);
+    void assignError(const TSourceLoc&amp; line, const char* op, TString left, TString right);
+    void unaryOpError(const TSourceLoc&amp; line, const char* op, TString operand);
+    void binaryOpError(const TSourceLoc&amp; line, const char* op, TString left, TString right);
+    bool precisionErrorCheck(const TSourceLoc&amp; line, TPrecision precision, TBasicType type);
+    bool lValueErrorCheck(const TSourceLoc&amp; line, const char* op, TIntermTyped*);
+    bool constErrorCheck(TIntermTyped* node);
+    bool integerErrorCheck(TIntermTyped* node, const char* token);
+    bool globalErrorCheck(const TSourceLoc&amp; line, bool global, const char* token);
+    bool constructorErrorCheck(const TSourceLoc&amp; line, TIntermNode*, TFunction&amp;, TOperator, TType*);
+    bool arraySizeErrorCheck(const TSourceLoc&amp; line, TIntermTyped* expr, int&amp; size);
+    bool arrayQualifierErrorCheck(const TSourceLoc&amp; line, TPublicType type);
+    bool arrayTypeErrorCheck(const TSourceLoc&amp; line, TPublicType type);
+    bool arrayErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType type, TVariable*&amp; variable);
+    bool voidErrorCheck(const TSourceLoc&amp;, const TString&amp;, const TPublicType&amp;);
+    bool boolErrorCheck(const TSourceLoc&amp;, const TIntermTyped*);
+    bool boolErrorCheck(const TSourceLoc&amp;, const TPublicType&amp;);
+    bool samplerErrorCheck(const TSourceLoc&amp; line, const TPublicType&amp; pType, const char* reason);
+    bool structQualifierErrorCheck(const TSourceLoc&amp; line, const TPublicType&amp; pType);
+    bool parameterSamplerErrorCheck(const TSourceLoc&amp; line, TQualifier qualifier, const TType&amp; type);
+    bool nonInitConstErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; type, bool array);
+    bool nonInitErrorCheck(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; type, TVariable*&amp; variable);
+    bool paramErrorCheck(const TSourceLoc&amp; line, TQualifier qualifier, TQualifier paramQualifier, TType* type);
+    bool extensionErrorCheck(const TSourceLoc&amp; line, const TString&amp;);
+
+    const TPragma&amp; pragma() const { return directiveHandler.pragma(); }
+    const TExtensionBehavior&amp; extensionBehavior() const { return directiveHandler.extensionBehavior(); }
+    bool supportsExtension(const char* extension);
+    bool isExtensionEnabled(const char* extension) const;
+
+    bool containsSampler(TType&amp; type);
+    bool areAllChildConst(TIntermAggregate* aggrNode);
+    const TFunction* findFunction(const TSourceLoc&amp; line, TFunction* pfnCall, bool *builtIn = 0);
+    bool executeInitializer(const TSourceLoc&amp; line, TString&amp; identifier, TPublicType&amp; pType,
+                            TIntermTyped* initializer, TIntermNode*&amp; intermNode, TVariable* variable = 0);
+
+    TIntermTyped* addConstructor(TIntermNode*, const TType*, TOperator, TFunction*, const TSourceLoc&amp;);
+    TIntermTyped* foldConstConstructor(TIntermAggregate* aggrNode, const TType&amp; type);
+    TIntermTyped* constructStruct(TIntermNode*, TType*, int, const TSourceLoc&amp;, bool subset);
+    TIntermTyped* constructBuiltIn(const TType*, TOperator, TIntermNode*, const TSourceLoc&amp;, bool subset);
+    TIntermTyped* addConstVectorNode(TVectorFields&amp;, TIntermTyped*, const TSourceLoc&amp;);
+    TIntermTyped* addConstMatrixNode(int , TIntermTyped*, const TSourceLoc&amp;);
+    TIntermTyped* addConstArrayNode(int index, TIntermTyped* node, const TSourceLoc&amp; line);
+    TIntermTyped* addConstStruct(TString&amp; , TIntermTyped*, const TSourceLoc&amp;);
+    TIntermTyped* addIndexExpression(TIntermTyped *baseExpression, const TSourceLoc&amp; location, TIntermTyped *indexExpression);
+
+    // Performs an error check for embedded struct declarations.
+    // Returns true if an error was raised due to the declaration of
+    // this struct.
+    bool enterStructDeclaration(const TSourceLoc&amp; line, const TString&amp; identifier);
+    void exitStructDeclaration();
+
+    bool structNestingErrorCheck(const TSourceLoc&amp; line, const TField&amp; field);
+};
+
+int PaParseStrings(size_t count, const char* const string[], const int length[],
+                   TParseContext* context);
+
+#endif // _PARSER_HELPER_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ParseContext.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorPoolAlloccpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,294 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/PoolAlloc.h&quot;
+
+#ifndef _MSC_VER
+#include &lt;stdint.h&gt;
+#endif
+#include &lt;stdio.h&gt;
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;compiler/translator/InitializeGlobals.h&quot;
+#include &quot;compiler/translator/osinclude.h&quot;
+
+OS_TLSIndex PoolIndex = OS_INVALID_TLS_INDEX;
+
+bool InitializePoolIndex()
+{
+    assert(PoolIndex == OS_INVALID_TLS_INDEX);
+
+    PoolIndex = OS_AllocTLSIndex();
+    return PoolIndex != OS_INVALID_TLS_INDEX;
+}
+
+void FreePoolIndex()
+{
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+
+    OS_FreeTLSIndex(PoolIndex);
+    PoolIndex = OS_INVALID_TLS_INDEX;
+}
+
+TPoolAllocator* GetGlobalPoolAllocator()
+{
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    return static_cast&lt;TPoolAllocator*&gt;(OS_GetTLSValue(PoolIndex));
+}
+
+void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator)
+{
+    assert(PoolIndex != OS_INVALID_TLS_INDEX);
+    OS_SetTLSValue(PoolIndex, poolAllocator);
+}
+
+//
+// Implement the functionality of the TPoolAllocator class, which
+// is documented in PoolAlloc.h.
+//
+TPoolAllocator::TPoolAllocator(int growthIncrement, int allocationAlignment) : 
+    pageSize(growthIncrement),
+    alignment(allocationAlignment),
+    freeList(0),
+    inUseList(0),
+    numCalls(0),
+    totalBytes(0)
+{
+    //
+    // Don't allow page sizes we know are smaller than all common
+    // OS page sizes.
+    //
+    if (pageSize &lt; 4*1024)
+        pageSize = 4*1024;
+
+    //
+    // A large currentPageOffset indicates a new page needs to
+    // be obtained to allocate memory.
+    //
+    currentPageOffset = pageSize;
+
+    //
+    // Adjust alignment to be at least pointer aligned and
+    // power of 2.
+    //
+    size_t minAlign = sizeof(void*);
+    alignment &amp;= ~(minAlign - 1);
+    if (alignment &lt; minAlign)
+        alignment = minAlign;
+    size_t a = 1;
+    while (a &lt; alignment)
+        a &lt;&lt;= 1;
+    alignment = a;
+    alignmentMask = a - 1;
+
+    //
+    // Align header skip
+    //
+    headerSkip = minAlign;
+    if (headerSkip &lt; sizeof(tHeader)) {
+        headerSkip = (sizeof(tHeader) + alignmentMask) &amp; ~alignmentMask;
+    }
+}
+
+TPoolAllocator::~TPoolAllocator()
+{
+    while (inUseList) {
+        tHeader* next = inUseList-&gt;nextPage;
+        inUseList-&gt;~tHeader();
+        delete [] reinterpret_cast&lt;char*&gt;(inUseList);
+        inUseList = next;
+    }
+
+    // We should not check the guard blocks
+    // here, because we did it already when the block was
+    // placed into the free list.
+    //
+    while (freeList) {
+        tHeader* next = freeList-&gt;nextPage;
+        delete [] reinterpret_cast&lt;char*&gt;(freeList);
+        freeList = next;
+    }
+}
+
+// Support MSVC++ 6.0
+const unsigned char TAllocation::guardBlockBeginVal = 0xfb;
+const unsigned char TAllocation::guardBlockEndVal   = 0xfe;
+const unsigned char TAllocation::userDataFill       = 0xcd;
+
+#ifdef GUARD_BLOCKS
+    const size_t TAllocation::guardBlockSize = 16;
+#else
+    const size_t TAllocation::guardBlockSize = 0;
+#endif
+
+//
+// Check a single guard block for damage
+//
+void TAllocation::checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const
+{
+#ifdef GUARD_BLOCKS
+    for (size_t x = 0; x &lt; guardBlockSize; x++) {
+        if (blockMem[x] != val) {
+            char assertMsg[80];
+
+            // We don't print the assert message.  It's here just to be helpful.
+#if defined(_MSC_VER)
+            snprintf(assertMsg, sizeof(assertMsg), &quot;PoolAlloc: Damage %s %Iu byte allocation at 0x%p\n&quot;,
+                    locText, size, data());
+#else
+            snprintf(assertMsg, sizeof(assertMsg), &quot;PoolAlloc: Damage %s %zu byte allocation at 0x%p\n&quot;,
+                    locText, size, data());
+#endif
+            assert(0 &amp;&amp; &quot;PoolAlloc: Damage in guard block&quot;);
+        }
+    }
+#endif
+}
+
+
+void TPoolAllocator::push()
+{
+    tAllocState state = { currentPageOffset, inUseList };
+
+    stack.push_back(state);
+        
+    //
+    // Indicate there is no current page to allocate from.
+    //
+    currentPageOffset = pageSize;
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred since the last push(), or since the
+// last pop(), or since the object's creation.
+//
+// The deallocated pages are saved for future allocations.
+//
+void TPoolAllocator::pop()
+{
+    if (stack.size() &lt; 1)
+        return;
+
+    tHeader* page = stack.back().page;
+    currentPageOffset = stack.back().offset;
+
+    while (inUseList != page) {
+        // invoke destructor to free allocation list
+        inUseList-&gt;~tHeader();
+        
+        tHeader* nextInUse = inUseList-&gt;nextPage;
+        if (inUseList-&gt;pageCount &gt; 1)
+            delete [] reinterpret_cast&lt;char*&gt;(inUseList);
+        else {
+            inUseList-&gt;nextPage = freeList;
+            freeList = inUseList;
+        }
+        inUseList = nextInUse;
+    }
+
+    stack.pop_back();
+}
+
+//
+// Do a mass-deallocation of all the individual allocations
+// that have occurred.
+//
+void TPoolAllocator::popAll()
+{
+    while (stack.size() &gt; 0)
+        pop();
+}
+
+void* TPoolAllocator::allocate(size_t numBytes)
+{
+    //
+    // Just keep some interesting statistics.
+    //
+    ++numCalls;
+    totalBytes += numBytes;
+
+    // If we are using guard blocks, all allocations are bracketed by
+    // them: [guardblock][allocation][guardblock].  numBytes is how
+    // much memory the caller asked for.  allocationSize is the total
+    // size including guard blocks.  In release build,
+    // guardBlockSize=0 and this all gets optimized away.
+    size_t allocationSize = TAllocation::allocationSize(numBytes);
+    // Detect integer overflow.
+    if (allocationSize &lt; numBytes)
+        return 0;
+
+    //
+    // Do the allocation, most likely case first, for efficiency.
+    // This step could be moved to be inline sometime.
+    //
+    if (allocationSize &lt;= pageSize - currentPageOffset) {
+        //
+        // Safe to allocate from currentPageOffset.
+        //
+        unsigned char* memory = reinterpret_cast&lt;unsigned char *&gt;(inUseList) + currentPageOffset;
+        currentPageOffset += allocationSize;
+        currentPageOffset = (currentPageOffset + alignmentMask) &amp; ~alignmentMask;
+
+        return initializeAllocation(inUseList, memory, numBytes);
+    }
+
+    if (allocationSize &gt; pageSize - headerSkip) {
+        //
+        // Do a multi-page allocation.  Don't mix these with the others.
+        // The OS is efficient and allocating and free-ing multiple pages.
+        //
+        size_t numBytesToAlloc = allocationSize + headerSkip;
+        // Detect integer overflow.
+        if (numBytesToAlloc &lt; allocationSize)
+            return 0;
+
+        tHeader* memory = reinterpret_cast&lt;tHeader*&gt;(::new char[numBytesToAlloc]);
+        if (memory == 0)
+            return 0;
+
+        // Use placement-new to initialize header
+        new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize);
+        inUseList = memory;
+
+        currentPageOffset = pageSize;  // make next allocation come from a new page
+
+        // No guard blocks for multi-page allocations (yet)
+        return reinterpret_cast&lt;void*&gt;(reinterpret_cast&lt;uintptr_t&gt;(memory) + headerSkip);
+    }
+
+    //
+    // Need a simple page to allocate from.
+    //
+    tHeader* memory;
+    if (freeList) {
+        memory = freeList;
+        freeList = freeList-&gt;nextPage;
+    } else {
+        memory = reinterpret_cast&lt;tHeader*&gt;(::new char[pageSize]);
+        if (memory == 0)
+            return 0;
+    }
+
+    // Use placement-new to initialize header
+    new(memory) tHeader(inUseList, 1);
+    inUseList = memory;
+    
+    unsigned char* ret = reinterpret_cast&lt;unsigned char *&gt;(inUseList) + headerSkip;
+    currentPageOffset = (headerSkip + allocationSize + alignmentMask) &amp; ~alignmentMask;
+
+    return initializeAllocation(inUseList, ret, numBytes);
+}
+
+
+//
+// Check all allocations in a list for damage by calling check on each.
+//
+void TAllocation::checkAllocList() const
+{
+    for (const TAllocation* alloc = this; alloc != 0; alloc = alloc-&gt;prevAlloc)
+        alloc-&gt;check();
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorPoolAlloch"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,300 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _POOLALLOC_INCLUDED_
+#define _POOLALLOC_INCLUDED_
+
+#ifdef _DEBUG
+#define GUARD_BLOCKS  // define to enable guard block sanity checking
+#endif
+
+//
+// This header defines an allocator that can be used to efficiently
+// allocate a large number of small requests for heap memory, with the 
+// intention that they are not individually deallocated, but rather 
+// collectively deallocated at one time.
+//
+// This simultaneously
+//
+// * Makes each individual allocation much more efficient; the
+//     typical allocation is trivial.
+// * Completely avoids the cost of doing individual deallocation.
+// * Saves the trouble of tracking down and plugging a large class of leaks.
+//
+// Individual classes can use this allocator by supplying their own
+// new and delete methods.
+//
+// STL containers can use this allocator by using the pool_allocator
+// class as the allocator (second) template argument.
+//
+
+#include &lt;stddef.h&gt;
+#include &lt;string.h&gt;
+#include &lt;vector&gt;
+
+// If we are using guard blocks, we must track each indivual
+// allocation.  If we aren't using guard blocks, these
+// never get instantiated, so won't have any impact.
+// 
+
+class TAllocation {
+public:
+    TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) :
+        size(size), mem(mem), prevAlloc(prev) {
+        // Allocations are bracketed:
+        //    [allocationHeader][initialGuardBlock][userData][finalGuardBlock]
+        // This would be cleaner with if (guardBlockSize)..., but that
+        // makes the compiler print warnings about 0 length memsets,
+        // even with the if() protecting them.
+#ifdef GUARD_BLOCKS
+        memset(preGuard(), guardBlockBeginVal, guardBlockSize);
+        memset(data(),      userDataFill,       size);
+        memset(postGuard(), guardBlockEndVal,   guardBlockSize);
+#endif
+    }
+
+    void check() const {
+        checkGuardBlock(preGuard(),  guardBlockBeginVal, &quot;before&quot;);
+        checkGuardBlock(postGuard(), guardBlockEndVal,   &quot;after&quot;);
+    }
+
+    void checkAllocList() const;
+
+    // Return total size needed to accomodate user buffer of 'size',
+    // plus our tracking data.
+    inline static size_t allocationSize(size_t size) {
+        return size + 2 * guardBlockSize + headerSize();
+    }
+
+    // Offset from surrounding buffer to get to user data buffer.
+    inline static unsigned char* offsetAllocation(unsigned char* m) {
+        return m + guardBlockSize + headerSize();
+    }
+
+private:
+    void checkGuardBlock(unsigned char* blockMem, unsigned char val, const char* locText) const;
+
+    // Find offsets to pre and post guard blocks, and user data buffer
+    unsigned char* preGuard()  const { return mem + headerSize(); }
+    unsigned char* data()      const { return preGuard() + guardBlockSize; }
+    unsigned char* postGuard() const { return data() + size; }
+
+    size_t size;                  // size of the user data area
+    unsigned char* mem;           // beginning of our allocation (pts to header)
+    TAllocation* prevAlloc;       // prior allocation in the chain
+
+    // Support MSVC++ 6.0
+    const static unsigned char guardBlockBeginVal;
+    const static unsigned char guardBlockEndVal;
+    const static unsigned char userDataFill;
+
+    const static size_t guardBlockSize;
+#ifdef GUARD_BLOCKS
+    inline static size_t headerSize() { return sizeof(TAllocation); }
+#else
+    inline static size_t headerSize() { return 0; }
+#endif
+};
+
+//
+// There are several stacks.  One is to track the pushing and popping
+// of the user, and not yet implemented.  The others are simply a 
+// repositories of free pages or used pages.
+//
+// Page stacks are linked together with a simple header at the beginning
+// of each allocation obtained from the underlying OS.  Multi-page allocations
+// are returned to the OS.  Individual page allocations are kept for future
+// re-use.
+//
+// The &quot;page size&quot; used is not, nor must it match, the underlying OS
+// page size.  But, having it be about that size or equal to a set of 
+// pages is likely most optimal.
+//
+class TPoolAllocator {
+public:
+    TPoolAllocator(int growthIncrement = 8*1024, int allocationAlignment = 16);
+
+    //
+    // Don't call the destructor just to free up the memory, call pop()
+    //
+    ~TPoolAllocator();
+
+    //
+    // Call push() to establish a new place to pop memory too.  Does not
+    // have to be called to get things started.
+    //
+    void push();
+
+    //
+    // Call pop() to free all memory allocated since the last call to push(),
+    // or if no last call to push, frees all memory since first allocation.
+    //
+    void pop();
+
+    //
+    // Call popAll() to free all memory allocated.
+    //
+    void popAll();
+
+    //
+    // Call allocate() to actually acquire memory.  Returns 0 if no memory
+    // available, otherwise a properly aligned pointer to 'numBytes' of memory.
+    //
+    void* allocate(size_t numBytes);
+
+    //
+    // There is no deallocate.  The point of this class is that
+    // deallocation can be skipped by the user of it, as the model
+    // of use is to simultaneously deallocate everything at once
+    // by calling pop(), and to not have to solve memory leak problems.
+    //
+
+protected:
+    friend struct tHeader;
+    
+    struct tHeader {
+        tHeader(tHeader* nextPage, size_t pageCount) :
+            nextPage(nextPage),
+            pageCount(pageCount)
+#ifdef GUARD_BLOCKS
+          , lastAllocation(0)
+#endif
+            { }
+
+        ~tHeader() {
+#ifdef GUARD_BLOCKS
+            if (lastAllocation)
+                lastAllocation-&gt;checkAllocList();
+#endif
+        }
+
+        tHeader* nextPage;
+        size_t pageCount;
+#ifdef GUARD_BLOCKS
+        TAllocation* lastAllocation;
+#endif
+    };
+
+    struct tAllocState {
+        size_t offset;
+        tHeader* page;
+    };
+    typedef std::vector&lt;tAllocState&gt; tAllocStack;
+
+    // Track allocations if and only if we're using guard blocks
+    void* initializeAllocation(tHeader* block, unsigned char* memory, size_t numBytes) {
+#ifdef GUARD_BLOCKS
+        new(memory) TAllocation(numBytes, memory, block-&gt;lastAllocation);
+        block-&gt;lastAllocation = reinterpret_cast&lt;TAllocation*&gt;(memory);
+#endif
+        // This is optimized entirely away if GUARD_BLOCKS is not defined.
+        return TAllocation::offsetAllocation(memory);
+    }
+
+    size_t pageSize;        // granularity of allocation from the OS
+    size_t alignment;       // all returned allocations will be aligned at 
+                            // this granularity, which will be a power of 2
+    size_t alignmentMask;
+    size_t headerSkip;      // amount of memory to skip to make room for the
+                            //      header (basically, size of header, rounded
+                            //      up to make it aligned
+    size_t currentPageOffset;  // next offset in top of inUseList to allocate from
+    tHeader* freeList;      // list of popped memory
+    tHeader* inUseList;     // list of all memory currently being used
+    tAllocStack stack;      // stack of where to allocate from, to partition pool
+
+    int numCalls;           // just an interesting statistic
+    size_t totalBytes;      // just an interesting statistic
+private:
+    TPoolAllocator&amp; operator=(const TPoolAllocator&amp;);  // dont allow assignment operator
+    TPoolAllocator(const TPoolAllocator&amp;);  // dont allow default copy constructor
+};
+
+
+//
+// There could potentially be many pools with pops happening at
+// different times.  But a simple use is to have a global pop
+// with everyone using the same global allocator.
+//
+extern TPoolAllocator* GetGlobalPoolAllocator();
+extern void SetGlobalPoolAllocator(TPoolAllocator* poolAllocator);
+
+//
+// This STL compatible allocator is intended to be used as the allocator
+// parameter to templatized STL containers, like vector and map.
+//
+// It will use the pools for allocation, and not
+// do any deallocation, but will still do destruction.
+//
+template&lt;class T&gt;
+class pool_allocator {
+public:
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+    typedef T&amp; reference;
+    typedef const T&amp; const_reference;
+    typedef T value_type;
+
+    template&lt;class Other&gt; 
+    struct rebind {
+        typedef pool_allocator&lt;Other&gt; other;
+    };
+    pointer address(reference x) const { return &amp;x; }
+    const_pointer address(const_reference x) const { return &amp;x; }
+
+    pool_allocator() : allocator(GetGlobalPoolAllocator()) { }
+    pool_allocator(TPoolAllocator&amp; a) : allocator(&amp;a) { }
+    pool_allocator(const pool_allocator&lt;T&gt;&amp; p) : allocator(p.allocator) { }
+
+    template &lt;class Other&gt;
+    pool_allocator&lt;T&gt;&amp; operator=(const pool_allocator&lt;Other&gt;&amp; p) {
+      allocator = p.allocator;
+      return *this;
+    }
+
+    template&lt;class Other&gt;
+    pool_allocator(const pool_allocator&lt;Other&gt;&amp; p) : allocator(&amp;p.getAllocator()) { }
+
+#if defined(__SUNPRO_CC) &amp;&amp; !defined(_RWSTD_ALLOCATOR)
+    // libCStd on some platforms have a different allocate/deallocate interface.
+    // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+    // allocated, not the number of elements.
+    void* allocate(size_type n) { 
+        return getAllocator().allocate(n);
+    }
+    void* allocate(size_type n, const void*) {
+        return getAllocator().allocate(n);
+    }
+    void deallocate(void*, size_type) {}
+#else
+    pointer allocate(size_type n) { 
+        return reinterpret_cast&lt;pointer&gt;(getAllocator().allocate(n * sizeof(T)));
+    }
+    pointer allocate(size_type n, const void*) { 
+        return reinterpret_cast&lt;pointer&gt;(getAllocator().allocate(n * sizeof(T)));
+    }
+    void deallocate(pointer, size_type) {}
+#endif  // _RWSTD_ALLOCATOR
+
+    void construct(pointer p, const T&amp; val) { new ((void *)p) T(val); }
+    void destroy(pointer p) { p-&gt;T::~T(); }
+
+    bool operator==(const pool_allocator&amp; rhs) const { return &amp;getAllocator() == &amp;rhs.getAllocator(); }
+    bool operator!=(const pool_allocator&amp; rhs) const { return &amp;getAllocator() != &amp;rhs.getAllocator(); }
+
+    size_type max_size() const { return static_cast&lt;size_type&gt;(-1) / sizeof(T); }
+    size_type max_size(int size) const { return static_cast&lt;size_type&gt;(-1) / size; }
+
+    void setAllocator(TPoolAllocator* a) { allocator = a; }
+    TPoolAllocator&amp; getAllocator() const { return *allocator; }
+
+protected:
+    TPoolAllocator* allocator;
+};
+
+#endif // _POOLALLOC_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/PoolAlloc.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorPragmah"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Pragma.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Pragma.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Pragma.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,19 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_PRAGMA_H_
+#define COMPILER_PRAGMA_H_
+
+struct TPragma {
+    // By default optimization is turned on and debug is turned off.
+    TPragma() : optimize(true), debug(false) { }
+    TPragma(bool o, bool d) : optimize(o), debug(d) { }
+
+    bool optimize;
+    bool debug;
+};
+
+#endif // COMPILER_PRAGMA_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Pragma.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorQualifierAlivecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+class TAliveTraverser : public TIntermTraverser {
+public:
+    TAliveTraverser(TQualifier q) : TIntermTraverser(true, false, false, true), found(false), qualifier(q)
+    {
+    }
+
+    bool wasFound() { return found; }
+
+protected:
+    bool found;
+    TQualifier qualifier;
+
+    void visitSymbol(TIntermSymbol*);
+    bool visitSelection(Visit, TIntermSelection*);
+};
+
+//
+// Report whether or not a variable of the given qualifier type
+// is guaranteed written.  Not always possible to determine if
+// it is written conditionally.
+//
+// ?? It does not do this well yet, this is just a place holder
+// that simply determines if it was reference at all, anywhere.
+//
+bool QualifierWritten(TIntermNode* node, TQualifier qualifier)
+{
+    TAliveTraverser it(qualifier);
+
+    if (node)
+        node-&gt;traverse(&amp;it);
+
+    return it.wasFound();
+}
+
+void TAliveTraverser::visitSymbol(TIntermSymbol* node)
+{
+    //
+    // If it's what we're looking for, record it.
+    //
+    if (node-&gt;getQualifier() == qualifier)
+        found = true;
+}
+
+bool TAliveTraverser::visitSelection(Visit preVisit, TIntermSelection* node)
+{
+    if (wasFound())
+        return false;
+
+    return true;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorQualifierAliveh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+//
+// 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.
+//
+
+bool QualifierWritten(TIntermNode* root, TQualifier);
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/QualifierAlive.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorRemoveTreecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/RemoveTree.h&quot;
+
+//
+// Code to recursively delete the intermediate tree.
+//
+
+class RemoveTree : public TIntermTraverser
+{
+public:
+    RemoveTree() : TIntermTraverser(false, false, true)
+    {
+    }
+
+protected:
+    void visitSymbol(TIntermSymbol*);
+    void visitConstantUnion(TIntermConstantUnion*);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitUnary(Visit visit, TIntermUnary*);
+    bool visitSelection(Visit visit, TIntermSelection*);
+    bool visitAggregate(Visit visit, TIntermAggregate*);
+};
+
+void RemoveTree::visitSymbol(TIntermSymbol* node)
+{
+    delete node;
+}
+
+bool RemoveTree::visitBinary(Visit visit, TIntermBinary* node)
+{
+    delete node;
+
+    return true;
+}
+
+bool RemoveTree::visitUnary(Visit visit, TIntermUnary* node)
+{
+    delete node;
+
+    return true;
+}
+
+bool RemoveTree::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    delete node;
+
+    return true;
+}
+
+bool RemoveTree::visitSelection(Visit visit, TIntermSelection* node)
+{
+    delete node;
+
+    return true;
+}
+
+void RemoveTree::visitConstantUnion(TIntermConstantUnion* node)
+{
+    delete node;
+}
+
+//
+// Entry point.
+//
+void RemoveAllTreeNodes(TIntermNode* root)
+{
+    RemoveTree it;
+
+    root-&gt;traverse(&amp;it);
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorRemoveTreeh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+//
+// 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.
+//
+
+void RemoveAllTreeNodes(TIntermNode*);
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RemoveTree.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorRenameFunctionh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_RENAME_FUNCTION
+#define COMPILER_RENAME_FUNCTION
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+//
+// Renames a function, including its declaration and any calls to it.
+//
+class RenameFunction : public TIntermTraverser
+{
+public:
+    RenameFunction(const TString&amp; oldFunctionName, const TString&amp; newFunctionName)
+    : TIntermTraverser(true, false, false)
+    , mOldFunctionName(oldFunctionName)
+    , mNewFunctionName(newFunctionName) {}
+
+    virtual bool visitAggregate(Visit visit, TIntermAggregate* node)
+    {
+        TOperator op = node-&gt;getOp();
+        if ((op == EOpFunction || op == EOpFunctionCall) &amp;&amp; node-&gt;getName() == mOldFunctionName)
+            node-&gt;setName(mNewFunctionName);
+        return true;
+    }
+
+private:
+    const TString mOldFunctionName;
+    const TString mNewFunctionName;
+};
+
+#endif  // COMPILER_RENAME_FUNCTION
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RenameFunction.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorRewriteElseBlockscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteElseBlocks.cpp: Implementation for tree transform to change
+//   all if-else blocks to if-if blocks.
+//
+
+#include &quot;compiler/translator/RewriteElseBlocks.h&quot;
+#include &quot;compiler/translator/NodeSearch.h&quot;
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+namespace sh
+{
+
+TIntermSymbol *MakeNewTemporary(const TString &amp;name, TBasicType type)
+{
+    TType variableType(type, EbpHigh, EvqInternal);
+    return new TIntermSymbol(-1, name, variableType);
+}
+
+TIntermBinary *MakeNewBinary(TOperator op, TIntermTyped *left, TIntermTyped *right, const TType &amp;resultType)
+{
+    TIntermBinary *binary = new TIntermBinary(op);
+    binary-&gt;setLeft(left);
+    binary-&gt;setRight(right);
+    binary-&gt;setType(resultType);
+    return binary;
+}
+
+TIntermUnary *MakeNewUnary(TOperator op, TIntermTyped *operand)
+{
+    TIntermUnary *unary = new TIntermUnary(op, operand-&gt;getType());
+    unary-&gt;setOperand(operand);
+    return unary;
+}
+
+bool ElseBlockRewriter::visitAggregate(Visit visit, TIntermAggregate *node)
+{
+    switch (node-&gt;getOp())
+    {
+      case EOpSequence:
+        {
+            for (size_t statementIndex = 0; statementIndex != node-&gt;getSequence().size(); statementIndex++)
+            {
+                TIntermNode *statement = node-&gt;getSequence()[statementIndex];
+                TIntermSelection *selection = statement-&gt;getAsSelectionNode();
+                if (selection &amp;&amp; selection-&gt;getFalseBlock() != NULL)
+                {
+                    node-&gt;getSequence()[statementIndex] = rewriteSelection(selection);
+                    delete selection;
+                }
+            }
+        }
+        break;
+
+      default: break;
+    }
+
+    return true;
+}
+
+TIntermNode *ElseBlockRewriter::rewriteSelection(TIntermSelection *selection)
+{
+    ASSERT(selection-&gt;getFalseBlock() != NULL);
+
+    TString temporaryName = &quot;cond_&quot; + str(mTemporaryIndex++);
+    TIntermTyped *typedCondition = selection-&gt;getCondition()-&gt;getAsTyped();
+    TType resultType(EbtBool, EbpUndefined);
+    TIntermSymbol *conditionSymbolA = MakeNewTemporary(temporaryName, EbtBool);
+    TIntermSymbol *conditionSymbolB = MakeNewTemporary(temporaryName, EbtBool);
+    TIntermSymbol *conditionSymbolC = MakeNewTemporary(temporaryName, EbtBool);
+    TIntermBinary *storeCondition = MakeNewBinary(EOpInitialize, conditionSymbolA,
+                                                  typedCondition, resultType);
+    TIntermUnary *negatedCondition = MakeNewUnary(EOpLogicalNot, conditionSymbolB);
+    TIntermSelection *falseBlock = new TIntermSelection(negatedCondition,
+                                                        selection-&gt;getFalseBlock(), NULL);
+    TIntermSelection *newIfElse = new TIntermSelection(conditionSymbolC,
+                                                       selection-&gt;getTrueBlock(), falseBlock);
+
+    TIntermAggregate *declaration = new TIntermAggregate(EOpDeclaration);
+    declaration-&gt;getSequence().push_back(storeCondition);
+
+    TIntermAggregate *block = new TIntermAggregate(EOpSequence);
+    block-&gt;getSequence().push_back(declaration);
+    block-&gt;getSequence().push_back(newIfElse);
+
+    return block;
+}
+
+void RewriteElseBlocks(TIntermNode *node)
+{
+    ElseBlockRewriter rewriter;
+    node-&gt;traverse(&amp;rewriter);
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorRewriteElseBlocksh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// RewriteElseBlocks.h: Prototype for tree transform to change
+//   all if-else blocks to if-if blocks.
+//
+
+#ifndef COMPILER_REWRITE_ELSE_BLOCKS_H_
+#define COMPILER_REWRITE_ELSE_BLOCKS_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+namespace sh
+{
+
+class ElseBlockRewriter : public TIntermTraverser
+{
+  public:
+      ElseBlockRewriter()
+          : TIntermTraverser(false, false, true, false)
+          , mTemporaryIndex(0)
+      {}
+
+  protected:
+    bool visitAggregate(Visit visit, TIntermAggregate *aggregate);
+
+  private:
+    int mTemporaryIndex;
+
+    TIntermNode *rewriteSelection(TIntermSelection *selection);
+};
+
+void RewriteElseBlocks(TIntermNode *node);
+
+}
+
+#endif // COMPILER_REWRITE_ELSE_BLOCKS_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/RewriteElseBlocks.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorSearchSymbolcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#include &quot;compiler/translator/SearchSymbol.h&quot;
+
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/OutputHLSL.h&quot;
+
+namespace sh
+{
+SearchSymbol::SearchSymbol(const TString &amp;symbol) : mSymbol(symbol)
+{
+    match = false;
+}
+
+void SearchSymbol::traverse(TIntermNode *node)
+{
+    node-&gt;traverse(this);
+}
+
+void SearchSymbol::visitSymbol(TIntermSymbol *symbolNode)
+{
+    if (symbolNode-&gt;getSymbol() == mSymbol)
+    {
+        match = true;
+    }
+}
+
+bool SearchSymbol::foundMatch() const
+{
+    return match;
+}
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorSearchSymbolh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// SearchSymbol is an AST traverser to detect the use of a given symbol name
+//
+
+#ifndef COMPILER_SEARCHSYMBOL_H_
+#define COMPILER_SEARCHSYMBOL_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+namespace sh
+{
+class SearchSymbol : public TIntermTraverser
+{
+  public:
+    SearchSymbol(const TString &amp;symbol);
+
+    void traverse(TIntermNode *node);
+    void visitSymbol(TIntermSymbol *symbolNode);
+
+    bool foundMatch() const;
+
+  protected:
+    const TString &amp;mSymbol;
+    bool match;
+};
+}
+
+#endif   // COMPILER_SEARCHSYMBOL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SearchSymbol.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorShHandleh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShHandle.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShHandle.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShHandle.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,180 @@
</span><ins>+//
+// 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 _SHHANDLE_INCLUDED_
+#define _SHHANDLE_INCLUDED_
+
+//
+// Machine independent part of the compiler private objects
+// sent as ShHandle to the driver.
+//
+// This should not be included by driver code.
+//
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/BuiltInFunctionEmulator.h&quot;
+#include &quot;compiler/translator/ExtensionBehavior.h&quot;
+#include &quot;compiler/translator/HashNames.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/SymbolTable.h&quot;
+#include &quot;compiler/translator/VariableInfo.h&quot;
+#include &quot;third_party/compiler/ArrayBoundsClamper.h&quot;
+
+class LongNameMap;
+class TCompiler;
+class TDependencyGraph;
+class TranslatorHLSL;
+
+//
+// Helper function to identify specs that are based on the WebGL spec,
+// like the CSS Shaders spec.
+//
+bool isWebGLBasedSpec(ShShaderSpec spec);
+
+//
+// The base class used to back handles returned to the driver.
+//
+class TShHandleBase {
+public:
+    TShHandleBase();
+    virtual ~TShHandleBase();
+    virtual TCompiler* getAsCompiler() { return 0; }
+    virtual TranslatorHLSL* getAsTranslatorHLSL() { return 0; }
+
+protected:
+    // Memory allocator. Allocates and tracks memory required by the compiler.
+    // Deallocates all memory when compiler is destructed.
+    TPoolAllocator allocator;
+};
+
+//
+// The base class for the machine dependent compiler to derive from
+// for managing object code from the compile.
+//
+class TCompiler : public TShHandleBase {
+public:
+    TCompiler(ShShaderType type, ShShaderSpec spec);
+    virtual ~TCompiler();
+    virtual TCompiler* getAsCompiler() { return this; }
+
+    bool Init(const ShBuiltInResources&amp; resources);
+    bool compile(const char* const shaderStrings[],
+                 size_t numStrings,
+                 int compileOptions);
+
+    // Get results of the last compilation.
+    TInfoSink&amp; getInfoSink() { return infoSink; }
+    const TVariableInfoList&amp; getAttribs() const { return attribs; }
+    const TVariableInfoList&amp; getUniforms() const { return uniforms; }
+    const TVariableInfoList&amp; getVaryings() const { return varyings; }
+    int getMappedNameMaxLength() const;
+
+    ShHashFunction64 getHashFunction() const { return hashFunction; }
+    NameMap&amp; getNameMap() { return nameMap; }
+    TSymbolTable&amp; getSymbolTable() { return symbolTable; }
+
+protected:
+    ShShaderType getShaderType() const { return shaderType; }
+    ShShaderSpec getShaderSpec() const { return shaderSpec; }
+    // Initialize symbol-table with built-in symbols.
+    bool InitBuiltInSymbolTable(const ShBuiltInResources&amp; resources);
+    // Clears the results from the previous compilation.
+    void clearResults();
+    // Return true if function recursion is detected or call depth exceeded.
+    bool detectCallDepth(TIntermNode* root, TInfoSink&amp; infoSink, bool limitCallStackDepth);
+    // Rewrites a shader's intermediate tree according to the CSS Shaders spec.
+    void rewriteCSSShader(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, uniforms, varyings.
+    void collectVariables(TIntermNode* root);
+    // Map long variable names into shorter ones.
+    void mapLongVariableNames(TIntermNode* root);
+    // Translate to object code.
+    virtual void translate(TIntermNode* root) = 0;
+    // Returns true if, after applying the packing rules in the GLSL 1.017 spec
+    // Appendix A, section 7, the shader does not use too many uniforms.
+    bool enforcePackingRestrictions();
+    // Insert statements to initialize varyings without static use in the beginning
+    // of main(). It is to work around a Mac driver where such varyings in a vertex
+    // shader may be optimized out incorrectly at compile time, causing a link failure.
+    // This function should only be applied to vertex shaders.
+    void initializeVaryingsWithoutStaticUse(TIntermNode* root);
+    // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
+    // It is to work around a Linux driver bug where missing this causes compile failure
+    // while spec says it is allowed.
+    // This function should only be applied to vertex shaders.
+    void initializeGLPosition(TIntermNode* root);
+    // Returns true if the shader passes the restrictions that aim to prevent timing attacks.
+    bool enforceTimingRestrictions(TIntermNode* root, bool outputGraph);
+    // Returns true if the shader does not use samplers.
+    bool enforceVertexShaderTimingRestrictions(TIntermNode* root);
+    // Returns true if the shader does not use sampler dependent values to affect control 
+    // flow or in operations whose time can depend on the input values.
+    bool enforceFragmentShaderTimingRestrictions(const TDependencyGraph&amp; graph);
+    // Return true if the maximum expression complexity below the limit.
+    bool limitExpressionComplexity(TIntermNode* root);
+    // Get built-in extensions with default behavior.
+    const TExtensionBehavior&amp; getExtensionBehavior() const;
+    // Get the resources set by InitBuiltInSymbolTable
+    const ShBuiltInResources&amp; getResources() const;
+
+    const ArrayBoundsClamper&amp; getArrayBoundsClamper() const;
+    ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
+    const BuiltInFunctionEmulator&amp; getBuiltInFunctionEmulator() const;
+
+private:
+    ShShaderType shaderType;
+    ShShaderSpec shaderSpec;
+
+    int maxUniformVectors;
+    int maxVaryingVectors;
+    int maxExpressionComplexity;
+    int maxCallStackDepth;
+
+    ShBuiltInResources compileResources;
+
+    // Built-in symbol table for the given language, spec, and resources.
+    // It is preserved from compile-to-compile.
+    TSymbolTable symbolTable;
+    // Built-in extensions with default behavior.
+    TExtensionBehavior extensionBehavior;
+    bool fragmentPrecisionHigh;
+
+    ArrayBoundsClamper arrayBoundsClamper;
+    ShArrayIndexClampingStrategy clampingStrategy;
+    BuiltInFunctionEmulator builtInFunctionEmulator;
+
+    // Results of compilation.
+    TInfoSink infoSink;  // Output sink.
+    TVariableInfoList attribs;  // Active attributes in the compiled shader.
+    TVariableInfoList uniforms;  // Active uniforms in the compiled shader.
+    TVariableInfoList varyings;  // Varyings in the compiled shader.
+
+    // Cached copy of the ref-counted singleton.
+    LongNameMap* longNameMap;
+
+    // name hashing.
+    ShHashFunction64 hashFunction;
+    NameMap nameMap;
+};
+
+//
+// This is the interface between the machine independent code
+// and the machine dependent code.
+//
+// The machine dependent code should derive from the classes
+// above. Then Construct*() and Delete*() will create and 
+// destroy the machine dependent objects, which contain the
+// above machine independent information.
+//
+TCompiler* ConstructCompiler(
+    ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
+void DeleteCompiler(TCompiler*);
+
+#endif // _SHHANDLE_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShHandle.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorShaderLangcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,390 @@
</span><ins>+//
+// 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.
+//
+
+//
+// Implement the top-level of interface to the compiler,
+// as defined in ShaderLang.h
+//
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/InitializeDll.h&quot;
+#include &quot;compiler/preprocessor/length_limits.h&quot;
+#include &quot;compiler/translator/ShHandle.h&quot;
+#include &quot;compiler/translator/TranslatorHLSL.h&quot;
+#include &quot;compiler/translator/VariablePacker.h&quot;
+
+//
+// This is the platform independent interface between an OGL driver
+// and the shading language compiler.
+//
+
+static bool checkVariableMaxLengths(const ShHandle handle,
+                                    size_t expectedValue)
+{
+    size_t activeUniformLimit = 0;
+    ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &amp;activeUniformLimit);
+    size_t activeAttribLimit = 0;
+    ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &amp;activeAttribLimit);
+    size_t varyingLimit = 0;
+    ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &amp;varyingLimit);
+    return (expectedValue == activeUniformLimit &amp;&amp;
+            expectedValue == activeAttribLimit &amp;&amp;
+            expectedValue == varyingLimit);
+}
+
+static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
+{
+    size_t mappedNameMaxLength = 0;
+    ShGetInfo(handle, SH_MAPPED_NAME_MAX_LENGTH, &amp;mappedNameMaxLength);
+    return (expectedValue == mappedNameMaxLength);
+}
+
+//
+// Driver must call this first, once, before doing any other compiler operations.
+// Subsequent calls to this function are no-op.
+//
+int ShInitialize()
+{
+    static const bool kInitialized = InitProcess();
+    return kInitialized ? 1 : 0;
+}
+
+//
+// Cleanup symbol tables
+//
+int ShFinalize()
+{
+    DetachProcess();
+    return 1;
+}
+
+//
+// Initialize built-in resources with minimum expected values.
+//
+void ShInitBuiltInResources(ShBuiltInResources* resources)
+{
+    // Constants.
+    resources-&gt;MaxVertexAttribs = 8;
+    resources-&gt;MaxVertexUniformVectors = 128;
+    resources-&gt;MaxVaryingVectors = 8;
+    resources-&gt;MaxVertexTextureImageUnits = 0;
+    resources-&gt;MaxCombinedTextureImageUnits = 8;
+    resources-&gt;MaxTextureImageUnits = 8;
+    resources-&gt;MaxFragmentUniformVectors = 16;
+    resources-&gt;MaxDrawBuffers = 1;
+
+    // Extensions.
+    resources-&gt;OES_standard_derivatives = 0;
+    resources-&gt;OES_EGL_image_external = 0;
+    resources-&gt;ARB_texture_rectangle = 0;
+    resources-&gt;EXT_draw_buffers = 0;
+    resources-&gt;EXT_frag_depth = 0;
+
+    // Disable highp precision in fragment shader by default.
+    resources-&gt;FragmentPrecisionHigh = 0;
+
+    // Disable name hashing by default.
+    resources-&gt;HashFunction = NULL;
+
+    resources-&gt;ArrayIndexClampingStrategy = SH_CLAMP_WITH_CLAMP_INTRINSIC;
+
+    resources-&gt;MaxExpressionComplexity = 256;
+    resources-&gt;MaxCallStackDepth = 256;
+}
+
+//
+// Driver calls these to create and destroy compiler objects.
+//
+ShHandle ShConstructCompiler(ShShaderType type, ShShaderSpec spec,
+                             ShShaderOutput output,
+                             const ShBuiltInResources* resources)
+{
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(ConstructCompiler(type, spec, output));
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (compiler == 0)
+        return 0;
+
+    // Generate built-in symbol table.
+    if (!compiler-&gt;Init(*resources)) {
+        ShDestruct(base);
+        return 0;
+    }
+
+    return reinterpret_cast&lt;void*&gt;(base);
+}
+
+void ShDestruct(ShHandle handle)
+{
+    if (handle == 0)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+
+    if (base-&gt;getAsCompiler())
+        DeleteCompiler(base-&gt;getAsCompiler());
+}
+
+//
+// Do an actual compile on the given strings.  The result is left 
+// in the given compile object.
+//
+// Return:  The return value of ShCompile is really boolean, indicating
+// success or failure.
+//
+int ShCompile(
+    const ShHandle handle,
+    const char* const shaderStrings[],
+    size_t numStrings,
+    int compileOptions)
+{
+    if (handle == 0)
+        return 0;
+
+    TShHandleBase* base = reinterpret_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (compiler == 0)
+        return 0;
+
+    bool success = compiler-&gt;compile(shaderStrings, numStrings, compileOptions);
+    return success ? 1 : 0;
+}
+
+void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
+{
+    if (!handle || !params)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (!compiler) return;
+
+    switch(pname)
+    {
+    case SH_INFO_LOG_LENGTH:
+        *params = compiler-&gt;getInfoSink().info.size() + 1;
+        break;
+    case SH_OBJECT_CODE_LENGTH:
+        *params = compiler-&gt;getInfoSink().obj.size() + 1;
+        break;
+    case SH_ACTIVE_UNIFORMS:
+        *params = compiler-&gt;getUniforms().size();
+        break;
+    case SH_ACTIVE_UNIFORM_MAX_LENGTH:
+        *params = 1 +  MAX_SYMBOL_NAME_LEN;
+        break;
+    case SH_ACTIVE_ATTRIBUTES:
+        *params = compiler-&gt;getAttribs().size();
+        break;
+    case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
+        break;
+    case SH_VARYINGS:
+        *params = compiler-&gt;getVaryings().size();
+        break;
+    case SH_VARYING_MAX_LENGTH:
+        *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;
+    case SH_NAME_MAX_LENGTH:
+        *params = 1 + MAX_SYMBOL_NAME_LEN;
+        break;
+    case SH_HASHED_NAME_MAX_LENGTH:
+        if (compiler-&gt;getHashFunction() == NULL) {
+            *params = 0;
+        } else {
+            // 64 bits hashing output requires 16 bytes for hex 
+            // representation.
+            const char HashedNamePrefix[] = HASHED_NAME_PREFIX;
+            *params = 16 + sizeof(HashedNamePrefix);
+        }
+        break;
+    case SH_HASHED_NAMES_COUNT:
+        *params = compiler-&gt;getNameMap().size();
+        break;
+    default: UNREACHABLE();
+    }
+}
+
+//
+// Return any compiler log of messages for the application.
+//
+void ShGetInfoLog(const ShHandle handle, char* infoLog)
+{
+    if (!handle || !infoLog)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (!compiler) return;
+
+    TInfoSink&amp; infoSink = compiler-&gt;getInfoSink();
+    strcpy(infoLog, infoSink.info.c_str());
+}
+
+//
+// Return any object code.
+//
+void ShGetObjectCode(const ShHandle handle, char* objCode)
+{
+    if (!handle || !objCode)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (!compiler) return;
+
+    TInfoSink&amp; infoSink = compiler-&gt;getInfoSink();
+    strcpy(objCode, infoSink.obj.c_str());
+}
+
+void ShGetVariableInfo(const ShHandle handle,
+                       ShShaderInfo varType,
+                       int index,
+                       size_t* length,
+                       int* size,
+                       ShDataType* type,
+                       ShPrecisionType* precision,
+                       int* staticUse,
+                       char* name,
+                       char* mappedName)
+{
+    if (!handle || !size || !type || !precision || !staticUse || !name)
+        return;
+    ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
+           (varType == SH_ACTIVE_UNIFORMS) ||
+           (varType == SH_VARYINGS));
+
+    TShHandleBase* base = reinterpret_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (compiler == 0)
+        return;
+
+    const TVariableInfoList&amp; varList =
+        varType == SH_ACTIVE_ATTRIBUTES ? compiler-&gt;getAttribs() :
+            (varType == SH_ACTIVE_UNIFORMS ? compiler-&gt;getUniforms() :
+                compiler-&gt;getVaryings());
+    if (index &lt; 0 || index &gt;= static_cast&lt;int&gt;(varList.size()))
+        return;
+
+    const TVariableInfo&amp; varInfo = varList[index];
+    if (length) *length = varInfo.name.size();
+    *size = varInfo.size;
+    *type = varInfo.type;
+    switch (varInfo.precision) {
+    case EbpLow:
+        *precision = SH_PRECISION_LOWP;
+        break;
+    case EbpMedium:
+        *precision = SH_PRECISION_MEDIUMP;
+        break;
+    case EbpHigh:
+        *precision = SH_PRECISION_HIGHP;
+        break;
+    default:
+        // Some types does not support precision, for example, boolean.
+        *precision = SH_PRECISION_UNDEFINED;
+        break;
+    }
+    *staticUse = varInfo.staticUse ? 1 : 0;
+
+    // This size must match that queried by
+    // SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
+    // in ShGetInfo, below.
+    size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN;
+    ASSERT(checkVariableMaxLengths(handle, variableLength));
+    strncpy(name, varInfo.name.c_str(), variableLength);
+    name[variableLength - 1] = 0;
+    if (mappedName) {
+        // This size must match that queried by
+        // SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
+        size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
+        ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
+        strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
+        mappedName[maxMappedNameLength - 1] = 0;
+    }
+}
+
+void ShGetNameHashingEntry(const ShHandle handle,
+                           int index,
+                           char* name,
+                           char* hashedName)
+{
+    if (!handle || !name || !hashedName || index &lt; 0)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+    TCompiler* compiler = base-&gt;getAsCompiler();
+    if (!compiler) return;
+
+    const NameMap&amp; nameMap = compiler-&gt;getNameMap();
+    if (index &gt;= static_cast&lt;int&gt;(nameMap.size()))
+        return;
+
+    NameMap::const_iterator it = nameMap.begin();
+    for (int i = 0; i &lt; index; ++i)
+        ++it;
+
+    size_t len = it-&gt;first.length() + 1;
+    size_t max_len = 0;
+    ShGetInfo(handle, SH_NAME_MAX_LENGTH, &amp;max_len);
+    if (len &gt; max_len) {
+        ASSERT(false);
+        len = max_len;
+    }
+    strncpy(name, it-&gt;first.c_str(), len);
+    // To be on the safe side in case the source is longer than expected.
+    name[len - 1] = '\0';
+
+    len = it-&gt;second.length() + 1;
+    max_len = 0;
+    ShGetInfo(handle, SH_HASHED_NAME_MAX_LENGTH, &amp;max_len);
+    if (len &gt; max_len) {
+        ASSERT(false);
+        len = max_len;
+    }
+    strncpy(hashedName, it-&gt;second.c_str(), len);
+    // To be on the safe side in case the source is longer than expected.
+    hashedName[len - 1] = '\0';
+}
+
+void ShGetInfoPointer(const ShHandle handle, ShShaderInfo pname, void** params)
+{
+    if (!handle || !params)
+        return;
+
+    TShHandleBase* base = static_cast&lt;TShHandleBase*&gt;(handle);
+    TranslatorHLSL* translator = base-&gt;getAsTranslatorHLSL();
+    if (!translator) return;
+
+    switch(pname)
+    {
+    case SH_ACTIVE_UNIFORMS_ARRAY:
+        *params = (void*)&amp;translator-&gt;getUniforms();
+        break;
+    default: UNREACHABLE();
+    }
+}
+
+int ShCheckVariablesWithinPackingLimits(
+    int maxVectors, ShVariableInfo* varInfoArray, size_t varInfoArraySize)
+{
+    if (varInfoArraySize == 0)
+        return 1;
+    ASSERT(varInfoArray);
+    TVariableInfoList variables;
+    for (size_t ii = 0; ii &lt; varInfoArraySize; ++ii)
+    {
+        TVariableInfo var(varInfoArray[ii].type, varInfoArray[ii].size);
+        variables.push_back(var);
+    }
+    VariablePacker packer;
+    return packer.CheckVariablesWithinPackingLimits(maxVectors, variables) ? 1 : 0;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ShaderLang.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorSymbolTablecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,216 @@
</span><ins>+//
+// 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.
+//
+
+//
+// Symbol table for parsing.  Most functionaliy and main ideas
+// are documented in the header file.
+//
+
+#if defined(_MSC_VER)
+#pragma warning(disable: 4718)
+#endif
+
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+#include &lt;stdio.h&gt;
+#include &lt;algorithm&gt;
+#include &lt;climits&gt;
+
+TType::TType(const TPublicType &amp;p) :
+            type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
+{
+    if (p.userDef)
+        structure = p.userDef-&gt;getStruct();
+}
+
+//
+// Recursively generate mangled names.
+//
+TString TType::buildMangledName() const
+{
+    TString mangledName;
+    if (isMatrix())
+        mangledName += 'm';
+    else if (isVector())
+        mangledName += 'v';
+
+    switch (type) {
+    case EbtFloat:       mangledName += 'f';      break;
+    case EbtInt:         mangledName += 'i';      break;
+    case EbtBool:        mangledName += 'b';      break;
+    case EbtSampler2D:   mangledName += &quot;s2&quot;;     break;
+    case EbtSamplerCube: mangledName += &quot;sC&quot;;     break;
+    case EbtStruct:      mangledName += structure-&gt;mangledName(); break;
+    default:             break;
+    }
+
+    mangledName += static_cast&lt;char&gt;('0' + getNominalSize());
+    if (isArray()) {
+        char buf[20];
+        snprintf(buf, sizeof(buf), &quot;%d&quot;, arraySize);
+        mangledName += '[';
+        mangledName += buf;
+        mangledName += ']';
+    }
+    return mangledName;
+}
+
+size_t TType::getObjectSize() const
+{
+    size_t totalSize = 0;
+
+    if (getBasicType() == EbtStruct)
+        totalSize = structure-&gt;objectSize();
+    else if (matrix)
+        totalSize = size * size;
+    else
+        totalSize = size;
+
+    if (isArray()) {
+        size_t arraySize = getArraySize();
+        if (arraySize &gt; INT_MAX / totalSize)
+            totalSize = INT_MAX;
+        else
+            totalSize *= arraySize;
+    }
+
+    return totalSize;
+}
+
+bool TStructure::containsArrays() const
+{
+    for (size_t i = 0; i &lt; mFields-&gt;size(); ++i) {
+        const TType* fieldType = (*mFields)[i]-&gt;type();
+        if (fieldType-&gt;isArray() || fieldType-&gt;isStructureContainingArrays())
+            return true;
+    }
+    return false;
+}
+
+TString TStructure::buildMangledName() const
+{
+    TString mangledName(&quot;struct-&quot;);
+    mangledName += *mName;
+    for (size_t i = 0; i &lt; mFields-&gt;size(); ++i) {
+        mangledName += '-';
+        mangledName += (*mFields)[i]-&gt;type()-&gt;getMangledName();
+    }
+    return mangledName;
+}
+
+size_t TStructure::calculateObjectSize() const
+{
+    size_t size = 0;
+    for (size_t i = 0; i &lt; mFields-&gt;size(); ++i) {
+        size_t fieldSize = (*mFields)[i]-&gt;type()-&gt;getObjectSize();
+        if (fieldSize &gt; INT_MAX - size)
+            size = INT_MAX;
+        else
+            size += fieldSize;
+    }
+    return size;
+}
+
+int TStructure::calculateDeepestNesting() const
+{
+    int maxNesting = 0;
+    for (size_t i = 0; i &lt; mFields-&gt;size(); ++i) {
+        maxNesting = std::max(maxNesting, (*mFields)[i]-&gt;type()-&gt;getDeepestStructNesting());
+    }
+    return 1 + maxNesting;
+}
+
+//
+// Dump functions.
+//
+
+void TVariable::dump(TInfoSink&amp; infoSink) const
+{
+    infoSink.debug &lt;&lt; getName().c_str() &lt;&lt; &quot;: &quot; &lt;&lt; type.getQualifierString() &lt;&lt; &quot; &quot; &lt;&lt; type.getPrecisionString() &lt;&lt; &quot; &quot; &lt;&lt; type.getBasicString();
+    if (type.isArray()) {
+        infoSink.debug &lt;&lt; &quot;[0]&quot;;
+    }
+    infoSink.debug &lt;&lt; &quot;\n&quot;;
+}
+
+void TFunction::dump(TInfoSink &amp;infoSink) const
+{
+    infoSink.debug &lt;&lt; getName().c_str() &lt;&lt; &quot;: &quot; &lt;&lt;  returnType.getBasicString() &lt;&lt; &quot; &quot; &lt;&lt; getMangledName().c_str() &lt;&lt; &quot;\n&quot;;
+}
+
+void TSymbolTableLevel::dump(TInfoSink &amp;infoSink) const
+{
+    tLevel::const_iterator it;
+    for (it = level.begin(); it != level.end(); ++it)
+        (*it).second-&gt;dump(infoSink);
+}
+
+void TSymbolTable::dump(TInfoSink &amp;infoSink) const
+{
+    for (int level = currentLevel(); level &gt;= 0; --level) {
+        infoSink.debug &lt;&lt; &quot;LEVEL &quot; &lt;&lt; level &lt;&lt; &quot;\n&quot;;
+        table[level]-&gt;dump(infoSink);
+    }
+}
+
+//
+// Functions have buried pointers to delete.
+//
+TFunction::~TFunction()
+{
+    for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
+        delete (*i).type;
+}
+
+//
+// Symbol table levels are a map of pointers to symbols that have to be deleted.
+//
+TSymbolTableLevel::~TSymbolTableLevel()
+{
+    for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
+        delete (*it).second;
+}
+
+//
+// Change all function entries in the table with the non-mangled name
+// to be related to the provided built-in operation.  This is a low
+// performance operation, and only intended for symbol tables that
+// live across a large number of compiles.
+//
+void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
+{
+    tLevel::iterator it;
+    for (it = level.begin(); it != level.end(); ++it) {
+        if ((*it).second-&gt;isFunction()) {
+            TFunction* function = static_cast&lt;TFunction*&gt;((*it).second);
+            if (function-&gt;getName() == name)
+                function-&gt;relateToOperator(op);
+        }
+    }
+}
+
+//
+// Change all function entries in the table with the non-mangled name
+// to be related to the provided built-in extension. This is a low
+// performance operation, and only intended for symbol tables that
+// live across a large number of compiles.
+//
+void TSymbolTableLevel::relateToExtension(const char* name, const TString&amp; ext)
+{
+    for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
+        TSymbol* symbol = it-&gt;second;
+        if (symbol-&gt;getName() == name)
+            symbol-&gt;relateToExtension(ext);
+    }
+}
+
+TSymbolTable::~TSymbolTable()
+{
+    for (size_t i = 0; i &lt; table.size(); ++i)
+        delete table[i];
+    for (size_t i = 0; i &lt; precisionStack.size(); ++i)
+        delete precisionStack[i];
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorSymbolTableh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,382 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _SYMBOL_TABLE_INCLUDED_
+#define _SYMBOL_TABLE_INCLUDED_
+
+//
+// Symbol table for parsing.  Has these design characteristics:
+//
+// * Same symbol table can be used to compile many shaders, to preserve
+//   effort of creating and loading with the large numbers of built-in
+//   symbols.
+//
+// * Name mangling will be used to give each function a unique name
+//   so that symbol table lookups are never ambiguous.  This allows
+//   a simpler symbol table structure.
+//
+// * Pushing and popping of scope, so symbol table will really be a stack 
+//   of symbol tables.  Searched from the top, with new inserts going into
+//   the top.
+//
+// * Constants:  Compile time constant symbols will keep their values
+//   in the symbol table.  The parser can substitute constants at parse
+//   time, including doing constant folding and constant propagation.
+//
+// * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
+//   are tracked in the intermediate representation, not the symbol table.
+//
+
+#include &lt;assert.h&gt;
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+//
+// Symbol base class.  (Can build functions or variables out of these...)
+//
+class TSymbol {    
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TSymbol(const TString* n) :  uniqueId(0), name(n) { }
+    virtual ~TSymbol() { /* don't delete name, it's from the pool */ }
+
+    const TString&amp; getName() const { return *name; }
+    virtual const TString&amp; getMangledName() const { return getName(); }
+    virtual bool isFunction() const { return false; }
+    virtual bool isVariable() const { return false; }
+    void setUniqueId(int id) { uniqueId = id; }
+    int getUniqueId() const { return uniqueId; }
+    virtual void dump(TInfoSink &amp;infoSink) const = 0;
+    void relateToExtension(const TString&amp; ext) { extension = ext; }
+    const TString&amp; getExtension() const { return extension; }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TSymbol);
+
+    int uniqueId;      // For real comparing during code generation
+    const TString *name;
+    TString extension;
+};
+
+//
+// Variable class, meaning a symbol that's not a function.
+// 
+// There could be a separate class heirarchy for Constant variables;
+// Only one of int, bool, or float, (or none) is correct for
+// any particular use, but it's easy to do this way, and doesn't
+// seem worth having separate classes, and &quot;getConst&quot; can't simply return
+// different values for different types polymorphically, so this is 
+// just simple and pragmatic.
+//
+class TVariable : public TSymbol {
+public:
+    TVariable(const TString *name, const TType&amp; t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0) { }
+    virtual ~TVariable() { }
+    virtual bool isVariable() const { return true; }    
+    TType&amp; getType() { return type; }    
+    const TType&amp; getType() const { return type; }
+    bool isUserType() const { return userType; }
+    void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
+
+    virtual void dump(TInfoSink &amp;infoSink) const;
+
+    ConstantUnion* getConstPointer()
+    { 
+        if (!unionArray)
+            unionArray = new ConstantUnion[type.getObjectSize()];
+
+        return unionArray;
+    }
+
+    ConstantUnion* getConstPointer() const { return unionArray; }
+
+    void shareConstPointer( ConstantUnion *constArray)
+    {
+        if (unionArray == constArray)
+            return;
+
+        delete[] unionArray;
+        unionArray = constArray;  
+    }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TVariable);
+
+    TType type;
+    bool userType;
+    // we are assuming that Pool Allocator will free the memory allocated to unionArray
+    // when this object is destroyed
+    ConstantUnion *unionArray;
+};
+
+//
+// The function sub-class of symbols and the parser will need to
+// share this definition of a function parameter.
+//
+struct TParameter {
+    TString *name;
+    TType* type;
+};
+
+//
+// The function sub-class of a symbol.  
+//
+class TFunction : public TSymbol {
+public:
+    TFunction(TOperator o) :
+        TSymbol(0),
+        returnType(TType(EbtVoid, EbpUndefined)),
+        op(o),
+        defined(false) { }
+    TFunction(const TString *name, TType&amp; retType, TOperator tOp = EOpNull) : 
+        TSymbol(name), 
+        returnType(retType),
+        mangledName(TFunction::mangleName(*name)),
+        op(tOp),
+        defined(false) { }
+    virtual ~TFunction();
+    virtual bool isFunction() const { return true; }    
+
+    static TString mangleName(const TString&amp; name) { return name + '('; }
+    static TString unmangleName(const TString&amp; mangledName)
+    {
+        return TString(mangledName.c_str(), mangledName.find_first_of('('));
+    }
+
+    void addParameter(TParameter&amp; p) 
+    { 
+        parameters.push_back(p);
+        mangledName = mangledName + p.type-&gt;getMangledName();
+    }
+
+    const TString&amp; getMangledName() const { return mangledName; }
+    const TType&amp; getReturnType() const { return returnType; }
+
+    void relateToOperator(TOperator o) { op = o; }
+    TOperator getBuiltInOp() const { return op; }
+
+    void setDefined() { defined = true; }
+    bool isDefined() { return defined; }
+
+    size_t getParamCount() const { return parameters.size(); }  
+    const TParameter&amp; getParam(size_t i) const { return parameters[i]; }
+
+    virtual void dump(TInfoSink &amp;infoSink) const;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TFunction);
+
+    typedef TVector&lt;TParameter&gt; TParamList;
+    TParamList parameters;
+    TType returnType;
+    TString mangledName;
+    TOperator op;
+    bool defined;
+};
+
+
+class TSymbolTableLevel {
+public:
+    typedef TMap&lt;TString, TSymbol*&gt; tLevel;
+    typedef tLevel::const_iterator const_iterator;
+    typedef const tLevel::value_type tLevelPair;
+    typedef std::pair&lt;tLevel::iterator, bool&gt; tInsertResult;
+
+    TSymbolTableLevel() { }
+    ~TSymbolTableLevel();
+
+    bool insert(const TString &amp;name, TSymbol &amp;symbol)
+    {
+        //
+        // returning true means symbol was added to the table
+        //
+        tInsertResult result = level.insert(tLevelPair(name, &amp;symbol));
+
+        return result.second;
+    }
+
+    bool insert(TSymbol &amp;symbol)
+    {
+        return insert(symbol.getMangledName(), symbol);
+    }
+
+    TSymbol* find(const TString&amp; name) const
+    {
+        tLevel::const_iterator it = level.find(name);
+        if (it == level.end())
+            return 0;
+        else
+            return (*it).second;
+    }
+
+    const_iterator begin() const
+    {
+        return level.begin();
+    }
+
+    const_iterator end() const
+    {
+        return level.end();
+    }
+
+    void relateToOperator(const char* name, TOperator op);
+    void relateToExtension(const char* name, const TString&amp; ext);
+    void dump(TInfoSink &amp;infoSink) const;
+
+protected:
+    tLevel level;
+};
+
+class TSymbolTable {
+public:
+    TSymbolTable() : uniqueId(0)
+    {
+        //
+        // The symbol table cannot be used until push() is called, but
+        // the lack of an initial call to push() can be used to detect
+        // that the symbol table has not been preloaded with built-ins.
+        //
+    }
+    ~TSymbolTable();
+
+    //
+    // When the symbol table is initialized with the built-ins, there should
+    // 'push' calls, so that built-ins are at level 0 and the shader
+    // globals are at level 1.
+    //
+    bool isEmpty() { return table.size() == 0; }
+    bool atBuiltInLevel() { return table.size() == 1; }
+    bool atGlobalLevel() { return table.size() &lt;= 2; }
+    void push()
+    {
+        table.push_back(new TSymbolTableLevel);
+        precisionStack.push_back(new PrecisionStackLevel);
+    }
+
+    void pop()
+    {
+        delete table.back();
+        table.pop_back();
+
+        delete precisionStack.back();
+        precisionStack.pop_back();
+    }
+
+    bool insert(TSymbol&amp; symbol)
+    {
+        symbol.setUniqueId(++uniqueId);
+        return table[currentLevel()]-&gt;insert(symbol);
+    }
+
+    bool insertConstInt(const char *name, int value)
+    {
+        TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1));
+        constant-&gt;getConstPointer()-&gt;setIConst(value);
+        return insert(*constant);
+    }
+
+    bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0)
+    {
+        TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
+
+        TParameter param1 = {NULL, ptype1};
+        function-&gt;addParameter(param1);
+
+        if(ptype2)
+        {
+            TParameter param2 = {NULL, ptype2};
+            function-&gt;addParameter(param2);
+        }
+
+        if(ptype3)
+        {
+            TParameter param3 = {NULL, ptype3};
+            function-&gt;addParameter(param3);
+        }
+
+        return insert(*function);
+    }
+
+    TSymbol* find(const TString&amp; name, bool* builtIn = 0, bool *sameScope = 0) 
+    {
+        int level = currentLevel();
+        TSymbol* symbol;
+        do {
+            symbol = table[level]-&gt;find(name);
+            --level;
+        } while (symbol == 0 &amp;&amp; level &gt;= 0);
+        level++;
+        if (builtIn)
+            *builtIn = level == 0;
+        if (sameScope)
+            *sameScope = level == currentLevel();
+        return symbol;
+    }
+
+    TSymbol* findBuiltIn(const TString &amp;name)
+    {
+        return table[0]-&gt;find(name);
+    }
+
+    TSymbolTableLevel* getOuterLevel() {
+        assert(table.size() &gt;= 2);
+        return table[currentLevel() - 1];
+    }
+
+    void relateToOperator(const char* name, TOperator op) {
+        table[0]-&gt;relateToOperator(name, op);
+    }
+    void relateToExtension(const char* name, const TString&amp; ext) {
+        table[0]-&gt;relateToExtension(name, ext);
+    }
+    void dump(TInfoSink &amp;infoSink) const;
+
+    bool setDefaultPrecision(const TPublicType&amp; type, TPrecision prec) {
+        if (!supportsPrecision(type.type))
+            return false;
+        if (type.size != 1 || type.matrix || type.array)
+            return false; // Not allowed to set for aggregate types
+        int indexOfLastElement = static_cast&lt;int&gt;(precisionStack.size()) - 1;
+        (*precisionStack[indexOfLastElement])[type.type] = prec; // Uses map operator [], overwrites the current value
+        return true;
+    }
+
+    // Searches down the precisionStack for a precision qualifier for the specified TBasicType
+    TPrecision getDefaultPrecision(TBasicType type) {
+        if (!supportsPrecision(type))
+            return EbpUndefined;
+        int level = static_cast&lt;int&gt;(precisionStack.size()) - 1;
+        assert(level &gt;= 0); // Just to be safe. Should not happen.
+        PrecisionStackLevel::iterator it;
+        TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
+        while (level &gt;= 0) {
+            it = precisionStack[level]-&gt;find(type);
+            if (it != precisionStack[level]-&gt;end()) {
+                prec = (*it).second;
+                break;
+            }
+            level--;
+        }
+        return prec;
+    }
+
+private:
+    int currentLevel() const { return static_cast&lt;int&gt;(table.size()) - 1; }
+
+    bool supportsPrecision(TBasicType type) {
+      // Only supports precision for int, float, and sampler types.
+      return type == EbtFloat || type == EbtInt || IsSampler(type);
+    }
+
+    int uniqueId;     // for unique identification in code generation
+    std::vector&lt;TSymbolTableLevel*&gt; table;
+    typedef TMap&lt;TBasicType, TPrecision&gt; PrecisionStackLevel;
+    std::vector&lt;PrecisionStackLevel*&gt; precisionStack;
+};
+
+#endif // _SYMBOL_TABLE_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/SymbolTable.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorESSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+//
+// 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 &quot;compiler/translator/TranslatorESSL.h&quot;
+
+#include &quot;compiler/translator/OutputESSL.h&quot;
+
+TranslatorESSL::TranslatorESSL(ShShaderType type, ShShaderSpec spec)
+    : TCompiler(type, spec) {
+}
+
+void TranslatorESSL::translate(TIntermNode* root) {
+    TInfoSinkBase&amp; sink = getInfoSink().obj;
+
+    // Write built-in extension behaviors.
+    writeExtensionBehavior();
+
+    // Write emulated built-in functions if needed.
+    getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
+        sink, getShaderType() == SH_FRAGMENT_SHADER);
+
+    // Write array bounds clamping emulation if needed.
+    getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
+    // Write translated shader.
+    TOutputESSL outputESSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
+    root-&gt;traverse(&amp;outputESSL);
+}
+
+void TranslatorESSL::writeExtensionBehavior() {
+    TInfoSinkBase&amp; sink = getInfoSink().obj;
+    const TExtensionBehavior&amp; extensionBehavior = getExtensionBehavior();
+    for (TExtensionBehavior::const_iterator iter = extensionBehavior.begin();
+         iter != extensionBehavior.end(); ++iter) {
+        if (iter-&gt;second != EBhUndefined) {
+            sink &lt;&lt; &quot;#extension &quot; &lt;&lt; iter-&gt;first &lt;&lt; &quot; : &quot;
+                 &lt;&lt; getBehaviorString(iter-&gt;second) &lt;&lt; &quot;\n&quot;;
+        }
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorESSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+//
+// 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 &quot;compiler/translator/ShHandle.h&quot;
+
+class TranslatorESSL : public TCompiler {
+public:
+    TranslatorESSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+    virtual void translate(TIntermNode* root);
+
+private:
+    void writeExtensionBehavior();
+};
+
+#endif  // COMPILER_TRANSLATORESSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorESSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorGLSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,44 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/TranslatorGLSL.h&quot;
+
+#include &quot;compiler/translator/OutputGLSL.h&quot;
+#include &quot;compiler/translator/VersionGLSL.h&quot;
+
+static void writeVersion(ShShaderType type, TIntermNode* root,
+                         TInfoSinkBase&amp; sink) {
+    TVersionGLSL versionGLSL(type);
+    root-&gt;traverse(&amp;versionGLSL);
+    int version = versionGLSL.getVersion();
+    // We need to write version directive only if it is greater than 110.
+    // If there is no version directive in the shader, 110 is implied.
+    if (version &gt; 110) {
+        sink &lt;&lt; &quot;#version &quot; &lt;&lt; version &lt;&lt; &quot;\n&quot;;
+    }
+}
+
+TranslatorGLSL::TranslatorGLSL(ShShaderType type, ShShaderSpec spec)
+    : TCompiler(type, spec) {
+}
+
+void TranslatorGLSL::translate(TIntermNode* root) {
+    TInfoSinkBase&amp; sink = getInfoSink().obj;
+
+    // Write GLSL version.
+    writeVersion(getShaderType(), root, sink);
+
+    // Write emulated built-in functions if needed.
+    getBuiltInFunctionEmulator().OutputEmulatedFunctionDefinition(
+        sink, false);
+
+    // Write array bounds clamping emulation if needed.
+    getArrayBoundsClamper().OutputClampingFunctionDefinition(sink);
+
+    // Write translated shader.
+    TOutputGLSL outputGLSL(sink, getArrayIndexClampingStrategy(), getHashFunction(), getNameMap(), getSymbolTable());
+    root-&gt;traverse(&amp;outputGLSL);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorGLSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATORGLSL_H_
+#define COMPILER_TRANSLATORGLSL_H_
+
+#include &quot;compiler/translator/ShHandle.h&quot;
+
+class TranslatorGLSL : public TCompiler {
+public:
+    TranslatorGLSL(ShShaderType type, ShShaderSpec spec);
+
+protected:
+    virtual void translate(TIntermNode* root);
+};
+
+#endif  // COMPILER_TRANSLATORGLSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorGLSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorHLSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,24 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/TranslatorHLSL.h&quot;
+
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+#include &quot;compiler/translator/OutputHLSL.h&quot;
+
+TranslatorHLSL::TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output)
+    : TCompiler(type, spec), mOutputType(output)
+{
+}
+
+void TranslatorHLSL::translate(TIntermNode *root)
+{
+    TParseContext&amp; parseContext = *GetGlobalParseContext();
+    sh::OutputHLSL outputHLSL(parseContext, getResources(), mOutputType);
+
+    outputHLSL.output();
+    mActiveUniforms = outputHLSL.getUniforms();
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTranslatorHLSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_TRANSLATORHLSL_H_
+#define COMPILER_TRANSLATORHLSL_H_
+
+#include &quot;compiler/translator/ShHandle.h&quot;
+#include &quot;compiler/translator/Uniform.h&quot;
+
+class TranslatorHLSL : public TCompiler {
+public:
+    TranslatorHLSL(ShShaderType type, ShShaderSpec spec, ShShaderOutput output);
+
+    virtual TranslatorHLSL *getAsTranslatorHLSL() { return this; }
+    const sh::ActiveUniforms &amp;getUniforms() { return mActiveUniforms; }
+
+protected:
+    virtual void translate(TIntermNode* root);
+
+    sh::ActiveUniforms mActiveUniforms;
+    ShShaderOutput mOutputType;
+};
+
+#endif  // COMPILER_TRANSLATORHLSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/TranslatorHLSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorTypesh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,307 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _TYPES_INCLUDED
+#define _TYPES_INCLUDED
+
+#include &quot;common/angleutils.h&quot;
+
+#include &quot;compiler/translator/BaseTypes.h&quot;
+#include &quot;compiler/translator/Common.h&quot;
+#include &quot;compiler/translator/compilerdebug.h&quot;
+
+struct TPublicType;
+class TType;
+
+class TField
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TField(TType* type, TString* name) : mType(type), mName(name) {}
+
+    // TODO(alokp): We should only return const type.
+    // Fix it by tweaking grammar.
+    TType* type() { return mType; }
+    const TType* type() const { return mType; }
+
+    const TString&amp; name() const { return *mName; }
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TField);
+    TType* mType;
+    TString* mName;
+};
+
+typedef TVector&lt;TField*&gt; TFieldList;
+inline TFieldList* NewPoolTFieldList()
+{
+    void* memory = GetGlobalPoolAllocator()-&gt;allocate(sizeof(TFieldList));
+    return new(memory) TFieldList;
+}
+
+class TStructure
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TStructure(TString* name, TFieldList* fields)
+        : mName(name),
+          mFields(fields),
+          mObjectSize(0),
+          mDeepestNesting(0) {
+    }
+
+    const TString&amp; name() const { return *mName; }
+    const TFieldList&amp; fields() const { return *mFields; }
+
+    const TString&amp; mangledName() const {
+        if (mMangledName.empty())
+            mMangledName = buildMangledName();
+        return mMangledName;
+    }
+    size_t objectSize() const {
+        if (mObjectSize == 0)
+            mObjectSize = calculateObjectSize();
+        return mObjectSize;
+    };
+    int deepestNesting() const {
+        if (mDeepestNesting == 0)
+            mDeepestNesting = calculateDeepestNesting();
+        return mDeepestNesting;
+    }
+    bool containsArrays() const;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(TStructure);
+    TString buildMangledName() const;
+    size_t calculateObjectSize() const;
+    int calculateDeepestNesting() const;
+
+    TString* mName;
+    TFieldList* mFields;
+
+    mutable TString mMangledName;
+    mutable size_t mObjectSize;
+    mutable int mDeepestNesting;
+};
+
+//
+// Base class for things that have a type.
+//
+class TType
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TType() {}
+    TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, unsigned char s = 1, bool m = false, bool a = false) :
+            type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0), structure(0)
+    {
+    }
+    explicit TType(const TPublicType &amp;p);
+    TType(TStructure* userDef, TPrecision p = EbpUndefined) :
+            type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0), structure(userDef)
+    {
+    }
+
+    TBasicType getBasicType() const { return type; }
+    void setBasicType(TBasicType t) { type = t; }
+
+    TPrecision getPrecision() const { return precision; }
+    void setPrecision(TPrecision p) { precision = p; }
+
+    TQualifier getQualifier() const { return qualifier; }
+    void setQualifier(TQualifier q) { qualifier = q; }
+
+    // One-dimensional size of single instance type
+    int getNominalSize() const { return size; }
+    void setNominalSize(unsigned char s) { size = s; }
+    // Full size of single instance of type
+    size_t getObjectSize() const;
+
+    int elementRegisterCount() const
+    {
+        if (structure)
+        {
+            const TFieldList &amp;fields = getStruct()-&gt;fields();
+            int registerCount = 0;
+
+            for (size_t i = 0; i &lt; fields.size(); i++)
+            {
+                registerCount += fields[i]-&gt;type()-&gt;totalRegisterCount();
+            }
+
+            return registerCount;
+        }
+        else if (isMatrix())
+        {
+            return getNominalSize();
+        }
+        else
+        {
+            return 1;
+        }
+    }
+
+    int totalRegisterCount() const
+    {
+        if (array)
+        {
+            return arraySize * elementRegisterCount();
+        }
+        else
+        {
+            return elementRegisterCount();
+        }
+    }
+
+    bool isMatrix() const { return matrix ? true : false; }
+    void setMatrix(bool m) { matrix = m; }
+
+    bool isArray() const  { return array ? true : false; }
+    int getArraySize() const { return arraySize; }
+    void setArraySize(int s) { array = true; arraySize = s; }
+    void clearArrayness() { array = false; arraySize = 0; }
+
+    bool isVector() const { return size &gt; 1 &amp;&amp; !matrix; }
+    bool isScalar() const { return size == 1 &amp;&amp; !matrix &amp;&amp; !structure; }
+
+    TStructure* getStruct() const { return structure; }
+    void setStruct(TStructure* s) { structure = s; }
+
+    const TString&amp; getMangledName() const {
+        if (mangled.empty()) {
+            mangled = buildMangledName();
+            mangled += ';';
+        }
+        return mangled;
+    }
+
+    bool sameElementType(const TType&amp; right) const {
+        return      type == right.type   &amp;&amp;
+                    size == right.size   &amp;&amp;
+                  matrix == right.matrix &amp;&amp;
+               structure == right.structure;
+    }
+    bool operator==(const TType&amp; right) const {
+        return      type == right.type   &amp;&amp;
+                    size == right.size   &amp;&amp;
+                  matrix == right.matrix &amp;&amp;
+                   array == right.array  &amp;&amp; (!array || arraySize == right.arraySize) &amp;&amp;
+               structure == right.structure;
+        // don't check the qualifier, it's not ever what's being sought after
+    }
+    bool operator!=(const TType&amp; right) const {
+        return !operator==(right);
+    }
+    bool operator&lt;(const TType&amp; right) const {
+        if (type != right.type) return type &lt; right.type;
+        if (size != right.size) return size &lt; right.size;
+        if (matrix != right.matrix) return matrix &lt; right.matrix;
+        if (array != right.array) return array &lt; right.array;
+        if (arraySize != right.arraySize) return arraySize &lt; right.arraySize;
+        if (structure != right.structure) return structure &lt; right.structure;
+
+        return false;
+    }
+
+    const char* getBasicString() const { return ::getBasicString(type); }
+    const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+    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 &quot;nesting2&quot;, 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 structure ? structure-&gt;deepestNesting() : 0;
+    }
+
+    bool isStructureContainingArrays() const {
+        return structure ? structure-&gt;containsArrays() : false;
+    }
+
+private:
+    TString buildMangledName() const;
+
+    TBasicType type;
+    TPrecision precision;
+    TQualifier qualifier;
+    unsigned char size;
+    bool matrix;
+    bool array;
+    int arraySize;
+
+    TStructure* structure;      // 0 unless this is a struct
+
+    mutable TString mangled;
+};
+
+//
+// This is a workaround for a problem with the yacc stack,  It can't have
+// types that it thinks have non-trivial constructors.  It should
+// just be used while recognizing the grammar, not anything else.  Pointers
+// could be used, but also trying to avoid lots of memory management overhead.
+//
+// Not as bad as it looks, there is no actual assumption that the fields
+// match up or are name the same or anything like that.
+//
+struct TPublicType
+{
+    TBasicType type;
+    TQualifier qualifier;
+    TPrecision precision;
+    unsigned char size;          // size of vector or matrix, not size of array
+    bool matrix;
+    bool array;
+    int arraySize;
+    TType* userDef;
+    TSourceLoc line;
+
+    void setBasic(TBasicType bt, TQualifier q, const TSourceLoc&amp; ln)
+    {
+        type = bt;
+        qualifier = q;
+        precision = EbpUndefined;
+        size = 1;
+        matrix = false;
+        array = false;
+        arraySize = 0;
+        userDef = 0;
+        line = ln;
+    }
+
+    void setAggregate(unsigned char s, bool m = false)
+    {
+        size = s;
+        matrix = m;
+    }
+
+    void setArray(bool a, int s = 0)
+    {
+        array = a;
+        arraySize = s;
+    }
+
+    bool isStructureContainingArrays() const
+    {
+        if (!userDef)
+        {
+            return false;
+        }
+
+        return userDef-&gt;isStructureContainingArrays();
+    }
+};
+
+#endif // _TYPES_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Types.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,184 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements.
+// The results are assigned to s# temporaries, which are used by the main translator instead of
+// the original expression.
+//
+
+#include &quot;compiler/translator/UnfoldShortCircuit.h&quot;
+
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/OutputHLSL.h&quot;
+
+namespace sh
+{
+UnfoldShortCircuit::UnfoldShortCircuit(TParseContext &amp;context, OutputHLSL *outputHLSL) : mContext(context), mOutputHLSL(outputHLSL)
+{
+    mTemporaryIndex = 0;
+}
+
+void UnfoldShortCircuit::traverse(TIntermNode *node)
+{
+    int rewindIndex = mTemporaryIndex;
+    node-&gt;traverse(this);
+    mTemporaryIndex = rewindIndex;
+}
+
+bool UnfoldShortCircuit::visitBinary(Visit visit, TIntermBinary *node)
+{
+    TInfoSinkBase &amp;out = mOutputHLSL-&gt;getBodyStream();
+
+    // If our right node doesn't have side effects, we know we don't need to unfold this
+    // expression: there will be no short-circuiting side effects to avoid
+    // (note: unfolding doesn't depend on the left node -- it will always be evaluated)
+    if (!node-&gt;getRight()-&gt;hasSideEffects())
+    {
+        return true;
+    }
+
+    switch (node-&gt;getOp())
+    {
+      case EOpLogicalOr:
+        // &quot;x || y&quot; is equivalent to &quot;x ? true : y&quot;, which unfolds to &quot;bool s; if(x) s = true; else s = y;&quot;,
+        // and then further simplifies down to &quot;bool s = x; if(!s) s = y;&quot;.
+        {
+            int i = mTemporaryIndex;
+
+            out &lt;&lt; &quot;bool s&quot; &lt;&lt; i &lt;&lt; &quot;;\n&quot;;
+
+            out &lt;&lt; &quot;{\n&quot;;
+
+            mTemporaryIndex = i + 1;
+            node-&gt;getLeft()-&gt;traverse(this);
+            out &lt;&lt; &quot;s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getLeft()-&gt;traverse(mOutputHLSL);
+            out &lt;&lt; &quot;;\n&quot;;
+            out &lt;&lt; &quot;if (!s&quot; &lt;&lt; i &lt;&lt; &quot;)\n&quot;
+                   &quot;{\n&quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getRight()-&gt;traverse(this);
+            out &lt;&lt; &quot;    s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getRight()-&gt;traverse(mOutputHLSL);
+            out &lt;&lt; &quot;;\n&quot;
+                   &quot;}\n&quot;;
+
+            out &lt;&lt; &quot;}\n&quot;;
+
+            mTemporaryIndex = i + 1;
+        }
+        return false;
+      case EOpLogicalAnd:
+        // &quot;x &amp;&amp; y&quot; is equivalent to &quot;x ? y : false&quot;, which unfolds to &quot;bool s; if(x) s = y; else s = false;&quot;,
+        // and then further simplifies down to &quot;bool s = x; if(s) s = y;&quot;.
+        {
+            int i = mTemporaryIndex;
+
+            out &lt;&lt; &quot;bool s&quot; &lt;&lt; i &lt;&lt; &quot;;\n&quot;;
+
+            out &lt;&lt; &quot;{\n&quot;;
+
+            mTemporaryIndex = i + 1;
+            node-&gt;getLeft()-&gt;traverse(this);
+            out &lt;&lt; &quot;s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getLeft()-&gt;traverse(mOutputHLSL);
+            out &lt;&lt; &quot;;\n&quot;;
+            out &lt;&lt; &quot;if (s&quot; &lt;&lt; i &lt;&lt; &quot;)\n&quot;
+                   &quot;{\n&quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getRight()-&gt;traverse(this);
+            out &lt;&lt; &quot;    s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+            mTemporaryIndex = i + 1;
+            node-&gt;getRight()-&gt;traverse(mOutputHLSL);
+            out &lt;&lt; &quot;;\n&quot;
+                   &quot;}\n&quot;;
+
+            out &lt;&lt; &quot;}\n&quot;;
+
+            mTemporaryIndex = i + 1;
+        }
+        return false;
+      default:
+        return true;
+    }
+}
+
+bool UnfoldShortCircuit::visitSelection(Visit visit, TIntermSelection *node)
+{
+    TInfoSinkBase &amp;out = mOutputHLSL-&gt;getBodyStream();
+
+    // Unfold &quot;b ? x : y&quot; into &quot;type s; if(b) s = x; else s = y;&quot;
+    if (node-&gt;usesTernaryOperator())
+    {
+        int i = mTemporaryIndex;
+
+        out &lt;&lt; mOutputHLSL-&gt;typeString(node-&gt;getType()) &lt;&lt; &quot; s&quot; &lt;&lt; i &lt;&lt; &quot;;\n&quot;;
+
+        out &lt;&lt; &quot;{\n&quot;;
+
+        mTemporaryIndex = i + 1;
+        node-&gt;getCondition()-&gt;traverse(this);
+        out &lt;&lt; &quot;if (&quot;;
+        mTemporaryIndex = i + 1;
+        node-&gt;getCondition()-&gt;traverse(mOutputHLSL);
+        out &lt;&lt; &quot;)\n&quot;
+               &quot;{\n&quot;;
+        mTemporaryIndex = i + 1;
+        node-&gt;getTrueBlock()-&gt;traverse(this);
+        out &lt;&lt; &quot;    s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+        mTemporaryIndex = i + 1;
+        node-&gt;getTrueBlock()-&gt;traverse(mOutputHLSL);
+        out &lt;&lt; &quot;;\n&quot;
+               &quot;}\n&quot;
+               &quot;else\n&quot;
+               &quot;{\n&quot;;
+        mTemporaryIndex = i + 1;
+        node-&gt;getFalseBlock()-&gt;traverse(this);
+        out &lt;&lt; &quot;    s&quot; &lt;&lt; i &lt;&lt; &quot; = &quot;;
+        mTemporaryIndex = i + 1;
+        node-&gt;getFalseBlock()-&gt;traverse(mOutputHLSL);
+        out &lt;&lt; &quot;;\n&quot;
+               &quot;}\n&quot;;
+
+        out &lt;&lt; &quot;}\n&quot;;
+
+        mTemporaryIndex = i + 1;
+    }
+
+    return false;
+}
+
+bool UnfoldShortCircuit::visitLoop(Visit visit, TIntermLoop *node)
+{
+    int rewindIndex = mTemporaryIndex;
+
+    if (node-&gt;getInit())
+    {
+        node-&gt;getInit()-&gt;traverse(this);
+    }
+    
+    if (node-&gt;getCondition())
+    {
+        node-&gt;getCondition()-&gt;traverse(this);
+    }
+
+    if (node-&gt;getExpression())
+    {
+        node-&gt;getExpression()-&gt;traverse(this);
+    }
+
+    mTemporaryIndex = rewindIndex;
+
+    return false;
+}
+
+int UnfoldShortCircuit::getNextTemporaryIndex()
+{
+    return mTemporaryIndex++;
+}
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuith"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// 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.
+//
+// UnfoldShortCircuit is an AST traverser to output short-circuiting operators as if-else statements
+//
+
+#ifndef COMPILER_UNFOLDSHORTCIRCUIT_H_
+#define COMPILER_UNFOLDSHORTCIRCUIT_H_
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+namespace sh
+{
+class OutputHLSL;
+
+class UnfoldShortCircuit : public TIntermTraverser
+{
+  public:
+    UnfoldShortCircuit(TParseContext &amp;context, OutputHLSL *outputHLSL);
+
+    void traverse(TIntermNode *node);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitSelection(Visit visit, TIntermSelection *node);
+    bool visitLoop(Visit visit, TIntermLoop *node);
+
+    int getNextTemporaryIndex();
+
+  protected:
+    TParseContext &amp;mContext;
+    OutputHLSL *const mOutputHLSL;
+
+    int mTemporaryIndex;
+};
+}
+
+#endif   // COMPILER_UNFOLDSHORTCIRCUIT_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuit.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitASTcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,81 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/UnfoldShortCircuitAST.h&quot;
+
+namespace
+{
+
+// &quot;x || y&quot; is equivalent to &quot;x ? true : y&quot;.
+TIntermSelection *UnfoldOR(TIntermTyped *x, TIntermTyped *y)
+{
+    const TType boolType(EbtBool, EbpUndefined);
+    ConstantUnion *u = new ConstantUnion;
+    u-&gt;setBConst(true);
+    TIntermConstantUnion *trueNode = new TIntermConstantUnion(
+        u, TType(EbtBool, EbpUndefined, EvqConst, 1));
+    return new TIntermSelection(x, trueNode, y, boolType);
+}
+
+// &quot;x &amp;&amp; y&quot; is equivalent to &quot;x ? y : false&quot;.
+TIntermSelection *UnfoldAND(TIntermTyped *x, TIntermTyped *y)
+{
+    const TType boolType(EbtBool, EbpUndefined);
+    ConstantUnion *u = new ConstantUnion;
+    u-&gt;setBConst(false);
+    TIntermConstantUnion *falseNode = new TIntermConstantUnion(
+        u, TType(EbtBool, EbpUndefined, EvqConst, 1));
+    return new TIntermSelection(x, y, falseNode, boolType);
+}
+
+}  // namespace anonymous
+
+bool UnfoldShortCircuitAST::visitBinary(Visit visit, TIntermBinary *node)
+{
+    TIntermSelection *replacement = NULL;
+
+    switch (node-&gt;getOp())
+    {
+      case EOpLogicalOr:
+        replacement = UnfoldOR(node-&gt;getLeft(), node-&gt;getRight());
+        break;
+      case EOpLogicalAnd:
+        replacement = UnfoldAND(node-&gt;getLeft(), node-&gt;getRight());
+        break;
+      default:
+        break;
+    }
+    if (replacement)
+    {
+        replacements.push_back(
+            NodeUpdateEntry(getParentNode(), node, replacement));
+    }
+    return true;
+}
+
+void UnfoldShortCircuitAST::updateTree()
+{
+    for (size_t ii = 0; ii &lt; replacements.size(); ++ii)
+    {
+        const NodeUpdateEntry&amp; entry = replacements[ii];
+        ASSERT(entry.parent);
+        bool replaced = entry.parent-&gt;replaceChildNode(
+            entry.original, entry.replacement);
+        ASSERT(replaced);
+
+        // In AST traversing, a parent is visited before its children.
+        // After we replace a node, if an immediate child is to
+        // be replaced, we need to make sure we don't update the replaced
+    // node; instead, we update the replacement node.
+        for (size_t jj = ii + 1; jj &lt; replacements.size(); ++jj)
+        {
+            NodeUpdateEntry&amp; entry2 = replacements[jj];
+            if (entry2.parent == entry.original)
+                entry2.parent = entry.replacement;
+        }
+    }
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUnfoldShortCircuitASTh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// UnfoldShortCircuitAST is an AST traverser to replace short-circuiting
+// operations with ternary operations.
+//
+
+#ifndef COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
+#define COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+// This traverser identifies all the short circuit binary  nodes that need to
+// be replaced, and creates the corresponding replacement nodes. However,
+// the actual replacements happen after the traverse through updateTree().
+
+class UnfoldShortCircuitAST : public TIntermTraverser
+{
+  public:
+    UnfoldShortCircuitAST() { }
+
+    virtual bool visitBinary(Visit visit, TIntermBinary *);
+
+    void updateTree();
+
+  private:
+    struct NodeUpdateEntry
+    {
+        NodeUpdateEntry(TIntermNode *_parent,
+                        TIntermNode *_original,
+                        TIntermNode *_replacement)
+            : parent(_parent),
+              original(_original),
+              replacement(_replacement) {}
+
+        TIntermNode *parent;
+        TIntermNode *original;
+        TIntermNode *replacement;
+    };
+
+    // During traversing, save all the replacements that need to happen;
+    // then replace them by calling updateNodes().
+    std::vector&lt;NodeUpdateEntry&gt; replacements;
+
+    DISALLOW_COPY_AND_ASSIGN(UnfoldShortCircuitAST);
+};
+
+#endif  // COMPILER_UNFOLD_SHORT_CIRCUIT_AST_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/UnfoldShortCircuitAST.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUniformcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/Uniform.h&quot;
+
+namespace sh
+{
+
+Uniform::Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex)
+{
+    this-&gt;type = type;
+    this-&gt;precision = precision;
+    this-&gt;name = name;
+    this-&gt;arraySize = arraySize;
+    this-&gt;registerIndex = registerIndex;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorUniformh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_UNIFORM_H_
+#define COMPILER_UNIFORM_H_
+
+#include &lt;string&gt;
+#include &lt;vector&gt;
+
+#define GL_APICALL
+#include &lt;GLES2/gl2.h&gt;
+
+namespace sh
+{
+
+struct Uniform
+{
+    Uniform(GLenum type, GLenum precision, const char *name, int arraySize, int registerIndex);
+
+    GLenum type;
+    GLenum precision;
+    std::string name;
+    unsigned int arraySize;
+    
+    int registerIndex;
+};
+
+typedef std::vector&lt;Uniform&gt; ActiveUniforms;
+
+}
+
+#endif   // COMPILER_UNIFORM_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/Uniform.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorValidateLimitationscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,512 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/ValidateLimitations.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+namespace {
+bool IsLoopIndex(const TIntermSymbol* symbol, const TLoopStack&amp; stack) {
+    for (TLoopStack::const_iterator i = stack.begin(); i != stack.end(); ++i) {
+        if (i-&gt;index.id == symbol-&gt;getId())
+            return true;
+    }
+    return false;
+}
+
+void MarkLoopForUnroll(const TIntermSymbol* symbol, TLoopStack&amp; stack) {
+    for (TLoopStack::iterator i = stack.begin(); i != stack.end(); ++i) {
+        if (i-&gt;index.id == symbol-&gt;getId()) {
+            ASSERT(i-&gt;loop != NULL);
+            i-&gt;loop-&gt;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.
+// Constant-index-expressions can include loop indices as defined in
+// GLSL ES 1.0 spec, Appendix A, section 4.
+// The following are constant-index-expressions:
+// - Constant expressions
+// - Loop indices as defined in section 4
+// - Expressions composed of both of the above
+class ValidateConstIndexExpr : public TIntermTraverser {
+public:
+    ValidateConstIndexExpr(const TLoopStack&amp; stack)
+        : mValid(true), mLoopStack(stack) {}
+
+    // Returns true if the parsed node represents a constant index expression.
+    bool isValid() const { return mValid; }
+
+    virtual void visitSymbol(TIntermSymbol* symbol) {
+        // Only constants and loop indices are allowed in a
+        // constant index expression.
+        if (mValid) {
+            mValid = (symbol-&gt;getQualifier() == EvqConst) ||
+                     IsLoopIndex(symbol, mLoopStack);
+        }
+    }
+
+private:
+    bool mValid;
+    const TLoopStack&amp; 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&amp; 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-&gt;getBasicType()) {
+              case EbtFloat:
+                mUsesFloatLoopIndex = true;
+                break;
+              case EbtInt:
+                mUsesIntLoopIndex = true;
+                MarkLoopForUnroll(symbol, mLoopStack);
+                break;
+              default:
+                UNREACHABLE();
+            }
+        }
+    }
+
+private:
+    bool mUsesFloatLoopIndex;
+    bool mUsesIntLoopIndex;
+    TLoopStack&amp; mLoopStack;
+};
+}  // namespace
+
+ValidateLimitations::ValidateLimitations(ShShaderType shaderType,
+                                         TInfoSinkBase&amp; sink)
+    : mShaderType(shaderType),
+      mSink(sink),
+      mNumErrors(0)
+{
+}
+
+bool ValidateLimitations::visitBinary(Visit, TIntermBinary* node)
+{
+    // Check if loop index is modified in the loop body.
+    validateOperation(node, node-&gt;getLeft());
+
+    // Check indexing.
+    switch (node-&gt;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-&gt;getLeft() != NULL) &amp;&amp; (node-&gt;getRight() != NULL) &amp;&amp;
+            (node-&gt;getLeft()-&gt;getAsSymbolNode())) {
+            TIntermSymbol* symbol = node-&gt;getLeft()-&gt;getAsSymbolNode();
+            if (IsSampler(symbol-&gt;getBasicType()) &amp;&amp; symbol-&gt;isArray()) {
+                ValidateLoopIndexExpr validate(mLoopStack);
+                node-&gt;getRight()-&gt;traverse(&amp;validate);
+                if (validate.usesFloatLoopIndex()) {
+                    error(node-&gt;getLine(),
+                          &quot;sampler array index is float loop index&quot;,
+                          &quot;for&quot;);
+                }
+            }
+        }
+#endif
+        validateIndexing(node);
+        break;
+      default: break;
+    }
+    return true;
+}
+
+bool ValidateLimitations::visitUnary(Visit, TIntermUnary* node)
+{
+    // Check if loop index is modified in the loop body.
+    validateOperation(node, node-&gt;getOperand());
+
+    return true;
+}
+
+bool ValidateLimitations::visitAggregate(Visit, TIntermAggregate* node)
+{
+    switch (node-&gt;getOp()) {
+      case EOpFunctionCall:
+        validateFunctionCall(node);
+        break;
+      default:
+        break;
+    }
+    return true;
+}
+
+bool ValidateLimitations::visitLoop(Visit, TIntermLoop* node)
+{
+    if (!validateLoopType(node))
+        return false;
+
+    TLoopInfo info;
+    memset(&amp;info, 0, sizeof(TLoopInfo));
+    info.loop = node;
+    if (!validateForLoopHeader(node, &amp;info))
+        return false;
+
+    TIntermNode* body = node-&gt;getBody();
+    if (body != NULL) {
+        mLoopStack.push_back(info);
+        body-&gt;traverse(this);
+        mLoopStack.pop_back();
+    }
+
+    // The loop is fully processed - no need to visit children.
+    return false;
+}
+
+void ValidateLimitations::error(TSourceLoc loc,
+                                const char *reason, const char* token)
+{
+    mSink.prefix(EPrefixError);
+    mSink.location(loc);
+    mSink &lt;&lt; &quot;'&quot; &lt;&lt; token &lt;&lt; &quot;' : &quot; &lt;&lt; reason &lt;&lt; &quot;\n&quot;;
+    ++mNumErrors;
+}
+
+bool ValidateLimitations::withinLoopBody() const
+{
+    return !mLoopStack.empty();
+}
+
+bool ValidateLimitations::isLoopIndex(const TIntermSymbol* symbol) const
+{
+    return IsLoopIndex(symbol, mLoopStack);
+}
+
+bool ValidateLimitations::validateLoopType(TIntermLoop* node) {
+    TLoopType type = node-&gt;getType();
+    if (type == ELoopFor)
+        return true;
+
+    // Reject while and do-while loops.
+    error(node-&gt;getLine(),
+          &quot;This type of loop is not allowed&quot;,
+          type == ELoopWhile ? &quot;while&quot; : &quot;do&quot;);
+    return false;
+}
+
+bool ValidateLimitations::validateForLoopHeader(TIntermLoop* node,
+                                                TLoopInfo* info)
+{
+    ASSERT(node-&gt;getType() == ELoopFor);
+
+    //
+    // The for statement has the form:
+    //    for ( init-declaration ; condition ; expression ) statement
+    //
+    if (!validateForLoopInit(node, info))
+        return false;
+    if (!validateForLoopCond(node, info))
+        return false;
+    if (!validateForLoopExpr(node, info))
+        return false;
+
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopInit(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* init = node-&gt;getInit();
+    if (init == NULL) {
+        error(node-&gt;getLine(), &quot;Missing init declaration&quot;, &quot;for&quot;);
+        return false;
+    }
+
+    //
+    // init-declaration has the form:
+    //     type-specifier identifier = constant-expression
+    //
+    TIntermAggregate* decl = init-&gt;getAsAggregate();
+    if ((decl == NULL) || (decl-&gt;getOp() != EOpDeclaration)) {
+        error(init-&gt;getLine(), &quot;Invalid init declaration&quot;, &quot;for&quot;);
+        return false;
+    }
+    // To keep things simple do not allow declaration list.
+    TIntermSequence&amp; declSeq = decl-&gt;getSequence();
+    if (declSeq.size() != 1) {
+        error(decl-&gt;getLine(), &quot;Invalid init declaration&quot;, &quot;for&quot;);
+        return false;
+    }
+    TIntermBinary* declInit = declSeq[0]-&gt;getAsBinaryNode();
+    if ((declInit == NULL) || (declInit-&gt;getOp() != EOpInitialize)) {
+        error(decl-&gt;getLine(), &quot;Invalid init declaration&quot;, &quot;for&quot;);
+        return false;
+    }
+    TIntermSymbol* symbol = declInit-&gt;getLeft()-&gt;getAsSymbolNode();
+    if (symbol == NULL) {
+        error(declInit-&gt;getLine(), &quot;Invalid init declaration&quot;, &quot;for&quot;);
+        return false;
+    }
+    // The loop index has type int or float.
+    TBasicType type = symbol-&gt;getBasicType();
+    if ((type != EbtInt) &amp;&amp; (type != EbtFloat)) {
+        error(symbol-&gt;getLine(),
+              &quot;Invalid type for loop index&quot;, getBasicString(type));
+        return false;
+    }
+    // The loop index is initialized with constant expression.
+    if (!isConstExpr(declInit-&gt;getRight())) {
+        error(declInit-&gt;getLine(),
+              &quot;Loop index cannot be initialized with non-constant expression&quot;,
+              symbol-&gt;getSymbol().c_str());
+        return false;
+    }
+
+    info-&gt;index.id = symbol-&gt;getId();
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopCond(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* cond = node-&gt;getCondition();
+    if (cond == NULL) {
+        error(node-&gt;getLine(), &quot;Missing condition&quot;, &quot;for&quot;);
+        return false;
+    }
+    //
+    // condition has the form:
+    //     loop_index relational_operator constant_expression
+    //
+    TIntermBinary* binOp = cond-&gt;getAsBinaryNode();
+    if (binOp == NULL) {
+        error(node-&gt;getLine(), &quot;Invalid condition&quot;, &quot;for&quot;);
+        return false;
+    }
+    // Loop index should be to the left of relational operator.
+    TIntermSymbol* symbol = binOp-&gt;getLeft()-&gt;getAsSymbolNode();
+    if (symbol == NULL) {
+        error(binOp-&gt;getLine(), &quot;Invalid condition&quot;, &quot;for&quot;);
+        return false;
+    }
+    if (symbol-&gt;getId() != info-&gt;index.id) {
+        error(symbol-&gt;getLine(),
+              &quot;Expected loop index&quot;, symbol-&gt;getSymbol().c_str());
+        return false;
+    }
+    // Relational operator is one of: &gt; &gt;= &lt; &lt;= == or !=.
+    switch (binOp-&gt;getOp()) {
+      case EOpEqual:
+      case EOpNotEqual:
+      case EOpLessThan:
+      case EOpGreaterThan:
+      case EOpLessThanEqual:
+      case EOpGreaterThanEqual:
+        break;
+      default:
+        error(binOp-&gt;getLine(),
+              &quot;Invalid relational operator&quot;,
+              getOperatorString(binOp-&gt;getOp()));
+        break;
+    }
+    // Loop index must be compared with a constant.
+    if (!isConstExpr(binOp-&gt;getRight())) {
+        error(binOp-&gt;getLine(),
+              &quot;Loop index cannot be compared with non-constant expression&quot;,
+              symbol-&gt;getSymbol().c_str());
+        return false;
+    }
+
+    return true;
+}
+
+bool ValidateLimitations::validateForLoopExpr(TIntermLoop* node,
+                                              TLoopInfo* info)
+{
+    TIntermNode* expr = node-&gt;getExpression();
+    if (expr == NULL) {
+        error(node-&gt;getLine(), &quot;Missing expression&quot;, &quot;for&quot;);
+        return false;
+    }
+
+    // for expression has one of the following forms:
+    //     loop_index++
+    //     loop_index--
+    //     loop_index += constant_expression
+    //     loop_index -= constant_expression
+    //     ++loop_index
+    //     --loop_index
+    // The last two forms are not specified in the spec, but I am assuming
+    // its an oversight.
+    TIntermUnary* unOp = expr-&gt;getAsUnaryNode();
+    TIntermBinary* binOp = unOp ? NULL : expr-&gt;getAsBinaryNode();
+
+    TOperator op = EOpNull;
+    TIntermSymbol* symbol = NULL;
+    if (unOp != NULL) {
+        op = unOp-&gt;getOp();
+        symbol = unOp-&gt;getOperand()-&gt;getAsSymbolNode();
+    } else if (binOp != NULL) {
+        op = binOp-&gt;getOp();
+        symbol = binOp-&gt;getLeft()-&gt;getAsSymbolNode();
+    }
+
+    // The operand must be loop index.
+    if (symbol == NULL) {
+        error(expr-&gt;getLine(), &quot;Invalid expression&quot;, &quot;for&quot;);
+        return false;
+    }
+    if (symbol-&gt;getId() != info-&gt;index.id) {
+        error(symbol-&gt;getLine(),
+              &quot;Expected loop index&quot;, symbol-&gt;getSymbol().c_str());
+        return false;
+    }
+
+    // The operator is one of: ++ -- += -=.
+    switch (op) {
+        case EOpPostIncrement:
+        case EOpPostDecrement:
+        case EOpPreIncrement:
+        case EOpPreDecrement:
+            ASSERT((unOp != NULL) &amp;&amp; (binOp == NULL));
+            break;
+        case EOpAddAssign:
+        case EOpSubAssign:
+            ASSERT((unOp == NULL) &amp;&amp; (binOp != NULL));
+            break;
+        default:
+            error(expr-&gt;getLine(), &quot;Invalid operator&quot;, getOperatorString(op));
+            return false;
+    }
+
+    // Loop index must be incremented/decremented with a constant.
+    if (binOp != NULL) {
+        if (!isConstExpr(binOp-&gt;getRight())) {
+            error(binOp-&gt;getLine(),
+                  &quot;Loop index cannot be modified by non-constant expression&quot;,
+                  symbol-&gt;getSymbol().c_str());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool ValidateLimitations::validateFunctionCall(TIntermAggregate* node)
+{
+    ASSERT(node-&gt;getOp() == EOpFunctionCall);
+
+    // If not within loop body, there is nothing to check.
+    if (!withinLoopBody())
+        return true;
+
+    // List of param indices for which loop indices are used as argument.
+    typedef std::vector&lt;size_t&gt; ParamIndex;
+    ParamIndex pIndex;
+    TIntermSequence&amp; params = node-&gt;getSequence();
+    for (TIntermSequence::size_type i = 0; i &lt; params.size(); ++i) {
+        TIntermSymbol* symbol = params[i]-&gt;getAsSymbolNode();
+        if (symbol &amp;&amp; isLoopIndex(symbol))
+            pIndex.push_back(i);
+    }
+    // If none of the loop indices are used as arguments,
+    // there is nothing to check.
+    if (pIndex.empty())
+        return true;
+
+    bool valid = true;
+    TSymbolTable&amp; symbolTable = GetGlobalParseContext()-&gt;symbolTable;
+    TSymbol* symbol = symbolTable.find(node-&gt;getName());
+    ASSERT(symbol &amp;&amp; symbol-&gt;isFunction());
+    TFunction* function = static_cast&lt;TFunction*&gt;(symbol);
+    for (ParamIndex::const_iterator i = pIndex.begin();
+         i != pIndex.end(); ++i) {
+        const TParameter&amp; param = function-&gt;getParam(*i);
+        TQualifier qual = param.type-&gt;getQualifier();
+        if ((qual == EvqOut) || (qual == EvqInOut)) {
+            error(params[*i]-&gt;getLine(),
+                  &quot;Loop index cannot be used as argument to a function out or inout parameter&quot;,
+                  params[*i]-&gt;getAsSymbolNode()-&gt;getSymbol().c_str());
+            valid = false;
+        }
+    }
+
+    return valid;
+}
+
+bool ValidateLimitations::validateOperation(TIntermOperator* node,
+                                            TIntermNode* operand) {
+    // Check if loop index is modified in the loop body.
+    if (!withinLoopBody() || !node-&gt;isAssignment())
+        return true;
+
+    const TIntermSymbol* symbol = operand-&gt;getAsSymbolNode();
+    if (symbol &amp;&amp; isLoopIndex(symbol)) {
+        error(node-&gt;getLine(),
+              &quot;Loop index cannot be statically assigned to within the body of the loop&quot;,
+              symbol-&gt;getSymbol().c_str());
+    }
+    return true;
+}
+
+bool ValidateLimitations::isConstExpr(TIntermNode* node)
+{
+    ASSERT(node != NULL);
+    return node-&gt;getAsConstantUnion() != NULL;
+}
+
+bool ValidateLimitations::isConstIndexExpr(TIntermNode* node)
+{
+    ASSERT(node != NULL);
+
+    ValidateConstIndexExpr validate(mLoopStack);
+    node-&gt;traverse(&amp;validate);
+    return validate.isValid();
+}
+
+bool ValidateLimitations::validateIndexing(TIntermBinary* node)
+{
+    ASSERT((node-&gt;getOp() == EOpIndexDirect) ||
+           (node-&gt;getOp() == EOpIndexIndirect));
+
+    bool valid = true;
+    TIntermTyped* index = node-&gt;getRight();
+    // The index expression must have integral type.
+    if (!index-&gt;isScalar() || (index-&gt;getBasicType() != EbtInt)) {
+        error(index-&gt;getLine(),
+              &quot;Index expression must have integral type&quot;,
+              index-&gt;getCompleteString().c_str());
+        valid = false;
+    }
+    // The index expession must be a constant-index-expression unless
+    // the operand is a uniform in a vertex shader.
+    TIntermTyped* operand = node-&gt;getLeft();
+    bool skip = (mShaderType == SH_VERTEX_SHADER) &amp;&amp;
+                (operand-&gt;getQualifier() == EvqUniform);
+    if (!skip &amp;&amp; !isConstIndexExpr(index)) {
+        error(index-&gt;getLine(), &quot;Index expression must be constant&quot;, &quot;[]&quot;);
+        valid = false;
+    }
+    return valid;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorValidateLimitationsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+class TInfoSinkBase;
+
+struct TLoopInfo {
+    struct TIndex {
+        int id;  // symbol id.
+    } index;
+    TIntermLoop* loop;
+};
+typedef TVector&lt;TLoopInfo&gt; TLoopStack;
+
+// Traverses intermediate tree to ensure that the shader does not exceed the
+// minimum functionality mandated in GLSL 1.0 spec, Appendix A.
+class ValidateLimitations : public TIntermTraverser {
+public:
+    ValidateLimitations(ShShaderType shaderType, TInfoSinkBase&amp; sink);
+
+    int numErrors() const { return mNumErrors; }
+
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+
+private:
+    void error(TSourceLoc loc, const char *reason, const char* token);
+
+    bool withinLoopBody() const;
+    bool isLoopIndex(const TIntermSymbol* symbol) const;
+    bool validateLoopType(TIntermLoop* node);
+    bool validateForLoopHeader(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopInit(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopCond(TIntermLoop* node, TLoopInfo* info);
+    bool validateForLoopExpr(TIntermLoop* node, TLoopInfo* info);
+    // Returns true if none of the loop indices is used as the argument to
+    // the given function out or inout parameter.
+    bool validateFunctionCall(TIntermAggregate* node);
+    bool validateOperation(TIntermOperator* node, TIntermNode* operand);
+
+    // Returns true if indexing does not exceed the minimum functionality
+    // mandated in GLSL 1.0 spec, Appendix A, Section 5.
+    bool isConstExpr(TIntermNode* node);
+    bool isConstIndexExpr(TIntermNode* node);
+    bool validateIndexing(TIntermBinary* node);
+
+    ShShaderType mShaderType;
+    TInfoSinkBase&amp; mSink;
+    int mNumErrors;
+    TLoopStack mLoopStack;
+};
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ValidateLimitations.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVariableInfocpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,312 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/VariableInfo.h&quot;
+
+namespace {
+
+TString arrayBrackets(int index)
+{
+    TStringStream stream;
+    stream &lt;&lt; &quot;[&quot; &lt;&lt; index &lt;&lt; &quot;]&quot;;
+    return stream.str();
+}
+
+// Returns the data type for an attribute, uniform, or varying.
+ShDataType getVariableDataType(const TType&amp; type)
+{
+    switch (type.getBasicType()) {
+      case EbtFloat:
+          if (type.isMatrix()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_FLOAT_MAT2;
+                case 3: return SH_FLOAT_MAT3;
+                case 4: return SH_FLOAT_MAT4;
+                default: UNREACHABLE();
+              }
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_FLOAT_VEC2;
+                case 3: return SH_FLOAT_VEC3;
+                case 4: return SH_FLOAT_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_FLOAT;
+          }
+      case EbtInt:
+          if (type.isMatrix()) {
+              UNREACHABLE();
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_INT_VEC2;
+                case 3: return SH_INT_VEC3;
+                case 4: return SH_INT_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_INT;
+          }
+      case EbtBool:
+          if (type.isMatrix()) {
+              UNREACHABLE();
+          } else if (type.isVector()) {
+              switch (type.getNominalSize()) {
+                case 2: return SH_BOOL_VEC2;
+                case 3: return SH_BOOL_VEC3;
+                case 4: return SH_BOOL_VEC4;
+                default: UNREACHABLE();
+              }
+          } else {
+              return SH_BOOL;
+          }
+      case EbtSampler2D: return SH_SAMPLER_2D;
+      case EbtSamplerCube: return SH_SAMPLER_CUBE;
+      case EbtSamplerExternalOES: return SH_SAMPLER_EXTERNAL_OES;
+      case EbtSampler2DRect: return SH_SAMPLER_2D_RECT_ARB;
+      default: UNREACHABLE();
+    }
+    return SH_NONE;
+}
+
+void getBuiltInVariableInfo(const TType&amp; type,
+                            const TString&amp; name,
+                            const TString&amp; mappedName,
+                            TVariableInfoList&amp; infoList);
+void getUserDefinedVariableInfo(const TType&amp; type,
+                                const TString&amp; name,
+                                const TString&amp; mappedName,
+                                TVariableInfoList&amp; infoList,
+                                ShHashFunction64 hashFunction);
+
+// Returns info for an attribute, uniform, or varying.
+void getVariableInfo(const TType&amp; type,
+                     const TString&amp; name,
+                     const TString&amp; mappedName,
+                     TVariableInfoList&amp; infoList,
+                     ShHashFunction64 hashFunction)
+{
+    if (type.getBasicType() == EbtStruct) {
+        if (type.isArray()) {
+            for (int i = 0; i &lt; type.getArraySize(); ++i) {
+                TString lname = name + arrayBrackets(i);
+                TString lmappedName = mappedName + arrayBrackets(i);
+                getUserDefinedVariableInfo(type, lname, lmappedName, infoList, hashFunction);
+            }
+        } else {
+            getUserDefinedVariableInfo(type, name, mappedName, infoList, hashFunction);
+        }
+    } else {
+        getBuiltInVariableInfo(type, name, mappedName, infoList);
+    }
+}
+
+void getBuiltInVariableInfo(const TType&amp; type,
+                            const TString&amp; name,
+                            const TString&amp; mappedName,
+                            TVariableInfoList&amp; infoList)
+{
+    ASSERT(type.getBasicType() != EbtStruct);
+
+    TVariableInfo varInfo;
+    if (type.isArray()) {
+        varInfo.name = (name + &quot;[0]&quot;).c_str();
+        varInfo.mappedName = (mappedName + &quot;[0]&quot;).c_str();
+        varInfo.size = type.getArraySize();
+        varInfo.isArray = true;
+    } else {
+        varInfo.name = name.c_str();
+        varInfo.mappedName = mappedName.c_str();
+        varInfo.size = 1;
+        varInfo.isArray = false;
+    }
+    varInfo.precision = type.getPrecision();
+    varInfo.type = getVariableDataType(type);
+    infoList.push_back(varInfo);
+}
+
+void getUserDefinedVariableInfo(const TType&amp; type,
+                                const TString&amp; name,
+                                const TString&amp; mappedName,
+                                TVariableInfoList&amp; infoList,
+                                ShHashFunction64 hashFunction)
+{
+    ASSERT(type.getBasicType() == EbtStruct);
+
+    const TFieldList&amp; fields = type.getStruct()-&gt;fields();
+    for (size_t i = 0; i &lt; fields.size(); ++i) {
+        const TType&amp; fieldType = *(fields[i]-&gt;type());
+        const TString&amp; fieldName = fields[i]-&gt;name();
+        getVariableInfo(fieldType,
+                        name + &quot;.&quot; + fieldName,
+                        mappedName + &quot;.&quot; + TIntermTraverser::hash(fieldName, hashFunction),
+                        infoList,
+                        hashFunction);
+    }
+}
+
+TVariableInfo* findVariable(const TType&amp; type,
+                            const TString&amp; name,
+                            TVariableInfoList&amp; infoList)
+{
+    // TODO(zmo): optimize this function.
+    TString myName = name;
+    if (type.isArray())
+        myName += &quot;[0]&quot;;
+    for (size_t ii = 0; ii &lt; infoList.size(); ++ii)
+    {
+        if (infoList[ii].name.c_str() == myName)
+            return &amp;(infoList[ii]);
+    }
+    return NULL;
+}
+
+}  // namespace anonymous
+
+TVariableInfo::TVariableInfo()
+    : type(SH_NONE),
+      size(0),
+      isArray(false),
+      precision(EbpUndefined),
+      staticUse(false)
+{
+}
+
+TVariableInfo::TVariableInfo(ShDataType type, int size)
+    : type(type),
+      size(size),
+      isArray(false),
+      precision(EbpUndefined),
+      staticUse(false)
+{
+}
+
+CollectVariables::CollectVariables(TVariableInfoList&amp; attribs,
+                                   TVariableInfoList&amp; uniforms,
+                                   TVariableInfoList&amp; varyings,
+                                   ShHashFunction64 hashFunction)
+    : mAttribs(attribs),
+      mUniforms(uniforms),
+      mVaryings(varyings),
+      mPointCoordAdded(false),
+      mFrontFacingAdded(false),
+      mFragCoordAdded(false),
+      mHashFunction(hashFunction)
+{
+}
+
+// We want to check whether a uniform/varying is statically used
+// because we only count the used ones in packing computing.
+// Also, gl_FragCoord, gl_PointCoord, and gl_FrontFacing count
+// toward varying counting if they are statically used in a fragment
+// shader.
+void CollectVariables::visitSymbol(TIntermSymbol* symbol)
+{
+    ASSERT(symbol != NULL);
+    TVariableInfo* var = NULL;
+    switch (symbol-&gt;getQualifier())
+    {
+    case EvqVaryingOut:
+    case EvqInvariantVaryingOut:
+    case EvqVaryingIn:
+    case EvqInvariantVaryingIn:
+        var = findVariable(symbol-&gt;getType(), symbol-&gt;getSymbol(), mVaryings);
+        break;
+    case EvqUniform:
+        var = findVariable(symbol-&gt;getType(), symbol-&gt;getSymbol(), mUniforms);
+        break;
+    case EvqFragCoord:
+        if (!mFragCoordAdded) {
+            TVariableInfo info;
+            info.name = &quot;gl_FragCoord&quot;;
+            info.mappedName = &quot;gl_FragCoord&quot;;
+            info.type = SH_FLOAT_VEC4;
+            info.size = 1;
+            info.precision = EbpMedium;  // Use mediump as it doesn't really matter.
+            info.staticUse = true;
+        mVaryings.push_back(info);
+            mFragCoordAdded = true;
+        }
+        return;
+    case EvqFrontFacing:
+        if (!mFrontFacingAdded) {
+            TVariableInfo info;
+            info.name = &quot;gl_FrontFacing&quot;;
+            info.mappedName = &quot;gl_FrontFacing&quot;;
+            info.type = SH_BOOL;
+            info.size = 1;
+            info.precision = EbpUndefined;
+            info.staticUse = true;
+        mVaryings.push_back(info);
+            mFrontFacingAdded = true;
+        }
+        return;
+    case EvqPointCoord:
+        if (!mPointCoordAdded) {
+            TVariableInfo info;
+            info.name = &quot;gl_PointCoord&quot;;
+            info.mappedName = &quot;gl_PointCoord&quot;;
+            info.type = SH_FLOAT_VEC2;
+            info.size = 1;
+            info.precision = EbpMedium;  // Use mediump as it doesn't really matter.
+            info.staticUse = true;
+        mVaryings.push_back(info);
+            mPointCoordAdded = true;
+        }
+        return;
+    default:
+        break;
+    }
+    if (var)
+        var-&gt;staticUse = true;
+}
+
+bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
+{
+    bool visitChildren = true;
+
+    switch (node-&gt;getOp())
+    {
+    case EOpDeclaration: {
+        const TIntermSequence&amp; sequence = node-&gt;getSequence();
+        TQualifier qualifier = sequence.front()-&gt;getAsTyped()-&gt;getQualifier();
+        if (qualifier == EvqAttribute || qualifier == EvqUniform ||
+            qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
+            qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
+        {
+            TVariableInfoList&amp; infoList = qualifier == EvqAttribute ? mAttribs :
+                (qualifier == EvqUniform ? mUniforms : mVaryings);
+            for (TIntermSequence::const_iterator i = sequence.begin();
+                 i != sequence.end(); ++i)
+            {
+                const TIntermSymbol* variable = (*i)-&gt;getAsSymbolNode();
+                // The only case in which the sequence will not contain a
+                // TIntermSymbol node is initialization. It will contain a
+                // TInterBinary node in that case. Since attributes, uniforms,
+                // and varyings cannot be initialized in a shader, we must have
+                // only TIntermSymbol nodes in the sequence.
+                ASSERT(variable != NULL);
+                TString processedSymbol;
+                if (mHashFunction == NULL)
+                    processedSymbol = variable-&gt;getSymbol();
+                else
+                    processedSymbol = TIntermTraverser::hash(variable-&gt;getOriginalSymbol(), mHashFunction);
+                getVariableInfo(variable-&gt;getType(),
+                                variable-&gt;getOriginalSymbol(),
+                                processedSymbol,
+                                infoList,
+                                mHashFunction);
+                visitChildren = false;
+            }
+        }
+        break;
+    }
+    default: break;
+    }
+
+    return visitChildren;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVariableInfoh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,52 @@
</span><ins>+//
+// 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 &quot;GLSLANG/ShaderLang.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+// Provides information about a variable.
+// It is currently being used to store info about active attribs and uniforms.
+struct TVariableInfo {
+    TVariableInfo(ShDataType type, int size);
+    TVariableInfo();
+
+    TPersistString name;
+    TPersistString mappedName;
+    ShDataType type;
+    int size;
+    bool isArray;
+    TPrecision precision;
+    bool staticUse;
+};
+typedef std::vector&lt;TVariableInfo&gt; TVariableInfoList;
+
+// Traverses intermediate tree to collect all attributes, uniforms, varyings.
+class CollectVariables : public TIntermTraverser {
+public:
+    CollectVariables(TVariableInfoList&amp; attribs,
+                     TVariableInfoList&amp; uniforms,
+                     TVariableInfoList&amp; varyings,
+                     ShHashFunction64 hashFunction);
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+
+private:
+    TVariableInfoList&amp; mAttribs;
+    TVariableInfoList&amp; mUniforms;
+    TVariableInfoList&amp; mVaryings;
+
+    bool mPointCoordAdded;
+    bool mFrontFacingAdded;
+    bool mFragCoordAdded;
+
+    ShHashFunction64 mHashFunction;
+};
+
+#endif  // COMPILER_VARIABLE_INFO_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariableInfo.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVariablePackercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,297 @@
</span><ins>+//
+// 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 &quot;compiler/translator/VariablePacker.h&quot;
+
+#include &lt;algorithm&gt;
+#include &quot;compiler/translator/ShHandle.h&quot;
+
+namespace {
+int GetSortOrder(ShDataType type)
+{
+    switch (type) {
+        case SH_FLOAT_MAT4:
+            return 0;
+        case SH_FLOAT_MAT2:
+            return 1;
+        case SH_FLOAT_VEC4:
+        case SH_INT_VEC4:
+        case SH_BOOL_VEC4:
+            return 2;
+        case SH_FLOAT_MAT3:
+            return 3;
+        case SH_FLOAT_VEC3:
+        case SH_INT_VEC3:
+        case SH_BOOL_VEC3:
+            return 4;
+        case SH_FLOAT_VEC2:
+        case SH_INT_VEC2:
+        case SH_BOOL_VEC2:
+            return 5;
+        case SH_FLOAT:
+        case SH_INT:
+        case SH_BOOL:
+        case SH_SAMPLER_2D:
+        case SH_SAMPLER_CUBE:
+        case SH_SAMPLER_EXTERNAL_OES:
+        case SH_SAMPLER_2D_RECT_ARB:
+            return 6;
+        default:
+            ASSERT(false);
+            return 7;
+    }
+}
+}    // namespace
+
+int VariablePacker::GetNumComponentsPerRow(ShDataType type)
+{
+    switch (type) {
+        case SH_FLOAT_MAT4:
+        case SH_FLOAT_MAT2:
+        case SH_FLOAT_VEC4:
+        case SH_INT_VEC4:
+        case SH_BOOL_VEC4:
+            return 4;
+        case SH_FLOAT_MAT3:
+        case SH_FLOAT_VEC3:
+        case SH_INT_VEC3:
+        case SH_BOOL_VEC3:
+            return 3;
+        case SH_FLOAT_VEC2:
+        case SH_INT_VEC2:
+        case SH_BOOL_VEC2:
+            return 2;
+        case SH_FLOAT:
+        case SH_INT:
+        case SH_BOOL:
+        case SH_SAMPLER_2D:
+        case SH_SAMPLER_CUBE:
+        case SH_SAMPLER_EXTERNAL_OES:
+        case SH_SAMPLER_2D_RECT_ARB:
+            return 1;
+        default:
+            ASSERT(false);
+            return 5;
+    }
+}
+
+int VariablePacker::GetNumRows(ShDataType type)
+{
+    switch (type) {
+        case SH_FLOAT_MAT4:
+            return 4;
+        case SH_FLOAT_MAT3:
+            return 3;
+        case SH_FLOAT_MAT2:
+            return 2;
+        case SH_FLOAT_VEC4:
+        case SH_INT_VEC4:
+        case SH_BOOL_VEC4:
+        case SH_FLOAT_VEC3:
+        case SH_INT_VEC3:
+        case SH_BOOL_VEC3:
+        case SH_FLOAT_VEC2:
+        case SH_INT_VEC2:
+        case SH_BOOL_VEC2:
+        case SH_FLOAT:
+        case SH_INT:
+        case SH_BOOL:
+        case SH_SAMPLER_2D:
+        case SH_SAMPLER_CUBE:
+        case SH_SAMPLER_EXTERNAL_OES:
+        case SH_SAMPLER_2D_RECT_ARB:
+            return 1;
+        default:
+            ASSERT(false);
+            return 100000;
+    }
+}
+
+struct TVariableInfoComparer {
+    bool operator()(const TVariableInfo&amp; lhs, const TVariableInfo&amp; rhs) const
+    {
+        int lhsSortOrder = GetSortOrder(lhs.type);
+        int rhsSortOrder = GetSortOrder(rhs.type);
+        if (lhsSortOrder != rhsSortOrder) {
+            return lhsSortOrder &lt; rhsSortOrder;
+        }
+        // Sort by largest first.
+        return lhs.size &gt; rhs.size;
+    }
+};
+
+unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
+{
+    return ((kColumnMask &lt;&lt; (kNumColumns - numComponentsPerRow)) &amp;
+                    kColumnMask) &gt;&gt; column;
+}
+
+void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
+{
+    unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
+    for (int r = 0; r &lt; numRows; ++r) {
+        int row = topRow + r;
+        ASSERT((rows_[row] &amp; columnFlags) == 0);
+        rows_[row] |= columnFlags;
+    }
+}
+
+bool VariablePacker::searchColumn(int column, int numRows, int* destRow, int* destSize)
+{
+    ASSERT(destRow);
+
+    for (; topNonFullRow_ &lt; maxRows_ &amp;&amp; rows_[topNonFullRow_] == kColumnMask;
+         ++topNonFullRow_) {
+    }
+
+    for (; bottomNonFullRow_ &gt;= 0 &amp;&amp; rows_[bottomNonFullRow_] == kColumnMask;
+         --bottomNonFullRow_) {
+    }
+
+    if (bottomNonFullRow_ - topNonFullRow_ + 1 &lt; numRows) {
+        return false;
+    }
+
+    unsigned columnFlags = makeColumnFlags(column, 1);
+    int topGoodRow = 0;
+    int smallestGoodTop = -1;
+    int smallestGoodSize = maxRows_ + 1;
+    int bottomRow = bottomNonFullRow_ + 1;
+    bool found = false;
+    for (int row = topNonFullRow_; row &lt;= bottomRow; ++row) {
+        bool rowEmpty = row &lt; bottomRow ? ((rows_[row] &amp; columnFlags) == 0) : false;
+        if (rowEmpty) {
+            if (!found) {
+                topGoodRow = row;
+                found = true;
+            }
+        } else {
+            if (found) {
+                int size = row - topGoodRow;
+                if (size &gt;= numRows &amp;&amp; size &lt; smallestGoodSize) {
+                    smallestGoodSize = size;
+                    smallestGoodTop = topGoodRow;
+                }
+            }
+            found = false;
+        }
+    }
+    if (smallestGoodTop &lt; 0) {
+        return false;
+    }
+
+    *destRow = smallestGoodTop;
+    if (destSize) {
+        *destSize = smallestGoodSize;
+    }
+    return true;
+}
+
+bool VariablePacker::CheckVariablesWithinPackingLimits(int maxVectors, const TVariableInfoList&amp; in_variables)
+{
+    ASSERT(maxVectors &gt; 0);
+    maxRows_ = maxVectors;
+    topNonFullRow_ = 0;
+    bottomNonFullRow_ = maxRows_ - 1;
+    TVariableInfoList variables(in_variables);
+
+    // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
+    // order by type, then by size of array, largest first.
+    std::sort(variables.begin(), variables.end(), TVariableInfoComparer());
+    rows_.clear();
+    rows_.resize(maxVectors, 0);
+
+    // Packs the 4 column variables.
+    size_t ii = 0;
+    for (; ii &lt; variables.size(); ++ii) {
+        const TVariableInfo&amp; variable = variables[ii];
+        if (GetNumComponentsPerRow(variable.type) != 4) {
+            break;
+        }
+        topNonFullRow_ += GetNumRows(variable.type) * variable.size;
+    }
+
+    if (topNonFullRow_ &gt; maxRows_) {
+        return false;
+    }
+
+    // Packs the 3 column variables.
+    int num3ColumnRows = 0;
+    for (; ii &lt; variables.size(); ++ii) {
+        const TVariableInfo&amp; variable = variables[ii];
+        if (GetNumComponentsPerRow(variable.type) != 3) {
+            break;
+        }
+        num3ColumnRows += GetNumRows(variable.type) * variable.size;
+    }
+
+    if (topNonFullRow_ + num3ColumnRows &gt; maxRows_) {
+        return false;
+    }
+
+    fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
+
+    // Packs the 2 column variables.
+    int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
+    int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
+    int rowsAvailableInColumns01 = twoColumnRowsAvailable;
+    int rowsAvailableInColumns23 = twoColumnRowsAvailable;
+    for (; ii &lt; variables.size(); ++ii) {
+        const TVariableInfo&amp; variable = variables[ii];
+        if (GetNumComponentsPerRow(variable.type) != 2) {
+            break;
+        }
+        int numRows = GetNumRows(variable.type) * variable.size;
+        if (numRows &lt;= rowsAvailableInColumns01) {
+            rowsAvailableInColumns01 -= numRows;
+        } else if (numRows &lt;= rowsAvailableInColumns23) {
+            rowsAvailableInColumns23 -= numRows;
+        } else {
+            return false;
+        }
+    }
+
+    int numRowsUsedInColumns01 =
+        twoColumnRowsAvailable - rowsAvailableInColumns01;
+    int numRowsUsedInColumns23 =
+        twoColumnRowsAvailable - rowsAvailableInColumns23;
+    fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
+    fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23,
+                2, 2);
+
+    // Packs the 1 column variables.
+    for (; ii &lt; variables.size(); ++ii) {
+        const TVariableInfo&amp; variable = variables[ii];
+        ASSERT(1 == GetNumComponentsPerRow(variable.type));
+        int numRows = GetNumRows(variable.type) * variable.size;
+        int smallestColumn = -1;
+        int smallestSize = maxRows_ + 1;
+        int topRow = -1;
+        for (int column = 0; column &lt; kNumColumns; ++column) {
+            int row = 0;
+            int size = 0;
+            if (searchColumn(column, numRows, &amp;row, &amp;size)) {
+                if (size &lt; smallestSize) {
+                    smallestSize = size;
+                    smallestColumn = column;
+                    topRow = row;
+                }
+            }
+        }
+
+        if (smallestColumn &lt; 0) {
+            return false;
+        }
+
+        fillColumns(topRow, numRows, smallestColumn, 1);
+    }
+
+    ASSERT(variables.size() == ii);
+
+    return true;
+}
+
+
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVariablePackerh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+//
+// 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 _VARIABLEPACKER_INCLUDED_
+#define _VARIABLEPACKER_INCLUDED_
+
+#include &lt;vector&gt;
+#include &quot;compiler/translator/ShHandle.h&quot;
+
+class VariablePacker {
+ public:
+    // Returns true if the passed in variables pack in maxVectors following
+    // the packing rules from the GLSL 1.017 spec, Appendix A, section 7.
+    bool CheckVariablesWithinPackingLimits(
+        int maxVectors,
+        const TVariableInfoList&amp; in_variables);
+
+    // Gets how many components in a row a data type takes.
+    static int GetNumComponentsPerRow(ShDataType type);
+
+    // Gets how many rows a data type takes.
+    static int GetNumRows(ShDataType type);
+
+ private:
+    static const int kNumColumns = 4;
+    static const unsigned kColumnMask = (1 &lt;&lt; kNumColumns) - 1;
+
+    unsigned makeColumnFlags(int column, int numComponentsPerRow);
+    void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
+    bool searchColumn(int column, int numRows, int* destRow, int* destSize);
+
+    int topNonFullRow_;
+    int bottomNonFullRow_;
+    int maxRows_;
+    std::vector&lt;unsigned&gt; rows_;
+};
+
+#endif // _VARIABLEPACKER_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VariablePacker.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVersionGLSLcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,140 @@
</span><ins>+//
+// 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 &quot;compiler/translator/VersionGLSL.h&quot;
+
+static const int GLSL_VERSION_110 = 110;
+static const int GLSL_VERSION_120 = 120;
+
+// We need to scan for the following:
+// 1. &quot;invariant&quot; keyword: This can occur in both - vertex and fragment shaders
+//    but only at the global scope.
+// 2. &quot;gl_PointCoord&quot; built-in variable: This can only occur in fragment shader
+//    but inside any scope.
+// 3. Call to a matrix constructor with another matrix as argument.
+//    (These constructors were reserved in GLSL version 1.10.)
+// 4. Arrays as &quot;out&quot; function parameters.
+//    GLSL spec section 6.1.1: &quot;When calling a function, expressions that do
+//    not evaluate to l-values cannot be passed to parameters declared as
+//    out or inout.&quot;
+//    GLSL 1.1 section 5.8: &quot;Other binary or unary expressions,
+//    non-dereferenced arrays, function names, swizzles with repeated fields,
+//    and constants cannot be l-values.&quot;
+//    GLSL 1.2 relaxed the restriction on arrays, section 5.8: &quot;Variables that
+//    are built-in types, entire structures or arrays... are all l-values.&quot;
+//
+// TODO(alokp): The following two cases of invariant decalaration get lost
+// during parsing - they do not get carried over to the intermediate tree.
+// Handle these cases:
+// 1. When a pragma is used to force all output variables to be invariant:
+//    - #pragma STDGL invariant(all)
+// 2. When a previously decalared or built-in variable is marked invariant:
+//    - invariant gl_Position;
+//    - varying vec3 color; invariant color;
+//
+TVersionGLSL::TVersionGLSL(ShShaderType type)
+    : mShaderType(type),
+      mVersion(GLSL_VERSION_110)
+{
+}
+
+void TVersionGLSL::visitSymbol(TIntermSymbol* node)
+{
+    if (node-&gt;getSymbol() == &quot;gl_PointCoord&quot;)
+        updateVersion(GLSL_VERSION_120);
+}
+
+void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
+{
+    return true;
+}
+
+bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
+{
+    return true;
+}
+
+bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
+{
+    return true;
+}
+
+bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
+{
+    bool visitChildren = true;
+
+    switch (node-&gt;getOp()) {
+      case EOpSequence:
+        // We need to visit sequence children to get to global or inner scope.
+        visitChildren = true;
+        break;
+      case EOpDeclaration: {
+        const TIntermSequence&amp; sequence = node-&gt;getSequence();
+        TQualifier qualifier = sequence.front()-&gt;getAsTyped()-&gt;getQualifier();
+        if ((qualifier == EvqInvariantVaryingIn) ||
+            (qualifier == EvqInvariantVaryingOut)) {
+            updateVersion(GLSL_VERSION_120);
+        }
+        break;
+      }
+      case EOpParameters: {
+        const TIntermSequence&amp; params = node-&gt;getSequence();
+        for (TIntermSequence::const_iterator iter = params.begin();
+             iter != params.end(); ++iter)
+        {
+            const TIntermTyped* param = (*iter)-&gt;getAsTyped();
+            if (param-&gt;isArray())
+            {
+                TQualifier qualifier = param-&gt;getQualifier();
+                if ((qualifier == EvqOut) || (qualifier ==  EvqInOut))
+                {
+                    updateVersion(GLSL_VERSION_120);
+                    break;
+                }
+            }
+        }
+        // Fully processed. No need to visit children.
+        visitChildren = false;
+        break;
+      }
+      case EOpConstructMat2:
+      case EOpConstructMat3:
+      case EOpConstructMat4: {
+        const TIntermSequence&amp; sequence = node-&gt;getSequence();
+        if (sequence.size() == 1) {
+          TIntermTyped* typed = sequence.front()-&gt;getAsTyped();
+          if (typed &amp;&amp; typed-&gt;isMatrix()) {
+            updateVersion(GLSL_VERSION_120);
+          }
+        }
+        break;
+      }
+
+      default: break;
+    }
+
+    return visitChildren;
+}
+
+bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
+{
+    return true;
+}
+
+bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
+{
+    return true;
+}
+
+void TVersionGLSL::updateVersion(int version)
+{
+    mVersion = std::max(version, mVersion);
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorVersionGLSLh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_VERSIONGLSL_H_
+#define COMPILER_VERSIONGLSL_H_
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+
+// Traverses the intermediate tree to return the minimum GLSL version
+// required to legally access all built-in features used in the shader.
+// GLSL 1.1 which is mandated by OpenGL 2.0 provides:
+//   - #version and #extension to declare version and extensions.
+//   - built-in functions refract, exp, and log.
+//   - updated step() to compare x &lt; edge instead of x &lt;= edge.
+// GLSL 1.2 which is mandated by OpenGL 2.1 provides:
+//   - many changes to reduce differences when compared to the ES specification.
+//   - invariant keyword and its support.
+//   - c++ style name hiding rules.
+//   - built-in variable gl_PointCoord for fragment shaders.
+//   - matrix constructors taking matrix as argument.
+//   - array as &quot;out&quot; function parameters
+//
+class TVersionGLSL : public TIntermTraverser {
+public:
+    TVersionGLSL(ShShaderType type);
+
+    // Returns 120 if the following is used the shader:
+    // - &quot;invariant&quot;,
+    // - &quot;gl_PointCoord&quot;,
+    // - matrix/matrix constructors
+    // - array &quot;out&quot; parameters
+    // Else 110 is returned.
+    int getVersion() { return mVersion; }
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual void visitConstantUnion(TIntermConstantUnion*);
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitSelection(Visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+    virtual bool visitBranch(Visit, TIntermBranch*);
+
+protected:
+    void updateVersion(int version);
+
+private:
+    ShShaderType mShaderType;
+    int mVersion;
+};
+
+#endif  // COMPILER_VERSIONGLSL_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/VersionGLSL.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorcompilerdebugcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,37 @@
</span><ins>+//
+// 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 &quot;compiler/translator/compilerdebug.h&quot;
+
+#include &lt;stdarg.h&gt;
+#include &lt;stdio.h&gt;
+
+#include &quot;compiler/translator/InitializeParseContext.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+#ifdef TRACE_ENABLED
+static const int kTraceBufferLen = 1024;
+
+extern &quot;C&quot; {
+void Trace(const char *format, ...) {
+    if (!format) return;
+
+    TParseContext* parseContext = GetGlobalParseContext();
+    if (parseContext) {
+        char buf[kTraceBufferLen];
+        va_list args;
+        va_start(args, format);
+        vsnprintf(buf, kTraceBufferLen, format, args);
+        va_end(args);
+
+        parseContext-&gt;trace(buf);
+    }
+}
+}  // extern &quot;C&quot;
+#endif  // TRACE_ENABLED
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorcompilerdebugh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+//
+// 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.h: Debugging utilities.
+
+#ifndef COMPILER_DEBUG_H_
+#define COMPILER_DEBUG_H_
+
+#include &lt;assert.h&gt;
+
+#ifdef _DEBUG
+#define TRACE_ENABLED  // define to enable debug message tracing
+#endif  // _DEBUG
+
+// Outputs text to the debug log
+#ifdef TRACE_ENABLED
+
+#ifdef  __cplusplus
+extern &quot;C&quot; {
+#endif  // __cplusplus
+void Trace(const char* format, ...);
+#ifdef  __cplusplus
+}
+#endif  // __cplusplus
+
+#else   // TRACE_ENABLED
+
+#define Trace(...) ((void)0)
+
+#endif  // TRACE_ENABLED
+
+// A macro asserting a condition and outputting failures to the debug log
+#define ASSERT(expression) do { \
+    if(!(expression)) \
+        Trace(&quot;Assert failed: %s(%d): &quot;#expression&quot;\n&quot;, __FUNCTION__, __LINE__); \
+    assert(expression); \
+} while(0)
+
+#define UNIMPLEMENTED() do { \
+    Trace(&quot;Unimplemented invoked: %s(%d)\n&quot;, __FUNCTION__, __LINE__); \
+    assert(false); \
+} while(0)
+
+#define UNREACHABLE() do { \
+    Trace(&quot;Unreachable reached: %s(%d)\n&quot;, __FUNCTION__, __LINE__); \
+    assert(false); \
+} while(0)
+
+#endif   // COMPILER_DEBUG_H_
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/compilerdebug.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+//
+// 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.
+//
+
+#pragma warning(disable: 4718)
+
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+#include &quot;compiler/translator/depgraph/DependencyGraphBuilder.h&quot;
+
+TDependencyGraph::TDependencyGraph(TIntermNode* intermNode)
+{
+    TDependencyGraphBuilder::build(intermNode, this);
+}
+
+TDependencyGraph::~TDependencyGraph()
+{
+    for (TGraphNodeVector::const_iterator iter = mAllNodes.begin(); iter != mAllNodes.end(); ++iter)
+    {
+        TGraphNode* node = *iter;
+        delete node;
+    }
+}
+
+TGraphArgument* TDependencyGraph::createArgument(TIntermAggregate* intermFunctionCall,
+                                                 int argumentNumber)
+{
+    TGraphArgument* argument = new TGraphArgument(intermFunctionCall, argumentNumber);
+    mAllNodes.push_back(argument);
+    return argument;
+}
+
+TGraphFunctionCall* TDependencyGraph::createFunctionCall(TIntermAggregate* intermFunctionCall)
+{
+    TGraphFunctionCall* functionCall = new TGraphFunctionCall(intermFunctionCall);
+    mAllNodes.push_back(functionCall);
+    if (functionCall-&gt;getIntermFunctionCall()-&gt;isUserDefined())
+        mUserDefinedFunctionCalls.push_back(functionCall);
+    return functionCall;
+}
+
+TGraphSymbol* TDependencyGraph::getOrCreateSymbol(TIntermSymbol* intermSymbol)
+{
+    TSymbolIdMap::const_iterator iter = mSymbolIdMap.find(intermSymbol-&gt;getId());
+
+    TGraphSymbol* symbol = NULL;
+
+    if (iter != mSymbolIdMap.end()) {
+        TSymbolIdPair pair = *iter;
+        symbol = pair.second;
+    } else {
+        symbol = new TGraphSymbol(intermSymbol);
+        mAllNodes.push_back(symbol);
+
+        TSymbolIdPair pair(intermSymbol-&gt;getId(), symbol);
+        mSymbolIdMap.insert(pair);
+
+        // We save all sampler symbols in a collection, so we can start graph traversals from them quickly.
+        if (IsSampler(intermSymbol-&gt;getBasicType()))
+            mSamplerSymbols.push_back(symbol);
+    }
+
+    return symbol;
+}
+
+TGraphSelection* TDependencyGraph::createSelection(TIntermSelection* intermSelection)
+{
+    TGraphSelection* selection = new TGraphSelection(intermSelection);
+    mAllNodes.push_back(selection);
+    return selection;
+}
+
+TGraphLoop* TDependencyGraph::createLoop(TIntermLoop* intermLoop)
+{
+    TGraphLoop* loop = new TGraphLoop(intermLoop);
+    mAllNodes.push_back(loop);
+    return loop;
+}
+
+TGraphLogicalOp* TDependencyGraph::createLogicalOp(TIntermBinary* intermLogicalOp)
+{
+    TGraphLogicalOp* logicalOp = new TGraphLogicalOp(intermLogicalOp);
+    mAllNodes.push_back(logicalOp);
+    return logicalOp;
+}
+
+const char* TGraphLogicalOp::getOpString() const
+{
+    const char* opString = NULL;
+    switch (getIntermLogicalOp()-&gt;getOp()) {
+        case EOpLogicalAnd: opString = &quot;and&quot;; break;
+        case EOpLogicalOr: opString = &quot;or&quot;; break;
+        default: opString = &quot;unknown&quot;; break;
+    }
+    return opString;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,212 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
+#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_H
+
+#include &quot;compiler/translator/intermediate.h&quot;
+
+#include &lt;set&gt;
+#include &lt;stack&gt;
+
+class TGraphNode;
+class TGraphParentNode;
+class TGraphArgument;
+class TGraphFunctionCall;
+class TGraphSymbol;
+class TGraphSelection;
+class TGraphLoop;
+class TGraphLogicalOp;
+class TDependencyGraphTraverser;
+class TDependencyGraphOutput;
+
+typedef std::set&lt;TGraphNode*&gt; TGraphNodeSet;
+typedef std::vector&lt;TGraphNode*&gt; TGraphNodeVector;
+typedef std::vector&lt;TGraphSymbol*&gt; TGraphSymbolVector;
+typedef std::vector&lt;TGraphFunctionCall*&gt; TFunctionCallVector;
+
+//
+// Base class for all dependency graph nodes.
+//
+class TGraphNode {
+public:
+    TGraphNode(TIntermNode* node) : intermNode(node) {}
+    virtual ~TGraphNode() {}
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+protected:
+    TIntermNode* intermNode;
+};
+
+//
+// Base class for dependency graph nodes that may have children.
+//
+class TGraphParentNode : public TGraphNode {
+public:
+    TGraphParentNode(TIntermNode* node) : TGraphNode(node) {}
+    virtual ~TGraphParentNode() {}
+    void addDependentNode(TGraphNode* node) { if (node != this) mDependentNodes.insert(node); }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+private:
+    TGraphNodeSet mDependentNodes;
+};
+
+//
+// Handle function call arguments.
+//
+class TGraphArgument : public TGraphParentNode {
+public:
+    TGraphArgument(TIntermAggregate* intermFunctionCall, int argumentNumber)
+        : TGraphParentNode(intermFunctionCall)
+        , mArgumentNumber(argumentNumber) {}
+    virtual ~TGraphArgument() {}
+    const TIntermAggregate* getIntermFunctionCall() const { return intermNode-&gt;getAsAggregate(); }
+    int getArgumentNumber() const { return mArgumentNumber; }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+private:
+    int mArgumentNumber;
+};
+
+//
+// Handle function calls.
+//
+class TGraphFunctionCall : public TGraphParentNode {
+public:
+    TGraphFunctionCall(TIntermAggregate* intermFunctionCall)
+        : TGraphParentNode(intermFunctionCall) {}
+    virtual ~TGraphFunctionCall() {}
+    const TIntermAggregate* getIntermFunctionCall() const { return intermNode-&gt;getAsAggregate(); }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+};
+
+//
+// Handle symbols.
+//
+class TGraphSymbol : public TGraphParentNode {
+public:
+    TGraphSymbol(TIntermSymbol* intermSymbol) : TGraphParentNode(intermSymbol) {}
+    virtual ~TGraphSymbol() {}
+    const TIntermSymbol* getIntermSymbol() const { return intermNode-&gt;getAsSymbolNode(); }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+};
+
+//
+// Handle if statements and ternary operators.
+//
+class TGraphSelection : public TGraphNode {
+public:
+    TGraphSelection(TIntermSelection* intermSelection) : TGraphNode(intermSelection) {}
+    virtual ~TGraphSelection() {}
+    const TIntermSelection* getIntermSelection() const { return intermNode-&gt;getAsSelectionNode(); }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+class TGraphLoop : public TGraphNode {
+public:
+    TGraphLoop(TIntermLoop* intermLoop) : TGraphNode(intermLoop) {}
+    virtual ~TGraphLoop() {}
+    const TIntermLoop* getIntermLoop() const { return intermNode-&gt;getAsLoopNode(); }
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+};
+
+//
+// Handle logical and, or.
+//
+class TGraphLogicalOp : public TGraphNode {
+public:
+    TGraphLogicalOp(TIntermBinary* intermLogicalOp) : TGraphNode(intermLogicalOp) {}
+    virtual ~TGraphLogicalOp() {}
+    const TIntermBinary* getIntermLogicalOp() const { return intermNode-&gt;getAsBinaryNode(); }
+    const char* getOpString() const;
+    virtual void traverse(TDependencyGraphTraverser* graphTraverser);
+};
+
+//
+// A dependency graph of symbols, function calls, conditions etc.
+//
+// This class provides an interface to the entry points of the dependency graph.
+//
+// Dependency graph nodes should be created by using one of the provided &quot;create...&quot; methods.
+// This class (and nobody else) manages the memory of the created nodes.
+// Nodes may not be removed after being added, so all created nodes will exist while the
+// TDependencyGraph instance exists.
+//
+class TDependencyGraph {
+public:
+    TDependencyGraph(TIntermNode* intermNode);
+    ~TDependencyGraph();
+    TGraphNodeVector::const_iterator begin() const { return mAllNodes.begin(); }
+    TGraphNodeVector::const_iterator end() const { return mAllNodes.end(); }
+
+    TGraphSymbolVector::const_iterator beginSamplerSymbols() const
+    {
+        return mSamplerSymbols.begin();
+    }
+
+    TGraphSymbolVector::const_iterator endSamplerSymbols() const
+    {
+        return mSamplerSymbols.end();
+    }
+
+    TFunctionCallVector::const_iterator beginUserDefinedFunctionCalls() const
+    {
+        return mUserDefinedFunctionCalls.begin();
+    }
+
+    TFunctionCallVector::const_iterator endUserDefinedFunctionCalls() const
+    {
+        return mUserDefinedFunctionCalls.end();
+    }
+
+    TGraphArgument* createArgument(TIntermAggregate* intermFunctionCall, int argumentNumber);
+    TGraphFunctionCall* createFunctionCall(TIntermAggregate* intermFunctionCall);
+    TGraphSymbol* getOrCreateSymbol(TIntermSymbol* intermSymbol);
+    TGraphSelection* createSelection(TIntermSelection* intermSelection);
+    TGraphLoop* createLoop(TIntermLoop* intermLoop);
+    TGraphLogicalOp* createLogicalOp(TIntermBinary* intermLogicalOp);
+private:
+    typedef TMap&lt;int, TGraphSymbol*&gt; TSymbolIdMap;
+    typedef std::pair&lt;int, TGraphSymbol*&gt; TSymbolIdPair;
+
+    TGraphNodeVector mAllNodes;
+    TGraphSymbolVector mSamplerSymbols;
+    TFunctionCallVector mUserDefinedFunctionCalls;
+    TSymbolIdMap mSymbolIdMap;
+};
+
+//
+// For traversing the dependency graph. Users should derive from this,
+// put their traversal specific data in it, and then pass it to a
+// traverse method.
+//
+// When using this, just fill in the methods for nodes you want visited.
+//
+class TDependencyGraphTraverser {
+public:
+    TDependencyGraphTraverser() : mDepth(0) {}
+
+    virtual void visitSymbol(TGraphSymbol* symbol) {};
+    virtual void visitArgument(TGraphArgument* selection) {};
+    virtual void visitFunctionCall(TGraphFunctionCall* functionCall) {};
+    virtual void visitSelection(TGraphSelection* selection) {};
+    virtual void visitLoop(TGraphLoop* loop) {};
+    virtual void visitLogicalOp(TGraphLogicalOp* logicalOp) {};
+
+    int getDepth() const { return mDepth; }
+    void incrementDepth() { ++mDepth; }
+    void decrementDepth() { --mDepth; }
+
+    void clearVisited() { mVisited.clear(); }
+    void markVisited(TGraphNode* node) { mVisited.insert(node); }
+    bool isVisited(TGraphNode* node) const { return mVisited.find(node) != mVisited.end(); }
+private:
+    int mDepth;
+    TGraphNodeSet mVisited;
+};
+
+#endif
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraph.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphBuildercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,227 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/depgraph/DependencyGraphBuilder.h&quot;
+
+void TDependencyGraphBuilder::build(TIntermNode* node, TDependencyGraph* graph)
+{
+    TDependencyGraphBuilder builder(graph);
+    builder.build(node);
+}
+
+bool TDependencyGraphBuilder::visitAggregate(Visit visit, TIntermAggregate* intermAggregate)
+{
+    switch (intermAggregate-&gt;getOp()) {
+        case EOpFunction: visitFunctionDefinition(intermAggregate); break;
+        case EOpFunctionCall: visitFunctionCall(intermAggregate); break;
+        default: visitAggregateChildren(intermAggregate); break;
+    }
+
+    return false;
+}
+
+void TDependencyGraphBuilder::visitFunctionDefinition(TIntermAggregate* intermAggregate)
+{
+    // Currently, we do not support user defined functions.
+    if (intermAggregate-&gt;getName() != &quot;main(&quot;)
+        return;
+
+    visitAggregateChildren(intermAggregate);
+}
+
+// Takes an expression like &quot;f(x)&quot; and creates a dependency graph like
+// &quot;x -&gt; argument 0 -&gt; function call&quot;.
+void TDependencyGraphBuilder::visitFunctionCall(TIntermAggregate* intermFunctionCall)
+{
+    TGraphFunctionCall* functionCall = mGraph-&gt;createFunctionCall(intermFunctionCall);
+
+    // Run through the function call arguments.
+    int argumentNumber = 0;
+    TIntermSequence&amp; intermArguments = intermFunctionCall-&gt;getSequence();
+    for (TIntermSequence::const_iterator iter = intermArguments.begin();
+         iter != intermArguments.end();
+         ++iter, ++argumentNumber)
+    {
+        TNodeSetMaintainer nodeSetMaintainer(this);
+
+        TIntermNode* intermArgument = *iter;
+        intermArgument-&gt;traverse(this);
+
+        if (TParentNodeSet* argumentNodes = mNodeSets.getTopSet()) {
+            TGraphArgument* argument = mGraph-&gt;createArgument(intermFunctionCall, argumentNumber);
+            connectMultipleNodesToSingleNode(argumentNodes, argument);
+            argument-&gt;addDependentNode(functionCall);
+        }
+    }
+
+    // Push the leftmost symbol of this function call into the current set of dependent symbols to
+    // represent the result of this function call.
+    // Thus, an expression like &quot;y = f(x)&quot; will yield a dependency graph like
+    // &quot;x -&gt; argument 0 -&gt; function call -&gt; y&quot;.
+    // This line essentially passes the function call node back up to an earlier visitAssignment
+    // call, which will create the connection &quot;function call -&gt; y&quot;.
+    mNodeSets.insertIntoTopSet(functionCall);
+}
+
+void TDependencyGraphBuilder::visitAggregateChildren(TIntermAggregate* intermAggregate)
+{
+    TIntermSequence&amp; sequence = intermAggregate-&gt;getSequence();
+    for(TIntermSequence::const_iterator iter = sequence.begin(); iter != sequence.end(); ++iter)
+    {
+        TIntermNode* intermChild = *iter;
+        intermChild-&gt;traverse(this);
+    }
+}
+
+void TDependencyGraphBuilder::visitSymbol(TIntermSymbol* intermSymbol)
+{
+    // Push this symbol into the set of dependent symbols for the current assignment or condition
+    // that we are traversing.
+    TGraphSymbol* symbol = mGraph-&gt;getOrCreateSymbol(intermSymbol);
+    mNodeSets.insertIntoTopSet(symbol);
+
+    // If this symbol is the current leftmost symbol under an assignment, replace the previous
+    // leftmost symbol with this symbol.
+    if (!mLeftmostSymbols.empty() &amp;&amp; mLeftmostSymbols.top() != &amp;mRightSubtree) {
+        mLeftmostSymbols.pop();
+        mLeftmostSymbols.push(symbol);
+    }
+}
+
+bool TDependencyGraphBuilder::visitBinary(Visit visit, TIntermBinary* intermBinary)
+{
+    TOperator op = intermBinary-&gt;getOp();
+    if (op == EOpInitialize || intermBinary-&gt;isAssignment())
+        visitAssignment(intermBinary);
+    else if (op == EOpLogicalAnd || op == EOpLogicalOr)
+        visitLogicalOp(intermBinary);
+    else
+        visitBinaryChildren(intermBinary);
+
+    return false;
+}
+
+void TDependencyGraphBuilder::visitAssignment(TIntermBinary* intermAssignment)
+{
+    TIntermTyped* intermLeft = intermAssignment-&gt;getLeft();
+    if (!intermLeft)
+        return;
+
+    TGraphSymbol* leftmostSymbol = NULL;
+
+    {
+        TNodeSetMaintainer nodeSetMaintainer(this);
+
+        {
+            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mLeftSubtree);
+            intermLeft-&gt;traverse(this);
+            leftmostSymbol = mLeftmostSymbols.top();
+
+            // After traversing the left subtree of this assignment, we should have found a real
+            // leftmost symbol, and the leftmost symbol should not be a placeholder.
+            ASSERT(leftmostSymbol != &amp;mLeftSubtree);
+            ASSERT(leftmostSymbol != &amp;mRightSubtree);
+        }
+
+        if (TIntermTyped* intermRight = intermAssignment-&gt;getRight()) {
+            TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+            intermRight-&gt;traverse(this);
+        }
+
+        if (TParentNodeSet* assignmentNodes = mNodeSets.getTopSet())
+            connectMultipleNodesToSingleNode(assignmentNodes, leftmostSymbol);
+    }
+
+    // Push the leftmost symbol of this assignment into the current set of dependent symbols to
+    // represent the result of this assignment.
+    // An expression like &quot;a = (b = c)&quot; will yield a dependency graph like &quot;c -&gt; b -&gt; a&quot;.
+    // This line essentially passes the leftmost symbol of the nested assignment (&quot;b&quot; in this
+    // example) back up to the earlier visitAssignment call for the outer assignment, which will
+    // create the connection &quot;b -&gt; a&quot;.
+    mNodeSets.insertIntoTopSet(leftmostSymbol);
+}
+
+void TDependencyGraphBuilder::visitLogicalOp(TIntermBinary* intermLogicalOp)
+{
+    if (TIntermTyped* intermLeft = intermLogicalOp-&gt;getLeft()) {
+        TNodeSetPropagatingMaintainer nodeSetMaintainer(this);
+
+        intermLeft-&gt;traverse(this);
+        if (TParentNodeSet* leftNodes = mNodeSets.getTopSet()) {
+            TGraphLogicalOp* logicalOp = mGraph-&gt;createLogicalOp(intermLogicalOp);
+            connectMultipleNodesToSingleNode(leftNodes, logicalOp);
+        }
+    }
+
+    if (TIntermTyped* intermRight = intermLogicalOp-&gt;getRight()) {
+        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+        intermRight-&gt;traverse(this);
+    }
+}
+
+void TDependencyGraphBuilder::visitBinaryChildren(TIntermBinary* intermBinary)
+{
+    if (TIntermTyped* intermLeft = intermBinary-&gt;getLeft())
+        intermLeft-&gt;traverse(this);
+
+    if (TIntermTyped* intermRight = intermBinary-&gt;getRight()) {
+        TLeftmostSymbolMaintainer leftmostSymbolMaintainer(this, mRightSubtree);
+        intermRight-&gt;traverse(this);
+    }
+}
+
+bool TDependencyGraphBuilder::visitSelection(Visit visit, TIntermSelection* intermSelection)
+{
+    if (TIntermNode* intermCondition = intermSelection-&gt;getCondition()) {
+        TNodeSetMaintainer nodeSetMaintainer(this);
+
+        intermCondition-&gt;traverse(this);
+        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
+            TGraphSelection* selection = mGraph-&gt;createSelection(intermSelection);
+            connectMultipleNodesToSingleNode(conditionNodes, selection);
+        }
+    }
+
+    if (TIntermNode* intermTrueBlock = intermSelection-&gt;getTrueBlock())
+        intermTrueBlock-&gt;traverse(this);
+
+    if (TIntermNode* intermFalseBlock = intermSelection-&gt;getFalseBlock())
+        intermFalseBlock-&gt;traverse(this);
+
+    return false;
+}
+
+bool TDependencyGraphBuilder::visitLoop(Visit visit, TIntermLoop* intermLoop)
+{
+    if (TIntermTyped* intermCondition = intermLoop-&gt;getCondition()) {
+        TNodeSetMaintainer nodeSetMaintainer(this);
+
+        intermCondition-&gt;traverse(this);
+        if (TParentNodeSet* conditionNodes = mNodeSets.getTopSet()) {
+            TGraphLoop* loop = mGraph-&gt;createLoop(intermLoop);
+            connectMultipleNodesToSingleNode(conditionNodes, loop);
+        }
+    }
+
+    if (TIntermNode* intermBody = intermLoop-&gt;getBody())
+        intermBody-&gt;traverse(this);
+
+    if (TIntermTyped* intermExpression = intermLoop-&gt;getExpression())
+        intermExpression-&gt;traverse(this);
+
+    return false;
+}
+
+
+void TDependencyGraphBuilder::connectMultipleNodesToSingleNode(TParentNodeSet* nodes,
+                                                               TGraphNode* node) const
+{
+    for (TParentNodeSet::const_iterator iter = nodes-&gt;begin(); iter != nodes-&gt;end(); ++iter)
+    {
+        TGraphParentNode* currentNode = *iter;
+        currentNode-&gt;addDependentNode(node);
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphBuilderh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,181 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
+
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+
+//
+// Creates a dependency graph of symbols, function calls, conditions etc. by traversing a
+// intermediate tree.
+//
+class TDependencyGraphBuilder : public TIntermTraverser {
+public:
+    static void build(TIntermNode* node, TDependencyGraph* graph);
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual bool visitBinary(Visit visit, TIntermBinary*);
+    virtual bool visitSelection(Visit visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit visit, TIntermLoop*);
+
+private:
+    typedef std::stack&lt;TGraphSymbol*&gt; TSymbolStack;
+    typedef std::set&lt;TGraphParentNode*&gt; TParentNodeSet;
+
+    //
+    // For collecting the dependent nodes of assignments, conditions, etc.
+    // while traversing the intermediate tree.
+    //
+    // This data structure is stack of sets. Each set contains dependency graph parent nodes.
+    //
+    class TNodeSetStack {
+    public:
+        TNodeSetStack() {};
+        ~TNodeSetStack() { clear(); }
+
+        // This should only be called after a pushSet.
+        // Returns NULL if the top set is empty.
+        TParentNodeSet* getTopSet() const
+        {
+            ASSERT(!nodeSets.empty());
+            TParentNodeSet* topSet = nodeSets.top();
+            return !topSet-&gt;empty() ? topSet : NULL;
+        }
+
+        void pushSet() { nodeSets.push(new TParentNodeSet()); }
+        void popSet()
+        {
+            ASSERT(!nodeSets.empty());
+            delete nodeSets.top();
+            nodeSets.pop();
+        }
+
+        // Pops the top set and adds its contents to the new top set.
+        // This should only be called after a pushSet.
+        // If there is no set below the top set, the top set is just deleted.
+        void popSetIntoNext()
+        {
+            ASSERT(!nodeSets.empty());
+            TParentNodeSet* oldTopSet = nodeSets.top();
+            nodeSets.pop();
+
+            if (!nodeSets.empty()) {
+                TParentNodeSet* newTopSet = nodeSets.top();
+                newTopSet-&gt;insert(oldTopSet-&gt;begin(), oldTopSet-&gt;end());
+            }
+
+            delete oldTopSet;
+        }
+
+        // Does nothing if there is no top set.
+        // This can be called when there is no top set if we are visiting
+        // symbols that are not under an assignment or condition.
+        // We don't need to track those symbols.
+        void insertIntoTopSet(TGraphParentNode* node)
+        {
+            if (nodeSets.empty())
+                return;
+
+            nodeSets.top()-&gt;insert(node);
+        }
+
+        void clear()
+        {
+            while (!nodeSets.empty())
+                popSet();
+        }
+
+    private:
+        typedef std::stack&lt;TParentNodeSet*&gt; TParentNodeSetStack;
+
+        TParentNodeSetStack nodeSets;
+    };
+
+    //
+    // An instance of this class pushes a new node set when instantiated.
+    // When the instance goes out of scope, it and pops the node set.
+    //
+    class TNodeSetMaintainer {
+    public:
+        TNodeSetMaintainer(TDependencyGraphBuilder* factory)
+            : sets(factory-&gt;mNodeSets) { sets.pushSet(); }
+        ~TNodeSetMaintainer() { sets.popSet(); }
+    protected:
+        TNodeSetStack&amp; sets;
+    };
+
+    //
+    // An instance of this class pushes a new node set when instantiated.
+    // When the instance goes out of scope, it and pops the top node set and adds its contents to
+    // the new top node set.
+    //
+    class TNodeSetPropagatingMaintainer {
+    public:
+        TNodeSetPropagatingMaintainer(TDependencyGraphBuilder* factory)
+            : sets(factory-&gt;mNodeSets) { sets.pushSet(); }
+        ~TNodeSetPropagatingMaintainer() { sets.popSetIntoNext(); }
+    protected:
+        TNodeSetStack&amp; sets;
+    };
+
+    //
+    // An instance of this class keeps track of the leftmost symbol while we're exploring an
+    // assignment.
+    // It will push the placeholder symbol kLeftSubtree when instantiated under a left subtree,
+    // and kRightSubtree under a right subtree.
+    // When it goes out of scope, it will pop the leftmost symbol at the top of the scope.
+    // During traversal, the TDependencyGraphBuilder will replace kLeftSubtree with a real symbol.
+    // kRightSubtree will never be replaced by a real symbol because we are tracking the leftmost
+    // symbol.
+    //
+    class TLeftmostSymbolMaintainer {
+    public:
+        TLeftmostSymbolMaintainer(TDependencyGraphBuilder* factory, TGraphSymbol&amp; subtree)
+            : leftmostSymbols(factory-&gt;mLeftmostSymbols)
+        {
+            needsPlaceholderSymbol = leftmostSymbols.empty() || leftmostSymbols.top() != &amp;subtree;
+            if (needsPlaceholderSymbol)
+                leftmostSymbols.push(&amp;subtree);
+        }
+
+        ~TLeftmostSymbolMaintainer()
+        {
+            if (needsPlaceholderSymbol)
+                leftmostSymbols.pop();
+        }
+
+    protected:
+        TSymbolStack&amp; leftmostSymbols;
+        bool needsPlaceholderSymbol;
+    };
+
+    TDependencyGraphBuilder(TDependencyGraph* graph)
+        : TIntermTraverser(true, false, false)
+        , mLeftSubtree(NULL)
+        , mRightSubtree(NULL)
+        , mGraph(graph) {}
+    void build(TIntermNode* intermNode) { intermNode-&gt;traverse(this); }
+
+    void connectMultipleNodesToSingleNode(TParentNodeSet* nodes, TGraphNode* node) const;
+
+    void visitAssignment(TIntermBinary*);
+    void visitLogicalOp(TIntermBinary*);
+    void visitBinaryChildren(TIntermBinary*);
+    void visitFunctionDefinition(TIntermAggregate*);
+    void visitFunctionCall(TIntermAggregate* intermFunctionCall);
+    void visitAggregateChildren(TIntermAggregate*);
+
+    TGraphSymbol mLeftSubtree;
+    TGraphSymbol mRightSubtree;
+
+    TDependencyGraph* mGraph;
+    TNodeSetStack mNodeSets;
+    TSymbolStack mLeftmostSymbols;
+};
+
+#endif  // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_BUILDER_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphBuilder.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphOutputcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/depgraph/DependencyGraphOutput.h&quot;
+
+void TDependencyGraphOutput::outputIndentation()
+{
+    for (int i = 0; i &lt; getDepth(); ++i)
+        mSink &lt;&lt; &quot;  &quot;;
+}
+
+void TDependencyGraphOutput::visitArgument(TGraphArgument* parameter)
+{
+    outputIndentation();
+    mSink &lt;&lt; &quot;argument &quot; &lt;&lt; parameter-&gt;getArgumentNumber() &lt;&lt; &quot; of call to &quot;
+          &lt;&lt; parameter-&gt;getIntermFunctionCall()-&gt;getName() &lt;&lt; &quot;\n&quot;;
+}
+
+void TDependencyGraphOutput::visitFunctionCall(TGraphFunctionCall* functionCall)
+{
+    outputIndentation();
+    mSink &lt;&lt; &quot;function call &quot; &lt;&lt;  functionCall-&gt;getIntermFunctionCall()-&gt;getName() &lt;&lt; &quot;\n&quot;;
+}
+
+void TDependencyGraphOutput::visitSymbol(TGraphSymbol* symbol)
+{
+    outputIndentation();
+    mSink &lt;&lt; symbol-&gt;getIntermSymbol()-&gt;getSymbol() &lt;&lt; &quot; (symbol id: &quot;
+          &lt;&lt; symbol-&gt;getIntermSymbol()-&gt;getId() &lt;&lt; &quot;)\n&quot;;
+}
+
+void TDependencyGraphOutput::visitSelection(TGraphSelection* selection)
+{
+    outputIndentation();
+    mSink &lt;&lt; &quot;selection\n&quot;;
+}
+
+void TDependencyGraphOutput::visitLoop(TGraphLoop* loop)
+{
+    outputIndentation();
+    mSink &lt;&lt; &quot;loop condition\n&quot;;
+}
+
+void TDependencyGraphOutput::visitLogicalOp(TGraphLogicalOp* logicalOp)
+{
+    outputIndentation();
+    mSink &lt;&lt; &quot;logical &quot; &lt;&lt; logicalOp-&gt;getOpString() &lt;&lt; &quot;\n&quot;;
+}
+
+void TDependencyGraphOutput::outputAllSpanningTrees(TDependencyGraph&amp; graph)
+{
+    mSink &lt;&lt; &quot;\n&quot;;
+
+    for (TGraphNodeVector::const_iterator iter = graph.begin(); iter != graph.end(); ++iter)
+    {
+        TGraphNode* symbol = *iter;
+        mSink &lt;&lt; &quot;--- Dependency graph spanning tree ---\n&quot;;
+        clearVisited();
+        symbol-&gt;traverse(this);
+        mSink &lt;&lt; &quot;\n&quot;;
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphOutputh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
+#define COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
+
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+
+class TDependencyGraphOutput : public TDependencyGraphTraverser {
+public:
+    TDependencyGraphOutput(TInfoSinkBase&amp; sink) : mSink(sink) {}
+    virtual void visitSymbol(TGraphSymbol* symbol);
+    virtual void visitArgument(TGraphArgument* parameter);
+    virtual void visitFunctionCall(TGraphFunctionCall* functionCall);
+    virtual void visitSelection(TGraphSelection* selection);
+    virtual void visitLoop(TGraphLoop* loop);
+    virtual void visitLogicalOp(TGraphLogicalOp* logicalOp);
+
+    void outputAllSpanningTrees(TDependencyGraph&amp; graph);
+private:
+    void outputIndentation();
+
+    TInfoSinkBase&amp; mSink;
+};
+
+#endif  // COMPILER_DEPGRAPH_DEPENDENCY_GRAPH_OUTPUT_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphOutput.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatordepgraphDependencyGraphTraversecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+
+// These methods do a breadth-first traversal through the graph and mark visited nodes.
+
+void TGraphNode::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;markVisited(this);
+}
+
+void TGraphParentNode::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    TGraphNode::traverse(graphTraverser);
+
+    graphTraverser-&gt;incrementDepth();
+
+    // Visit the parent node's children.
+    for (TGraphNodeSet::const_iterator iter = mDependentNodes.begin();
+         iter != mDependentNodes.end();
+         ++iter)
+    {
+        TGraphNode* node = *iter;
+        if (!graphTraverser-&gt;isVisited(node))
+            node-&gt;traverse(graphTraverser);
+    }
+
+    graphTraverser-&gt;decrementDepth();
+}
+
+void TGraphArgument::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitArgument(this);
+    TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphFunctionCall::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitFunctionCall(this);
+    TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphSymbol::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitSymbol(this);
+    TGraphParentNode::traverse(graphTraverser);
+}
+
+void TGraphSelection::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitSelection(this);
+    TGraphNode::traverse(graphTraverser);
+}
+
+void TGraphLoop::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitLoop(this);
+    TGraphNode::traverse(graphTraverser);
+}
+
+void TGraphLogicalOp::traverse(TDependencyGraphTraverser* graphTraverser)
+{
+    graphTraverser-&gt;visitLogicalOp(this);
+    TGraphNode::traverse(graphTraverser);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/depgraph/DependencyGraphTraverse.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorgenerate_parsersh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,27 @@
</span><ins>+#!/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
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/generate_parser.sh
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslangh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+struct TParseContext;
+extern int glslang_initialize(TParseContext* context);
+extern int glslang_finalize(TParseContext* context);
+
+extern int glslang_scan(size_t count,
+                        const char* const string[],
+                        const int length[],
+                        TParseContext* context);
+extern int glslang_parse(TParseContext* context);
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslangl"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.l        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,355 @@
</span><ins>+/*
+//
+// 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 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_parser.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
+*/
+
+%top{
+//
+// 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.
+//
+
+// 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 &quot;-Wunused-function&quot;
+#pragma GCC diagnostic ignored &quot;-Wunused-variable&quot;
+#pragma GCC diagnostic ignored &quot;-Wswitch-enum&quot;
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4065)
+#pragma warning(disable: 4189)
+#pragma warning(disable: 4505)
+#pragma warning(disable: 4701)
+#endif
+}
+
+%{
+#include &quot;compiler/translator/glslang.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;compiler/preprocessor/Token.h&quot;
+#include &quot;compiler/translator/util.h&quot;
+#include &quot;compiler/translator/glslang_tab.h&quot;
+
+/* windows only pragma */
+#ifdef _MSC_VER
+#pragma warning(disable : 4102)
+#endif
+
+#define YY_USER_ACTION                                 \
+    yylloc-&gt;first_file = yylloc-&gt;last_file = yycolumn; \
+    yylloc-&gt;first_line = yylloc-&gt;last_line = yylineno;
+
+#define YY_INPUT(buf, result, max_size) \
+    result = string_input(buf, max_size, yyscanner);
+
+static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+static int int_constant(yyscan_t yyscanner);
+static int float_constant(yyscan_t yyscanner);
+%}
+
+%option noyywrap nounput never-interactive
+%option yylineno reentrant bison-bridge bison-locations
+%option extra-type=&quot;TParseContext*&quot;
+
+D           [0-9]
+L           [a-zA-Z_]
+H           [a-fA-F0-9]
+E           [Ee][+-]?{D}+
+O           [0-7]
+
+%%
+
+&quot;invariant&quot;    { return INVARIANT; }
+&quot;highp&quot;        { return HIGH_PRECISION; }
+&quot;mediump&quot;      { return MEDIUM_PRECISION; }
+&quot;lowp&quot;         { return LOW_PRECISION; }
+&quot;precision&quot;    { return PRECISION; }
+
+&quot;attribute&quot;    { return ATTRIBUTE; }
+&quot;const&quot;        { return CONST_QUAL; }
+&quot;uniform&quot;      { return UNIFORM; }
+&quot;varying&quot;      { return VARYING; }
+
+&quot;break&quot;        { return BREAK; }
+&quot;continue&quot;     { return CONTINUE; }
+&quot;do&quot;           { return DO; }
+&quot;for&quot;          { return FOR; }
+&quot;while&quot;        { return WHILE; }
+
+&quot;if&quot;           { return IF; }
+&quot;else&quot;         { return ELSE; }
+
+&quot;in&quot;           { return IN_QUAL; }
+&quot;out&quot;          { return OUT_QUAL; }
+&quot;inout&quot;        { return INOUT_QUAL; }
+
+&quot;float&quot;        { return FLOAT_TYPE; }
+&quot;int&quot;          { return INT_TYPE; }
+&quot;void&quot;         { return VOID_TYPE; }
+&quot;bool&quot;         { return BOOL_TYPE; }
+&quot;true&quot;         { yylval-&gt;lex.b = true;  return BOOLCONSTANT; }
+&quot;false&quot;        { yylval-&gt;lex.b = false; return BOOLCONSTANT; }
+
+&quot;discard&quot;      { return DISCARD; }
+&quot;return&quot;       { return RETURN; }
+
+&quot;mat2&quot;         { return MATRIX2; }
+&quot;mat3&quot;         { return MATRIX3; }
+&quot;mat4&quot;         { return MATRIX4; }
+
+&quot;vec2&quot;         { return VEC2; }
+&quot;vec3&quot;         { return VEC3; }
+&quot;vec4&quot;         { return VEC4; }
+&quot;ivec2&quot;        { return IVEC2; }
+&quot;ivec3&quot;        { return IVEC3; }
+&quot;ivec4&quot;        { return IVEC4; }
+&quot;bvec2&quot;        { return BVEC2; }
+&quot;bvec3&quot;        { return BVEC3; }
+&quot;bvec4&quot;        { return BVEC4; }
+
+&quot;sampler2D&quot;          { return SAMPLER2D; }
+&quot;samplerCube&quot;        { return SAMPLERCUBE; }
+&quot;samplerExternalOES&quot; { return SAMPLER_EXTERNAL_OES; }
+&quot;sampler2DRect&quot;      { return SAMPLER2DRECT; }
+
+&quot;struct&quot;       { return STRUCT; }
+
+&quot;asm&quot;          { return reserved_word(yyscanner); }
+
+&quot;class&quot;        { return reserved_word(yyscanner); }
+&quot;union&quot;        { return reserved_word(yyscanner); }
+&quot;enum&quot;         { return reserved_word(yyscanner); }
+&quot;typedef&quot;      { return reserved_word(yyscanner); }
+&quot;template&quot;     { return reserved_word(yyscanner); }
+&quot;this&quot;         { return reserved_word(yyscanner); }
+&quot;packed&quot;       { return reserved_word(yyscanner); }
+
+&quot;goto&quot;         { return reserved_word(yyscanner); }
+&quot;switch&quot;       { return reserved_word(yyscanner); }
+&quot;default&quot;      { return reserved_word(yyscanner); }
+
+&quot;inline&quot;       { return reserved_word(yyscanner); }
+&quot;noinline&quot;     { return reserved_word(yyscanner); }
+&quot;volatile&quot;     { return reserved_word(yyscanner); }
+&quot;public&quot;       { return reserved_word(yyscanner); }
+&quot;static&quot;       { return reserved_word(yyscanner); }
+&quot;extern&quot;       { return reserved_word(yyscanner); }
+&quot;external&quot;     { return reserved_word(yyscanner); }
+&quot;interface&quot;    { return reserved_word(yyscanner); }
+&quot;flat&quot;         { return reserved_word(yyscanner); }
+
+&quot;long&quot;         { return reserved_word(yyscanner); }
+&quot;short&quot;        { return reserved_word(yyscanner); }
+&quot;double&quot;       { return reserved_word(yyscanner); }
+&quot;half&quot;         { return reserved_word(yyscanner); }
+&quot;fixed&quot;        { return reserved_word(yyscanner); }
+&quot;unsigned&quot;     { return reserved_word(yyscanner); }
+&quot;superp&quot;       { return reserved_word(yyscanner); }
+
+&quot;input&quot;        { return reserved_word(yyscanner); }
+&quot;output&quot;       { return reserved_word(yyscanner); }
+
+&quot;hvec2&quot;        { return reserved_word(yyscanner); }
+&quot;hvec3&quot;        { return reserved_word(yyscanner); }
+&quot;hvec4&quot;        { return reserved_word(yyscanner); }
+&quot;dvec2&quot;        { return reserved_word(yyscanner); }
+&quot;dvec3&quot;        { return reserved_word(yyscanner); }
+&quot;dvec4&quot;        { return reserved_word(yyscanner); }
+&quot;fvec2&quot;        { return reserved_word(yyscanner); }
+&quot;fvec3&quot;        { return reserved_word(yyscanner); }
+&quot;fvec4&quot;        { return reserved_word(yyscanner); }
+
+&quot;sampler1D&quot;           { return reserved_word(yyscanner); }
+&quot;sampler3D&quot;           { return reserved_word(yyscanner); }
+&quot;sampler1DShadow&quot;     { return reserved_word(yyscanner); }
+&quot;sampler2DShadow&quot;     { return reserved_word(yyscanner); }
+&quot;sampler3DRect&quot;       { return reserved_word(yyscanner); }
+&quot;sampler2DRectShadow&quot; { return reserved_word(yyscanner); }
+
+&quot;sizeof&quot;       { return reserved_word(yyscanner); }
+&quot;cast&quot;         { return reserved_word(yyscanner); }
+
+&quot;namespace&quot;    { return reserved_word(yyscanner); }
+&quot;using&quot;        { return reserved_word(yyscanner); }
+
+{L}({L}|{D})*       {
+   yylval-&gt;lex.string = NewPoolTString(yytext); 
+   return check_type(yyscanner);
+}
+
+0[xX]{H}+         { return int_constant(yyscanner); }
+0{O}+             { return int_constant(yyscanner); }
+{D}+              { return int_constant(yyscanner); }
+
+{D}+{E}           { return float_constant(yyscanner); }
+{D}+&quot;.&quot;{D}*({E})? { return float_constant(yyscanner); }
+&quot;.&quot;{D}+({E})?     { return float_constant(yyscanner); }
+
+&quot;+=&quot;            { return ADD_ASSIGN; }
+&quot;-=&quot;            { return SUB_ASSIGN; }
+&quot;*=&quot;            { return MUL_ASSIGN; }
+&quot;/=&quot;            { return DIV_ASSIGN; }
+&quot;%=&quot;            { return MOD_ASSIGN; }
+&quot;&lt;&lt;=&quot;           { return LEFT_ASSIGN; }
+&quot;&gt;&gt;=&quot;           { return RIGHT_ASSIGN; }
+&quot;&amp;=&quot;            { return AND_ASSIGN; }
+&quot;^=&quot;            { return XOR_ASSIGN; }
+&quot;|=&quot;            { return OR_ASSIGN; }
+
+&quot;++&quot;            { return INC_OP; }
+&quot;--&quot;            { return DEC_OP; }
+&quot;&amp;&amp;&quot;            { return AND_OP; }
+&quot;||&quot;            { return OR_OP; }
+&quot;^^&quot;            { return XOR_OP; }
+&quot;&lt;=&quot;            { return LE_OP; }
+&quot;&gt;=&quot;            { return GE_OP; }
+&quot;==&quot;            { return EQ_OP; }
+&quot;!=&quot;            { return NE_OP; }
+&quot;&lt;&lt;&quot;            { return LEFT_OP; }
+&quot;&gt;&gt;&quot;            { return RIGHT_OP; }
+&quot;;&quot;             { return SEMICOLON; }
+(&quot;{&quot;|&quot;&lt;%&quot;)      { return LEFT_BRACE; }
+(&quot;}&quot;|&quot;%&gt;&quot;)      { return RIGHT_BRACE; }
+&quot;,&quot;         { return COMMA; }
+&quot;:&quot;         { return COLON; }
+&quot;=&quot;         { return EQUAL; }
+&quot;(&quot;         { return LEFT_PAREN; }
+&quot;)&quot;         { return RIGHT_PAREN; }
+(&quot;[&quot;|&quot;&lt;:&quot;)  { return LEFT_BRACKET; }
+(&quot;]&quot;|&quot;:&gt;&quot;)  { return RIGHT_BRACKET; }
+&quot;.&quot;         { return DOT; }
+&quot;!&quot;         { return BANG; }
+&quot;-&quot;         { return DASH; }
+&quot;~&quot;         { return TILDE; }
+&quot;+&quot;         { return PLUS; }
+&quot;*&quot;         { return STAR; }
+&quot;/&quot;         { return SLASH; }
+&quot;%&quot;         { return PERCENT; }
+&quot;&lt;&quot;         { return LEFT_ANGLE; }
+&quot;&gt;&quot;         { return RIGHT_ANGLE; }
+&quot;|&quot;         { return VERTICAL_BAR; }
+&quot;^&quot;         { return CARET; }
+&quot;&amp;&quot;         { return AMPERSAND; }
+&quot;?&quot;         { return QUESTION; }
+
+[ \t\v\n\f\r] { }
+&lt;&lt;EOF&gt;&gt;    { yyterminate(); }
+.          { assert(false); return 0; }
+
+%%
+
+yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
+    pp::Token token;
+    yyget_extra(yyscanner)-&gt;preprocessor.lex(&amp;token);
+    yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
+    if (len &lt; max_size)
+        memcpy(buf, token.text.c_str(), len);
+    yyset_column(token.location.file, yyscanner);
+    yyset_lineno(token.location.line, yyscanner);
+
+    if (len &gt;= max_size)
+        YY_FATAL_ERROR(&quot;Input buffer overflow&quot;);
+    else if (len &gt; 0)
+        buf[len++] = ' ';
+    return len;
+}
+
+int check_type(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+    
+    int token = IDENTIFIER;
+    TSymbol* symbol = yyextra-&gt;symbolTable.find(yytext);
+    if (symbol &amp;&amp; symbol-&gt;isVariable()) {
+        TVariable* variable = static_cast&lt;TVariable*&gt;(symbol);
+        if (variable-&gt;isUserType())
+            token = TYPE_NAME;
+    }
+    yylval-&gt;lex.symbol = symbol;
+    return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    yyextra-&gt;error(*yylloc, &quot;Illegal use of reserved word&quot;, yytext, &quot;&quot;);
+    yyextra-&gt;recover();
+    return 0;
+}
+
+void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) {
+    context-&gt;error(*lloc, reason, yyget_text(context-&gt;scanner));
+    context-&gt;recover();
+}
+
+int int_constant(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    if (!atoi_clamp(yytext, &amp;(yylval-&gt;lex.i)))
+        yyextra-&gt;warning(*yylloc, &quot;Integer overflow&quot;, yytext, &quot;&quot;);
+    return INTCONSTANT;
+}
+
+int float_constant(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    if (!atof_clamp(yytext, &amp;(yylval-&gt;lex.f)))
+        yyextra-&gt;warning(*yylloc, &quot;Float overflow&quot;, yytext, &quot;&quot;);
+    return FLOATCONSTANT;
+}
+
+int glslang_initialize(TParseContext* context) {
+    yyscan_t scanner = NULL;
+    if (yylex_init_extra(context, &amp;scanner))
+        return 1;
+
+    context-&gt;scanner = scanner;
+    return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+    yyscan_t scanner = context-&gt;scanner;
+    if (scanner == NULL) return 0;
+    
+    context-&gt;scanner = NULL;
+    yylex_destroy(scanner);
+
+    return 0;
+}
+
+int glslang_scan(size_t count, const char* const string[], const int length[],
+                 TParseContext* context) {
+    yyrestart(NULL, context-&gt;scanner);
+    yyset_column(0, context-&gt;scanner);
+    yyset_lineno(1, context-&gt;scanner);
+
+    // Initialize preprocessor.
+    if (!context-&gt;preprocessor.init(count, string, length))
+        return 1;
+    context-&gt;preprocessor.setMaxTokenLength(SH_MAX_TOKEN_LENGTH);
+
+    // Define extension macros.
+    const TExtensionBehavior&amp; extBehavior = context-&gt;extensionBehavior();
+    for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+         iter != extBehavior.end(); ++iter) {
+        context-&gt;preprocessor.predefineMacro(iter-&gt;first.c_str(), 1);
+    }
+    if (context-&gt;fragmentPrecisionHigh)
+        context-&gt;preprocessor.predefineMacro(&quot;GL_FRAGMENT_PRECISION_HIGH&quot;, 1);
+
+    return 0;
+}
+
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslangy"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang.y        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,2015 @@
</span><ins>+/*
+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+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_parser.sh,
+WHICH GENERATES THE GLSL ES PARSER (glslang_tab.cpp AND glslang_tab.h).
+*/
+
+%{
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// 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 &quot;-Wunused-function&quot;
+#pragma GCC diagnostic ignored &quot;-Wunused-variable&quot;
+#pragma GCC diagnostic ignored &quot;-Wswitch-enum&quot;
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4065)
+#pragma warning(disable: 4189)
+#pragma warning(disable: 4505)
+#pragma warning(disable: 4701)
+#endif
+
+#include &quot;compiler/translator/SymbolTable.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#define YYENABLE_NLS 0
+
+#define YYLEX_PARAM context-&gt;scanner
+%}
+
+%expect 1 /* One shift reduce conflict because of if | else */
+%pure-parser
+%parse-param {TParseContext* context}
+%locations
+%lex-param {YYLEX_PARAM}
+
+%code requires {
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define SH_MAX_TOKEN_LENGTH 256  // WebGL spec.
+}
+
+%union {
+    struct {
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TPrecision precision;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TField* field;
+            TFieldList* fieldList;
+        };
+    } interm;
+}
+
+%{
+extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
+extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
+
+#define YYLLOC_DEFAULT(Current, Rhs, N)                      \
+  do {                                                       \
+      if (N) {                                               \
+        (Current).first_file = YYRHSLOC(Rhs, 1).first_file;  \
+        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;  \
+        (Current).last_file = YYRHSLOC(Rhs, N).last_file;    \
+        (Current).last_line = YYRHSLOC(Rhs, N).last_line;    \
+      }                                                      \
+      else {                                                 \
+        (Current).first_file = YYRHSLOC(Rhs, 0).last_file;   \
+        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;   \
+        (Current).last_file = YYRHSLOC(Rhs, 0).last_file;    \
+        (Current).last_line = YYRHSLOC(Rhs, 0).last_line;    \
+      }                                                      \
+  } while (0)
+
+#define VERTEX_ONLY(S, L) {  \
+    if (context-&gt;shaderType != SH_VERTEX_SHADER) {  \
+        context-&gt;error(L, &quot; supported in vertex shaders only &quot;, S);  \
+        context-&gt;recover();  \
+    }  \
+}
+
+#define FRAG_ONLY(S, L) {  \
+    if (context-&gt;shaderType != SH_FRAGMENT_SHADER) {  \
+        context-&gt;error(L, &quot; supported in fragment shaders only &quot;, S);  \
+        context-&gt;recover();  \
+    }  \
+}
+%}
+
+%token &lt;lex&gt; INVARIANT HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
+%token &lt;lex&gt; ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
+%token &lt;lex&gt; BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
+%token &lt;lex&gt; BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
+%token &lt;lex&gt; MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
+%token &lt;lex&gt; STRUCT VOID_TYPE WHILE
+%token &lt;lex&gt; SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT
+
+%token &lt;lex&gt; IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT
+%token &lt;lex&gt; LEFT_OP RIGHT_OP
+%token &lt;lex&gt; INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
+%token &lt;lex&gt; AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
+%token &lt;lex&gt; MOD_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN XOR_ASSIGN OR_ASSIGN
+%token &lt;lex&gt; SUB_ASSIGN
+
+%token &lt;lex&gt; LEFT_PAREN RIGHT_PAREN LEFT_BRACKET RIGHT_BRACKET LEFT_BRACE RIGHT_BRACE DOT
+%token &lt;lex&gt; COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
+%token &lt;lex&gt; LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
+
+%type &lt;lex&gt; identifier
+%type &lt;interm&gt; assignment_operator unary_operator
+%type &lt;interm.intermTypedNode&gt; variable_identifier primary_expression postfix_expression
+%type &lt;interm.intermTypedNode&gt; expression integer_expression assignment_expression
+%type &lt;interm.intermTypedNode&gt; unary_expression multiplicative_expression additive_expression
+%type &lt;interm.intermTypedNode&gt; relational_expression equality_expression
+%type &lt;interm.intermTypedNode&gt; conditional_expression constant_expression
+%type &lt;interm.intermTypedNode&gt; logical_or_expression logical_xor_expression logical_and_expression
+%type &lt;interm.intermTypedNode&gt; shift_expression and_expression exclusive_or_expression inclusive_or_expression
+%type &lt;interm.intermTypedNode&gt; function_call initializer condition conditionopt
+
+%type &lt;interm.intermNode&gt; translation_unit function_definition
+%type &lt;interm.intermNode&gt; statement simple_statement
+%type &lt;interm.intermAggregate&gt;  statement_list compound_statement
+%type &lt;interm.intermNode&gt; declaration_statement selection_statement expression_statement
+%type &lt;interm.intermNode&gt; declaration external_declaration
+%type &lt;interm.intermNode&gt; for_init_statement compound_statement_no_new_scope
+%type &lt;interm.nodePair&gt; selection_rest_statement for_rest_statement
+%type &lt;interm.intermNode&gt; iteration_statement jump_statement statement_no_new_scope statement_with_scope
+%type &lt;interm&gt; single_declaration init_declarator_list
+
+%type &lt;interm&gt; parameter_declaration parameter_declarator parameter_type_specifier
+%type &lt;interm.qualifier&gt; parameter_qualifier
+
+%type &lt;interm.precision&gt; precision_qualifier
+%type &lt;interm.type&gt; type_qualifier fully_specified_type type_specifier
+%type &lt;interm.type&gt; type_specifier_no_prec type_specifier_nonarray
+%type &lt;interm.type&gt; struct_specifier
+%type &lt;interm.field&gt; struct_declarator
+%type &lt;interm.fieldList&gt; struct_declarator_list struct_declaration struct_declaration_list
+%type &lt;interm.function&gt; function_header function_declarator function_identifier
+%type &lt;interm.function&gt; function_header_with_parameters function_call_header
+%type &lt;interm&gt; function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
+%type &lt;interm&gt; function_call_or_method
+
+%start translation_unit
+%%
+
+identifier
+    : IDENTIFIER
+    | TYPE_NAME
+
+variable_identifier
+    : IDENTIFIER {
+        // The symbol table search was done in the lexical phase
+        const TSymbol *symbol = $1.symbol;
+        const TVariable *variable = 0;
+
+        if (!symbol)
+        {
+            context-&gt;error(@1, &quot;undeclared identifier&quot;, $1.string-&gt;c_str());
+            context-&gt;recover();
+        }
+        else if (!symbol-&gt;isVariable())
+        {
+            context-&gt;error(@1, &quot;variable expected&quot;, $1.string-&gt;c_str());
+            context-&gt;recover();
+        }
+        else
+        {
+            variable = static_cast&lt;const TVariable*&gt;(symbol);
+
+            if (context-&gt;symbolTable.findBuiltIn(variable-&gt;getName()) &amp;&amp;
+                !variable-&gt;getExtension().empty() &amp;&amp;
+                context-&gt;extensionErrorCheck(@1, variable-&gt;getExtension()))
+            {
+                context-&gt;recover();
+            }
+        }
+
+        if (!variable)
+        {
+            TType type(EbtFloat, EbpUndefined);
+            TVariable *fakeVariable = new TVariable($1.string, type);
+            context-&gt;symbolTable.insert(*fakeVariable);
+            variable = fakeVariable;
+        }
+
+        if (variable-&gt;getType().getQualifier() == EvqConst)
+        {
+            ConstantUnion* constArray = variable-&gt;getConstPointer();
+            TType t(variable-&gt;getType());
+            $$ = context-&gt;intermediate.addConstantUnion(constArray, t, @1);
+        }
+        else
+        {
+            $$ = context-&gt;intermediate.addSymbol(variable-&gt;getUniqueId(),
+                                                 variable-&gt;getName(),
+                                                 variable-&gt;getType(),
+                                                 @1);
+        }
+
+        // don't delete $1.string, it's used by error recovery, and the pool
+        // pop will reclaim the memory
+    }
+    ;
+
+primary_expression
+    : variable_identifier {
+        $$ = $1;
+    }
+    | INTCONSTANT {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setIConst($1.i);
+        $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @1);
+    }
+    | FLOATCONSTANT {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setFConst($1.f);
+        $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
+    }
+    | BOOLCONSTANT {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setBConst($1.b);
+        $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @1);
+    }
+    | LEFT_PAREN expression RIGHT_PAREN {
+        $$ = $2;
+    }
+    ;
+
+postfix_expression
+    : primary_expression {
+        $$ = $1;
+    }
+    | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
+        $$ = context-&gt;addIndexExpression($1, @2, $3);
+    }
+    | function_call {
+        $$ = $1;
+    }
+    | postfix_expression DOT identifier {
+        if ($1-&gt;isArray()) {
+            context-&gt;error(@3, &quot;cannot apply dot operator to an array&quot;, &quot;.&quot;);
+            context-&gt;recover();
+        }
+
+        if ($1-&gt;isVector()) {
+            TVectorFields fields;
+            if (! context-&gt;parseVectorFields(*$3.string, $1-&gt;getNominalSize(), fields, @3)) {
+                fields.num = 1;
+                fields.offsets[0] = 0;
+                context-&gt;recover();
+            }
+
+            if ($1-&gt;getType().getQualifier() == EvqConst) { // constant folding for vector fields
+                $$ = context-&gt;addConstVectorNode(fields, $1, @3);
+                if ($$ == 0) {
+                    context-&gt;recover();
+                    $$ = $1;
+                }
+                else
+                    $$-&gt;setType(TType($1-&gt;getBasicType(), $1-&gt;getPrecision(), EvqConst, (int) (*$3.string).size()));
+            } else {
+                TString vectorString = *$3.string;
+                TIntermTyped* index = context-&gt;intermediate.addSwizzle(fields, @3);
+                $$ = context-&gt;intermediate.addIndex(EOpVectorSwizzle, $1, index, @2);
+                $$-&gt;setType(TType($1-&gt;getBasicType(), $1-&gt;getPrecision(), EvqTemporary, (int) vectorString.size()));
+            }
+        } else if ($1-&gt;isMatrix()) {
+            TMatrixFields fields;
+            if (! context-&gt;parseMatrixFields(*$3.string, $1-&gt;getNominalSize(), fields, @3)) {
+                fields.wholeRow = false;
+                fields.wholeCol = false;
+                fields.row = 0;
+                fields.col = 0;
+                context-&gt;recover();
+            }
+
+            if (fields.wholeRow || fields.wholeCol) {
+                context-&gt;error(@2, &quot; non-scalar fields not implemented yet&quot;, &quot;.&quot;);
+                context-&gt;recover();
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setIConst(0);
+                TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
+                $$ = context-&gt;intermediate.addIndex(EOpIndexDirect, $1, index, @2);
+                $$-&gt;setType(TType($1-&gt;getBasicType(), $1-&gt;getPrecision(),EvqTemporary, $1-&gt;getNominalSize()));
+            } else {
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setIConst(fields.col * $1-&gt;getNominalSize() + fields.row);
+                TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), @3);
+                $$ = context-&gt;intermediate.addIndex(EOpIndexDirect, $1, index, @2);
+                $$-&gt;setType(TType($1-&gt;getBasicType(), $1-&gt;getPrecision()));
+            }
+        } else if ($1-&gt;getBasicType() == EbtStruct) {
+            bool fieldFound = false;
+            const TFieldList&amp; fields = $1-&gt;getType().getStruct()-&gt;fields();
+            unsigned int i;
+            for (i = 0; i &lt; fields.size(); ++i) {
+                if (fields[i]-&gt;name() == *$3.string) {
+                    fieldFound = true;
+                    break;
+                }
+            }
+            if (fieldFound) {
+                if ($1-&gt;getType().getQualifier() == EvqConst) {
+                    $$ = context-&gt;addConstStruct(*$3.string, $1, @2);
+                    if ($$ == 0) {
+                        context-&gt;recover();
+                        $$ = $1;
+                    }
+                    else {
+                        $$-&gt;setType(*fields[i]-&gt;type());
+                        // change the qualifier of the return type, not of the structure field
+                        // as the structure definition is shared between various structures.
+                        $$-&gt;getTypePointer()-&gt;setQualifier(EvqConst);
+                    }
+                } else {
+                    ConstantUnion *unionArray = new ConstantUnion[1];
+                    unionArray-&gt;setIConst(i);
+                    TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, *fields[i]-&gt;type(), @3);
+                    $$ = context-&gt;intermediate.addIndex(EOpIndexDirectStruct, $1, index, @2);
+                    $$-&gt;setType(*fields[i]-&gt;type());
+                }
+            } else {
+                context-&gt;error(@2, &quot; no such field in structure&quot;, $3.string-&gt;c_str());
+                context-&gt;recover();
+                $$ = $1;
+            }
+        } else {
+            context-&gt;error(@2, &quot; field selection requires structure, vector, or matrix on left hand side&quot;, $3.string-&gt;c_str());
+            context-&gt;recover();
+            $$ = $1;
+        }
+        // don't delete $3.string, it's from the pool
+    }
+    | postfix_expression INC_OP {
+        if (context-&gt;lValueErrorCheck(@2, &quot;++&quot;, $1))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addUnaryMath(EOpPostIncrement, $1, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;unaryOpError(@2, &quot;++&quot;, $1-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    | postfix_expression DEC_OP {
+        if (context-&gt;lValueErrorCheck(@2, &quot;--&quot;, $1))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addUnaryMath(EOpPostDecrement, $1, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;unaryOpError(@2, &quot;--&quot;, $1-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+integer_expression
+    : expression {
+        if (context-&gt;integerErrorCheck($1, &quot;[]&quot;))
+            context-&gt;recover();
+        $$ = $1;
+    }
+    ;
+
+function_call
+    : function_call_or_method {
+        TFunction* fnCall = $1.function;
+        TOperator op = fnCall-&gt;getBuiltInOp();
+
+        if (op != EOpNull)
+        {
+            //
+            // Then this should be a constructor.
+            // Don't go through the symbol table for constructors.
+            // Their parameters will be verified algorithmically.
+            //
+            TType type(EbtVoid, EbpUndefined);  // use this to get the type back
+            if (context-&gt;constructorErrorCheck(@1, $1.intermNode, *fnCall, op, &amp;type)) {
+                $$ = 0;
+            } else {
+                //
+                // It's a constructor, of type 'type'.
+                //
+                $$ = context-&gt;addConstructor($1.intermNode, &amp;type, op, fnCall, @1);
+            }
+
+            if ($$ == 0) {
+                context-&gt;recover();
+                $$ = context-&gt;intermediate.setAggregateOperator(0, op, @1);
+            }
+            $$-&gt;setType(type);
+        } else {
+            //
+            // Not a constructor.  Find it in the symbol table.
+            //
+            const TFunction* fnCandidate;
+            bool builtIn;
+            fnCandidate = context-&gt;findFunction(@1, fnCall, &amp;builtIn);
+            if (fnCandidate) {
+                //
+                // A declared function.
+                //
+                if (builtIn &amp;&amp; !fnCandidate-&gt;getExtension().empty() &amp;&amp;
+                    context-&gt;extensionErrorCheck(@1, fnCandidate-&gt;getExtension())) {
+                    context-&gt;recover();
+                }
+                op = fnCandidate-&gt;getBuiltInOp();
+                if (builtIn &amp;&amp; op != EOpNull) {
+                    //
+                    // A function call mapped to a built-in operation.
+                    //
+                    if (fnCandidate-&gt;getParamCount() == 1) {
+                        //
+                        // Treat it like a built-in unary operator.
+                        //
+                        $$ = context-&gt;intermediate.addUnaryMath(op, $1.intermNode, @1, context-&gt;symbolTable);
+                        if ($$ == 0)  {
+                            std::stringstream extraInfoStream;
+                            extraInfoStream &lt;&lt; &quot;built in unary operator function.  Type: &quot; &lt;&lt; static_cast&lt;TIntermTyped*&gt;($1.intermNode)-&gt;getCompleteString();
+                            std::string extraInfo = extraInfoStream.str();
+                            context-&gt;error($1.intermNode-&gt;getLine(), &quot; wrong operand type&quot;, &quot;Internal Error&quot;, extraInfo.c_str());
+                            YYERROR;
+                        }
+                    } else {
+                        $$ = context-&gt;intermediate.setAggregateOperator($1.intermAggregate, op, @1);
+                    }
+                } else {
+                    // This is a real function call
+
+                    $$ = context-&gt;intermediate.setAggregateOperator($1.intermAggregate, EOpFunctionCall, @1);
+                    $$-&gt;setType(fnCandidate-&gt;getReturnType());
+
+                    // this is how we know whether the given function is a builtIn function or a user defined function
+                    // if builtIn == false, it's a userDefined -&gt; could be an overloaded builtIn function also
+                    // if builtIn == true, it's definitely a builtIn function with EOpNull
+                    if (!builtIn)
+                        $$-&gt;getAsAggregate()-&gt;setUserDefined();
+                    $$-&gt;getAsAggregate()-&gt;setName(fnCandidate-&gt;getMangledName());
+
+                    TQualifier qual;
+                    for (size_t i = 0; i &lt; fnCandidate-&gt;getParamCount(); ++i) {
+                        qual = fnCandidate-&gt;getParam(i).type-&gt;getQualifier();
+                        if (qual == EvqOut || qual == EvqInOut) {
+                            if (context-&gt;lValueErrorCheck($$-&gt;getLine(), &quot;assign&quot;, $$-&gt;getAsAggregate()-&gt;getSequence()[i]-&gt;getAsTyped())) {
+                                context-&gt;error($1.intermNode-&gt;getLine(), &quot;Constant value cannot be passed for 'out' or 'inout' parameters.&quot;, &quot;Error&quot;);
+                                context-&gt;recover();
+                            }
+                        }
+                    }
+                }
+                $$-&gt;setType(fnCandidate-&gt;getReturnType());
+            } else {
+                // error message was put out by PaFindFunction()
+                // Put on a dummy node for error recovery
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setFConst(0.0f);
+                $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), @1);
+                context-&gt;recover();
+            }
+        }
+        delete fnCall;
+    }
+    ;
+
+function_call_or_method
+    : function_call_generic {
+        $$ = $1;
+    }
+    | postfix_expression DOT function_call_generic {
+        context-&gt;error(@3, &quot;methods are not supported&quot;, &quot;&quot;);
+        context-&gt;recover();
+        $$ = $3;
+    }
+    ;
+
+function_call_generic
+    : function_call_header_with_parameters RIGHT_PAREN {
+        $$ = $1;
+    }
+    | function_call_header_no_parameters RIGHT_PAREN {
+        $$ = $1;
+    }
+    ;
+
+function_call_header_no_parameters
+    : function_call_header VOID_TYPE {
+        $$.function = $1;
+        $$.intermNode = 0;
+    }
+    | function_call_header {
+        $$.function = $1;
+        $$.intermNode = 0;
+    }
+    ;
+
+function_call_header_with_parameters
+    : function_call_header assignment_expression {
+        TParameter param = { 0, new TType($2-&gt;getType()) };
+        $1-&gt;addParameter(param);
+        $$.function = $1;
+        $$.intermNode = $2;
+    }
+    | function_call_header_with_parameters COMMA assignment_expression {
+        TParameter param = { 0, new TType($3-&gt;getType()) };
+        $1.function-&gt;addParameter(param);
+        $$.function = $1.function;
+        $$.intermNode = context-&gt;intermediate.growAggregate($1.intermNode, $3, @2);
+    }
+    ;
+
+function_call_header
+    : function_identifier LEFT_PAREN {
+        $$ = $1;
+    }
+    ;
+
+// Grammar Note:  Constructors look like functions, but are recognized as types.
+
+function_identifier
+    : type_specifier_nonarray {
+        //
+        // Constructor
+        //
+        TOperator op = EOpNull;
+        if ($1.userDef) {
+            op = EOpConstructStruct;
+        } else {
+            switch ($1.type) {
+            case EbtFloat:
+                if ($1.matrix) {
+                    switch($1.size) {
+                    case 2: op = EOpConstructMat2;  break;
+                    case 3: op = EOpConstructMat3;  break;
+                    case 4: op = EOpConstructMat4;  break;
+                    }
+                } else {
+                    switch($1.size) {
+                    case 1: op = EOpConstructFloat; break;
+                    case 2: op = EOpConstructVec2;  break;
+                    case 3: op = EOpConstructVec3;  break;
+                    case 4: op = EOpConstructVec4;  break;
+                    }
+                }
+                break;
+            case EbtInt:
+                switch($1.size) {
+                case 1: op = EOpConstructInt;   break;
+                case 2: op = EOpConstructIVec2; break;
+                case 3: op = EOpConstructIVec3; break;
+                case 4: op = EOpConstructIVec4; break;
+                }
+                break;
+            case EbtBool:
+                switch($1.size) {
+                case 1: op = EOpConstructBool;  break;
+                case 2: op = EOpConstructBVec2; break;
+                case 3: op = EOpConstructBVec3; break;
+                case 4: op = EOpConstructBVec4; break;
+                }
+                break;
+            default: break;
+            }
+            if (op == EOpNull) {
+                context-&gt;error(@1, &quot;cannot construct this type&quot;, getBasicString($1.type));
+                context-&gt;recover();
+                $1.type = EbtFloat;
+                op = EOpConstructFloat;
+            }
+        }
+        TString tempString;
+        TType type($1);
+        TFunction *function = new TFunction(&amp;tempString, type, op);
+        $$ = function;
+    }
+    | IDENTIFIER {
+        if (context-&gt;reservedErrorCheck(@1, *$1.string))
+            context-&gt;recover();
+        TType type(EbtVoid, EbpUndefined);
+        TFunction *function = new TFunction($1.string, type);
+        $$ = function;
+    }
+    ;
+
+unary_expression
+    : postfix_expression {
+        $$ = $1;
+    }
+    | INC_OP unary_expression {
+        if (context-&gt;lValueErrorCheck(@1, &quot;++&quot;, $2))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addUnaryMath(EOpPreIncrement, $2, @1, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;unaryOpError(@1, &quot;++&quot;, $2-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $2;
+        }
+    }
+    | DEC_OP unary_expression {
+        if (context-&gt;lValueErrorCheck(@1, &quot;--&quot;, $2))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addUnaryMath(EOpPreDecrement, $2, @1, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;unaryOpError(@1, &quot;--&quot;, $2-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $2;
+        }
+    }
+    | unary_operator unary_expression {
+        if ($1.op != EOpNull) {
+            $$ = context-&gt;intermediate.addUnaryMath($1.op, $2, @1, context-&gt;symbolTable);
+            if ($$ == 0) {
+                const char* errorOp = &quot;&quot;;
+                switch($1.op) {
+                case EOpNegative:   errorOp = &quot;-&quot;; break;
+                case EOpLogicalNot: errorOp = &quot;!&quot;; break;
+                default: break;
+                }
+                context-&gt;unaryOpError(@1, errorOp, $2-&gt;getCompleteString());
+                context-&gt;recover();
+                $$ = $2;
+            }
+        } else
+            $$ = $2;
+    }
+    ;
+// Grammar Note:  No traditional style type casts.
+
+unary_operator
+    : PLUS  { $$.op = EOpNull; }
+    | DASH  { $$.op = EOpNegative; }
+    | BANG  { $$.op = EOpLogicalNot; }
+    ;
+// Grammar Note:  No '*' or '&amp;' unary ops.  Pointers are not supported.
+
+multiplicative_expression
+    : unary_expression { $$ = $1; }
+    | multiplicative_expression STAR unary_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpMul, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;*&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    | multiplicative_expression SLASH unary_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpDiv, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;/&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+additive_expression
+    : multiplicative_expression { $$ = $1; }
+    | additive_expression PLUS multiplicative_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpAdd, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;+&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    | additive_expression DASH multiplicative_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpSub, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;-&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+shift_expression
+    : additive_expression { $$ = $1; }
+    ;
+
+relational_expression
+    : shift_expression { $$ = $1; }
+    | relational_expression LEFT_ANGLE shift_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpLessThan, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;&lt;&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    | relational_expression RIGHT_ANGLE shift_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpGreaterThan, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;&gt;&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    | relational_expression LE_OP shift_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;&lt;=&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    | relational_expression GE_OP shift_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;&gt;=&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    ;
+
+equality_expression
+    : relational_expression { $$ = $1; }
+    | equality_expression EQ_OP relational_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpEqual, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;==&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    | equality_expression NE_OP relational_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpNotEqual, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;!=&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    ;
+
+and_expression
+    : equality_expression { $$ = $1; }
+    ;
+
+exclusive_or_expression
+    : and_expression { $$ = $1; }
+    ;
+
+inclusive_or_expression
+    : exclusive_or_expression { $$ = $1; }
+    ;
+
+logical_and_expression
+    : inclusive_or_expression { $$ = $1; }
+    | logical_and_expression AND_OP inclusive_or_expression {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;&amp;&amp;&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    ;
+
+logical_xor_expression
+    : logical_and_expression { $$ = $1; }
+    | logical_xor_expression XOR_OP logical_and_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpLogicalXor, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;^^&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    ;
+
+logical_or_expression
+    : logical_xor_expression { $$ = $1; }
+    | logical_or_expression OR_OP logical_xor_expression  {
+        $$ = context-&gt;intermediate.addBinaryMath(EOpLogicalOr, $1, $3, @2, context-&gt;symbolTable);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;||&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            $$ = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), @2);
+        }
+    }
+    ;
+
+conditional_expression
+    : logical_or_expression { $$ = $1; }
+    | logical_or_expression QUESTION expression COLON assignment_expression {
+       if (context-&gt;boolErrorCheck(@2, $1))
+            context-&gt;recover();
+
+        $$ = context-&gt;intermediate.addSelection($1, $3, $5, @2);
+        if ($3-&gt;getType() != $5-&gt;getType())
+            $$ = 0;
+
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;:&quot;, $3-&gt;getCompleteString(), $5-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $5;
+        }
+    }
+    ;
+
+assignment_expression
+    : conditional_expression { $$ = $1; }
+    | unary_expression assignment_operator assignment_expression {
+        if (context-&gt;lValueErrorCheck(@2, &quot;assign&quot;, $1))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addAssign($2.op, $1, $3, @2);
+        if ($$ == 0) {
+            context-&gt;assignError(@2, &quot;assign&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $1;
+        }
+    }
+    ;
+
+assignment_operator
+    : EQUAL        { $$.op = EOpAssign; }
+    | MUL_ASSIGN   { $$.op = EOpMulAssign; }
+    | DIV_ASSIGN   { $$.op = EOpDivAssign; }
+    | ADD_ASSIGN   { $$.op = EOpAddAssign; }
+    | SUB_ASSIGN   { $$.op = EOpSubAssign; }
+    ;
+
+expression
+    : assignment_expression {
+        $$ = $1;
+    }
+    | expression COMMA assignment_expression {
+        $$ = context-&gt;intermediate.addComma($1, $3, @2);
+        if ($$ == 0) {
+            context-&gt;binaryOpError(@2, &quot;,&quot;, $1-&gt;getCompleteString(), $3-&gt;getCompleteString());
+            context-&gt;recover();
+            $$ = $3;
+        }
+    }
+    ;
+
+constant_expression
+    : conditional_expression {
+        if (context-&gt;constErrorCheck($1))
+            context-&gt;recover();
+        $$ = $1;
+    }
+    ;
+
+declaration
+    : function_prototype SEMICOLON   {
+        TFunction &amp;function = *($1.function);
+        
+        TIntermAggregate *prototype = new TIntermAggregate;
+        prototype-&gt;setType(function.getReturnType());
+        prototype-&gt;setName(function.getName());
+        
+        for (size_t i = 0; i &lt; function.getParamCount(); i++)
+        {
+            const TParameter &amp;param = function.getParam(i);
+            if (param.name != 0)
+            {
+                TVariable variable(param.name, *param.type);
+                
+                prototype = context-&gt;intermediate.growAggregate(prototype, context-&gt;intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
+            }
+            else
+            {
+                prototype = context-&gt;intermediate.growAggregate(prototype, context-&gt;intermediate.addSymbol(0, &quot;&quot;, *param.type, @1), @1);
+            }
+        }
+        
+        prototype-&gt;setOp(EOpPrototype);
+        $$ = prototype;
+
+        context-&gt;symbolTable.pop();
+    }
+    | init_declarator_list SEMICOLON {
+        if ($1.intermAggregate)
+            $1.intermAggregate-&gt;setOp(EOpDeclaration);
+        $$ = $1.intermAggregate;
+    }
+    | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
+        if (($2 == EbpHigh) &amp;&amp; (context-&gt;shaderType == SH_FRAGMENT_SHADER) &amp;&amp; !context-&gt;fragmentPrecisionHigh) {
+            context-&gt;error(@1, &quot;precision is not supported in fragment shader&quot;, &quot;highp&quot;);
+            context-&gt;recover();
+        }
+        if (!context-&gt;symbolTable.setDefaultPrecision( $3, $2 )) {
+            context-&gt;error(@1, &quot;illegal type argument for default precision qualifier&quot;, getBasicString($3.type));
+            context-&gt;recover();
+        }
+        $$ = 0;
+    }
+    ;
+
+function_prototype
+    : function_declarator RIGHT_PAREN  {
+        //
+        // Multiple declarations of the same function are allowed.
+        //
+        // If this is a definition, the definition production code will check for redefinitions
+        // (we don't know at this point if it's a definition or not).
+        //
+        // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
+        //
+        TFunction* prevDec = static_cast&lt;TFunction*&gt;(context-&gt;symbolTable.find($1-&gt;getMangledName()));
+        if (prevDec) {
+            if (prevDec-&gt;getReturnType() != $1-&gt;getReturnType()) {
+                context-&gt;error(@2, &quot;overloaded functions must have the same return type&quot;, $1-&gt;getReturnType().getBasicString());
+                context-&gt;recover();
+            }
+            for (size_t i = 0; i &lt; prevDec-&gt;getParamCount(); ++i) {
+                if (prevDec-&gt;getParam(i).type-&gt;getQualifier() != $1-&gt;getParam(i).type-&gt;getQualifier()) {
+                    context-&gt;error(@2, &quot;overloaded functions must have the same parameter qualifiers&quot;, $1-&gt;getParam(i).type-&gt;getQualifierString());
+                    context-&gt;recover();
+                }
+            }
+        }
+
+        //
+        // Check for previously declared variables using the same name.
+        //
+        TSymbol *prevSym = context-&gt;symbolTable.find($1-&gt;getName());
+        if (prevSym)
+        {
+            if (!prevSym-&gt;isFunction())
+            {
+                context-&gt;error(@2, &quot;redefinition&quot;, $1-&gt;getName().c_str(), &quot;function&quot;);
+                context-&gt;recover();
+            }
+        }
+        else
+        {
+            // Insert the unmangled name to detect potential future redefinition as a variable.
+            context-&gt;symbolTable.getOuterLevel()-&gt;insert($1-&gt;getName(), *$1);
+        }
+
+        //
+        // If this is a redeclaration, it could also be a definition,
+        // in which case, we want to use the variable names from this one, and not the one that's
+        // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
+        //
+        $$.function = $1;
+
+        // 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-&gt;symbolTable.getOuterLevel()-&gt;insert(*$$.function);
+    }
+    ;
+
+function_declarator
+    : function_header {
+        $$ = $1;
+    }
+    | function_header_with_parameters {
+        $$ = $1;
+    }
+    ;
+
+
+function_header_with_parameters
+    : function_header parameter_declaration {
+        // Add the parameter
+        $$ = $1;
+        if ($2.param.type-&gt;getBasicType() != EbtVoid)
+            $1-&gt;addParameter($2.param);
+        else
+            delete $2.param.type;
+    }
+    | function_header_with_parameters COMMA parameter_declaration {
+        //
+        // Only first parameter of one-parameter functions can be void
+        // The check for named parameters not being void is done in parameter_declarator
+        //
+        if ($3.param.type-&gt;getBasicType() == EbtVoid) {
+            //
+            // This parameter &gt; first is void
+            //
+            context-&gt;error(@2, &quot;cannot be an argument type except for '(void)'&quot;, &quot;void&quot;);
+            context-&gt;recover();
+            delete $3.param.type;
+        } else {
+            // Add the parameter
+            $$ = $1;
+            $1-&gt;addParameter($3.param);
+        }
+    }
+    ;
+
+function_header
+    : fully_specified_type IDENTIFIER LEFT_PAREN {
+        if ($1.qualifier != EvqGlobal &amp;&amp; $1.qualifier != EvqTemporary) {
+            context-&gt;error(@2, &quot;no qualifiers allowed for function return&quot;, getQualifierString($1.qualifier));
+            context-&gt;recover();
+        }
+        // make sure a sampler is not involved as well...
+        if (context-&gt;structQualifierErrorCheck(@2, $1))
+            context-&gt;recover();
+
+        // Add the function as a prototype after parsing it (we do not support recursion)
+        TFunction *function;
+        TType type($1);
+        function = new TFunction($2.string, type);
+        $$ = function;
+        
+        context-&gt;symbolTable.push();
+    }
+    ;
+
+parameter_declarator
+    // Type + name
+    : type_specifier identifier {
+        if ($1.type == EbtVoid) {
+            context-&gt;error(@2, &quot;illegal use of type 'void'&quot;, $2.string-&gt;c_str());
+            context-&gt;recover();
+        }
+        if (context-&gt;reservedErrorCheck(@2, *$2.string))
+            context-&gt;recover();
+        TParameter param = {$2.string, new TType($1)};
+        $$.param = param;
+    }
+    | type_specifier identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        // Check that we can make an array out of this type
+        if (context-&gt;arrayTypeErrorCheck(@3, $1))
+            context-&gt;recover();
+
+        if (context-&gt;reservedErrorCheck(@2, *$2.string))
+            context-&gt;recover();
+
+        int size;
+        if (context-&gt;arraySizeErrorCheck(@3, $4, size))
+            context-&gt;recover();
+        $1.setArray(true, size);
+
+        TType* type = new TType($1);
+        TParameter param = { $2.string, type };
+        $$.param = param;
+    }
+    ;
+
+parameter_declaration
+    //
+    // The only parameter qualifier a parameter can have are
+    // IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
+    //
+
+    //
+    // Type + name
+    //
+    : type_qualifier parameter_qualifier parameter_declarator {
+        $$ = $3;
+        if (context-&gt;paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
+            context-&gt;recover();
+    }
+    | parameter_qualifier parameter_declarator {
+        $$ = $2;
+        if (context-&gt;parameterSamplerErrorCheck(@2, $1, *$2.param.type))
+            context-&gt;recover();
+        if (context-&gt;paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
+            context-&gt;recover();
+    }
+    //
+    // Only type
+    //
+    | type_qualifier parameter_qualifier parameter_type_specifier {
+        $$ = $3;
+        if (context-&gt;paramErrorCheck(@3, $1.qualifier, $2, $$.param.type))
+            context-&gt;recover();
+    }
+    | parameter_qualifier parameter_type_specifier {
+        $$ = $2;
+        if (context-&gt;parameterSamplerErrorCheck(@2, $1, *$2.param.type))
+            context-&gt;recover();
+        if (context-&gt;paramErrorCheck(@2, EvqTemporary, $1, $$.param.type))
+            context-&gt;recover();
+    }
+    ;
+
+parameter_qualifier
+    : /* empty */ {
+        $$ = EvqIn;
+    }
+    | IN_QUAL {
+        $$ = EvqIn;
+    }
+    | OUT_QUAL {
+        $$ = EvqOut;
+    }
+    | INOUT_QUAL {
+        $$ = EvqInOut;
+    }
+    ;
+
+parameter_type_specifier
+    : type_specifier {
+        TParameter param = { 0, new TType($1) };
+        $$.param = param;
+    }
+    ;
+
+init_declarator_list
+    : single_declaration {
+        $$ = $1;
+    }
+    | init_declarator_list COMMA identifier {
+        if ($1.type.type == EbtInvariant &amp;&amp; !$3.symbol)
+        {
+            context-&gt;error(@3, &quot;undeclared identifier declared as invariant&quot;, $3.string-&gt;c_str());
+            context-&gt;recover();
+        }
+
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *$3.string, TType($1.type), @3);
+        $$.intermAggregate = context-&gt;intermediate.growAggregate($1.intermNode, symbol, @3);
+        
+        if (context-&gt;structQualifierErrorCheck(@3, $$.type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck(@3, *$3.string, $$.type, false))
+            context-&gt;recover();
+
+        TVariable* variable = 0;
+        if (context-&gt;nonInitErrorCheck(@3, *$3.string, $$.type, variable))
+            context-&gt;recover();
+        if (symbol &amp;&amp; variable)
+            symbol-&gt;setId(variable-&gt;getUniqueId());
+    }
+    | init_declarator_list COMMA identifier LEFT_BRACKET RIGHT_BRACKET {
+        if (context-&gt;structQualifierErrorCheck(@3, $1.type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
+            context-&gt;recover();
+
+        $$ = $1;
+
+        if (context-&gt;arrayTypeErrorCheck(@4, $1.type) || context-&gt;arrayQualifierErrorCheck(@4, $1.type))
+            context-&gt;recover();
+        else {
+            $1.type.setArray(true);
+            TVariable* variable;
+            if (context-&gt;arrayErrorCheck(@4, *$3.string, $1.type, variable))
+                context-&gt;recover();
+        }
+    }
+    | init_declarator_list COMMA identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        if (context-&gt;structQualifierErrorCheck(@3, $1.type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck(@3, *$3.string, $1.type, true))
+            context-&gt;recover();
+
+        $$ = $1;
+
+        if (context-&gt;arrayTypeErrorCheck(@4, $1.type) || context-&gt;arrayQualifierErrorCheck(@4, $1.type))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck(@4, $5, size))
+                context-&gt;recover();
+            $1.type.setArray(true, size);
+            TVariable* variable = 0;
+            if (context-&gt;arrayErrorCheck(@4, *$3.string, $1.type, variable))
+                context-&gt;recover();
+            TType type = TType($1.type);
+            type.setArraySize(size);
+            $$.intermAggregate = context-&gt;intermediate.growAggregate($1.intermNode, context-&gt;intermediate.addSymbol(variable ? variable-&gt;getUniqueId() : 0, *$3.string, type, @3), @3);
+        }
+    }
+    | init_declarator_list COMMA identifier EQUAL initializer {
+        if (context-&gt;structQualifierErrorCheck(@3, $1.type))
+            context-&gt;recover();
+
+        $$ = $1;
+
+        TIntermNode* intermNode;
+        if (!context-&gt;executeInitializer(@3, *$3.string, $1.type, $5, intermNode)) {
+            //
+            // build the intermediate representation
+            //
+            if (intermNode)
+        $$.intermAggregate = context-&gt;intermediate.growAggregate($1.intermNode, intermNode, @4);
+            else
+                $$.intermAggregate = $1.intermAggregate;
+        } else {
+            context-&gt;recover();
+            $$.intermAggregate = 0;
+        }
+    }
+    ;
+
+single_declaration
+    : fully_specified_type {
+        $$.type = $1;
+        $$.intermAggregate = context-&gt;intermediate.makeAggregate(context-&gt;intermediate.addSymbol(0, &quot;&quot;, TType($1), @1), @1);
+    }
+    | fully_specified_type identifier {
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *$2.string, TType($1), @2);
+        $$.intermAggregate = context-&gt;intermediate.makeAggregate(symbol, @2);
+        
+        if (context-&gt;structQualifierErrorCheck(@2, $$.type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck(@2, *$2.string, $$.type, false))
+            context-&gt;recover();
+            
+            $$.type = $1;
+
+        TVariable* variable = 0;
+        if (context-&gt;nonInitErrorCheck(@2, *$2.string, $$.type, variable))
+            context-&gt;recover();
+        if (variable &amp;&amp; symbol)
+            symbol-&gt;setId(variable-&gt;getUniqueId());
+    }
+    | fully_specified_type identifier LEFT_BRACKET RIGHT_BRACKET {
+        context-&gt;error(@2, &quot;unsized array declarations not supported&quot;, $2.string-&gt;c_str());
+        context-&gt;recover();
+
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *$2.string, TType($1), @2);
+        $$.intermAggregate = context-&gt;intermediate.makeAggregate(symbol, @2);
+        $$.type = $1;
+    }
+    | fully_specified_type identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        TType type = TType($1);
+        int size;
+        if (context-&gt;arraySizeErrorCheck(@2, $4, size))
+            context-&gt;recover();
+        type.setArraySize(size);
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *$2.string, type, @2);
+        $$.intermAggregate = context-&gt;intermediate.makeAggregate(symbol, @2);
+        
+        if (context-&gt;structQualifierErrorCheck(@2, $1))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck(@2, *$2.string, $1, true))
+            context-&gt;recover();
+
+        $$.type = $1;
+
+        if (context-&gt;arrayTypeErrorCheck(@3, $1) || context-&gt;arrayQualifierErrorCheck(@3, $1))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck(@3, $4, size))
+                context-&gt;recover();
+
+            $1.setArray(true, size);
+            TVariable* variable = 0;
+            if (context-&gt;arrayErrorCheck(@3, *$2.string, $1, variable))
+                context-&gt;recover();
+            if (variable &amp;&amp; symbol)
+                symbol-&gt;setId(variable-&gt;getUniqueId());
+        }
+    }
+    | fully_specified_type identifier EQUAL initializer {
+        if (context-&gt;structQualifierErrorCheck(@2, $1))
+            context-&gt;recover();
+
+        $$.type = $1;
+
+        TIntermNode* intermNode;
+        if (!context-&gt;executeInitializer(@2, *$2.string, $1, $4, intermNode)) {
+        //
+        // Build intermediate representation
+        //
+            if(intermNode)
+                $$.intermAggregate = context-&gt;intermediate.makeAggregate(intermNode, @3);
+            else
+                $$.intermAggregate = 0;
+        } else {
+            context-&gt;recover();
+            $$.intermAggregate = 0;
+        }
+    }
+    | INVARIANT IDENTIFIER {
+        VERTEX_ONLY(&quot;invariant declaration&quot;, @1);
+        if (context-&gt;globalErrorCheck(@1, context-&gt;symbolTable.atGlobalLevel(), &quot;invariant varying&quot;))
+            context-&gt;recover();
+        $$.type.setBasic(EbtInvariant, EvqInvariantVaryingOut, @2);
+        if (!$2.symbol)
+        {
+            context-&gt;error(@2, &quot;undeclared identifier declared as invariant&quot;, $2.string-&gt;c_str());
+            context-&gt;recover();
+            
+            $$.intermAggregate = 0;
+        }
+        else
+        {
+            TIntermSymbol *symbol = context-&gt;intermediate.addSymbol(0, *$2.string, TType($$.type), @2);
+            $$.intermAggregate = context-&gt;intermediate.makeAggregate(symbol, @2);
+        }
+    }
+    ;
+
+fully_specified_type
+    : type_specifier {
+        $$ = $1;
+
+        if ($1.array) {
+            context-&gt;error(@1, &quot;not supported&quot;, &quot;first-class array&quot;);
+            context-&gt;recover();
+            $1.setArray(false);
+        }
+    }
+    | type_qualifier type_specifier  {
+        if ($2.array) {
+            context-&gt;error(@2, &quot;not supported&quot;, &quot;first-class array&quot;);
+            context-&gt;recover();
+            $2.setArray(false);
+        }
+
+        if ($1.qualifier == EvqAttribute &amp;&amp;
+            ($2.type == EbtBool || $2.type == EbtInt)) {
+            context-&gt;error(@2, &quot;cannot be bool or int&quot;, getQualifierString($1.qualifier));
+            context-&gt;recover();
+        }
+        if (($1.qualifier == EvqVaryingIn || $1.qualifier == EvqVaryingOut) &amp;&amp;
+            ($2.type == EbtBool || $2.type == EbtInt)) {
+            context-&gt;error(@2, &quot;cannot be bool or int&quot;, getQualifierString($1.qualifier));
+            context-&gt;recover();
+        }
+        $$ = $2;
+        $$.qualifier = $1.qualifier;
+    }
+    ;
+
+type_qualifier
+    : CONST_QUAL {
+        $$.setBasic(EbtVoid, EvqConst, @1);
+    }
+    | ATTRIBUTE {
+        VERTEX_ONLY(&quot;attribute&quot;, @1);
+        if (context-&gt;globalErrorCheck(@1, context-&gt;symbolTable.atGlobalLevel(), &quot;attribute&quot;))
+            context-&gt;recover();
+        $$.setBasic(EbtVoid, EvqAttribute, @1);
+    }
+    | VARYING {
+        if (context-&gt;globalErrorCheck(@1, context-&gt;symbolTable.atGlobalLevel(), &quot;varying&quot;))
+            context-&gt;recover();
+        if (context-&gt;shaderType == SH_VERTEX_SHADER)
+            $$.setBasic(EbtVoid, EvqVaryingOut, @1);
+        else
+            $$.setBasic(EbtVoid, EvqVaryingIn, @1);
+    }
+    | INVARIANT VARYING {
+        if (context-&gt;globalErrorCheck(@1, context-&gt;symbolTable.atGlobalLevel(), &quot;invariant varying&quot;))
+            context-&gt;recover();
+        if (context-&gt;shaderType == SH_VERTEX_SHADER)
+            $$.setBasic(EbtVoid, EvqInvariantVaryingOut, @1);
+        else
+            $$.setBasic(EbtVoid, EvqInvariantVaryingIn, @1);
+    }
+    | UNIFORM {
+        if (context-&gt;globalErrorCheck(@1, context-&gt;symbolTable.atGlobalLevel(), &quot;uniform&quot;))
+            context-&gt;recover();
+        $$.setBasic(EbtVoid, EvqUniform, @1);
+    }
+    ;
+
+type_specifier
+    : type_specifier_no_prec {
+        $$ = $1;
+
+        if ($$.precision == EbpUndefined) {
+            $$.precision = context-&gt;symbolTable.getDefaultPrecision($1.type);
+            if (context-&gt;precisionErrorCheck(@1, $$.precision, $1.type)) {
+                context-&gt;recover();
+            }
+        }
+    }
+    | precision_qualifier type_specifier_no_prec {
+        $$ = $2;
+        $$.precision = $1;
+    }
+    ;
+
+precision_qualifier
+    : HIGH_PRECISION {
+        $$ = EbpHigh;
+    }
+    | MEDIUM_PRECISION {
+        $$ = EbpMedium;
+    }
+    | LOW_PRECISION  {
+        $$ = EbpLow;
+    }
+    ;
+
+type_specifier_no_prec
+    : type_specifier_nonarray {
+        $$ = $1;
+    }
+    | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        $$ = $1;
+
+        if (context-&gt;arrayTypeErrorCheck(@2, $1))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck(@2, $3, size))
+                context-&gt;recover();
+            $$.setArray(true, size);
+        }
+    }
+    ;
+
+type_specifier_nonarray
+    : VOID_TYPE {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtVoid, qual, @1);
+    }
+    | FLOAT_TYPE {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+    }
+    | INT_TYPE {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, @1);
+    }
+    | BOOL_TYPE {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, @1);
+    }
+    | VEC2 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(2);
+    }
+    | VEC3 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(3);
+    }
+    | VEC4 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(4);
+    }
+    | BVEC2 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, @1);
+        $$.setAggregate(2);
+    }
+    | BVEC3 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, @1);
+        $$.setAggregate(3);
+    }
+    | BVEC4 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtBool, qual, @1);
+        $$.setAggregate(4);
+    }
+    | IVEC2 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, @1);
+        $$.setAggregate(2);
+    }
+    | IVEC3 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, @1);
+        $$.setAggregate(3);
+    }
+    | IVEC4 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtInt, qual, @1);
+        $$.setAggregate(4);
+    }
+    | MATRIX2 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(2, true);
+    }
+    | MATRIX3 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(3, true);
+    }
+    | MATRIX4 {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtFloat, qual, @1);
+        $$.setAggregate(4, true);
+    }
+    | SAMPLER2D {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler2D, qual, @1);
+    }
+    | SAMPLERCUBE {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerCube, qual, @1);
+    }
+    | SAMPLER_EXTERNAL_OES {
+        if (!context-&gt;supportsExtension(&quot;GL_OES_EGL_image_external&quot;)) {
+            context-&gt;error(@1, &quot;unsupported type&quot;, &quot;samplerExternalOES&quot;);
+            context-&gt;recover();
+        }
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSamplerExternalOES, qual, @1);
+    }
+    | SAMPLER2DRECT {
+        if (!context-&gt;supportsExtension(&quot;GL_ARB_texture_rectangle&quot;)) {
+            context-&gt;error(@1, &quot;unsupported type&quot;, &quot;sampler2DRect&quot;);
+            context-&gt;recover();
+        }
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtSampler2DRect, qual, @1);
+    }
+    | struct_specifier {
+        $$ = $1;
+        $$.qualifier = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+    }
+    | TYPE_NAME {
+        //
+        // This is for user defined type names.  The lexical phase looked up the
+        // type.
+        //
+        TType&amp; structure = static_cast&lt;TVariable*&gt;($1.symbol)-&gt;getType();
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        $$.setBasic(EbtStruct, qual, @1);
+        $$.userDef = &amp;structure;
+    }
+    ;
+
+struct_specifier
+    : STRUCT identifier LEFT_BRACE { if (context-&gt;enterStructDeclaration(@2, *$2.string)) context-&gt;recover(); } struct_declaration_list RIGHT_BRACE {
+        if (context-&gt;reservedErrorCheck(@2, *$2.string))
+            context-&gt;recover();
+
+        TType* structure = new TType(new TStructure($2.string, $5));
+        TVariable* userTypeDef = new TVariable($2.string, *structure, true);
+        if (! context-&gt;symbolTable.insert(*userTypeDef)) {
+            context-&gt;error(@2, &quot;redefinition&quot;, $2.string-&gt;c_str(), &quot;struct&quot;);
+            context-&gt;recover();
+        }
+        $$.setBasic(EbtStruct, EvqTemporary, @1);
+        $$.userDef = structure;
+        context-&gt;exitStructDeclaration();
+    }
+    | STRUCT LEFT_BRACE { if (context-&gt;enterStructDeclaration(@2, *$2.string)) context-&gt;recover(); } struct_declaration_list RIGHT_BRACE {
+        TType* structure = new TType(new TStructure(NewPoolTString(&quot;&quot;), $4));
+        $$.setBasic(EbtStruct, EvqTemporary, @1);
+        $$.userDef = structure;
+        context-&gt;exitStructDeclaration();
+    }
+    ;
+
+struct_declaration_list
+    : struct_declaration {
+        $$ = $1;
+    }
+    | struct_declaration_list struct_declaration {
+        $$ = $1;
+        for (size_t i = 0; i &lt; $2-&gt;size(); ++i) {
+            TField* field = (*$2)[i];
+            for (size_t j = 0; j &lt; $$-&gt;size(); ++j) {
+                if ((*$$)[j]-&gt;name() == field-&gt;name()) {
+                    context-&gt;error(@2, &quot;duplicate field name in structure:&quot;, &quot;struct&quot;, field-&gt;name().c_str());
+                    context-&gt;recover();
+                }
+            }
+            $$-&gt;push_back(field);
+        }
+    }
+    ;
+
+struct_declaration
+    : type_specifier struct_declarator_list SEMICOLON {
+        $$ = $2;
+
+        if (context-&gt;voidErrorCheck(@1, (*$2)[0]-&gt;name(), $1)) {
+            context-&gt;recover();
+        }
+        for (unsigned int i = 0; i &lt; $$-&gt;size(); ++i) {
+            //
+            // Careful not to replace already known aspects of type, like array-ness
+            //
+            TType* type = (*$$)[i]-&gt;type();
+            type-&gt;setBasicType($1.type);
+            type-&gt;setNominalSize($1.size);
+            type-&gt;setMatrix($1.matrix);
+            type-&gt;setPrecision($1.precision);
+
+            // don't allow arrays of arrays
+            if (type-&gt;isArray()) {
+                if (context-&gt;arrayTypeErrorCheck(@1, $1))
+                    context-&gt;recover();
+            }
+            if ($1.array)
+                type-&gt;setArraySize($1.arraySize);
+            if ($1.userDef)
+                type-&gt;setStruct($1.userDef-&gt;getStruct());
+
+            if (context-&gt;structNestingErrorCheck(@1, *(*$$)[i]))
+                context-&gt;recover();
+        }
+    }
+    ;
+
+struct_declarator_list
+    : struct_declarator {
+        $$ = NewPoolTFieldList();
+        $$-&gt;push_back($1);
+    }
+    | struct_declarator_list COMMA struct_declarator {
+        $$-&gt;push_back($3);
+    }
+    ;
+
+struct_declarator
+    : identifier {
+        if (context-&gt;reservedErrorCheck(@1, *$1.string))
+            context-&gt;recover();
+
+        TType* type = new TType(EbtVoid, EbpUndefined);
+        $$ = new TField(type, $1.string);
+    }
+    | identifier LEFT_BRACKET constant_expression RIGHT_BRACKET {
+        if (context-&gt;reservedErrorCheck(@1, *$1.string))
+            context-&gt;recover();
+
+        TType* type = new TType(EbtVoid, EbpUndefined);
+        int size = 0;
+        if (context-&gt;arraySizeErrorCheck(@3, $3, size))
+            context-&gt;recover();
+        type-&gt;setArraySize(size);
+
+        $$ = new TField(type, $1.string);
+    }
+    ;
+
+initializer
+    : assignment_expression { $$ = $1; }
+    ;
+
+declaration_statement
+    : declaration { $$ = $1; }
+    ;
+
+statement
+    : compound_statement  { $$ = $1; }
+    | simple_statement    { $$ = $1; }
+    ;
+
+// Grammar Note:  No labeled statements; 'goto' is not supported.
+
+simple_statement
+    : declaration_statement { $$ = $1; }
+    | expression_statement  { $$ = $1; }
+    | selection_statement   { $$ = $1; }
+    | iteration_statement   { $$ = $1; }
+    | jump_statement        { $$ = $1; }
+    ;
+
+compound_statement
+    : LEFT_BRACE RIGHT_BRACE { $$ = 0; }
+    | LEFT_BRACE { context-&gt;symbolTable.push(); } statement_list { context-&gt;symbolTable.pop(); } RIGHT_BRACE {
+        if ($3 != 0) {
+            $3-&gt;setOp(EOpSequence);
+            $3-&gt;setLine(@$);
+        }
+        $$ = $3;
+    }
+    ;
+
+statement_no_new_scope
+    : compound_statement_no_new_scope { $$ = $1; }
+    | simple_statement                { $$ = $1; }
+    ;
+
+statement_with_scope
+    : { context-&gt;symbolTable.push(); } compound_statement_no_new_scope { context-&gt;symbolTable.pop(); $$ = $2; }
+    | { context-&gt;symbolTable.push(); } simple_statement                { context-&gt;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) {
+            $2-&gt;setOp(EOpSequence);
+            $2-&gt;setLine(@$);
+        }
+        $$ = $2;
+    }
+    ;
+
+statement_list
+    : statement {
+        $$ = context-&gt;intermediate.makeAggregate($1, @$);
+    }
+    | statement_list statement {
+        $$ = context-&gt;intermediate.growAggregate($1, $2, @$);
+    }
+    ;
+
+expression_statement
+    : SEMICOLON  { $$ = 0; }
+    | expression SEMICOLON  { $$ = static_cast&lt;TIntermNode*&gt;($1); }
+    ;
+
+selection_statement
+    : IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
+        if (context-&gt;boolErrorCheck(@1, $3))
+            context-&gt;recover();
+        $$ = context-&gt;intermediate.addSelection($3, $5, @1);
+    }
+    ;
+
+selection_rest_statement
+    : statement_with_scope ELSE statement_with_scope {
+        $$.node1 = $1;
+        $$.node2 = $3;
+    }
+    | statement_with_scope {
+        $$.node1 = $1;
+        $$.node2 = 0;
+    }
+    ;
+
+// Grammar Note:  No 'switch'.  Switch statements not supported.
+
+condition
+    // In 1996 c++ draft, conditions can include single declarations
+    : expression {
+        $$ = $1;
+        if (context-&gt;boolErrorCheck($1-&gt;getLine(), $1))
+            context-&gt;recover();
+    }
+    | fully_specified_type identifier EQUAL initializer {
+        TIntermNode* intermNode;
+        if (context-&gt;structQualifierErrorCheck(@2, $1))
+            context-&gt;recover();
+        if (context-&gt;boolErrorCheck(@2, $1))
+            context-&gt;recover();
+
+        if (!context-&gt;executeInitializer(@2, *$2.string, $1, $4, intermNode))
+            $$ = $4;
+        else {
+            context-&gt;recover();
+            $$ = 0;
+        }
+    }
+    ;
+
+iteration_statement
+    : WHILE LEFT_PAREN { context-&gt;symbolTable.push(); ++context-&gt;loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
+        context-&gt;symbolTable.pop();
+        $$ = context-&gt;intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, @1);
+        --context-&gt;loopNestingLevel;
+    }
+    | DO { ++context-&gt;loopNestingLevel; } statement_with_scope WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
+        if (context-&gt;boolErrorCheck(@8, $6))
+            context-&gt;recover();
+
+        $$ = context-&gt;intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, @4);
+        --context-&gt;loopNestingLevel;
+    }
+    | FOR LEFT_PAREN { context-&gt;symbolTable.push(); ++context-&gt;loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
+        context-&gt;symbolTable.pop();
+        $$ = context-&gt;intermediate.addLoop(ELoopFor, $4, reinterpret_cast&lt;TIntermTyped*&gt;($5.node1), reinterpret_cast&lt;TIntermTyped*&gt;($5.node2), $7, @1);
+        --context-&gt;loopNestingLevel;
+    }
+    ;
+
+for_init_statement
+    : expression_statement {
+        $$ = $1;
+    }
+    | declaration_statement {
+        $$ = $1;
+    }
+    ;
+
+conditionopt
+    : condition {
+        $$ = $1;
+    }
+    | /* May be null */ {
+        $$ = 0;
+    }
+    ;
+
+for_rest_statement
+    : conditionopt SEMICOLON {
+        $$.node1 = $1;
+        $$.node2 = 0;
+    }
+    | conditionopt SEMICOLON expression  {
+        $$.node1 = $1;
+        $$.node2 = $3;
+    }
+    ;
+
+jump_statement
+    : CONTINUE SEMICOLON {
+        if (context-&gt;loopNestingLevel &lt;= 0) {
+            context-&gt;error(@1, &quot;continue statement only allowed in loops&quot;, &quot;&quot;);
+            context-&gt;recover();
+        }
+        $$ = context-&gt;intermediate.addBranch(EOpContinue, @1);
+    }
+    | BREAK SEMICOLON {
+        if (context-&gt;loopNestingLevel &lt;= 0) {
+            context-&gt;error(@1, &quot;break statement only allowed in loops&quot;, &quot;&quot;);
+            context-&gt;recover();
+        }
+        $$ = context-&gt;intermediate.addBranch(EOpBreak, @1);
+    }
+    | RETURN SEMICOLON {
+        $$ = context-&gt;intermediate.addBranch(EOpReturn, @1);
+        if (context-&gt;currentFunctionType-&gt;getBasicType() != EbtVoid) {
+            context-&gt;error(@1, &quot;non-void function must return a value&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        }
+    }
+    | RETURN expression SEMICOLON {
+        $$ = context-&gt;intermediate.addBranch(EOpReturn, $2, @1);
+        context-&gt;functionReturnsValue = true;
+        if (context-&gt;currentFunctionType-&gt;getBasicType() == EbtVoid) {
+            context-&gt;error(@1, &quot;void function cannot return a value&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        } else if (*(context-&gt;currentFunctionType) != $2-&gt;getType()) {
+            context-&gt;error(@1, &quot;function return is not matching type:&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        }
+    }
+    | DISCARD SEMICOLON {
+        FRAG_ONLY(&quot;discard&quot;, @1);
+        $$ = context-&gt;intermediate.addBranch(EOpKill, @1);
+    }
+    ;
+
+// Grammar Note:  No 'goto'.  Gotos are not supported.
+
+translation_unit
+    : external_declaration {
+        $$ = $1;
+        context-&gt;treeRoot = $$;
+    }
+    | translation_unit external_declaration {
+        $$ = context-&gt;intermediate.growAggregate($1, $2, @$);
+        context-&gt;treeRoot = $$;
+    }
+    ;
+
+external_declaration
+    : function_definition {
+        $$ = $1;
+    }
+    | declaration {
+        $$ = $1;
+    }
+    ;
+
+function_definition
+    : function_prototype {
+        TFunction* function = $1.function;
+        
+        const TSymbol *builtIn = context-&gt;symbolTable.findBuiltIn(function-&gt;getMangledName());
+        
+        if (builtIn)
+        {
+            context-&gt;error(@1, &quot;built-in functions cannot be redefined&quot;, function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        
+        TFunction* prevDec = static_cast&lt;TFunction*&gt;(context-&gt;symbolTable.find(function-&gt;getMangledName()));
+        //
+        // Note:  'prevDec' could be 'function' if this is the first time we've seen function
+        // as it would have just been put in the symbol table.  Otherwise, we're looking up
+        // an earlier occurance.
+        //
+        if (prevDec-&gt;isDefined()) {
+            //
+            // Then this function already has a body.
+            //
+            context-&gt;error(@1, &quot;function already has a body&quot;, function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        prevDec-&gt;setDefined();
+
+        //
+        // Raise error message if main function takes any parameters or return anything other than void
+        //
+        if (function-&gt;getName() == &quot;main&quot;) {
+            if (function-&gt;getParamCount() &gt; 0) {
+                context-&gt;error(@1, &quot;function cannot take any parameter(s)&quot;, function-&gt;getName().c_str());
+                context-&gt;recover();
+            }
+            if (function-&gt;getReturnType().getBasicType() != EbtVoid) {
+                context-&gt;error(@1, &quot;&quot;, function-&gt;getReturnType().getBasicString(), &quot;main function cannot return a value&quot;);
+                context-&gt;recover();
+            }
+        }
+
+        //
+        // Remember the return type for later checking for RETURN statements.
+        //
+        context-&gt;currentFunctionType = &amp;(prevDec-&gt;getReturnType());
+        context-&gt;functionReturnsValue = false;
+
+        //
+        // Insert parameters into the symbol table.
+        // If the parameter has no name, it's not an error, just don't insert it
+        // (could be used for unused args).
+        //
+        // Also, accumulate the list of parameters into the HIL, so lower level code
+        // knows where to find parameters.
+        //
+        TIntermAggregate* paramNodes = new TIntermAggregate;
+        for (size_t i = 0; i &lt; function-&gt;getParamCount(); i++) {
+            const TParameter&amp; param = function-&gt;getParam(i);
+            if (param.name != 0) {
+                TVariable *variable = new TVariable(param.name, *param.type);
+                //
+                // Insert the parameters with name in the symbol table.
+                //
+                if (! context-&gt;symbolTable.insert(*variable)) {
+                    context-&gt;error(@1, &quot;redefinition&quot;, variable-&gt;getName().c_str());
+                    context-&gt;recover();
+                    delete variable;
+                }
+
+                //
+                // Add the parameter to the HIL
+                //
+                paramNodes = context-&gt;intermediate.growAggregate(
+                                               paramNodes,
+                                               context-&gt;intermediate.addSymbol(variable-&gt;getUniqueId(),
+                                                                               variable-&gt;getName(),
+                                                                               variable-&gt;getType(),
+                                                                               @1),
+                                               @1);
+            } else {
+                paramNodes = context-&gt;intermediate.growAggregate(paramNodes, context-&gt;intermediate.addSymbol(0, &quot;&quot;, *param.type, @1), @1);
+            }
+        }
+        context-&gt;intermediate.setAggregateOperator(paramNodes, EOpParameters, @1);
+        $1.intermAggregate = paramNodes;
+        context-&gt;loopNestingLevel = 0;
+    }
+    compound_statement_no_new_scope {
+        //?? Check that all paths return a value if return type != void ?
+        //   May be best done as post process phase on intermediate code
+        if (context-&gt;currentFunctionType-&gt;getBasicType() != EbtVoid &amp;&amp; ! context-&gt;functionReturnsValue) {
+            context-&gt;error(@1, &quot;function does not return a value:&quot;, &quot;&quot;, $1.function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        
+        $$ = context-&gt;intermediate.growAggregate($1.intermAggregate, $3, @$);
+        context-&gt;intermediate.setAggregateOperator($$, EOpFunction, @1);
+        $$-&gt;getAsAggregate()-&gt;setName($1.function-&gt;getMangledName().c_str());
+        $$-&gt;getAsAggregate()-&gt;setType($1.function-&gt;getReturnType());
+
+        // store the pragma information for debug and optimize and other vendor specific
+        // information. This information can be queried from the parse tree
+        $$-&gt;getAsAggregate()-&gt;setOptimize(context-&gt;pragma().optimize);
+        $$-&gt;getAsAggregate()-&gt;setDebug(context-&gt;pragma().debug);
+
+        context-&gt;symbolTable.pop();
+    }
+    ;
+
+%%
+
+int glslang_parse(TParseContext* context) {
+    return yyparse(context);
+}
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_lexcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,2978 @@
</span><ins>+#line 17 &quot;./glslang.l&quot;
+//
+// 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.
+//
+
+// 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 &quot;-Wunused-function&quot;
+#pragma GCC diagnostic ignored &quot;-Wunused-variable&quot;
+#pragma GCC diagnostic ignored &quot;-Wswitch-enum&quot;
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4065)
+#pragma warning(disable: 4189)
+#pragma warning(disable: 4505)
+#pragma warning(disable: 4701)
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored &quot;-Wunknown-pragmas&quot;
+#pragma clang diagnostic ignored &quot;-Wdeprecated-register&quot;
+#endif
+
+#line 25 &quot;./glslang_lex.cpp&quot;
+
+#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 37
+#if YY_FLEX_SUBMINOR_VERSION &gt; 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;errno.h&gt;
+#include &lt;stdlib.h&gt;
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have &lt;inttypes.h&gt;. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) &amp;&amp; __STDC_VERSION__ &gt;= 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 &lt;inttypes.h&gt;
+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;
+
+/* 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 /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The &quot;const&quot; 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-&gt;yyin_r
+#define yyout yyg-&gt;yyout_r
+#define yyextra yyg-&gt;yyextra_r
+#define yyleng yyg-&gt;yyleng_r
+#define yytext yyg-&gt;yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE-&gt;yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE-&gt;yy_bs_column)
+#define yy_flex_debug yyg-&gt;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-&gt;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-&gt;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 &quot;start processing a new file&quot;. */
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
+     *       access to the local variable yy_act. Since yyless() is a macro, it would break
+     *       existing scanners that call yyless() from OUTSIDE yylex. 
+     *       One obvious solution it to make yy_act a global. I tried that, and saw
+     *       a 5% performance hit in a non-yylineno scanner, because yy_act is
+     *       normally declared as a register variable-- so it is not worth it.
+     */
+    #define  YY_LESS_LINENO(n) \
+            do { \
+                int yyl;\
+                for ( yyl = n; yyl &lt; yyleng; ++yyl )\
+                    if ( yytext[yyl] == '\n' )\
+                        --yylineno;\
+            }while(0)
+    
+/* Return all but the first &quot;n&quot; 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-&gt;yy_hold_char; \
+        YY_RESTORE_YY_MORE_OFFSET \
+        yyg-&gt;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-&gt;yytext_ptr , yyscanner )
+
+#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.
+     */
+    yy_size_t yy_n_chars;
+
+    /* Whether we &quot;own&quot; 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 &quot;interactive&quot; 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; /**&lt; The line count. */
+    int yy_bs_column; /**&lt; 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 &quot;new&quot;
+     * (via yyrestart()), so that the user can continue scanning by
+     * just pointing yyin at a new input file.
+     */
+#define YY_BUFFER_EOF_PENDING 2
+
+    };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * &quot;scanner state&quot;.
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg-&gt;yy_buffer_stack \
+                          ? yyg-&gt;yy_buffer_stack[yyg-&gt;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-&gt;yy_buffer_stack[yyg-&gt;yy_buffer_stack_top]
+
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
+
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,yy_size_t len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+    { \
+    if ( ! YY_CURRENT_BUFFER ){ \
+        yyensure_buffer_stack (yyscanner); \
+        YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+    } \
+    YY_CURRENT_BUFFER_LVALUE-&gt;yy_is_interactive = is_interactive; \
+    }
+
+#define yy_set_bol(at_bol) \
+    { \
+    if ( ! YY_CURRENT_BUFFER ){\
+        yyensure_buffer_stack (yyscanner); \
+        YY_CURRENT_BUFFER_LVALUE =    \
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+    } \
+    YY_CURRENT_BUFFER_LVALUE-&gt;yy_at_bol = at_bol; \
+    }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE-&gt;yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(yyscanner) 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-&gt;yytext_ptr = yy_bp; \
+    yyleng = (size_t) (yy_cp - yy_bp); \
+    yyg-&gt;yy_hold_char = *yy_cp; \
+    *yy_cp = '\0'; \
+    yyg-&gt;yy_c_buf_p = yy_cp;
+
+#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
+    {
+    flex_int32_t yy_verify;
+    flex_int32_t yy_nxt;
+    };
+static yyconst flex_int16_t yy_accept[443] =
+    {   0,
+        0,    0,  148,  146,  145,  145,  132,  138,  143,  127,
+      128,  136,  135,  124,  133,  131,  137,   96,   96,  125,
+      121,  139,  126,  140,  144,   93,  129,  130,  142,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,  122,
+      141,  123,  134,  118,  104,  123,  112,  107,  102,  110,
+      100,  111,  101,   99,  103,   98,   95,   96,    0,    0,
+      130,  122,  129,  119,  115,  117,  116,  120,   93,  108,
+      114,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   12,   93,   93,   93,   93,   93,   93,   93,   93,
+
+       93,   93,   93,   93,   93,   15,   17,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,  109,  113,    0,   98,    0,    0,
+       97,   94,  105,  106,   45,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   13,   93,   93,   93,   93,   93,   93,
+       93,   93,   21,   93,   93,   93,   93,   93,   93,   93,
+       93,   18,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+
+       93,   93,   93,   93,   93,    0,   99,    0,   98,   93,
+       23,   93,   93,   90,   93,   93,   93,   93,   93,   93,
+       93,   16,   48,   93,   93,   93,   64,   93,   93,   53,
+       68,   93,   93,   93,   93,   93,   93,   93,   93,   65,
+        4,   28,   29,   30,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   93,   93,   93,   93,
+       51,   24,   93,   93,   93,   93,   93,   93,   31,   32,
+       33,   22,   93,   93,   93,   10,   37,   38,   39,   46,
+        7,   93,   93,   93,   93,   77,   78,   79,   93,   25,
+       69,   20,   80,   81,   82,    2,   74,   75,   76,   93,
+
+       19,   72,   93,   93,   34,   35,   36,   93,   93,   93,
+       93,   93,   93,   93,   93,   93,   66,   93,   93,   93,
+       93,   93,   93,   93,   93,   47,   93,   92,   93,   93,
+       14,   93,   93,   93,   93,   67,   61,   56,   93,   93,
+       93,   93,   93,   73,   52,   93,   59,   27,   93,   89,
+       60,   44,   71,   54,   93,   93,   93,   93,   93,   93,
+       93,   93,   55,   26,   93,   93,   93,    3,   93,   93,
+       93,   93,   93,   49,    8,   93,    9,   93,   93,   11,
+       62,   93,   93,   93,   57,   93,   93,   93,   93,   93,
+       93,   50,   70,   58,    6,   63,    1,   91,    5,   83,
+
+       40,   84,   93,   93,   93,   93,   93,   93,   93,   93,
+       93,   93,   93,   93,   41,   93,   93,   93,   93,   93,
+       93,   93,   43,   93,   87,   93,   93,   93,   93,   93,
+       85,   93,   86,   93,   93,   93,   93,   93,   93,   42,
+       88,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        2,    2,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    1,    1,    1,    5,    6,    1,    7,
+        8,    9,   10,   11,   12,   13,   14,   15,   16,   17,
+       18,   19,   20,   20,   20,   21,   21,   22,   23,   24,
+       25,   26,   27,    1,   28,   28,   29,   30,   31,   28,
+       32,   32,   32,   32,   32,   32,   32,   32,   33,   32,
+       32,   34,   35,   32,   32,   32,   32,   36,   32,   32,
+       37,    1,   38,   39,   32,    1,   40,   41,   42,   43,
+
+       44,   45,   46,   47,   48,   32,   49,   50,   51,   52,
+       53,   54,   32,   55,   56,   57,   58,   59,   60,   61,
+       62,   63,   64,   65,   66,   67,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    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[68] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    2,    2,    2,    2,    2,    2,
+        2,    1,    1,    1,    1,    1,    1,    2,    2,    2,
+        2,    3,    3,    3,    3,    3,    1,    1,    1,    2,
+        2,    2,    2,    2,    2,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[445] =
+    {   0,
+        0,    0,  587,  588,  588,  588,  561,   43,   64,  588,
+      588,  560,   61,  588,   60,   58,  559,   77,   86,  557,
+      588,  104,  557,   55,  588,    0,  588,  588,   75,   26,
+       57,   82,   83,   73,   93,  528,   97,   95,  527,   44,
+       71,  521,  104,  534,  110,  116,   35,  111,  530,  588,
+      114,  588,  588,  588,  588,  588,  588,  588,  588,  588,
+      588,  588,  588,  165,  588,  172,  202,  211,  233,    0,
+      588,  588,  588,  551,  588,  588,  588,  550,    0,  588,
+      588,  523,  516,  519,  527,  526,  513,  528,  515,  521,
+      509,  506,  519,  506,  503,  503,  509,  497,  108,  502,
+
+      512,  498,  504,  507,  508,    0,  145,  507,  113,  493,
+      506,  497,  499,  489,  503,  500,  502,  485,  490,  487,
+      476,  157,  484,  489,  485,  487,  476,  479,  118,  484,
+      476,  488,   70,  481,  588,  588,  246,  253,  270,  219,
+      283,    0,  588,  588,    0,  473,  477,  486,  483,  467,
+      467,  119,  482,  479,  479,  477,  474,  466,  472,  459,
+      470,  456,  472,    0,  469,  457,  464,  461,  465,  458,
+      447,  446,  459,  462,  459,  454,  445,  188,  450,  453,
+      444,  441,  445,  451,  442,  433,  436,  434,  444,  430,
+      428,  441,  427,  429,  426,  437,  436,  124,  431,  426,
+
+      415,  258,  433,  435,  424,  290,  297,  304,  311,  425,
+        0,  423,  275,    0,  415,  413,  421,  410,  427,  416,
+      316,    0,    0,  410,  420,  420,    0,  405,  319,    0,
+        0,  407,  322,  408,  402,  401,  402,  401,  325,    0,
+        0,    0,    0,    0,  397,  398,  403,  394,  407,  402,
+      401,  393,  397,  389,  392,  396,  401,  387,  399,  390,
+        0,    0,  396,  385,  385,  390,  389,  386,    0,    0,
+        0,    0,  376,  388,  390,    0,    0,    0,    0,    0,
+        0,  378,  379,  373,  383,    0,    0,    0,  374,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,  381,
+
+        0,    0,  379,  375,    0,    0,    0,  371,  367,  372,
+      362,  375,  361,  374,  363,  370,    0,  368,  370,  354,
+      356,  362,  368,  363,  351,    0,  353,    0,  352,  355,
+        0,  344,  343,  343,  356,    0,  358,    0,  357,  356,
+      341,  354,  341,    0,    0,  344,    0,    0,  336,    0,
+        0,    0,    0,    0,  333,  344,  337,  343,  340,  335,
+      327,  339,    0,    0,  332,  339,  328,    0,  337,  334,
+      324,  329,  332,    0,    0,  332,    0,  330,  329,    0,
+        0,  328,  314,  326,    0,  317,  338,  337,  336,  307,
+      303,    0,    0,    0,    0,    0,    0,    0,    0,  328,
+
+      166,  325,  316,  299,  308,  310,  306,  308,  307,  306,
+      309,  306,  256,  253,    0,  228,  238,  222,  235,  203,
+      207,  204,  212,  191,    0,  201,  165,  167,  153,  161,
+        0,  170,    0,  175,  151,  141,  100,  114,   59,    0,
+        0,  588,  359,  113
+    } ;
+
+static yyconst flex_int16_t yy_def[445] =
+    {   0,
+      442,    1,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  443,  442,  442,  442,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  444,
+      442,  442,  442,  442,  442,  442,  442,  442,  443,  442,
+      442,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  442,  442,  442,  442,  442,  442,
+      442,  444,  442,  442,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+
+      443,  443,  443,  443,  443,  442,  442,  442,  442,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,  443,  443,  443,  443,  443,  443,  443,  443,  443,
+      443,    0,  442,  442
+    } ;
+
+static yyconst flex_int16_t yy_nxt[656] =
+    {   0,
+        4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
+       14,   15,   16,   17,   18,   19,   19,   19,   19,   19,
+       19,   20,   21,   22,   23,   24,   25,   26,   26,   26,
+       26,   26,   26,   26,   26,   26,   27,   28,   29,   30,
+       31,   32,   33,   34,   35,   36,   37,   38,   26,   39,
+       40,   41,   42,   43,   44,   45,   46,   47,   48,   49,
+       26,   26,   26,   50,   51,   52,   53,   55,   56,   57,
+       60,   62,   64,   64,   64,   64,   64,   64,   64,   77,
+       78,   82,   83,  110,   63,   61,  129,  111,   58,   66,
+      130,   67,   67,   67,   67,   67,   67,   68,   66,   80,
+
+       68,   68,   68,   68,   68,   68,   68,   69,   72,   84,
+      112,   85,   70,   81,  142,   86,   69,  203,  441,  204,
+       69,   87,   94,  113,   95,   73,   90,   74,   75,   69,
+       91,   88,   97,   96,   89,   92,  103,   70,  135,  106,
+       98,   93,   99,  115,  104,  100,  107,  162,  440,  119,
+      131,  101,  439,  108,  132,  105,  120,  121,  116,  125,
+      163,  117,  126,  133,  176,  198,  122,  123,  264,  124,
+      127,  438,  177,  199,  216,  217,  265,  128,  136,   64,
+       64,   64,   64,   64,   64,   64,  138,  138,  138,  138,
+      138,  138,  138,  437,  170,  137,  190,  171,  172,  406,
+
+      407,  173,  139,  174,  242,  243,  244,  436,  137,  435,
+      434,  191,  433,  432,   66,  139,   67,   67,   67,   67,
+       67,   67,   68,   66,  431,   68,   68,   68,   68,   68,
+       68,   68,   69,  141,  141,  141,  141,  141,  141,  141,
+      430,   69,  140,  429,  140,   69,  428,  141,  141,  141,
+      141,  141,  141,  141,   69,  206,  427,  206,  426,  425,
+      207,  207,  207,  207,  207,  207,  207,  138,  138,  138,
+      138,  138,  138,  138,  269,  270,  271,  424,  423,  208,
+      422,  208,  421,  139,  209,  209,  209,  209,  209,  209,
+      209,  277,  278,  279,  420,  419,  139,  141,  141,  141,
+
+      141,  141,  141,  141,  207,  207,  207,  207,  207,  207,
+      207,  207,  207,  207,  207,  207,  207,  207,  209,  209,
+      209,  209,  209,  209,  209,  209,  209,  209,  209,  209,
+      209,  209,  286,  287,  288,  293,  294,  295,  297,  298,
+      299,  305,  306,  307,  387,  388,  389,  418,  417,  416,
+      415,  414,  413,  412,  411,  410,  409,  390,  408,  391,
+       79,   79,  405,  404,  403,  402,  401,  400,  399,  398,
+      397,  396,  395,  394,  393,  392,  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,  318,  317,  316,  315,  314,  313,
+      312,  311,  310,  309,  308,  304,  303,  302,  301,  300,
+      296,  292,  291,  290,  289,  285,  284,  283,  282,  281,
+      280,  276,  275,  274,  273,  272,  268,  267,  266,  263,
+      262,  261,  260,  259,  258,  257,  256,  255,  254,  253,
+      252,  251,  250,  249,  248,  247,  246,  245,  241,  240,
+
+      239,  238,  237,  236,  235,  234,  233,  232,  231,  230,
+      229,  228,  227,  226,  225,  224,  223,  222,  221,  220,
+      219,  218,  215,  214,  213,  212,  211,  210,  205,  202,
+      201,  200,  197,  196,  195,  194,  193,  192,  189,  188,
+      187,  186,  185,  184,  183,  182,  181,  180,  179,  178,
+      175,  169,  168,  167,  166,  165,  164,  161,  160,  159,
+      158,  157,  156,  155,  154,  153,  152,  151,  150,  149,
+      148,  147,  146,  145,  144,  143,  134,  118,  114,  109,
+      102,   76,   71,   65,   59,   54,  442,    3,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442
+    } ;
+
+static yyconst flex_int16_t yy_chk[656] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    8,    8,    9,
+       13,   15,   16,   16,   16,   16,   16,   16,   16,   24,
+       24,   30,   30,   40,   15,   13,   47,   40,    9,   18,
+       47,   18,   18,   18,   18,   18,   18,   18,   19,   29,
+
+       19,   19,   19,   19,   19,   19,   19,   18,   22,   31,
+       41,   31,   18,   29,  444,   31,   19,  133,  439,  133,
+       18,   32,   34,   41,   34,   22,   33,   22,   22,   19,
+       33,   32,   35,   34,   32,   33,   37,   18,   51,   38,
+       35,   33,   35,   43,   37,   35,   38,   99,  438,   45,
+       48,   35,  437,   38,   48,   37,   45,   45,   43,   46,
+       99,   43,   46,   48,  109,  129,   45,   45,  198,   45,
+       46,  436,  109,  129,  152,  152,  198,   46,   51,   64,
+       64,   64,   64,   64,   64,   64,   66,   66,   66,   66,
+       66,   66,   66,  435,  107,   64,  122,  107,  107,  401,
+
+      401,  107,   66,  107,  178,  178,  178,  434,   64,  432,
+      430,  122,  429,  428,   67,   66,   67,   67,   67,   67,
+       67,   67,   67,   68,  427,   68,   68,   68,   68,   68,
+       68,   68,   67,  140,  140,  140,  140,  140,  140,  140,
+      426,   68,   69,  424,   69,   67,  423,   69,   69,   69,
+       69,   69,   69,   69,   68,  137,  422,  137,  421,  420,
+      137,  137,  137,  137,  137,  137,  137,  138,  138,  138,
+      138,  138,  138,  138,  202,  202,  202,  419,  418,  139,
+      417,  139,  416,  138,  139,  139,  139,  139,  139,  139,
+      139,  213,  213,  213,  414,  413,  138,  141,  141,  141,
+
+      141,  141,  141,  141,  206,  206,  206,  206,  206,  206,
+      206,  207,  207,  207,  207,  207,  207,  207,  208,  208,
+      208,  208,  208,  208,  208,  209,  209,  209,  209,  209,
+      209,  209,  221,  221,  221,  229,  229,  229,  233,  233,
+      233,  239,  239,  239,  372,  372,  372,  412,  411,  410,
+      409,  408,  407,  406,  405,  404,  403,  372,  402,  372,
+      443,  443,  400,  391,  390,  389,  388,  387,  386,  384,
+      383,  382,  379,  378,  376,  373,  371,  370,  369,  367,
+      366,  365,  362,  361,  360,  359,  358,  357,  356,  355,
+      349,  346,  343,  342,  341,  340,  339,  337,  335,  334,
+
+      333,  332,  330,  329,  327,  325,  324,  323,  322,  321,
+      320,  319,  318,  316,  315,  314,  313,  312,  311,  310,
+      309,  308,  304,  303,  300,  289,  285,  284,  283,  282,
+      275,  274,  273,  268,  267,  266,  265,  264,  263,  260,
+      259,  258,  257,  256,  255,  254,  253,  252,  251,  250,
+      249,  248,  247,  246,  245,  238,  237,  236,  235,  234,
+      232,  228,  226,  225,  224,  220,  219,  218,  217,  216,
+      215,  212,  210,  205,  204,  203,  201,  200,  199,  197,
+      196,  195,  194,  193,  192,  191,  190,  189,  188,  187,
+      186,  185,  184,  183,  182,  181,  180,  179,  177,  176,
+
+      175,  174,  173,  172,  171,  170,  169,  168,  167,  166,
+      165,  163,  162,  161,  160,  159,  158,  157,  156,  155,
+      154,  153,  151,  150,  149,  148,  147,  146,  134,  132,
+      131,  130,  128,  127,  126,  125,  124,  123,  121,  120,
+      119,  118,  117,  116,  115,  114,  113,  112,  111,  110,
+      108,  105,  104,  103,  102,  101,  100,   98,   97,   96,
+       95,   94,   93,   92,   91,   90,   89,   88,   87,   86,
+       85,   84,   83,   82,   78,   74,   49,   44,   42,   39,
+       36,   23,   20,   17,   12,    7,    3,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442,  442,  442,  442,  442,  442,
+      442,  442,  442,  442,  442
+    } ;
+
+/* Table of booleans, true if rule could match eol. */
+static yyconst flex_int32_t yy_rule_can_match_eol[148] =
+    {   0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 1, 0, 0,     };
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+/*
+//
+// Copyright (c) 2002-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 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_parser.sh,
+WHICH GENERATES THE GLSL ES LEXER (glslang_lex.cpp).
+*/
+
+#include &quot;compiler/translator/glslang.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;compiler/preprocessor/Token.h&quot;
+#include &quot;compiler/translator/util.h&quot;
+#include &quot;compiler/translator/glslang_tab.h&quot;
+
+/* windows only pragma */
+#ifdef _MSC_VER
+#pragma warning(disable : 4102)
+#endif
+
+#define YY_USER_ACTION                                 \
+    yylloc-&gt;first_file = yylloc-&gt;last_file = yycolumn; \
+    yylloc-&gt;first_line = yylloc-&gt;last_line = yylineno;
+
+#define YY_INPUT(buf, result, max_size) \
+    result = string_input(buf, max_size, yyscanner);
+
+static yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner);
+static int check_type(yyscan_t yyscanner);
+static int reserved_word(yyscan_t yyscanner);
+static int int_constant(yyscan_t yyscanner);
+static int float_constant(yyscan_t yyscanner);
+
+#define INITIAL 0
+
+#define YY_EXTRA_TYPE TParseContext*
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+    {
+
+    /* User-defined. Not touched by flex. */
+    YY_EXTRA_TYPE yyextra_r;
+
+    /* The rest are the same as the globals declared in the non-reentrant scanner. */
+    FILE *yyin_r, *yyout_r;
+    size_t yy_buffer_stack_top; /**&lt; index of top of stack. */
+    size_t yy_buffer_stack_max; /**&lt; capacity of stack. */
+    YY_BUFFER_STATE * yy_buffer_stack; /**&lt; Stack as an array. */
+    char yy_hold_char;
+    yy_size_t yy_n_chars;
+    yy_size_t 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-&gt;yylval_r
+    
+    #    define yylloc yyg-&gt;yylloc_r
+    
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+   These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (yyscan_t yyscanner );
+
+int yyget_debug (yyscan_t yyscanner );
+
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *yyget_in (yyscan_t yyscanner );
+
+void yyset_in  (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *yyget_out (yyscan_t yyscanner );
+
+void yyset_out  (FILE * out_str ,yyscan_t yyscanner );
+
+yy_size_t yyget_leng (yyscan_t yyscanner );
+
+char *yyget_text (yyscan_t yyscanner );
+
+int yyget_lineno (yyscan_t yyscanner );
+
+void yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+int yyget_column  (yyscan_t yyscanner );
+
+void yyset_column (int column_no ,yyscan_t yyscanner );
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
+
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+       YYLTYPE *yyget_lloc (yyscan_t yyscanner );
+    
+        void yyset_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 &quot;C&quot; int yywrap (yyscan_t yyscanner );
+#else
+extern int yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* 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 do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into &quot;buf&quot;.  number of characters read, or YY_NULL,
+ * is returned in &quot;result&quot;.
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+    if ( YY_CURRENT_BUFFER_LVALUE-&gt;yy_is_interactive ) \
+        { \
+        int c = '*'; \
+        size_t n; \
+        for ( n = 0; n &lt; max_size &amp;&amp; \
+                 (c = getc( yyin )) != EOF &amp;&amp; c != '\n'; ++n ) \
+            buf[n] = (char) c; \
+        if ( c == '\n' ) \
+            buf[n++] = (char) c; \
+        if ( c == EOF &amp;&amp; ferror( yyin ) ) \
+            YY_FATAL_ERROR( &quot;input in flex scanner failed&quot; ); \
+        result = n; \
+        } \
+    else \
+        { \
+        errno=0; \
+        while ( (result = fread(buf, 1, max_size, yyin))==0 &amp;&amp; ferror(yyin)) \
+            { \
+            if( errno != EINTR) \
+                { \
+                YY_FATAL_ERROR( &quot;input in flex scanner failed&quot; ); \
+                break; \
+                } \
+            errno=0; \
+            clearerr(yyin); \
+            } \
+        }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write &quot;yyterminate();&quot; -
+ * we don't want an extra ';' after the &quot;return&quot; because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex \
+               (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
+               (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 \
+    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-&gt;yy_init )
+        {
+        yyg-&gt;yy_init = 1;
+
+#ifdef YY_USER_INIT
+        YY_USER_INIT;
+#endif
+
+        if ( ! yyg-&gt;yy_start )
+            yyg-&gt;yy_start = 1;  /* first start state */
+
+        if ( ! yyin )
+            yyin = stdin;
+
+        if ( ! yyout )
+            yyout = stdout;
+
+        if ( ! YY_CURRENT_BUFFER ) {
+            yyensure_buffer_stack (yyscanner);
+            YY_CURRENT_BUFFER_LVALUE =
+                yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+        }
+
+        yy_load_buffer_state(yyscanner );
+        }
+
+    while ( 1 )     /* loops until end-of-file is reached */
+        {
+        yy_cp = yyg-&gt;yy_c_buf_p;
+
+        /* Support of yytext. */
+        *yy_cp = yyg-&gt;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-&gt;yy_start;
+yy_match:
+        do
+            {
+            register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+            if ( yy_accept[yy_current_state] )
+                {
+                yyg-&gt;yy_last_accepting_state = yy_current_state;
+                yyg-&gt;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 &gt;= 443 )
+                    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 != 442 );
+        yy_cp = yyg-&gt;yy_last_accepting_cpos;
+        yy_current_state = yyg-&gt;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 &amp;&amp; yy_rule_can_match_eol[yy_act] )
+            {
+            yy_size_t yyl;
+            for ( yyl = 0; yyl &lt; 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-&gt;yy_hold_char;
+            yy_cp = yyg-&gt;yy_last_accepting_cpos;
+            yy_current_state = yyg-&gt;yy_last_accepting_state;
+            goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+{ return INVARIANT; }
+    YY_BREAK
+case 2:
+YY_RULE_SETUP
+{ return HIGH_PRECISION; }
+    YY_BREAK
+case 3:
+YY_RULE_SETUP
+{ return MEDIUM_PRECISION; }
+    YY_BREAK
+case 4:
+YY_RULE_SETUP
+{ return LOW_PRECISION; }
+    YY_BREAK
+case 5:
+YY_RULE_SETUP
+{ return PRECISION; }
+    YY_BREAK
+case 6:
+YY_RULE_SETUP
+{ return ATTRIBUTE; }
+    YY_BREAK
+case 7:
+YY_RULE_SETUP
+{ return CONST_QUAL; }
+    YY_BREAK
+case 8:
+YY_RULE_SETUP
+{ return UNIFORM; }
+    YY_BREAK
+case 9:
+YY_RULE_SETUP
+{ return VARYING; }
+    YY_BREAK
+case 10:
+YY_RULE_SETUP
+{ return BREAK; }
+    YY_BREAK
+case 11:
+YY_RULE_SETUP
+{ return CONTINUE; }
+    YY_BREAK
+case 12:
+YY_RULE_SETUP
+{ return DO; }
+    YY_BREAK
+case 13:
+YY_RULE_SETUP
+{ return FOR; }
+    YY_BREAK
+case 14:
+YY_RULE_SETUP
+{ return WHILE; }
+    YY_BREAK
+case 15:
+YY_RULE_SETUP
+{ return IF; }
+    YY_BREAK
+case 16:
+YY_RULE_SETUP
+{ return ELSE; }
+    YY_BREAK
+case 17:
+YY_RULE_SETUP
+{ return IN_QUAL; }
+    YY_BREAK
+case 18:
+YY_RULE_SETUP
+{ return OUT_QUAL; }
+    YY_BREAK
+case 19:
+YY_RULE_SETUP
+{ return INOUT_QUAL; }
+    YY_BREAK
+case 20:
+YY_RULE_SETUP
+{ return FLOAT_TYPE; }
+    YY_BREAK
+case 21:
+YY_RULE_SETUP
+{ return INT_TYPE; }
+    YY_BREAK
+case 22:
+YY_RULE_SETUP
+{ return VOID_TYPE; }
+    YY_BREAK
+case 23:
+YY_RULE_SETUP
+{ return BOOL_TYPE; }
+    YY_BREAK
+case 24:
+YY_RULE_SETUP
+{ yylval-&gt;lex.b = true;  return BOOLCONSTANT; }
+    YY_BREAK
+case 25:
+YY_RULE_SETUP
+{ yylval-&gt;lex.b = false; return BOOLCONSTANT; }
+    YY_BREAK
+case 26:
+YY_RULE_SETUP
+{ return DISCARD; }
+    YY_BREAK
+case 27:
+YY_RULE_SETUP
+{ return RETURN; }
+    YY_BREAK
+case 28:
+YY_RULE_SETUP
+{ return MATRIX2; }
+    YY_BREAK
+case 29:
+YY_RULE_SETUP
+{ return MATRIX3; }
+    YY_BREAK
+case 30:
+YY_RULE_SETUP
+{ return MATRIX4; }
+    YY_BREAK
+case 31:
+YY_RULE_SETUP
+{ return VEC2; }
+    YY_BREAK
+case 32:
+YY_RULE_SETUP
+{ return VEC3; }
+    YY_BREAK
+case 33:
+YY_RULE_SETUP
+{ return VEC4; }
+    YY_BREAK
+case 34:
+YY_RULE_SETUP
+{ return IVEC2; }
+    YY_BREAK
+case 35:
+YY_RULE_SETUP
+{ return IVEC3; }
+    YY_BREAK
+case 36:
+YY_RULE_SETUP
+{ return IVEC4; }
+    YY_BREAK
+case 37:
+YY_RULE_SETUP
+{ return BVEC2; }
+    YY_BREAK
+case 38:
+YY_RULE_SETUP
+{ return BVEC3; }
+    YY_BREAK
+case 39:
+YY_RULE_SETUP
+{ return BVEC4; }
+    YY_BREAK
+case 40:
+YY_RULE_SETUP
+{ return SAMPLER2D; }
+    YY_BREAK
+case 41:
+YY_RULE_SETUP
+{ return SAMPLERCUBE; }
+    YY_BREAK
+case 42:
+YY_RULE_SETUP
+{ return SAMPLER_EXTERNAL_OES; }
+    YY_BREAK
+case 43:
+YY_RULE_SETUP
+{ return SAMPLER2DRECT; }
+    YY_BREAK
+case 44:
+YY_RULE_SETUP
+{ return STRUCT; }
+    YY_BREAK
+case 45:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 46:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 47:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 48:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 49:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 50:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 51:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 52:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 53:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 54:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 55:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 56:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 57:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 58:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 59:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 60:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 61:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 62:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 63:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 64:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 65:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 66:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 67:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 68:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 69:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 70:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 71:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 72:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 73:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 74:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 75:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 76:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 77:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 78:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 79:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 80:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 81:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 82:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 83:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 84:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 85:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 86:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 87:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 88:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 89:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 90:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 91:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 92:
+YY_RULE_SETUP
+{ return reserved_word(yyscanner); }
+    YY_BREAK
+case 93:
+YY_RULE_SETUP
+{
+   yylval-&gt;lex.string = NewPoolTString(yytext); 
+   return check_type(yyscanner);
+}
+    YY_BREAK
+case 94:
+YY_RULE_SETUP
+{ return int_constant(yyscanner); }
+    YY_BREAK
+case 95:
+YY_RULE_SETUP
+{ return int_constant(yyscanner); }
+    YY_BREAK
+case 96:
+YY_RULE_SETUP
+{ return int_constant(yyscanner); }
+    YY_BREAK
+case 97:
+YY_RULE_SETUP
+{ return float_constant(yyscanner); }
+    YY_BREAK
+case 98:
+YY_RULE_SETUP
+{ return float_constant(yyscanner); }
+    YY_BREAK
+case 99:
+YY_RULE_SETUP
+{ return float_constant(yyscanner); }
+    YY_BREAK
+case 100:
+YY_RULE_SETUP
+{ return ADD_ASSIGN; }
+    YY_BREAK
+case 101:
+YY_RULE_SETUP
+{ return SUB_ASSIGN; }
+    YY_BREAK
+case 102:
+YY_RULE_SETUP
+{ return MUL_ASSIGN; }
+    YY_BREAK
+case 103:
+YY_RULE_SETUP
+{ return DIV_ASSIGN; }
+    YY_BREAK
+case 104:
+YY_RULE_SETUP
+{ return MOD_ASSIGN; }
+    YY_BREAK
+case 105:
+YY_RULE_SETUP
+{ return LEFT_ASSIGN; }
+    YY_BREAK
+case 106:
+YY_RULE_SETUP
+{ return RIGHT_ASSIGN; }
+    YY_BREAK
+case 107:
+YY_RULE_SETUP
+{ return AND_ASSIGN; }
+    YY_BREAK
+case 108:
+YY_RULE_SETUP
+{ return XOR_ASSIGN; }
+    YY_BREAK
+case 109:
+YY_RULE_SETUP
+{ return OR_ASSIGN; }
+    YY_BREAK
+case 110:
+YY_RULE_SETUP
+{ return INC_OP; }
+    YY_BREAK
+case 111:
+YY_RULE_SETUP
+{ return DEC_OP; }
+    YY_BREAK
+case 112:
+YY_RULE_SETUP
+{ return AND_OP; }
+    YY_BREAK
+case 113:
+YY_RULE_SETUP
+{ return OR_OP; }
+    YY_BREAK
+case 114:
+YY_RULE_SETUP
+{ return XOR_OP; }
+    YY_BREAK
+case 115:
+YY_RULE_SETUP
+{ return LE_OP; }
+    YY_BREAK
+case 116:
+YY_RULE_SETUP
+{ return GE_OP; }
+    YY_BREAK
+case 117:
+YY_RULE_SETUP
+{ return EQ_OP; }
+    YY_BREAK
+case 118:
+YY_RULE_SETUP
+{ return NE_OP; }
+    YY_BREAK
+case 119:
+YY_RULE_SETUP
+{ return LEFT_OP; }
+    YY_BREAK
+case 120:
+YY_RULE_SETUP
+{ return RIGHT_OP; }
+    YY_BREAK
+case 121:
+YY_RULE_SETUP
+{ return SEMICOLON; }
+    YY_BREAK
+case 122:
+YY_RULE_SETUP
+{ return LEFT_BRACE; }
+    YY_BREAK
+case 123:
+YY_RULE_SETUP
+{ return RIGHT_BRACE; }
+    YY_BREAK
+case 124:
+YY_RULE_SETUP
+{ return COMMA; }
+    YY_BREAK
+case 125:
+YY_RULE_SETUP
+{ return COLON; }
+    YY_BREAK
+case 126:
+YY_RULE_SETUP
+{ return EQUAL; }
+    YY_BREAK
+case 127:
+YY_RULE_SETUP
+{ return LEFT_PAREN; }
+    YY_BREAK
+case 128:
+YY_RULE_SETUP
+{ return RIGHT_PAREN; }
+    YY_BREAK
+case 129:
+YY_RULE_SETUP
+{ return LEFT_BRACKET; }
+    YY_BREAK
+case 130:
+YY_RULE_SETUP
+{ return RIGHT_BRACKET; }
+    YY_BREAK
+case 131:
+YY_RULE_SETUP
+{ return DOT; }
+    YY_BREAK
+case 132:
+YY_RULE_SETUP
+{ return BANG; }
+    YY_BREAK
+case 133:
+YY_RULE_SETUP
+{ return DASH; }
+    YY_BREAK
+case 134:
+YY_RULE_SETUP
+{ return TILDE; }
+    YY_BREAK
+case 135:
+YY_RULE_SETUP
+{ return PLUS; }
+    YY_BREAK
+case 136:
+YY_RULE_SETUP
+{ return STAR; }
+    YY_BREAK
+case 137:
+YY_RULE_SETUP
+{ return SLASH; }
+    YY_BREAK
+case 138:
+YY_RULE_SETUP
+{ return PERCENT; }
+    YY_BREAK
+case 139:
+YY_RULE_SETUP
+{ return LEFT_ANGLE; }
+    YY_BREAK
+case 140:
+YY_RULE_SETUP
+{ return RIGHT_ANGLE; }
+    YY_BREAK
+case 141:
+YY_RULE_SETUP
+{ return VERTICAL_BAR; }
+    YY_BREAK
+case 142:
+YY_RULE_SETUP
+{ return CARET; }
+    YY_BREAK
+case 143:
+YY_RULE_SETUP
+{ return AMPERSAND; }
+    YY_BREAK
+case 144:
+YY_RULE_SETUP
+{ return QUESTION; }
+    YY_BREAK
+case 145:
+/* rule 145 can match eol */
+YY_RULE_SETUP
+{ }
+    YY_BREAK
+case YY_STATE_EOF(INITIAL):
+{ yyterminate(); }
+    YY_BREAK
+case 146:
+YY_RULE_SETUP
+{ assert(false); return 0; }
+    YY_BREAK
+case 147:
+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-&gt;yytext_ptr) - 1;
+
+        /* Undo the effects of YY_DO_BEFORE_ACTION. */
+        *yy_cp = yyg-&gt;yy_hold_char;
+        YY_RESTORE_YY_MORE_OFFSET
+
+        if ( YY_CURRENT_BUFFER_LVALUE-&gt;yy_buffer_status == YY_BUFFER_NEW )
+            {
+            /* We're scanning a new file or input source.  It's
+             * possible that this happened because the user
+             * just pointed yyin at a new source and called
+             * yylex().  If so, then we have to assure
+             * consistency between YY_CURRENT_BUFFER and our
+             * globals.  Here is the right place to do so, because
+             * this is the first action (other than possibly a
+             * back-up) that will match for the new input source.
+             */
+            yyg-&gt;yy_n_chars = YY_CURRENT_BUFFER_LVALUE-&gt;yy_n_chars;
+            YY_CURRENT_BUFFER_LVALUE-&gt;yy_input_file = yyin;
+            YY_CURRENT_BUFFER_LVALUE-&gt;yy_buffer_status = YY_BUFFER_NORMAL;
+            }
+
+        /* Note that here we test for yy_c_buf_p &quot;&lt;=&quot; 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-&gt;yy_c_buf_p &lt;= &amp;YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars] )
+            { /* This was really a NUL. */
+            yy_state_type yy_next_state;
+
+            yyg-&gt;yy_c_buf_p = yyg-&gt;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-&gt;yytext_ptr + YY_MORE_ADJ;
+
+            if ( yy_next_state )
+                {
+                /* Consume the NUL. */
+                yy_cp = ++yyg-&gt;yy_c_buf_p;
+                yy_current_state = yy_next_state;
+                goto yy_match;
+                }
+
+            else
+                {
+                yy_cp = yyg-&gt;yy_last_accepting_cpos;
+                yy_current_state = yyg-&gt;yy_last_accepting_state;
+                goto yy_find_action;
+                }
+            }
+
+        else switch ( yy_get_next_buffer( yyscanner ) )
+            {
+            case EOB_ACT_END_OF_FILE:
+                {
+                yyg-&gt;yy_did_buffer_switch_on_eof = 0;
+
+                if ( yywrap(yyscanner ) )
+                    {
+                    /* Note: because we've taken care in
+                     * yy_get_next_buffer() to have set up
+                     * yytext, we can now set up
+                     * yy_c_buf_p so that if some total
+                     * hoser (like flex itself) wants to
+                     * call the scanner after we return the
+                     * YY_NULL, it'll still work - another
+                     * YY_NULL will get returned.
+                     */
+                    yyg-&gt;yy_c_buf_p = yyg-&gt;yytext_ptr + YY_MORE_ADJ;
+
+                    yy_act = YY_STATE_EOF(YY_START);
+                    goto do_action;
+                    }
+
+                else
+                    {
+                    if ( ! yyg-&gt;yy_did_buffer_switch_on_eof )
+                        YY_NEW_FILE;
+                    }
+                break;
+                }
+
+            case EOB_ACT_CONTINUE_SCAN:
+                yyg-&gt;yy_c_buf_p =
+                    yyg-&gt;yytext_ptr + yy_amount_of_matched_text;
+
+                yy_current_state = yy_get_previous_state( yyscanner );
+
+                yy_cp = yyg-&gt;yy_c_buf_p;
+                yy_bp = yyg-&gt;yytext_ptr + YY_MORE_ADJ;
+                goto yy_match;
+
+            case EOB_ACT_LAST_MATCH:
+                yyg-&gt;yy_c_buf_p =
+                &amp;YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars];
+
+                yy_current_state = yy_get_previous_state( yyscanner );
+
+                yy_cp = yyg-&gt;yy_c_buf_p;
+                yy_bp = yyg-&gt;yytext_ptr + YY_MORE_ADJ;
+                goto yy_find_action;
+            }
+        break;
+        }
+
+    default:
+        YY_FATAL_ERROR(
+            &quot;fatal flex scanner internal error--no action found&quot; );
+    } /* end of action switch */
+        } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *  EOB_ACT_LAST_MATCH -
+ *  EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *  EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    register char *dest = YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf;
+    register char *source = yyg-&gt;yytext_ptr;
+    register int number_to_move, i;
+    int ret_val;
+
+    if ( yyg-&gt;yy_c_buf_p &gt; &amp;YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars + 1] )
+        YY_FATAL_ERROR(
+        &quot;fatal flex scanner internal error--end of buffer missed&quot; );
+
+    if ( YY_CURRENT_BUFFER_LVALUE-&gt;yy_fill_buffer == 0 )
+        { /* Don't try to fill the buffer, so this is an EOF. */
+        if ( yyg-&gt;yy_c_buf_p - yyg-&gt;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-&gt;yy_c_buf_p - yyg-&gt;yytext_ptr) - 1;
+
+    for ( i = 0; i &lt; number_to_move; ++i )
+        *(dest++) = *(source++);
+
+    if ( YY_CURRENT_BUFFER_LVALUE-&gt;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-&gt;yy_n_chars = yyg-&gt;yy_n_chars = 0;
+
+    else
+        {
+            yy_size_t num_to_read =
+            YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_size - number_to_move - 1;
+
+        while ( num_to_read &lt;= 0 )
+            { /* Not enough room in the buffer - grow it. */
+
+            /* just a shorter name for the current buffer */
+            YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+            int yy_c_buf_p_offset =
+                (int) (yyg-&gt;yy_c_buf_p - b-&gt;yy_ch_buf);
+
+            if ( b-&gt;yy_is_our_buffer )
+                {
+                yy_size_t new_size = b-&gt;yy_buf_size * 2;
+
+                if ( new_size &lt;= 0 )
+                    b-&gt;yy_buf_size += b-&gt;yy_buf_size / 8;
+                else
+                    b-&gt;yy_buf_size *= 2;
+
+                b-&gt;yy_ch_buf = (char *)
+                    /* Include room in for 2 EOB chars. */
+                    yyrealloc((void *) b-&gt;yy_ch_buf,b-&gt;yy_buf_size + 2 ,yyscanner );
+                }
+            else
+                /* Can't grow it, we don't own it. */
+                b-&gt;yy_ch_buf = 0;
+
+            if ( ! b-&gt;yy_ch_buf )
+                YY_FATAL_ERROR(
+                &quot;fatal error - scanner input buffer overflow&quot; );
+
+            yyg-&gt;yy_c_buf_p = &amp;b-&gt;yy_ch_buf[yy_c_buf_p_offset];
+
+            num_to_read = YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_size -
+                        number_to_move - 1;
+
+            }
+
+        if ( num_to_read &gt; YY_READ_BUF_SIZE )
+            num_to_read = YY_READ_BUF_SIZE;
+
+        /* Read in more data. */
+        YY_INPUT( (&amp;YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[number_to_move]),
+            yyg-&gt;yy_n_chars, num_to_read );
+
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_n_chars = yyg-&gt;yy_n_chars;
+        }
+
+    if ( yyg-&gt;yy_n_chars == 0 )
+        {
+        if ( number_to_move == YY_MORE_ADJ )
+            {
+            ret_val = EOB_ACT_END_OF_FILE;
+            yyrestart(yyin  ,yyscanner);
+            }
+
+        else
+            {
+            ret_val = EOB_ACT_LAST_MATCH;
+            YY_CURRENT_BUFFER_LVALUE-&gt;yy_buffer_status =
+                YY_BUFFER_EOF_PENDING;
+            }
+        }
+
+    else
+        ret_val = EOB_ACT_CONTINUE_SCAN;
+
+    if ((yy_size_t) (yyg-&gt;yy_n_chars + number_to_move) &gt; YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_size) {
+        /* Extend the array by 50%, plus the number we really need. */
+        yy_size_t new_size = yyg-&gt;yy_n_chars + number_to_move + (yyg-&gt;yy_n_chars &gt;&gt; 1);
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf,new_size ,yyscanner );
+        if ( ! YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf )
+            YY_FATAL_ERROR( &quot;out of dynamic memory in yy_get_next_buffer()&quot; );
+    }
+
+    yyg-&gt;yy_n_chars += number_to_move;
+    YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+    YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+    yyg-&gt;yytext_ptr = &amp;YY_CURRENT_BUFFER_LVALUE-&gt;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-&gt;yy_start;
+
+    for ( yy_cp = yyg-&gt;yytext_ptr + YY_MORE_ADJ; yy_cp &lt; yyg-&gt;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-&gt;yy_last_accepting_state = yy_current_state;
+            yyg-&gt;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 &gt;= 443 )
+                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-&gt;yy_c_buf_p;
+
+    register YY_CHAR yy_c = 1;
+    if ( yy_accept[yy_current_state] )
+        {
+        yyg-&gt;yy_last_accepting_state = yy_current_state;
+        yyg-&gt;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 &gt;= 443 )
+            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 == 442);
+
+    (void)yyg;
+    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-&gt;yy_c_buf_p = yyg-&gt;yy_hold_char;
+
+    if ( *yyg-&gt;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-&gt;yy_c_buf_p &lt; &amp;YY_CURRENT_BUFFER_LVALUE-&gt;yy_ch_buf[yyg-&gt;yy_n_chars] )
+            /* This was really a NUL. */
+            *yyg-&gt;yy_c_buf_p = '\0';
+
+        else
+            { /* need more input */
+            yy_size_t offset = yyg-&gt;yy_c_buf_p - yyg-&gt;yytext_ptr;
+            ++yyg-&gt;yy_c_buf_p;
+
+            switch ( yy_get_next_buffer( yyscanner ) )
+                {
+                case EOB_ACT_LAST_MATCH:
+                    /* This happens because yy_g_n_b()
+                     * sees that we've accumulated a
+                     * token and flags that we need to
+                     * try matching the token before
+                     * proceeding.  But for input(),
+                     * there's no matching to consider.
+                     * So convert the EOB_ACT_LAST_MATCH
+                     * to EOB_ACT_END_OF_FILE.
+                     */
+
+                    /* Reset buffer status. */
+                    yyrestart(yyin ,yyscanner);
+
+                    /*FALLTHROUGH*/
+
+                case EOB_ACT_END_OF_FILE:
+                    {
+                    if ( yywrap(yyscanner ) )
+                        return EOF;
+
+                    if ( ! yyg-&gt;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-&gt;yy_c_buf_p = yyg-&gt;yytext_ptr + offset;
+                    break;
+                }
+            }
+        }
+
+    c = *(unsigned char *) yyg-&gt;yy_c_buf_p; /* cast for 8-bit char's */
+    *yyg-&gt;yy_c_buf_p = '\0';    /* preserve yytext */
+    yyg-&gt;yy_hold_char = *++yyg-&gt;yy_c_buf_p;
+
+    if ( c == '\n' )
+           
+    do{ yylineno++;
+        yycolumn=0;
+    }while(0)
+;
+
+    return c;
+}
+#endif  /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void yyrestart  (FILE * input_file , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    if ( ! YY_CURRENT_BUFFER ){
+        yyensure_buffer_stack (yyscanner);
+        YY_CURRENT_BUFFER_LVALUE =
+            yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+    }
+
+    yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+    yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* TODO. We should be able to replace this entire function body
+     * with
+     *      yypop_buffer_state();
+     *      yypush_buffer_state(new_buffer);
+     */
+    yyensure_buffer_stack (yyscanner);
+    if ( YY_CURRENT_BUFFER == new_buffer )
+        return;
+
+    if ( YY_CURRENT_BUFFER )
+        {
+        /* Flush out information for old buffer. */
+        *yyg-&gt;yy_c_buf_p = yyg-&gt;yy_hold_char;
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_pos = yyg-&gt;yy_c_buf_p;
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_n_chars = yyg-&gt;yy_n_chars;
+        }
+
+    YY_CURRENT_BUFFER_LVALUE = new_buffer;
+    yy_load_buffer_state(yyscanner );
+
+    /* We don't actually know whether we did this switch during
+     * EOF (yywrap()) processing, but the only time this flag
+     * is looked at is after yywrap() is called, so it's safe
+     * to go ahead and always set it.
+     */
+    yyg-&gt;yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyg-&gt;yy_n_chars = YY_CURRENT_BUFFER_LVALUE-&gt;yy_n_chars;
+    yyg-&gt;yytext_ptr = yyg-&gt;yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_pos;
+    yyin = YY_CURRENT_BUFFER_LVALUE-&gt;yy_input_file;
+    yyg-&gt;yy_hold_char = *yyg-&gt;yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size , yyscan_t yyscanner)
+{
+    YY_BUFFER_STATE b;
+    
+    b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+    if ( ! b )
+        YY_FATAL_ERROR( &quot;out of dynamic memory in yy_create_buffer()&quot; );
+
+    b-&gt;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-&gt;yy_ch_buf = (char *) yyalloc(b-&gt;yy_buf_size + 2 ,yyscanner );
+    if ( ! b-&gt;yy_ch_buf )
+        YY_FATAL_ERROR( &quot;out of dynamic memory in yy_create_buffer()&quot; );
+
+    b-&gt;yy_is_our_buffer = 1;
+
+    yy_init_buffer(b,file ,yyscanner);
+
+    return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+    void yy_delete_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    if ( ! b )
+        return;
+
+    if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+        YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+    if ( b-&gt;yy_is_our_buffer )
+        yyfree((void *) b-&gt;yy_ch_buf ,yyscanner );
+
+    yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file , yyscan_t yyscanner)
+
+{
+    int oerrno = errno;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    yy_flush_buffer(b ,yyscanner);
+
+    b-&gt;yy_input_file = file;
+    b-&gt;yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then yy_init_buffer was _probably_
+     * called from yyrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b-&gt;yy_bs_lineno = 1;
+        b-&gt;yy_bs_column = 0;
+    }
+
+        b-&gt;yy_is_interactive = 0;
+    
+    errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+    void yy_flush_buffer (YY_BUFFER_STATE  b , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    if ( ! b )
+        return;
+
+    b-&gt;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-&gt;yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+    b-&gt;yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+    b-&gt;yy_buf_pos = &amp;b-&gt;yy_ch_buf[0];
+
+    b-&gt;yy_at_bol = 1;
+    b-&gt;yy_buffer_status = YY_BUFFER_NEW;
+
+    if ( b == YY_CURRENT_BUFFER )
+        yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    if (new_buffer == NULL)
+        return;
+
+    yyensure_buffer_stack(yyscanner);
+
+    /* This block is copied from yy_switch_to_buffer. */
+    if ( YY_CURRENT_BUFFER )
+        {
+        /* Flush out information for old buffer. */
+        *yyg-&gt;yy_c_buf_p = yyg-&gt;yy_hold_char;
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_buf_pos = yyg-&gt;yy_c_buf_p;
+        YY_CURRENT_BUFFER_LVALUE-&gt;yy_n_chars = yyg-&gt;yy_n_chars;
+        }
+
+    /* Only push if top exists. Otherwise, replace top. */
+    if (YY_CURRENT_BUFFER)
+        yyg-&gt;yy_buffer_stack_top++;
+    YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+    /* copied from yy_switch_to_buffer. */
+    yy_load_buffer_state(yyscanner );
+    yyg-&gt;yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    if (!YY_CURRENT_BUFFER)
+        return;
+
+    yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+    YY_CURRENT_BUFFER_LVALUE = NULL;
+    if (yyg-&gt;yy_buffer_stack_top &gt; 0)
+        --yyg-&gt;yy_buffer_stack_top;
+
+    if (YY_CURRENT_BUFFER) {
+        yy_load_buffer_state(yyscanner );
+        yyg-&gt;yy_did_buffer_switch_on_eof = 1;
+    }
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+    yy_size_t num_to_alloc;
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    if (!yyg-&gt;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-&gt;yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+                                (num_to_alloc * sizeof(struct yy_buffer_state*)
+                                , yyscanner);
+        if ( ! yyg-&gt;yy_buffer_stack )
+            YY_FATAL_ERROR( &quot;out of dynamic memory in yyensure_buffer_stack()&quot; );
+                                  
+        memset(yyg-&gt;yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+                
+        yyg-&gt;yy_buffer_stack_max = num_to_alloc;
+        yyg-&gt;yy_buffer_stack_top = 0;
+        return;
+    }
+
+    if (yyg-&gt;yy_buffer_stack_top &gt;= (yyg-&gt;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-&gt;yy_buffer_stack_max + grow_size;
+        yyg-&gt;yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+                                (yyg-&gt;yy_buffer_stack,
+                                num_to_alloc * sizeof(struct yy_buffer_state*)
+                                , yyscanner);
+        if ( ! yyg-&gt;yy_buffer_stack )
+            YY_FATAL_ERROR( &quot;out of dynamic memory in yyensure_buffer_stack()&quot; );
+
+        /* zero only the new slots.*/
+        memset(yyg-&gt;yy_buffer_stack + yyg-&gt;yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+        yyg-&gt;yy_buffer_stack_max = num_to_alloc;
+    }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size , yyscan_t yyscanner)
+{
+    YY_BUFFER_STATE b;
+    
+    if ( size &lt; 2 ||
+         base[size-2] != YY_END_OF_BUFFER_CHAR ||
+         base[size-1] != YY_END_OF_BUFFER_CHAR )
+        /* They forgot to leave room for the EOB's. */
+        return 0;
+
+    b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+    if ( ! b )
+        YY_FATAL_ERROR( &quot;out of dynamic memory in yy_scan_buffer()&quot; );
+
+    b-&gt;yy_buf_size = size - 2;  /* &quot;- 2&quot; to take care of EOB's */
+    b-&gt;yy_buf_pos = b-&gt;yy_ch_buf = base;
+    b-&gt;yy_is_our_buffer = 0;
+    b-&gt;yy_input_file = 0;
+    b-&gt;yy_n_chars = b-&gt;yy_buf_size;
+    b-&gt;yy_is_interactive = 0;
+    b-&gt;yy_at_bol = 1;
+    b-&gt;yy_fill_buffer = 0;
+    b-&gt;yy_buffer_status = YY_BUFFER_NEW;
+
+    yy_switch_to_buffer(b ,yyscanner );
+
+    return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+    
+    return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes  (yyconst char * yybytes, yy_size_t  _yybytes_len , yyscan_t yyscanner)
+{
+    YY_BUFFER_STATE b;
+    char *buf;
+    yy_size_t n;
+    yy_size_t i;
+    
+    /* Get memory for full buffer, including space for trailing EOB's. */
+    n = _yybytes_len + 2;
+    buf = (char *) yyalloc(n ,yyscanner );
+    if ( ! buf )
+        YY_FATAL_ERROR( &quot;out of dynamic memory in yy_scan_bytes()&quot; );
+
+    for ( i = 0; i &lt; _yybytes_len; ++i )
+        buf[i] = yybytes[i];
+
+    buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+    b = yy_scan_buffer(buf,n ,yyscanner);
+    if ( ! b )
+        YY_FATAL_ERROR( &quot;bad buffer in yy_scan_bytes()&quot; );
+
+    /* It's okay to grow etc. this buffer, and we should throw it
+     * away when we're done.
+     */
+    b-&gt;yy_is_our_buffer = 1;
+
+    return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+        (void) fprintf( stderr, &quot;%s\n&quot;, 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-&gt;yy_hold_char; \
+        yyg-&gt;yy_c_buf_p = yytext + yyless_macro_arg; \
+        yyg-&gt;yy_hold_char = *yyg-&gt;yy_c_buf_p; \
+        *yyg-&gt;yy_c_buf_p = '\0'; \
+        yyleng = yyless_macro_arg; \
+        } \
+    while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    
+        if (! YY_CURRENT_BUFFER)
+            return 0;
+    
+    return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+yy_size_t yyget_leng  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE  user_defined , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int  line_number , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* lineno is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           YY_FATAL_ERROR( &quot;yyset_lineno called with no buffer&quot; );
+    
+    yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int  column_no , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+        /* column is only valid if an input buffer exists. */
+        if (! YY_CURRENT_BUFFER )
+           YY_FATAL_ERROR( &quot;yyset_column called with no buffer&quot; );
+    
+    yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE *  in_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyin = in_str ;
+}
+
+void yyset_out (FILE *  out_str , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yyout = out_str ;
+}
+
+int yyget_debug  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yy_flex_debug;
+}
+
+void yyset_debug (int  bdebug , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * yyget_lval  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylval;
+}
+
+void yyset_lval (YYSTYPE *  yylval_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    return yylloc;
+}
+    
+void yyset_lloc (YYLTYPE *  yylloc_param , yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    yylloc = yylloc_param;
+}
+    
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+
+    /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+    struct yyguts_t dummy_yyguts;
+
+    yyset_extra (yy_user_defined, &amp;dummy_yyguts);
+
+    if (ptr_yy_globals == NULL){
+        errno = EINVAL;
+        return 1;
+    }
+    
+    *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &amp;dummy_yyguts );
+    
+    if (*ptr_yy_globals == NULL){
+        errno = ENOMEM;
+        return 1;
+    }
+    
+    /* By setting to 0xAA, we expose bugs in
+    yy_init_globals. Leave at 0x00 for releases. */
+    memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+    
+    yyset_extra (yy_user_defined, *ptr_yy_globals);
+    
+    return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+    /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from yylex_destroy(), so don't allocate here.
+     */
+
+    yyg-&gt;yy_buffer_stack = 0;
+    yyg-&gt;yy_buffer_stack_top = 0;
+    yyg-&gt;yy_buffer_stack_max = 0;
+    yyg-&gt;yy_c_buf_p = (char *) 0;
+    yyg-&gt;yy_init = 0;
+    yyg-&gt;yy_start = 0;
+
+    yyg-&gt;yy_start_stack_ptr = 0;
+    yyg-&gt;yy_start_stack_depth = 0;
+    yyg-&gt;yy_start_stack =  NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    yyin = stdin;
+    yyout = stdout;
+#else
+    yyin = (FILE *) 0;
+    yyout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * yylex_init()
+     */
+    return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy  (yyscan_t yyscanner)
+{
+    struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+    /* Pop the buffer stack, destroying each element. */
+    while(YY_CURRENT_BUFFER){
+        yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+        YY_CURRENT_BUFFER_LVALUE = NULL;
+        yypop_buffer_state(yyscanner);
+    }
+
+    /* Destroy the stack itself. */
+    yyfree(yyg-&gt;yy_buffer_stack ,yyscanner);
+    yyg-&gt;yy_buffer_stack = NULL;
+
+    /* Destroy the start condition stack. */
+        yyfree(yyg-&gt;yy_start_stack ,yyscanner );
+        yyg-&gt;yy_start_stack = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * yylex() is called, initialization will occur. */
+    yy_init_globals( yyscanner);
+
+    /* Destroy the main struct (reentrant only). */
+    yyfree ( yyscanner , yyscanner );
+    yyscanner = NULL;
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+    register int i;
+    for ( i = 0; i &lt; n; ++i )
+        s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+    register int n;
+    for ( n = 0; s[n]; ++n )
+        ;
+
+    return n;
+}
+#endif
+
+void *yyalloc (yy_size_t  size , yyscan_t yyscanner)
+{
+    return (void *) malloc( size );
+}
+
+void *yyrealloc  (void * ptr, yy_size_t  size , yyscan_t yyscanner)
+{
+    /* The cast to (char *) in the following accommodates both
+     * implementations that use char* generic pointers, and those
+     * that use void* generic pointers.  It works with the latter
+     * because both ANSI C and C++ allow castless assignment from
+     * any pointer type to void*, and deal with argument conversions
+     * as though doing an assignment.
+     */
+    return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+    free( (char *) ptr );   /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME &quot;yytables&quot;
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
+    pp::Token token;
+    yyget_extra(yyscanner)-&gt;preprocessor.lex(&amp;token);
+    yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
+    if (len &lt; max_size)
+        memcpy(buf, token.text.c_str(), len);
+    yyset_column(token.location.file,yyscanner);
+    yyset_lineno(token.location.line,yyscanner);
+
+    if (len &gt;= max_size)
+        YY_FATAL_ERROR(&quot;Input buffer overflow&quot;);
+    else if (len &gt; 0)
+        buf[len++] = ' ';
+    return len;
+}
+
+int check_type(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+    
+    int token = IDENTIFIER;
+    TSymbol* symbol = yyextra-&gt;symbolTable.find(yytext);
+    if (symbol &amp;&amp; symbol-&gt;isVariable()) {
+        TVariable* variable = static_cast&lt;TVariable*&gt;(symbol);
+        if (variable-&gt;isUserType())
+            token = TYPE_NAME;
+    }
+    yylval-&gt;lex.symbol = symbol;
+    return token;
+}
+
+int reserved_word(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    yyextra-&gt;error(*yylloc, &quot;Illegal use of reserved word&quot;, yytext, &quot;&quot;);
+    yyextra-&gt;recover();
+    return 0;
+}
+
+void yyerror(YYLTYPE* lloc, TParseContext* context, const char* reason) {
+    context-&gt;error(*lloc, reason, yyget_text(context-&gt;scanner));
+    context-&gt;recover();
+}
+
+int int_constant(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    if (!atoi_clamp(yytext, &amp;(yylval-&gt;lex.i)))
+        yyextra-&gt;warning(*yylloc, &quot;Integer overflow&quot;, yytext, &quot;&quot;);
+    return INTCONSTANT;
+}
+
+int float_constant(yyscan_t yyscanner) {
+    struct yyguts_t* yyg = (struct yyguts_t*) yyscanner;
+
+    if (!atof_clamp(yytext, &amp;(yylval-&gt;lex.f)))
+        yyextra-&gt;warning(*yylloc, &quot;Float overflow&quot;, yytext, &quot;&quot;);
+    return FLOATCONSTANT;
+}
+
+int glslang_initialize(TParseContext* context) {
+    yyscan_t scanner = NULL;
+    if (yylex_init_extra(context,&amp;scanner))
+        return 1;
+
+    context-&gt;scanner = scanner;
+    return 0;
+}
+
+int glslang_finalize(TParseContext* context) {
+    yyscan_t scanner = context-&gt;scanner;
+    if (scanner == NULL) return 0;
+    
+    context-&gt;scanner = NULL;
+    yylex_destroy(scanner);
+
+    return 0;
+}
+
+int glslang_scan(size_t count, const char* const string[], const int length[],
+                 TParseContext* context) {
+    yyrestart(NULL,context-&gt;scanner);
+    yyset_column(0,context-&gt;scanner);
+    yyset_lineno(1,context-&gt;scanner);
+
+    // Initialize preprocessor.
+    if (!context-&gt;preprocessor.init(count, string, length))
+        return 1;
+    context-&gt;preprocessor.setMaxTokenLength(SH_MAX_TOKEN_LENGTH);
+
+    // Define extension macros.
+    const TExtensionBehavior&amp; extBehavior = context-&gt;extensionBehavior();
+    for (TExtensionBehavior::const_iterator iter = extBehavior.begin();
+         iter != extBehavior.end(); ++iter) {
+        context-&gt;preprocessor.predefineMacro(iter-&gt;first.c_str(), 1);
+    }
+    if (context-&gt;fragmentPrecisionHigh)
+        context-&gt;preprocessor.predefineMacro(&quot;GL_FRAGMENT_PRECISION_HIGH&quot;, 1);
+
+    return 0;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_lex.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_tabcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,4884 @@
</span><ins>+/* A Bison parser, made by GNU Bison 2.7.1.  */
+
+/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */
+
+/* Bison implementation for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2013 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 3 of the License, 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, see &lt;http://www.gnu.org/licenses/&gt;.  */
+
+/* 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 &quot;semantic&quot; 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 &quot;INFRINGES ON
+   USER NAME SPACE&quot; below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION &quot;2.7.1&quot;
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME &quot;yacc.c&quot;
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Push parsers.  */
+#define YYPUSH 0
+
+/* Pull parsers.  */
+#define YYPULL 1
+
+
+
+
+/* Copy the first part of user declarations.  */
+
+
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// This file is auto-generated by generate_parser.sh. DO NOT EDIT!
+
+// Ignore errors in auto-generated code.
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored &quot;-Wunused-function&quot;
+#pragma GCC diagnostic ignored &quot;-Wunused-variable&quot;
+#pragma GCC diagnostic ignored &quot;-Wswitch-enum&quot;
+#elif defined(_MSC_VER)
+#pragma warning(disable: 4065)
+#pragma warning(disable: 4189)
+#pragma warning(disable: 4505)
+#pragma warning(disable: 4701)
+#endif
+
+#include &quot;compiler/translator/SymbolTable.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#define YYENABLE_NLS 0
+
+#define YYLEX_PARAM context-&gt;scanner
+
+
+
+# ifndef YY_NULL
+#  if defined __cplusplus &amp;&amp; 201103L &lt;= __cplusplus
+#   define YY_NULL nullptr
+#  else
+#   define YY_NULL 0
+#  endif
+# endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* In a future release of Bison, this section will be replaced
+   by #include &quot;glslang_tab.h&quot;.  */
+#ifndef YY_YY_GLSLANG_TAB_H_INCLUDED
+# define YY_YY_GLSLANG_TAB_H_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+/* &quot;%code requires&quot; blocks.  */
+
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define SH_MAX_TOKEN_LENGTH 256  // WebGL spec.
+
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INVARIANT = 258,
+     HIGH_PRECISION = 259,
+     MEDIUM_PRECISION = 260,
+     LOW_PRECISION = 261,
+     PRECISION = 262,
+     ATTRIBUTE = 263,
+     CONST_QUAL = 264,
+     BOOL_TYPE = 265,
+     FLOAT_TYPE = 266,
+     INT_TYPE = 267,
+     BREAK = 268,
+     CONTINUE = 269,
+     DO = 270,
+     ELSE = 271,
+     FOR = 272,
+     IF = 273,
+     DISCARD = 274,
+     RETURN = 275,
+     BVEC2 = 276,
+     BVEC3 = 277,
+     BVEC4 = 278,
+     IVEC2 = 279,
+     IVEC3 = 280,
+     IVEC4 = 281,
+     VEC2 = 282,
+     VEC3 = 283,
+     VEC4 = 284,
+     MATRIX2 = 285,
+     MATRIX3 = 286,
+     MATRIX4 = 287,
+     IN_QUAL = 288,
+     OUT_QUAL = 289,
+     INOUT_QUAL = 290,
+     UNIFORM = 291,
+     VARYING = 292,
+     STRUCT = 293,
+     VOID_TYPE = 294,
+     WHILE = 295,
+     SAMPLER2D = 296,
+     SAMPLERCUBE = 297,
+     SAMPLER_EXTERNAL_OES = 298,
+     SAMPLER2DRECT = 299,
+     IDENTIFIER = 300,
+     TYPE_NAME = 301,
+     FLOATCONSTANT = 302,
+     INTCONSTANT = 303,
+     BOOLCONSTANT = 304,
+     LEFT_OP = 305,
+     RIGHT_OP = 306,
+     INC_OP = 307,
+     DEC_OP = 308,
+     LE_OP = 309,
+     GE_OP = 310,
+     EQ_OP = 311,
+     NE_OP = 312,
+     AND_OP = 313,
+     OR_OP = 314,
+     XOR_OP = 315,
+     MUL_ASSIGN = 316,
+     DIV_ASSIGN = 317,
+     ADD_ASSIGN = 318,
+     MOD_ASSIGN = 319,
+     LEFT_ASSIGN = 320,
+     RIGHT_ASSIGN = 321,
+     AND_ASSIGN = 322,
+     XOR_ASSIGN = 323,
+     OR_ASSIGN = 324,
+     SUB_ASSIGN = 325,
+     LEFT_PAREN = 326,
+     RIGHT_PAREN = 327,
+     LEFT_BRACKET = 328,
+     RIGHT_BRACKET = 329,
+     LEFT_BRACE = 330,
+     RIGHT_BRACE = 331,
+     DOT = 332,
+     COMMA = 333,
+     COLON = 334,
+     EQUAL = 335,
+     SEMICOLON = 336,
+     BANG = 337,
+     DASH = 338,
+     TILDE = 339,
+     PLUS = 340,
+     STAR = 341,
+     SLASH = 342,
+     PERCENT = 343,
+     LEFT_ANGLE = 344,
+     RIGHT_ANGLE = 345,
+     VERTICAL_BAR = 346,
+     CARET = 347,
+     AMPERSAND = 348,
+     QUESTION = 349
+   };
+#endif
+
+
+#if ! defined YYSTYPE &amp;&amp; ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+
+    struct {
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TPrecision precision;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TField* field;
+            TFieldList* fieldList;
+        };
+    } interm;
+
+
+
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE &amp;&amp; ! 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
+
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (TParseContext* context);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_GLSLANG_TAB_H_INCLUDED  */
+
+/* Copy the second part of user declarations.  */
+
+
+extern int yylex(YYSTYPE* yylval, YYLTYPE* yylloc, void* yyscanner);
+extern void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason);
+
+#define YYLLOC_DEFAULT(Current, Rhs, N)                      \
+  do {                                                       \
+      if (YYID(N)) {                                         \
+        (Current).first_file = YYRHSLOC(Rhs, 1).first_file;  \
+        (Current).first_line = YYRHSLOC(Rhs, 1).first_line;  \
+        (Current).last_file = YYRHSLOC(Rhs, N).last_file;    \
+        (Current).last_line = YYRHSLOC(Rhs, N).last_line;    \
+      }                                                      \
+      else {                                                 \
+        (Current).first_file = YYRHSLOC(Rhs, 0).last_file;   \
+        (Current).first_line = YYRHSLOC(Rhs, 0).last_line;   \
+        (Current).last_file = YYRHSLOC(Rhs, 0).last_file;    \
+        (Current).last_line = YYRHSLOC(Rhs, 0).last_line;    \
+      }                                                      \
+  } while (0)
+
+#define VERTEX_ONLY(S, L) {  \
+    if (context-&gt;shaderType != SH_VERTEX_SHADER) {  \
+        context-&gt;error(L, &quot; supported in vertex shaders only &quot;, S);  \
+        context-&gt;recover();  \
+    }  \
+}
+
+#define FRAG_ONLY(S, L) {  \
+    if (context-&gt;shaderType != SH_FRAGMENT_SHADER) {  \
+        context-&gt;error(L, &quot; supported in fragment shaders only &quot;, S);  \
+        context-&gt;recover();  \
+    }  \
+}
+
+
+
+#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 &amp;&amp; (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include &lt;stddef.h&gt; /* 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 defined YYENABLE_NLS &amp;&amp; YYENABLE_NLS
+#  if ENABLE_NLS
+#   include &lt;libintl.h&gt; /* INFRINGES ON USER NAME SPACE */
+#   define YY_(Msgid) dgettext (&quot;bison-runtime&quot;, Msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(Msgid) Msgid
+# endif
+#endif
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if (! defined __GNUC__ || __GNUC__ &lt; 2 \
+      || (__GNUC__ == 2 &amp;&amp; __GNUC_MINOR__ &lt; 5))
+#  define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+/* Suppress unused-variable warnings by &quot;using&quot; 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 yyi)
+#else
+static int
+YYID (yyi)
+    int yyi;
+#endif
+{
+  return yyi;
+}
+#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 &lt;alloca.h&gt; /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include &lt;malloc.h&gt; /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H &amp;&amp; ! defined EXIT_SUCCESS &amp;&amp; (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include &lt;stdlib.h&gt; /* INFRINGES ON USER NAME SPACE */
+      /* Use EXIT_SUCCESS as a witness for stdlib.h.  */
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
+#     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 &amp;&amp; ! defined EXIT_SUCCESS \
+       &amp;&amp; ! ((defined YYMALLOC || defined malloc) \
+         &amp;&amp; (defined YYFREE || defined free)))
+#   include &lt;stdlib.h&gt; /* INFRINGES ON USER NAME SPACE */
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc &amp;&amp; ! defined EXIT_SUCCESS &amp;&amp; (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 &amp;&amp; ! defined EXIT_SUCCESS &amp;&amp; (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 \
+     &amp;&amp; (! defined __cplusplus \
+     || (defined YYLTYPE_IS_TRIVIAL &amp;&amp; YYLTYPE_IS_TRIVIAL \
+         &amp;&amp; defined YYSTYPE_IS_TRIVIAL &amp;&amp; YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss_alloc;
+  YYSTYPE yyvs_alloc;
+  YYLTYPE yyls_alloc;
+};
+
+/* 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)
+
+# define YYCOPY_NEEDED 1
+
+/* 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_alloc, Stack)               \
+    do                                  \
+      {                                 \
+    YYSIZE_T yynewbytes;                        \
+    YYCOPY (&amp;yyptr-&gt;Stack_alloc, Stack, yysize);            \
+    Stack = &amp;yyptr-&gt;Stack_alloc;                    \
+    yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+    yyptr += yynewbytes / sizeof (*yyptr);              \
+      }                                 \
+    while (YYID (0))
+
+#endif
+
+#if defined YYCOPY_NEEDED &amp;&amp; YYCOPY_NEEDED
+/* Copy COUNT objects from SRC to DST.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ &amp;&amp; 1 &lt; __GNUC__
+#   define YYCOPY(Dst, Src, Count) \
+      __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
+#  else
+#   define YYCOPY(Dst, Src, Count)              \
+      do                                        \
+        {                                       \
+          YYSIZE_T yyi;                         \
+          for (yyi = 0; yyi &lt; (Count); yyi++)   \
+            (Dst)[yyi] = (Src)[yyi];            \
+        }                                       \
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  74
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   1490
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  95
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  84
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  202
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  307
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   349
+
+#define YYTRANSLATE(YYX)                        \
+  ((unsigned int) (YYX) &lt;= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,
+      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
+      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
+      85,    86,    87,    88,    89,    90,    91,    92,    93,    94
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint16 yyprhs[] =
+{
+       0,     0,     3,     5,     7,     9,    11,    13,    15,    17,
+      21,    23,    28,    30,    34,    37,    40,    42,    44,    46,
+      50,    53,    56,    59,    61,    64,    68,    71,    73,    75,
+      77,    80,    83,    86,    88,    90,    92,    94,    98,   102,
+     104,   108,   112,   114,   116,   120,   124,   128,   132,   134,
+     138,   142,   144,   146,   148,   150,   154,   156,   160,   162,
+     166,   168,   174,   176,   180,   182,   184,   186,   188,   190,
+     192,   196,   198,   201,   204,   209,   212,   214,   216,   219,
+     223,   227,   230,   236,   240,   243,   247,   250,   251,   253,
+     255,   257,   259,   261,   265,   271,   278,   284,   286,   289,
+     294,   300,   305,   308,   310,   313,   315,   317,   319,   322,
+     324,   326,   329,   331,   333,   335,   337,   342,   344,   346,
+     348,   350,   352,   354,   356,   358,   360,   362,   364,   366,
+     368,   370,   372,   374,   376,   378,   380,   382,   384,   386,
+     387,   394,   395,   401,   403,   406,   410,   412,   416,   418,
+     423,   425,   427,   429,   431,   433,   435,   437,   439,   441,
+     444,   445,   446,   452,   454,   456,   457,   460,   461,   464,
+     467,   471,   473,   476,   478,   481,   487,   491,   493,   495,
+     500,   501,   508,   509,   518,   519,   527,   529,   531,   533,
+     534,   537,   541,   544,   547,   550,   554,   557,   559,   562,
+     564,   566,   567
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int16 yyrhs[] =
+{
+     175,     0,    -1,    45,    -1,    46,    -1,    45,    -1,    97,
+      -1,    48,    -1,    47,    -1,    49,    -1,    71,   124,    72,
+      -1,    98,    -1,    99,    73,   100,    74,    -1,   101,    -1,
+      99,    77,    96,    -1,    99,    52,    -1,    99,    53,    -1,
+     124,    -1,   102,    -1,   103,    -1,    99,    77,   103,    -1,
+     105,    72,    -1,   104,    72,    -1,   106,    39,    -1,   106,
+      -1,   106,   122,    -1,   105,    78,   122,    -1,   107,    71,
+      -1,   142,    -1,    45,    -1,    99,    -1,    52,   108,    -1,
+      53,   108,    -1,   109,   108,    -1,    85,    -1,    83,    -1,
+      82,    -1,   108,    -1,   110,    86,   108,    -1,   110,    87,
+     108,    -1,   110,    -1,   111,    85,   110,    -1,   111,    83,
+     110,    -1,   111,    -1,   112,    -1,   113,    89,   112,    -1,
+     113,    90,   112,    -1,   113,    54,   112,    -1,   113,    55,
+     112,    -1,   113,    -1,   114,    56,   113,    -1,   114,    57,
+     113,    -1,   114,    -1,   115,    -1,   116,    -1,   117,    -1,
+     118,    58,   117,    -1,   118,    -1,   119,    60,   118,    -1,
+     119,    -1,   120,    59,   119,    -1,   120,    -1,   120,    94,
+     124,    79,   122,    -1,   121,    -1,   108,   123,   122,    -1,
+      80,    -1,    61,    -1,    62,    -1,    63,    -1,    70,    -1,
+     122,    -1,   124,    78,   122,    -1,   121,    -1,   127,    81,
+      -1,   135,    81,    -1,     7,   140,   141,    81,    -1,   128,
+      72,    -1,   130,    -1,   129,    -1,   130,   132,    -1,   129,
+      78,   132,    -1,   137,    45,    71,    -1,   139,    96,    -1,
+     139,    96,    73,   125,    74,    -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,    78,    96,    -1,   135,    78,    96,    73,    74,
+      -1,   135,    78,    96,    73,   125,    74,    -1,   135,    78,
+      96,    80,   150,    -1,   137,    -1,   137,    96,    -1,   137,
+      96,    73,    74,    -1,   137,    96,    73,   125,    74,    -1,
+     137,    96,    80,   150,    -1,     3,    45,    -1,   139,    -1,
+     138,   139,    -1,     9,    -1,     8,    -1,    37,    -1,     3,
+      37,    -1,    36,    -1,   141,    -1,   140,   141,    -1,     4,
+      -1,     5,    -1,     6,    -1,   142,    -1,   142,    73,   125,
+      74,    -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,    43,    -1,
+      44,    -1,   143,    -1,    46,    -1,    -1,    38,    96,    75,
+     144,   146,    76,    -1,    -1,    38,    75,   145,   146,    76,
+      -1,   147,    -1,   146,   147,    -1,   139,   148,    81,    -1,
+     149,    -1,   148,    78,   149,    -1,    96,    -1,    96,    73,
+     125,    74,    -1,   122,    -1,   126,    -1,   154,    -1,   153,
+      -1,   151,    -1,   163,    -1,   164,    -1,   167,    -1,   174,
+      -1,    75,    76,    -1,    -1,    -1,    75,   155,   162,   156,
+      76,    -1,   161,    -1,   153,    -1,    -1,   159,   161,    -1,
+      -1,   160,   153,    -1,    75,    76,    -1,    75,   162,    76,
+      -1,   152,    -1,   162,   152,    -1,    81,    -1,   124,    81,
+      -1,    18,    71,   124,    72,   165,    -1,   158,    16,   158,
+      -1,   158,    -1,   124,    -1,   137,    96,    80,   150,    -1,
+      -1,    40,    71,   168,   166,    72,   157,    -1,    -1,    15,
+     169,   158,    40,    71,   124,    72,    81,    -1,    -1,    17,
+      71,   170,   171,   173,    72,   157,    -1,   163,    -1,   151,
+      -1,   166,    -1,    -1,   172,    81,    -1,   172,    81,   124,
+      -1,    14,    81,    -1,    13,    81,    -1,    20,    81,    -1,
+      20,   124,    81,    -1,    19,    81,    -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,   180,   180,   181,   184,   239,   242,   247,   252,   257,
+     263,   266,   269,   272,   367,   377,   390,   398,   498,   501,
+     509,   512,   518,   522,   529,   535,   544,   552,   607,   617,
+     620,   630,   640,   661,   662,   663,   668,   669,   677,   688,
+     689,   697,   708,   712,   713,   723,   733,   743,   756,   757,
+     767,   780,   784,   788,   792,   793,   806,   807,   820,   821,
+     834,   835,   852,   853,   866,   867,   868,   869,   870,   874,
+     877,   888,   896,   923,   928,   942,   997,  1000,  1007,  1015,
+    1036,  1057,  1067,  1095,  1100,  1110,  1115,  1125,  1128,  1131,
+    1134,  1140,  1147,  1150,  1172,  1190,  1214,  1237,  1241,  1259,
+    1267,  1299,  1319,  1340,  1349,  1372,  1375,  1381,  1389,  1397,
+    1405,  1415,  1422,  1425,  1428,  1434,  1437,  1452,  1456,  1460,
+    1464,  1468,  1473,  1478,  1483,  1488,  1493,  1498,  1503,  1508,
+    1513,  1518,  1523,  1528,  1532,  1536,  1544,  1552,  1556,  1569,
+    1569,  1583,  1583,  1592,  1595,  1611,  1644,  1648,  1654,  1661,
+    1676,  1680,  1684,  1685,  1691,  1692,  1693,  1694,  1695,  1699,
+    1700,  1700,  1700,  1710,  1711,  1715,  1715,  1716,  1716,  1721,
+    1724,  1734,  1737,  1743,  1744,  1748,  1756,  1760,  1770,  1775,
+    1792,  1792,  1797,  1797,  1804,  1804,  1812,  1815,  1821,  1824,
+    1830,  1834,  1841,  1848,  1855,  1862,  1873,  1882,  1886,  1893,
+    1896,  1902,  1902
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || 0
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  &quot;$end&quot;, &quot;error&quot;, &quot;$undefined&quot;, &quot;INVARIANT&quot;, &quot;HIGH_PRECISION&quot;,
+  &quot;MEDIUM_PRECISION&quot;, &quot;LOW_PRECISION&quot;, &quot;PRECISION&quot;, &quot;ATTRIBUTE&quot;,
+  &quot;CONST_QUAL&quot;, &quot;BOOL_TYPE&quot;, &quot;FLOAT_TYPE&quot;, &quot;INT_TYPE&quot;, &quot;BREAK&quot;, &quot;CONTINUE&quot;,
+  &quot;DO&quot;, &quot;ELSE&quot;, &quot;FOR&quot;, &quot;IF&quot;, &quot;DISCARD&quot;, &quot;RETURN&quot;, &quot;BVEC2&quot;, &quot;BVEC3&quot;,
+  &quot;BVEC4&quot;, &quot;IVEC2&quot;, &quot;IVEC3&quot;, &quot;IVEC4&quot;, &quot;VEC2&quot;, &quot;VEC3&quot;, &quot;VEC4&quot;, &quot;MATRIX2&quot;,
+  &quot;MATRIX3&quot;, &quot;MATRIX4&quot;, &quot;IN_QUAL&quot;, &quot;OUT_QUAL&quot;, &quot;INOUT_QUAL&quot;, &quot;UNIFORM&quot;,
+  &quot;VARYING&quot;, &quot;STRUCT&quot;, &quot;VOID_TYPE&quot;, &quot;WHILE&quot;, &quot;SAMPLER2D&quot;, &quot;SAMPLERCUBE&quot;,
+  &quot;SAMPLER_EXTERNAL_OES&quot;, &quot;SAMPLER2DRECT&quot;, &quot;IDENTIFIER&quot;, &quot;TYPE_NAME&quot;,
+  &quot;FLOATCONSTANT&quot;, &quot;INTCONSTANT&quot;, &quot;BOOLCONSTANT&quot;, &quot;LEFT_OP&quot;, &quot;RIGHT_OP&quot;,
+  &quot;INC_OP&quot;, &quot;DEC_OP&quot;, &quot;LE_OP&quot;, &quot;GE_OP&quot;, &quot;EQ_OP&quot;, &quot;NE_OP&quot;, &quot;AND_OP&quot;,
+  &quot;OR_OP&quot;, &quot;XOR_OP&quot;, &quot;MUL_ASSIGN&quot;, &quot;DIV_ASSIGN&quot;, &quot;ADD_ASSIGN&quot;,
+  &quot;MOD_ASSIGN&quot;, &quot;LEFT_ASSIGN&quot;, &quot;RIGHT_ASSIGN&quot;, &quot;AND_ASSIGN&quot;, &quot;XOR_ASSIGN&quot;,
+  &quot;OR_ASSIGN&quot;, &quot;SUB_ASSIGN&quot;, &quot;LEFT_PAREN&quot;, &quot;RIGHT_PAREN&quot;, &quot;LEFT_BRACKET&quot;,
+  &quot;RIGHT_BRACKET&quot;, &quot;LEFT_BRACE&quot;, &quot;RIGHT_BRACE&quot;, &quot;DOT&quot;, &quot;COMMA&quot;, &quot;COLON&quot;,
+  &quot;EQUAL&quot;, &quot;SEMICOLON&quot;, &quot;BANG&quot;, &quot;DASH&quot;, &quot;TILDE&quot;, &quot;PLUS&quot;, &quot;STAR&quot;, &quot;SLASH&quot;,
+  &quot;PERCENT&quot;, &quot;LEFT_ANGLE&quot;, &quot;RIGHT_ANGLE&quot;, &quot;VERTICAL_BAR&quot;, &quot;CARET&quot;,
+  &quot;AMPERSAND&quot;, &quot;QUESTION&quot;, &quot;$accept&quot;, &quot;identifier&quot;, &quot;variable_identifier&quot;,
+  &quot;primary_expression&quot;, &quot;postfix_expression&quot;, &quot;integer_expression&quot;,
+  &quot;function_call&quot;, &quot;function_call_or_method&quot;, &quot;function_call_generic&quot;,
+  &quot;function_call_header_no_parameters&quot;,
+  &quot;function_call_header_with_parameters&quot;, &quot;function_call_header&quot;,
+  &quot;function_identifier&quot;, &quot;unary_expression&quot;, &quot;unary_operator&quot;,
+  &quot;multiplicative_expression&quot;, &quot;additive_expression&quot;, &quot;shift_expression&quot;,
+  &quot;relational_expression&quot;, &quot;equality_expression&quot;, &quot;and_expression&quot;,
+  &quot;exclusive_or_expression&quot;, &quot;inclusive_or_expression&quot;,
+  &quot;logical_and_expression&quot;, &quot;logical_xor_expression&quot;,
+  &quot;logical_or_expression&quot;, &quot;conditional_expression&quot;,
+  &quot;assignment_expression&quot;, &quot;assignment_operator&quot;, &quot;expression&quot;,
+  &quot;constant_expression&quot;, &quot;declaration&quot;, &quot;function_prototype&quot;,
+  &quot;function_declarator&quot;, &quot;function_header_with_parameters&quot;,
+  &quot;function_header&quot;, &quot;parameter_declarator&quot;, &quot;parameter_declaration&quot;,
+  &quot;parameter_qualifier&quot;, &quot;parameter_type_specifier&quot;,
+  &quot;init_declarator_list&quot;, &quot;single_declaration&quot;, &quot;fully_specified_type&quot;,
+  &quot;type_qualifier&quot;, &quot;type_specifier&quot;, &quot;precision_qualifier&quot;,
+  &quot;type_specifier_no_prec&quot;, &quot;type_specifier_nonarray&quot;, &quot;struct_specifier&quot;,
+  &quot;$@1&quot;, &quot;$@2&quot;, &quot;struct_declaration_list&quot;, &quot;struct_declaration&quot;,
+  &quot;struct_declarator_list&quot;, &quot;struct_declarator&quot;, &quot;initializer&quot;,
+  &quot;declaration_statement&quot;, &quot;statement&quot;, &quot;simple_statement&quot;,
+  &quot;compound_statement&quot;, &quot;$@3&quot;, &quot;$@4&quot;, &quot;statement_no_new_scope&quot;,
+  &quot;statement_with_scope&quot;, &quot;$@5&quot;, &quot;$@6&quot;, &quot;compound_statement_no_new_scope&quot;,
+  &quot;statement_list&quot;, &quot;expression_statement&quot;, &quot;selection_statement&quot;,
+  &quot;selection_rest_statement&quot;, &quot;condition&quot;, &quot;iteration_statement&quot;, &quot;$@7&quot;,
+  &quot;$@8&quot;, &quot;$@9&quot;, &quot;for_init_statement&quot;, &quot;conditionopt&quot;, &quot;for_rest_statement&quot;,
+  &quot;jump_statement&quot;, &quot;translation_unit&quot;, &quot;external_declaration&quot;,
+  &quot;function_definition&quot;, &quot;$@10&quot;, YY_NULL
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,
+     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,
+     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,
+     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,
+     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,
+     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
+     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
+     345,   346,   347,   348,   349
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    95,    96,    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,   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.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     1,     1,     1,     1,     1,     1,     1,     3,
+       1,     4,     1,     3,     2,     2,     1,     1,     1,     3,
+       2,     2,     2,     1,     2,     3,     2,     1,     1,     1,
+       2,     2,     2,     1,     1,     1,     1,     3,     3,     1,
+       3,     3,     1,     1,     3,     3,     3,     3,     1,     3,
+       3,     1,     1,     1,     1,     3,     1,     3,     1,     3,
+       1,     5,     1,     3,     1,     1,     1,     1,     1,     1,
+       3,     1,     2,     2,     4,     2,     1,     1,     2,     3,
+       3,     2,     5,     3,     2,     3,     2,     0,     1,     1,
+       1,     1,     1,     3,     5,     6,     5,     1,     2,     4,
+       5,     4,     2,     1,     2,     1,     1,     1,     2,     1,
+       1,     2,     1,     1,     1,     1,     4,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     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 reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       0,     0,   112,   113,   114,     0,   106,   105,   120,   118,
+     119,   124,   125,   126,   127,   128,   129,   121,   122,   123,
+     130,   131,   132,   109,   107,     0,   117,   133,   134,   135,
+     136,   138,   200,   201,     0,    77,    87,     0,    92,    97,
+       0,   103,     0,   110,   115,   137,     0,   197,   199,   108,
+     102,     0,     2,     3,   141,     0,    72,     0,    75,    87,
+       0,    88,    89,    90,    78,     0,    87,     0,    73,     2,
+      98,   104,   111,     0,     1,   198,     0,     0,   139,     0,
+     202,    79,    84,    86,    91,     0,    93,    80,     0,     0,
+       4,     7,     6,     8,     0,     0,     0,    35,    34,    33,
+       5,    10,    29,    12,    17,    18,     0,     0,    23,     0,
+      36,     0,    39,    42,    43,    48,    51,    52,    53,    54,
+      56,    58,    60,    71,     0,    27,    74,     0,     0,   143,
+       0,     0,     0,   182,     0,     0,     0,     0,     0,   160,
+     169,   173,    36,    62,    69,     0,   151,     0,   115,   154,
+     171,   153,   152,     0,   155,   156,   157,   158,    81,    83,
+      85,     0,     0,    99,     0,   150,   101,    30,    31,     0,
+      14,    15,     0,     0,    21,    20,     0,    22,    24,    26,
+      32,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   116,   148,     0,   146,   142,
+     144,     0,   193,   192,   167,   184,     0,   196,   194,     0,
+     180,   159,     0,    65,    66,    67,    68,    64,     0,     0,
+     174,   170,   172,     0,    94,     0,    96,   100,     9,     0,
+      16,     2,     3,    13,    19,    25,    37,    38,    41,    40,
+      46,    47,    44,    45,    49,    50,    55,    57,    59,     0,
+       0,     0,   145,   140,     0,     0,     0,     0,     0,   195,
+       0,   161,    63,    70,     0,    95,    11,     0,     0,   147,
+       0,   166,   168,   187,   186,   189,   167,   178,     0,     0,
+       0,    82,    61,   149,     0,   188,     0,     0,   177,   175,
+       0,     0,   162,     0,   190,     0,   167,     0,   164,   181,
+     163,     0,   191,   185,   176,   179,   183
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int16 yydefgoto[] =
+{
+      -1,   196,   100,   101,   102,   229,   103,   104,   105,   106,
+     107,   108,   109,   142,   111,   112,   113,   114,   115,   116,
+     117,   118,   119,   120,   121,   122,   143,   144,   218,   145,
+     124,   146,   147,    34,    35,    36,    82,    64,    65,    83,
+      37,    38,    39,    40,    41,    42,    43,   125,    45,   130,
+      77,   128,   129,   197,   198,   166,   149,   150,   151,   152,
+     212,   280,   299,   254,   255,   256,   300,   153,   154,   155,
+     289,   279,   156,   260,   204,   257,   275,   286,   287,   157,
+      46,    47,    48,    57
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -261
+static const yytype_int16 yypact[] =
+{
+    1327,   -20,  -261,  -261,  -261,   113,  -261,  -261,  -261,  -261,
+    -261,  -261,  -261,  -261,  -261,  -261,  -261,  -261,  -261,  -261,
+    -261,  -261,  -261,  -261,  -261,   -19,  -261,  -261,  -261,  -261,
+    -261,  -261,  -261,   -61,   -40,   -28,    75,    -7,  -261,    24,
+    1370,  -261,  1444,  -261,   -11,  -261,  1283,  -261,  -261,  -261,
+    -261,  1444,  -261,  -261,  -261,     6,  -261,    54,  -261,    88,
+      62,  -261,  -261,  -261,  -261,  1370,    59,    91,  -261,    36,
+     -50,  -261,  -261,  1051,  -261,  -261,    63,  1370,  -261,   293,
+    -261,  -261,  -261,  -261,    91,  1370,   -12,  -261,   856,  1051,
+      77,  -261,  -261,  -261,  1051,  1051,  1051,  -261,  -261,  -261,
+    -261,  -261,   -14,  -261,  -261,  -261,    84,   -44,  1116,    95,
+    -261,  1051,    53,     3,  -261,   -36,    89,  -261,  -261,  -261,
+     104,   107,   -45,  -261,    96,  -261,  -261,    91,  1184,  -261,
+    1370,    92,    93,  -261,    98,   101,    94,   921,   105,   102,
+    -261,  -261,    72,  -261,  -261,     9,  -261,   -61,    42,  -261,
+    -261,  -261,  -261,   376,  -261,  -261,  -261,  -261,   106,  -261,
+    -261,   986,  1051,  -261,   103,  -261,  -261,  -261,  -261,   -41,
+    -261,  -261,  1051,  1407,  -261,  -261,  1051,   110,  -261,  -261,
+    -261,  1051,  1051,  1051,  1051,  1051,  1051,  1051,  1051,  1051,
+    1051,  1051,  1051,  1051,  1051,  -261,   109,    23,  -261,  -261,
+    -261,  1227,  -261,  -261,   111,  -261,  1051,  -261,  -261,    25,
+    -261,  -261,   459,  -261,  -261,  -261,  -261,  -261,  1051,  1051,
+    -261,  -261,  -261,  1051,  -261,   114,  -261,  -261,  -261,   115,
+     112,    77,   116,  -261,  -261,  -261,  -261,  -261,    53,    53,
+    -261,  -261,  -261,  -261,   -36,   -36,  -261,   104,   107,    76,
+    1051,    91,  -261,  -261,   145,    54,   625,   708,    -6,  -261,
+     791,   459,  -261,  -261,   117,  -261,  -261,  1051,   120,  -261,
+     124,  -261,  -261,  -261,  -261,   791,   111,   112,    91,   125,
+     122,  -261,  -261,  -261,  1051,  -261,   118,   128,   180,  -261,
+     126,   542,  -261,    -5,  1051,   542,   111,  1051,  -261,  -261,
+    -261,   123,   112,  -261,  -261,  -261,  -261
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int16 yypgoto[] =
+{
+    -261,   -24,  -261,  -261,  -261,  -261,  -261,  -261,    34,  -261,
+    -261,  -261,  -261,    32,  -261,   -33,  -261,   -27,   -26,  -261,
+    -261,  -261,    14,    16,    18,  -261,   -66,   -87,  -261,   -92,
+     -85,    11,    12,  -261,  -261,  -261,   141,   150,   161,   143,
+    -261,  -261,  -231,     5,   -30,   224,   -18,     0,  -261,  -261,
+    -261,   100,  -119,  -261,   -17,  -156,   -25,  -145,  -243,  -261,
+    -261,  -261,   -64,  -260,  -261,  -261,   -52,    21,   -22,  -261,
+    -261,   -39,  -261,  -261,  -261,  -261,  -261,  -261,  -261,  -261,
+    -261,   191,  -261,  -261
+};
+
+/* 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 YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -166
+static const yytype_int16 yytable[] =
+{
+      44,    55,   165,   164,   169,    80,   226,   123,   222,   200,
+      71,    32,    33,   272,   193,    70,   288,    49,   185,   186,
+      56,   178,   123,    88,    72,    50,    52,    53,   175,   278,
+      89,   228,    58,    76,   176,    84,   304,   219,   170,   171,
+      44,    66,    44,    86,   278,   209,    44,   127,   298,   194,
+      59,    44,   298,   187,   188,    84,    54,    32,    33,   172,
+     158,   161,    73,   173,    66,    44,   276,   301,   162,    69,
+      53,    67,   219,   219,    68,   165,   225,    44,    60,   148,
+     230,    78,   200,     6,     7,    44,   183,   219,   184,   235,
+     220,    60,    61,    62,    63,   123,     6,     7,   127,    49,
+     127,   251,   249,   219,   252,   110,   259,    87,    61,    62,
+      63,    23,    24,   -27,   258,    73,   222,     2,     3,     4,
+     110,    61,    62,    63,    23,    24,   167,   168,    44,    79,
+      44,   262,   263,   213,   214,   215,    52,    53,   264,   181,
+     182,   305,   216,   180,   126,   189,   190,   -76,   -28,   233,
+     238,   239,   217,   148,   219,   267,   174,   123,   240,   241,
+     242,   243,   191,   244,   245,   268,   179,   192,   277,   205,
+     195,   127,   206,   202,   203,   207,   210,   227,   211,   223,
+     282,  -117,   250,   277,   123,   270,  -165,  -138,   265,   266,
+     219,   281,   293,   110,   283,   284,   296,   291,   292,   294,
+     295,    44,   302,   271,   306,   246,   297,   234,   247,    81,
+     165,   248,   148,   236,   237,   110,   110,   110,   110,   110,
+     110,   110,   110,   110,   110,   110,   159,    85,   160,    51,
+     201,   303,   273,   261,   269,   274,   285,    75,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,   290,   110,   148,   148,     0,     0,
+     148,   148,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,   148,     0,     0,     0,     0,
+       0,     0,   110,     0,     0,     0,     0,     0,     0,     0,
+       0,   148,     0,     0,     0,   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,    29,    30,    90,    31,
+      91,    92,    93,     0,     0,    94,    95,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,    96,     0,     0,     0,   139,   140,
+       0,     0,     0,     0,   141,    97,    98,     0,    99,     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,    29,
+      30,    90,    31,    91,    92,    93,     0,     0,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    96,     0,     0,
+       0,   139,   221,     0,     0,     0,     0,   141,    97,    98,
+       0,    99,     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,    29,    30,    90,    31,    91,    92,    93,     0,
+       0,    94,    95,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      96,     0,     0,     0,   139,     0,     0,     0,     0,     0,
+     141,    97,    98,     0,    99,     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,    29,    30,    90,    31,    91,
+      92,    93,     0,     0,    94,    95,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    96,     0,     0,     0,    79,     0,     0,
+       0,     0,     0,   141,    97,    98,     0,    99,     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,    29,    30,
+      90,    31,    91,    92,    93,     0,     0,    94,    95,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    96,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,   141,    97,    98,     0,
+      99,     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,    90,    31,    91,    92,    93,     0,     0,
+      94,    95,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    96,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,   141,
+      97,    98,     0,    99,    60,     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,    29,    30,    90,    31,    91,    92,
+      93,     0,     0,    94,    95,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    96,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,    97,    98,     0,    99,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      30,    90,    31,    91,    92,    93,     0,     0,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    96,     0,     0,
+     163,     8,     9,    10,     0,     0,     0,     0,    97,    98,
+       0,    99,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,     0,     0,    25,
+      26,     0,    27,    28,    29,    30,    90,    31,    91,    92,
+      93,     0,     0,    94,    95,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    96,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,   208,    97,    98,     0,    99,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,    26,     0,    27,    28,    29,
+      30,    90,    31,    91,    92,    93,     0,     0,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    96,     0,     0,
+     224,     8,     9,    10,     0,     0,     0,     0,    97,    98,
+       0,    99,    11,    12,    13,    14,    15,    16,    17,    18,
+      19,    20,    21,    22,     0,     0,     0,     0,     0,    25,
+      26,     0,    27,    28,    29,    30,    90,    31,    91,    92,
+      93,     0,     0,    94,    95,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    96,     0,     0,     0,     8,     9,    10,     0,
+       0,     0,     0,    97,    98,     0,    99,    11,    12,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,     0,
+       0,     0,     0,     0,    25,   177,     0,    27,    28,    29,
+      30,    90,    31,    91,    92,    93,     0,     0,    94,    95,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    96,     2,     3,
+       4,     0,     0,     0,     8,     9,    10,     0,    97,    98,
+       0,    99,     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,     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,
+     199,     0,     0,     0,     0,    25,    26,     0,    27,    28,
+      29,    30,     0,    31,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    74,     0,     0,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,     0,     0,     0,     0,
+       0,     0,     0,   253,    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,     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,   231,   232,     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,     0,
+      31
+};
+
+#define yypact_value_is_default(Yystate) \
+  (!!((Yystate) == (-261)))
+
+#define yytable_value_is_error(Yytable_value) \
+  YYID (0)
+
+static const yytype_int16 yycheck[] =
+{
+       0,    25,    89,    88,    96,    57,   162,    73,   153,   128,
+      40,     0,     0,   256,    59,    39,   276,    37,    54,    55,
+      81,   108,    88,    73,    42,    45,    45,    46,    72,   260,
+      80,    72,    72,    51,    78,    65,   296,    78,    52,    53,
+      40,    36,    42,    67,   275,   137,    46,    77,   291,    94,
+      78,    51,   295,    89,    90,    85,    75,    46,    46,    73,
+      84,    73,    73,    77,    59,    65,    72,    72,    80,    45,
+      46,    78,    78,    78,    81,   162,   161,    77,     3,    79,
+     172,    75,   201,     8,     9,    85,    83,    78,    85,   176,
+      81,     3,    33,    34,    35,   161,     8,     9,   128,    37,
+     130,    78,   194,    78,    81,    73,    81,    71,    33,    34,
+      35,    36,    37,    71,   206,    73,   261,     4,     5,     6,
+      88,    33,    34,    35,    36,    37,    94,    95,   128,    75,
+     130,   218,   219,    61,    62,    63,    45,    46,   223,    86,
+      87,   297,    70,   111,    81,    56,    57,    72,    71,   173,
+     183,   184,    80,   153,    78,    79,    72,   223,   185,   186,
+     187,   188,    58,   189,   190,   250,    71,    60,   260,    71,
+      74,   201,    71,    81,    81,    81,    71,    74,    76,    73,
+     267,    71,    73,   275,   250,    40,    75,    71,    74,    74,
+      78,    74,   284,   161,    74,    71,    16,    72,    76,    81,
+      72,   201,   294,   255,    81,   191,    80,   173,   192,    59,
+     297,   193,   212,   181,   182,   183,   184,   185,   186,   187,
+     188,   189,   190,   191,   192,   193,    85,    66,    85,     5,
+     130,   295,   257,   212,   251,   257,   275,    46,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,   278,   223,   256,   257,    -1,    -1,
+     260,   261,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,   275,    -1,    -1,    -1,    -1,
+      -1,    -1,   250,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   291,    -1,    -1,    -1,   295,     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,    -1,    -1,    52,    53,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,    75,    76,
+      -1,    -1,    -1,    -1,    81,    82,    83,    -1,    85,     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,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
+      -1,    75,    76,    -1,    -1,    -1,    -1,    81,    82,    83,
+      -1,    85,     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,    -1,
+      -1,    52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      71,    -1,    -1,    -1,    75,    -1,    -1,    -1,    -1,    -1,
+      81,    82,    83,    -1,    85,     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,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    71,    -1,    -1,    -1,    75,    -1,    -1,
+      -1,    -1,    -1,    81,    82,    83,    -1,    85,     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,    -1,    -1,    52,    53,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    81,    82,    83,    -1,
+      85,     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,    49,    -1,    -1,
+      52,    53,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    81,
+      82,    83,    -1,    85,     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,
+      49,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    82,    83,    -1,    85,    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,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
+      74,    10,    11,    12,    -1,    -1,    -1,    -1,    82,    83,
+      -1,    85,    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,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    81,    82,    83,    -1,    85,    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,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,    -1,    -1,
+      74,    10,    11,    12,    -1,    -1,    -1,    -1,    82,    83,
+      -1,    85,    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,    -1,    -1,    52,    53,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    71,    -1,    -1,    -1,    10,    11,    12,    -1,
+      -1,    -1,    -1,    82,    83,    -1,    85,    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,    -1,    -1,    52,    53,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    71,     4,     5,
+       6,    -1,    -1,    -1,    10,    11,    12,    -1,    82,    83,
+      -1,    85,    -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,
+      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,
+      76,    -1,    -1,    -1,    -1,    38,    39,    -1,    41,    42,
+      43,    44,    -1,    46,    -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,    76,    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,    -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,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    21,    22,    23,    24,    25,
+      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
+      -1,    -1,    38,    39,    -1,    41,    42,    43,    44,    -1,
+      46
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,     5,     6,     7,     8,     9,    10,    11,
+      12,    21,    22,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,    36,    37,    38,    39,    41,    42,    43,
+      44,    46,   126,   127,   128,   129,   130,   135,   136,   137,
+     138,   139,   140,   141,   142,   143,   175,   176,   177,    37,
+      45,   140,    45,    46,    75,    96,    81,   178,    72,    78,
+       3,    33,    34,    35,   132,   133,   138,    78,    81,    45,
+      96,   139,   141,    73,     0,   176,   141,   145,    75,    75,
+     161,   132,   131,   134,   139,   133,    96,    71,    73,    80,
+      45,    47,    48,    49,    52,    53,    71,    82,    83,    85,
+      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,    81,   139,   146,   147,
+     144,    13,    14,    15,    17,    18,    19,    20,    40,    75,
+      76,    81,   108,   121,   122,   124,   126,   127,   142,   151,
+     152,   153,   154,   162,   163,   164,   167,   174,    96,   131,
+     134,    73,    80,    74,   125,   122,   150,   108,   108,   124,
+      52,    53,    73,    77,    72,    72,    78,    39,   122,    71,
+     108,    86,    87,    83,    85,    54,    55,    89,    90,    56,
+      57,    58,    60,    59,    94,    74,    96,   148,   149,    76,
+     147,   146,    81,    81,   169,    71,    71,    81,    81,   124,
+      71,    76,   155,    61,    62,    63,    70,    80,   123,    78,
+      81,    76,   152,    73,    74,   125,   150,    74,    72,   100,
+     124,    45,    46,    96,   103,   122,   108,   108,   110,   110,
+     112,   112,   112,   112,   113,   113,   117,   118,   119,   124,
+      73,    78,    81,    76,   158,   159,   160,   170,   124,    81,
+     168,   162,   122,   122,   125,    74,    74,    79,   125,   149,
+      40,   161,   153,   151,   163,   171,    72,   124,   137,   166,
+     156,    74,   122,    74,    71,   166,   172,   173,   158,   165,
+      96,    72,    76,   124,    81,    72,    16,    80,   153,   157,
+     161,    72,   124,   157,   158,   150,    81
+};
+
+#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.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
+
+#define YYFAIL      goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)                                  \
+do                                                              \
+  if (yychar == YYEMPTY)                                        \
+    {                                                           \
+      yychar = (Token);                                         \
+      yylval = (Value);                                         \
+      YYPOPSTACK (yylen);                                       \
+      yystate = *yyssp;                                         \
+      goto yybackup;                                            \
+    }                                                           \
+  else                                                          \
+    {                                                           \
+      yyerror (&amp;yylloc, context, YY_(&quot;syntax error: cannot back up&quot;)); \
+      YYERROR;                          \
+    }                               \
+while (YYID (0))
+
+/* Error token number */
+#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).  */
+
+#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
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
+/* 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 defined YYLTYPE_IS_TRIVIAL &amp;&amp; YYLTYPE_IS_TRIVIAL
+
+/* Print *YYLOCP on YYO.  Private, do not rely on its existence. */
+
+__attribute__((__unused__))
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static unsigned
+yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp)
+#else
+static unsigned
+yy_location_print_ (yyo, yylocp)
+    FILE *yyo;
+    YYLTYPE const * const yylocp;
+#endif
+{
+  unsigned res = 0;
+  int end_col = 0 != yylocp-&gt;last_column ? yylocp-&gt;last_column - 1 : 0;
+  if (0 &lt;= yylocp-&gt;first_line)
+    {
+      res += fprintf (yyo, &quot;%d&quot;, yylocp-&gt;first_line);
+      if (0 &lt;= yylocp-&gt;first_column)
+        res += fprintf (yyo, &quot;.%d&quot;, yylocp-&gt;first_column);
+    }
+  if (0 &lt;= yylocp-&gt;last_line)
+    {
+      if (yylocp-&gt;first_line &lt; yylocp-&gt;last_line)
+        {
+          res += fprintf (yyo, &quot;-%d&quot;, yylocp-&gt;last_line);
+          if (0 &lt;= end_col)
+            res += fprintf (yyo, &quot;.%d&quot;, end_col);
+        }
+      else if (0 &lt;= end_col &amp;&amp; yylocp-&gt;first_column &lt; end_col)
+        res += fprintf (yyo, &quot;-%d&quot;, end_col);
+    }
+  return res;
+ }
+
+#  define YY_LOCATION_PRINT(File, Loc)          \
+  yy_location_print_ (File, &amp;(Loc))
+
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&amp;yylval, &amp;yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&amp;yylval, &amp;yylloc)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include &lt;stdio.h&gt; /* 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, &quot;%s &quot;, Title);                   \
+      yy_symbol_print (stderr,                        \
+          Type, Value, Location, context); \
+      YYFPRINTF (stderr, &quot;\n&quot;);                       \
+    }                                     \
+} 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, TParseContext* 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;
+    TParseContext* context;
+#endif
+{
+  FILE *yyo = yyoutput;
+  YYUSE (yyo);
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+  YYUSE (context);
+# ifdef YYPRINT
+  if (yytype &lt; YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  YYUSE (yytype);
+}
+
+
+/*--------------------------------.
+| 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, TParseContext* context)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, context)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    TParseContext* context;
+#endif
+{
+  if (yytype &lt; YYNTOKENS)
+    YYFPRINTF (yyoutput, &quot;token %s (&quot;, yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, &quot;nterm %s (&quot;, yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, &quot;: &quot;);
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, context);
+  YYFPRINTF (yyoutput, &quot;)&quot;);
+}
+
+/*------------------------------------------------------------------.
+| 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 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+    yytype_int16 *yybottom;
+    yytype_int16 *yytop;
+#endif
+{
+  YYFPRINTF (stderr, &quot;Stack now&quot;);
+  for (; yybottom &lt;= yytop; yybottom++)
+    {
+      int yybot = *yybottom;
+      YYFPRINTF (stderr, &quot; %d&quot;, yybot);
+    }
+  YYFPRINTF (stderr, &quot;\n&quot;);
+}
+
+# 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, TParseContext* context)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, context)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+    TParseContext* context;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, &quot;Reducing stack by rule %d (line %lu):\n&quot;,
+         yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi &lt; yynrhs; yyi++)
+    {
+      YYFPRINTF (stderr, &quot;   $%d = &quot;, yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+               &amp;(yyvsp[(yyi + 1) - (yynrhs)])
+               , &amp;(yylsp[(yyi + 1) - (yynrhs)])            , context);
+      YYFPRINTF (stderr, &quot;\n&quot;);
+    }
+}
+
+# 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 &lt; YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ &amp;&amp; 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__ &amp;&amp; defined _STRING_H &amp;&amp; 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 == '&quot;')
+    {
+      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 '&quot;':
+        if (yyres)
+          yyres[yyn] = '\0';
+        return yyn;
+      }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
+
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = YY_NULL;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the &quot;unexpected&quot;, one per
+     &quot;expected&quot;). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       &lt;http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html&gt;
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple &quot;syntax error&quot;.
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
+    {
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn &lt; 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim &lt; YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx &lt; yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx &amp;&amp; yyx != YYTERROR
+                &amp;&amp; !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                {
+                  YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
+                  if (! (yysize &lt;= yysize1
+                         &amp;&amp; yysize1 &lt;= YYSTACK_ALLOC_MAXIMUM))
+                    return 2;
+                  yysize = yysize1;
+                }
+              }
+        }
+    }
+
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_(&quot;syntax error&quot;));
+      YYCASE_(1, YY_(&quot;syntax error, unexpected %s&quot;));
+      YYCASE_(2, YY_(&quot;syntax error, unexpected %s, expecting %s&quot;));
+      YYCASE_(3, YY_(&quot;syntax error, unexpected %s, expecting %s or %s&quot;));
+      YYCASE_(4, YY_(&quot;syntax error, unexpected %s, expecting %s or %s or %s&quot;));
+      YYCASE_(5, YY_(&quot;syntax error, unexpected %s, expecting %s or %s or %s or %s&quot;));
+# undef YYCASE_
+    }
+
+  {
+    YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
+    if (! (yysize &lt;= yysize1 &amp;&amp; yysize1 &lt;= YYSTACK_ALLOC_MAXIMUM))
+      return 2;
+    yysize = yysize1;
+  }
+
+  if (*yymsg_alloc &lt; yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize &lt;= *yymsg_alloc
+             &amp;&amp; *yymsg_alloc &lt;= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
+    }
+
+  /* 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 &quot;%s&quot;s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' &amp;&amp; yyformat[1] == 's' &amp;&amp; yyi &lt; yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
+}
+#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, TParseContext* context)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, context)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+    TParseContext* context;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+  YYUSE (context);
+
+  if (!yymsg)
+    yymsg = &quot;Deleting&quot;;
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  YYUSE (yytype);
+}
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (TParseContext* context)
+#else
+int
+yyparse (context)
+    TParseContext* context;
+#endif
+#endif
+{
+/* The lookahead symbol.  */
+int yychar;
+
+
+#if defined __GNUC__ &amp;&amp; 407 &lt;= __GNUC__ * 100 + __GNUC_MINOR__
+/* Suppress an incorrect diagnostic about yylval being uninitialized.  */
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
+    _Pragma (&quot;GCC diagnostic push&quot;) \
+    _Pragma (&quot;GCC diagnostic ignored \&quot;-Wuninitialized\&quot;&quot;)\
+    _Pragma (&quot;GCC diagnostic ignored \&quot;-Wmaybe-uninitialized\&quot;&quot;)
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
+    _Pragma (&quot;GCC diagnostic pop&quot;)
+#else
+/* Default value used for initialization, for pacifying older GCCs
+   or non-GCC compilers.  */
+static YYSTYPE yyval_default;
+# define YY_INITIAL_VALUE(Value) = Value
+#endif
+static YYLTYPE yyloc_default
+# if defined YYLTYPE_IS_TRIVIAL &amp;&amp; YYLTYPE_IS_TRIVIAL
+  = { 1, 1, 1, 1 }
+# endif
+;
+#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+# define YY_IGNORE_MAYBE_UNINITIALIZED_END
+#endif
+#ifndef YY_INITIAL_VALUE
+# define YY_INITIAL_VALUE(Value) /* Nothing. */
+#endif
+
+/* The semantic value of the lookahead symbol.  */
+YYSTYPE yylval YY_INITIAL_VALUE(yyval_default);
+
+/* Location data for the lookahead symbol.  */
+YYLTYPE yylloc = yyloc_default;
+
+
+    /* Number of syntax errors so far.  */
+    int yynerrs;
+
+    int yystate;
+    /* Number of tokens to shift before error messages enabled.  */
+    int yyerrstatus;
+
+    /* The stacks and their tools:
+       `yyss': related to states.
+       `yyvs': related to semantic values.
+       `yyls': related to locations.
+
+       Refer to the stacks through separate pointers, to allow yyoverflow
+       to reallocate them elsewhere.  */
+
+    /* The state stack.  */
+    yytype_int16 yyssa[YYINITDEPTH];
+    yytype_int16 *yyss;
+    yytype_int16 *yyssp;
+
+    /* The semantic value stack.  */
+    YYSTYPE yyvsa[YYINITDEPTH];
+    YYSTYPE *yyvs;
+    YYSTYPE *yyvsp;
+
+    /* The location stack.  */
+    YYLTYPE yylsa[YYINITDEPTH];
+    YYLTYPE *yyls;
+    YYLTYPE *yylsp;
+
+    /* The locations where the error started and ended.  */
+    YYLTYPE yyerror_range[3];
+
+    YYSIZE_T yystacksize;
+
+  int yyn;
+  int yyresult;
+  /* Lookahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  yyssp = yyss = yyssa;
+  yyvsp = yyvs = yyvsa;
+  yylsp = yyls = yylsa;
+  yystacksize = YYINITDEPTH;
+
+  YYDPRINTF ((stderr, &quot;Starting parse\n&quot;));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY; /* Cause a token to be read.  */
+  yylsp[0] = yylloc;
+  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 &lt;= 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 &amp;'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_(&quot;memory exhausted&quot;),
+            &amp;yyss1, yysize * sizeof (*yyssp),
+            &amp;yyvs1, yysize * sizeof (*yyvsp),
+            &amp;yyls1, yysize * sizeof (*yylsp),
+            &amp;yystacksize);
+
+    yyls = yyls1;
+    yyss = yyss1;
+    yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH &lt;= yystacksize)
+    goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH &lt; yystacksize)
+    yystacksize = YYMAXDEPTH;
+
+      {
+    yytype_int16 *yyss1 = yyss;
+    union yyalloc *yyptr =
+      (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+    if (! yyptr)
+      goto yyexhaustedlab;
+    YYSTACK_RELOCATE (yyss_alloc, yyss);
+    YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+    YYSTACK_RELOCATE (yyls_alloc, 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, &quot;Stack size increased to %lu\n&quot;,
+          (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 &lt;= yyssp)
+    YYABORT;
+    }
+
+  YYDPRINTF ((stderr, &quot;Entering state %d\n&quot;, yystate));
+
+  if (yystate == YYFINAL)
+    YYACCEPT;
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     lookahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to lookahead token.  */
+  yyn = yypact[yystate];
+  if (yypact_value_is_default (yyn))
+    goto yydefault;
+
+  /* Not known =&gt; get a lookahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, &quot;Reading a token: &quot;));
+      yychar = YYLEX;
+    }
+
+  if (yychar &lt;= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, &quot;Now at end of input.\n&quot;));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT (&quot;Next token is&quot;, yytoken, &amp;yylval, &amp;yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn &lt; 0 || YYLAST &lt; yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn &lt;= 0)
+    {
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the lookahead token.  */
+  YY_SYMBOL_PRINT (&quot;Shifting&quot;, yytoken, &amp;yylval, &amp;yylloc);
+
+  /* Discard the shifted token.  */
+  yychar = YYEMPTY;
+
+  yystate = yyn;
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+  *++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 4:
+
+    {
+        // The symbol table search was done in the lexical phase
+        const TSymbol *symbol = (yyvsp[(1) - (1)].lex).symbol;
+        const TVariable *variable = 0;
+
+        if (!symbol)
+        {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;undeclared identifier&quot;, (yyvsp[(1) - (1)].lex).string-&gt;c_str());
+            context-&gt;recover();
+        }
+        else if (!symbol-&gt;isVariable())
+        {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;variable expected&quot;, (yyvsp[(1) - (1)].lex).string-&gt;c_str());
+            context-&gt;recover();
+        }
+        else
+        {
+            variable = static_cast&lt;const TVariable*&gt;(symbol);
+
+            if (context-&gt;symbolTable.findBuiltIn(variable-&gt;getName()) &amp;&amp;
+                !variable-&gt;getExtension().empty() &amp;&amp;
+                context-&gt;extensionErrorCheck((yylsp[(1) - (1)]), variable-&gt;getExtension()))
+            {
+                context-&gt;recover();
+            }
+        }
+
+        if (!variable)
+        {
+            TType type(EbtFloat, EbpUndefined);
+            TVariable *fakeVariable = new TVariable((yyvsp[(1) - (1)].lex).string, type);
+            context-&gt;symbolTable.insert(*fakeVariable);
+            variable = fakeVariable;
+        }
+
+        if (variable-&gt;getType().getQualifier() == EvqConst)
+        {
+            ConstantUnion* constArray = variable-&gt;getConstPointer();
+            TType t(variable-&gt;getType());
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(constArray, t, (yylsp[(1) - (1)]));
+        }
+        else
+        {
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addSymbol(variable-&gt;getUniqueId(),
+                                                 variable-&gt;getName(),
+                                                 variable-&gt;getType(),
+                                                 (yylsp[(1) - (1)]));
+        }
+
+        // don't delete $1.string, it's used by error recovery, and the pool
+        // pop will reclaim the memory
+    }
+    break;
+
+  case 5:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 6:
+
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setIConst((yyvsp[(1) - (1)].lex).i);
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 7:
+
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setFConst((yyvsp[(1) - (1)].lex).f);
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 8:
+
+    {
+        ConstantUnion *unionArray = new ConstantUnion[1];
+        unionArray-&gt;setBConst((yyvsp[(1) - (1)].lex).b);
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 9:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(2) - (3)].interm.intermTypedNode);
+    }
+    break;
+
+  case 10:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 11:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;addIndexExpression((yyvsp[(1) - (4)].interm.intermTypedNode), (yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode));
+    }
+    break;
+
+  case 12:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 13:
+
+    {
+        if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;isArray()) {
+            context-&gt;error((yylsp[(3) - (3)]), &quot;cannot apply dot operator to an array&quot;, &quot;.&quot;);
+            context-&gt;recover();
+        }
+
+        if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;isVector()) {
+            TVectorFields fields;
+            if (! context-&gt;parseVectorFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getNominalSize(), fields, (yylsp[(3) - (3)]))) {
+                fields.num = 1;
+                fields.offsets[0] = 0;
+                context-&gt;recover();
+            }
+
+            if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getType().getQualifier() == EvqConst) { // constant folding for vector fields
+                (yyval.interm.intermTypedNode) = context-&gt;addConstVectorNode(fields, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(3) - (3)]));
+                if ((yyval.interm.intermTypedNode) == 0) {
+                    context-&gt;recover();
+                    (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+                }
+                else
+                    (yyval.interm.intermTypedNode)-&gt;setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getPrecision(), EvqConst, (int) (*(yyvsp[(3) - (3)].lex).string).size()));
+            } else {
+                TString vectorString = *(yyvsp[(3) - (3)].lex).string;
+                TIntermTyped* index = context-&gt;intermediate.addSwizzle(fields, (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context-&gt;intermediate.addIndex(EOpVectorSwizzle, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
+                (yyval.interm.intermTypedNode)-&gt;setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getPrecision(), EvqTemporary, (int) vectorString.size()));
+            }
+        } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;isMatrix()) {
+            TMatrixFields fields;
+            if (! context-&gt;parseMatrixFields(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getNominalSize(), fields, (yylsp[(3) - (3)]))) {
+                fields.wholeRow = false;
+                fields.wholeCol = false;
+                fields.row = 0;
+                fields.col = 0;
+                context-&gt;recover();
+            }
+
+            if (fields.wholeRow || fields.wholeCol) {
+                context-&gt;error((yylsp[(2) - (3)]), &quot; non-scalar fields not implemented yet&quot;, &quot;.&quot;);
+                context-&gt;recover();
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setIConst(0);
+                TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context-&gt;intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
+                (yyval.interm.intermTypedNode)-&gt;setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getPrecision(),EvqTemporary, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getNominalSize()));
+            } else {
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setIConst(fields.col * (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getNominalSize() + fields.row);
+                TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtInt, EbpUndefined, EvqConst), (yylsp[(3) - (3)]));
+                (yyval.interm.intermTypedNode) = context-&gt;intermediate.addIndex(EOpIndexDirect, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
+                (yyval.interm.intermTypedNode)-&gt;setType(TType((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getBasicType(), (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getPrecision()));
+            }
+        } else if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getBasicType() == EbtStruct) {
+            bool fieldFound = false;
+            const TFieldList&amp; fields = (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getType().getStruct()-&gt;fields();
+            unsigned int i;
+            for (i = 0; i &lt; fields.size(); ++i) {
+                if (fields[i]-&gt;name() == *(yyvsp[(3) - (3)].lex).string) {
+                    fieldFound = true;
+                    break;
+                }
+            }
+            if (fieldFound) {
+                if ((yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getType().getQualifier() == EvqConst) {
+                    (yyval.interm.intermTypedNode) = context-&gt;addConstStruct(*(yyvsp[(3) - (3)].lex).string, (yyvsp[(1) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
+                    if ((yyval.interm.intermTypedNode) == 0) {
+                        context-&gt;recover();
+                        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+                    }
+                    else {
+                        (yyval.interm.intermTypedNode)-&gt;setType(*fields[i]-&gt;type());
+                        // change the qualifier of the return type, not of the structure field
+                        // as the structure definition is shared between various structures.
+                        (yyval.interm.intermTypedNode)-&gt;getTypePointer()-&gt;setQualifier(EvqConst);
+                    }
+                } else {
+                    ConstantUnion *unionArray = new ConstantUnion[1];
+                    unionArray-&gt;setIConst(i);
+                    TIntermTyped* index = context-&gt;intermediate.addConstantUnion(unionArray, *fields[i]-&gt;type(), (yylsp[(3) - (3)]));
+                    (yyval.interm.intermTypedNode) = context-&gt;intermediate.addIndex(EOpIndexDirectStruct, (yyvsp[(1) - (3)].interm.intermTypedNode), index, (yylsp[(2) - (3)]));
+                    (yyval.interm.intermTypedNode)-&gt;setType(*fields[i]-&gt;type());
+                }
+            } else {
+                context-&gt;error((yylsp[(2) - (3)]), &quot; no such field in structure&quot;, (yyvsp[(3) - (3)].lex).string-&gt;c_str());
+                context-&gt;recover();
+                (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+            }
+        } else {
+            context-&gt;error((yylsp[(2) - (3)]), &quot; field selection requires structure, vector, or matrix on left hand side&quot;, (yyvsp[(3) - (3)].lex).string-&gt;c_str());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+        // don't delete $3.string, it's from the pool
+    }
+    break;
+
+  case 14:
+
+    {
+        if (context-&gt;lValueErrorCheck((yylsp[(2) - (2)]), &quot;++&quot;, (yyvsp[(1) - (2)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;unaryOpError((yylsp[(2) - (2)]), &quot;++&quot;, (yyvsp[(1) - (2)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 15:
+
+    {
+        if (context-&gt;lValueErrorCheck((yylsp[(2) - (2)]), &quot;--&quot;, (yyvsp[(1) - (2)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yylsp[(2) - (2)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;unaryOpError((yylsp[(2) - (2)]), &quot;--&quot;, (yyvsp[(1) - (2)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 16:
+
+    {
+        if (context-&gt;integerErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode), &quot;[]&quot;))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 17:
+
+    {
+        TFunction* fnCall = (yyvsp[(1) - (1)].interm).function;
+        TOperator op = fnCall-&gt;getBuiltInOp();
+
+        if (op != EOpNull)
+        {
+            //
+            // Then this should be a constructor.
+            // Don't go through the symbol table for constructors.
+            // Their parameters will be verified algorithmically.
+            //
+            TType type(EbtVoid, EbpUndefined);  // use this to get the type back
+            if (context-&gt;constructorErrorCheck((yylsp[(1) - (1)]), (yyvsp[(1) - (1)].interm).intermNode, *fnCall, op, &amp;type)) {
+                (yyval.interm.intermTypedNode) = 0;
+            } else {
+                //
+                // It's a constructor, of type 'type'.
+                //
+                (yyval.interm.intermTypedNode) = context-&gt;addConstructor((yyvsp[(1) - (1)].interm).intermNode, &amp;type, op, fnCall, (yylsp[(1) - (1)]));
+            }
+
+            if ((yyval.interm.intermTypedNode) == 0) {
+                context-&gt;recover();
+                (yyval.interm.intermTypedNode) = context-&gt;intermediate.setAggregateOperator(0, op, (yylsp[(1) - (1)]));
+            }
+            (yyval.interm.intermTypedNode)-&gt;setType(type);
+        } else {
+            //
+            // Not a constructor.  Find it in the symbol table.
+            //
+            const TFunction* fnCandidate;
+            bool builtIn;
+            fnCandidate = context-&gt;findFunction((yylsp[(1) - (1)]), fnCall, &amp;builtIn);
+            if (fnCandidate) {
+                //
+                // A declared function.
+                //
+                if (builtIn &amp;&amp; !fnCandidate-&gt;getExtension().empty() &amp;&amp;
+                    context-&gt;extensionErrorCheck((yylsp[(1) - (1)]), fnCandidate-&gt;getExtension())) {
+                    context-&gt;recover();
+                }
+                op = fnCandidate-&gt;getBuiltInOp();
+                if (builtIn &amp;&amp; op != EOpNull) {
+                    //
+                    // A function call mapped to a built-in operation.
+                    //
+                    if (fnCandidate-&gt;getParamCount() == 1) {
+                        //
+                        // Treat it like a built-in unary operator.
+                        //
+                        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, (yylsp[(1) - (1)]), context-&gt;symbolTable);
+                        if ((yyval.interm.intermTypedNode) == 0)  {
+                            std::stringstream extraInfoStream;
+                            extraInfoStream &lt;&lt; &quot;built in unary operator function.  Type: &quot; &lt;&lt; static_cast&lt;TIntermTyped*&gt;((yyvsp[(1) - (1)].interm).intermNode)-&gt;getCompleteString();
+                            std::string extraInfo = extraInfoStream.str();
+                            context-&gt;error((yyvsp[(1) - (1)].interm).intermNode-&gt;getLine(), &quot; wrong operand type&quot;, &quot;Internal Error&quot;, extraInfo.c_str());
+                            YYERROR;
+                        }
+                    } else {
+                        (yyval.interm.intermTypedNode) = context-&gt;intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, op, (yylsp[(1) - (1)]));
+                    }
+                } else {
+                    // This is a real function call
+
+                    (yyval.interm.intermTypedNode) = context-&gt;intermediate.setAggregateOperator((yyvsp[(1) - (1)].interm).intermAggregate, EOpFunctionCall, (yylsp[(1) - (1)]));
+                    (yyval.interm.intermTypedNode)-&gt;setType(fnCandidate-&gt;getReturnType());
+
+                    // this is how we know whether the given function is a builtIn function or a user defined function
+                    // if builtIn == false, it's a userDefined -&gt; could be an overloaded builtIn function also
+                    // if builtIn == true, it's definitely a builtIn function with EOpNull
+                    if (!builtIn)
+                        (yyval.interm.intermTypedNode)-&gt;getAsAggregate()-&gt;setUserDefined();
+                    (yyval.interm.intermTypedNode)-&gt;getAsAggregate()-&gt;setName(fnCandidate-&gt;getMangledName());
+
+                    TQualifier qual;
+                    for (size_t i = 0; i &lt; fnCandidate-&gt;getParamCount(); ++i) {
+                        qual = fnCandidate-&gt;getParam(i).type-&gt;getQualifier();
+                        if (qual == EvqOut || qual == EvqInOut) {
+                            if (context-&gt;lValueErrorCheck((yyval.interm.intermTypedNode)-&gt;getLine(), &quot;assign&quot;, (yyval.interm.intermTypedNode)-&gt;getAsAggregate()-&gt;getSequence()[i]-&gt;getAsTyped())) {
+                                context-&gt;error((yyvsp[(1) - (1)].interm).intermNode-&gt;getLine(), &quot;Constant value cannot be passed for 'out' or 'inout' parameters.&quot;, &quot;Error&quot;);
+                                context-&gt;recover();
+                            }
+                        }
+                    }
+                }
+                (yyval.interm.intermTypedNode)-&gt;setType(fnCandidate-&gt;getReturnType());
+            } else {
+                // error message was put out by PaFindFunction()
+                // Put on a dummy node for error recovery
+                ConstantUnion *unionArray = new ConstantUnion[1];
+                unionArray-&gt;setFConst(0.0f);
+                (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtFloat, EbpUndefined, EvqConst), (yylsp[(1) - (1)]));
+                context-&gt;recover();
+            }
+        }
+        delete fnCall;
+    }
+    break;
+
+  case 18:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (1)].interm);
+    }
+    break;
+
+  case 19:
+
+    {
+        context-&gt;error((yylsp[(3) - (3)]), &quot;methods are not supported&quot;, &quot;&quot;);
+        context-&gt;recover();
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+    }
+    break;
+
+  case 20:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (2)].interm);
+    }
+    break;
+
+  case 21:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (2)].interm);
+    }
+    break;
+
+  case 22:
+
+    {
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+        (yyval.interm).intermNode = 0;
+    }
+    break;
+
+  case 23:
+
+    {
+        (yyval.interm).function = (yyvsp[(1) - (1)].interm.function);
+        (yyval.interm).intermNode = 0;
+    }
+    break;
+
+  case 24:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(2) - (2)].interm.intermTypedNode)-&gt;getType()) };
+        (yyvsp[(1) - (2)].interm.function)-&gt;addParameter(param);
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+        (yyval.interm).intermNode = (yyvsp[(2) - (2)].interm.intermTypedNode);
+    }
+    break;
+
+  case 25:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getType()) };
+        (yyvsp[(1) - (3)].interm).function-&gt;addParameter(param);
+        (yyval.interm).function = (yyvsp[(1) - (3)].interm).function;
+        (yyval.interm).intermNode = context-&gt;intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
+    }
+    break;
+
+  case 26:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+    }
+    break;
+
+  case 27:
+
+    {
+        //
+        // Constructor
+        //
+        TOperator op = EOpNull;
+        if ((yyvsp[(1) - (1)].interm.type).userDef) {
+            op = EOpConstructStruct;
+        } else {
+            switch ((yyvsp[(1) - (1)].interm.type).type) {
+            case EbtFloat:
+                if ((yyvsp[(1) - (1)].interm.type).matrix) {
+                    switch((yyvsp[(1) - (1)].interm.type).size) {
+                    case 2: op = EOpConstructMat2;  break;
+                    case 3: op = EOpConstructMat3;  break;
+                    case 4: op = EOpConstructMat4;  break;
+                    }
+                } else {
+                    switch((yyvsp[(1) - (1)].interm.type).size) {
+                    case 1: op = EOpConstructFloat; break;
+                    case 2: op = EOpConstructVec2;  break;
+                    case 3: op = EOpConstructVec3;  break;
+                    case 4: op = EOpConstructVec4;  break;
+                    }
+                }
+                break;
+            case EbtInt:
+                switch((yyvsp[(1) - (1)].interm.type).size) {
+                case 1: op = EOpConstructInt;   break;
+                case 2: op = EOpConstructIVec2; break;
+                case 3: op = EOpConstructIVec3; break;
+                case 4: op = EOpConstructIVec4; break;
+                }
+                break;
+            case EbtBool:
+                switch((yyvsp[(1) - (1)].interm.type).size) {
+                case 1: op = EOpConstructBool;  break;
+                case 2: op = EOpConstructBVec2; break;
+                case 3: op = EOpConstructBVec3; break;
+                case 4: op = EOpConstructBVec4; break;
+                }
+                break;
+            default: break;
+            }
+            if (op == EOpNull) {
+                context-&gt;error((yylsp[(1) - (1)]), &quot;cannot construct this type&quot;, getBasicString((yyvsp[(1) - (1)].interm.type).type));
+                context-&gt;recover();
+                (yyvsp[(1) - (1)].interm.type).type = EbtFloat;
+                op = EOpConstructFloat;
+            }
+        }
+        TString tempString;
+        TType type((yyvsp[(1) - (1)].interm.type));
+        TFunction *function = new TFunction(&amp;tempString, type, op);
+        (yyval.interm.function) = function;
+    }
+    break;
+
+  case 28:
+
+    {
+        if (context-&gt;reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
+            context-&gt;recover();
+        TType type(EbtVoid, EbpUndefined);
+        TFunction *function = new TFunction((yyvsp[(1) - (1)].lex).string, type);
+        (yyval.interm.function) = function;
+    }
+    break;
+
+  case 29:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 30:
+
+    {
+        if (context-&gt;lValueErrorCheck((yylsp[(1) - (2)]), &quot;++&quot;, (yyvsp[(2) - (2)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;unaryOpError((yylsp[(1) - (2)]), &quot;++&quot;, (yyvsp[(2) - (2)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 31:
+
+    {
+        if (context-&gt;lValueErrorCheck((yylsp[(1) - (2)]), &quot;--&quot;, (yyvsp[(2) - (2)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;unaryOpError((yylsp[(1) - (2)]), &quot;--&quot;, (yyvsp[(2) - (2)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 32:
+
+    {
+        if ((yyvsp[(1) - (2)].interm).op != EOpNull) {
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yylsp[(1) - (2)]), context-&gt;symbolTable);
+            if ((yyval.interm.intermTypedNode) == 0) {
+                const char* errorOp = &quot;&quot;;
+                switch((yyvsp[(1) - (2)].interm).op) {
+                case EOpNegative:   errorOp = &quot;-&quot;; break;
+                case EOpLogicalNot: errorOp = &quot;!&quot;; break;
+                default: break;
+                }
+                context-&gt;unaryOpError((yylsp[(1) - (2)]), errorOp, (yyvsp[(2) - (2)].interm.intermTypedNode)-&gt;getCompleteString());
+                context-&gt;recover();
+                (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+            }
+        } else
+            (yyval.interm.intermTypedNode) = (yyvsp[(2) - (2)].interm.intermTypedNode);
+    }
+    break;
+
+  case 33:
+
+    { (yyval.interm).op = EOpNull; }
+    break;
+
+  case 34:
+
+    { (yyval.interm).op = EOpNegative; }
+    break;
+
+  case 35:
+
+    { (yyval.interm).op = EOpLogicalNot; }
+    break;
+
+  case 36:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 37:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;*&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 38:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;/&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 39:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 40:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;+&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 41:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;-&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 42:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 43:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 44:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;&lt;&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 45:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;&gt;&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 46:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;&lt;=&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 47:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;&gt;=&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 48:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 49:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;==&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 50:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;!=&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 51:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 52:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 53:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 54:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 55:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;&amp;&amp;&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 56:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 57:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;^^&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 58:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 59:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]), context-&gt;symbolTable);
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;||&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            ConstantUnion *unionArray = new ConstantUnion[1];
+            unionArray-&gt;setBConst(false);
+            (yyval.interm.intermTypedNode) = context-&gt;intermediate.addConstantUnion(unionArray, TType(EbtBool, EbpUndefined, EvqConst), (yylsp[(2) - (3)]));
+        }
+    }
+    break;
+
+  case 60:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 61:
+
+    {
+       if (context-&gt;boolErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.intermTypedNode)))
+            context-&gt;recover();
+
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yylsp[(2) - (5)]));
+        if ((yyvsp[(3) - (5)].interm.intermTypedNode)-&gt;getType() != (yyvsp[(5) - (5)].interm.intermTypedNode)-&gt;getType())
+            (yyval.interm.intermTypedNode) = 0;
+
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (5)]), &quot;:&quot;, (yyvsp[(3) - (5)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(5) - (5)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 62:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 63:
+
+    {
+        if (context-&gt;lValueErrorCheck((yylsp[(2) - (3)]), &quot;assign&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addAssign((yyvsp[(2) - (3)].interm).op, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;assignError((yylsp[(2) - (3)]), &quot;assign&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 64:
+
+    { (yyval.interm).op = EOpAssign; }
+    break;
+
+  case 65:
+
+    { (yyval.interm).op = EOpMulAssign; }
+    break;
+
+  case 66:
+
+    { (yyval.interm).op = EOpDivAssign; }
+    break;
+
+  case 67:
+
+    { (yyval.interm).op = EOpAddAssign; }
+    break;
+
+  case 68:
+
+    { (yyval.interm).op = EOpSubAssign; }
+    break;
+
+  case 69:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 70:
+
+    {
+        (yyval.interm.intermTypedNode) = context-&gt;intermediate.addComma((yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yylsp[(2) - (3)]));
+        if ((yyval.interm.intermTypedNode) == 0) {
+            context-&gt;binaryOpError((yylsp[(2) - (3)]), &quot;,&quot;, (yyvsp[(1) - (3)].interm.intermTypedNode)-&gt;getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)-&gt;getCompleteString());
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = (yyvsp[(3) - (3)].interm.intermTypedNode);
+        }
+    }
+    break;
+
+  case 71:
+
+    {
+        if (context-&gt;constErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 72:
+
+    {
+        TFunction &amp;function = *((yyvsp[(1) - (2)].interm).function);
+        
+        TIntermAggregate *prototype = new TIntermAggregate;
+        prototype-&gt;setType(function.getReturnType());
+        prototype-&gt;setName(function.getName());
+        
+        for (size_t i = 0; i &lt; function.getParamCount(); i++)
+        {
+            const TParameter &amp;param = function.getParam(i);
+            if (param.name != 0)
+            {
+                TVariable variable(param.name, *param.type);
+                
+                prototype = context-&gt;intermediate.growAggregate(prototype, context-&gt;intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yylsp[(1) - (2)])), (yylsp[(1) - (2)]));
+            }
+            else
+            {
+                prototype = context-&gt;intermediate.growAggregate(prototype, context-&gt;intermediate.addSymbol(0, &quot;&quot;, *param.type, (yylsp[(1) - (2)])), (yylsp[(1) - (2)]));
+            }
+        }
+        
+        prototype-&gt;setOp(EOpPrototype);
+        (yyval.interm.intermNode) = prototype;
+
+        context-&gt;symbolTable.pop();
+    }
+    break;
+
+  case 73:
+
+    {
+        if ((yyvsp[(1) - (2)].interm).intermAggregate)
+            (yyvsp[(1) - (2)].interm).intermAggregate-&gt;setOp(EOpDeclaration);
+        (yyval.interm.intermNode) = (yyvsp[(1) - (2)].interm).intermAggregate;
+    }
+    break;
+
+  case 74:
+
+    {
+        if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) &amp;&amp; (context-&gt;shaderType == SH_FRAGMENT_SHADER) &amp;&amp; !context-&gt;fragmentPrecisionHigh) {
+            context-&gt;error((yylsp[(1) - (4)]), &quot;precision is not supported in fragment shader&quot;, &quot;highp&quot;);
+            context-&gt;recover();
+        }
+        if (!context-&gt;symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type), (yyvsp[(2) - (4)].interm.precision) )) {
+            context-&gt;error((yylsp[(1) - (4)]), &quot;illegal type argument for default precision qualifier&quot;, getBasicString((yyvsp[(3) - (4)].interm.type).type));
+            context-&gt;recover();
+        }
+        (yyval.interm.intermNode) = 0;
+    }
+    break;
+
+  case 75:
+
+    {
+        //
+        // Multiple declarations of the same function are allowed.
+        //
+        // If this is a definition, the definition production code will check for redefinitions
+        // (we don't know at this point if it's a definition or not).
+        //
+        // Redeclarations are allowed.  But, return types and parameter qualifiers must match.
+        //
+        TFunction* prevDec = static_cast&lt;TFunction*&gt;(context-&gt;symbolTable.find((yyvsp[(1) - (2)].interm.function)-&gt;getMangledName()));
+        if (prevDec) {
+            if (prevDec-&gt;getReturnType() != (yyvsp[(1) - (2)].interm.function)-&gt;getReturnType()) {
+                context-&gt;error((yylsp[(2) - (2)]), &quot;overloaded functions must have the same return type&quot;, (yyvsp[(1) - (2)].interm.function)-&gt;getReturnType().getBasicString());
+                context-&gt;recover();
+            }
+            for (size_t i = 0; i &lt; prevDec-&gt;getParamCount(); ++i) {
+                if (prevDec-&gt;getParam(i).type-&gt;getQualifier() != (yyvsp[(1) - (2)].interm.function)-&gt;getParam(i).type-&gt;getQualifier()) {
+                    context-&gt;error((yylsp[(2) - (2)]), &quot;overloaded functions must have the same parameter qualifiers&quot;, (yyvsp[(1) - (2)].interm.function)-&gt;getParam(i).type-&gt;getQualifierString());
+                    context-&gt;recover();
+                }
+            }
+        }
+
+        //
+        // Check for previously declared variables using the same name.
+        //
+        TSymbol *prevSym = context-&gt;symbolTable.find((yyvsp[(1) - (2)].interm.function)-&gt;getName());
+        if (prevSym)
+        {
+            if (!prevSym-&gt;isFunction())
+            {
+                context-&gt;error((yylsp[(2) - (2)]), &quot;redefinition&quot;, (yyvsp[(1) - (2)].interm.function)-&gt;getName().c_str(), &quot;function&quot;);
+                context-&gt;recover();
+            }
+        }
+        else
+        {
+            // Insert the unmangled name to detect potential future redefinition as a variable.
+            context-&gt;symbolTable.getOuterLevel()-&gt;insert((yyvsp[(1) - (2)].interm.function)-&gt;getName(), *(yyvsp[(1) - (2)].interm.function));
+        }
+
+        //
+        // If this is a redeclaration, it could also be a definition,
+        // in which case, we want to use the variable names from this one, and not the one that's
+        // being redeclared.  So, pass back up this declaration, not the one in the symbol table.
+        //
+        (yyval.interm).function = (yyvsp[(1) - (2)].interm.function);
+
+        // 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-&gt;symbolTable.getOuterLevel()-&gt;insert(*(yyval.interm).function);
+    }
+    break;
+
+  case 76:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+    }
+    break;
+
+  case 77:
+
+    {
+        (yyval.interm.function) = (yyvsp[(1) - (1)].interm.function);
+    }
+    break;
+
+  case 78:
+
+    {
+        // Add the parameter
+        (yyval.interm.function) = (yyvsp[(1) - (2)].interm.function);
+        if ((yyvsp[(2) - (2)].interm).param.type-&gt;getBasicType() != EbtVoid)
+            (yyvsp[(1) - (2)].interm.function)-&gt;addParameter((yyvsp[(2) - (2)].interm).param);
+        else
+            delete (yyvsp[(2) - (2)].interm).param.type;
+    }
+    break;
+
+  case 79:
+
+    {
+        //
+        // Only first parameter of one-parameter functions can be void
+        // The check for named parameters not being void is done in parameter_declarator
+        //
+        if ((yyvsp[(3) - (3)].interm).param.type-&gt;getBasicType() == EbtVoid) {
+            //
+            // This parameter &gt; first is void
+            //
+            context-&gt;error((yylsp[(2) - (3)]), &quot;cannot be an argument type except for '(void)'&quot;, &quot;void&quot;);
+            context-&gt;recover();
+            delete (yyvsp[(3) - (3)].interm).param.type;
+        } else {
+            // Add the parameter
+            (yyval.interm.function) = (yyvsp[(1) - (3)].interm.function);
+            (yyvsp[(1) - (3)].interm.function)-&gt;addParameter((yyvsp[(3) - (3)].interm).param);
+        }
+    }
+    break;
+
+  case 80:
+
+    {
+        if ((yyvsp[(1) - (3)].interm.type).qualifier != EvqGlobal &amp;&amp; (yyvsp[(1) - (3)].interm.type).qualifier != EvqTemporary) {
+            context-&gt;error((yylsp[(2) - (3)]), &quot;no qualifiers allowed for function return&quot;, getQualifierString((yyvsp[(1) - (3)].interm.type).qualifier));
+            context-&gt;recover();
+        }
+        // make sure a sampler is not involved as well...
+        if (context-&gt;structQualifierErrorCheck((yylsp[(2) - (3)]), (yyvsp[(1) - (3)].interm.type)))
+            context-&gt;recover();
+
+        // Add the function as a prototype after parsing it (we do not support recursion)
+        TFunction *function;
+        TType type((yyvsp[(1) - (3)].interm.type));
+        function = new TFunction((yyvsp[(2) - (3)].lex).string, type);
+        (yyval.interm.function) = function;
+        
+        context-&gt;symbolTable.push();
+    }
+    break;
+
+  case 81:
+
+    {
+        if ((yyvsp[(1) - (2)].interm.type).type == EbtVoid) {
+            context-&gt;error((yylsp[(2) - (2)]), &quot;illegal use of type 'void'&quot;, (yyvsp[(2) - (2)].lex).string-&gt;c_str());
+            context-&gt;recover();
+        }
+        if (context-&gt;reservedErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string))
+            context-&gt;recover();
+        TParameter param = {(yyvsp[(2) - (2)].lex).string, new TType((yyvsp[(1) - (2)].interm.type))};
+        (yyval.interm).param = param;
+    }
+    break;
+
+  case 82:
+
+    {
+        // Check that we can make an array out of this type
+        if (context-&gt;arrayTypeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)))
+            context-&gt;recover();
+
+        if (context-&gt;reservedErrorCheck((yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string))
+            context-&gt;recover();
+
+        int size;
+        if (context-&gt;arraySizeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+            context-&gt;recover();
+        (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+
+        TType* type = new TType((yyvsp[(1) - (5)].interm.type));
+        TParameter param = { (yyvsp[(2) - (5)].lex).string, type };
+        (yyval.interm).param = param;
+    }
+    break;
+
+  case 83:
+
+    {
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+        if (context-&gt;paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+            context-&gt;recover();
+    }
+    break;
+
+  case 84:
+
+    {
+        (yyval.interm) = (yyvsp[(2) - (2)].interm);
+        if (context-&gt;parameterSamplerErrorCheck((yylsp[(2) - (2)]), (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+            context-&gt;recover();
+        if (context-&gt;paramErrorCheck((yylsp[(2) - (2)]), EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+            context-&gt;recover();
+    }
+    break;
+
+  case 85:
+
+    {
+        (yyval.interm) = (yyvsp[(3) - (3)].interm);
+        if (context-&gt;paramErrorCheck((yylsp[(3) - (3)]), (yyvsp[(1) - (3)].interm.type).qualifier, (yyvsp[(2) - (3)].interm.qualifier), (yyval.interm).param.type))
+            context-&gt;recover();
+    }
+    break;
+
+  case 86:
+
+    {
+        (yyval.interm) = (yyvsp[(2) - (2)].interm);
+        if (context-&gt;parameterSamplerErrorCheck((yylsp[(2) - (2)]), (yyvsp[(1) - (2)].interm.qualifier), *(yyvsp[(2) - (2)].interm).param.type))
+            context-&gt;recover();
+        if (context-&gt;paramErrorCheck((yylsp[(2) - (2)]), EvqTemporary, (yyvsp[(1) - (2)].interm.qualifier), (yyval.interm).param.type))
+            context-&gt;recover();
+    }
+    break;
+
+  case 87:
+
+    {
+        (yyval.interm.qualifier) = EvqIn;
+    }
+    break;
+
+  case 88:
+
+    {
+        (yyval.interm.qualifier) = EvqIn;
+    }
+    break;
+
+  case 89:
+
+    {
+        (yyval.interm.qualifier) = EvqOut;
+    }
+    break;
+
+  case 90:
+
+    {
+        (yyval.interm.qualifier) = EvqInOut;
+    }
+    break;
+
+  case 91:
+
+    {
+        TParameter param = { 0, new TType((yyvsp[(1) - (1)].interm.type)) };
+        (yyval.interm).param = param;
+    }
+    break;
+
+  case 92:
+
+    {
+        (yyval.interm) = (yyvsp[(1) - (1)].interm);
+    }
+    break;
+
+  case 93:
+
+    {
+        if ((yyvsp[(1) - (3)].interm).type.type == EbtInvariant &amp;&amp; !(yyvsp[(3) - (3)].lex).symbol)
+        {
+            context-&gt;error((yylsp[(3) - (3)]), &quot;undeclared identifier declared as invariant&quot;, (yyvsp[(3) - (3)].lex).string-&gt;c_str());
+            context-&gt;recover();
+        }
+
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *(yyvsp[(3) - (3)].lex).string, TType((yyvsp[(1) - (3)].interm).type), (yylsp[(3) - (3)]));
+        (yyval.interm).intermAggregate = context-&gt;intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermNode, symbol, (yylsp[(3) - (3)]));
+        
+        if (context-&gt;structQualifierErrorCheck((yylsp[(3) - (3)]), (yyval.interm).type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, false))
+            context-&gt;recover();
+
+        TVariable* variable = 0;
+        if (context-&gt;nonInitErrorCheck((yylsp[(3) - (3)]), *(yyvsp[(3) - (3)].lex).string, (yyval.interm).type, variable))
+            context-&gt;recover();
+        if (symbol &amp;&amp; variable)
+            symbol-&gt;setId(variable-&gt;getUniqueId());
+    }
+    break;
+
+  case 94:
+
+    {
+        if (context-&gt;structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, true))
+            context-&gt;recover();
+
+        (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+        if (context-&gt;arrayTypeErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type) || context-&gt;arrayQualifierErrorCheck((yylsp[(4) - (5)]), (yyvsp[(1) - (5)].interm).type))
+            context-&gt;recover();
+        else {
+            (yyvsp[(1) - (5)].interm).type.setArray(true);
+            TVariable* variable;
+            if (context-&gt;arrayErrorCheck((yylsp[(4) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, variable))
+                context-&gt;recover();
+        }
+    }
+    break;
+
+  case 95:
+
+    {
+        if (context-&gt;structQualifierErrorCheck((yylsp[(3) - (6)]), (yyvsp[(1) - (6)].interm).type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck((yylsp[(3) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, true))
+            context-&gt;recover();
+
+        (yyval.interm) = (yyvsp[(1) - (6)].interm);
+
+        if (context-&gt;arrayTypeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type) || context-&gt;arrayQualifierErrorCheck((yylsp[(4) - (6)]), (yyvsp[(1) - (6)].interm).type))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck((yylsp[(4) - (6)]), (yyvsp[(5) - (6)].interm.intermTypedNode), size))
+                context-&gt;recover();
+            (yyvsp[(1) - (6)].interm).type.setArray(true, size);
+            TVariable* variable = 0;
+            if (context-&gt;arrayErrorCheck((yylsp[(4) - (6)]), *(yyvsp[(3) - (6)].lex).string, (yyvsp[(1) - (6)].interm).type, variable))
+                context-&gt;recover();
+            TType type = TType((yyvsp[(1) - (6)].interm).type);
+            type.setArraySize(size);
+            (yyval.interm).intermAggregate = context-&gt;intermediate.growAggregate((yyvsp[(1) - (6)].interm).intermNode, context-&gt;intermediate.addSymbol(variable ? variable-&gt;getUniqueId() : 0, *(yyvsp[(3) - (6)].lex).string, type, (yylsp[(3) - (6)])), (yylsp[(3) - (6)]));
+        }
+    }
+    break;
+
+  case 96:
+
+    {
+        if (context-&gt;structQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm).type))
+            context-&gt;recover();
+
+        (yyval.interm) = (yyvsp[(1) - (5)].interm);
+
+        TIntermNode* intermNode;
+        if (!context-&gt;executeInitializer((yylsp[(3) - (5)]), *(yyvsp[(3) - (5)].lex).string, (yyvsp[(1) - (5)].interm).type, (yyvsp[(5) - (5)].interm.intermTypedNode), intermNode)) {
+            //
+            // build the intermediate representation
+            //
+            if (intermNode)
+        (yyval.interm).intermAggregate = context-&gt;intermediate.growAggregate((yyvsp[(1) - (5)].interm).intermNode, intermNode, (yylsp[(4) - (5)]));
+            else
+                (yyval.interm).intermAggregate = (yyvsp[(1) - (5)].interm).intermAggregate;
+        } else {
+            context-&gt;recover();
+            (yyval.interm).intermAggregate = 0;
+        }
+    }
+    break;
+
+  case 97:
+
+    {
+        (yyval.interm).type = (yyvsp[(1) - (1)].interm.type);
+        (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(context-&gt;intermediate.addSymbol(0, &quot;&quot;, TType((yyvsp[(1) - (1)].interm.type)), (yylsp[(1) - (1)])), (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 98:
+
+    {
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyvsp[(1) - (2)].interm.type)), (yylsp[(2) - (2)]));
+        (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(symbol, (yylsp[(2) - (2)]));
+        
+        if (context-&gt;structQualifierErrorCheck((yylsp[(2) - (2)]), (yyval.interm).type))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, false))
+            context-&gt;recover();
+            
+            (yyval.interm).type = (yyvsp[(1) - (2)].interm.type);
+
+        TVariable* variable = 0;
+        if (context-&gt;nonInitErrorCheck((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string, (yyval.interm).type, variable))
+            context-&gt;recover();
+        if (variable &amp;&amp; symbol)
+            symbol-&gt;setId(variable-&gt;getUniqueId());
+    }
+    break;
+
+  case 99:
+
+    {
+        context-&gt;error((yylsp[(2) - (4)]), &quot;unsized array declarations not supported&quot;, (yyvsp[(2) - (4)].lex).string-&gt;c_str());
+        context-&gt;recover();
+
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *(yyvsp[(2) - (4)].lex).string, TType((yyvsp[(1) - (4)].interm.type)), (yylsp[(2) - (4)]));
+        (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(symbol, (yylsp[(2) - (4)]));
+        (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+    }
+    break;
+
+  case 100:
+
+    {
+        TType type = TType((yyvsp[(1) - (5)].interm.type));
+        int size;
+        if (context-&gt;arraySizeErrorCheck((yylsp[(2) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+            context-&gt;recover();
+        type.setArraySize(size);
+        TIntermSymbol* symbol = context-&gt;intermediate.addSymbol(0, *(yyvsp[(2) - (5)].lex).string, type, (yylsp[(2) - (5)]));
+        (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(symbol, (yylsp[(2) - (5)]));
+        
+        if (context-&gt;structQualifierErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.type)))
+            context-&gt;recover();
+
+        if (context-&gt;nonInitConstErrorCheck((yylsp[(2) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), true))
+            context-&gt;recover();
+
+        (yyval.interm).type = (yyvsp[(1) - (5)].interm.type);
+
+        if (context-&gt;arrayTypeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)) || context-&gt;arrayQualifierErrorCheck((yylsp[(3) - (5)]), (yyvsp[(1) - (5)].interm.type)))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck((yylsp[(3) - (5)]), (yyvsp[(4) - (5)].interm.intermTypedNode), size))
+                context-&gt;recover();
+
+            (yyvsp[(1) - (5)].interm.type).setArray(true, size);
+            TVariable* variable = 0;
+            if (context-&gt;arrayErrorCheck((yylsp[(3) - (5)]), *(yyvsp[(2) - (5)].lex).string, (yyvsp[(1) - (5)].interm.type), variable))
+                context-&gt;recover();
+            if (variable &amp;&amp; symbol)
+                symbol-&gt;setId(variable-&gt;getUniqueId());
+        }
+    }
+    break;
+
+  case 101:
+
+    {
+        if (context-&gt;structQualifierErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
+            context-&gt;recover();
+
+        (yyval.interm).type = (yyvsp[(1) - (4)].interm.type);
+
+        TIntermNode* intermNode;
+        if (!context-&gt;executeInitializer((yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode)) {
+        //
+        // Build intermediate representation
+        //
+            if(intermNode)
+                (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(intermNode, (yylsp[(3) - (4)]));
+            else
+                (yyval.interm).intermAggregate = 0;
+        } else {
+            context-&gt;recover();
+            (yyval.interm).intermAggregate = 0;
+        }
+    }
+    break;
+
+  case 102:
+
+    {
+        VERTEX_ONLY(&quot;invariant declaration&quot;, (yylsp[(1) - (2)]));
+        if (context-&gt;globalErrorCheck((yylsp[(1) - (2)]), context-&gt;symbolTable.atGlobalLevel(), &quot;invariant varying&quot;))
+            context-&gt;recover();
+        (yyval.interm).type.setBasic(EbtInvariant, EvqInvariantVaryingOut, (yylsp[(2) - (2)]));
+        if (!(yyvsp[(2) - (2)].lex).symbol)
+        {
+            context-&gt;error((yylsp[(2) - (2)]), &quot;undeclared identifier declared as invariant&quot;, (yyvsp[(2) - (2)].lex).string-&gt;c_str());
+            context-&gt;recover();
+            
+            (yyval.interm).intermAggregate = 0;
+        }
+        else
+        {
+            TIntermSymbol *symbol = context-&gt;intermediate.addSymbol(0, *(yyvsp[(2) - (2)].lex).string, TType((yyval.interm).type), (yylsp[(2) - (2)]));
+            (yyval.interm).intermAggregate = context-&gt;intermediate.makeAggregate(symbol, (yylsp[(2) - (2)]));
+        }
+    }
+    break;
+
+  case 103:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+
+        if ((yyvsp[(1) - (1)].interm.type).array) {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;not supported&quot;, &quot;first-class array&quot;);
+            context-&gt;recover();
+            (yyvsp[(1) - (1)].interm.type).setArray(false);
+        }
+    }
+    break;
+
+  case 104:
+
+    {
+        if ((yyvsp[(2) - (2)].interm.type).array) {
+            context-&gt;error((yylsp[(2) - (2)]), &quot;not supported&quot;, &quot;first-class array&quot;);
+            context-&gt;recover();
+            (yyvsp[(2) - (2)].interm.type).setArray(false);
+        }
+
+        if ((yyvsp[(1) - (2)].interm.type).qualifier == EvqAttribute &amp;&amp;
+            ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+            context-&gt;error((yylsp[(2) - (2)]), &quot;cannot be bool or int&quot;, getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
+            context-&gt;recover();
+        }
+        if (((yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingIn || (yyvsp[(1) - (2)].interm.type).qualifier == EvqVaryingOut) &amp;&amp;
+            ((yyvsp[(2) - (2)].interm.type).type == EbtBool || (yyvsp[(2) - (2)].interm.type).type == EbtInt)) {
+            context-&gt;error((yylsp[(2) - (2)]), &quot;cannot be bool or int&quot;, getQualifierString((yyvsp[(1) - (2)].interm.type).qualifier));
+            context-&gt;recover();
+        }
+        (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+        (yyval.interm.type).qualifier = (yyvsp[(1) - (2)].interm.type).qualifier;
+    }
+    break;
+
+  case 105:
+
+    {
+        (yyval.interm.type).setBasic(EbtVoid, EvqConst, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 106:
+
+    {
+        VERTEX_ONLY(&quot;attribute&quot;, (yylsp[(1) - (1)]));
+        if (context-&gt;globalErrorCheck((yylsp[(1) - (1)]), context-&gt;symbolTable.atGlobalLevel(), &quot;attribute&quot;))
+            context-&gt;recover();
+        (yyval.interm.type).setBasic(EbtVoid, EvqAttribute, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 107:
+
+    {
+        if (context-&gt;globalErrorCheck((yylsp[(1) - (1)]), context-&gt;symbolTable.atGlobalLevel(), &quot;varying&quot;))
+            context-&gt;recover();
+        if (context-&gt;shaderType == SH_VERTEX_SHADER)
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingOut, (yylsp[(1) - (1)]));
+        else
+            (yyval.interm.type).setBasic(EbtVoid, EvqVaryingIn, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 108:
+
+    {
+        if (context-&gt;globalErrorCheck((yylsp[(1) - (2)]), context-&gt;symbolTable.atGlobalLevel(), &quot;invariant varying&quot;))
+            context-&gt;recover();
+        if (context-&gt;shaderType == SH_VERTEX_SHADER)
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingOut, (yylsp[(1) - (2)]));
+        else
+            (yyval.interm.type).setBasic(EbtVoid, EvqInvariantVaryingIn, (yylsp[(1) - (2)]));
+    }
+    break;
+
+  case 109:
+
+    {
+        if (context-&gt;globalErrorCheck((yylsp[(1) - (1)]), context-&gt;symbolTable.atGlobalLevel(), &quot;uniform&quot;))
+            context-&gt;recover();
+        (yyval.interm.type).setBasic(EbtVoid, EvqUniform, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 110:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+
+        if ((yyval.interm.type).precision == EbpUndefined) {
+            (yyval.interm.type).precision = context-&gt;symbolTable.getDefaultPrecision((yyvsp[(1) - (1)].interm.type).type);
+            if (context-&gt;precisionErrorCheck((yylsp[(1) - (1)]), (yyval.interm.type).precision, (yyvsp[(1) - (1)].interm.type).type)) {
+                context-&gt;recover();
+            }
+        }
+    }
+    break;
+
+  case 111:
+
+    {
+        (yyval.interm.type) = (yyvsp[(2) - (2)].interm.type);
+        (yyval.interm.type).precision = (yyvsp[(1) - (2)].interm.precision);
+    }
+    break;
+
+  case 112:
+
+    {
+        (yyval.interm.precision) = EbpHigh;
+    }
+    break;
+
+  case 113:
+
+    {
+        (yyval.interm.precision) = EbpMedium;
+    }
+    break;
+
+  case 114:
+
+    {
+        (yyval.interm.precision) = EbpLow;
+    }
+    break;
+
+  case 115:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+    }
+    break;
+
+  case 116:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (4)].interm.type);
+
+        if (context-&gt;arrayTypeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
+            context-&gt;recover();
+        else {
+            int size;
+            if (context-&gt;arraySizeErrorCheck((yylsp[(2) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+                context-&gt;recover();
+            (yyval.interm.type).setArray(true, size);
+        }
+    }
+    break;
+
+  case 117:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtVoid, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 118:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 119:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 120:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 121:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(2);
+    }
+    break;
+
+  case 122:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(3);
+    }
+    break;
+
+  case 123:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(4);
+    }
+    break;
+
+  case 124:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(2);
+    }
+    break;
+
+  case 125:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(3);
+    }
+    break;
+
+  case 126:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtBool, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(4);
+    }
+    break;
+
+  case 127:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(2);
+    }
+    break;
+
+  case 128:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(3);
+    }
+    break;
+
+  case 129:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtInt, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(4);
+    }
+    break;
+
+  case 130:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(2, true);
+    }
+    break;
+
+  case 131:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(3, true);
+    }
+    break;
+
+  case 132:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtFloat, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).setAggregate(4, true);
+    }
+    break;
+
+  case 133:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSampler2D, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 134:
+
+    {
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSamplerCube, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 135:
+
+    {
+        if (!context-&gt;supportsExtension(&quot;GL_OES_EGL_image_external&quot;)) {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;unsupported type&quot;, &quot;samplerExternalOES&quot;);
+            context-&gt;recover();
+        }
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSamplerExternalOES, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 136:
+
+    {
+        if (!context-&gt;supportsExtension(&quot;GL_ARB_texture_rectangle&quot;)) {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;unsupported type&quot;, &quot;sampler2DRect&quot;);
+            context-&gt;recover();
+        }
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtSampler2DRect, qual, (yylsp[(1) - (1)]));
+    }
+    break;
+
+  case 137:
+
+    {
+        (yyval.interm.type) = (yyvsp[(1) - (1)].interm.type);
+        (yyval.interm.type).qualifier = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+    }
+    break;
+
+  case 138:
+
+    {
+        //
+        // This is for user defined type names.  The lexical phase looked up the
+        // type.
+        //
+        TType&amp; structure = static_cast&lt;TVariable*&gt;((yyvsp[(1) - (1)].lex).symbol)-&gt;getType();
+        TQualifier qual = context-&gt;symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
+        (yyval.interm.type).setBasic(EbtStruct, qual, (yylsp[(1) - (1)]));
+        (yyval.interm.type).userDef = &amp;structure;
+    }
+    break;
+
+  case 139:
+
+    { if (context-&gt;enterStructDeclaration((yylsp[(2) - (3)]), *(yyvsp[(2) - (3)].lex).string)) context-&gt;recover(); }
+    break;
+
+  case 140:
+
+    {
+        if (context-&gt;reservedErrorCheck((yylsp[(2) - (6)]), *(yyvsp[(2) - (6)].lex).string))
+            context-&gt;recover();
+
+        TType* structure = new TType(new TStructure((yyvsp[(2) - (6)].lex).string, (yyvsp[(5) - (6)].interm.fieldList)));
+        TVariable* userTypeDef = new TVariable((yyvsp[(2) - (6)].lex).string, *structure, true);
+        if (! context-&gt;symbolTable.insert(*userTypeDef)) {
+            context-&gt;error((yylsp[(2) - (6)]), &quot;redefinition&quot;, (yyvsp[(2) - (6)].lex).string-&gt;c_str(), &quot;struct&quot;);
+            context-&gt;recover();
+        }
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (6)]));
+        (yyval.interm.type).userDef = structure;
+        context-&gt;exitStructDeclaration();
+    }
+    break;
+
+  case 141:
+
+    { if (context-&gt;enterStructDeclaration((yylsp[(2) - (2)]), *(yyvsp[(2) - (2)].lex).string)) context-&gt;recover(); }
+    break;
+
+  case 142:
+
+    {
+        TType* structure = new TType(new TStructure(NewPoolTString(&quot;&quot;), (yyvsp[(4) - (5)].interm.fieldList)));
+        (yyval.interm.type).setBasic(EbtStruct, EvqTemporary, (yylsp[(1) - (5)]));
+        (yyval.interm.type).userDef = structure;
+        context-&gt;exitStructDeclaration();
+    }
+    break;
+
+  case 143:
+
+    {
+        (yyval.interm.fieldList) = (yyvsp[(1) - (1)].interm.fieldList);
+    }
+    break;
+
+  case 144:
+
+    {
+        (yyval.interm.fieldList) = (yyvsp[(1) - (2)].interm.fieldList);
+        for (size_t i = 0; i &lt; (yyvsp[(2) - (2)].interm.fieldList)-&gt;size(); ++i) {
+            TField* field = (*(yyvsp[(2) - (2)].interm.fieldList))[i];
+            for (size_t j = 0; j &lt; (yyval.interm.fieldList)-&gt;size(); ++j) {
+                if ((*(yyval.interm.fieldList))[j]-&gt;name() == field-&gt;name()) {
+                    context-&gt;error((yylsp[(2) - (2)]), &quot;duplicate field name in structure:&quot;, &quot;struct&quot;, field-&gt;name().c_str());
+                    context-&gt;recover();
+                }
+            }
+            (yyval.interm.fieldList)-&gt;push_back(field);
+        }
+    }
+    break;
+
+  case 145:
+
+    {
+        (yyval.interm.fieldList) = (yyvsp[(2) - (3)].interm.fieldList);
+
+        if (context-&gt;voidErrorCheck((yylsp[(1) - (3)]), (*(yyvsp[(2) - (3)].interm.fieldList))[0]-&gt;name(), (yyvsp[(1) - (3)].interm.type))) {
+            context-&gt;recover();
+        }
+        for (unsigned int i = 0; i &lt; (yyval.interm.fieldList)-&gt;size(); ++i) {
+            //
+            // Careful not to replace already known aspects of type, like array-ness
+            //
+            TType* type = (*(yyval.interm.fieldList))[i]-&gt;type();
+            type-&gt;setBasicType((yyvsp[(1) - (3)].interm.type).type);
+            type-&gt;setNominalSize((yyvsp[(1) - (3)].interm.type).size);
+            type-&gt;setMatrix((yyvsp[(1) - (3)].interm.type).matrix);
+            type-&gt;setPrecision((yyvsp[(1) - (3)].interm.type).precision);
+
+            // don't allow arrays of arrays
+            if (type-&gt;isArray()) {
+                if (context-&gt;arrayTypeErrorCheck((yylsp[(1) - (3)]), (yyvsp[(1) - (3)].interm.type)))
+                    context-&gt;recover();
+            }
+            if ((yyvsp[(1) - (3)].interm.type).array)
+                type-&gt;setArraySize((yyvsp[(1) - (3)].interm.type).arraySize);
+            if ((yyvsp[(1) - (3)].interm.type).userDef)
+                type-&gt;setStruct((yyvsp[(1) - (3)].interm.type).userDef-&gt;getStruct());
+
+            if (context-&gt;structNestingErrorCheck((yylsp[(1) - (3)]), *(*(yyval.interm.fieldList))[i]))
+                context-&gt;recover();
+        }
+    }
+    break;
+
+  case 146:
+
+    {
+        (yyval.interm.fieldList) = NewPoolTFieldList();
+        (yyval.interm.fieldList)-&gt;push_back((yyvsp[(1) - (1)].interm.field));
+    }
+    break;
+
+  case 147:
+
+    {
+        (yyval.interm.fieldList)-&gt;push_back((yyvsp[(3) - (3)].interm.field));
+    }
+    break;
+
+  case 148:
+
+    {
+        if (context-&gt;reservedErrorCheck((yylsp[(1) - (1)]), *(yyvsp[(1) - (1)].lex).string))
+            context-&gt;recover();
+
+        TType* type = new TType(EbtVoid, EbpUndefined);
+        (yyval.interm.field) = new TField(type, (yyvsp[(1) - (1)].lex).string);
+    }
+    break;
+
+  case 149:
+
+    {
+        if (context-&gt;reservedErrorCheck((yylsp[(1) - (4)]), *(yyvsp[(1) - (4)].lex).string))
+            context-&gt;recover();
+
+        TType* type = new TType(EbtVoid, EbpUndefined);
+        int size = 0;
+        if (context-&gt;arraySizeErrorCheck((yylsp[(3) - (4)]), (yyvsp[(3) - (4)].interm.intermTypedNode), size))
+            context-&gt;recover();
+        type-&gt;setArraySize(size);
+
+        (yyval.interm.field) = new TField(type, (yyvsp[(1) - (4)].lex).string);
+    }
+    break;
+
+  case 150:
+
+    { (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode); }
+    break;
+
+  case 151:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 152:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermAggregate); }
+    break;
+
+  case 153:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 154:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 155:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 156:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 157:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 158:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 159:
+
+    { (yyval.interm.intermAggregate) = 0; }
+    break;
+
+  case 160:
+
+    { context-&gt;symbolTable.push(); }
+    break;
+
+  case 161:
+
+    { context-&gt;symbolTable.pop(); }
+    break;
+
+  case 162:
+
+    {
+        if ((yyvsp[(3) - (5)].interm.intermAggregate) != 0) {
+            (yyvsp[(3) - (5)].interm.intermAggregate)-&gt;setOp(EOpSequence);
+            (yyvsp[(3) - (5)].interm.intermAggregate)-&gt;setLine((yyloc));
+        }
+        (yyval.interm.intermAggregate) = (yyvsp[(3) - (5)].interm.intermAggregate);
+    }
+    break;
+
+  case 163:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 164:
+
+    { (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode); }
+    break;
+
+  case 165:
+
+    { context-&gt;symbolTable.push(); }
+    break;
+
+  case 166:
+
+    { context-&gt;symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
+    break;
+
+  case 167:
+
+    { context-&gt;symbolTable.push(); }
+    break;
+
+  case 168:
+
+    { context-&gt;symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[(2) - (2)].interm.intermNode); }
+    break;
+
+  case 169:
+
+    {
+        (yyval.interm.intermNode) = 0;
+    }
+    break;
+
+  case 170:
+
+    {
+        if ((yyvsp[(2) - (3)].interm.intermAggregate)) {
+            (yyvsp[(2) - (3)].interm.intermAggregate)-&gt;setOp(EOpSequence);
+            (yyvsp[(2) - (3)].interm.intermAggregate)-&gt;setLine((yyloc));
+        }
+        (yyval.interm.intermNode) = (yyvsp[(2) - (3)].interm.intermAggregate);
+    }
+    break;
+
+  case 171:
+
+    {
+        (yyval.interm.intermAggregate) = context-&gt;intermediate.makeAggregate((yyvsp[(1) - (1)].interm.intermNode), (yyloc));
+    }
+    break;
+
+  case 172:
+
+    {
+        (yyval.interm.intermAggregate) = context-&gt;intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermAggregate), (yyvsp[(2) - (2)].interm.intermNode), (yyloc));
+    }
+    break;
+
+  case 173:
+
+    { (yyval.interm.intermNode) = 0; }
+    break;
+
+  case 174:
+
+    { (yyval.interm.intermNode) = static_cast&lt;TIntermNode*&gt;((yyvsp[(1) - (2)].interm.intermTypedNode)); }
+    break;
+
+  case 175:
+
+    {
+        if (context-&gt;boolErrorCheck((yylsp[(1) - (5)]), (yyvsp[(3) - (5)].interm.intermTypedNode)))
+            context-&gt;recover();
+        (yyval.interm.intermNode) = context-&gt;intermediate.addSelection((yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.nodePair), (yylsp[(1) - (5)]));
+    }
+    break;
+
+  case 176:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermNode);
+    }
+    break;
+
+  case 177:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (1)].interm.intermNode);
+        (yyval.interm.nodePair).node2 = 0;
+    }
+    break;
+
+  case 178:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+        if (context-&gt;boolErrorCheck((yyvsp[(1) - (1)].interm.intermTypedNode)-&gt;getLine(), (yyvsp[(1) - (1)].interm.intermTypedNode)))
+            context-&gt;recover();
+    }
+    break;
+
+  case 179:
+
+    {
+        TIntermNode* intermNode;
+        if (context-&gt;structQualifierErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
+            context-&gt;recover();
+        if (context-&gt;boolErrorCheck((yylsp[(2) - (4)]), (yyvsp[(1) - (4)].interm.type)))
+            context-&gt;recover();
+
+        if (!context-&gt;executeInitializer((yylsp[(2) - (4)]), *(yyvsp[(2) - (4)].lex).string, (yyvsp[(1) - (4)].interm.type), (yyvsp[(4) - (4)].interm.intermTypedNode), intermNode))
+            (yyval.interm.intermTypedNode) = (yyvsp[(4) - (4)].interm.intermTypedNode);
+        else {
+            context-&gt;recover();
+            (yyval.interm.intermTypedNode) = 0;
+        }
+    }
+    break;
+
+  case 180:
+
+    { context-&gt;symbolTable.push(); ++context-&gt;loopNestingLevel; }
+    break;
+
+  case 181:
+
+    {
+        context-&gt;symbolTable.pop();
+        (yyval.interm.intermNode) = context-&gt;intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yylsp[(1) - (6)]));
+        --context-&gt;loopNestingLevel;
+    }
+    break;
+
+  case 182:
+
+    { ++context-&gt;loopNestingLevel; }
+    break;
+
+  case 183:
+
+    {
+        if (context-&gt;boolErrorCheck((yylsp[(8) - (8)]), (yyvsp[(6) - (8)].interm.intermTypedNode)))
+            context-&gt;recover();
+
+        (yyval.interm.intermNode) = context-&gt;intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yylsp[(4) - (8)]));
+        --context-&gt;loopNestingLevel;
+    }
+    break;
+
+  case 184:
+
+    { context-&gt;symbolTable.push(); ++context-&gt;loopNestingLevel; }
+    break;
+
+  case 185:
+
+    {
+        context-&gt;symbolTable.pop();
+        (yyval.interm.intermNode) = context-&gt;intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast&lt;TIntermTyped*&gt;((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast&lt;TIntermTyped*&gt;((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yylsp[(1) - (7)]));
+        --context-&gt;loopNestingLevel;
+    }
+    break;
+
+  case 186:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    }
+    break;
+
+  case 187:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    }
+    break;
+
+  case 188:
+
+    {
+        (yyval.interm.intermTypedNode) = (yyvsp[(1) - (1)].interm.intermTypedNode);
+    }
+    break;
+
+  case 189:
+
+    {
+        (yyval.interm.intermTypedNode) = 0;
+    }
+    break;
+
+  case 190:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (2)].interm.intermTypedNode);
+        (yyval.interm.nodePair).node2 = 0;
+    }
+    break;
+
+  case 191:
+
+    {
+        (yyval.interm.nodePair).node1 = (yyvsp[(1) - (3)].interm.intermTypedNode);
+        (yyval.interm.nodePair).node2 = (yyvsp[(3) - (3)].interm.intermTypedNode);
+    }
+    break;
+
+  case 192:
+
+    {
+        if (context-&gt;loopNestingLevel &lt;= 0) {
+            context-&gt;error((yylsp[(1) - (2)]), &quot;continue statement only allowed in loops&quot;, &quot;&quot;);
+            context-&gt;recover();
+        }
+        (yyval.interm.intermNode) = context-&gt;intermediate.addBranch(EOpContinue, (yylsp[(1) - (2)]));
+    }
+    break;
+
+  case 193:
+
+    {
+        if (context-&gt;loopNestingLevel &lt;= 0) {
+            context-&gt;error((yylsp[(1) - (2)]), &quot;break statement only allowed in loops&quot;, &quot;&quot;);
+            context-&gt;recover();
+        }
+        (yyval.interm.intermNode) = context-&gt;intermediate.addBranch(EOpBreak, (yylsp[(1) - (2)]));
+    }
+    break;
+
+  case 194:
+
+    {
+        (yyval.interm.intermNode) = context-&gt;intermediate.addBranch(EOpReturn, (yylsp[(1) - (2)]));
+        if (context-&gt;currentFunctionType-&gt;getBasicType() != EbtVoid) {
+            context-&gt;error((yylsp[(1) - (2)]), &quot;non-void function must return a value&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        }
+    }
+    break;
+
+  case 195:
+
+    {
+        (yyval.interm.intermNode) = context-&gt;intermediate.addBranch(EOpReturn, (yyvsp[(2) - (3)].interm.intermTypedNode), (yylsp[(1) - (3)]));
+        context-&gt;functionReturnsValue = true;
+        if (context-&gt;currentFunctionType-&gt;getBasicType() == EbtVoid) {
+            context-&gt;error((yylsp[(1) - (3)]), &quot;void function cannot return a value&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        } else if (*(context-&gt;currentFunctionType) != (yyvsp[(2) - (3)].interm.intermTypedNode)-&gt;getType()) {
+            context-&gt;error((yylsp[(1) - (3)]), &quot;function return is not matching type:&quot;, &quot;return&quot;);
+            context-&gt;recover();
+        }
+    }
+    break;
+
+  case 196:
+
+    {
+        FRAG_ONLY(&quot;discard&quot;, (yylsp[(1) - (2)]));
+        (yyval.interm.intermNode) = context-&gt;intermediate.addBranch(EOpKill, (yylsp[(1) - (2)]));
+    }
+    break;
+
+  case 197:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+        context-&gt;treeRoot = (yyval.interm.intermNode);
+    }
+    break;
+
+  case 198:
+
+    {
+        (yyval.interm.intermNode) = context-&gt;intermediate.growAggregate((yyvsp[(1) - (2)].interm.intermNode), (yyvsp[(2) - (2)].interm.intermNode), (yyloc));
+        context-&gt;treeRoot = (yyval.interm.intermNode);
+    }
+    break;
+
+  case 199:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    }
+    break;
+
+  case 200:
+
+    {
+        (yyval.interm.intermNode) = (yyvsp[(1) - (1)].interm.intermNode);
+    }
+    break;
+
+  case 201:
+
+    {
+        TFunction* function = (yyvsp[(1) - (1)].interm).function;
+        
+        const TSymbol *builtIn = context-&gt;symbolTable.findBuiltIn(function-&gt;getMangledName());
+        
+        if (builtIn)
+        {
+            context-&gt;error((yylsp[(1) - (1)]), &quot;built-in functions cannot be redefined&quot;, function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        
+        TFunction* prevDec = static_cast&lt;TFunction*&gt;(context-&gt;symbolTable.find(function-&gt;getMangledName()));
+        //
+        // Note:  'prevDec' could be 'function' if this is the first time we've seen function
+        // as it would have just been put in the symbol table.  Otherwise, we're looking up
+        // an earlier occurance.
+        //
+        if (prevDec-&gt;isDefined()) {
+            //
+            // Then this function already has a body.
+            //
+            context-&gt;error((yylsp[(1) - (1)]), &quot;function already has a body&quot;, function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        prevDec-&gt;setDefined();
+
+        //
+        // Raise error message if main function takes any parameters or return anything other than void
+        //
+        if (function-&gt;getName() == &quot;main&quot;) {
+            if (function-&gt;getParamCount() &gt; 0) {
+                context-&gt;error((yylsp[(1) - (1)]), &quot;function cannot take any parameter(s)&quot;, function-&gt;getName().c_str());
+                context-&gt;recover();
+            }
+            if (function-&gt;getReturnType().getBasicType() != EbtVoid) {
+                context-&gt;error((yylsp[(1) - (1)]), &quot;&quot;, function-&gt;getReturnType().getBasicString(), &quot;main function cannot return a value&quot;);
+                context-&gt;recover();
+            }
+        }
+
+        //
+        // Remember the return type for later checking for RETURN statements.
+        //
+        context-&gt;currentFunctionType = &amp;(prevDec-&gt;getReturnType());
+        context-&gt;functionReturnsValue = false;
+
+        //
+        // Insert parameters into the symbol table.
+        // If the parameter has no name, it's not an error, just don't insert it
+        // (could be used for unused args).
+        //
+        // Also, accumulate the list of parameters into the HIL, so lower level code
+        // knows where to find parameters.
+        //
+        TIntermAggregate* paramNodes = new TIntermAggregate;
+        for (size_t i = 0; i &lt; function-&gt;getParamCount(); i++) {
+            const TParameter&amp; param = function-&gt;getParam(i);
+            if (param.name != 0) {
+                TVariable *variable = new TVariable(param.name, *param.type);
+                //
+                // Insert the parameters with name in the symbol table.
+                //
+                if (! context-&gt;symbolTable.insert(*variable)) {
+                    context-&gt;error((yylsp[(1) - (1)]), &quot;redefinition&quot;, variable-&gt;getName().c_str());
+                    context-&gt;recover();
+                    delete variable;
+                }
+
+                //
+                // Add the parameter to the HIL
+                //
+                paramNodes = context-&gt;intermediate.growAggregate(
+                                               paramNodes,
+                                               context-&gt;intermediate.addSymbol(variable-&gt;getUniqueId(),
+                                                                               variable-&gt;getName(),
+                                                                               variable-&gt;getType(),
+                                                                               (yylsp[(1) - (1)])),
+                                               (yylsp[(1) - (1)]));
+            } else {
+                paramNodes = context-&gt;intermediate.growAggregate(paramNodes, context-&gt;intermediate.addSymbol(0, &quot;&quot;, *param.type, (yylsp[(1) - (1)])), (yylsp[(1) - (1)]));
+            }
+        }
+        context-&gt;intermediate.setAggregateOperator(paramNodes, EOpParameters, (yylsp[(1) - (1)]));
+        (yyvsp[(1) - (1)].interm).intermAggregate = paramNodes;
+        context-&gt;loopNestingLevel = 0;
+    }
+    break;
+
+  case 202:
+
+    {
+        //?? Check that all paths return a value if return type != void ?
+        //   May be best done as post process phase on intermediate code
+        if (context-&gt;currentFunctionType-&gt;getBasicType() != EbtVoid &amp;&amp; ! context-&gt;functionReturnsValue) {
+            context-&gt;error((yylsp[(1) - (3)]), &quot;function does not return a value:&quot;, &quot;&quot;, (yyvsp[(1) - (3)].interm).function-&gt;getName().c_str());
+            context-&gt;recover();
+        }
+        
+        (yyval.interm.intermNode) = context-&gt;intermediate.growAggregate((yyvsp[(1) - (3)].interm).intermAggregate, (yyvsp[(3) - (3)].interm.intermNode), (yyloc));
+        context-&gt;intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yylsp[(1) - (3)]));
+        (yyval.interm.intermNode)-&gt;getAsAggregate()-&gt;setName((yyvsp[(1) - (3)].interm).function-&gt;getMangledName().c_str());
+        (yyval.interm.intermNode)-&gt;getAsAggregate()-&gt;setType((yyvsp[(1) - (3)].interm).function-&gt;getReturnType());
+
+        // store the pragma information for debug and optimize and other vendor specific
+        // information. This information can be queried from the parse tree
+        (yyval.interm.intermNode)-&gt;getAsAggregate()-&gt;setOptimize(context-&gt;pragma().optimize);
+        (yyval.interm.intermNode)-&gt;getAsAggregate()-&gt;setDebug(context-&gt;pragma().debug);
+
+        context-&gt;symbolTable.pop();
+    }
+    break;
+
+
+
+      default: break;
+    }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
+  YY_SYMBOL_PRINT (&quot;-&gt; $$ =&quot;, yyr1[yyn], &amp;yyval, &amp;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 &lt;= yystate &amp;&amp; yystate &lt;= YYLAST &amp;&amp; yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (&amp;yylloc, context, YY_(&quot;syntax error&quot;));
+#else
+# define YYSYNTAX_ERROR yysyntax_error (&amp;yymsg_alloc, &amp;yymsg, \
+                                        yyssp, yytoken)
+      {
+        char const *yymsgp = YY_(&quot;syntax error&quot;);
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (&amp;yylloc, context, yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
+      }
+# undef YYSYNTAX_ERROR
+#endif
+    }
+
+  yyerror_range[1] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse lookahead token after an
+     error, discard it.  */
+
+      if (yychar &lt;= YYEOF)
+    {
+      /* Return failure if at end of input.  */
+      if (yychar == YYEOF)
+        YYABORT;
+    }
+      else
+    {
+      yydestruct (&quot;Error: discarding&quot;,
+              yytoken, &amp;yylval, &amp;yylloc, context);
+      yychar = YYEMPTY;
+    }
+    }
+
+  /* Else will try to reuse lookahead 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[1] = 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 (!yypact_value_is_default (yyn))
+    {
+      yyn += YYTERROR;
+      if (0 &lt;= yyn &amp;&amp; yyn &lt;= YYLAST &amp;&amp; yycheck[yyn] == YYTERROR)
+        {
+          yyn = yytable[yyn];
+          if (0 &lt; yyn)
+        break;
+        }
+    }
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+    YYABORT;
+
+      yyerror_range[1] = *yylsp;
+      yydestruct (&quot;Error: popping&quot;,
+          yystos[yystate], yyvsp, yylsp, context);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
+  *++yyvsp = yylval;
+  YY_IGNORE_MAYBE_UNINITIALIZED_END
+
+  yyerror_range[2] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the lookahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, yyerror_range, 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT (&quot;Shifting&quot;, 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;
+
+#if !defined yyoverflow || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&amp;yylloc, context, YY_(&quot;memory exhausted&quot;));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEMPTY)
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct (&quot;Cleanup: discarding lookahead&quot;,
+                  yytoken, &amp;yylval, &amp;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 (&quot;Cleanup: popping&quot;,
+          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);
+}
+
+
+
+
+
+int glslang_parse(TParseContext* context) {
+    return yyparse(context);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorglslang_tabh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,225 @@
</span><ins>+/* A Bison parser, made by GNU Bison 2.7.1.  */
+
+/* Apple Note: For the avoidance of doubt, Apple elects to distribute this file under the terms of the BSD license. */
+
+/* Bison interface for Yacc-like parsers in C
+   
+      Copyright (C) 1984, 1989-1990, 2000-2013 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 3 of the License, 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, see &lt;http://www.gnu.org/licenses/&gt;.  */
+
+/* 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.  */
+
+#ifndef YY_YY_GLSLANG_TAB_H_INCLUDED
+# define YY_YY_GLSLANG_TAB_H_INCLUDED
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int yydebug;
+#endif
+/* &quot;%code requires&quot; blocks.  */
+
+
+#define YYLTYPE TSourceLoc
+#define YYLTYPE_IS_DECLARED 1
+#define SH_MAX_TOKEN_LENGTH 256  // WebGL spec.
+
+
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     INVARIANT = 258,
+     HIGH_PRECISION = 259,
+     MEDIUM_PRECISION = 260,
+     LOW_PRECISION = 261,
+     PRECISION = 262,
+     ATTRIBUTE = 263,
+     CONST_QUAL = 264,
+     BOOL_TYPE = 265,
+     FLOAT_TYPE = 266,
+     INT_TYPE = 267,
+     BREAK = 268,
+     CONTINUE = 269,
+     DO = 270,
+     ELSE = 271,
+     FOR = 272,
+     IF = 273,
+     DISCARD = 274,
+     RETURN = 275,
+     BVEC2 = 276,
+     BVEC3 = 277,
+     BVEC4 = 278,
+     IVEC2 = 279,
+     IVEC3 = 280,
+     IVEC4 = 281,
+     VEC2 = 282,
+     VEC3 = 283,
+     VEC4 = 284,
+     MATRIX2 = 285,
+     MATRIX3 = 286,
+     MATRIX4 = 287,
+     IN_QUAL = 288,
+     OUT_QUAL = 289,
+     INOUT_QUAL = 290,
+     UNIFORM = 291,
+     VARYING = 292,
+     STRUCT = 293,
+     VOID_TYPE = 294,
+     WHILE = 295,
+     SAMPLER2D = 296,
+     SAMPLERCUBE = 297,
+     SAMPLER_EXTERNAL_OES = 298,
+     SAMPLER2DRECT = 299,
+     IDENTIFIER = 300,
+     TYPE_NAME = 301,
+     FLOATCONSTANT = 302,
+     INTCONSTANT = 303,
+     BOOLCONSTANT = 304,
+     LEFT_OP = 305,
+     RIGHT_OP = 306,
+     INC_OP = 307,
+     DEC_OP = 308,
+     LE_OP = 309,
+     GE_OP = 310,
+     EQ_OP = 311,
+     NE_OP = 312,
+     AND_OP = 313,
+     OR_OP = 314,
+     XOR_OP = 315,
+     MUL_ASSIGN = 316,
+     DIV_ASSIGN = 317,
+     ADD_ASSIGN = 318,
+     MOD_ASSIGN = 319,
+     LEFT_ASSIGN = 320,
+     RIGHT_ASSIGN = 321,
+     AND_ASSIGN = 322,
+     XOR_ASSIGN = 323,
+     OR_ASSIGN = 324,
+     SUB_ASSIGN = 325,
+     LEFT_PAREN = 326,
+     RIGHT_PAREN = 327,
+     LEFT_BRACKET = 328,
+     RIGHT_BRACKET = 329,
+     LEFT_BRACE = 330,
+     RIGHT_BRACE = 331,
+     DOT = 332,
+     COMMA = 333,
+     COLON = 334,
+     EQUAL = 335,
+     SEMICOLON = 336,
+     BANG = 337,
+     DASH = 338,
+     TILDE = 339,
+     PLUS = 340,
+     STAR = 341,
+     SLASH = 342,
+     PERCENT = 343,
+     LEFT_ANGLE = 344,
+     RIGHT_ANGLE = 345,
+     VERTICAL_BAR = 346,
+     CARET = 347,
+     AMPERSAND = 348,
+     QUESTION = 349
+   };
+#endif
+
+
+#if ! defined YYSTYPE &amp;&amp; ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+
+    struct {
+        union {
+            TString *string;
+            float f;
+            int i;
+            bool b;
+        };
+        TSymbol* symbol;
+    } lex;
+    struct {
+        TOperator op;
+        union {
+            TIntermNode* intermNode;
+            TIntermNodePair nodePair;
+            TIntermTyped* intermTypedNode;
+            TIntermAggregate* intermAggregate;
+        };
+        union {
+            TPublicType type;
+            TPrecision precision;
+            TQualifier qualifier;
+            TFunction* function;
+            TParameter param;
+            TField* field;
+            TFieldList* fieldList;
+        };
+    } interm;
+
+
+
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE &amp;&amp; ! 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
+
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (TParseContext* context);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !YY_YY_GLSLANG_TAB_H_INCLUDED  */
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/glslang_tab.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorintermOutcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,424 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/localintermediate.h&quot;
+
+//
+// Two purposes:
+// 1.  Show an example of how to iterate tree.  Functions can
+//     also directly call Traverse() on children themselves to
+//     have finer grained control over the process than shown here.
+//     See the last function for how to get started.
+// 2.  Print out a text based description of the tree.
+//
+
+//
+// Use this class to carry along data from node to node in
+// the traversal
+//
+class TOutputTraverser : public TIntermTraverser {
+public:
+    TOutputTraverser(TInfoSinkBase&amp; i) : sink(i) { }
+    TInfoSinkBase&amp; sink;
+
+protected:
+    void visitSymbol(TIntermSymbol*);
+    void visitConstantUnion(TIntermConstantUnion*);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitUnary(Visit visit, TIntermUnary*);
+    bool visitSelection(Visit visit, TIntermSelection*);
+    bool visitAggregate(Visit visit, TIntermAggregate*);
+    bool visitLoop(Visit visit, TIntermLoop*);
+    bool visitBranch(Visit visit, TIntermBranch*);
+};
+
+TString TType::getCompleteString() const
+{
+    TStringStream stream;
+
+    if (qualifier != EvqTemporary &amp;&amp; qualifier != EvqGlobal)
+        stream &lt;&lt; getQualifierString() &lt;&lt; &quot; &quot; &lt;&lt; getPrecisionString() &lt;&lt; &quot; &quot;;
+    if (array)
+        stream &lt;&lt; &quot;array[&quot; &lt;&lt; getArraySize() &lt;&lt; &quot;] of &quot;;
+    if (matrix)
+        stream &lt;&lt; static_cast&lt;int&gt;(size) &lt;&lt; &quot;X&quot; &lt;&lt; static_cast&lt;int&gt;(size) &lt;&lt; &quot; matrix of &quot;;
+    else if (size &gt; 1)
+        stream &lt;&lt; static_cast&lt;int&gt;(size) &lt;&lt; &quot;-component vector of &quot;;
+
+    stream &lt;&lt; getBasicString();
+    return stream.str();
+}
+
+//
+// Helper functions for printing, not part of traversing.
+//
+
+void OutputTreeText(TInfoSinkBase&amp; sink, TIntermNode* node, const int depth)
+{
+    int i;
+
+    sink.location(node-&gt;getLine());
+
+    for (i = 0; i &lt; depth; ++i)
+        sink &lt;&lt; &quot;  &quot;;
+}
+
+//
+// The rest of the file are the traversal functions.  The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children.  If you process children yourself,
+// return false.
+//
+
+void TOutputTraverser::visitSymbol(TIntermSymbol* node)
+{
+    OutputTreeText(sink, node, depth);
+
+    sink &lt;&lt; &quot;'&quot; &lt;&lt; node-&gt;getSymbol() &lt;&lt; &quot;' &quot;;
+    sink &lt;&lt; &quot;(&quot; &lt;&lt; node-&gt;getCompleteString() &lt;&lt; &quot;)\n&quot;;
+}
+
+bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    OutputTreeText(out, node, depth);
+
+    switch (node-&gt;getOp()) {
+        case EOpAssign:                   out &lt;&lt; &quot;move second child to first child&quot;;           break;
+        case EOpInitialize:               out &lt;&lt; &quot;initialize first child with second child&quot;;   break;
+        case EOpAddAssign:                out &lt;&lt; &quot;add second child into first child&quot;;          break;
+        case EOpSubAssign:                out &lt;&lt; &quot;subtract second child into first child&quot;;     break;
+        case EOpMulAssign:                out &lt;&lt; &quot;multiply second child into first child&quot;;     break;
+        case EOpVectorTimesMatrixAssign:  out &lt;&lt; &quot;matrix mult second child into first child&quot;;  break;
+        case EOpVectorTimesScalarAssign:  out &lt;&lt; &quot;vector scale second child into first child&quot;; break;
+        case EOpMatrixTimesScalarAssign:  out &lt;&lt; &quot;matrix scale second child into first child&quot;; break;
+        case EOpMatrixTimesMatrixAssign:  out &lt;&lt; &quot;matrix mult second child into first child&quot;; break;
+        case EOpDivAssign:                out &lt;&lt; &quot;divide second child into first child&quot;;       break;
+        case EOpIndexDirect:   out &lt;&lt; &quot;direct index&quot;;   break;
+        case EOpIndexIndirect: out &lt;&lt; &quot;indirect index&quot;; break;
+        case EOpIndexDirectStruct:   out &lt;&lt; &quot;direct index for structure&quot;;   break;
+        case EOpVectorSwizzle: out &lt;&lt; &quot;vector swizzle&quot;; break;
+
+        case EOpAdd:    out &lt;&lt; &quot;add&quot;;                     break;
+        case EOpSub:    out &lt;&lt; &quot;subtract&quot;;                break;
+        case EOpMul:    out &lt;&lt; &quot;component-wise multiply&quot;; break;
+        case EOpDiv:    out &lt;&lt; &quot;divide&quot;;                  break;
+        case EOpEqual:            out &lt;&lt; &quot;Compare Equal&quot;;                 break;
+        case EOpNotEqual:         out &lt;&lt; &quot;Compare Not Equal&quot;;             break;
+        case EOpLessThan:         out &lt;&lt; &quot;Compare Less Than&quot;;             break;
+        case EOpGreaterThan:      out &lt;&lt; &quot;Compare Greater Than&quot;;          break;
+        case EOpLessThanEqual:    out &lt;&lt; &quot;Compare Less Than or Equal&quot;;    break;
+        case EOpGreaterThanEqual: out &lt;&lt; &quot;Compare Greater Than or Equal&quot;; break;
+
+        case EOpVectorTimesScalar: out &lt;&lt; &quot;vector-scale&quot;;          break;
+        case EOpVectorTimesMatrix: out &lt;&lt; &quot;vector-times-matrix&quot;;   break;
+        case EOpMatrixTimesVector: out &lt;&lt; &quot;matrix-times-vector&quot;;   break;
+        case EOpMatrixTimesScalar: out &lt;&lt; &quot;matrix-scale&quot;;          break;
+        case EOpMatrixTimesMatrix: out &lt;&lt; &quot;matrix-multiply&quot;;       break;
+
+        case EOpLogicalOr:  out &lt;&lt; &quot;logical-or&quot;;   break;
+        case EOpLogicalXor: out &lt;&lt; &quot;logical-xor&quot;; break;
+        case EOpLogicalAnd: out &lt;&lt; &quot;logical-and&quot;; break;
+        default: out &lt;&lt; &quot;&lt;unknown op&gt;&quot;;
+    }
+
+    out &lt;&lt; &quot; (&quot; &lt;&lt; node-&gt;getCompleteString() &lt;&lt; &quot;)&quot;;
+
+    out &lt;&lt; &quot;\n&quot;;
+
+    return true;
+}
+
+bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    OutputTreeText(out, node, depth);
+
+    switch (node-&gt;getOp()) {
+        case EOpNegative:       out &lt;&lt; &quot;Negate value&quot;;         break;
+        case EOpVectorLogicalNot:
+        case EOpLogicalNot:     out &lt;&lt; &quot;Negate conditional&quot;;   break;
+
+        case EOpPostIncrement:  out &lt;&lt; &quot;Post-Increment&quot;;       break;
+        case EOpPostDecrement:  out &lt;&lt; &quot;Post-Decrement&quot;;       break;
+        case EOpPreIncrement:   out &lt;&lt; &quot;Pre-Increment&quot;;        break;
+        case EOpPreDecrement:   out &lt;&lt; &quot;Pre-Decrement&quot;;        break;
+
+        case EOpConvIntToBool:  out &lt;&lt; &quot;Convert int to bool&quot;;  break;
+        case EOpConvFloatToBool:out &lt;&lt; &quot;Convert float to bool&quot;;break;
+        case EOpConvBoolToFloat:out &lt;&lt; &quot;Convert bool to float&quot;;break;
+        case EOpConvIntToFloat: out &lt;&lt; &quot;Convert int to float&quot;; break;
+        case EOpConvFloatToInt: out &lt;&lt; &quot;Convert float to int&quot;; break;
+        case EOpConvBoolToInt:  out &lt;&lt; &quot;Convert bool to int&quot;;  break;
+
+        case EOpRadians:        out &lt;&lt; &quot;radians&quot;;              break;
+        case EOpDegrees:        out &lt;&lt; &quot;degrees&quot;;              break;
+        case EOpSin:            out &lt;&lt; &quot;sine&quot;;                 break;
+        case EOpCos:            out &lt;&lt; &quot;cosine&quot;;               break;
+        case EOpTan:            out &lt;&lt; &quot;tangent&quot;;              break;
+        case EOpAsin:           out &lt;&lt; &quot;arc sine&quot;;             break;
+        case EOpAcos:           out &lt;&lt; &quot;arc cosine&quot;;           break;
+        case EOpAtan:           out &lt;&lt; &quot;arc tangent&quot;;          break;
+
+        case EOpExp:            out &lt;&lt; &quot;exp&quot;;                  break;
+        case EOpLog:            out &lt;&lt; &quot;log&quot;;                  break;
+        case EOpExp2:           out &lt;&lt; &quot;exp2&quot;;                 break;
+        case EOpLog2:           out &lt;&lt; &quot;log2&quot;;                 break;
+        case EOpSqrt:           out &lt;&lt; &quot;sqrt&quot;;                 break;
+        case EOpInverseSqrt:    out &lt;&lt; &quot;inverse sqrt&quot;;         break;
+
+        case EOpAbs:            out &lt;&lt; &quot;Absolute value&quot;;       break;
+        case EOpSign:           out &lt;&lt; &quot;Sign&quot;;                 break;
+        case EOpFloor:          out &lt;&lt; &quot;Floor&quot;;                break;
+        case EOpCeil:           out &lt;&lt; &quot;Ceiling&quot;;              break;
+        case EOpFract:          out &lt;&lt; &quot;Fraction&quot;;             break;
+
+        case EOpLength:         out &lt;&lt; &quot;length&quot;;               break;
+        case EOpNormalize:      out &lt;&lt; &quot;normalize&quot;;            break;
+            //  case EOpDPdx:           out &lt;&lt; &quot;dPdx&quot;;                 break;               
+            //  case EOpDPdy:           out &lt;&lt; &quot;dPdy&quot;;                 break;   
+            //  case EOpFwidth:         out &lt;&lt; &quot;fwidth&quot;;               break;                   
+
+        case EOpAny:            out &lt;&lt; &quot;any&quot;;                  break;
+        case EOpAll:            out &lt;&lt; &quot;all&quot;;                  break;
+
+        default:
+            out.prefix(EPrefixError);
+            out &lt;&lt; &quot;Bad unary op&quot;;
+    }
+
+    out &lt;&lt; &quot; (&quot; &lt;&lt; node-&gt;getCompleteString() &lt;&lt; &quot;)&quot;;
+
+    out &lt;&lt; &quot;\n&quot;;
+
+    return true;
+}
+
+bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    if (node-&gt;getOp() == EOpNull) {
+        out.prefix(EPrefixError);
+        out &lt;&lt; &quot;node is still EOpNull!&quot;;
+        return true;
+    }
+
+    OutputTreeText(out, node, depth);
+
+    switch (node-&gt;getOp()) {
+        case EOpSequence:      out &lt;&lt; &quot;Sequence\n&quot;; return true;
+        case EOpComma:         out &lt;&lt; &quot;Comma\n&quot;; return true;
+        case EOpFunction:      out &lt;&lt; &quot;Function Definition: &quot; &lt;&lt; node-&gt;getName(); break;
+        case EOpFunctionCall:  out &lt;&lt; &quot;Function Call: &quot; &lt;&lt; node-&gt;getName(); break;
+        case EOpParameters:    out &lt;&lt; &quot;Function Parameters: &quot;;              break;
+
+        case EOpConstructFloat: out &lt;&lt; &quot;Construct float&quot;; break;
+        case EOpConstructVec2:  out &lt;&lt; &quot;Construct vec2&quot;;  break;
+        case EOpConstructVec3:  out &lt;&lt; &quot;Construct vec3&quot;;  break;
+        case EOpConstructVec4:  out &lt;&lt; &quot;Construct vec4&quot;;  break;
+        case EOpConstructBool:  out &lt;&lt; &quot;Construct bool&quot;;  break;
+        case EOpConstructBVec2: out &lt;&lt; &quot;Construct bvec2&quot;; break;
+        case EOpConstructBVec3: out &lt;&lt; &quot;Construct bvec3&quot;; break;
+        case EOpConstructBVec4: out &lt;&lt; &quot;Construct bvec4&quot;; break;
+        case EOpConstructInt:   out &lt;&lt; &quot;Construct int&quot;;   break;
+        case EOpConstructIVec2: out &lt;&lt; &quot;Construct ivec2&quot;; break;
+        case EOpConstructIVec3: out &lt;&lt; &quot;Construct ivec3&quot;; break;
+        case EOpConstructIVec4: out &lt;&lt; &quot;Construct ivec4&quot;; break;
+        case EOpConstructMat2:  out &lt;&lt; &quot;Construct mat2&quot;;  break;
+        case EOpConstructMat3:  out &lt;&lt; &quot;Construct mat3&quot;;  break;
+        case EOpConstructMat4:  out &lt;&lt; &quot;Construct mat4&quot;;  break;
+        case EOpConstructStruct:  out &lt;&lt; &quot;Construct structure&quot;;  break;
+
+        case EOpLessThan:         out &lt;&lt; &quot;Compare Less Than&quot;;             break;
+        case EOpGreaterThan:      out &lt;&lt; &quot;Compare Greater Than&quot;;          break;
+        case EOpLessThanEqual:    out &lt;&lt; &quot;Compare Less Than or Equal&quot;;    break;
+        case EOpGreaterThanEqual: out &lt;&lt; &quot;Compare Greater Than or Equal&quot;; break;
+        case EOpVectorEqual:      out &lt;&lt; &quot;Equal&quot;;                         break;
+        case EOpVectorNotEqual:   out &lt;&lt; &quot;NotEqual&quot;;                      break;
+
+        case EOpMod:           out &lt;&lt; &quot;mod&quot;;         break;
+        case EOpPow:           out &lt;&lt; &quot;pow&quot;;         break;
+
+        case EOpAtan:          out &lt;&lt; &quot;arc tangent&quot;; break;
+
+        case EOpMin:           out &lt;&lt; &quot;min&quot;;         break;
+        case EOpMax:           out &lt;&lt; &quot;max&quot;;         break;
+        case EOpClamp:         out &lt;&lt; &quot;clamp&quot;;       break;
+        case EOpMix:           out &lt;&lt; &quot;mix&quot;;         break;
+        case EOpStep:          out &lt;&lt; &quot;step&quot;;        break;
+        case EOpSmoothStep:    out &lt;&lt; &quot;smoothstep&quot;;  break;
+
+        case EOpDistance:      out &lt;&lt; &quot;distance&quot;;                break;
+        case EOpDot:           out &lt;&lt; &quot;dot-product&quot;;             break;
+        case EOpCross:         out &lt;&lt; &quot;cross-product&quot;;           break;
+        case EOpFaceForward:   out &lt;&lt; &quot;face-forward&quot;;            break;
+        case EOpReflect:       out &lt;&lt; &quot;reflect&quot;;                 break;
+        case EOpRefract:       out &lt;&lt; &quot;refract&quot;;                 break;
+        case EOpMul:           out &lt;&lt; &quot;component-wise multiply&quot;; break;
+
+        case EOpDeclaration:   out &lt;&lt; &quot;Declaration: &quot;;   break;
+
+        default:
+            out.prefix(EPrefixError);
+            out &lt;&lt; &quot;Bad aggregation op&quot;;
+    }
+
+    if (node-&gt;getOp() != EOpSequence &amp;&amp; node-&gt;getOp() != EOpParameters)
+        out &lt;&lt; &quot; (&quot; &lt;&lt; node-&gt;getCompleteString() &lt;&lt; &quot;)&quot;;
+
+    out &lt;&lt; &quot;\n&quot;;
+
+    return true;
+}
+
+bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    OutputTreeText(out, node, depth);
+
+    out &lt;&lt; &quot;Test condition and select&quot;;
+    out &lt;&lt; &quot; (&quot; &lt;&lt; node-&gt;getCompleteString() &lt;&lt; &quot;)\n&quot;;
+
+    ++depth;
+
+    OutputTreeText(sink, node, depth);
+    out &lt;&lt; &quot;Condition\n&quot;;
+    node-&gt;getCondition()-&gt;traverse(this);
+
+    OutputTreeText(sink, node, depth);
+    if (node-&gt;getTrueBlock()) {
+        out &lt;&lt; &quot;true case\n&quot;;
+        node-&gt;getTrueBlock()-&gt;traverse(this);
+    } else
+        out &lt;&lt; &quot;true case is null\n&quot;;
+
+    if (node-&gt;getFalseBlock()) {
+        OutputTreeText(sink, node, depth);
+        out &lt;&lt; &quot;false case\n&quot;;
+        node-&gt;getFalseBlock()-&gt;traverse(this);
+    }
+
+    --depth;
+
+    return false;
+}
+
+void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    size_t size = node-&gt;getType().getObjectSize();
+
+    for (size_t i = 0; i &lt; size; i++) {
+        OutputTreeText(out, node, depth);
+        switch (node-&gt;getUnionArrayPointer()[i].getType()) {
+            case EbtBool:
+                if (node-&gt;getUnionArrayPointer()[i].getBConst())
+                    out &lt;&lt; &quot;true&quot;;
+                else
+                    out &lt;&lt; &quot;false&quot;;
+
+                out &lt;&lt; &quot; (&quot; &lt;&lt; &quot;const bool&quot; &lt;&lt; &quot;)&quot;;
+                out &lt;&lt; &quot;\n&quot;;
+                break;
+            case EbtFloat:
+                out &lt;&lt; node-&gt;getUnionArrayPointer()[i].getFConst();
+                out &lt;&lt; &quot; (const float)\n&quot;;
+                break;
+            case EbtInt:
+                out &lt;&lt; node-&gt;getUnionArrayPointer()[i].getIConst();
+                out &lt;&lt; &quot; (const int)\n&quot;;
+                break;
+            default:
+                out.message(EPrefixInternalError, node-&gt;getLine(), &quot;Unknown constant&quot;);
+                break;
+        }
+    }
+}
+
+bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    OutputTreeText(out, node, depth);
+
+    out &lt;&lt; &quot;Loop with condition &quot;;
+    if (node-&gt;getType() == ELoopDoWhile)
+        out &lt;&lt; &quot;not &quot;;
+    out &lt;&lt; &quot;tested first\n&quot;;
+
+    ++depth;
+
+    OutputTreeText(sink, node, depth);
+    if (node-&gt;getCondition()) {
+        out &lt;&lt; &quot;Loop Condition\n&quot;;
+        node-&gt;getCondition()-&gt;traverse(this);
+    } else
+        out &lt;&lt; &quot;No loop condition\n&quot;;
+
+    OutputTreeText(sink, node, depth);
+    if (node-&gt;getBody()) {
+        out &lt;&lt; &quot;Loop Body\n&quot;;
+        node-&gt;getBody()-&gt;traverse(this);
+    } else
+        out &lt;&lt; &quot;No loop body\n&quot;;
+
+    if (node-&gt;getExpression()) {
+        OutputTreeText(sink, node, depth);
+        out &lt;&lt; &quot;Loop Terminal Expression\n&quot;;
+        node-&gt;getExpression()-&gt;traverse(this);
+    }
+
+    --depth;
+
+    return false;
+}
+
+bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
+{
+    TInfoSinkBase&amp; out = sink;
+
+    OutputTreeText(out, node, depth);
+
+    switch (node-&gt;getFlowOp()) {
+        case EOpKill:      out &lt;&lt; &quot;Branch: Kill&quot;;           break;
+        case EOpBreak:     out &lt;&lt; &quot;Branch: Break&quot;;          break;
+        case EOpContinue:  out &lt;&lt; &quot;Branch: Continue&quot;;       break;
+        case EOpReturn:    out &lt;&lt; &quot;Branch: Return&quot;;         break;
+        default:           out &lt;&lt; &quot;Branch: Unknown Branch&quot;; break;
+    }
+
+    if (node-&gt;getExpression()) {
+        out &lt;&lt; &quot; with expression\n&quot;;
+        ++depth;
+        node-&gt;getExpression()-&gt;traverse(this);
+        --depth;
+    } else
+        out &lt;&lt; &quot;\n&quot;;
+
+    return false;
+}
+
+//
+// This function is the one to call externally to start the traversal.
+// Individual functions can be initialized to 0 to skip processing of that
+// type of node.  It's children will still be processed.
+//
+void TIntermediate::outputTree(TIntermNode* root)
+{
+    if (root == 0)
+        return;
+
+    TOutputTraverser it(infoSink.info);
+
+    root-&gt;traverse(&amp;it);
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermOut.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorintermediateh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,635 @@
</span><ins>+//
+// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// Definition of the in-memory high-level intermediate representation
+// of shaders.  This is a tree that parser creates.
+//
+// Nodes in the tree are defined as a hierarchy of classes derived from 
+// TIntermNode. Each is a node in a tree.  There is no preset branching factor;
+// each node can have it's own type of list of children.
+//
+
+#ifndef __INTERMEDIATE_H
+#define __INTERMEDIATE_H
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &lt;algorithm&gt;
+#include &quot;compiler/translator/Common.h&quot;
+#include &quot;compiler/translator/Types.h&quot;
+#include &quot;compiler/translator/ConstantUnion.h&quot;
+
+//
+// Operators used by the high-level (parse tree) representation.
+//
+enum TOperator {
+    EOpNull,            // if in a node, should only mean a node is still being built
+    EOpSequence,        // denotes a list of statements, or parameters, etc.
+    EOpFunctionCall,    
+    EOpFunction,        // For function definition
+    EOpParameters,      // an aggregate listing the parameters to a function
+
+    EOpDeclaration,
+    EOpPrototype,
+
+    //
+    // Unary operators
+    //
+
+    EOpNegative,
+    EOpLogicalNot,
+    EOpVectorLogicalNot,
+
+    EOpPostIncrement,
+    EOpPostDecrement,
+    EOpPreIncrement,
+    EOpPreDecrement,
+
+    EOpConvIntToBool,
+    EOpConvFloatToBool,
+    EOpConvBoolToFloat,
+    EOpConvIntToFloat,
+    EOpConvFloatToInt,
+    EOpConvBoolToInt,
+
+    //
+    // binary operations
+    //
+
+    EOpAdd,
+    EOpSub,
+    EOpMul,
+    EOpDiv,
+    EOpEqual,
+    EOpNotEqual,
+    EOpVectorEqual,
+    EOpVectorNotEqual,
+    EOpLessThan,
+    EOpGreaterThan,
+    EOpLessThanEqual,
+    EOpGreaterThanEqual,
+    EOpComma,
+
+    EOpVectorTimesScalar,
+    EOpVectorTimesMatrix,
+    EOpMatrixTimesVector,
+    EOpMatrixTimesScalar,
+
+    EOpLogicalOr,
+    EOpLogicalXor,
+    EOpLogicalAnd,
+
+    EOpIndexDirect,
+    EOpIndexIndirect,
+    EOpIndexDirectStruct,
+
+    EOpVectorSwizzle,
+
+    //
+    // Built-in functions potentially mapped to operators
+    //
+
+    EOpRadians,
+    EOpDegrees,
+    EOpSin,
+    EOpCos,
+    EOpTan,
+    EOpAsin,
+    EOpAcos,
+    EOpAtan,
+
+    EOpPow,
+    EOpExp,
+    EOpLog,
+    EOpExp2,
+    EOpLog2,
+    EOpSqrt,
+    EOpInverseSqrt,
+
+    EOpAbs,
+    EOpSign,
+    EOpFloor,
+    EOpCeil,
+    EOpFract,
+    EOpMod,
+    EOpMin,
+    EOpMax,
+    EOpClamp,
+    EOpMix,
+    EOpStep,
+    EOpSmoothStep,
+
+    EOpLength,
+    EOpDistance,
+    EOpDot,
+    EOpCross,
+    EOpNormalize,
+    EOpFaceForward,
+    EOpReflect,
+    EOpRefract,
+
+    EOpDFdx,            // Fragment only, OES_standard_derivatives extension
+    EOpDFdy,            // Fragment only, OES_standard_derivatives extension
+    EOpFwidth,          // Fragment only, OES_standard_derivatives extension
+
+    EOpMatrixTimesMatrix,
+
+    EOpAny,
+    EOpAll,
+
+    //
+    // Branch
+    //
+
+    EOpKill,            // Fragment only
+    EOpReturn,
+    EOpBreak,
+    EOpContinue,
+
+    //
+    // Constructors
+    //
+
+    EOpConstructInt,
+    EOpConstructBool,
+    EOpConstructFloat,
+    EOpConstructVec2,
+    EOpConstructVec3,
+    EOpConstructVec4,
+    EOpConstructBVec2,
+    EOpConstructBVec3,
+    EOpConstructBVec4,
+    EOpConstructIVec2,
+    EOpConstructIVec3,
+    EOpConstructIVec4,
+    EOpConstructMat2,
+    EOpConstructMat3,
+    EOpConstructMat4,
+    EOpConstructStruct,
+
+    //
+    // moves
+    //
+
+    EOpAssign,
+    EOpInitialize,
+    EOpAddAssign,
+    EOpSubAssign,
+    EOpMulAssign,
+    EOpVectorTimesMatrixAssign,
+    EOpVectorTimesScalarAssign,
+    EOpMatrixTimesScalarAssign,
+    EOpMatrixTimesMatrixAssign,
+    EOpDivAssign
+};
+
+extern const char* getOperatorString(TOperator op);
+
+class TIntermTraverser;
+class TIntermAggregate;
+class TIntermBinary;
+class TIntermUnary;
+class TIntermConstantUnion;
+class TIntermSelection;
+class TIntermTyped;
+class TIntermSymbol;
+class TIntermLoop;
+class TInfoSink;
+
+//
+// Base class for the tree nodes
+//
+class TIntermNode {
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermNode() {
+        // TODO: Move this to TSourceLoc constructor
+        // after getting rid of TPublicType.
+        line.first_file = line.last_file = 0;
+        line.first_line = line.last_line = 0;
+    }
+    virtual ~TIntermNode() { }
+
+    const TSourceLoc&amp; getLine() const { return line; }
+    void setLine(const TSourceLoc&amp; l) { line = l; }
+
+    virtual void traverse(TIntermTraverser*) = 0;
+    virtual TIntermTyped* getAsTyped() { return 0; }
+    virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
+    virtual TIntermAggregate* getAsAggregate() { return 0; }
+    virtual TIntermBinary* getAsBinaryNode() { return 0; }
+    virtual TIntermUnary* getAsUnaryNode() { return 0; }
+    virtual TIntermSelection* getAsSelectionNode() { return 0; }
+    virtual TIntermSymbol* getAsSymbolNode() { return 0; }
+    virtual TIntermLoop* getAsLoopNode() { return 0; }
+
+    // Replace a child node. Return true if |original| is a child
+    // node and it is replaced; otherwise, return false.
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement) = 0;
+
+protected:
+    TSourceLoc line;
+};
+
+//
+// This is just to help yacc.
+//
+struct TIntermNodePair {
+    TIntermNode* node1;
+    TIntermNode* node2;
+};
+
+//
+// Intermediate class for nodes that have a type.
+//
+class TIntermTyped : public TIntermNode {
+public:
+    TIntermTyped(const TType&amp; t) : type(t)  { }
+    virtual TIntermTyped* getAsTyped() { return this; }
+
+    virtual bool hasSideEffects() const = 0;
+
+    void setType(const TType&amp; t) { type = t; }
+    const TType&amp; getType() const { return type; }
+    TType* getTypePointer() { return &amp;type; }
+
+    TBasicType getBasicType() const { return type.getBasicType(); }
+    TQualifier getQualifier() const { return type.getQualifier(); }
+    TPrecision getPrecision() const { return type.getPrecision(); }
+    int getNominalSize() const { return type.getNominalSize(); }
+    
+    bool isMatrix() const { return type.isMatrix(); }
+    bool isArray()  const { return type.isArray(); }
+    bool isVector() const { return type.isVector(); }
+    bool isScalar() const { return type.isScalar(); }
+    const char* getBasicString() const { return type.getBasicString(); }
+    const char* getQualifierString() const { return type.getQualifierString(); }
+    TString getCompleteString() const { return type.getCompleteString(); }
+
+    int totalRegisterCount() const { return type.totalRegisterCount(); }
+    int elementRegisterCount() const { return type.elementRegisterCount(); }
+    int getArraySize() const { return type.getArraySize(); }
+
+protected:
+    TType type;
+};
+
+//
+// Handle for, do-while, and while loops.
+//
+enum TLoopType {
+    ELoopFor,
+    ELoopWhile,
+    ELoopDoWhile
+};
+
+class TIntermLoop : public TIntermNode {
+public:
+    TIntermLoop(TLoopType aType,
+                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
+                TIntermNode* aBody) :
+            type(aType),
+            init(aInit),
+            cond(aCond),
+            expr(aExpr),
+            body(aBody),
+            unrollFlag(false) { }
+
+    virtual TIntermLoop* getAsLoopNode() { return this; }
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    TLoopType getType() const { return type; }
+    TIntermNode* getInit() { return init; }
+    TIntermTyped* getCondition() { return cond; }
+    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.
+};
+
+//
+// Handle break, continue, return, and kill.
+//
+class TIntermBranch : public TIntermNode {
+public:
+    TIntermBranch(TOperator op, TIntermTyped* e) :
+            flowOp(op),
+            expression(e) { }
+
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    TOperator getFlowOp() { return flowOp; }
+    TIntermTyped* getExpression() { return expression; }
+
+protected:
+    TOperator flowOp;
+    TIntermTyped* expression;  // non-zero except for &quot;return exp;&quot; statements
+};
+
+//
+// Nodes that correspond to symbols or constants in the source code.
+//
+class TIntermSymbol : public TIntermTyped {
+public:
+    // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
+    // per process globalpoolallocator, then it causes increased memory usage per compile
+    // it is essential to use &quot;symbol = sym&quot; to assign to symbol
+    TIntermSymbol(int i, const TString&amp; sym, const TType&amp; t) : 
+            TIntermTyped(t), id(i)  { symbol = sym; originalSymbol = sym; } 
+
+    virtual bool hasSideEffects() const { return false; }
+
+    int getId() const { return id; }
+    const TString&amp; getSymbol() const { return symbol; }
+
+    void setId(int newId) { id = newId; }
+    void setSymbol(const TString&amp; sym) { symbol = sym; }
+
+    const TString&amp; getOriginalSymbol() const { return originalSymbol; }
+
+    virtual void traverse(TIntermTraverser*);
+    virtual TIntermSymbol* getAsSymbolNode() { return this; }
+    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+
+protected:
+    int id;
+    TString symbol;
+    TString originalSymbol;
+};
+
+class TIntermConstantUnion : public TIntermTyped {
+public:
+    TIntermConstantUnion(ConstantUnion *unionPointer, const TType&amp; t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+
+    virtual bool hasSideEffects() const { return false; }
+
+    ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
+    
+    int getIConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
+    float getFConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
+    bool getBConst(size_t index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
+
+    virtual TIntermConstantUnion* getAsConstantUnion()  { return this; }
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(TIntermNode *, TIntermNode *) { return false; }
+
+    TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&amp;);
+
+protected:
+    ConstantUnion *unionArrayPointer;
+};
+
+//
+// Intermediate class for node types that hold operators.
+//
+class TIntermOperator : public TIntermTyped {
+public:
+    TOperator getOp() const { return op; }
+    void setOp(TOperator o) { op = o; }
+
+    bool isAssignment() const;
+    bool isConstructor() const;
+
+    virtual bool hasSideEffects() const { return isAssignment(); }
+
+protected:
+    TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
+    TIntermOperator(TOperator o, const TType&amp; t) : TIntermTyped(t), op(o) {}
+    TOperator op;
+};
+
+//
+// Nodes for all the basic binary math operators.
+//
+class TIntermBinary : public TIntermOperator {
+public:
+    TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
+
+    virtual TIntermBinary* getAsBinaryNode() { return this; }
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    virtual bool hasSideEffects() const { return (isAssignment() || left-&gt;hasSideEffects() || right-&gt;hasSideEffects()); }
+
+    void setLeft(TIntermTyped* n) { left = n; }
+    void setRight(TIntermTyped* n) { right = n; }
+    TIntermTyped* getLeft() const { return left; }
+    TIntermTyped* getRight() const { return right; }
+    bool promote(TInfoSink&amp;);
+
+    void setAddIndexClamp() { addIndexClamp = true; }
+    bool getAddIndexClamp() { return addIndexClamp; }
+
+protected:
+    TIntermTyped* left;
+    TIntermTyped* right;
+
+    // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
+    bool addIndexClamp;
+};
+
+//
+// Nodes for unary math operators.
+//
+class TIntermUnary : public TIntermOperator {
+public:
+    TIntermUnary(TOperator o, const TType&amp; 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; }
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    virtual bool hasSideEffects() const { return (isAssignment() || operand-&gt;hasSideEffects()); }
+
+    void setOperand(TIntermTyped* o) { operand = o; }
+    TIntermTyped* getOperand() { return operand; }    
+    bool promote(TInfoSink&amp;);
+
+    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&lt;TIntermNode*&gt; TIntermSequence;
+typedef TVector&lt;int&gt; TQualifierList;
+
+//
+// Nodes that operate on an arbitrary sized set of children.
+//
+class TIntermAggregate : public TIntermOperator {
+public:
+    TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
+    TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
+    ~TIntermAggregate() { }
+
+    virtual TIntermAggregate* getAsAggregate() { return this; }
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    // Conservatively assume function calls and other aggregate operators have side-effects
+    virtual bool hasSideEffects() const { return true; }
+
+    TIntermSequence&amp; getSequence() { return sequence; }
+
+    void setName(const TString&amp; n) { name = n; }
+    const TString&amp; getName() const { return name; }
+
+    void setUserDefined() { userDefined = true; }
+    bool isUserDefined() const { return userDefined; }
+
+    void setOptimize(bool o) { optimize = o; }
+    bool getOptimize() { return optimize; }
+    void setDebug(bool d) { debug = d; }
+    bool getDebug() { return debug; }
+
+    void setUseEmulatedFunction() { useEmulatedFunction = true; }
+    bool getUseEmulatedFunction() { return useEmulatedFunction; }
+
+protected:
+    TIntermAggregate(const TIntermAggregate&amp;); // disallow copy constructor
+    TIntermAggregate&amp; operator=(const TIntermAggregate&amp;); // disallow assignment operator
+    TIntermSequence sequence;
+    TString name;
+    bool userDefined; // used for user defined function names
+
+    bool optimize;
+    bool debug;
+
+    // If set to true, replace the built-in function call with an emulated one
+    // to work around driver bugs.
+    bool useEmulatedFunction;
+};
+
+//
+// For if tests.  Simplified since there is no switch statement.
+//
+class TIntermSelection : public TIntermTyped {
+public:
+    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
+            TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+    TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType&amp; type) :
+            TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+
+    virtual void traverse(TIntermTraverser*);
+    virtual bool replaceChildNode(
+        TIntermNode *original, TIntermNode *replacement);
+
+    // Conservatively assume selections have side-effects
+    virtual bool hasSideEffects() const { return true; }
+
+    bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
+    TIntermNode* getCondition() const { return condition; }
+    TIntermNode* getTrueBlock() const { return trueBlock; }
+    TIntermNode* getFalseBlock() const { return falseBlock; }
+    TIntermSelection* getAsSelectionNode() { return this; }
+
+protected:
+    TIntermTyped* condition;
+    TIntermNode* trueBlock;
+    TIntermNode* falseBlock;
+};
+
+enum Visit
+{
+    PreVisit,
+    InVisit,
+    PostVisit
+};
+
+//
+// For traversing the tree.  User should derive from this, 
+// put their traversal specific data in it, and then pass
+// it to a Traverse method.
+//
+// When using this, just fill in the methods for nodes you want visited.
+// Return false from a pre-visit to skip visiting that node's subtree.
+//
+class TIntermTraverser
+{
+public:
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) : 
+            preVisit(preVisit),
+            inVisit(inVisit),
+            postVisit(postVisit),
+            rightToLeft(rightToLeft),
+            depth(0),
+            maxDepth(0) {}
+    virtual ~TIntermTraverser() {}
+
+    virtual void visitSymbol(TIntermSymbol*) {}
+    virtual void visitConstantUnion(TIntermConstantUnion*) {}
+    virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
+    virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
+    virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
+    virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
+    virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
+    virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
+
+    int getMaxDepth() const {return maxDepth;}
+
+    void incrementDepth(TIntermNode *current)
+    {
+        depth++;
+        maxDepth = std::max(maxDepth, depth);
+        path.push_back(current);
+    }
+
+    void decrementDepth()
+    {
+        depth--;
+        path.pop_back();
+    }
+
+    TIntermNode *getParentNode()
+    {
+        return path.size() == 0 ? NULL : path.back();
+    }
+
+    // Return the original name if hash function pointer is NULL;
+    // otherwise return the hashed name.
+    static TString hash(const TString&amp; name, ShHashFunction64 hashFunction);
+
+    const bool preVisit;
+    const bool inVisit;
+    const bool postVisit;
+    const bool rightToLeft;
+
+protected:
+    int depth;
+    int maxDepth;
+
+    // All the nodes from root to the current node's parent during traversing.
+    TVector&lt;TIntermNode *&gt; path;
+};
+
+#endif // __INTERMEDIATE_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/intermediate.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorlocalintermediateh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/localintermediate.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/localintermediate.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/localintermediate.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef _LOCAL_INTERMEDIATE_INCLUDED_
+#define _LOCAL_INTERMEDIATE_INCLUDED_
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/SymbolTable.h&quot;
+
+struct TVectorFields {
+    int offsets[4];
+    int num;
+};
+
+//
+// Set of helper functions to help parse and build the tree.
+//
+class TInfoSink;
+class TIntermediate {
+public:    
+    POOL_ALLOCATOR_NEW_DELETE();
+    TIntermediate(TInfoSink&amp; i) : infoSink(i) { }
+
+    TIntermSymbol* addSymbol(int Id, const TString&amp;, const TType&amp;, const TSourceLoc&amp;);
+    TIntermTyped* addConversion(TOperator, const TType&amp;, TIntermTyped*);
+    TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp;, TSymbolTable&amp;);
+    TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp;);
+    TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, const TSourceLoc&amp;);
+    TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, const TSourceLoc&amp;, TSymbolTable&amp;);
+    TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&amp;);
+    TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&amp;);
+    TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, const TSourceLoc&amp;);
+    TIntermNode*  addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&amp;);
+    TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&amp;);
+    TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&amp;);
+    TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&amp;, const TSourceLoc&amp;);
+    TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
+    bool parseConstTree(const TSourceLoc&amp;, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&amp;, TType, bool singleConstantParam = false);        
+    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, const TSourceLoc&amp;);
+    TIntermBranch* addBranch(TOperator, const TSourceLoc&amp;);
+    TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&amp;);
+    TIntermTyped* addSwizzle(TVectorFields&amp;, const TSourceLoc&amp;);
+    bool postProcess(TIntermNode*);
+    void remove(TIntermNode*);
+    void outputTree(TIntermNode*);
+
+private:
+    void operator=(TIntermediate&amp;); // prevent assignments
+
+    TInfoSink&amp; infoSink;
+};
+
+#endif // _LOCAL_INTERMEDIATE_INCLUDED_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/localintermediate.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorosincludeh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/osinclude.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/osinclude.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/osinclude.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef __OSINCLUDE_H
+#define __OSINCLUDE_H
+
+//
+// This file contains contains os-specific datatypes and
+// declares any os-specific functions.
+//
+
+#if defined(_WIN32) || defined(_WIN64)
+#define ANGLE_OS_WIN
+#elif defined(__APPLE__) || defined(__linux__) || \
+      defined(__FreeBSD__) || defined(__OpenBSD__) || \
+      defined(__NetBSD__) || defined(__DragonFly__) || \
+      defined(__sun) || defined(ANDROID) || \
+      defined(__GLIBC__) || defined(__GNU__) || \
+      defined(__QNX__)
+#define ANGLE_OS_POSIX
+#else
+#error Unsupported platform.
+#endif
+
+#if defined(ANGLE_OS_WIN)
+#define STRICT
+#define VC_EXTRALEAN 1
+#include &lt;windows.h&gt;
+#elif defined(ANGLE_OS_POSIX)
+#include &lt;pthread.h&gt;
+#include &lt;semaphore.h&gt;
+#include &lt;errno.h&gt;
+#endif  // ANGLE_OS_WIN
+
+
+#include &quot;compiler/translator/compilerdebug.h&quot;
+
+//
+// Thread Local Storage Operations
+//
+#if defined(ANGLE_OS_WIN)
+typedef DWORD OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES)
+#elif defined(ANGLE_OS_POSIX)
+typedef pthread_key_t OS_TLSIndex;
+#define OS_INVALID_TLS_INDEX (static_cast&lt;OS_TLSIndex&gt;(-1))
+#endif  // ANGLE_OS_WIN
+
+OS_TLSIndex OS_AllocTLSIndex();
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex);
+
+inline void* OS_GetTLSValue(OS_TLSIndex nIndex)
+{
+    ASSERT(nIndex != OS_INVALID_TLS_INDEX);
+#if defined(ANGLE_OS_WIN)
+    return TlsGetValue(nIndex);
+#elif defined(ANGLE_OS_POSIX)
+    return pthread_getspecific(nIndex);
+#endif  // ANGLE_OS_WIN
+}
+
+#endif // __OSINCLUDE_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/osinclude.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorossource_posixcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_posix.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_posix.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_posix.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,64 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+//
+// This file contains the posix specific functions
+//
+#include &quot;compiler/translator/osinclude.h&quot;
+
+#if !defined(ANGLE_OS_POSIX)
+#error Trying to build a posix specific file in a non-posix build.
+#endif
+
+//
+// Thread Local Storage Operations
+//
+OS_TLSIndex OS_AllocTLSIndex()
+{
+    pthread_key_t pPoolIndex;
+
+    //
+    // Create global pool key.
+    //
+    if ((pthread_key_create(&amp;pPoolIndex, NULL)) != 0) {
+        assert(0 &amp;&amp; &quot;OS_AllocTLSIndex(): Unable to allocate Thread Local Storage&quot;);
+        return false;
+    }
+    else {
+        return pPoolIndex;
+    }
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+    if (nIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 &amp;&amp; &quot;OS_SetTLSValue(): Invalid TLS Index&quot;);
+        return false;
+    }
+
+    if (pthread_setspecific(nIndex, lpvValue) == 0)
+        return true;
+    else
+        return false;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+    if (nIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 &amp;&amp; &quot;OS_SetTLSValue(): Invalid TLS Index&quot;);
+        return false;
+    }
+
+    //
+    // Delete the global pool key.
+    //
+    if (pthread_key_delete(nIndex) == 0)
+        return true;
+    else
+        return false;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_posix.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorossource_wincpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_win.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_win.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_win.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/osinclude.h&quot;
+//
+// This file contains contains the window's specific functions
+//
+
+#if !defined(ANGLE_OS_WIN)
+#error Trying to build a windows specific file in a non windows build.
+#endif
+
+
+//
+// Thread Local Storage Operations
+//
+OS_TLSIndex OS_AllocTLSIndex()
+{
+    DWORD dwIndex = TlsAlloc();
+    if (dwIndex == TLS_OUT_OF_INDEXES) {
+        assert(0 &amp;&amp; &quot;OS_AllocTLSIndex(): Unable to allocate Thread Local Storage&quot;);
+        return OS_INVALID_TLS_INDEX;
+    }
+
+    return dwIndex;
+}
+
+
+bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue)
+{
+    if (nIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 &amp;&amp; &quot;OS_SetTLSValue(): Invalid TLS Index&quot;);
+        return false;
+    }
+
+    if (TlsSetValue(nIndex, lpvValue))
+        return true;
+    else
+        return false;
+}
+
+
+bool OS_FreeTLSIndex(OS_TLSIndex nIndex)
+{
+    if (nIndex == OS_INVALID_TLS_INDEX) {
+        assert(0 &amp;&amp; &quot;OS_SetTLSValue(): Invalid TLS Index&quot;);
+        return false;
+    }
+
+    if (TlsFree(nIndex))
+        return true;
+    else
+        return false;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/ossource_win.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorparseConstcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,245 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/ParseContext.h&quot;
+
+//
+// Use this class to carry along data from node to node in 
+// the traversal
+//
+class TConstTraverser : public TIntermTraverser {
+public:
+    TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink&amp; sink, TSymbolTable&amp; symTable, TType&amp; t)
+        : error(false),
+          index(0),
+          unionArray(cUnion),
+          type(t),
+          constructorType(constructType),
+          singleConstantParam(singleConstParam),
+          infoSink(sink),
+          symbolTable(symTable),
+          size(0),
+          isMatrix(false),
+          matrixSize(0) {
+    }
+
+    bool error;
+
+protected:
+    void visitSymbol(TIntermSymbol*);
+    void visitConstantUnion(TIntermConstantUnion*);
+    bool visitBinary(Visit visit, TIntermBinary*);
+    bool visitUnary(Visit visit, TIntermUnary*);
+    bool visitSelection(Visit visit, TIntermSelection*);
+    bool visitAggregate(Visit visit, TIntermAggregate*);
+    bool visitLoop(Visit visit, TIntermLoop*);
+    bool visitBranch(Visit visit, TIntermBranch*);
+
+    size_t index;
+    ConstantUnion *unionArray;
+    TType type;
+    TOperator constructorType;
+    bool singleConstantParam;
+    TInfoSink&amp; infoSink;
+    TSymbolTable&amp; symbolTable;
+    size_t size; // size of the constructor ( 4 for vec4)
+    bool isMatrix;
+    size_t matrixSize; // dimension of the matrix (nominal size and not the instance size)
+};
+
+//
+// The rest of the file are the traversal functions.  The last one
+// is the one that starts the traversal.
+//
+// Return true from interior nodes to have the external traversal
+// continue on to children.  If you process children yourself,
+// return false.
+//
+
+void TConstTraverser::visitSymbol(TIntermSymbol* node)
+{
+    infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Symbol Node found in constant constructor&quot;);
+    return;
+
+}
+
+bool TConstTraverser::visitBinary(Visit visit, TIntermBinary* node)
+{
+    TQualifier qualifier = node-&gt;getType().getQualifier();
+    
+    if (qualifier != EvqConst) {
+        TString buf;
+        buf.append(&quot;'constructor' : assigning non-constant to &quot;);
+        buf.append(type.getCompleteString());
+        infoSink.info.message(EPrefixError, node-&gt;getLine(), buf.c_str());
+        error = true;
+        return false;  
+    }
+
+   infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Binary Node found in constant constructor&quot;);
+    
+    return false;
+}
+
+bool TConstTraverser::visitUnary(Visit visit, TIntermUnary* node)
+{
+    TString buf;
+    buf.append(&quot;'constructor' : assigning non-constant to &quot;);
+    buf.append(type.getCompleteString());
+    infoSink.info.message(EPrefixError, node-&gt;getLine(), buf.c_str());
+    error = true;
+    return false;  
+}
+
+bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    if (!node-&gt;isConstructor() &amp;&amp; node-&gt;getOp() != EOpComma) {
+        TString buf;
+        buf.append(&quot;'constructor' : assigning non-constant to &quot;);
+        buf.append(type.getCompleteString());
+        infoSink.info.message(EPrefixError, node-&gt;getLine(), buf.c_str());
+        error = true;
+        return false;  
+    }
+
+    if (node-&gt;getSequence().size() == 0) {
+        error = true;
+        return false;
+    }
+
+    bool flag = node-&gt;getSequence().size() == 1 &amp;&amp; node-&gt;getSequence()[0]-&gt;getAsTyped()-&gt;getAsConstantUnion();
+    if (flag) 
+    {
+        singleConstantParam = true; 
+        constructorType = node-&gt;getOp();
+        size = node-&gt;getType().getObjectSize();
+
+        if (node-&gt;getType().isMatrix()) {
+            isMatrix = true;
+            matrixSize = node-&gt;getType().getNominalSize();
+        }
+    }       
+
+    for (TIntermSequence::iterator p = node-&gt;getSequence().begin(); 
+                                   p != node-&gt;getSequence().end(); p++) {
+
+        if (node-&gt;getOp() == EOpComma)
+            index = 0;           
+
+        (*p)-&gt;traverse(this);
+    }   
+    if (flag) 
+    {
+        singleConstantParam = false;   
+        constructorType = EOpNull;
+        size = 0;
+        isMatrix = false;
+        matrixSize = 0;
+    }
+    return false;
+}
+
+bool TConstTraverser::visitSelection(Visit visit, TIntermSelection* node)
+{
+    infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Selection Node found in constant constructor&quot;);
+    error = true;
+    return false;
+}
+
+void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
+{
+    if (!node-&gt;getUnionArrayPointer())
+    {
+        // The constant was not initialized, this should already have been logged
+        assert(infoSink.info.size() != 0);
+        return;
+    }
+
+    ConstantUnion* leftUnionArray = unionArray;
+    size_t instanceSize = type.getObjectSize();
+
+    if (index &gt;= instanceSize)
+        return;
+
+    if (!singleConstantParam) {
+        size_t size = node-&gt;getType().getObjectSize();
+    
+        ConstantUnion *rightUnionArray = node-&gt;getUnionArrayPointer();
+        for (size_t i = 0; i &lt; size; i++) {
+            if (index &gt;= instanceSize)
+                return;
+            leftUnionArray[index] = rightUnionArray[i];
+
+            (index)++;
+        }
+    } else {
+        size_t totalSize = index + size;
+        ConstantUnion *rightUnionArray = node-&gt;getUnionArrayPointer();
+        if (!isMatrix) {
+            size_t count = 0;
+            for (size_t i = index; i &lt; totalSize; i++) {
+                if (i &gt;= instanceSize)
+                    return;
+
+                leftUnionArray[i] = rightUnionArray[count];
+
+                (index)++;
+                
+                if (node-&gt;getType().getObjectSize() &gt; 1)
+                    count++;
+            }
+        } else {  // for matrix constructors
+            size_t count = 0;
+            size_t element = index;
+            for (size_t i = index; i &lt; totalSize; i++) {
+                if (i &gt;= instanceSize)
+                    return;
+                if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 )
+                    leftUnionArray[i] = rightUnionArray[count];
+                else 
+                    leftUnionArray[i].setFConst(0.0f);
+
+                (index)++;
+
+                if (node-&gt;getType().getObjectSize() &gt; 1)
+                    count++;                
+            }
+        }
+    }
+}
+
+bool TConstTraverser::visitLoop(Visit visit, TIntermLoop* node)
+{
+    infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Loop Node found in constant constructor&quot;);
+    error = true;
+    return false;
+}
+
+bool TConstTraverser::visitBranch(Visit visit, TIntermBranch* node)
+{
+    infoSink.info.message(EPrefixInternalError, node-&gt;getLine(), &quot;Branch Node found in constant constructor&quot;);
+    error = true;
+    return false;
+}
+
+//
+// This function is the one to call externally to start the traversal.
+// Individual functions can be initialized to 0 to skip processing of that
+// type of node.  It's children will still be processed.
+//
+bool TIntermediate::parseConstTree(const TSourceLoc&amp; line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable&amp; symbolTable, TType t, bool singleConstantParam)
+{
+    if (root == 0)
+        return false;
+
+    TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t);
+
+    root-&gt;traverse(&amp;it);
+    if (it.error)
+        return true;
+    else
+        return false;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/parseConst.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictFragmentShaderTimingcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,127 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/InfoSink.h&quot;
+#include &quot;compiler/translator/ParseContext.h&quot;
+#include &quot;compiler/translator/depgraph/DependencyGraphOutput.h&quot;
+#include &quot;compiler/translator/timing/RestrictFragmentShaderTiming.h&quot;
+
+RestrictFragmentShaderTiming::RestrictFragmentShaderTiming(TInfoSinkBase&amp; sink)
+    : mSink(sink)
+    , mNumErrors(0)
+{
+    // Sampling ops found only in fragment shaders.
+    mSamplingOps.insert(&quot;texture2D(s21;vf2;f1;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(s21;vf3;f1;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(s21;vf4;f1;&quot;);
+    mSamplingOps.insert(&quot;textureCube(sC1;vf3;f1;&quot;);
+    // Sampling ops found in both vertex and fragment shaders.
+    mSamplingOps.insert(&quot;texture2D(s21;vf2;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(s21;vf3;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(s21;vf4;&quot;);
+    mSamplingOps.insert(&quot;textureCube(sC1;vf3;&quot;);
+    // Sampling ops provided by OES_EGL_image_external.
+    mSamplingOps.insert(&quot;texture2D(1;vf2;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(1;vf3;&quot;);
+    mSamplingOps.insert(&quot;texture2DProj(1;vf4;&quot;);
+    // Sampling ops provided by ARB_texture_rectangle.
+    mSamplingOps.insert(&quot;texture2DRect(1;vf2;&quot;);
+    mSamplingOps.insert(&quot;texture2DRectProj(1;vf3;&quot;);
+    mSamplingOps.insert(&quot;texture2DRectProj(1;vf4;&quot;);
+}
+
+// FIXME(mvujovic): We do not know if the execution time of built-in operations like sin, pow, etc.
+// can vary based on the value of the input arguments. If so, we should restrict those as well.
+void RestrictFragmentShaderTiming::enforceRestrictions(const TDependencyGraph&amp; graph)
+{
+    mNumErrors = 0;
+
+    // FIXME(mvujovic): The dependency graph does not support user defined function calls right now,
+    // so we generate errors for them.
+    validateUserDefinedFunctionCallUsage(graph);
+
+    // Starting from each sampler, traverse the dependency graph and generate an error each time we
+    // hit a node where sampler dependent values are not allowed.
+    for (TGraphSymbolVector::const_iterator iter = graph.beginSamplerSymbols();
+         iter != graph.endSamplerSymbols();
+         ++iter)
+    {
+        TGraphSymbol* samplerSymbol = *iter;
+        clearVisited();
+        samplerSymbol-&gt;traverse(this);
+    }
+}
+
+void RestrictFragmentShaderTiming::validateUserDefinedFunctionCallUsage(const TDependencyGraph&amp; graph)
+{
+    for (TFunctionCallVector::const_iterator iter = graph.beginUserDefinedFunctionCalls();
+         iter != graph.endUserDefinedFunctionCalls();
+         ++iter)
+    {
+        TGraphFunctionCall* functionCall = *iter;
+        beginError(functionCall-&gt;getIntermFunctionCall());
+        mSink &lt;&lt; &quot;A call to a user defined function is not permitted.\n&quot;;
+    }
+}
+
+void RestrictFragmentShaderTiming::beginError(const TIntermNode* node)
+{
+    ++mNumErrors;
+    mSink.prefix(EPrefixError);
+    mSink.location(node-&gt;getLine());
+}
+
+bool RestrictFragmentShaderTiming::isSamplingOp(const TIntermAggregate* intermFunctionCall) const
+{
+    return !intermFunctionCall-&gt;isUserDefined() &amp;&amp;
+           mSamplingOps.find(intermFunctionCall-&gt;getName()) != mSamplingOps.end();
+}
+
+void RestrictFragmentShaderTiming::visitArgument(TGraphArgument* parameter)
+{
+    // Texture cache access time might leak sensitive information.
+    // Thus, we restrict sampler dependent values from affecting the coordinate or LOD bias of a
+    // sampling operation.
+    if (isSamplingOp(parameter-&gt;getIntermFunctionCall())) {
+        switch (parameter-&gt;getArgumentNumber()) {
+            case 1:
+                // Second argument (coord)
+                beginError(parameter-&gt;getIntermFunctionCall());
+                mSink &lt;&lt; &quot;An expression dependent on a sampler is not permitted to be the&quot;
+                      &lt;&lt; &quot; coordinate argument of a sampling operation.\n&quot;;
+                break;
+            case 2:
+                // Third argument (bias)
+                beginError(parameter-&gt;getIntermFunctionCall());
+                mSink &lt;&lt; &quot;An expression dependent on a sampler is not permitted to be the&quot;
+                      &lt;&lt; &quot; bias argument of a sampling operation.\n&quot;;
+                break;
+            default:
+                // First argument (sampler)
+                break;
+        }
+    }
+}
+
+void RestrictFragmentShaderTiming::visitSelection(TGraphSelection* selection)
+{
+    beginError(selection-&gt;getIntermSelection());
+    mSink &lt;&lt; &quot;An expression dependent on a sampler is not permitted in a conditional statement.\n&quot;;
+}
+
+void RestrictFragmentShaderTiming::visitLoop(TGraphLoop* loop)
+{
+    beginError(loop-&gt;getIntermLoop());
+    mSink &lt;&lt; &quot;An expression dependent on a sampler is not permitted in a loop condition.\n&quot;;
+}
+
+void RestrictFragmentShaderTiming::visitLogicalOp(TGraphLogicalOp* logicalOp)
+{
+    beginError(logicalOp-&gt;getIntermLogicalOp());
+    mSink &lt;&lt; &quot;An expression dependent on a sampler is not permitted on the left hand side of a logical &quot;
+          &lt;&lt; logicalOp-&gt;getOpString()
+          &lt;&lt; &quot; operator.\n&quot;;
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictFragmentShaderTimingh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
+#define COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/depgraph/DependencyGraph.h&quot;
+
+class TInfoSinkBase;
+
+class RestrictFragmentShaderTiming : TDependencyGraphTraverser {
+public:
+    RestrictFragmentShaderTiming(TInfoSinkBase&amp; sink);
+    void enforceRestrictions(const TDependencyGraph&amp; graph);
+    int numErrors() const { return mNumErrors; }
+
+    virtual void visitArgument(TGraphArgument* parameter);
+    virtual void visitSelection(TGraphSelection* selection);
+    virtual void visitLoop(TGraphLoop* loop);
+    virtual void visitLogicalOp(TGraphLogicalOp* logicalOp);
+
+private:
+    void beginError(const TIntermNode* node);
+    void validateUserDefinedFunctionCallUsage(const TDependencyGraph&amp; graph);
+    bool isSamplingOp(const TIntermAggregate* intermFunctionCall) const;
+
+    TInfoSinkBase&amp; mSink;
+    int mNumErrors;
+
+    typedef std::set&lt;TString&gt; StringSet;
+    StringSet mSamplingOps;
+};
+
+#endif  // COMPILER_TIMING_RESTRICT_FRAGMENT_SHADER_TIMING_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictFragmentShaderTiming.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictVertexShaderTimingcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,17 @@
</span><ins>+//
+// 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.
+//
+
+#include &quot;compiler/translator/timing/RestrictVertexShaderTiming.h&quot;
+
+void RestrictVertexShaderTiming::visitSymbol(TIntermSymbol* node)
+{
+    if (IsSampler(node-&gt;getBasicType())) {
+        ++mNumErrors;
+        mSink.message(EPrefixError,
+                      node-&gt;getLine(),
+                      &quot;Samplers are not permitted in vertex shaders&quot;);
+    }
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatortimingRestrictVertexShaderTimingh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+//
+// 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.
+//
+
+#ifndef COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
+#define COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
+
+#include &quot;GLSLANG/ShaderLang.h&quot;
+
+#include &quot;compiler/translator/intermediate.h&quot;
+#include &quot;compiler/translator/InfoSink.h&quot;
+
+class TInfoSinkBase;
+
+class RestrictVertexShaderTiming : public TIntermTraverser {
+public:
+    RestrictVertexShaderTiming(TInfoSinkBase&amp; sink)
+        : TIntermTraverser(true, false, false)
+        , mSink(sink)
+        , mNumErrors(0) {}
+
+    void enforceRestrictions(TIntermNode* root) { root-&gt;traverse(this); }
+    int numErrors() { return mNumErrors; }
+
+    virtual void visitSymbol(TIntermSymbol*);
+private:
+    TInfoSinkBase&amp; mSink;
+    int mNumErrors;
+};
+
+#endif  // COMPILER_TIMING_RESTRICT_VERTEX_SHADER_TIMING_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/timing/RestrictVertexShaderTiming.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorutilcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+//
+// Copyright (c) 2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include &quot;compiler/translator/util.h&quot;
+
+#include &lt;limits&gt;
+
+#include &quot;compiler/preprocessor/numeric_lex.h&quot;
+
+bool atof_clamp(const char *str, float *value)
+{
+    bool success = pp::numeric_lex_float(str, value);
+    if (!success)
+        *value = std::numeric_limits&lt;float&gt;::max();
+    return success;
+}
+
+bool atoi_clamp(const char *str, int *value)
+{
+    bool success = pp::numeric_lex_int(str, value);
+    if (!success)
+        *value = std::numeric_limits&lt;int&gt;::max();
+    return success;
+}
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrccompilertranslatorutilh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,20 @@
</span><ins>+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_UTIL_H
+#define COMPILER_UTIL_H
+
+// atof_clamp is like atof but
+//   1. it forces C locale, i.e. forcing '.' as decimal point.
+//   2. it clamps the value to -FLT_MAX or FLT_MAX if overflow happens.
+// Return false if overflow happens.
+extern bool atof_clamp(const char *str, float *value);
+
+// If overflow happens, clamp the value to INT_MIN or INT_MAX.
+// Return false if overflow happens.
+extern bool atoi_clamp(const char *str, int *value);
+
+#endif // COMPILER_UTIL_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/compiler/translator/util.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11BufferStorage11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,366 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage11.cpp Defines the BufferStorage11 class.
+
+#include &quot;libGLESv2/renderer/d3d11/BufferStorage11.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+
+namespace rx
+{
+
+BufferStorage11::BufferStorage11(Renderer11 *renderer)
+{
+    mRenderer = renderer;
+
+    mStagingBuffer = NULL;
+    mStagingBufferSize = 0;
+
+    mSize = 0;
+
+    mResolvedData = NULL;
+    mResolvedDataSize = 0;
+    mResolvedDataValid = false;
+
+    mReadUsageCount = 0;
+    mWriteUsageCount = 0;
+}
+
+BufferStorage11::~BufferStorage11()
+{
+    SafeRelease(mStagingBuffer);
+
+    if (mResolvedData)
+    {
+        free(mResolvedData);
+        mResolvedData = NULL;
+    }
+
+    for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++)
+    {
+        SafeDelete(it-&gt;second);
+    }
+}
+
+BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage));
+    return static_cast&lt;BufferStorage11*&gt;(bufferStorage);
+}
+
+void *BufferStorage11::getData()
+{
+    ASSERT(mStagingBuffer);
+
+    if (!mResolvedDataValid)
+    {
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+        ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+        HRESULT result;
+
+        if (!mResolvedData || mResolvedDataSize &lt; mStagingBufferSize)
+        {
+            free(mResolvedData);
+            mResolvedData = malloc(mSize);
+            mResolvedDataSize = mSize;
+        }
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        result = context-&gt;Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            return gl::error(GL_OUT_OF_MEMORY, (void*)NULL);
+        }
+
+        memcpy(mResolvedData, mappedResource.pData, mSize);
+
+        context-&gt;Unmap(mStagingBuffer, 0);
+
+        mResolvedDataValid = true;
+    }
+
+    mReadUsageCount = 0;
+
+    return mResolvedData;
+}
+
+void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset)
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+    ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+    HRESULT result;
+
+    const unsigned int requiredStagingBufferSize = size + offset;
+    const bool createStagingBuffer = !mStagingBuffer || mStagingBufferSize &lt; requiredStagingBufferSize;
+
+    if (createStagingBuffer)
+    {
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = requiredStagingBufferSize;
+        bufferDesc.Usage = D3D11_USAGE_STAGING;
+        bufferDesc.BindFlags = 0;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result;
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+        ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+        ID3D11Buffer *newStagingBuffer;
+
+        if (data &amp;&amp; offset == 0)
+        {
+            D3D11_SUBRESOURCE_DATA initialData;
+            initialData.pSysMem = data;
+            initialData.SysMemPitch = requiredStagingBufferSize;
+            initialData.SysMemSlicePitch = 0;
+
+            result = device-&gt;CreateBuffer(&amp;bufferDesc, &amp;initialData, &amp;newStagingBuffer);
+        }
+        else
+        {
+            result = device-&gt;CreateBuffer(&amp;bufferDesc, NULL, &amp;newStagingBuffer);
+        }
+
+        if (FAILED(result))
+        {
+            mStagingBufferSize = 0;
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        mStagingBufferSize = requiredStagingBufferSize;
+
+        if (mStagingBuffer &amp;&amp; offset &gt; 0)
+        {
+            // If offset is greater than zero and the buffer is non-null, need to preserve the data from
+            // the old buffer up to offset
+            D3D11_BOX srcBox;
+            srcBox.left = 0;
+            srcBox.right = std::min(offset, requiredStagingBufferSize);
+            srcBox.top = 0;
+            srcBox.bottom = 1;
+            srcBox.front = 0;
+            srcBox.back = 1;
+
+            context-&gt;CopySubresourceRegion(newStagingBuffer, 0, 0, 0, 0, mStagingBuffer, 0, &amp;srcBox);
+        }
+
+        SafeRelease(mStagingBuffer);
+        mStagingBuffer = newStagingBuffer;
+    }
+
+    if (data &amp;&amp; (offset != 0 || !createStagingBuffer))
+    {
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        result = context-&gt;Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        unsigned char *offsetBufferPointer = reinterpret_cast&lt;unsigned char *&gt;(mappedResource.pData) + offset;
+        memcpy(offsetBufferPointer, data, size);
+
+        context-&gt;Unmap(mStagingBuffer, 0);
+    }
+
+    for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++)
+    {
+        it-&gt;second-&gt;markDirty();
+    }
+
+    mSize = std::max(mSize, requiredStagingBufferSize);
+    mWriteUsageCount = 0;
+
+    mResolvedDataValid = false;
+}
+
+void BufferStorage11::copyData(BufferStorage* sourceStorage, unsigned int size,
+                               unsigned int sourceOffset, unsigned int destOffset)
+{
+    BufferStorage11* source = makeBufferStorage11(sourceStorage);
+    if (source)
+    {
+        ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+
+        D3D11_BOX srcBox;
+        srcBox.left = sourceOffset;
+        srcBox.right = sourceOffset + size;
+        srcBox.top = 0;
+        srcBox.bottom = 1;
+        srcBox.front = 0;
+        srcBox.back = 1;
+
+        ASSERT(mStagingBuffer &amp;&amp; source-&gt;mStagingBuffer);
+        context-&gt;CopySubresourceRegion(mStagingBuffer, 0, destOffset, 0, 0, source-&gt;mStagingBuffer, 0, &amp;srcBox);
+    }
+}
+
+void BufferStorage11::clear()
+{
+    mResolvedDataValid = false;
+    mSize = 0;
+}
+
+unsigned int BufferStorage11::getSize() const
+{
+    return mSize;
+}
+
+bool BufferStorage11::supportsDirectBinding() const
+{
+    return true;
+}
+
+void BufferStorage11::markBufferUsage()
+{
+    mReadUsageCount++;
+    mWriteUsageCount++;
+
+    const unsigned int usageLimit = 5;
+
+    if (mReadUsageCount &gt; usageLimit &amp;&amp; mResolvedData)
+    {
+        free(mResolvedData);
+        mResolvedData = NULL;
+        mResolvedDataSize = 0;
+        mResolvedDataValid = false;
+    }
+}
+
+ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage)
+{
+    markBufferUsage();
+
+    DirectBufferStorage11 *directBuffer = NULL;
+
+    auto directBufferIt = mDirectBuffers.find(usage);
+    if (directBufferIt != mDirectBuffers.end())
+    {
+        directBuffer = directBufferIt-&gt;second;
+    }
+
+    if (directBuffer)
+    {
+        if (directBuffer-&gt;isDirty())
+        {
+            // if updateFromStagingBuffer returns true, the D3D buffer has been recreated
+            // and we should update our serial
+            if (directBuffer-&gt;updateFromStagingBuffer(mStagingBuffer, mSize, 0))
+            {
+                updateSerial();
+            }
+        }
+    }
+    else
+    {
+        // buffer is not allocated, create it
+        directBuffer = new DirectBufferStorage11(mRenderer, usage);
+        directBuffer-&gt;updateFromStagingBuffer(mStagingBuffer, mSize, 0);
+
+        mDirectBuffers.insert(std::make_pair(usage, directBuffer));
+        updateSerial();
+    }
+
+    return directBuffer-&gt;getD3DBuffer();
+}
+
+DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage)
+    : mRenderer(renderer),
+      mUsage(usage),
+      mDirectBuffer(NULL),
+      mBufferSize(0),
+      mDirty(false)
+{
+}
+
+DirectBufferStorage11::~DirectBufferStorage11()
+{
+    SafeRelease(mDirectBuffer);
+}
+
+BufferUsage DirectBufferStorage11::getUsage() const
+{
+    return mUsage;
+}
+
+// Returns true if it recreates the direct buffer
+bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset)
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+    ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+
+    // unused for now
+    ASSERT(offset == 0);
+
+    unsigned int requiredBufferSize = size + offset;
+    bool createBuffer = !mDirectBuffer || mBufferSize &lt; requiredBufferSize;
+
+    // (Re)initialize D3D buffer if needed
+    if (createBuffer)
+    {
+        D3D11_BUFFER_DESC bufferDesc;
+        fillBufferDesc(&amp;bufferDesc, mRenderer, mUsage, requiredBufferSize);
+
+        ID3D11Buffer *newBuffer;
+        HRESULT result = device-&gt;CreateBuffer(&amp;bufferDesc, NULL, &amp;newBuffer);
+
+        if (FAILED(result))
+        {
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        // No longer need the old buffer
+        SafeRelease(mDirectBuffer);
+        mDirectBuffer = newBuffer;
+
+        mBufferSize = bufferDesc.ByteWidth;
+    }
+
+    // Copy data via staging buffer
+    D3D11_BOX srcBox;
+    srcBox.left = 0;
+    srcBox.right = size;
+    srcBox.top = 0;
+    srcBox.bottom = 1;
+    srcBox.front = 0;
+    srcBox.back = 1;
+
+    context-&gt;CopySubresourceRegion(mDirectBuffer, 0, offset, 0, 0, stagingBuffer, 0, &amp;srcBox);
+
+    mDirty = false;
+
+    return createBuffer;
+}
+
+void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize)
+{
+    bufferDesc-&gt;ByteWidth = bufferSize;
+    bufferDesc-&gt;MiscFlags = 0;
+    bufferDesc-&gt;StructureByteStride = 0;
+
+    switch (usage)
+    {
+      case BUFFER_USAGE_VERTEX:
+        bufferDesc-&gt;Usage = D3D11_USAGE_DEFAULT;
+        bufferDesc-&gt;BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        bufferDesc-&gt;CPUAccessFlags = 0;
+        break;
+
+      case BUFFER_USAGE_INDEX:
+        bufferDesc-&gt;Usage = D3D11_USAGE_DEFAULT;
+        bufferDesc-&gt;BindFlags = D3D11_BIND_INDEX_BUFFER;
+        bufferDesc-&gt;CPUAccessFlags = 0;
+        break;
+
+    default:
+        UNREACHABLE();
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11BufferStorage11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,92 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage11.h Defines the BufferStorage11 class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
+#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
+
+#include &quot;libGLESv2/renderer/BufferStorage.h&quot;
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+class DirectBufferStorage11;
+
+enum BufferUsage
+{
+    BUFFER_USAGE_VERTEX,
+    BUFFER_USAGE_INDEX,
+};
+
+class BufferStorage11 : public BufferStorage
+{
+  public:
+    explicit BufferStorage11(Renderer11 *renderer);
+    virtual ~BufferStorage11();
+
+    static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage);
+
+    virtual void *getData();
+    virtual void setData(const void* data, unsigned int size, unsigned int offset);
+    virtual void copyData(BufferStorage* sourceStorage, unsigned int size,
+                          unsigned int sourceOffset, unsigned int destOffset);
+    virtual void clear();
+    virtual unsigned int getSize() const;
+    virtual bool supportsDirectBinding() const;
+
+    ID3D11Buffer *getBuffer(BufferUsage usage);
+
+  private:
+    Renderer11 *mRenderer;
+
+    ID3D11Buffer *mStagingBuffer;
+    unsigned int mStagingBufferSize;
+
+    std::map&lt;BufferUsage, DirectBufferStorage11*&gt; mDirectBuffers;
+
+    unsigned int mSize;
+
+    void *mResolvedData;
+    unsigned int mResolvedDataSize;
+    bool mResolvedDataValid;
+
+    unsigned int mReadUsageCount;
+    unsigned int mWriteUsageCount;
+
+    void markBufferUsage();
+};
+
+// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points
+// - vertex buffers
+// - index buffers
+class DirectBufferStorage11
+{
+  public:
+    DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage);
+    ~DirectBufferStorage11();
+
+    BufferUsage getUsage() const;
+    bool updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset);
+
+    ID3D11Buffer *getD3DBuffer() { return mDirectBuffer; }
+    bool isDirty() const { return mDirty; }
+    void markDirty() { mDirty = true; }
+
+  private:
+    Renderer11 *mRenderer;
+    const BufferUsage mUsage;
+    ID3D11Buffer *mDirectBuffer;
+    size_t mBufferSize;
+    bool mDirty;
+
+    static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/BufferStorage11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Fence11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,134 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl.
+
+#include &quot;libGLESv2/renderer/d3d11/Fence11.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+
+namespace rx
+{
+
+Fence11::Fence11(rx::Renderer11 *renderer)
+{
+    mRenderer = renderer;
+    mQuery = NULL;
+}
+
+Fence11::~Fence11()
+{
+    if (mQuery)
+    {
+        mQuery-&gt;Release();
+        mQuery = NULL;
+    }
+}
+
+GLboolean Fence11::isFence()
+{
+    // GL_NV_fence spec:
+    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+    return mQuery != NULL;
+}
+
+void Fence11::setFence(GLenum condition)
+{
+    if (!mQuery)
+    {
+        D3D11_QUERY_DESC queryDesc;
+        queryDesc.Query = D3D11_QUERY_EVENT;
+        queryDesc.MiscFlags = 0;
+
+        if (FAILED(mRenderer-&gt;getDevice()-&gt;CreateQuery(&amp;queryDesc, &amp;mQuery)))
+        {
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    mRenderer-&gt;getDeviceContext()-&gt;End(mQuery);
+
+    setCondition(condition);
+    setStatus(GL_FALSE);
+}
+
+GLboolean Fence11::testFence()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+    }
+
+    HRESULT result = mRenderer-&gt;getDeviceContext()-&gt;GetData(mQuery, NULL, 0, 0);
+
+    if (mRenderer-&gt;isDeviceLost())
+    {
+       return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+    }
+
+    ASSERT(result == S_OK || result == S_FALSE);
+    setStatus(result == S_OK);
+    return getStatus();
+}
+
+void Fence11::finishFence()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    while (!testFence())
+    {
+        Sleep(0);
+    }
+}
+
+void Fence11::getFenceiv(GLenum pname, GLint *params)
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    switch (pname)
+    {
+      case GL_FENCE_STATUS_NV:
+        {
+            // GL_NV_fence spec:
+            // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+            // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+            if (getStatus())
+            {
+                params[0] = GL_TRUE;
+                return;
+            }
+
+            HRESULT result = mRenderer-&gt;getDeviceContext()-&gt;GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+
+            if (mRenderer-&gt;isDeviceLost())
+            {
+                params[0] = GL_TRUE;
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+
+            ASSERT(result == S_OK || result == S_FALSE);
+            setStatus(result == S_OK);
+            params[0] = getStatus();
+
+            break;
+        }
+      case GL_FENCE_CONDITION_NV:
+        params[0] = getCondition();
+        break;
+      default:
+        return gl::error(GL_INVALID_ENUM);
+        break;
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Fence11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl.
+
+#ifndef LIBGLESV2_RENDERER_Fence11_H_
+#define LIBGLESV2_RENDERER_Fence11_H_
+
+#include &quot;libGLESv2/renderer/FenceImpl.h&quot;
+
+namespace rx
+{
+class Renderer11;
+
+class Fence11 : public FenceImpl
+{
+  public:
+    explicit Fence11(rx::Renderer11 *renderer);
+    virtual ~Fence11();
+
+    GLboolean isFence();
+    void setFence(GLenum condition);
+    GLboolean testFence();
+    void finishFence();
+    void getFenceiv(GLenum pname, GLint *params);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Fence11);
+
+    rx::Renderer11 *mRenderer;
+    ID3D11Query *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FENCE11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Fence11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Image11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,495 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image11.h: Implements the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Image11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/TextureStorage11.h&quot;
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/utilities.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+#include &quot;libGLESv2/renderer/generatemip.h&quot;
+
+namespace rx
+{
+
+Image11::Image11()
+{
+    mStagingTexture = NULL;
+    mRenderer = NULL;
+    mDXGIFormat = DXGI_FORMAT_UNKNOWN;
+}
+
+Image11::~Image11()
+{
+    if (mStagingTexture)
+    {
+        mStagingTexture-&gt;Release();
+    }
+}
+
+Image11 *Image11::makeImage11(Image *img)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img));
+    return static_cast&lt;rx::Image11*&gt;(img);
+}
+
+void Image11::generateMipmap(Image11 *dest, Image11 *src)
+{
+    ASSERT(src-&gt;getDXGIFormat() == dest-&gt;getDXGIFormat());
+    ASSERT(src-&gt;getWidth() == 1 || src-&gt;getWidth() / 2 == dest-&gt;getWidth());
+    ASSERT(src-&gt;getHeight() == 1 || src-&gt;getHeight() / 2 == dest-&gt;getHeight());
+
+    D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped;
+    dest-&gt;map(D3D11_MAP_WRITE, &amp;destMapped);
+    src-&gt;map(D3D11_MAP_READ, &amp;srcMapped);
+
+    const unsigned char *sourceData = reinterpret_cast&lt;const unsigned char*&gt;(srcMapped.pData);
+    unsigned char *destData = reinterpret_cast&lt;unsigned char*&gt;(destMapped.pData);
+
+    if (sourceData &amp;&amp; destData)
+    {
+        switch (src-&gt;getDXGIFormat())
+        {
+          case DXGI_FORMAT_R8G8B8A8_UNORM:
+          case DXGI_FORMAT_B8G8R8A8_UNORM:
+            GenerateMip&lt;R8G8B8A8&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_A8_UNORM:
+            GenerateMip&lt;A8&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R8_UNORM:
+            GenerateMip&lt;R8&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R32G32B32A32_FLOAT:
+            GenerateMip&lt;A32B32G32R32F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R32G32B32_FLOAT:
+            GenerateMip&lt;R32G32B32F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R16G16B16A16_FLOAT:
+            GenerateMip&lt;A16B16G16R16F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R8G8_UNORM:
+            GenerateMip&lt;R8G8&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R16_FLOAT:
+            GenerateMip&lt;R16F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R16G16_FLOAT:
+            GenerateMip&lt;R16G16F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R32_FLOAT:
+            GenerateMip&lt;R32F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          case DXGI_FORMAT_R32G32_FLOAT:
+            GenerateMip&lt;R32G32F&gt;(src-&gt;getWidth(), src-&gt;getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch);
+            break;
+          default:
+            UNREACHABLE();
+            break;
+        }
+
+        dest-&gt;unmap();
+        src-&gt;unmap();
+    }
+
+    dest-&gt;markDirty();
+}
+
+static bool FormatRequiresInitialization(DXGI_FORMAT dxgiFormat, GLenum internalFormat)
+{
+    return (dxgiFormat == DXGI_FORMAT_R8G8B8A8_UNORM &amp;&amp; gl::GetAlphaSize(internalFormat) == 0) ||
+           (dxgiFormat == DXGI_FORMAT_R32G32B32A32_FLOAT &amp;&amp; gl::GetAlphaSize(internalFormat) == 0);
+}
+
+bool Image11::isDirty() const
+{
+    return ((mStagingTexture || FormatRequiresInitialization(mDXGIFormat, mInternalFormat)) &amp;&amp; mDirty);
+}
+
+bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage-&gt;getStorageInstance());
+    return storage11-&gt;updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height);
+}
+
+bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage-&gt;getStorageInstance());
+    return storage11-&gt;updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height);
+}
+
+bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
+{
+    if (mWidth != width ||
+        mHeight != height ||
+        mInternalFormat != internalformat ||
+        forceRelease)
+    {
+        mRenderer = Renderer11::makeRenderer11(renderer);
+
+        mWidth = width;
+        mHeight = height;
+        mInternalFormat = internalformat;
+        // compute the d3d format that will be used
+        mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+        mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat);
+
+        if (mStagingTexture)
+        {
+            mStagingTexture-&gt;Release();
+            mStagingTexture = NULL;
+        }
+        
+        return true;
+    }
+
+    return false;
+}
+
+bool Image11::isRenderableFormat() const
+{
+    return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat);
+}
+
+DXGI_FORMAT Image11::getDXGIFormat() const
+{
+    // this should only happen if the image hasn't been redefined first
+    // which would be a bug by the caller
+    ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN);
+
+    return mDXGIFormat;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
+// into the target pixel rectangle.
+void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                       GLint unpackAlignment, const void *input)
+{
+    D3D11_MAPPED_SUBRESOURCE mappedImage;
+    HRESULT result = map(D3D11_MAP_WRITE, &amp;mappedImage);
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not map image for loading.&quot;);
+        return;
+    }
+    
+    GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
+    size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8;
+    void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize));
+
+    switch (mInternalFormat)
+    {
+      case GL_ALPHA8_EXT:
+        loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_LUMINANCE8_EXT:
+        loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+        break;
+      case GL_ALPHA32F_EXT:
+        loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_LUMINANCE32F_EXT:
+        loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_ALPHA16F_EXT:
+        loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_LUMINANCE16F_EXT:
+        loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false);
+        break;
+      case GL_LUMINANCE_ALPHA32F_EXT:
+        loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_LUMINANCE_ALPHA16F_EXT:
+        loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGB8_OES:
+        loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGB565:
+        loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGBA8_OES:
+        loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGBA4:
+        loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGB5_A1:
+        loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_BGRA8_EXT:
+        loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGB32F_EXT:
+        loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGB16F_EXT:
+        loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGBA32F_EXT:
+        loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      case GL_RGBA16F_EXT:
+        loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData);
+        break;
+      default: UNREACHABLE(); 
+    }
+
+    unmap();
+}
+
+void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                const void *input)
+{
+    ASSERT(xoffset % 4 == 0);
+    ASSERT(yoffset % 4 == 0);
+
+    D3D11_MAPPED_SUBRESOURCE mappedImage;
+    HRESULT result = map(D3D11_MAP_WRITE, &amp;mappedImage);
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not map image for loading.&quot;);
+        return;
+    }
+
+    // Size computation assumes a 4x4 block compressed texture format
+    size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8;
+    void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize));
+
+    GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
+    GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
+    int rows = inputSize / inputPitch;
+    for (int i = 0; i &lt; rows; ++i)
+    {
+        memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
+    }
+
+    unmap();
+}
+
+void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    gl::Renderbuffer *colorbuffer = source-&gt;getReadColorbuffer();
+
+    if (colorbuffer &amp;&amp; colorbuffer-&gt;getActualFormat() == (GLuint)mActualFormat)
+    {
+        // No conversion needed-- use copyback fastpath
+        ID3D11Texture2D *colorBufferTexture = NULL;
+        unsigned int subresourceIndex = 0;
+
+        if (mRenderer-&gt;getRenderTargetResource(colorbuffer, &amp;subresourceIndex, &amp;colorBufferTexture))
+        {
+            D3D11_TEXTURE2D_DESC textureDesc;
+            colorBufferTexture-&gt;GetDesc(&amp;textureDesc);
+
+            ID3D11Device *device = mRenderer-&gt;getDevice();
+            ID3D11DeviceContext *deviceContext = mRenderer-&gt;getDeviceContext();
+
+            ID3D11Texture2D* srcTex = NULL;
+            if (textureDesc.SampleDesc.Count &gt; 1)
+            {
+                D3D11_TEXTURE2D_DESC resolveDesc;
+                resolveDesc.Width = textureDesc.Width;
+                resolveDesc.Height = textureDesc.Height;
+                resolveDesc.MipLevels = 1;
+                resolveDesc.ArraySize = 1;
+                resolveDesc.Format = textureDesc.Format;
+                resolveDesc.SampleDesc.Count = 1;
+                resolveDesc.SampleDesc.Quality = 0;
+                resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+                resolveDesc.BindFlags = 0;
+                resolveDesc.CPUAccessFlags = 0;
+                resolveDesc.MiscFlags = 0;
+
+                HRESULT result = device-&gt;CreateTexture2D(&amp;resolveDesc, NULL, &amp;srcTex);
+                if (FAILED(result))
+                {
+                    ERR(&quot;Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.&quot;, result);
+                    return;
+                }
+
+                deviceContext-&gt;ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format);
+                subresourceIndex = 0;
+            }
+            else
+            {
+                srcTex = colorBufferTexture;
+                srcTex-&gt;AddRef();
+            }
+
+            D3D11_BOX srcBox;
+            srcBox.left = x;
+            srcBox.right = x + width;
+            srcBox.top = y;
+            srcBox.bottom = y + height;
+            srcBox.front = 0;
+            srcBox.back = 1;
+
+            deviceContext-&gt;CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &amp;srcBox);
+
+            srcTex-&gt;Release();
+            colorBufferTexture-&gt;Release();
+        }
+    }
+    else
+    {
+        // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels
+        D3D11_MAPPED_SUBRESOURCE mappedImage;
+        HRESULT result = map(D3D11_MAP_WRITE, &amp;mappedImage);
+
+        // determine the offset coordinate into the destination buffer
+        GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset;
+        void *dataOffset = static_cast&lt;unsigned char*&gt;(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset;
+
+        mRenderer-&gt;readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), 
+                              gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset);
+
+        unmap();
+    }
+}
+
+ID3D11Texture2D *Image11::getStagingTexture()
+{
+    createStagingTexture();
+
+    return mStagingTexture;
+}
+
+unsigned int Image11::getStagingSubresource()
+{
+    createStagingTexture();
+
+    return mStagingSubresource;
+}
+
+template &lt;typename T, size_t N&gt;
+static void setDefaultData(ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, UINT subresource,
+                           GLsizei width, GLsizei height, const T (&amp;defaultData)[N])
+{
+    D3D11_MAPPED_SUBRESOURCE map;
+    deviceContext-&gt;Map(texture, subresource, D3D11_MAP_WRITE, 0, &amp;map);
+
+    unsigned char* ptr = reinterpret_cast&lt;unsigned char*&gt;(map.pData);
+    size_t pixelSize = sizeof(T) * N;
+
+    for (GLsizei y = 0; y &lt; height; y++)
+    {
+        for (GLsizei x = 0; x &lt; width; x++)
+        {
+            memcpy(ptr + (y * map.RowPitch) + (x * pixelSize), defaultData, pixelSize);
+        }
+    }
+
+    deviceContext-&gt;Unmap(texture, subresource);
+}
+
+void Image11::createStagingTexture()
+{
+    if (mStagingTexture)
+    {
+        return;
+    }
+
+    ID3D11Texture2D *newTexture = NULL;
+    int lodOffset = 1;
+    const DXGI_FORMAT dxgiFormat = getDXGIFormat();
+    ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures
+
+    if (mWidth != 0 &amp;&amp; mHeight != 0)
+    {
+        GLsizei width = mWidth;
+        GLsizei height = mHeight;
+
+        // adjust size if needed for compressed textures
+        gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &amp;width, &amp;height, &amp;lodOffset);
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+
+        D3D11_TEXTURE2D_DESC desc;
+        desc.Width = width;
+        desc.Height = height;
+        desc.MipLevels = lodOffset + 1;
+        desc.ArraySize = 1;
+        desc.Format = dxgiFormat;
+        desc.SampleDesc.Count = 1;
+        desc.SampleDesc.Quality = 0;
+        desc.Usage = D3D11_USAGE_STAGING;
+        desc.BindFlags = 0;
+        desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
+        desc.MiscFlags = 0;
+
+        HRESULT result = device-&gt;CreateTexture2D(&amp;desc, NULL, &amp;newTexture);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == E_OUTOFMEMORY);
+            ERR(&quot;Creating image failed.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    mStagingTexture = newTexture;
+    mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1);
+    mDirty = false;
+
+    if (mDXGIFormat == DXGI_FORMAT_R8G8B8A8_UNORM &amp;&amp; gl::GetAlphaSize(mInternalFormat) == 0)
+    {
+        unsigned char defaultPixel[4] = { 0, 0, 0, 255 };
+        setDefaultData(mRenderer-&gt;getDeviceContext(), mStagingTexture, mStagingSubresource, mWidth, mHeight, defaultPixel);
+    }
+    else if (mDXGIFormat == DXGI_FORMAT_R32G32B32A32_FLOAT &amp;&amp; gl::GetAlphaSize(mInternalFormat) == 0)
+    {
+        float defaultPixel[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
+        setDefaultData(mRenderer-&gt;getDeviceContext(), mStagingTexture, mStagingSubresource, mWidth, mHeight, defaultPixel);
+    }
+}
+
+HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map)
+{
+    createStagingTexture();
+
+    HRESULT result = E_FAIL;
+
+    if (mStagingTexture)
+    {
+        ID3D11DeviceContext *deviceContext = mRenderer-&gt;getDeviceContext();
+        result = deviceContext-&gt;Map(mStagingTexture, mStagingSubresource, mapType, 0, map);
+
+        // this can fail if the device is removed (from TDR)
+        if (d3d11::isDeviceLostError(result))
+        {
+            mRenderer-&gt;notifyDeviceLost();
+        }
+        else if (SUCCEEDED(result))
+        {
+            mDirty = true;
+        }
+    }
+
+    return result;
+}
+
+void Image11::unmap()
+{
+    if (mStagingTexture)
+    {
+        ID3D11DeviceContext *deviceContext = mRenderer-&gt;getDeviceContext();
+        deviceContext-&gt;Unmap(mStagingTexture, mStagingSubresource);
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Image11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,76 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image11.h: Defines the rx::Image11 class, which acts as the interface to
+// the actual underlying resources of a Texture
+
+#ifndef LIBGLESV2_RENDERER_IMAGE11_H_
+#define LIBGLESV2_RENDERER_IMAGE11_H_
+
+#include &quot;libGLESv2/renderer/Image.h&quot;
+
+#include &quot;common/debug.h&quot;
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Image11 : public Image
+{
+  public:
+    Image11();
+    virtual ~Image11();
+
+    static Image11 *makeImage11(Image *img);
+
+    static void generateMipmap(Image11 *dest, Image11 *src);
+
+    virtual bool isDirty() const;
+
+    virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+    virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
+
+    virtual bool isRenderableFormat() const;
+    DXGI_FORMAT getDXGIFormat() const;
+    
+    virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                  GLint unpackAlignment, const void *input);
+    virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                    const void *input);
+
+    virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+
+  protected:
+    HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map);
+    void unmap();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Image11);
+
+    ID3D11Texture2D *getStagingTexture();
+    unsigned int getStagingSubresource();
+    void createStagingTexture();
+
+    Renderer11 *mRenderer;
+
+    DXGI_FORMAT mDXGIFormat;
+    ID3D11Texture2D *mStagingTexture;
+    unsigned int mStagingSubresource;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_IMAGE11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Image11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11IndexBuffer11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,183 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation.
+
+#include &quot;libGLESv2/renderer/d3d11/IndexBuffer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+
+namespace rx
+{
+
+IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer)
+{
+    mBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+IndexBuffer11::~IndexBuffer11()
+{
+    if (mBuffer)
+    {
+        mBuffer-&gt;Release();
+        mBuffer = NULL;
+    }
+}
+
+bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+    if (mBuffer)
+    {
+        mBuffer-&gt;Release();
+        mBuffer = NULL;
+    }
+
+    updateSerial();
+
+    if (bufferSize &gt; 0)
+    {
+        ID3D11Device* dxDevice = mRenderer-&gt;getDevice();
+
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = bufferSize;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result = dxDevice-&gt;CreateBuffer(&amp;bufferDesc, NULL, &amp;mBuffer);
+        if (FAILED(result))
+        {
+            return false;
+        }
+    }
+
+    mBufferSize = bufferSize;
+    mIndexType = indexType;
+    mDynamicUsage = dynamic;
+
+    return true;
+}
+
+IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer));
+    return static_cast&lt;IndexBuffer11*&gt;(indexBuffer);
+}
+
+bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+    if (mBuffer)
+    {
+        // Check for integer overflows and out-out-bounds map requests
+        if (offset + size &lt; offset || offset + size &gt; mBufferSize)
+        {
+            ERR(&quot;Index buffer map range is not inside the buffer.&quot;);
+            return false;
+        }
+
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext-&gt;Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            ERR(&quot;Index buffer map failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        *outMappedMemory = reinterpret_cast&lt;char*&gt;(mappedResource.pData) + offset;
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool IndexBuffer11::unmapBuffer()
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+        dxContext-&gt;Unmap(mBuffer, 0);
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+GLenum IndexBuffer11::getIndexType() const
+{
+    return mIndexType;
+}
+
+unsigned int IndexBuffer11::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType)
+{
+    if (bufferSize &gt; mBufferSize || indexType != mIndexType)
+    {
+        return initialize(bufferSize, indexType, mDynamicUsage);
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool IndexBuffer11::discard()
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext-&gt;Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            ERR(&quot;Index buffer map failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        dxContext-&gt;Unmap(mBuffer, 0);
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+DXGI_FORMAT IndexBuffer11::getIndexFormat() const
+{
+    switch (mIndexType)
+    {
+      case GL_UNSIGNED_BYTE:    return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_SHORT:   return DXGI_FORMAT_R16_UINT;
+      case GL_UNSIGNED_INT:     return DXGI_FORMAT_R32_UINT;
+      default: UNREACHABLE();   return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+ID3D11Buffer *IndexBuffer11::getBuffer() const
+{
+    return mBuffer;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11IndexBuffer11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_
+
+#include &quot;libGLESv2/renderer/IndexBuffer.h&quot;
+
+namespace rx
+{
+class Renderer11;
+
+class IndexBuffer11 : public IndexBuffer
+{
+  public:
+    explicit IndexBuffer11(Renderer11 *const renderer);
+    virtual ~IndexBuffer11();
+
+    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+
+    static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer);
+
+    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+    virtual bool unmapBuffer();
+
+    virtual GLenum getIndexType() const;
+    virtual unsigned int getBufferSize() const;
+    virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+
+    virtual bool discard();
+
+    DXGI_FORMAT getIndexFormat() const;
+    ID3D11Buffer *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(IndexBuffer11);
+
+    rx::Renderer11 *const mRenderer;
+
+    ID3D11Buffer *mBuffer;
+    unsigned int mBufferSize;
+    GLenum mIndexType;
+    bool mDynamicUsage;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/IndexBuffer11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11InputLayoutCachecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,213 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#include &quot;libGLESv2/renderer/d3d11/InputLayoutCache.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/VertexBuffer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/BufferStorage11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/ShaderExecutable11.h&quot;
+#include &quot;libGLESv2/ProgramBinary.h&quot;
+#include &quot;libGLESv2/Context.h&quot;
+#include &quot;libGLESv2/renderer/VertexDataManager.h&quot;
+
+#include &quot;third_party/murmurhash/MurmurHash3.h&quot;
+
+namespace rx
+{
+
+const unsigned int InputLayoutCache::kMaxInputLayouts = 1024;
+
+InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts)
+{
+    mCounter = 0;
+    mDevice = NULL;
+    mDeviceContext = NULL;
+    mCurrentIL = NULL;
+    for (unsigned int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        mCurrentBuffers[i] = -1;
+        mCurrentVertexStrides[i] = -1;
+        mCurrentVertexOffsets[i] = -1;
+    }
+}
+
+InputLayoutCache::~InputLayoutCache()
+{
+    clear();
+}
+
+void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context)
+{
+    clear();
+    mDevice = device;
+    mDeviceContext = context;
+}
+
+void InputLayoutCache::clear()
+{
+    for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+    {
+        i-&gt;second.inputLayout-&gt;Release();
+    }
+    mInputLayoutMap.clear();
+    markDirty();
+}
+
+void InputLayoutCache::markDirty()
+{
+    mCurrentIL = NULL;
+    for (unsigned int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        mCurrentBuffers[i] = -1;
+        mCurrentVertexStrides[i] = -1;
+        mCurrentVertexOffsets[i] = -1;
+    }
+}
+
+GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+                                            gl::ProgramBinary *programBinary)
+{
+    int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS];
+    programBinary-&gt;sortAttributesByLayout(attributes, sortedSemanticIndices);
+
+    if (!mDevice || !mDeviceContext)
+    {
+        ERR(&quot;InputLayoutCache is not initialized.&quot;);
+        return GL_INVALID_OPERATION;
+    }
+
+    InputLayoutKey ilKey = { 0 };
+
+    ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL };
+    unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 };
+    UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 };
+    UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 };
+
+    static const char* semanticName = &quot;TEXCOORD&quot;;
+
+    for (unsigned int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (attributes[i].active)
+        {
+            VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer);
+            BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL;
+
+            D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor &gt; 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA;
+
+            // Record the type of the associated vertex shader vector in our key
+            // This will prevent mismatched vertex shaders from using the same input layout
+            GLint attributeSize;
+            programBinary-&gt;getActiveAttribute(ilKey.elementCount, 0, NULL, &amp;attributeSize, &amp;ilKey.elements[ilKey.elementCount].glslElementType, NULL);
+
+            ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName;
+            ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i];
+            ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute-&gt;mArrayEnabled ? vertexBuffer-&gt;getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT;
+            ilKey.elements[ilKey.elementCount].desc.InputSlot = i;
+            ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0;
+            ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass;
+            ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor;
+            ilKey.elementCount++;
+
+            vertexBuffers[i] = bufferStorage ? bufferStorage-&gt;getBuffer(BUFFER_USAGE_VERTEX) : vertexBuffer-&gt;getBuffer();
+            vertexBufferSerials[i] = bufferStorage ? bufferStorage-&gt;getSerial() : vertexBuffer-&gt;getSerial();
+            vertexStrides[i] = attributes[i].stride;
+            vertexOffsets[i] = attributes[i].offset;
+        }
+    }
+
+    ID3D11InputLayout *inputLayout = NULL;
+
+    InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey);
+    if (i != mInputLayoutMap.end())
+    {
+        inputLayout = i-&gt;second.inputLayout;
+        i-&gt;second.lastUsedTime = mCounter++;
+    }
+    else
+    {
+        ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary-&gt;getVertexExecutable());
+
+        D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS];
+        for (unsigned int j = 0; j &lt; ilKey.elementCount; ++j)
+        {
+            descs[j] = ilKey.elements[j].desc;
+        }
+
+        HRESULT result = mDevice-&gt;CreateInputLayout(descs, ilKey.elementCount, shader-&gt;getFunction(), shader-&gt;getLength(), &amp;inputLayout);
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to crate input layout, result: 0x%08x&quot;, result);
+            return GL_INVALID_OPERATION;
+        }
+
+        if (mInputLayoutMap.size() &gt;= kMaxInputLayouts)
+        {
+            TRACE(&quot;Overflowed the limit of %u input layouts, removing the least recently used &quot;
+                  &quot;to make room.&quot;, kMaxInputLayouts);
+
+            InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin();
+            for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++)
+            {
+                if (i-&gt;second.lastUsedTime &lt; leastRecentlyUsed-&gt;second.lastUsedTime)
+                {
+                    leastRecentlyUsed = i;
+                }
+            }
+            leastRecentlyUsed-&gt;second.inputLayout-&gt;Release();
+            mInputLayoutMap.erase(leastRecentlyUsed);
+        }
+
+        InputLayoutCounterPair inputCounterPair;
+        inputCounterPair.inputLayout = inputLayout;
+        inputCounterPair.lastUsedTime = mCounter++;
+
+        mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair));
+    }
+
+    if (inputLayout != mCurrentIL)
+    {
+        mDeviceContext-&gt;IASetInputLayout(inputLayout);
+        mCurrentIL = inputLayout;
+    }
+
+    for (unsigned int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] ||
+            vertexOffsets[i] != mCurrentVertexOffsets[i])
+        {
+            mDeviceContext-&gt;IASetVertexBuffers(i, 1, &amp;vertexBuffers[i], &amp;vertexStrides[i], &amp;vertexOffsets[i]);
+            mCurrentBuffers[i] = vertexBufferSerials[i];
+            mCurrentVertexStrides[i] = vertexStrides[i];
+            mCurrentVertexOffsets[i] = vertexOffsets[i];
+        }
+    }
+
+    return GL_NO_ERROR;
+}
+
+std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &amp;inputLayout)
+{
+    static const unsigned int seed = 0xDEADBEEF;
+
+    std::size_t hash = 0;
+    MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &amp;hash);
+    return hash;
+}
+
+bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &amp;a, const InputLayoutKey &amp;b)
+{
+    if (a.elementCount != b.elementCount)
+    {
+        return false;
+    }
+
+    return std::equal(a.begin(), a.end(), b.begin());
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11InputLayoutCacheh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,95 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches
+// D3D11 input layouts.
+
+#ifndef LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+#define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
+
+#include &quot;libGLESv2/Constants.h&quot;
+#include &quot;common/angleutils.h&quot;
+
+namespace gl
+{
+class ProgramBinary;
+}
+
+namespace rx
+{
+struct TranslatedAttribute;
+
+class InputLayoutCache
+{
+  public:
+    InputLayoutCache();
+    virtual ~InputLayoutCache();
+
+    void initialize(ID3D11Device *device, ID3D11DeviceContext *context);
+    void clear();
+    void markDirty();
+
+    GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS],
+                              gl::ProgramBinary *programBinary);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(InputLayoutCache);
+
+    struct InputLayoutElement
+    {
+        D3D11_INPUT_ELEMENT_DESC desc;
+        GLenum glslElementType;
+    };
+
+    struct InputLayoutKey
+    {
+        unsigned int elementCount;
+        InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS];
+
+        const char *begin() const
+        {
+            return reinterpret_cast&lt;const char*&gt;(&amp;elementCount);
+        }
+
+        const char *end() const
+        {
+            return reinterpret_cast&lt;const char*&gt;(&amp;elements[elementCount]);
+        }
+    };
+
+    struct InputLayoutCounterPair
+    {
+        ID3D11InputLayout *inputLayout;
+        unsigned long long lastUsedTime;
+    };
+
+    ID3D11InputLayout *mCurrentIL;
+    unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS];
+    UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS];
+    UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS];
+
+    static std::size_t hashInputLayout(const InputLayoutKey &amp;inputLayout);
+    static bool compareInputLayouts(const InputLayoutKey &amp;a, const InputLayoutKey &amp;b);
+
+    typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &amp;);
+    typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &amp;, const InputLayoutKey &amp;);
+    typedef std::unordered_map&lt;InputLayoutKey,
+                               InputLayoutCounterPair,
+                               InputLayoutHashFunction,
+                               InputLayoutEqualityFunction&gt; InputLayoutMap;
+    InputLayoutMap mInputLayoutMap;
+
+    static const unsigned int kMaxInputLayouts;
+
+    unsigned long long mCounter;
+
+    ID3D11Device *mDevice;
+    ID3D11DeviceContext *mDeviceContext;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/InputLayoutCache.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Query11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#include &quot;libGLESv2/renderer/d3d11/Query11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+
+namespace rx
+{
+
+Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type)
+{
+    mRenderer = renderer;
+    mQuery = NULL;
+}
+
+Query11::~Query11()
+{
+    if (mQuery)
+    {
+        mQuery-&gt;Release();
+        mQuery = NULL;
+    }
+}
+
+void Query11::begin()
+{
+    if (mQuery == NULL)
+    {
+        D3D11_QUERY_DESC queryDesc;
+        queryDesc.Query = D3D11_QUERY_OCCLUSION;
+        queryDesc.MiscFlags = 0;
+
+        if (FAILED(mRenderer-&gt;getDevice()-&gt;CreateQuery(&amp;queryDesc, &amp;mQuery)))
+        {
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    mRenderer-&gt;getDeviceContext()-&gt;Begin(mQuery);
+}
+
+void Query11::end()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    mRenderer-&gt;getDeviceContext()-&gt;End(mQuery);
+
+    mStatus = GL_FALSE;
+    mResult = GL_FALSE;
+}
+
+GLuint Query11::getResult()
+{
+    if (mQuery != NULL)
+    {
+        while (!testQuery())
+        {
+            Sleep(0);
+            // explicitly check for device loss, some drivers seem to return S_FALSE
+            // if the device is lost
+            if (mRenderer-&gt;testDeviceLost(true))
+            {
+                return gl::error(GL_OUT_OF_MEMORY, 0);
+            }
+        }
+    }
+
+    return mResult;
+}
+
+GLboolean Query11::isResultAvailable()
+{
+    if (mQuery != NULL)
+    {
+        testQuery();
+    }
+
+    return mStatus;
+}
+
+GLboolean Query11::testQuery()
+{
+    if (mQuery != NULL &amp;&amp; mStatus != GL_TRUE)
+    {
+        UINT64 numPixels = 0;
+        HRESULT result = mRenderer-&gt;getDeviceContext()-&gt;GetData(mQuery, &amp;numPixels, sizeof(UINT64), 0);
+        if (result == S_OK)
+        {
+            mStatus = GL_TRUE;
+
+            switch (getType())
+            {
+              case GL_ANY_SAMPLES_PASSED_EXT:
+              case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+                mResult = (numPixels &gt; 0) ? GL_TRUE : GL_FALSE;
+                break;
+              default:
+                UNREACHABLE();
+            }
+        }
+        else if (mRenderer-&gt;testDeviceLost(true))
+        {
+            return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+        }
+
+        return mStatus;
+    }
+
+    return GL_TRUE; // prevent blocking when query is null
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Query11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl.
+
+#ifndef LIBGLESV2_RENDERER_QUERY11_H_
+#define LIBGLESV2_RENDERER_QUERY11_H_
+
+#include &quot;libGLESv2/renderer/QueryImpl.h&quot;
+
+namespace rx
+{
+class Renderer11;
+
+class Query11 : public QueryImpl
+{
+  public:
+    Query11(rx::Renderer11 *renderer, GLenum type);
+    virtual ~Query11();
+
+    void begin();
+    void end();
+    GLuint getResult();
+    GLboolean isResultAvailable();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Query11);
+
+    GLboolean testQuery();
+
+    rx::Renderer11 *mRenderer;
+    ID3D11Query *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_QUERY11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Query11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderStateCachecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,438 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#include &quot;libGLESv2/renderer/d3d11/RenderStateCache.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+#include &quot;libGLESv2/utilities.h&quot;
+#include &quot;common/debug.h&quot;
+#include &quot;third_party/murmurhash/MurmurHash3.h&quot;
+
+namespace rx
+{
+
+// MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState,
+// ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum
+// number of unique states of each type an application can create is 4096
+const unsigned int RenderStateCache::kMaxBlendStates = 4096;
+const unsigned int RenderStateCache::kMaxRasterizerStates = 4096;
+const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096;
+const unsigned int RenderStateCache::kMaxSamplerStates = 4096;
+
+RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0),
+                                       mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates),
+                                       mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates),
+                                       mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates),
+                                       mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates)
+{
+}
+
+RenderStateCache::~RenderStateCache()
+{
+    clear();
+}
+
+void RenderStateCache::initialize(ID3D11Device *device)
+{
+    clear();
+    mDevice = device;
+}
+
+void RenderStateCache::clear()
+{
+    for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
+    {
+        i-&gt;second.first-&gt;Release();
+    }
+    mBlendStateCache.clear();
+
+    for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
+    {
+        i-&gt;second.first-&gt;Release();
+    }
+    mRasterizerStateCache.clear();
+
+    for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+    {
+        i-&gt;second.first-&gt;Release();
+    }
+    mDepthStencilStateCache.clear();
+
+    for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
+    {
+        i-&gt;second.first-&gt;Release();
+    }
+    mSamplerStateCache.clear();
+}
+
+std::size_t RenderStateCache::hashBlendState(const BlendStateKey &amp;blendState)
+{
+    static const unsigned int seed = 0xABCDEF98;
+
+    std::size_t hash = 0;
+    MurmurHash3_x86_32(&amp;blendState, sizeof(BlendStateKey), seed, &amp;hash);
+    return hash;
+}
+
+bool RenderStateCache::compareBlendStates(const BlendStateKey &amp;a, const BlendStateKey &amp;b)
+{
+    return memcmp(&amp;a, &amp;b, sizeof(gl::BlendState)) == 0;
+}
+
+ID3D11BlendState *RenderStateCache::getBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState)
+{
+    if (!mDevice)
+    {
+        ERR(&quot;RenderStateCache is not initialized.&quot;);
+        return NULL;
+    }
+
+    bool mrt = false;
+
+    BlendStateKey key = { 0 };
+    key.blendState = blendState;
+    for (unsigned int i = 0; i &lt; D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+    {
+        gl::Renderbuffer *renderBuffer = framebuffer-&gt;getColorbuffer(i);
+        if (renderBuffer)
+        {
+            if (i &gt; 0)
+            {
+                mrt = true;
+            }
+
+            GLenum internalFormat = renderBuffer-&gt;getInternalFormat();
+            key.rtChannels[i][0] = gl::GetRedSize(internalFormat) &gt; 0;
+            key.rtChannels[i][1] = gl::GetGreenSize(internalFormat) &gt; 0;
+            key.rtChannels[i][2] = gl::GetBlueSize(internalFormat) &gt; 0;;
+            key.rtChannels[i][3] = gl::GetAlphaSize(internalFormat) &gt; 0;
+        }
+        else
+        {
+            key.rtChannels[i][0] = false;
+            key.rtChannels[i][1] = false;
+            key.rtChannels[i][2] = false;
+            key.rtChannels[i][3] = false;
+        }
+    }
+
+    BlendStateMap::iterator i = mBlendStateCache.find(key);
+    if (i != mBlendStateCache.end())
+    {
+        BlendStateCounterPair &amp;state = i-&gt;second;
+        state.second = mCounter++;
+        return state.first;
+    }
+    else
+    {
+        if (mBlendStateCache.size() &gt;= kMaxBlendStates)
+        {
+            TRACE(&quot;Overflowed the limit of %u blend states, removing the least recently used &quot;
+                  &quot;to make room.&quot;, kMaxBlendStates);
+
+            BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin();
+            for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++)
+            {
+                if (i-&gt;second.second &lt; leastRecentlyUsed-&gt;second.second)
+                {
+                    leastRecentlyUsed = i;
+                }
+            }
+            leastRecentlyUsed-&gt;second.first-&gt;Release();
+            mBlendStateCache.erase(leastRecentlyUsed);
+        }
+
+        // Create a new blend state and insert it into the cache
+        D3D11_BLEND_DESC blendDesc = { 0 };
+        blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage;
+        blendDesc.IndependentBlendEnable = mrt ? TRUE : FALSE;
+
+        for (unsigned int i = 0; i &lt; D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
+        {
+            D3D11_RENDER_TARGET_BLEND_DESC &amp;rtBlend = blendDesc.RenderTarget[i];
+
+            rtBlend.BlendEnable = blendState.blend;
+            if (blendState.blend)
+            {
+                rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false);
+                rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false);
+                rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB);
+
+                rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true);
+                rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true);
+                rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha);
+            }
+
+            rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(key.rtChannels[i][0] &amp;&amp; blendState.colorMaskRed,
+                                                                       key.rtChannels[i][1] &amp;&amp; blendState.colorMaskGreen,
+                                                                       key.rtChannels[i][2] &amp;&amp; blendState.colorMaskBlue,
+                                                                       key.rtChannels[i][3] &amp;&amp; blendState.colorMaskAlpha);
+        }
+
+        ID3D11BlendState *dx11BlendState = NULL;
+        HRESULT result = mDevice-&gt;CreateBlendState(&amp;blendDesc, &amp;dx11BlendState);
+        if (FAILED(result) || !dx11BlendState)
+        {
+            ERR(&quot;Unable to create a ID3D11BlendState, HRESULT: 0x%X.&quot;, result);
+            return NULL;
+        }
+
+        mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++)));
+
+        return dx11BlendState;
+    }
+}
+
+std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &amp;rasterState)
+{
+    static const unsigned int seed = 0xABCDEF98;
+
+    std::size_t hash = 0;
+    MurmurHash3_x86_32(&amp;rasterState, sizeof(RasterizerStateKey), seed, &amp;hash);
+    return hash;
+}
+
+bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &amp;a, const RasterizerStateKey &amp;b)
+{
+    return memcmp(&amp;a, &amp;b, sizeof(RasterizerStateKey)) == 0;
+}
+
+ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &amp;rasterState,
+                                                            bool scissorEnabled, unsigned int depthSize)
+{
+    if (!mDevice)
+    {
+        ERR(&quot;RenderStateCache is not initialized.&quot;);
+        return NULL;
+    }
+
+    RasterizerStateKey key;
+    key.rasterizerState = rasterState;
+    key.scissorEnabled = scissorEnabled;
+    key.depthSize = depthSize;
+
+    RasterizerStateMap::iterator i = mRasterizerStateCache.find(key);
+    if (i != mRasterizerStateCache.end())
+    {
+        RasterizerStateCounterPair &amp;state = i-&gt;second;
+        state.second = mCounter++;
+        return state.first;
+    }
+    else
+    {
+        if (mRasterizerStateCache.size() &gt;= kMaxRasterizerStates)
+        {
+            TRACE(&quot;Overflowed the limit of %u rasterizer states, removing the least recently used &quot;
+                  &quot;to make room.&quot;, kMaxRasterizerStates);
+
+            RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin();
+            for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++)
+            {
+                if (i-&gt;second.second &lt; leastRecentlyUsed-&gt;second.second)
+                {
+                    leastRecentlyUsed = i;
+                }
+            }
+            leastRecentlyUsed-&gt;second.first-&gt;Release();
+            mRasterizerStateCache.erase(leastRecentlyUsed);
+        }
+
+        D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode);
+
+        // Disable culling if drawing points
+        if (rasterState.pointDrawMode)
+        {
+            cullMode = D3D11_CULL_NONE;
+        }
+
+        D3D11_RASTERIZER_DESC rasterDesc;
+        rasterDesc.FillMode = D3D11_FILL_SOLID;
+        rasterDesc.CullMode = cullMode;
+        rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE;
+        rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast&lt;int&gt;(depthSize));
+        rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though.
+        rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor;
+        rasterDesc.DepthClipEnable = TRUE;
+        rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE;
+        rasterDesc.MultisampleEnable = rasterState.multiSample;
+        rasterDesc.AntialiasedLineEnable = FALSE;
+
+        ID3D11RasterizerState *dx11RasterizerState = NULL;
+        HRESULT result = mDevice-&gt;CreateRasterizerState(&amp;rasterDesc, &amp;dx11RasterizerState);
+        if (FAILED(result) || !dx11RasterizerState)
+        {
+            ERR(&quot;Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.&quot;, result);
+            return NULL;
+        }
+
+        mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++)));
+
+        return dx11RasterizerState;
+    }
+}
+
+std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &amp;dsState)
+{
+    static const unsigned int seed = 0xABCDEF98;
+
+    std::size_t hash = 0;
+    MurmurHash3_x86_32(&amp;dsState, sizeof(gl::DepthStencilState), seed, &amp;hash);
+    return hash;
+}
+
+bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &amp;a, const gl::DepthStencilState &amp;b)
+{
+    return memcmp(&amp;a, &amp;b, sizeof(gl::DepthStencilState)) == 0;
+}
+
+ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &amp;dsState)
+{
+    if (!mDevice)
+    {
+        ERR(&quot;RenderStateCache is not initialized.&quot;);
+        return NULL;
+    }
+
+    DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState);
+    if (i != mDepthStencilStateCache.end())
+    {
+        DepthStencilStateCounterPair &amp;state = i-&gt;second;
+        state.second = mCounter++;
+        return state.first;
+    }
+    else
+    {
+        if (mDepthStencilStateCache.size() &gt;= kMaxDepthStencilStates)
+        {
+            TRACE(&quot;Overflowed the limit of %u depth stencil states, removing the least recently used &quot;
+                  &quot;to make room.&quot;, kMaxDepthStencilStates);
+
+            DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin();
+            for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++)
+            {
+                if (i-&gt;second.second &lt; leastRecentlyUsed-&gt;second.second)
+                {
+                    leastRecentlyUsed = i;
+                }
+            }
+            leastRecentlyUsed-&gt;second.first-&gt;Release();
+            mDepthStencilStateCache.erase(leastRecentlyUsed);
+        }
+
+        D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 };
+        dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE;
+        dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask);
+        dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc);
+        dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE;
+        dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask);
+        dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask);
+        dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail);
+        dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail);
+        dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass);
+        dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc);
+        dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail);
+        dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail);
+        dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass);
+        dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc);
+
+        ID3D11DepthStencilState *dx11DepthStencilState = NULL;
+        HRESULT result = mDevice-&gt;CreateDepthStencilState(&amp;dsDesc, &amp;dx11DepthStencilState);
+        if (FAILED(result) || !dx11DepthStencilState)
+        {
+            ERR(&quot;Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.&quot;, result);
+            return NULL;
+        }
+
+        mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++)));
+
+        return dx11DepthStencilState;
+    }
+}
+
+std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &amp;samplerState)
+{
+    static const unsigned int seed = 0xABCDEF98;
+
+    std::size_t hash = 0;
+    MurmurHash3_x86_32(&amp;samplerState, sizeof(gl::SamplerState), seed, &amp;hash);
+    return hash;
+}
+
+bool RenderStateCache::compareSamplerStates(const gl::SamplerState &amp;a, const gl::SamplerState &amp;b)
+{
+    return memcmp(&amp;a, &amp;b, sizeof(gl::SamplerState)) == 0;
+}
+
+ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &amp;samplerState)
+{
+    if (!mDevice)
+    {
+        ERR(&quot;RenderStateCache is not initialized.&quot;);
+        return NULL;
+    }
+
+    SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState);
+    if (i != mSamplerStateCache.end())
+    {
+        SamplerStateCounterPair &amp;state = i-&gt;second;
+        state.second = mCounter++;
+        return state.first;
+    }
+    else
+    {
+        if (mSamplerStateCache.size() &gt;= kMaxSamplerStates)
+        {
+            TRACE(&quot;Overflowed the limit of %u sampler states, removing the least recently used &quot;
+                  &quot;to make room.&quot;, kMaxSamplerStates);
+
+            SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin();
+            for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++)
+            {
+                if (i-&gt;second.second &lt; leastRecentlyUsed-&gt;second.second)
+                {
+                    leastRecentlyUsed = i;
+                }
+            }
+            leastRecentlyUsed-&gt;second.first-&gt;Release();
+            mSamplerStateCache.erase(leastRecentlyUsed);
+        }
+
+        D3D11_SAMPLER_DESC samplerDesc;
+        samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy);
+        samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS);
+        samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT);
+        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.MipLODBias = static_cast&lt;float&gt;(samplerState.lodOffset);
+        samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy;
+        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+        samplerDesc.BorderColor[0] = 0.0f;
+        samplerDesc.BorderColor[1] = 0.0f;
+        samplerDesc.BorderColor[2] = 0.0f;
+        samplerDesc.BorderColor[3] = 0.0f;
+        samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset);
+        samplerDesc.MaxLOD = gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset);
+
+        ID3D11SamplerState *dx11SamplerState = NULL;
+        HRESULT result = mDevice-&gt;CreateSamplerState(&amp;samplerDesc, &amp;dx11SamplerState);
+        if (FAILED(result) || !dx11SamplerState)
+        {
+            ERR(&quot;Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.&quot;, result);
+            return NULL;
+        }
+
+        mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++)));
+
+        return dx11SamplerState;
+    }
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderStateCacheh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,111 @@
</span><ins>+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render
+// state objects.
+
+#ifndef LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
+#define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
+
+#include &quot;libGLESv2/angletypes.h&quot;
+#include &quot;common/angleutils.h&quot;
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+
+class RenderStateCache
+{
+  public:
+    RenderStateCache();
+    virtual ~RenderStateCache();
+
+    void initialize(ID3D11Device *device);
+    void clear();
+
+    // Increments refcount on the returned blend state, Release() must be called.
+    ID3D11BlendState *getBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState);
+    ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &amp;rasterState,
+                                              bool scissorEnabled, unsigned int depthSize);
+    ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &amp;dsState);
+    ID3D11SamplerState *getSamplerState(const gl::SamplerState &amp;samplerState);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(RenderStateCache);
+
+    unsigned long long mCounter;
+
+    // Blend state cache
+    struct BlendStateKey
+    {
+        gl::BlendState blendState;
+        bool rtChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4];
+    };
+    static std::size_t hashBlendState(const BlendStateKey &amp;blendState);
+    static bool compareBlendStates(const BlendStateKey &amp;a, const BlendStateKey &amp;b);
+    static const unsigned int kMaxBlendStates;
+
+    typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &amp;);
+    typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &amp;, const BlendStateKey &amp;);
+    typedef std::pair&lt;ID3D11BlendState*, unsigned long long&gt; BlendStateCounterPair;
+    typedef std::unordered_map&lt;BlendStateKey, BlendStateCounterPair, BlendStateHashFunction, BlendStateEqualityFunction&gt; BlendStateMap;
+    BlendStateMap mBlendStateCache;
+
+    // Rasterizer state cache
+    struct RasterizerStateKey
+    {
+        gl::RasterizerState rasterizerState;
+        bool scissorEnabled;
+        unsigned int depthSize;
+    };
+    static std::size_t hashRasterizerState(const RasterizerStateKey &amp;rasterState);
+    static bool compareRasterizerStates(const RasterizerStateKey &amp;a, const RasterizerStateKey &amp;b);
+    static const unsigned int kMaxRasterizerStates;
+
+    typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &amp;);
+    typedef bool (*RasterizerStateEqualityFunction)(const RasterizerStateKey &amp;, const RasterizerStateKey &amp;);
+    typedef std::pair&lt;ID3D11RasterizerState*, unsigned long long&gt; RasterizerStateCounterPair;
+    typedef std::unordered_map&lt;RasterizerStateKey, RasterizerStateCounterPair, RasterizerStateHashFunction, RasterizerStateEqualityFunction&gt; RasterizerStateMap;
+    RasterizerStateMap mRasterizerStateCache;
+
+    // Depth stencil state cache
+    static std::size_t hashDepthStencilState(const gl::DepthStencilState &amp;dsState);
+    static bool compareDepthStencilStates(const gl::DepthStencilState &amp;a, const gl::DepthStencilState &amp;b);
+    static const unsigned int kMaxDepthStencilStates;
+
+    typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &amp;);
+    typedef bool (*DepthStencilStateEqualityFunction)(const gl::DepthStencilState &amp;, const gl::DepthStencilState &amp;);
+    typedef std::pair&lt;ID3D11DepthStencilState*, unsigned long long&gt; DepthStencilStateCounterPair;
+    typedef std::unordered_map&lt;gl::DepthStencilState,
+                               DepthStencilStateCounterPair,
+                               DepthStencilStateHashFunction,
+                               DepthStencilStateEqualityFunction&gt; DepthStencilStateMap;
+    DepthStencilStateMap mDepthStencilStateCache;
+
+    // Sample state cache
+    static std::size_t hashSamplerState(const gl::SamplerState &amp;samplerState);
+    static bool compareSamplerStates(const gl::SamplerState &amp;a, const gl::SamplerState &amp;b);
+    static const unsigned int kMaxSamplerStates;
+
+    typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &amp;);
+    typedef bool (*SamplerStateEqualityFunction)(const gl::SamplerState &amp;, const gl::SamplerState &amp;);
+    typedef std::pair&lt;ID3D11SamplerState*, unsigned long long&gt; SamplerStateCounterPair;
+    typedef std::unordered_map&lt;gl::SamplerState,
+                               SamplerStateCounterPair,
+                               SamplerStateHashFunction,
+                               SamplerStateEqualityFunction&gt; SamplerStateMap;
+    SamplerStateMap mSamplerStateCache;
+
+    ID3D11Device *mDevice;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERSTATECACHE_H_
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderStateCache.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderTarget11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,355 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#include &quot;libGLESv2/renderer/d3d11/RenderTarget11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+
+namespace rx
+{
+
+static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view)
+{
+    D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+    view-&gt;GetDesc(&amp;rtvDesc);
+
+    D3D11_TEXTURE2D_DESC texDesc;
+    texture-&gt;GetDesc(&amp;texDesc);
+
+    unsigned int mipSlice = 0;
+    unsigned int arraySlice = 0;
+    unsigned int mipLevels = texDesc.MipLevels;
+
+    switch (rtvDesc.ViewDimension)
+    {
+      case D3D11_RTV_DIMENSION_TEXTURE1D:
+        mipSlice = rtvDesc.Texture1D.MipSlice;
+        arraySlice = 0;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE1DARRAY:
+        mipSlice = rtvDesc.Texture1DArray.MipSlice;
+        arraySlice = rtvDesc.Texture1DArray.FirstArraySlice;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE2D:
+        mipSlice = rtvDesc.Texture2D.MipSlice;
+        arraySlice = 0;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE2DARRAY:
+        mipSlice = rtvDesc.Texture2DArray.MipSlice;
+        arraySlice = rtvDesc.Texture2DArray.FirstArraySlice;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE2DMS:
+        mipSlice = 0;
+        arraySlice = 0;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY:
+        mipSlice = 0;
+        arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice;
+        break;
+
+      case D3D11_RTV_DIMENSION_TEXTURE3D:
+        mipSlice = rtvDesc.Texture3D.MipSlice;
+        arraySlice = 0;
+        break;
+
+      case D3D11_RTV_DIMENSION_UNKNOWN:
+      case D3D11_RTV_DIMENSION_BUFFER:
+        UNIMPLEMENTED();
+        break;
+
+      default:
+        UNREACHABLE();
+        break;
+    }
+
+    return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view)
+{
+    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+    view-&gt;GetDesc(&amp;dsvDesc);
+
+    D3D11_TEXTURE2D_DESC texDesc;
+    texture-&gt;GetDesc(&amp;texDesc);
+
+    unsigned int mipSlice = 0;
+    unsigned int arraySlice = 0;
+    unsigned int mipLevels = texDesc.MipLevels;
+
+    switch (dsvDesc.ViewDimension)
+    {
+      case D3D11_DSV_DIMENSION_TEXTURE1D:
+        mipSlice = dsvDesc.Texture1D.MipSlice;
+        arraySlice = 0;
+        break;
+
+      case D3D11_DSV_DIMENSION_TEXTURE1DARRAY:
+        mipSlice = dsvDesc.Texture1DArray.MipSlice;
+        arraySlice = dsvDesc.Texture1DArray.FirstArraySlice;
+        break;
+
+      case D3D11_DSV_DIMENSION_TEXTURE2D:
+        mipSlice = dsvDesc.Texture2D.MipSlice;
+        arraySlice = 0;
+        break;
+
+      case D3D11_DSV_DIMENSION_TEXTURE2DARRAY:
+        mipSlice = dsvDesc.Texture2DArray.MipSlice;
+        arraySlice = dsvDesc.Texture2DArray.FirstArraySlice;
+        break;
+
+      case D3D11_DSV_DIMENSION_TEXTURE2DMS:
+        mipSlice = 0;
+        arraySlice = 0;
+        break;
+
+      case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY:
+        mipSlice = 0;
+        arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice;
+        break;
+
+      case D3D11_RTV_DIMENSION_UNKNOWN:
+        UNIMPLEMENTED();
+        break;
+
+      default:
+        UNREACHABLE();
+        break;
+    }
+
+    return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels);
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+{
+    mRenderer = Renderer11::makeRenderer11(renderer);
+    mTexture = tex;
+    mRenderTarget = rtv;
+    mDepthStencil = NULL;
+    mShaderResource = srv;
+    mSubresourceIndex = 0;
+
+    if (mRenderTarget &amp;&amp; mTexture)
+    {
+        D3D11_RENDER_TARGET_VIEW_DESC desc;
+        mRenderTarget-&gt;GetDesc(&amp;desc);
+
+        D3D11_TEXTURE2D_DESC texDesc;
+        mTexture-&gt;GetDesc(&amp;texDesc);
+
+        mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget);
+        mWidth = width;
+        mHeight = height;
+        mSamples = (texDesc.SampleDesc.Count &gt; 1) ? texDesc.SampleDesc.Count : 0;
+
+        mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+        mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+    }
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height)
+{
+    mRenderer = Renderer11::makeRenderer11(renderer);
+    mTexture = tex;
+    mRenderTarget = NULL;
+    mDepthStencil = dsv;
+    mShaderResource = srv;
+    mSubresourceIndex = 0;
+
+    if (mDepthStencil &amp;&amp; mTexture)
+    {
+        D3D11_DEPTH_STENCIL_VIEW_DESC desc;
+        mDepthStencil-&gt;GetDesc(&amp;desc);
+
+        D3D11_TEXTURE2D_DESC texDesc;
+        mTexture-&gt;GetDesc(&amp;texDesc);
+
+        mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil);
+        mWidth = width;
+        mHeight = height;
+        mSamples = (texDesc.SampleDesc.Count &gt; 1) ? texDesc.SampleDesc.Count : 0;
+
+        mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+        mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format);
+    }
+}
+
+RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth)
+{
+    mRenderer = Renderer11::makeRenderer11(renderer);
+    mTexture = NULL;
+    mRenderTarget = NULL;
+    mDepthStencil = NULL;
+    mShaderResource = NULL;
+
+    DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format);
+
+    int supportedSamples = mRenderer-&gt;getNearestSupportedSamples(requestedFormat, samples);
+    if (supportedSamples &lt; 0)
+    {
+        gl::error(GL_OUT_OF_MEMORY);
+        return;
+    }
+
+    if (width &gt; 0 &amp;&amp; height &gt; 0)
+    {
+        // Create texture resource
+        D3D11_TEXTURE2D_DESC desc;
+        desc.Width = width; 
+        desc.Height = height;
+        desc.MipLevels = 1;
+        desc.ArraySize = 1;
+        desc.Format = requestedFormat;
+        desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples;
+        desc.SampleDesc.Quality = 0;
+        desc.Usage = D3D11_USAGE_DEFAULT;
+        desc.CPUAccessFlags = 0;
+        desc.MiscFlags = 0;
+        desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE));
+
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+        HRESULT result = device-&gt;CreateTexture2D(&amp;desc, NULL, &amp;mTexture);
+
+        if (result == E_OUTOFMEMORY)
+        {
+            gl::error(GL_OUT_OF_MEMORY);
+            return;
+        }
+        ASSERT(SUCCEEDED(result));
+
+        if (depth)
+        {
+            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+            dsvDesc.Format = requestedFormat;
+            dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS;
+            dsvDesc.Texture2D.MipSlice = 0;
+            dsvDesc.Flags = 0;
+            result = device-&gt;CreateDepthStencilView(mTexture, &amp;dsvDesc, &amp;mDepthStencil);
+
+            if (result == E_OUTOFMEMORY)
+            {
+                mTexture-&gt;Release();
+                mTexture = NULL;
+                gl::error(GL_OUT_OF_MEMORY);
+            }
+            ASSERT(SUCCEEDED(result));
+        }
+        else
+        {
+            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+            rtvDesc.Format = requestedFormat;
+            rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS;
+            rtvDesc.Texture2D.MipSlice = 0;
+            result = device-&gt;CreateRenderTargetView(mTexture, &amp;rtvDesc, &amp;mRenderTarget);
+
+            if (result == E_OUTOFMEMORY)
+            {
+                mTexture-&gt;Release();
+                mTexture = NULL;
+                gl::error(GL_OUT_OF_MEMORY);
+                return;
+            }
+            ASSERT(SUCCEEDED(result));
+
+            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+            srvDesc.Format = requestedFormat;
+            srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS;
+            srvDesc.Texture2D.MostDetailedMip = 0;
+            srvDesc.Texture2D.MipLevels = 1;
+            result = device-&gt;CreateShaderResourceView(mTexture, &amp;srvDesc, &amp;mShaderResource);
+
+            if (result == E_OUTOFMEMORY)
+            {
+                mTexture-&gt;Release();
+                mTexture = NULL;
+                mRenderTarget-&gt;Release();
+                mRenderTarget = NULL;
+                gl::error(GL_OUT_OF_MEMORY);
+                return;
+            }
+            ASSERT(SUCCEEDED(result));
+        }
+    }
+
+    mWidth = width;
+    mHeight = height;
+    mInternalFormat = format;
+    mSamples = supportedSamples;
+    mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat);
+    mSubresourceIndex = D3D11CalcSubresource(0, 0, 1);
+}
+
+RenderTarget11::~RenderTarget11()
+{
+    if (mTexture)
+    {
+        mTexture-&gt;Release();
+        mTexture = NULL;
+    }
+
+    if (mRenderTarget)
+    {
+        mRenderTarget-&gt;Release();
+        mRenderTarget = NULL;
+    }
+
+    if (mDepthStencil)
+    {
+        mDepthStencil-&gt;Release();
+        mDepthStencil = NULL;
+    }
+
+    if (mShaderResource)
+    {
+        mShaderResource-&gt;Release();
+        mShaderResource = NULL;
+    }
+}
+
+RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target));
+    return static_cast&lt;rx::RenderTarget11*&gt;(target);
+}
+
+ID3D11Texture2D *RenderTarget11::getTexture() const
+{
+    return mTexture;
+}
+
+ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const
+{
+    return mRenderTarget;
+}
+
+ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const
+{
+    return mDepthStencil;
+}
+
+ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const
+{
+    return mShaderResource;
+}
+
+unsigned int RenderTarget11::getSubresourceIndex() const
+{
+    return mSubresourceIndex;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11RenderTarget11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers
+// retained by Renderbuffers.
+
+#ifndef LIBGLESV2_RENDERER_RENDERTARGET11_H_
+#define LIBGLESV2_RENDERER_RENDERTARGET11_H_
+
+#include &quot;libGLESv2/renderer/RenderTarget.h&quot;
+
+namespace rx
+{
+class Renderer;
+class Renderer11;
+
+class RenderTarget11 : public RenderTarget
+{
+  public:
+    RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+    RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height);
+    RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth);
+    virtual ~RenderTarget11();
+
+    static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget);
+
+    ID3D11Texture2D *getTexture() const;
+    ID3D11RenderTargetView *getRenderTargetView() const;
+    ID3D11DepthStencilView *getDepthStencilView() const;
+    ID3D11ShaderResourceView *getShaderResourceView() const;
+
+    unsigned int getSubresourceIndex() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(RenderTarget11);
+
+    unsigned int mSubresourceIndex;
+    ID3D11Texture2D *mTexture;
+    ID3D11RenderTargetView *mRenderTarget;
+    ID3D11DepthStencilView *mDepthStencil;
+    ID3D11ShaderResourceView *mShaderResource;
+
+    Renderer11 *mRenderer;
+};
+
+}
+
+#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/RenderTarget11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Renderer11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,3623 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer.
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/utilities.h&quot;
+#include &quot;libGLESv2/Buffer.h&quot;
+#include &quot;libGLESv2/ProgramBinary.h&quot;
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/RenderTarget11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/ShaderExecutable11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/SwapChain11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Image11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/VertexBuffer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/IndexBuffer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/BufferStorage11.h&quot;
+#include &quot;libGLESv2/renderer/VertexDataManager.h&quot;
+#include &quot;libGLESv2/renderer/IndexDataManager.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/TextureStorage11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Query11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Fence11.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h&quot;
+
+#include &quot;libEGL/Display.h&quot;
+
+// Enable ANGLE_SKIP_DXGI_1_2_CHECK if there is not a possibility of using cross-process
+// HWNDs or the Windows 7 Platform Update (KB2670838) is expected to be installed.
+#ifndef ANGLE_SKIP_DXGI_1_2_CHECK
+#define ANGLE_SKIP_DXGI_1_2_CHECK 0
+#endif
+
+#ifdef _DEBUG
+// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples
+// and conformance tests. to enable all warnings, remove this define.
+#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1
+#endif
+
+namespace rx
+{
+static const DXGI_FORMAT RenderTargetFormats[] =
+    {
+        DXGI_FORMAT_B8G8R8A8_UNORM,
+        DXGI_FORMAT_R8G8B8A8_UNORM
+    };
+
+static const DXGI_FORMAT DepthStencilFormats[] =
+    {
+        DXGI_FORMAT_UNKNOWN,
+        DXGI_FORMAT_D24_UNORM_S8_UINT,
+        DXGI_FORMAT_D16_UNORM
+    };
+
+enum
+{
+    MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16
+};
+
+Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc)
+{
+    mVertexDataManager = NULL;
+    mIndexDataManager = NULL;
+
+    mLineLoopIB = NULL;
+    mTriangleFanIB = NULL;
+
+    mCopyResourcesInitialized = false;
+    mCopyVB = NULL;
+    mCopySampler = NULL;
+    mCopyIL = NULL;
+    mCopyVS = NULL;
+    mCopyRGBAPS = NULL;
+    mCopyRGBPS = NULL;
+    mCopyLumPS = NULL;
+    mCopyLumAlphaPS = NULL;
+
+    mClearResourcesInitialized = false;
+    mClearVB = NULL;
+    mClearIL = NULL;
+    mClearVS = NULL;
+    mClearSinglePS = NULL;
+    mClearMultiplePS = NULL;
+    mClearScissorRS = NULL;
+    mClearNoScissorRS = NULL;
+
+    mSyncQuery = NULL;
+
+    mD3d11Module = NULL;
+    mDxgiModule = NULL;
+
+    mDeviceLost = false;
+
+    mMaxSupportedSamples = 0;
+
+    mDevice = NULL;
+    mDeviceContext = NULL;
+    mDxgiAdapter = NULL;
+    mDxgiFactory = NULL;
+
+    mDriverConstantBufferVS = NULL;
+    mDriverConstantBufferPS = NULL;
+
+    mBGRATextureSupport = false;
+
+    mIsGeometryShaderActive = false;
+}
+
+Renderer11::~Renderer11()
+{
+    release();
+}
+
+Renderer11 *Renderer11::makeRenderer11(Renderer *renderer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer));
+    return static_cast&lt;rx::Renderer11*&gt;(renderer);
+}
+
+#ifndef __d3d11_1_h__
+#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081)
+#endif
+
+EGLint Renderer11::initialize()
+{
+    if (!initializeCompiler())
+    {
+        return EGL_NOT_INITIALIZED;
+    }
+
+    mDxgiModule = LoadLibrary(TEXT(&quot;dxgi.dll&quot;));
+    mD3d11Module = LoadLibrary(TEXT(&quot;d3d11.dll&quot;));
+
+    if (mD3d11Module == NULL || mDxgiModule == NULL)
+    {
+        ERR(&quot;Could not load D3D11 or DXGI library - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    // create the D3D11 device
+    ASSERT(mDevice == NULL);
+    PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, &quot;D3D11CreateDevice&quot;);
+
+    if (D3D11CreateDevice == NULL)
+    {
+        ERR(&quot;Could not retrieve D3D11CreateDevice address - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    D3D_FEATURE_LEVEL featureLevels[] =
+    {
+        D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1,
+        D3D_FEATURE_LEVEL_10_0,
+    };
+
+    HRESULT result = S_OK;
+
+#ifdef _DEBUG
+    result = D3D11CreateDevice(NULL,
+                               D3D_DRIVER_TYPE_HARDWARE,
+                               NULL,
+                               D3D11_CREATE_DEVICE_DEBUG,
+                               featureLevels,
+                               ArraySize(featureLevels),
+                               D3D11_SDK_VERSION,
+                               &amp;mDevice,
+                               &amp;mFeatureLevel,
+                               &amp;mDeviceContext);
+
+    if (!mDevice || FAILED(result))
+    {
+        ERR(&quot;Failed creating Debug D3D11 device - falling back to release runtime.\n&quot;);
+    }
+
+    if (!mDevice || FAILED(result))
+#endif
+    {
+        result = D3D11CreateDevice(NULL,
+                                   D3D_DRIVER_TYPE_HARDWARE,
+                                   NULL,
+                                   0,
+                                   featureLevels,
+                                   ArraySize(featureLevels),
+                                   D3D11_SDK_VERSION,
+                                   &amp;mDevice,
+                                   &amp;mFeatureLevel,
+                                   &amp;mDeviceContext);
+
+        if (!mDevice || FAILED(result))
+        {
+            ERR(&quot;Could not create D3D11 device - aborting!\n&quot;);
+            return EGL_NOT_INITIALIZED;   // Cleanup done by destructor through glDestroyRenderer
+        }
+    }
+
+#if !ANGLE_SKIP_DXGI_1_2_CHECK
+    // In order to create a swap chain for an HWND owned by another process, DXGI 1.2 is required.
+    // The easiest way to check is to query for a IDXGIDevice2.
+    bool requireDXGI1_2 = false;
+    HWND hwnd = WindowFromDC(mDc);
+    if (hwnd)
+    {
+        DWORD currentProcessId = GetCurrentProcessId();
+        DWORD wndProcessId;
+        GetWindowThreadProcessId(hwnd, &amp;wndProcessId);
+        requireDXGI1_2 = (currentProcessId != wndProcessId);
+    }
+    else
+    {
+        requireDXGI1_2 = true;
+    }
+
+    if (requireDXGI1_2)
+    {
+        IDXGIDevice2 *dxgiDevice2 = NULL;
+        result = mDevice-&gt;QueryInterface(__uuidof(IDXGIDevice2), (void**)&amp;dxgiDevice2);
+        if (FAILED(result))
+        {
+            ERR(&quot;DXGI 1.2 required to present to HWNDs owned by another process.\n&quot;);
+            return EGL_NOT_INITIALIZED;
+        }
+        SafeRelease(dxgiDevice2);
+    }
+#endif
+
+    IDXGIDevice *dxgiDevice = NULL;
+    result = mDevice-&gt;QueryInterface(__uuidof(IDXGIDevice), (void**)&amp;dxgiDevice);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not query DXGI device - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    result = dxgiDevice-&gt;GetParent(__uuidof(IDXGIAdapter), (void**)&amp;mDxgiAdapter);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not retrieve DXGI adapter - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    dxgiDevice-&gt;Release();
+
+    mDxgiAdapter-&gt;GetDesc(&amp;mAdapterDescription);
+    memset(mDescription, 0, sizeof(mDescription));
+    wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1);
+
+    result = mDxgiAdapter-&gt;GetParent(__uuidof(IDXGIFactory), (void**)&amp;mDxgiFactory);
+
+    if (!mDxgiFactory || FAILED(result))
+    {
+        ERR(&quot;Could not create DXGI factory - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log
+#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) &amp;&amp; defined(_DEBUG)
+    ID3D11InfoQueue *infoQueue;
+    result = mDevice-&gt;QueryInterface(__uuidof(ID3D11InfoQueue),  (void **)&amp;infoQueue);
+
+    if (SUCCEEDED(result))
+    {
+        D3D11_MESSAGE_ID hideMessages[] =
+        {
+            D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET
+        };
+
+        D3D11_INFO_QUEUE_FILTER filter = {0};
+        filter.DenyList.NumIDs = ArraySize(hideMessages);
+        filter.DenyList.pIDList = hideMessages;
+
+        infoQueue-&gt;AddStorageFilterEntries(&amp;filter);
+
+        infoQueue-&gt;Release();
+    }
+#endif
+
+    unsigned int maxSupportedSamples = 0;
+    unsigned int rtFormatCount = ArraySize(RenderTargetFormats);
+    unsigned int dsFormatCount = ArraySize(DepthStencilFormats);
+    for (unsigned int i = 0; i &lt; rtFormatCount + dsFormatCount; ++i)
+    {
+        DXGI_FORMAT format = (i &lt; rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount];
+        if (format != DXGI_FORMAT_UNKNOWN)
+        {
+            UINT formatSupport;
+            result = mDevice-&gt;CheckFormatSupport(format, &amp;formatSupport);
+            if (SUCCEEDED(result) &amp;&amp; (formatSupport &amp; D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET))
+            {
+                MultisampleSupportInfo supportInfo;
+
+                for (unsigned int j = 1; j &lt;= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++)
+                {
+                    result = mDevice-&gt;CheckMultisampleQualityLevels(format, j, &amp;supportInfo.qualityLevels[j - 1]);
+                    if (SUCCEEDED(result) &amp;&amp; supportInfo.qualityLevels[j - 1] &gt; 0)
+                    {
+                        maxSupportedSamples = std::max(j, maxSupportedSamples);
+                    }
+                    else
+                    {
+                        supportInfo.qualityLevels[j - 1] = 0;
+                    }
+                }
+
+                mMultisampleSupportMap.insert(std::make_pair(format, supportInfo));
+            }
+        }
+    }
+    mMaxSupportedSamples = maxSupportedSamples;
+
+    initializeDevice();
+
+    // BGRA texture support is optional in feature levels 10 and 10_1
+    UINT formatSupport;
+    result = mDevice-&gt;CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &amp;formatSupport);
+    if (FAILED(result))
+    {
+        ERR(&quot;Error checking BGRA format support: 0x%08X&quot;, result);
+    }
+    else
+    {
+        const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET);
+        mBGRATextureSupport = (formatSupport &amp; flags) == flags;
+    }
+
+    // Check floating point texture support
+    static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE;
+    static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET;
+    static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE;
+
+    DXGI_FORMAT float16Formats[] =
+    {
+        DXGI_FORMAT_R16_FLOAT,
+        DXGI_FORMAT_R16G16_FLOAT,
+        DXGI_FORMAT_R16G16B16A16_FLOAT,
+    };
+
+    DXGI_FORMAT float32Formats[] =
+    {
+        DXGI_FORMAT_R32_FLOAT,
+        DXGI_FORMAT_R32G32_FLOAT,
+        DXGI_FORMAT_R32G32B32A32_FLOAT,
+    };
+
+    mFloat16TextureSupport = true;
+    mFloat16FilterSupport = true;
+    mFloat16RenderSupport = true;
+    for (unsigned int i = 0; i &lt; ArraySize(float16Formats); i++)
+    {
+        if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(float16Formats[i], &amp;formatSupport)))
+        {
+            mFloat16TextureSupport = mFloat16TextureSupport &amp;&amp; (formatSupport &amp; requiredTextureFlags) == requiredTextureFlags;
+            mFloat16FilterSupport = mFloat16FilterSupport &amp;&amp; (formatSupport &amp; requiredFilterFlags) == requiredFilterFlags;
+            mFloat16RenderSupport = mFloat16RenderSupport &amp;&amp; (formatSupport &amp; requiredRenderableFlags) == requiredRenderableFlags;
+        }
+        else
+        {
+            mFloat16TextureSupport = false;
+            mFloat16RenderSupport = false;
+            mFloat16FilterSupport = false;
+        }
+    }
+
+    mFloat32TextureSupport = true;
+    mFloat32FilterSupport = true;
+    mFloat32RenderSupport = true;
+    for (unsigned int i = 0; i &lt; ArraySize(float32Formats); i++)
+    {
+        if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(float32Formats[i], &amp;formatSupport)))
+        {
+            mFloat32TextureSupport = mFloat32TextureSupport &amp;&amp; (formatSupport &amp; requiredTextureFlags) == requiredTextureFlags;
+            mFloat32FilterSupport = mFloat32FilterSupport &amp;&amp; (formatSupport &amp; requiredFilterFlags) == requiredFilterFlags;
+            mFloat32RenderSupport = mFloat32RenderSupport &amp;&amp; (formatSupport &amp; requiredRenderableFlags) == requiredRenderableFlags;
+        }
+        else
+        {
+            mFloat32TextureSupport = false;
+            mFloat32FilterSupport = false;
+            mFloat32RenderSupport = false;
+        }
+    }
+
+    // Check compressed texture support
+    const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D;
+
+    if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &amp;formatSupport)))
+    {
+        mDXT1TextureSupport = (formatSupport &amp; requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+    }
+    else
+    {
+        mDXT1TextureSupport = false;
+    }
+
+    if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &amp;formatSupport)))
+    {
+        mDXT3TextureSupport = (formatSupport &amp; requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+    }
+    else
+    {
+        mDXT3TextureSupport = false;
+    }
+
+    if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &amp;formatSupport)))
+    {
+        mDXT5TextureSupport = (formatSupport &amp; requiredCompressedTextureFlags) == requiredCompressedTextureFlags;
+    }
+    else
+    {
+        mDXT5TextureSupport = false;
+    }
+
+    // Check depth texture support
+    DXGI_FORMAT depthTextureFormats[] =
+    {
+        DXGI_FORMAT_D16_UNORM,
+        DXGI_FORMAT_D24_UNORM_S8_UINT,
+    };
+
+    static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL |
+                                                          D3D11_FORMAT_SUPPORT_TEXTURE2D;
+
+    mDepthTextureSupport = true;
+    for (unsigned int i = 0; i &lt; ArraySize(depthTextureFormats); i++)
+    {
+        if (SUCCEEDED(mDevice-&gt;CheckFormatSupport(depthTextureFormats[i], &amp;formatSupport)))
+        {
+            mDepthTextureSupport = mDepthTextureSupport &amp;&amp; ((formatSupport &amp; requiredDepthTextureFlags) == requiredDepthTextureFlags);
+        }
+        else
+        {
+            mDepthTextureSupport = false;
+        }
+    }
+
+    return EGL_SUCCESS;
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+void Renderer11::initializeDevice()
+{
+    mStateCache.initialize(mDevice);
+    mInputLayoutCache.initialize(mDevice, mDeviceContext);
+
+    ASSERT(!mVertexDataManager &amp;&amp; !mIndexDataManager);
+    mVertexDataManager = new VertexDataManager(this);
+    mIndexDataManager = new IndexDataManager(this);
+
+    markAllStateDirty();
+}
+
+int Renderer11::generateConfigs(ConfigDesc **configDescList)
+{
+    unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
+    unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
+    (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
+    int numConfigs = 0;
+    
+    for (unsigned int formatIndex = 0; formatIndex &lt; numRenderFormats; formatIndex++)
+    {
+        for (unsigned int depthStencilIndex = 0; depthStencilIndex &lt; numDepthFormats; depthStencilIndex++)
+        {
+            DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
+
+            UINT formatSupport = 0;
+            HRESULT result = mDevice-&gt;CheckFormatSupport(renderTargetFormat, &amp;formatSupport);
+
+            if (SUCCEEDED(result) &amp;&amp; (formatSupport &amp; D3D11_FORMAT_SUPPORT_RENDER_TARGET))
+            {
+                DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
+
+                bool depthStencilFormatOK = true;
+
+                if (depthStencilFormat != DXGI_FORMAT_UNKNOWN)
+                {
+                    UINT formatSupport = 0;
+                    result = mDevice-&gt;CheckFormatSupport(depthStencilFormat, &amp;formatSupport);
+                    depthStencilFormatOK = SUCCEEDED(result) &amp;&amp; (formatSupport &amp; D3D11_FORMAT_SUPPORT_DEPTH_STENCIL);
+                }
+
+                if (depthStencilFormatOK)
+                {
+                    ConfigDesc newConfig;
+                    newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat);
+                    newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat);
+                    newConfig.multiSample = 0;     // FIXME: enumerate multi-sampling
+                    newConfig.fastConfig = true;   // Assume all DX11 format conversions to be fast
+
+                    (*configDescList)[numConfigs++] = newConfig;
+                }
+            }
+        }
+    }
+
+    return numConfigs;
+}
+
+void Renderer11::deleteConfigs(ConfigDesc *configDescList)
+{
+    delete [] (configDescList);
+}
+
+void Renderer11::sync(bool block)
+{
+    if (block)
+    {
+        HRESULT result;
+
+        if (!mSyncQuery)
+        {
+            D3D11_QUERY_DESC queryDesc;
+            queryDesc.Query = D3D11_QUERY_EVENT;
+            queryDesc.MiscFlags = 0;
+
+            result = mDevice-&gt;CreateQuery(&amp;queryDesc, &amp;mSyncQuery);
+            ASSERT(SUCCEEDED(result));
+        }
+
+        mDeviceContext-&gt;End(mSyncQuery);
+        mDeviceContext-&gt;Flush();
+
+        do
+        {
+            result = mDeviceContext-&gt;GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH);
+
+            // Keep polling, but allow other threads to do something useful first
+            Sleep(0);
+
+            if (testDeviceLost(true))
+            {
+                return;
+            }
+        }
+        while (result == S_FALSE);
+    }
+    else
+    {
+        mDeviceContext-&gt;Flush();
+    }
+}
+
+SwapChain *Renderer11::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+{
+    return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+}
+
+void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &amp;samplerState)
+{
+    if (type == gl::SAMPLER_PIXEL)
+    {
+        if (index &lt; 0 || index &gt;= gl::MAX_TEXTURE_IMAGE_UNITS)
+        {
+            ERR(&quot;Pixel shader sampler index %i is not valid.&quot;, index);
+            return;
+        }
+
+        if (mForceSetPixelSamplerStates[index] || memcmp(&amp;samplerState, &amp;mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+        {
+            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
+
+            if (!dxSamplerState)
+            {
+                ERR(&quot;NULL sampler state returned by RenderStateCache::getSamplerState, setting the default&quot;
+                    &quot;sampler state for pixel shaders at slot %i.&quot;, index);
+            }
+
+            mDeviceContext-&gt;PSSetSamplers(index, 1, &amp;dxSamplerState);
+
+            mCurPixelSamplerStates[index] = samplerState;
+        }
+
+        mForceSetPixelSamplerStates[index] = false;
+    }
+    else if (type == gl::SAMPLER_VERTEX)
+    {
+        if (index &lt; 0 || index &gt;= (int)getMaxVertexTextureImageUnits())
+        {
+            ERR(&quot;Vertex shader sampler index %i is not valid.&quot;, index);
+            return;
+        }
+
+        if (mForceSetVertexSamplerStates[index] || memcmp(&amp;samplerState, &amp;mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0)
+        {
+            ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState);
+
+            if (!dxSamplerState)
+            {
+                ERR(&quot;NULL sampler state returned by RenderStateCache::getSamplerState, setting the default&quot;
+                    &quot;sampler state for vertex shaders at slot %i.&quot;, index);
+            }
+
+            mDeviceContext-&gt;VSSetSamplers(index, 1, &amp;dxSamplerState);
+
+            mCurVertexSamplerStates[index] = samplerState;
+        }
+
+        mForceSetVertexSamplerStates[index] = false;
+    }
+    else UNREACHABLE();
+}
+
+void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
+{
+    ID3D11ShaderResourceView *textureSRV = NULL;
+    unsigned int serial = 0;
+    bool forceSetTexture = false;
+
+    if (texture)
+    {
+        TextureStorageInterface *texStorage = texture-&gt;getNativeTexture();
+        if (texStorage)
+        {
+            TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage-&gt;getStorageInstance());
+            textureSRV = storage11-&gt;getSRV();
+        }
+
+        // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly
+        // missing the shader resource view
+        ASSERT(textureSRV != NULL);
+
+        serial = texture-&gt;getTextureSerial();
+        forceSetTexture = texture-&gt;hasDirtyImages();
+    }
+
+    if (type == gl::SAMPLER_PIXEL)
+    {
+        if (index &lt; 0 || index &gt;= gl::MAX_TEXTURE_IMAGE_UNITS)
+        {
+            ERR(&quot;Pixel shader sampler index %i is not valid.&quot;, index);
+            return;
+        }
+
+        if (forceSetTexture || mCurPixelTextureSerials[index] != serial)
+        {
+            mDeviceContext-&gt;PSSetShaderResources(index, 1, &amp;textureSRV);
+        }
+
+        mCurPixelTextureSerials[index] = serial;
+    }
+    else if (type == gl::SAMPLER_VERTEX)
+    {
+        if (index &lt; 0 || index &gt;= (int)getMaxVertexTextureImageUnits())
+        {
+            ERR(&quot;Vertex shader sampler index %i is not valid.&quot;, index);
+            return;
+        }
+
+        if (forceSetTexture || mCurVertexTextureSerials[index] != serial)
+        {
+            mDeviceContext-&gt;VSSetShaderResources(index, 1, &amp;textureSRV);
+        }
+
+        mCurVertexTextureSerials[index] = serial;
+    }
+    else UNREACHABLE();
+}
+
+void Renderer11::setRasterizerState(const gl::RasterizerState &amp;rasterState)
+{
+    if (mForceSetRasterState || memcmp(&amp;rasterState, &amp;mCurRasterState, sizeof(gl::RasterizerState)) != 0)
+    {
+        ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled,
+                                                                              mCurDepthSize);
+        if (!dxRasterState)
+        {
+            ERR(&quot;NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default&quot;
+                &quot;rasterizer state.&quot;);
+        }
+
+        mDeviceContext-&gt;RSSetState(dxRasterState);
+
+        mCurRasterState = rasterState;
+    }
+
+    mForceSetRasterState = false;
+}
+
+void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState, const gl::Color &amp;blendColor,
+                               unsigned int sampleMask)
+{
+    if (mForceSetBlendState ||
+        memcmp(&amp;blendState, &amp;mCurBlendState, sizeof(gl::BlendState)) != 0 ||
+        memcmp(&amp;blendColor, &amp;mCurBlendColor, sizeof(gl::Color)) != 0 ||
+        sampleMask != mCurSampleMask)
+    {
+        ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState);
+        if (!dxBlendState)
+        {
+            ERR(&quot;NULL blend state returned by RenderStateCache::getBlendState, setting the default &quot;
+                &quot;blend state.&quot;);
+        }
+
+        float blendColors[4] = {0.0f};
+        if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &amp;&amp; blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &amp;&amp;
+            blendState.destBlendRGB != GL_CONSTANT_ALPHA &amp;&amp; blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+        {
+            blendColors[0] = blendColor.red;
+            blendColors[1] = blendColor.green;
+            blendColors[2] = blendColor.blue;
+            blendColors[3] = blendColor.alpha;
+        }
+        else
+        {
+            blendColors[0] = blendColor.alpha;
+            blendColors[1] = blendColor.alpha;
+            blendColors[2] = blendColor.alpha;
+            blendColors[3] = blendColor.alpha;
+        }
+
+        mDeviceContext-&gt;OMSetBlendState(dxBlendState, blendColors, sampleMask);
+
+        mCurBlendState = blendState;
+        mCurBlendColor = blendColor;
+        mCurSampleMask = sampleMask;
+    }
+
+    mForceSetBlendState = false;
+}
+
+void Renderer11::setDepthStencilState(const gl::DepthStencilState &amp;depthStencilState, int stencilRef,
+                                      int stencilBackRef, bool frontFaceCCW)
+{
+    if (mForceSetDepthStencilState ||
+        memcmp(&amp;depthStencilState, &amp;mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 ||
+        stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef)
+    {
+        if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
+            stencilRef != stencilBackRef ||
+            depthStencilState.stencilMask != depthStencilState.stencilBackMask)
+        {
+            ERR(&quot;Separate front/back stencil writemasks, reference values, or stencil mask values are &quot;
+                &quot;invalid under WebGL.&quot;);
+            return gl::error(GL_INVALID_OPERATION);
+        }
+
+        ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState);
+        if (!dxDepthStencilState)
+        {
+            ERR(&quot;NULL depth stencil state returned by RenderStateCache::getDepthStencilState, &quot;
+                &quot;setting the default depth stencil state.&quot;);
+        }
+
+        mDeviceContext-&gt;OMSetDepthStencilState(dxDepthStencilState, static_cast&lt;UINT&gt;(stencilRef));
+
+        mCurDepthStencilState = depthStencilState;
+        mCurStencilRef = stencilRef;
+        mCurStencilBackRef = stencilBackRef;
+    }
+
+    mForceSetDepthStencilState = false;
+}
+
+void Renderer11::setScissorRectangle(const gl::Rectangle &amp;scissor, bool enabled)
+{
+    if (mForceSetScissor || memcmp(&amp;scissor, &amp;mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+        enabled != mScissorEnabled)
+    {
+        if (enabled)
+        {
+            D3D11_RECT rect;
+            rect.left = std::max(0, scissor.x);
+            rect.top = std::max(0, scissor.y);
+            rect.right = scissor.x + std::max(0, scissor.width);
+            rect.bottom = scissor.y + std::max(0, scissor.height);
+
+            mDeviceContext-&gt;RSSetScissorRects(1, &amp;rect);
+        }
+
+        if (enabled != mScissorEnabled)
+        {
+            mForceSetRasterState = true;
+        }
+
+        mCurScissor = scissor;
+        mScissorEnabled = enabled;
+    }
+
+    mForceSetScissor = false;
+}
+
+bool Renderer11::setViewport(const gl::Rectangle &amp;viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, 
+                             bool ignoreViewport)
+{
+    gl::Rectangle actualViewport = viewport;
+    float actualZNear = gl::clamp01(zNear);
+    float actualZFar = gl::clamp01(zFar);
+    if (ignoreViewport)
+    {
+        actualViewport.x = 0;
+        actualViewport.y = 0;
+        actualViewport.width = mRenderTargetDesc.width;
+        actualViewport.height = mRenderTargetDesc.height;
+        actualZNear = 0.0f;
+        actualZFar = 1.0f;
+    }
+
+    // Get D3D viewport bounds, which depends on the feature level
+    const Range&amp; viewportBounds = getViewportBounds();
+
+    // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds
+    D3D11_VIEWPORT dxViewport;
+    dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end);
+    dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end);
+    dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension());
+    dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension());
+    dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast&lt;int&gt;(dxViewport.TopLeftX));
+    dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast&lt;int&gt;(dxViewport.TopLeftY));
+    dxViewport.MinDepth = actualZNear;
+    dxViewport.MaxDepth = actualZFar;
+
+    if (dxViewport.Width &lt;= 0 || dxViewport.Height &lt;= 0)
+    {
+        return false;   // Nothing to render
+    }
+
+    bool viewportChanged = mForceSetViewport || memcmp(&amp;actualViewport, &amp;mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+                           actualZNear != mCurNear || actualZFar != mCurFar;
+
+    if (viewportChanged)
+    {
+        mDeviceContext-&gt;RSSetViewports(1, &amp;dxViewport);
+
+        mCurViewport = actualViewport;
+        mCurNear = actualZNear;
+        mCurFar = actualZFar;
+
+        mPixelConstants.viewCoords[0] = actualViewport.width  * 0.5f;
+        mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f;
+        mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width  * 0.5f);
+        mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+
+        mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+        mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+
+        mVertexConstants.depthRange[0] = actualZNear;
+        mVertexConstants.depthRange[1] = actualZFar;
+        mVertexConstants.depthRange[2] = actualZFar - actualZNear;
+
+        mPixelConstants.depthRange[0] = actualZNear;
+        mPixelConstants.depthRange[1] = actualZFar;
+        mPixelConstants.depthRange[2] = actualZFar - actualZNear;
+    }
+
+    mForceSetViewport = false;
+    return true;
+}
+
+bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+    D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
+
+    GLsizei minCount = 0;
+
+    switch (mode)
+    {
+      case GL_POINTS:         primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;   minCount = 1; break;
+      case GL_LINES:          primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;      minCount = 2; break;
+      case GL_LINE_LOOP:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
+      case GL_LINE_STRIP:     primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;     minCount = 2; break;
+      case GL_TRIANGLES:      primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
+      case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break;
+          // emulate fans via rewriting index buffer
+      case GL_TRIANGLE_FAN:   primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;  minCount = 3; break;
+      default:
+        return gl::error(GL_INVALID_ENUM, false);
+    }
+
+    if (primitiveTopology != mCurrentPrimitiveTopology)
+    {
+        mDeviceContext-&gt;IASetPrimitiveTopology(primitiveTopology);
+        mCurrentPrimitiveTopology = primitiveTopology;
+    }
+
+    return count &gt;= minCount;
+}
+
+bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer)
+{
+    // Get the color render buffer and serial
+    // Also extract the render target dimensions and view
+    unsigned int renderTargetWidth = 0;
+    unsigned int renderTargetHeight = 0;
+    GLenum renderTargetFormat = 0;
+    unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0};
+    ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
+    bool missingColorRenderTarget = true;
+
+    for (unsigned int colorAttachment = 0; colorAttachment &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+    {
+        const GLenum drawBufferState = framebuffer-&gt;getDrawBufferState(colorAttachment);
+
+        if (framebuffer-&gt;getColorbufferType(colorAttachment) != GL_NONE &amp;&amp; drawBufferState != GL_NONE)
+        {
+            // the draw buffer must be either &quot;none&quot;, &quot;back&quot; for the default buffer or the same index as this color (in order)
+            ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment));
+
+            gl::Renderbuffer *colorbuffer = framebuffer-&gt;getColorbuffer(colorAttachment);
+
+            if (!colorbuffer)
+            {
+                ERR(&quot;render target pointer unexpectedly null.&quot;);
+                return false;
+            }
+
+            // check for zero-sized default framebuffer, which is a special case.
+            // in this case we do not wish to modify any state and just silently return false.
+            // this will not report any gl error but will cause the calling method to return.
+            if (colorbuffer-&gt;getWidth() == 0 || colorbuffer-&gt;getHeight() == 0)
+            {
+                return false;
+            }
+
+            renderTargetSerials[colorAttachment] = colorbuffer-&gt;getSerial();
+
+            // Extract the render target dimensions and view
+            RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer-&gt;getRenderTarget());
+            if (!renderTarget)
+            {
+                ERR(&quot;render target pointer unexpectedly null.&quot;);
+                return false;
+            }
+
+            framebufferRTVs[colorAttachment] = renderTarget-&gt;getRenderTargetView();
+            if (!framebufferRTVs[colorAttachment])
+            {
+                ERR(&quot;render target view pointer unexpectedly null.&quot;);
+                return false;
+            }
+
+            if (missingColorRenderTarget)
+            {
+                renderTargetWidth = colorbuffer-&gt;getWidth();
+                renderTargetHeight = colorbuffer-&gt;getHeight();
+                renderTargetFormat = colorbuffer-&gt;getActualFormat();
+                missingColorRenderTarget = false;
+            }
+
+#ifdef _DEBUG
+            // Workaround for Debug SETSHADERRESOURCES_HAZARD D3D11 warnings
+            for (unsigned int vertexSerialIndex = 0; vertexSerialIndex &lt; gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; vertexSerialIndex++)
+            {
+                if (colorbuffer-&gt;getTextureSerial() != 0 &amp;&amp; mCurVertexTextureSerials[vertexSerialIndex] == colorbuffer-&gt;getTextureSerial())
+                {
+                    setTexture(gl::SAMPLER_VERTEX, vertexSerialIndex, NULL);
+                }
+            }
+
+            for (unsigned int pixelSerialIndex = 0; pixelSerialIndex &lt; gl::MAX_TEXTURE_IMAGE_UNITS; pixelSerialIndex++)
+            {
+                if (colorbuffer-&gt;getTextureSerial() != 0 &amp;&amp; mCurPixelTextureSerials[pixelSerialIndex] == colorbuffer-&gt;getTextureSerial())
+                {
+                    setTexture(gl::SAMPLER_PIXEL, pixelSerialIndex, NULL);
+                }
+            }
+#endif
+        }
+    }
+
+    // Get the depth stencil render buffer and serials
+    gl::Renderbuffer *depthStencil = NULL;
+    unsigned int depthbufferSerial = 0;
+    unsigned int stencilbufferSerial = 0;
+    if (framebuffer-&gt;getDepthbufferType() != GL_NONE)
+    {
+        depthStencil = framebuffer-&gt;getDepthbuffer();
+        if (!depthStencil)
+        {
+            ERR(&quot;Depth stencil pointer unexpectedly null.&quot;);
+            SafeRelease(framebufferRTVs);
+            return false;
+        }
+
+        depthbufferSerial = depthStencil-&gt;getSerial();
+    }
+    else if (framebuffer-&gt;getStencilbufferType() != GL_NONE)
+    {
+        depthStencil = framebuffer-&gt;getStencilbuffer();
+        if (!depthStencil)
+        {
+            ERR(&quot;Depth stencil pointer unexpectedly null.&quot;);
+            SafeRelease(framebufferRTVs);
+            return false;
+        }
+
+        stencilbufferSerial = depthStencil-&gt;getSerial();
+    }
+
+    // Extract the depth stencil sizes and view
+    unsigned int depthSize = 0;
+    unsigned int stencilSize = 0;
+    ID3D11DepthStencilView* framebufferDSV = NULL;
+    if (depthStencil)
+    {
+        RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil-&gt;getDepthStencil());
+        if (!depthStencilRenderTarget)
+        {
+            ERR(&quot;render target pointer unexpectedly null.&quot;);
+            SafeRelease(framebufferRTVs);
+            return false;
+        }
+
+        framebufferDSV = depthStencilRenderTarget-&gt;getDepthStencilView();
+        if (!framebufferDSV)
+        {
+            ERR(&quot;depth stencil view pointer unexpectedly null.&quot;);
+            SafeRelease(framebufferRTVs);
+            return false;
+        }
+
+        // If there is no render buffer, the width, height and format values come from
+        // the depth stencil
+        if (missingColorRenderTarget)
+        {
+            renderTargetWidth = depthStencil-&gt;getWidth();
+            renderTargetHeight = depthStencil-&gt;getHeight();
+            renderTargetFormat = depthStencil-&gt;getActualFormat();
+        }
+
+        depthSize = depthStencil-&gt;getDepthSize();
+        stencilSize = depthStencil-&gt;getStencilSize();
+    }
+
+    // Apply the render target and depth stencil
+    if (!mRenderTargetDescInitialized || !mDepthStencilInitialized ||
+        memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 ||
+        depthbufferSerial != mAppliedDepthbufferSerial ||
+        stencilbufferSerial != mAppliedStencilbufferSerial)
+    {
+        mDeviceContext-&gt;OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV);
+
+        mRenderTargetDesc.width = renderTargetWidth;
+        mRenderTargetDesc.height = renderTargetHeight;
+        mRenderTargetDesc.format = renderTargetFormat;
+        mForceSetViewport = true;
+        mForceSetScissor = true;
+
+        if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
+        {
+            mCurDepthSize = depthSize;
+            mForceSetRasterState = true;
+        }
+
+        mCurStencilSize = stencilSize;
+
+        for (unsigned int rtIndex = 0; rtIndex &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+        {
+            mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex];
+        }
+        mAppliedDepthbufferSerial = depthbufferSerial;
+        mAppliedStencilbufferSerial = stencilbufferSerial;
+        mRenderTargetDescInitialized = true;
+        mDepthStencilInitialized = true;
+    }
+
+    return true;
+}
+
+GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+{
+    TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
+    GLenum err = mVertexDataManager-&gt;prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+    if (err != GL_NO_ERROR)
+    {
+        return err;
+    }
+
+    return mInputLayoutCache.applyVertexBuffers(attributes, programBinary);
+}
+
+GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+    GLenum err = mIndexDataManager-&gt;prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+
+    if (err == GL_NO_ERROR)
+    {
+        if (indexInfo-&gt;storage)
+        {
+            if (indexInfo-&gt;serial != mAppliedStorageIBSerial || indexInfo-&gt;startOffset != mAppliedIBOffset)
+            {
+                BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo-&gt;storage);
+                IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo-&gt;indexBuffer);
+
+                mDeviceContext-&gt;IASetIndexBuffer(storage-&gt;getBuffer(BUFFER_USAGE_INDEX), indexBuffer-&gt;getIndexFormat(), indexInfo-&gt;startOffset);
+
+                mAppliedIBSerial = 0;
+                mAppliedStorageIBSerial = storage-&gt;getSerial();
+                mAppliedIBOffset = indexInfo-&gt;startOffset;
+            }
+        }
+        else if (indexInfo-&gt;serial != mAppliedIBSerial || indexInfo-&gt;startOffset != mAppliedIBOffset)
+        {
+            IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo-&gt;indexBuffer);
+
+            mDeviceContext-&gt;IASetIndexBuffer(indexBuffer-&gt;getBuffer(), indexBuffer-&gt;getIndexFormat(), indexInfo-&gt;startOffset);
+
+            mAppliedIBSerial = indexInfo-&gt;serial;
+            mAppliedStorageIBSerial = 0;
+            mAppliedIBOffset = indexInfo-&gt;startOffset;
+        }
+    }
+
+    return err;
+}
+
+void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+    if (mode == GL_LINE_LOOP)
+    {
+        drawLineLoop(count, GL_NONE, NULL, 0, NULL);
+    }
+    else if (mode == GL_TRIANGLE_FAN)
+    {
+        drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances);
+    }
+    else if (instances &gt; 0)
+    {
+        mDeviceContext-&gt;DrawInstanced(count, instances, 0, 0);
+    }
+    else
+    {
+        mDeviceContext-&gt;Draw(count, 0);
+    }
+}
+
+void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &amp;indexInfo, GLsizei instances)
+{
+    if (mode == GL_LINE_LOOP)
+    {
+        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+    }
+    else if (mode == GL_TRIANGLE_FAN)
+    {
+        drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances);
+    }
+    else if (instances &gt; 0)
+    {
+        mDeviceContext-&gt;DrawIndexedInstanced(count, instances, 0, -static_cast&lt;int&gt;(indexInfo.minIndex), 0);
+    }
+    else
+    {
+        mDeviceContext-&gt;DrawIndexed(count, 0, -static_cast&lt;int&gt;(indexInfo.minIndex));
+    }
+}
+
+void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+    // Get the raw indices for an indexed draw
+    if (type != GL_NONE &amp;&amp; elementArrayBuffer)
+    {
+        gl::Buffer *indexBuffer = elementArrayBuffer;
+        BufferStorage *storage = indexBuffer-&gt;getStorage();
+        intptr_t offset = reinterpret_cast&lt;intptr_t&gt;(indices);
+        indices = static_cast&lt;const GLubyte*&gt;(storage-&gt;getData()) + offset;
+    }
+
+    if (!mLineLoopIB)
+    {
+        mLineLoopIB = new StreamingIndexBufferInterface(this);
+        if (!mLineLoopIB-&gt;reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+        {
+            delete mLineLoopIB;
+            mLineLoopIB = NULL;
+
+            ERR(&quot;Could not create a 32-bit looping index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    // Checked by Renderer11::applyPrimitiveType
+    ASSERT(count &gt;= 0);
+
+    if (static_cast&lt;unsigned int&gt;(count) + 1 &gt; (std::numeric_limits&lt;unsigned int&gt;::max() / sizeof(unsigned int)))
+    {
+        ERR(&quot;Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    const unsigned int spaceNeeded = (static_cast&lt;unsigned int&gt;(count) + 1) * sizeof(unsigned int);
+    if (!mLineLoopIB-&gt;reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+    {
+        ERR(&quot;Could not reserve enough space in looping index buffer for GL_LINE_LOOP.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    void* mappedMemory = NULL;
+    unsigned int offset;
+    if (!mLineLoopIB-&gt;mapBuffer(spaceNeeded, &amp;mappedMemory, &amp;offset))
+    {
+        ERR(&quot;Could not map index buffer for GL_LINE_LOOP.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    unsigned int *data = reinterpret_cast&lt;unsigned int*&gt;(mappedMemory);
+    unsigned int indexBufferOffset = offset;
+
+    switch (type)
+    {
+      case GL_NONE:   // Non-indexed draw
+        for (int i = 0; i &lt; count; i++)
+        {
+            data[i] = i;
+        }
+        data[count] = 0;
+        break;
+      case GL_UNSIGNED_BYTE:
+        for (int i = 0; i &lt; count; i++)
+        {
+            data[i] = static_cast&lt;const GLubyte*&gt;(indices)[i];
+        }
+        data[count] = static_cast&lt;const GLubyte*&gt;(indices)[0];
+        break;
+      case GL_UNSIGNED_SHORT:
+        for (int i = 0; i &lt; count; i++)
+        {
+            data[i] = static_cast&lt;const GLushort*&gt;(indices)[i];
+        }
+        data[count] = static_cast&lt;const GLushort*&gt;(indices)[0];
+        break;
+      case GL_UNSIGNED_INT:
+        for (int i = 0; i &lt; count; i++)
+        {
+            data[i] = static_cast&lt;const GLuint*&gt;(indices)[i];
+        }
+        data[count] = static_cast&lt;const GLuint*&gt;(indices)[0];
+        break;
+      default: UNREACHABLE();
+    }
+
+    if (!mLineLoopIB-&gt;unmapBuffer())
+    {
+        ERR(&quot;Could not unmap index buffer for GL_LINE_LOOP.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    if (mAppliedIBSerial != mLineLoopIB-&gt;getSerial() || mAppliedIBOffset != indexBufferOffset)
+    {
+        IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB-&gt;getIndexBuffer());
+
+        mDeviceContext-&gt;IASetIndexBuffer(indexBuffer-&gt;getBuffer(), indexBuffer-&gt;getIndexFormat(), indexBufferOffset);
+        mAppliedIBSerial = mLineLoopIB-&gt;getSerial();
+        mAppliedStorageIBSerial = 0;
+        mAppliedIBOffset = indexBufferOffset;
+    }
+
+    mDeviceContext-&gt;DrawIndexed(count + 1, 0, -minIndex);
+}
+
+void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances)
+{
+    // Get the raw indices for an indexed draw
+    if (type != GL_NONE &amp;&amp; elementArrayBuffer)
+    {
+        gl::Buffer *indexBuffer = elementArrayBuffer;
+        BufferStorage *storage = indexBuffer-&gt;getStorage();
+        intptr_t offset = reinterpret_cast&lt;intptr_t&gt;(indices);
+        indices = static_cast&lt;const GLubyte*&gt;(storage-&gt;getData()) + offset;
+    }
+
+    if (!mTriangleFanIB)
+    {
+        mTriangleFanIB = new StreamingIndexBufferInterface(this);
+        if (!mTriangleFanIB-&gt;reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+        {
+            delete mTriangleFanIB;
+            mTriangleFanIB = NULL;
+
+            ERR(&quot;Could not create a scratch index buffer for GL_TRIANGLE_FAN.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    // Checked by Renderer11::applyPrimitiveType
+    ASSERT(count &gt;= 3);
+
+    const unsigned int numTris = count - 2;
+
+    if (numTris &gt; (std::numeric_limits&lt;unsigned int&gt;::max() / (sizeof(unsigned int) * 3)))
+    {
+        ERR(&quot;Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int);
+    if (!mTriangleFanIB-&gt;reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+    {
+        ERR(&quot;Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    void* mappedMemory = NULL;
+    unsigned int offset;
+    if (!mTriangleFanIB-&gt;mapBuffer(spaceNeeded, &amp;mappedMemory, &amp;offset))
+    {
+        ERR(&quot;Could not map scratch index buffer for GL_TRIANGLE_FAN.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    unsigned int *data = reinterpret_cast&lt;unsigned int*&gt;(mappedMemory);
+    unsigned int indexBufferOffset = offset;
+
+    switch (type)
+    {
+      case GL_NONE:   // Non-indexed draw
+        for (unsigned int i = 0; i &lt; numTris; i++)
+        {
+            data[i*3 + 0] = 0;
+            data[i*3 + 1] = i + 1;
+            data[i*3 + 2] = i + 2;
+        }
+        break;
+      case GL_UNSIGNED_BYTE:
+        for (unsigned int i = 0; i &lt; numTris; i++)
+        {
+            data[i*3 + 0] = static_cast&lt;const GLubyte*&gt;(indices)[0];
+            data[i*3 + 1] = static_cast&lt;const GLubyte*&gt;(indices)[i + 1];
+            data[i*3 + 2] = static_cast&lt;const GLubyte*&gt;(indices)[i + 2];
+        }
+        break;
+      case GL_UNSIGNED_SHORT:
+        for (unsigned int i = 0; i &lt; numTris; i++)
+        {
+            data[i*3 + 0] = static_cast&lt;const GLushort*&gt;(indices)[0];
+            data[i*3 + 1] = static_cast&lt;const GLushort*&gt;(indices)[i + 1];
+            data[i*3 + 2] = static_cast&lt;const GLushort*&gt;(indices)[i + 2];
+        }
+        break;
+      case GL_UNSIGNED_INT:
+        for (unsigned int i = 0; i &lt; numTris; i++)
+        {
+            data[i*3 + 0] = static_cast&lt;const GLuint*&gt;(indices)[0];
+            data[i*3 + 1] = static_cast&lt;const GLuint*&gt;(indices)[i + 1];
+            data[i*3 + 2] = static_cast&lt;const GLuint*&gt;(indices)[i + 2];
+        }
+        break;
+      default: UNREACHABLE();
+    }
+
+    if (!mTriangleFanIB-&gt;unmapBuffer())
+    {
+        ERR(&quot;Could not unmap scratch index buffer for GL_TRIANGLE_FAN.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    if (mAppliedIBSerial != mTriangleFanIB-&gt;getSerial() || mAppliedIBOffset != indexBufferOffset)
+    {
+        IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB-&gt;getIndexBuffer());
+
+        mDeviceContext-&gt;IASetIndexBuffer(indexBuffer-&gt;getBuffer(), indexBuffer-&gt;getIndexFormat(), indexBufferOffset);
+        mAppliedIBSerial = mTriangleFanIB-&gt;getSerial();
+        mAppliedStorageIBSerial = 0;
+        mAppliedIBOffset = indexBufferOffset;
+    }
+
+    if (instances &gt; 0)
+    {
+        mDeviceContext-&gt;DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0);
+    }
+    else
+    {
+        mDeviceContext-&gt;DrawIndexed(numTris * 3, 0, -minIndex);
+    }
+}
+
+void Renderer11::applyShaders(gl::ProgramBinary *programBinary)
+{
+    unsigned int programBinarySerial = programBinary-&gt;getSerial();
+    const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial);
+
+    if (updateProgramState)
+    {
+        ShaderExecutable *vertexExe = programBinary-&gt;getVertexExecutable();
+        ShaderExecutable *pixelExe = programBinary-&gt;getPixelExecutable();
+
+        ID3D11VertexShader *vertexShader = NULL;
+        if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)-&gt;getVertexShader();
+
+        ID3D11PixelShader *pixelShader = NULL;
+        if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)-&gt;getPixelShader();
+
+        mDeviceContext-&gt;PSSetShader(pixelShader, NULL, 0);
+        mDeviceContext-&gt;VSSetShader(vertexShader, NULL, 0);
+
+        programBinary-&gt;dirtyAllUniforms();
+
+        mAppliedProgramBinarySerial = programBinarySerial;
+    }
+
+    // Only use the geometry shader currently for point sprite drawing
+    const bool usesGeometryShader = (programBinary-&gt;usesGeometryShader() &amp;&amp; mCurRasterState.pointDrawMode);
+
+    if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive)
+    {
+        if (usesGeometryShader)
+        {
+            ShaderExecutable *geometryExe = programBinary-&gt;getGeometryExecutable();
+            ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)-&gt;getGeometryShader();
+            mDeviceContext-&gt;GSSetShader(geometryShader, NULL, 0);
+        }
+        else
+        {
+            mDeviceContext-&gt;GSSetShader(NULL, NULL, 0);
+        }
+
+        mIsGeometryShaderActive = usesGeometryShader;
+    }
+}
+
+void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
+{
+    ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary-&gt;getVertexExecutable());
+    ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary-&gt;getPixelExecutable());
+
+    unsigned int totalRegisterCountVS = 0;
+    unsigned int totalRegisterCountPS = 0;
+
+    bool vertexUniformsDirty = false;
+    bool pixelUniformsDirty = false;
+
+    for (gl::UniformArray::const_iterator uniform_iterator = uniformArray-&gt;begin(); uniform_iterator != uniformArray-&gt;end(); uniform_iterator++)
+    {
+        const gl::Uniform *uniform = *uniform_iterator;
+
+        if (uniform-&gt;vsRegisterIndex &gt;= 0)
+        {
+            totalRegisterCountVS += uniform-&gt;registerCount;
+            vertexUniformsDirty = vertexUniformsDirty || uniform-&gt;dirty;
+        }
+
+        if (uniform-&gt;psRegisterIndex &gt;= 0)
+        {
+            totalRegisterCountPS += uniform-&gt;registerCount;
+            pixelUniformsDirty = pixelUniformsDirty || uniform-&gt;dirty;
+        }
+    }
+
+    ID3D11Buffer *vertexConstantBuffer = vertexExecutable-&gt;getConstantBuffer(mDevice, totalRegisterCountVS);
+    ID3D11Buffer *pixelConstantBuffer = pixelExecutable-&gt;getConstantBuffer(mDevice, totalRegisterCountPS);
+
+    float (*mapVS)[4] = NULL;
+    float (*mapPS)[4] = NULL;
+
+    if (totalRegisterCountVS &gt; 0 &amp;&amp; vertexUniformsDirty)
+    {
+        D3D11_MAPPED_SUBRESOURCE map = {0};
+        HRESULT result = mDeviceContext-&gt;Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;map);
+        ASSERT(SUCCEEDED(result));
+        mapVS = (float(*)[4])map.pData;
+    }
+
+    if (totalRegisterCountPS &gt; 0 &amp;&amp; pixelUniformsDirty)
+    {
+        D3D11_MAPPED_SUBRESOURCE map = {0};
+        HRESULT result = mDeviceContext-&gt;Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;map);
+        ASSERT(SUCCEEDED(result));
+        mapPS = (float(*)[4])map.pData;
+    }
+
+    for (gl::UniformArray::iterator uniform_iterator = uniformArray-&gt;begin(); uniform_iterator != uniformArray-&gt;end(); uniform_iterator++)
+    {
+        gl::Uniform *uniform = *uniform_iterator;
+
+        if (uniform-&gt;type !=  GL_SAMPLER_2D &amp;&amp; uniform-&gt;type != GL_SAMPLER_CUBE)
+        {
+            if (uniform-&gt;vsRegisterIndex &gt;= 0 &amp;&amp; mapVS)
+            {
+                memcpy(mapVS + uniform-&gt;vsRegisterIndex, uniform-&gt;data, uniform-&gt;registerCount * sizeof(float[4]));
+            }
+
+            if (uniform-&gt;psRegisterIndex &gt;= 0 &amp;&amp; mapPS)
+            {
+                memcpy(mapPS + uniform-&gt;psRegisterIndex, uniform-&gt;data, uniform-&gt;registerCount * sizeof(float[4]));
+            }
+        }
+
+        uniform-&gt;dirty = false;
+    }
+
+    if (mapVS)
+    {
+        mDeviceContext-&gt;Unmap(vertexConstantBuffer, 0);
+    }
+
+    if (mapPS)
+    {
+        mDeviceContext-&gt;Unmap(pixelConstantBuffer, 0);
+    }
+
+    if (mCurrentVertexConstantBuffer != vertexConstantBuffer)
+    {
+        mDeviceContext-&gt;VSSetConstantBuffers(0, 1, &amp;vertexConstantBuffer);
+        mCurrentVertexConstantBuffer = vertexConstantBuffer;
+    }
+
+    if (mCurrentPixelConstantBuffer != pixelConstantBuffer)
+    {
+        mDeviceContext-&gt;PSSetConstantBuffers(0, 1, &amp;pixelConstantBuffer);
+        mCurrentPixelConstantBuffer = pixelConstantBuffer;
+    }
+
+    // Driver uniforms
+    if (!mDriverConstantBufferVS)
+    {
+        D3D11_BUFFER_DESC constantBufferDescription = {0};
+        constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants);
+        constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
+        constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+        constantBufferDescription.CPUAccessFlags = 0;
+        constantBufferDescription.MiscFlags = 0;
+        constantBufferDescription.StructureByteStride = 0;
+
+        HRESULT result = mDevice-&gt;CreateBuffer(&amp;constantBufferDescription, NULL, &amp;mDriverConstantBufferVS);
+        ASSERT(SUCCEEDED(result));
+
+        mDeviceContext-&gt;VSSetConstantBuffers(1, 1, &amp;mDriverConstantBufferVS);
+    }
+
+    if (!mDriverConstantBufferPS)
+    {
+        D3D11_BUFFER_DESC constantBufferDescription = {0};
+        constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants);
+        constantBufferDescription.Usage = D3D11_USAGE_DEFAULT;
+        constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+        constantBufferDescription.CPUAccessFlags = 0;
+        constantBufferDescription.MiscFlags = 0;
+        constantBufferDescription.StructureByteStride = 0;
+
+        HRESULT result = mDevice-&gt;CreateBuffer(&amp;constantBufferDescription, NULL, &amp;mDriverConstantBufferPS);
+        ASSERT(SUCCEEDED(result));
+
+        mDeviceContext-&gt;PSSetConstantBuffers(1, 1, &amp;mDriverConstantBufferPS);
+    }
+
+    if (memcmp(&amp;mVertexConstants, &amp;mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0)
+    {
+        mDeviceContext-&gt;UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &amp;mVertexConstants, 16, 0);
+        memcpy(&amp;mAppliedVertexConstants, &amp;mVertexConstants, sizeof(dx_VertexConstants));
+    }
+
+    if (memcmp(&amp;mPixelConstants, &amp;mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0)
+    {
+        mDeviceContext-&gt;UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &amp;mPixelConstants, 16, 0);
+        memcpy(&amp;mAppliedPixelConstants, &amp;mPixelConstants, sizeof(dx_PixelConstants));
+    }
+
+    // needed for the point sprite geometry shader
+    if (mCurrentGeometryConstantBuffer != mDriverConstantBufferPS)
+    {
+        mDeviceContext-&gt;GSSetConstantBuffers(0, 1, &amp;mDriverConstantBufferPS);
+        mCurrentGeometryConstantBuffer = mDriverConstantBufferPS;
+    }
+}
+
+void Renderer11::clear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer)
+{
+     gl::Renderbuffer *firstRenderbuffer = frameBuffer-&gt;getFirstColorbuffer();
+     GLenum internalFormat = firstRenderbuffer ? firstRenderbuffer-&gt;getInternalFormat() : GL_NONE;
+
+     bool needMaskedColorClear = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) &amp;&amp;
+                                 ((!clearParams.colorMaskRed &amp;&amp; gl::GetRedSize(internalFormat) &gt; 0) ||
+                                  (!clearParams.colorMaskGreen &amp;&amp; gl::GetGreenSize(internalFormat) &gt; 0) ||
+                                  (!clearParams.colorMaskBlue &amp;&amp; gl::GetBlueSize(internalFormat) &gt; 0) ||
+                                  (!clearParams.colorMaskAlpha &amp;&amp; gl::GetAlphaSize(internalFormat) &gt; 0));
+
+     unsigned int stencilUnmasked = 0x0;
+     if (frameBuffer-&gt;hasStencil())
+     {
+         unsigned int stencilSize = gl::GetStencilSize(frameBuffer-&gt;getStencilbuffer()-&gt;getActualFormat());
+         stencilUnmasked = (0x1 &lt;&lt; stencilSize) - 1;
+     }
+     bool needMaskedStencilClear = (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT) &amp;&amp;
+                                   (clearParams.stencilWriteMask &amp; stencilUnmasked) != stencilUnmasked;
+
+     bool needScissoredClear = mScissorEnabled &amp;&amp; (mCurScissor.x &gt; 0 || mCurScissor.y &gt; 0 ||
+                                                   mCurScissor.x + mCurScissor.width &lt; mRenderTargetDesc.width ||
+                                                   mCurScissor.y + mCurScissor.height &lt; mRenderTargetDesc.height);
+
+     if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear)
+     {
+         maskedClear(clearParams, frameBuffer);
+     }
+     else
+     {
+         if (clearParams.mask &amp; GL_COLOR_BUFFER_BIT)
+         {
+             for (unsigned int colorAttachment = 0; colorAttachment &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+             {
+                 if (frameBuffer-&gt;isEnabledColorAttachment(colorAttachment))
+                 {
+                     gl::Renderbuffer *renderbufferObject = frameBuffer-&gt;getColorbuffer(colorAttachment);
+                     if (renderbufferObject)
+                     {
+                        RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject-&gt;getRenderTarget());
+                        if (!renderTarget)
+                        {
+                            ERR(&quot;render target pointer unexpectedly null.&quot;);
+                            return;
+                        }
+
+                        ID3D11RenderTargetView *framebufferRTV = renderTarget-&gt;getRenderTargetView();
+                        if (!framebufferRTV)
+                        {
+                            ERR(&quot;render target view pointer unexpectedly null.&quot;);
+                            return;
+                        }
+
+                        GLenum format = renderbufferObject-&gt;getInternalFormat();
+
+                        const float clearValues[4] = { (gl::GetRedSize(format) &gt; 0)   ? clearParams.colorClearValue.red   : 0.0f,
+                                                       (gl::GetGreenSize(format) &gt; 0) ? clearParams.colorClearValue.green : 0.0f,
+                                                       (gl::GetBlueSize(format) &gt; 0)  ? clearParams.colorClearValue.blue  : 0.0f,
+                                                       (gl::GetAlphaSize(format) &gt; 0) ? clearParams.colorClearValue.alpha : 1.0f };
+                        mDeviceContext-&gt;ClearRenderTargetView(framebufferRTV, clearValues);
+                    }
+                 }
+             }
+        }
+        if (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT || clearParams.mask &amp; GL_STENCIL_BUFFER_BIT)
+        {
+            gl::Renderbuffer *renderbufferObject = frameBuffer-&gt;getDepthOrStencilbuffer();
+            if (renderbufferObject)
+            {
+                RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject-&gt;getDepthStencil());
+                if (!renderTarget)
+                {
+                    ERR(&quot;render target pointer unexpectedly null.&quot;);
+                    return;
+                }
+
+                ID3D11DepthStencilView *framebufferDSV = renderTarget-&gt;getDepthStencilView();
+                if (!framebufferDSV)
+                {
+                    ERR(&quot;depth stencil view pointer unexpectedly null.&quot;);
+                    return;
+                }
+
+                UINT clearFlags = 0;
+                if (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT)
+                {
+                    clearFlags |= D3D11_CLEAR_DEPTH;
+                }
+                if (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT)
+                {
+                    clearFlags |= D3D11_CLEAR_STENCIL;
+                }
+
+                float depthClear = gl::clamp01(clearParams.depthClearValue);
+                UINT8 stencilClear = clearParams.stencilClearValue &amp; 0x000000FF;
+
+                mDeviceContext-&gt;ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear);
+            }
+        }
+    }
+}
+
+void Renderer11::maskedClear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer)
+{
+    HRESULT result;
+
+    if (!mClearResourcesInitialized)
+    {
+        ASSERT(!mClearVB &amp;&amp; !mClearVS &amp;&amp; !mClearSinglePS &amp;&amp; !mClearMultiplePS &amp;&amp; !mClearScissorRS &amp;&amp; !mClearNoScissorRS);
+
+        D3D11_BUFFER_DESC vbDesc;
+        vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4;
+        vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+        vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        vbDesc.MiscFlags = 0;
+        vbDesc.StructureByteStride = 0;
+
+        result = mDevice-&gt;CreateBuffer(&amp;vbDesc, NULL, &amp;mClearVB);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearVB, &quot;Renderer11 masked clear vertex buffer&quot;);
+
+        D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+        {
+            { &quot;POSITION&quot;, 0, DXGI_FORMAT_R32G32B32_FLOAT,    0,  0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+            { &quot;COLOR&quot;,    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        };
+
+        result = mDevice-&gt;CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &amp;mClearIL);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearIL, &quot;Renderer11 masked clear input layout&quot;);
+
+        result = mDevice-&gt;CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &amp;mClearVS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearVS, &quot;Renderer11 masked clear vertex shader&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &amp;mClearSinglePS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearSinglePS, &quot;Renderer11 masked clear pixel shader (1 RT)&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &amp;mClearMultiplePS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearMultiplePS, &quot;Renderer11 masked clear pixel shader (MRT)&quot;);
+
+        D3D11_RASTERIZER_DESC rsScissorDesc;
+        rsScissorDesc.FillMode = D3D11_FILL_SOLID;
+        rsScissorDesc.CullMode = D3D11_CULL_NONE;
+        rsScissorDesc.FrontCounterClockwise = FALSE;
+        rsScissorDesc.DepthBias = 0;
+        rsScissorDesc.DepthBiasClamp = 0.0f;
+        rsScissorDesc.SlopeScaledDepthBias = 0.0f;
+        rsScissorDesc.DepthClipEnable = FALSE;
+        rsScissorDesc.ScissorEnable = TRUE;
+        rsScissorDesc.MultisampleEnable = FALSE;
+        rsScissorDesc.AntialiasedLineEnable = FALSE;
+
+        result = mDevice-&gt;CreateRasterizerState(&amp;rsScissorDesc, &amp;mClearScissorRS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearScissorRS, &quot;Renderer11 masked clear scissor rasterizer state&quot;);
+
+        D3D11_RASTERIZER_DESC rsNoScissorDesc;
+        rsNoScissorDesc.FillMode = D3D11_FILL_SOLID;
+        rsNoScissorDesc.CullMode = D3D11_CULL_NONE;
+        rsNoScissorDesc.FrontCounterClockwise = FALSE;
+        rsNoScissorDesc.DepthBias = 0;
+        rsNoScissorDesc.DepthBiasClamp = 0.0f;
+        rsNoScissorDesc.SlopeScaledDepthBias = 0.0f;
+        rsNoScissorDesc.DepthClipEnable = FALSE;
+        rsNoScissorDesc.ScissorEnable = FALSE;
+        rsNoScissorDesc.MultisampleEnable = FALSE;
+        rsNoScissorDesc.AntialiasedLineEnable = FALSE;
+
+        result = mDevice-&gt;CreateRasterizerState(&amp;rsNoScissorDesc, &amp;mClearNoScissorRS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mClearNoScissorRS, &quot;Renderer11 masked clear no scissor rasterizer state&quot;);
+
+        mClearResourcesInitialized = true;
+    }
+
+    // Prepare the depth stencil state to write depth values if the depth should be cleared
+    // and stencil values if the stencil should be cleared
+    gl::DepthStencilState glDSState;
+    glDSState.depthTest = (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT) != 0;
+    glDSState.depthFunc = GL_ALWAYS;
+    glDSState.depthMask = (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT) != 0;
+    glDSState.stencilTest = (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT) != 0;
+    glDSState.stencilFunc = GL_ALWAYS;
+    glDSState.stencilMask = 0;
+    glDSState.stencilFail = GL_REPLACE;
+    glDSState.stencilPassDepthFail = GL_REPLACE;
+    glDSState.stencilPassDepthPass = GL_REPLACE;
+    glDSState.stencilWritemask = clearParams.stencilWriteMask;
+    glDSState.stencilBackFunc = GL_ALWAYS;
+    glDSState.stencilBackMask = 0;
+    glDSState.stencilBackFail = GL_REPLACE;
+    glDSState.stencilBackPassDepthFail = GL_REPLACE;
+    glDSState.stencilBackPassDepthPass = GL_REPLACE;
+    glDSState.stencilBackWritemask = clearParams.stencilWriteMask;
+
+    int stencilClear = clearParams.stencilClearValue &amp; 0x000000FF;
+
+    ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState);
+
+    // Prepare the blend state to use a write mask if the color buffer should be cleared
+    gl::BlendState glBlendState;
+    glBlendState.blend = false;
+    glBlendState.sourceBlendRGB = GL_ONE;
+    glBlendState.destBlendRGB = GL_ZERO;
+    glBlendState.sourceBlendAlpha = GL_ONE;
+    glBlendState.destBlendAlpha = GL_ZERO;
+    glBlendState.blendEquationRGB = GL_FUNC_ADD;
+    glBlendState.blendEquationAlpha = GL_FUNC_ADD;
+    glBlendState.colorMaskRed = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false;
+    glBlendState.colorMaskGreen = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false;
+    glBlendState.colorMaskBlue = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false;
+    glBlendState.colorMaskAlpha = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false;
+    glBlendState.sampleAlphaToCoverage = false;
+    glBlendState.dither = false;
+
+    static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+    static const UINT sampleMask = 0xFFFFFFFF;
+
+    ID3D11BlendState *blendState = mStateCache.getBlendState(frameBuffer, glBlendState);
+
+    // Set the vertices
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    result = mDeviceContext-&gt;Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
+    if (FAILED(result))
+    {
+        ERR(&quot;Failed to map masked clear vertex buffer, HRESULT: 0x%X.&quot;, result);
+        return;
+    }
+
+    d3d11::PositionDepthColorVertex *vertices = reinterpret_cast&lt;d3d11::PositionDepthColorVertex*&gt;(mappedResource.pData);
+
+    float depthClear = gl::clamp01(clearParams.depthClearValue);
+    d3d11::SetPositionDepthColorVertex(&amp;vertices[0], -1.0f,  1.0f, depthClear, clearParams.colorClearValue);
+    d3d11::SetPositionDepthColorVertex(&amp;vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue);
+    d3d11::SetPositionDepthColorVertex(&amp;vertices[2],  1.0f,  1.0f, depthClear, clearParams.colorClearValue);
+    d3d11::SetPositionDepthColorVertex(&amp;vertices[3],  1.0f, -1.0f, depthClear, clearParams.colorClearValue);
+
+    mDeviceContext-&gt;Unmap(mClearVB, 0);
+
+    // Apply state
+    mDeviceContext-&gt;OMSetBlendState(blendState, blendFactors, sampleMask);
+    mDeviceContext-&gt;OMSetDepthStencilState(dsState, stencilClear);
+    mDeviceContext-&gt;RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS);
+
+    // Apply shaders
+    ID3D11PixelShader *pixelShader = frameBuffer-&gt;usingExtendedDrawBuffers() ? mClearMultiplePS : mClearSinglePS;
+
+    mDeviceContext-&gt;IASetInputLayout(mClearIL);
+    mDeviceContext-&gt;VSSetShader(mClearVS, NULL, 0);
+    mDeviceContext-&gt;PSSetShader(pixelShader, NULL, 0);
+    mDeviceContext-&gt;GSSetShader(NULL, NULL, 0);
+
+    // Apply vertex buffer
+    static UINT stride = sizeof(d3d11::PositionDepthColorVertex);
+    static UINT startIdx = 0;
+    mDeviceContext-&gt;IASetVertexBuffers(0, 1, &amp;mClearVB, &amp;stride, &amp;startIdx);
+    mDeviceContext-&gt;IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+    // Draw the clear quad
+    mDeviceContext-&gt;Draw(4, 0);
+
+    // Clean up
+    markAllStateDirty();
+}
+
+void Renderer11::markAllStateDirty()
+{
+    for (unsigned int rtIndex = 0; rtIndex &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+    {
+        mAppliedRenderTargetSerials[rtIndex] = 0;
+    }
+    mAppliedDepthbufferSerial = 0;
+    mAppliedStencilbufferSerial = 0;
+    mDepthStencilInitialized = false;
+    mRenderTargetDescInitialized = false;
+
+    for (int i = 0; i &lt; gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+    {
+        mForceSetVertexSamplerStates[i] = true;
+        mCurVertexTextureSerials[i] = 0;
+    }
+    for (int i = 0; i &lt; gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+    {
+        mForceSetPixelSamplerStates[i] = true;
+        mCurPixelTextureSerials[i] = 0;
+    }
+
+    mForceSetBlendState = true;
+    mForceSetRasterState = true;
+    mForceSetDepthStencilState = true;
+    mForceSetScissor = true;
+    mForceSetViewport = true;
+
+    mAppliedIBSerial = 0;
+    mAppliedStorageIBSerial = 0;
+    mAppliedIBOffset = 0;
+
+    mAppliedProgramBinarySerial = 0;
+    memset(&amp;mAppliedVertexConstants, 0, sizeof(dx_VertexConstants));
+    memset(&amp;mAppliedPixelConstants, 0, sizeof(dx_PixelConstants));
+
+    mInputLayoutCache.markDirty();
+
+    mCurrentVertexConstantBuffer = NULL;
+    mCurrentPixelConstantBuffer = NULL;
+    mCurrentGeometryConstantBuffer = NULL;
+
+    mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED;
+}
+
+void Renderer11::releaseDeviceResources()
+{
+    mStateCache.clear();
+    mInputLayoutCache.clear();
+
+    delete mVertexDataManager;
+    mVertexDataManager = NULL;
+
+    delete mIndexDataManager;
+    mIndexDataManager = NULL;
+
+    delete mLineLoopIB;
+    mLineLoopIB = NULL;
+
+    delete mTriangleFanIB;
+    mTriangleFanIB = NULL;
+
+    SafeRelease(mCopyVB);
+    SafeRelease(mCopySampler);
+    SafeRelease(mCopyIL);
+    SafeRelease(mCopyIL);
+    SafeRelease(mCopyVS);
+    SafeRelease(mCopyRGBAPS);
+    SafeRelease(mCopyRGBPS);
+    SafeRelease(mCopyLumPS);
+    SafeRelease(mCopyLumAlphaPS);
+
+    mCopyResourcesInitialized = false;
+
+    SafeRelease(mClearVB);
+    SafeRelease(mClearIL);
+    SafeRelease(mClearVS);
+    SafeRelease(mClearSinglePS);
+    SafeRelease(mClearMultiplePS);
+    SafeRelease(mClearScissorRS);
+    SafeRelease(mClearNoScissorRS);
+
+    mClearResourcesInitialized = false;
+
+    SafeRelease(mDriverConstantBufferVS);
+    SafeRelease(mDriverConstantBufferPS);
+    SafeRelease(mSyncQuery);
+}
+
+void Renderer11::notifyDeviceLost()
+{
+    mDeviceLost = true;
+    mDisplay-&gt;notifyDeviceLost();
+}
+
+bool Renderer11::isDeviceLost()
+{
+    return mDeviceLost;
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer11::testDeviceLost(bool notify)
+{
+    bool isLost = false;
+
+    // GetRemovedReason is used to test if the device is removed
+    HRESULT result = mDevice-&gt;GetDeviceRemovedReason();
+    isLost = d3d11::isDeviceLostError(result);
+
+    if (isLost)
+    {
+        // Log error if this is a new device lost event
+        if (mDeviceLost == false)
+        {
+            ERR(&quot;The D3D11 device was removed: 0x%08X&quot;, result);
+        }
+
+        // ensure we note the device loss --
+        // we'll probably get this done again by notifyDeviceLost
+        // but best to remember it!
+        // Note that we don't want to clear the device loss status here
+        // -- this needs to be done by resetDevice
+        mDeviceLost = true;
+        if (notify)
+        {
+            notifyDeviceLost();
+        }
+    }
+
+    return isLost;
+}
+
+bool Renderer11::testDeviceResettable()
+{
+    // determine if the device is resettable by creating a dummy device
+    PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, &quot;D3D11CreateDevice&quot;);
+
+    if (D3D11CreateDevice == NULL)
+    {
+        return false;
+    }
+
+    D3D_FEATURE_LEVEL featureLevels[] =
+    {
+        D3D_FEATURE_LEVEL_11_0,
+        D3D_FEATURE_LEVEL_10_1,
+        D3D_FEATURE_LEVEL_10_0,
+    };
+
+    ID3D11Device* dummyDevice;
+    D3D_FEATURE_LEVEL dummyFeatureLevel;
+    ID3D11DeviceContext* dummyContext;
+
+    HRESULT result = D3D11CreateDevice(NULL,
+                                       D3D_DRIVER_TYPE_HARDWARE,
+                                       NULL,
+                                       #if defined(_DEBUG)
+                                       D3D11_CREATE_DEVICE_DEBUG,
+                                       #else
+                                       0,
+                                       #endif
+                                       featureLevels,
+                                       ArraySize(featureLevels),
+                                       D3D11_SDK_VERSION,
+                                       &amp;dummyDevice,
+                                       &amp;dummyFeatureLevel,
+                                       &amp;dummyContext);
+
+    if (!mDevice || FAILED(result))
+    {
+        return false;
+    }
+
+    dummyContext-&gt;Release();
+    dummyDevice-&gt;Release();
+
+    return true;
+}
+
+void Renderer11::release()
+{
+    releaseDeviceResources();
+
+    if (mDxgiFactory)
+    {
+        mDxgiFactory-&gt;Release();
+        mDxgiFactory = NULL;
+    }
+
+    if (mDxgiAdapter)
+    {
+        mDxgiAdapter-&gt;Release();
+        mDxgiAdapter = NULL;
+    }
+
+    if (mDeviceContext)
+    {
+        mDeviceContext-&gt;ClearState();
+        mDeviceContext-&gt;Flush();
+        mDeviceContext-&gt;Release();
+        mDeviceContext = NULL;
+    }
+
+    if (mDevice)
+    {
+        mDevice-&gt;Release();
+        mDevice = NULL;
+    }
+
+    if (mD3d11Module)
+    {
+        FreeLibrary(mD3d11Module);
+        mD3d11Module = NULL;
+    }
+
+    if (mDxgiModule)
+    {
+        FreeLibrary(mDxgiModule);
+        mDxgiModule = NULL;
+    }
+}
+
+bool Renderer11::resetDevice()
+{
+    // recreate everything
+    release();
+    EGLint result = initialize();
+
+    if (result != EGL_SUCCESS)
+    {
+        ERR(&quot;Could not reinitialize D3D11 device: %08X&quot;, result);
+        return false;
+    }
+
+    mDeviceLost = false;
+
+    return true;
+}
+
+DWORD Renderer11::getAdapterVendor() const
+{
+    return mAdapterDescription.VendorId;
+}
+
+std::string Renderer11::getRendererDescription() const
+{
+    std::ostringstream rendererString;
+
+    rendererString &lt;&lt; mDescription;
+    rendererString &lt;&lt; &quot; Direct3D11&quot;;
+
+    rendererString &lt;&lt; &quot; vs_&quot; &lt;&lt; getMajorShaderModel() &lt;&lt; &quot;_&quot; &lt;&lt; getMinorShaderModel();
+    rendererString &lt;&lt; &quot; ps_&quot; &lt;&lt; getMajorShaderModel() &lt;&lt; &quot;_&quot; &lt;&lt; getMinorShaderModel();
+
+    return rendererString.str();
+}
+
+GUID Renderer11::getAdapterIdentifier() const
+{
+    // Use the adapter LUID as our adapter ID
+    // This number is local to a machine is only guaranteed to be unique between restarts
+    META_ASSERT(sizeof(LUID) &lt;= sizeof(GUID));
+    GUID adapterId = {0};
+    memcpy(&amp;adapterId, &amp;mAdapterDescription.AdapterLuid, sizeof(LUID));
+    return adapterId;
+}
+
+bool Renderer11::getBGRATextureSupport() const
+{
+    return mBGRATextureSupport;
+}
+
+bool Renderer11::getDXT1TextureSupport()
+{
+    return mDXT1TextureSupport;
+}
+
+bool Renderer11::getDXT3TextureSupport()
+{
+    return mDXT3TextureSupport;
+}
+
+bool Renderer11::getDXT5TextureSupport()
+{
+    return mDXT5TextureSupport;
+}
+
+bool Renderer11::getDepthTextureSupport() const
+{
+    return mDepthTextureSupport;
+}
+
+bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable)
+{
+    *renderable = mFloat32RenderSupport;
+    *filtering = mFloat32FilterSupport;
+    return mFloat32TextureSupport;
+}
+
+bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable)
+{
+    *renderable = mFloat16RenderSupport;
+    *filtering = mFloat16FilterSupport;
+    return mFloat16TextureSupport;
+}
+
+bool Renderer11::getLuminanceTextureSupport()
+{
+    return false;
+}
+
+bool Renderer11::getLuminanceAlphaTextureSupport()
+{
+    return false;
+}
+
+bool Renderer11::getTextureFilterAnisotropySupport() const
+{
+    return true;
+}
+
+float Renderer11::getTextureMaxAnisotropy() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+        return D3D11_MAX_MAXANISOTROPY;
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return D3D10_MAX_MAXANISOTROPY;
+      default: UNREACHABLE();
+        return 0;
+    }
+}
+
+bool Renderer11::getEventQuerySupport()
+{
+    return true;
+}
+
+Range Renderer11::getViewportBounds() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+        return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX);
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX);
+      default: UNREACHABLE();
+        return Range(0, 0);
+    }
+}
+
+unsigned int Renderer11::getMaxVertexTextureImageUnits() const
+{
+    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 &lt;= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4;
+      default: UNREACHABLE();
+        return 0;
+    }
+}
+
+unsigned int Renderer11::getMaxCombinedTextureImageUnits() const
+{
+    return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
+}
+
+unsigned int Renderer11::getReservedVertexUniformVectors() const
+{
+    return 0;   // Driver uniforms are stored in a separate constant buffer
+}
+
+unsigned int Renderer11::getReservedFragmentUniformVectors() const
+{
+    return 0;   // Driver uniforms are stored in a separate constant buffer
+}
+
+unsigned int Renderer11::getMaxVertexUniformVectors() const
+{
+    META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 &lt;= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+    ASSERT(mFeatureLevel &gt;= D3D_FEATURE_LEVEL_10_0);
+    return MAX_VERTEX_UNIFORM_VECTORS_D3D11;
+}
+
+unsigned int Renderer11::getMaxFragmentUniformVectors() const
+{
+    META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 &lt;= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT);
+    ASSERT(mFeatureLevel &gt;= D3D_FEATURE_LEVEL_10_0);
+    return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11;
+}
+
+unsigned int Renderer11::getMaxVaryingVectors() const
+{
+    META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT);
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+        return D3D11_VS_OUTPUT_REGISTER_COUNT;
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return D3D10_VS_OUTPUT_REGISTER_COUNT;
+      default: UNREACHABLE();
+        return 0;
+    }
+}
+
+bool Renderer11::getNonPower2TextureSupport() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return true;
+      default: UNREACHABLE();
+        return false;
+    }
+}
+
+bool Renderer11::getOcclusionQuerySupport() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return true;
+      default: UNREACHABLE();
+        return false;
+    }
+}
+
+bool Renderer11::getInstancingSupport() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return true;
+      default: UNREACHABLE();
+        return false;
+    }
+}
+
+bool Renderer11::getShareHandleSupport() const
+{
+    // We only currently support share handles with BGRA surfaces, because
+    // chrome needs BGRA. Once chrome fixes this, we should always support them.
+    // PIX doesn't seem to support using share handles, so disable them.
+    return getBGRATextureSupport() &amp;&amp; !gl::perfActive();
+}
+
+bool Renderer11::getDerivativeInstructionSupport() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        return true;
+      default: UNREACHABLE();
+        return false;
+    }
+}
+
+bool Renderer11::getPostSubBufferSupport() const
+{
+    // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2.
+    return false;
+}
+
+int Renderer11::getMajorShaderModel() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION;   // 5
+      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION;   // 4
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+int Renderer11::getMinorShaderModel() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION;   // 0
+      case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION;   // 0
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+float Renderer11::getMaxPointSize() const
+{
+    // choose a reasonable maximum. we enforce this in the shader.
+    // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size)
+    return 1024.0f;
+}
+
+int Renderer11::getMaxViewportDimension() const
+{
+    // Maximum viewport size must be at least as large as the largest render buffer (or larger).
+    // In our case return the maximum texture size, which is the maximum render buffer size.
+    META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 &lt;= D3D11_VIEWPORT_BOUNDS_MAX);
+    META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 &lt;= D3D10_VIEWPORT_BOUNDS_MAX);
+
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: 
+        return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: 
+        return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
+      default: UNREACHABLE();      
+        return 0;
+    }
+}
+
+int Renderer11::getMaxTextureWidth() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+int Renderer11::getMaxTextureHeight() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 16384
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;   // 8192
+      default: UNREACHABLE();      return 0;
+    }
+}
+
+bool Renderer11::get32BitIndexSupport() const
+{
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0: 
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP &gt;= 32;   // true
+      default: UNREACHABLE();      return false;
+    }
+}
+
+int Renderer11::getMinSwapInterval() const
+{
+    return 0;
+}
+
+int Renderer11::getMaxSwapInterval() const
+{
+    return 4;
+}
+
+int Renderer11::getMaxSupportedSamples() const
+{
+    return mMaxSupportedSamples;
+}
+
+int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const
+{
+    if (requested == 0)
+    {
+        return 0;
+    }
+
+    MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format);
+    if (iter != mMultisampleSupportMap.end())
+    {
+        const MultisampleSupportInfo&amp; info = iter-&gt;second;
+        for (unsigned int i = requested - 1; i &lt; D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++)
+        {
+            if (info.qualityLevels[i] &gt; 0)
+            {
+                return i + 1;
+            }
+        }
+    }
+
+    return -1;
+}
+
+unsigned int Renderer11::getMaxRenderTargets() const
+{
+    META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT &lt;= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+    META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT &lt;= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
+
+    switch (mFeatureLevel)
+    {
+      case D3D_FEATURE_LEVEL_11_0:
+        return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;  // 8
+      case D3D_FEATURE_LEVEL_10_1:
+      case D3D_FEATURE_LEVEL_10_0:
+        // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader
+        // outputs to multiple RTs that are not bound.
+        // TODO: Remove pixel shader outputs for render targets that are not bound.
+        return 1;
+      default:
+        UNREACHABLE();
+        return 1;
+    }
+}
+
+bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+{
+    if (source &amp;&amp; dest)
+    {
+        TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source-&gt;getStorageInstance());
+        TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest-&gt;getStorageInstance());
+
+        mDeviceContext-&gt;CopyResource(dest11-&gt;getBaseTexture(), source11-&gt;getBaseTexture());
+        return true;
+    }
+
+    return false;
+}
+
+bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+{
+    if (source &amp;&amp; dest)
+    {
+        TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source-&gt;getStorageInstance());
+        TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest-&gt;getStorageInstance());
+
+        mDeviceContext-&gt;CopyResource(dest11-&gt;getBaseTexture(), source11-&gt;getBaseTexture());
+        return true;
+    }
+
+    return false;
+}
+
+bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getReadColorbuffer();
+    if (!colorbuffer)
+    {
+        ERR(&quot;Failed to retrieve the color buffer from the frame buffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer-&gt;getRenderTarget());
+    if (!sourceRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the render target from the frame buffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11ShaderResourceView *source = sourceRenderTarget-&gt;getShaderResourceView();
+    if (!source)
+    {
+        ERR(&quot;Failed to retrieve the render target view from the render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage-&gt;getStorageInstance());
+    if (!storage11)
+    {
+        ERR(&quot;Failed to retrieve the texture storage from the destination.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11-&gt;getRenderTarget(level));
+    if (!destRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the render target from the destination storage.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11RenderTargetView *dest = destRenderTarget-&gt;getRenderTargetView();
+    if (!dest)
+    {
+        ERR(&quot;Failed to retrieve the render target view from the destination render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    gl::Rectangle destRect;
+    destRect.x = xoffset;
+    destRect.y = yoffset;
+    destRect.width = sourceRect.width;
+    destRect.height = sourceRect.height;
+
+    bool ret = copyTexture(source, sourceRect, sourceRenderTarget-&gt;getWidth(), sourceRenderTarget-&gt;getHeight(),
+                           dest, destRect, destRenderTarget-&gt;getWidth(), destRenderTarget-&gt;getHeight(), destFormat);
+
+    return ret;
+}
+
+bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getReadColorbuffer();
+    if (!colorbuffer)
+    {
+        ERR(&quot;Failed to retrieve the color buffer from the frame buffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer-&gt;getRenderTarget());
+    if (!sourceRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the render target from the frame buffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11ShaderResourceView *source = sourceRenderTarget-&gt;getShaderResourceView();
+    if (!source)
+    {
+        ERR(&quot;Failed to retrieve the render target view from the render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage-&gt;getStorageInstance());
+    if (!storage11)
+    {
+        ERR(&quot;Failed to retrieve the texture storage from the destination.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11-&gt;getRenderTarget(target, level));
+    if (!destRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the render target from the destination storage.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11RenderTargetView *dest = destRenderTarget-&gt;getRenderTargetView();
+    if (!dest)
+    {
+        ERR(&quot;Failed to retrieve the render target view from the destination render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    gl::Rectangle destRect;
+    destRect.x = xoffset;
+    destRect.y = yoffset;
+    destRect.width = sourceRect.width;
+    destRect.height = sourceRect.height;
+
+    bool ret = copyTexture(source, sourceRect, sourceRenderTarget-&gt;getWidth(), sourceRenderTarget-&gt;getHeight(),
+                           dest, destRect, destRenderTarget-&gt;getWidth(), destRenderTarget-&gt;getHeight(), destFormat);
+
+    return ret;
+}
+
+bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &amp;sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+                             ID3D11RenderTargetView *dest, const gl::Rectangle &amp;destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat)
+{
+    HRESULT result;
+
+    if (!mCopyResourcesInitialized)
+    {
+        ASSERT(!mCopyVB &amp;&amp; !mCopySampler &amp;&amp; !mCopyIL &amp;&amp; !mCopyVS &amp;&amp; !mCopyRGBAPS &amp;&amp; !mCopyRGBPS &amp;&amp; !mCopyLumPS &amp;&amp; !mCopyLumAlphaPS);
+
+        D3D11_BUFFER_DESC vbDesc;
+        vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+        vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+        vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        vbDesc.MiscFlags = 0;
+        vbDesc.StructureByteStride = 0;
+
+        result = mDevice-&gt;CreateBuffer(&amp;vbDesc, NULL, &amp;mCopyVB);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyVB, &quot;Renderer11 copy texture vertex buffer&quot;);
+
+        D3D11_SAMPLER_DESC samplerDesc;
+        samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+        samplerDesc.MipLODBias = 0.0f;
+        samplerDesc.MaxAnisotropy = 0;
+        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+        samplerDesc.BorderColor[0] = 0.0f;
+        samplerDesc.BorderColor[1] = 0.0f;
+        samplerDesc.BorderColor[2] = 0.0f;
+        samplerDesc.BorderColor[3] = 0.0f;
+        samplerDesc.MinLOD = 0.0f;
+        samplerDesc.MaxLOD = 0.0f;
+
+        result = mDevice-&gt;CreateSamplerState(&amp;samplerDesc, &amp;mCopySampler);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopySampler, &quot;Renderer11 copy sampler&quot;);
+
+        D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+        {
+            { &quot;POSITION&quot;, 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+            { &quot;TEXCOORD&quot;, 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        };
+
+        result = mDevice-&gt;CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &amp;mCopyIL);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyIL, &quot;Renderer11 copy texture input layout&quot;);
+
+        result = mDevice-&gt;CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &amp;mCopyVS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyVS, &quot;Renderer11 copy texture vertex shader&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &amp;mCopyRGBAPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyRGBAPS, &quot;Renderer11 copy texture RGBA pixel shader&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &amp;mCopyRGBPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyRGBPS, &quot;Renderer11 copy texture RGB pixel shader&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &amp;mCopyLumPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyLumPS, &quot;Renderer11 copy texture luminance pixel shader&quot;);
+
+        result = mDevice-&gt;CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &amp;mCopyLumAlphaPS);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mCopyLumAlphaPS, &quot;Renderer11 copy texture luminance alpha pixel shader&quot;);
+
+        mCopyResourcesInitialized = true;
+    }
+
+    // Verify the source and destination area sizes
+    if (sourceArea.x &lt; 0 || sourceArea.x + sourceArea.width &gt; static_cast&lt;int&gt;(sourceWidth) ||
+        sourceArea.y &lt; 0 || sourceArea.y + sourceArea.height &gt; static_cast&lt;int&gt;(sourceHeight) ||
+        destArea.x &lt; 0 || destArea.x + destArea.width &gt; static_cast&lt;int&gt;(destWidth) ||
+        destArea.y &lt; 0 || destArea.y + destArea.height &gt; static_cast&lt;int&gt;(destHeight))
+    {
+        return gl::error(GL_INVALID_VALUE, false);
+    }
+
+    // Set vertices
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    result = mDeviceContext-&gt;Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
+    if (FAILED(result))
+    {
+        ERR(&quot;Failed to map vertex buffer for texture copy, HRESULT: 0x%X.&quot;, result);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    d3d11::PositionTexCoordVertex *vertices = static_cast&lt;d3d11::PositionTexCoordVertex*&gt;(mappedResource.pData);
+
+    // Create a quad in homogeneous coordinates
+    float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f;
+    float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f;
+    float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f;
+    float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f;
+
+    float u1 = sourceArea.x / float(sourceWidth);
+    float v1 = sourceArea.y / float(sourceHeight);
+    float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth);
+    float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight);
+
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[0], x1, y1, u1, v2);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[1], x1, y2, u1, v1);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[2], x2, y1, u2, v2);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[3], x2, y2, u2, v1);
+
+    mDeviceContext-&gt;Unmap(mCopyVB, 0);
+
+    static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+    static UINT startIdx = 0;
+    mDeviceContext-&gt;IASetVertexBuffers(0, 1, &amp;mCopyVB, &amp;stride, &amp;startIdx);
+
+    // Apply state
+    mDeviceContext-&gt;OMSetBlendState(NULL, NULL, 0xFFFFFFF);
+    mDeviceContext-&gt;OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+    mDeviceContext-&gt;RSSetState(NULL);
+
+    // Apply shaders
+    mDeviceContext-&gt;IASetInputLayout(mCopyIL);
+    mDeviceContext-&gt;IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+    mDeviceContext-&gt;VSSetShader(mCopyVS, NULL, 0);
+
+    ID3D11PixelShader *ps = NULL;
+    switch(destFormat)
+    {
+      case GL_RGBA:            ps = mCopyRGBAPS;     break;
+      case GL_RGB:             ps = mCopyRGBPS;      break;
+      case GL_ALPHA:           ps = mCopyRGBAPS;     break;
+      case GL_BGRA_EXT:        ps = mCopyRGBAPS;     break;
+      case GL_LUMINANCE:       ps = mCopyLumPS;      break;
+      case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break;
+      default: UNREACHABLE();  ps = NULL;            break;
+    }
+
+    mDeviceContext-&gt;PSSetShader(ps, NULL, 0);
+    mDeviceContext-&gt;GSSetShader(NULL, NULL, 0);
+
+    // Unset the currently bound shader resource to avoid conflicts
+    static ID3D11ShaderResourceView *const nullSRV = NULL;
+    mDeviceContext-&gt;PSSetShaderResources(0, 1, &amp;nullSRV);
+
+    // Apply render target
+    setOneTimeRenderTarget(dest);
+
+    // Set the viewport
+    D3D11_VIEWPORT viewport;
+    viewport.TopLeftX = 0;
+    viewport.TopLeftY = 0;
+    viewport.Width = destWidth;
+    viewport.Height = destHeight;
+    viewport.MinDepth = 0.0f;
+    viewport.MaxDepth = 1.0f;
+    mDeviceContext-&gt;RSSetViewports(1, &amp;viewport);
+
+    // Apply textures
+    mDeviceContext-&gt;PSSetShaderResources(0, 1, &amp;source);
+    mDeviceContext-&gt;PSSetSamplers(0, 1, &amp;mCopySampler);
+
+    // Draw the quad
+    mDeviceContext-&gt;Draw(4, 0);
+
+    // Unbind textures and render targets and vertex buffer
+    mDeviceContext-&gt;PSSetShaderResources(0, 1, &amp;nullSRV);
+
+    unapplyRenderTargets();
+
+    UINT zero = 0;
+    ID3D11Buffer *const nullBuffer = NULL;
+    mDeviceContext-&gt;IASetVertexBuffers(0, 1, &amp;nullBuffer, &amp;zero, &amp;zero);
+
+    markAllStateDirty();
+
+    return true;
+}
+
+void Renderer11::unapplyRenderTargets()
+{
+    setOneTimeRenderTarget(NULL);
+}
+
+void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView)
+{
+    ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL};
+
+    rtvArray[0] = renderTargetView;
+
+    mDeviceContext-&gt;OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL);
+
+    // Do not preserve the serial for this one-time-use render target
+    for (unsigned int rtIndex = 0; rtIndex &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++)
+    {
+        mAppliedRenderTargetSerials[rtIndex] = 0;
+    }
+}
+
+RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth)
+{
+    SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
+    RenderTarget11 *renderTarget = NULL;
+
+    if (depth)
+    {
+        // Note: depth stencil may be NULL for 0 sized surfaces
+        renderTarget = new RenderTarget11(this, swapChain11-&gt;getDepthStencil(),
+                                          swapChain11-&gt;getDepthStencilTexture(), NULL,
+                                          swapChain11-&gt;getWidth(), swapChain11-&gt;getHeight());
+    }
+    else
+    {
+        // Note: render target may be NULL for 0 sized surfaces
+        renderTarget = new RenderTarget11(this, swapChain11-&gt;getRenderTarget(),
+                                          swapChain11-&gt;getOffscreenTexture(),
+                                          swapChain11-&gt;getRenderTargetShaderResource(),
+                                          swapChain11-&gt;getWidth(), swapChain11-&gt;getHeight());
+    }
+    return renderTarget;
+}
+
+RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
+{
+    RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth);
+    return renderTarget;
+}
+
+ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type)
+{
+    ShaderExecutable11 *executable = NULL;
+
+    switch (type)
+    {
+      case rx::SHADER_VERTEX:
+        {
+            ID3D11VertexShader *vshader = NULL;
+            HRESULT result = mDevice-&gt;CreateVertexShader(function, length, NULL, &amp;vshader);
+            ASSERT(SUCCEEDED(result));
+
+            if (vshader)
+            {
+                executable = new ShaderExecutable11(function, length, vshader);
+            }
+        }
+        break;
+      case rx::SHADER_PIXEL:
+        {
+            ID3D11PixelShader *pshader = NULL;
+            HRESULT result = mDevice-&gt;CreatePixelShader(function, length, NULL, &amp;pshader);
+            ASSERT(SUCCEEDED(result));
+
+            if (pshader)
+            {
+                executable = new ShaderExecutable11(function, length, pshader);
+            }
+        }
+        break;
+      case rx::SHADER_GEOMETRY:
+        {
+            ID3D11GeometryShader *gshader = NULL;
+            HRESULT result = mDevice-&gt;CreateGeometryShader(function, length, NULL, &amp;gshader);
+            ASSERT(SUCCEEDED(result));
+
+            if (gshader)
+            {
+                executable = new ShaderExecutable11(function, length, gshader);
+            }
+        }
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+
+    return executable;
+}
+
+ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &amp;infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround)
+{
+    const char *profile = NULL;
+
+    switch (type)
+    {
+      case rx::SHADER_VERTEX:
+        profile = &quot;vs_4_0&quot;;
+        break;
+      case rx::SHADER_PIXEL:
+        profile = &quot;ps_4_0&quot;;
+        break;
+      case rx::SHADER_GEOMETRY:
+        profile = &quot;gs_4_0&quot;;
+        break;
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+
+    ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, D3DCOMPILE_OPTIMIZATION_LEVEL0, false);
+    if (!binary)
+        return NULL;
+
+    ShaderExecutable *executable = loadExecutable((DWORD *)binary-&gt;GetBufferPointer(), binary-&gt;GetBufferSize(), type);
+    binary-&gt;Release();
+
+    return executable;
+}
+
+VertexBuffer *Renderer11::createVertexBuffer()
+{
+    return new VertexBuffer11(this);
+}
+
+IndexBuffer *Renderer11::createIndexBuffer()
+{
+    return new IndexBuffer11(this);
+}
+
+BufferStorage *Renderer11::createBufferStorage()
+{
+    return new BufferStorage11(this);
+}
+
+QueryImpl *Renderer11::createQuery(GLenum type)
+{
+    return new Query11(this, type);
+}
+
+FenceImpl *Renderer11::createFence()
+{
+    return new Fence11(this);
+}
+
+bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource)
+{
+    ASSERT(colorbuffer != NULL);
+
+    RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer-&gt;getRenderTarget());
+    if (renderTarget)
+    {
+        *subresourceIndex = renderTarget-&gt;getSubresourceIndex();
+
+        ID3D11RenderTargetView *colorBufferRTV = renderTarget-&gt;getRenderTargetView();
+        if (colorBufferRTV)
+        {
+            ID3D11Resource *textureResource = NULL;
+            colorBufferRTV-&gt;GetResource(&amp;textureResource);
+
+            if (textureResource)
+            {
+                HRESULT result = textureResource-&gt;QueryInterface(IID_ID3D11Texture2D, (void**)resource);
+                textureResource-&gt;Release();
+
+                if (SUCCEEDED(result))
+                {
+                    return true;
+                }
+                else
+                {
+                    ERR(&quot;Failed to extract the ID3D11Texture2D from the render target resource, &quot;
+                        &quot;HRESULT: 0x%X.&quot;, result);
+                }
+            }
+        }
+    }
+
+    return false;
+}
+
+bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &amp;readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &amp;drawRect,
+                          bool blitRenderTarget, bool blitDepthStencil)
+{
+    if (blitRenderTarget)
+    {
+        gl::Renderbuffer *readBuffer = readTarget-&gt;getReadColorbuffer();
+
+        if (!readBuffer)
+        {
+            ERR(&quot;Failed to retrieve the read buffer from the read framebuffer.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        RenderTarget *readRenderTarget = readBuffer-&gt;getRenderTarget();
+
+        for (unsigned int colorAttachment = 0; colorAttachment &lt; gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
+        {
+            if (drawTarget-&gt;isEnabledColorAttachment(colorAttachment))
+            {
+                gl::Renderbuffer *drawBuffer = drawTarget-&gt;getColorbuffer(colorAttachment);
+
+                if (!drawBuffer)
+                {
+                    ERR(&quot;Failed to retrieve the draw buffer from the draw framebuffer.&quot;);
+                    return gl::error(GL_OUT_OF_MEMORY, false);
+                }
+
+                RenderTarget *drawRenderTarget = drawBuffer-&gt;getRenderTarget();
+
+                if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false))
+                {
+                    return false;
+                }
+            }
+        }
+    }
+
+    if (blitDepthStencil)
+    {
+        gl::Renderbuffer *readBuffer = readTarget-&gt;getDepthOrStencilbuffer();
+        gl::Renderbuffer *drawBuffer = drawTarget-&gt;getDepthOrStencilbuffer();
+
+        if (!readBuffer)
+        {
+            ERR(&quot;Failed to retrieve the read depth-stencil buffer from the read framebuffer.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        if (!drawBuffer)
+        {
+            ERR(&quot;Failed to retrieve the draw depth-stencil buffer from the draw framebuffer.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        RenderTarget *readRenderTarget = readBuffer-&gt;getDepthStencil();
+        RenderTarget *drawRenderTarget = drawBuffer-&gt;getDepthStencil();
+
+        if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true))
+        {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+                            GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
+{
+    ID3D11Texture2D *colorBufferTexture = NULL;
+    unsigned int subresourceIndex = 0;
+
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getReadColorbuffer();
+
+    if (colorbuffer &amp;&amp; getRenderTargetResource(colorbuffer, &amp;subresourceIndex, &amp;colorBufferTexture))
+    {
+        gl::Rectangle area;
+        area.x = x;
+        area.y = y;
+        area.width = width;
+        area.height = height;
+
+        readTextureData(colorBufferTexture, subresourceIndex, area, colorbuffer-&gt;getActualFormat(), format, type, outputPitch,
+                        packReverseRowOrder, packAlignment, pixels);
+
+        colorBufferTexture-&gt;Release();
+        colorBufferTexture = NULL;
+    }
+}
+
+Image *Renderer11::createImage()
+{
+    return new Image11();
+}
+
+void Renderer11::generateMipmap(Image *dest, Image *src)
+{
+    Image11 *dest11 = Image11::makeImage11(dest);
+    Image11 *src11 = Image11::makeImage11(src);
+    Image11::generateMipmap(dest11, src11);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain)
+{
+    SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain);
+    return new TextureStorage11_2D(this, swapChain11);
+}
+
+TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+{
+    return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height);
+}
+
+TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+{
+    return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size);
+}
+
+static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum sourceGLFormat, GLenum destFormat, GLenum destType)
+{
+    if (sourceFormat == DXGI_FORMAT_A8_UNORM &amp;&amp;
+        destFormat   == GL_ALPHA &amp;&amp;
+        destType     == GL_UNSIGNED_BYTE)
+    {
+        return 1;
+    }
+    else if (sourceFormat   == DXGI_FORMAT_R8G8B8A8_UNORM &amp;&amp;
+             sourceGLFormat == GL_RGBA8_OES &amp;&amp;
+             destFormat     == GL_RGBA &amp;&amp;
+             destType       == GL_UNSIGNED_BYTE)
+    {
+        return 4;
+    }
+    else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM &amp;&amp;
+             destFormat   == GL_BGRA_EXT &amp;&amp;
+             destType     == GL_UNSIGNED_BYTE)
+    {
+        return 4;
+    }
+    else if (sourceFormat   == DXGI_FORMAT_R16G16B16A16_FLOAT &amp;&amp;
+             sourceGLFormat == GL_RGBA16F_EXT &amp;&amp;
+             destFormat     == GL_RGBA &amp;&amp;
+             destType       == GL_HALF_FLOAT_OES)
+    {
+        return 8;
+    }
+    else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT &amp;&amp;
+             destFormat   == GL_RGB &amp;&amp;
+             destType     == GL_FLOAT)
+    {
+        return 12;
+    }
+    else if (sourceFormat   == DXGI_FORMAT_R32G32B32A32_FLOAT &amp;&amp;
+             sourceGLFormat == GL_RGBA32F_EXT &amp;&amp;
+             destFormat     == GL_RGBA &amp;&amp;
+             destType       == GL_FLOAT)
+    {
+        return 16;
+    }
+    else
+    {
+        return 0;
+    }
+}
+
+static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, GLenum glFormat, unsigned int x,
+                                  unsigned int y, int inputPitch, gl::Color *outColor)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+        {
+            unsigned int rgba = *reinterpret_cast&lt;const unsigned int*&gt;(data + 4 * x + y * inputPitch);
+            outColor-&gt;red =   (rgba &amp; 0x000000FF) * (1.0f / 0x000000FF);
+            outColor-&gt;green = (rgba &amp; 0x0000FF00) * (1.0f / 0x0000FF00);
+            outColor-&gt;blue =  (rgba &amp; 0x00FF0000) * (1.0f / 0x00FF0000);
+
+            if (gl::GetAlphaSize(glFormat) &gt; 0)
+            {
+                outColor-&gt;alpha = (rgba &amp; 0xFF000000) * (1.0f / 0xFF000000);
+            }
+            else
+            {
+                outColor-&gt;alpha = 1.0f;
+            }
+        }
+        break;
+
+      case DXGI_FORMAT_A8_UNORM:
+        {
+            outColor-&gt;red =   0.0f;
+            outColor-&gt;green = 0.0f;
+            outColor-&gt;blue =  0.0f;
+            outColor-&gt;alpha = *(data + x + y * inputPitch) / 255.0f;
+        }
+        break;
+
+      case DXGI_FORMAT_R32G32B32A32_FLOAT:
+        {
+            outColor-&gt;red =   *(reinterpret_cast&lt;const float*&gt;(data + 16 * x + y * inputPitch) + 0);
+            outColor-&gt;green = *(reinterpret_cast&lt;const float*&gt;(data + 16 * x + y * inputPitch) + 1);
+            outColor-&gt;blue =  *(reinterpret_cast&lt;const float*&gt;(data + 16 * x + y * inputPitch) + 2);
+
+            if (gl::GetAlphaSize(glFormat) &gt; 0)
+            {
+                outColor-&gt;alpha = *(reinterpret_cast&lt;const float*&gt;(data + 16 * x + y * inputPitch) + 3);
+            }
+            else
+            {
+                outColor-&gt;alpha = 1.0f;
+            }
+        }
+        break;
+
+      case DXGI_FORMAT_R32G32B32_FLOAT:
+        {
+            outColor-&gt;red =   *(reinterpret_cast&lt;const float*&gt;(data + 12 * x + y * inputPitch) + 0);
+            outColor-&gt;green = *(reinterpret_cast&lt;const float*&gt;(data + 12 * x + y * inputPitch) + 1);
+            outColor-&gt;blue =  *(reinterpret_cast&lt;const float*&gt;(data + 12 * x + y * inputPitch) + 2);
+            outColor-&gt;alpha = 1.0f;
+        }
+        break;
+
+      case DXGI_FORMAT_R16G16B16A16_FLOAT:
+        {
+            outColor-&gt;red =   gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 8 * x + y * inputPitch) + 0));
+            outColor-&gt;green = gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 8 * x + y * inputPitch) + 1));
+            outColor-&gt;blue =  gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 8 * x + y * inputPitch) + 2));
+
+            if (gl::GetAlphaSize(glFormat) &gt; 0)
+            {
+                outColor-&gt;alpha = gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 8 * x + y * inputPitch) + 3));
+            }
+            else
+            {
+                outColor-&gt;alpha = 1.0f;
+            }
+        }
+        break;
+
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+        {
+            unsigned int bgra = *reinterpret_cast&lt;const unsigned int*&gt;(data + 4 * x + y * inputPitch);
+            outColor-&gt;red =   (bgra &amp; 0x00FF0000) * (1.0f / 0x00FF0000);
+            outColor-&gt;blue =  (bgra &amp; 0x000000FF) * (1.0f / 0x000000FF);
+            outColor-&gt;green = (bgra &amp; 0x0000FF00) * (1.0f / 0x0000FF00);
+            outColor-&gt;alpha = (bgra &amp; 0xFF000000) * (1.0f / 0xFF000000);
+        }
+        break;
+
+      case DXGI_FORMAT_R8_UNORM:
+        {
+            outColor-&gt;red =   *(data + x + y * inputPitch) / 255.0f;
+            outColor-&gt;green = 0.0f;
+            outColor-&gt;blue =  0.0f;
+            outColor-&gt;alpha = 1.0f;
+        }
+        break;
+
+      case DXGI_FORMAT_R8G8_UNORM:
+        {
+            unsigned short rg = *reinterpret_cast&lt;const unsigned short*&gt;(data + 2 * x + y * inputPitch);
+
+            outColor-&gt;red =   (rg &amp; 0xFF00) * (1.0f / 0xFF00);
+            outColor-&gt;green = (rg &amp; 0x00FF) * (1.0f / 0x00FF);
+            outColor-&gt;blue =  0.0f;
+            outColor-&gt;alpha = 1.0f;
+        }
+        break;
+
+      case DXGI_FORMAT_R16_FLOAT:
+        {
+            outColor-&gt;red =   gl::float16ToFloat32(*reinterpret_cast&lt;const unsigned short*&gt;(data + 2 * x + y * inputPitch));
+            outColor-&gt;green = 0.0f;
+            outColor-&gt;blue =  0.0f;
+            outColor-&gt;alpha = 1.0f;
+        }
+        break;
+
+      case DXGI_FORMAT_R16G16_FLOAT:
+        {
+            outColor-&gt;red =   gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 4 * x + y * inputPitch) + 0));
+            outColor-&gt;green = gl::float16ToFloat32(*(reinterpret_cast&lt;const unsigned short*&gt;(data + 4 * x + y * inputPitch) + 1));
+            outColor-&gt;blue =  0.0f;
+            outColor-&gt;alpha = 1.0f;
+        }
+        break;
+
+      default:
+        ERR(&quot;ReadPixelColor not implemented for DXGI format %u.&quot;, format);
+        UNIMPLEMENTED();
+        break;
+    }
+}
+
+static inline void writePixelColor(const gl::Color &amp;color, GLenum format, GLenum type, unsigned int x,
+                                   unsigned int y, int outputPitch, void *outData)
+{
+    unsigned char* byteData = reinterpret_cast&lt;unsigned char*&gt;(outData);
+    unsigned short* shortData = reinterpret_cast&lt;unsigned short*&gt;(outData);
+
+    switch (format)
+    {
+      case GL_RGBA:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:
+            byteData[4 * x + y * outputPitch + 0] = static_cast&lt;unsigned char&gt;(255 * color.red   + 0.5f);
+            byteData[4 * x + y * outputPitch + 1] = static_cast&lt;unsigned char&gt;(255 * color.green + 0.5f);
+            byteData[4 * x + y * outputPitch + 2] = static_cast&lt;unsigned char&gt;(255 * color.blue  + 0.5f);
+            byteData[4 * x + y * outputPitch + 3] = static_cast&lt;unsigned char&gt;(255 * color.alpha + 0.5f);
+            break;
+
+          default:
+            ERR(&quot;WritePixelColor not implemented for format GL_RGBA and type 0x%X.&quot;, type);
+            UNIMPLEMENTED();
+            break;
+        }
+        break;
+
+      case GL_BGRA_EXT:
+        switch (type)
+        {
+          case GL_UNSIGNED_BYTE:
+            byteData[4 * x + y * outputPitch + 0] = static_cast&lt;unsigned char&gt;(255 * color.blue  + 0.5f);
+            byteData[4 * x + y * outputPitch + 1] = static_cast&lt;unsigned char&gt;(255 * color.green + 0.5f);
+            byteData[4 * x + y * outputPitch + 2] = static_cast&lt;unsigned char&gt;(255 * color.red   + 0.5f);
+            byteData[4 * x + y * outputPitch + 3] = static_cast&lt;unsigned char&gt;(255 * color.alpha + 0.5f);
+            break;
+
+          case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+            // According to the desktop GL spec in the &quot;Transfer of Pixel Rectangles&quot; section
+            // this type is packed as follows:
+            //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+            //  --------------------------------------------------------------------------------
+            // |       4th         |        3rd         |        2nd        |   1st component   |
+            //  --------------------------------------------------------------------------------
+            // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+            shortData[x + y * outputPitch / sizeof(unsigned short)] =
+                (static_cast&lt;unsigned short&gt;(15 * color.alpha + 0.5f) &lt;&lt; 12) |
+                (static_cast&lt;unsigned short&gt;(15 * color.red   + 0.5f) &lt;&lt;  8) |
+                (static_cast&lt;unsigned short&gt;(15 * color.green + 0.5f) &lt;&lt;  4) |
+                (static_cast&lt;unsigned short&gt;(15 * color.blue  + 0.5f) &lt;&lt;  0);
+            break;
+
+          case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+            // According to the desktop GL spec in the &quot;Transfer of Pixel Rectangles&quot; section
+            // this type is packed as follows:
+            //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+            //  --------------------------------------------------------------------------------
+            // | 4th |          3rd           |           2nd          |      1st component     |
+            //  --------------------------------------------------------------------------------
+            // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+            shortData[x + y * outputPitch / sizeof(unsigned short)] =
+                (static_cast&lt;unsigned short&gt;(     color.alpha + 0.5f) &lt;&lt; 15) |
+                (static_cast&lt;unsigned short&gt;(31 * color.red   + 0.5f) &lt;&lt; 10) |
+                (static_cast&lt;unsigned short&gt;(31 * color.green + 0.5f) &lt;&lt;  5) |
+                (static_cast&lt;unsigned short&gt;(31 * color.blue  + 0.5f) &lt;&lt;  0);
+            break;
+
+          default:
+            ERR(&quot;WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.&quot;, type);
+            UNIMPLEMENTED();
+            break;
+        }
+        break;
+
+      case GL_RGB:
+        switch (type)
+        {
+          case GL_UNSIGNED_SHORT_5_6_5:
+            shortData[x + y * outputPitch / sizeof(unsigned short)] =
+                (static_cast&lt;unsigned short&gt;(31 * color.blue  + 0.5f) &lt;&lt;  0) |
+                (static_cast&lt;unsigned short&gt;(63 * color.green + 0.5f) &lt;&lt;  5) |
+                (static_cast&lt;unsigned short&gt;(31 * color.red   + 0.5f) &lt;&lt; 11);
+            break;
+
+          case GL_UNSIGNED_BYTE:
+            byteData[3 * x + y * outputPitch + 0] = static_cast&lt;unsigned char&gt;(255 * color.red +   0.5f);
+            byteData[3 * x + y * outputPitch + 1] = static_cast&lt;unsigned char&gt;(255 * color.green + 0.5f);
+            byteData[3 * x + y * outputPitch + 2] = static_cast&lt;unsigned char&gt;(255 * color.blue +  0.5f);
+            break;
+
+          default:
+            ERR(&quot;WritePixelColor not implemented for format GL_RGB and type 0x%X.&quot;, type);
+            UNIMPLEMENTED();
+            break;
+        }
+        break;
+
+      default:
+        ERR(&quot;WritePixelColor not implemented for format 0x%X.&quot;, format);
+        UNIMPLEMENTED();
+        break;
+    }
+}
+
+void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &amp;area,
+                                 GLenum sourceFormat, GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
+                                 GLint packAlignment, void *pixels)
+{
+    D3D11_TEXTURE2D_DESC textureDesc;
+    texture-&gt;GetDesc(&amp;textureDesc);
+
+    D3D11_TEXTURE2D_DESC stagingDesc;
+    stagingDesc.Width = area.width;
+    stagingDesc.Height = area.height;
+    stagingDesc.MipLevels = 1;
+    stagingDesc.ArraySize = 1;
+    stagingDesc.Format = textureDesc.Format;
+    stagingDesc.SampleDesc.Count = 1;
+    stagingDesc.SampleDesc.Quality = 0;
+    stagingDesc.Usage = D3D11_USAGE_STAGING;
+    stagingDesc.BindFlags = 0;
+    stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+    stagingDesc.MiscFlags = 0;
+
+    ID3D11Texture2D* stagingTex = NULL;
+    HRESULT result = mDevice-&gt;CreateTexture2D(&amp;stagingDesc, NULL, &amp;stagingTex);
+    if (FAILED(result))
+    {
+        ERR(&quot;Failed to create staging texture for readPixels, HRESULT: 0x%X.&quot;, result);
+        return;
+    }
+
+    ID3D11Texture2D* srcTex = NULL;
+    if (textureDesc.SampleDesc.Count &gt; 1)
+    {
+        D3D11_TEXTURE2D_DESC resolveDesc;
+        resolveDesc.Width = textureDesc.Width;
+        resolveDesc.Height = textureDesc.Height;
+        resolveDesc.MipLevels = 1;
+        resolveDesc.ArraySize = 1;
+        resolveDesc.Format = textureDesc.Format;
+        resolveDesc.SampleDesc.Count = 1;
+        resolveDesc.SampleDesc.Quality = 0;
+        resolveDesc.Usage = D3D11_USAGE_DEFAULT;
+        resolveDesc.BindFlags = 0;
+        resolveDesc.CPUAccessFlags = 0;
+        resolveDesc.MiscFlags = 0;
+
+        result = mDevice-&gt;CreateTexture2D(&amp;resolveDesc, NULL, &amp;srcTex);
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to create resolve texture for readPixels, HRESULT: 0x%X.&quot;, result);
+            stagingTex-&gt;Release();
+            return;
+        }
+
+        mDeviceContext-&gt;ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format);
+        subResource = 0;
+    }
+    else
+    {
+        srcTex = texture;
+        srcTex-&gt;AddRef();
+    }
+
+    D3D11_BOX srcBox;
+    srcBox.left = area.x;
+    srcBox.right = area.x + area.width;
+    srcBox.top = area.y;
+    srcBox.bottom = area.y + area.height;
+    srcBox.front = 0;
+    srcBox.back = 1;
+
+    mDeviceContext-&gt;CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &amp;srcBox);
+
+    srcTex-&gt;Release();
+    srcTex = NULL;
+
+    D3D11_MAPPED_SUBRESOURCE mapping;
+    mDeviceContext-&gt;Map(stagingTex, 0, D3D11_MAP_READ, 0, &amp;mapping);
+
+    unsigned char *source;
+    int inputPitch;
+    if (packReverseRowOrder)
+    {
+        source = static_cast&lt;unsigned char*&gt;(mapping.pData) + mapping.RowPitch * (area.height - 1);
+        inputPitch = -static_cast&lt;int&gt;(mapping.RowPitch);
+    }
+    else
+    {
+        source = static_cast&lt;unsigned char*&gt;(mapping.pData);
+        inputPitch = static_cast&lt;int&gt;(mapping.RowPitch);
+    }
+
+    unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, sourceFormat, format, type);
+    if (fastPixelSize != 0)
+    {
+        unsigned char *dest = static_cast&lt;unsigned char*&gt;(pixels);
+        for (int j = 0; j &lt; area.height; j++)
+        {
+            memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize);
+        }
+    }
+    else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM &amp;&amp;
+             format == GL_RGBA &amp;&amp;
+             type == GL_UNSIGNED_BYTE)
+    {
+        // Fast path for swapping red with blue
+        unsigned char *dest = static_cast&lt;unsigned char*&gt;(pixels);
+
+        for (int j = 0; j &lt; area.height; j++)
+        {
+            for (int i = 0; i &lt; area.width; i++)
+            {
+                unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+                *(unsigned int*)(dest + 4 * i + j * outputPitch) =
+                    (argb &amp; 0xFF00FF00) |       // Keep alpha and green
+                    (argb &amp; 0x00FF0000) &gt;&gt; 16 | // Move red to blue
+                    (argb &amp; 0x000000FF) &lt;&lt; 16;  // Move blue to red
+            }
+        }
+    }
+    else
+    {
+        gl::Color pixelColor;
+        for (int j = 0; j &lt; area.height; j++)
+        {
+            for (int i = 0; i &lt; area.width; i++)
+            {
+                readPixelColor(source, textureDesc.Format, sourceFormat, i, j, inputPitch, &amp;pixelColor);
+                writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels);
+            }
+        }
+    }
+
+    mDeviceContext-&gt;Unmap(stagingTex, 0);
+
+    stagingTex-&gt;Release();
+    stagingTex = NULL;
+}
+
+bool Renderer11::blitRenderbufferRect(const gl::Rectangle &amp;readRect, const gl::Rectangle &amp;drawRect, RenderTarget *readRenderTarget, 
+                                      RenderTarget *drawRenderTarget, bool wholeBufferCopy)
+{
+    ASSERT(readRect.width == drawRect.width &amp;&amp; readRect.height == drawRect.height);
+
+    RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget);
+    if (!drawRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the draw render target from the draw framebuffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11Texture2D *drawTexture = drawRenderTarget11-&gt;getTexture();
+    unsigned int drawSubresource = drawRenderTarget11-&gt;getSubresourceIndex();
+
+    RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget);
+    if (!readRenderTarget)
+    {
+        ERR(&quot;Failed to retrieve the read render target from the read framebuffer.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    ID3D11Texture2D *readTexture = NULL;
+    unsigned int readSubresource = 0;
+    if (readRenderTarget-&gt;getSamples() &gt; 0)
+    {
+        readTexture = resolveMultisampledTexture(readRenderTarget11-&gt;getTexture(), readRenderTarget11-&gt;getSubresourceIndex());
+        readSubresource = 0;
+    }
+    else
+    {
+        readTexture = readRenderTarget11-&gt;getTexture();
+        readTexture-&gt;AddRef();
+        readSubresource = readRenderTarget11-&gt;getSubresourceIndex();
+    }
+
+    if (!readTexture)
+    {
+        ERR(&quot;Failed to retrieve the read render target view from the read render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    D3D11_BOX readBox;
+    readBox.left = readRect.x;
+    readBox.right = readRect.x + readRect.width;
+    readBox.top = readRect.y;
+    readBox.bottom = readRect.y + readRect.height;
+    readBox.front = 0;
+    readBox.back = 1;
+
+    // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox
+    // We also require complete framebuffer copies for depth-stencil blit.
+    D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &amp;readBox;
+
+    mDeviceContext-&gt;CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0,
+                                          readTexture, readSubresource, pSrcBox);
+
+    SafeRelease(readTexture);
+
+    return true;
+}
+
+ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource)
+{
+    D3D11_TEXTURE2D_DESC textureDesc;
+    source-&gt;GetDesc(&amp;textureDesc);
+
+    if (textureDesc.SampleDesc.Count &gt; 1)
+    {
+        D3D11_TEXTURE2D_DESC resolveDesc;
+        resolveDesc.Width = textureDesc.Width;
+        resolveDesc.Height = textureDesc.Height;
+        resolveDesc.MipLevels = 1;
+        resolveDesc.ArraySize = 1;
+        resolveDesc.Format = textureDesc.Format;
+        resolveDesc.SampleDesc.Count = 1;
+        resolveDesc.SampleDesc.Quality = 0;
+        resolveDesc.Usage = textureDesc.Usage;
+        resolveDesc.BindFlags = textureDesc.BindFlags;
+        resolveDesc.CPUAccessFlags = 0;
+        resolveDesc.MiscFlags = 0;
+
+        ID3D11Texture2D *resolveTexture = NULL;
+        HRESULT result = mDevice-&gt;CreateTexture2D(&amp;resolveDesc, NULL, &amp;resolveTexture);
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to create a multisample resolve texture, HRESULT: 0x%X.&quot;, result);
+            return NULL;
+        }
+
+        mDeviceContext-&gt;ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format);
+        return resolveTexture;
+    }
+    else
+    {
+        source-&gt;AddRef();
+        return source;
+    }
+}
+
+bool Renderer11::getLUID(LUID *adapterLuid) const
+{
+    adapterLuid-&gt;HighPart = 0;
+    adapterLuid-&gt;LowPart = 0;
+
+    if (!mDxgiAdapter)
+    {
+        return false;
+    }
+
+    DXGI_ADAPTER_DESC adapterDesc;
+    if (FAILED(mDxgiAdapter-&gt;GetDesc(&amp;adapterDesc)))
+    {
+        return false;
+    }
+
+    *adapterLuid = adapterDesc.AdapterLuid;
+    return true;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11Renderer11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,358 @@
</span><ins>+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer11.h: Defines a back-end specific class for the D3D11 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER11_H_
+#define LIBGLESV2_RENDERER_RENDERER11_H_
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;libGLESv2/angletypes.h&quot;
+#include &quot;libGLESv2/mathutil.h&quot;
+
+#include &quot;libGLESv2/renderer/Renderer.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/RenderStateCache.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/InputLayoutCache.h&quot;
+#include &quot;libGLESv2/renderer/RenderTarget.h&quot;
+
+namespace gl
+{
+class Renderbuffer;
+}
+
+namespace rx
+{
+
+class VertexDataManager;
+class IndexDataManager;
+class StreamingIndexBufferInterface;
+
+enum
+{
+    MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024,
+    MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024
+};
+
+class Renderer11 : public Renderer
+{
+  public:
+    Renderer11(egl::Display *display, HDC hDc);
+    virtual ~Renderer11();
+
+    static Renderer11 *makeRenderer11(Renderer *renderer);
+
+    virtual EGLint initialize();
+    virtual bool resetDevice();
+
+    virtual int generateConfigs(ConfigDesc **configDescList);
+    virtual void deleteConfigs(ConfigDesc *configDescList);
+
+    virtual void sync(bool block);
+
+    virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+    virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &amp;sampler);
+    virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+
+    virtual void setRasterizerState(const gl::RasterizerState &amp;rasterState);
+    virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState, const gl::Color &amp;blendColor,
+                               unsigned int sampleMask);
+    virtual void setDepthStencilState(const gl::DepthStencilState &amp;depthStencilState, int stencilRef,
+                                      int stencilBackRef, bool frontFaceCCW);
+
+    virtual void setScissorRectangle(const gl::Rectangle &amp;scissor, bool enabled);
+    virtual bool setViewport(const gl::Rectangle &amp;viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+                             bool ignoreViewport);
+
+    virtual bool applyPrimitiveType(GLenum mode, GLsizei count);
+    virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
+    virtual void applyShaders(gl::ProgramBinary *programBinary);
+    virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
+    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+    virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+
+    virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+    virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &amp;indexInfo, GLsizei instances);
+
+    virtual void clear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer);
+
+    virtual void markAllStateDirty();
+
+    // lost device
+    void notifyDeviceLost();
+    virtual bool isDeviceLost();
+    virtual bool testDeviceLost(bool notify);
+    virtual bool testDeviceResettable();
+
+    // Renderer capabilities
+    virtual DWORD getAdapterVendor() const;
+    virtual std::string getRendererDescription() const;
+    virtual GUID getAdapterIdentifier() const;
+
+    virtual bool getBGRATextureSupport() const;
+    virtual bool getDXT1TextureSupport();
+    virtual bool getDXT3TextureSupport();
+    virtual bool getDXT5TextureSupport();
+    virtual bool getEventQuerySupport();
+    virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
+    virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
+    virtual bool getLuminanceTextureSupport();
+    virtual bool getLuminanceAlphaTextureSupport();
+    virtual unsigned int getMaxVertexTextureImageUnits() const;
+    virtual unsigned int getMaxCombinedTextureImageUnits() const;
+    virtual unsigned int getReservedVertexUniformVectors() const;
+    virtual unsigned int getReservedFragmentUniformVectors() const;
+    virtual unsigned int getMaxVertexUniformVectors() const;
+    virtual unsigned int getMaxFragmentUniformVectors() const;
+    virtual unsigned int getMaxVaryingVectors() const;
+    virtual bool getNonPower2TextureSupport() const;
+    virtual bool getDepthTextureSupport() const;
+    virtual bool getOcclusionQuerySupport() const;
+    virtual bool getInstancingSupport() const;
+    virtual bool getTextureFilterAnisotropySupport() const;
+    virtual float getTextureMaxAnisotropy() const;
+    virtual bool getShareHandleSupport() const;
+    virtual bool getDerivativeInstructionSupport() const;
+    virtual bool getPostSubBufferSupport() const;
+
+    virtual int getMajorShaderModel() const;
+    virtual float getMaxPointSize() const;
+    virtual int getMaxViewportDimension() const;
+    virtual int getMaxTextureWidth() const;
+    virtual int getMaxTextureHeight() const;
+    virtual bool get32BitIndexSupport() const;
+    virtual int getMinSwapInterval() const;
+    virtual int getMaxSwapInterval() const;
+
+    virtual GLsizei getMaxSupportedSamples() const;
+    int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const;
+
+    virtual unsigned int getMaxRenderTargets() const;
+
+    // Pixel operations
+    virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
+    virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
+
+    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+
+    bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &amp;sourceArea, unsigned int sourceWidth, unsigned int sourceHeight,
+                     ID3D11RenderTargetView *dest, const gl::Rectangle &amp;destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat);
+
+    virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &amp;readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &amp;drawRect,
+                          bool blitRenderTarget, bool blitDepthStencil);
+    virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+                            GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
+
+    // RenderTarget creation
+    virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
+    virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
+
+    // Shader operations
+    virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
+    virtual ShaderExecutable *compileToExecutable(gl::InfoLog &amp;infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround);
+
+    // Image operations
+    virtual Image *createImage();
+    virtual void generateMipmap(Image *dest, Image *source);
+    virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
+    virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+    virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+
+    // Buffer creation
+    virtual VertexBuffer *createVertexBuffer();
+    virtual IndexBuffer *createIndexBuffer();
+    virtual BufferStorage *createBufferStorage();
+
+    // Query and Fence creation
+    virtual QueryImpl *createQuery(GLenum type);
+    virtual FenceImpl *createFence();
+
+    // D3D11-renderer specific methods
+    ID3D11Device *getDevice() { return mDevice; }
+    ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; };
+    IDXGIFactory *getDxgiFactory() { return mDxgiFactory; };
+
+    bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource);
+    void unapplyRenderTargets();
+    void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView);
+
+    virtual bool getLUID(LUID *adapterLuid) const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Renderer11);
+
+    void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+    void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances);
+
+    void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &amp;area,
+                         GLenum sourceFormat, GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder,
+                         GLint packAlignment, void *pixels);
+
+    void maskedClear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer);
+    rx::Range getViewportBounds() const;
+
+    bool blitRenderbufferRect(const gl::Rectangle &amp;readRect, const gl::Rectangle &amp;drawRect, RenderTarget *readRenderTarget, 
+                              RenderTarget *drawRenderTarget, bool wholeBufferCopy);
+    ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource);
+
+    HMODULE mD3d11Module;
+    HMODULE mDxgiModule;
+    HDC mDc;
+
+    bool mDeviceLost;
+
+    void initializeDevice();
+    void releaseDeviceResources();
+    int getMinorShaderModel() const;
+    void release();
+
+    RenderStateCache mStateCache;
+
+    // Support flags
+    bool mFloat16TextureSupport;
+    bool mFloat16FilterSupport;
+    bool mFloat16RenderSupport;
+
+    bool mFloat32TextureSupport;
+    bool mFloat32FilterSupport;
+    bool mFloat32RenderSupport;
+
+    bool mDXT1TextureSupport;
+    bool mDXT3TextureSupport;
+    bool mDXT5TextureSupport;
+
+    bool mDepthTextureSupport;
+
+    // Multisample format support
+    struct MultisampleSupportInfo
+    {
+        unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT];
+    };
+
+    typedef std::unordered_map&lt;DXGI_FORMAT, MultisampleSupportInfo, std::hash&lt;int&gt; &gt; MultisampleSupportMap;
+    MultisampleSupportMap mMultisampleSupportMap;
+
+    unsigned int mMaxSupportedSamples;
+
+    // current render target states
+    unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS];
+    unsigned int mAppliedDepthbufferSerial;
+    unsigned int mAppliedStencilbufferSerial;
+    bool mDepthStencilInitialized;
+    bool mRenderTargetDescInitialized;
+    rx::RenderTarget::Desc mRenderTargetDesc;
+    unsigned int mCurDepthSize;
+    unsigned int mCurStencilSize;
+
+    // Currently applied sampler states
+    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+    bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+    // Currently applied textures
+    unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+    // Currently applied blend state
+    bool mForceSetBlendState;
+    gl::BlendState mCurBlendState;
+    gl::Color mCurBlendColor;
+    unsigned int mCurSampleMask;
+
+    // Currently applied rasterizer state
+    bool mForceSetRasterState;
+    gl::RasterizerState mCurRasterState;
+
+    // Currently applied depth stencil state
+    bool mForceSetDepthStencilState;
+    gl::DepthStencilState mCurDepthStencilState;
+    int mCurStencilRef;
+    int mCurStencilBackRef;
+
+    // Currently applied scissor rectangle
+    bool mForceSetScissor;
+    bool mScissorEnabled;
+    gl::Rectangle mCurScissor;
+
+    // Currently applied viewport
+    bool mForceSetViewport;
+    gl::Rectangle mCurViewport;
+    float mCurNear;
+    float mCurFar;
+
+    // Currently applied primitive topology
+    D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology;
+
+    unsigned int mAppliedIBSerial;
+    unsigned int mAppliedStorageIBSerial;
+    unsigned int mAppliedIBOffset;
+
+    unsigned int mAppliedProgramBinarySerial;
+    bool mIsGeometryShaderActive;
+
+    dx_VertexConstants mVertexConstants;
+    dx_VertexConstants mAppliedVertexConstants;
+    ID3D11Buffer *mDriverConstantBufferVS;
+    ID3D11Buffer *mCurrentVertexConstantBuffer;
+
+    dx_PixelConstants mPixelConstants;
+    dx_PixelConstants mAppliedPixelConstants;
+    ID3D11Buffer *mDriverConstantBufferPS;
+    ID3D11Buffer *mCurrentPixelConstantBuffer;
+
+    ID3D11Buffer *mCurrentGeometryConstantBuffer;
+
+    // Vertex, index and input layouts
+    VertexDataManager *mVertexDataManager;
+    IndexDataManager *mIndexDataManager;
+    InputLayoutCache mInputLayoutCache;
+
+    StreamingIndexBufferInterface *mLineLoopIB;
+    StreamingIndexBufferInterface *mTriangleFanIB;
+
+    // Texture copy resources
+    bool mCopyResourcesInitialized;
+    ID3D11Buffer *mCopyVB;
+    ID3D11SamplerState *mCopySampler;
+    ID3D11InputLayout *mCopyIL;
+    ID3D11VertexShader *mCopyVS;
+    ID3D11PixelShader *mCopyRGBAPS;
+    ID3D11PixelShader *mCopyRGBPS;
+    ID3D11PixelShader *mCopyLumPS;
+    ID3D11PixelShader *mCopyLumAlphaPS;
+
+    // Masked clear resources
+    bool mClearResourcesInitialized;
+    ID3D11Buffer *mClearVB;
+    ID3D11InputLayout *mClearIL;
+    ID3D11VertexShader *mClearVS;
+    ID3D11PixelShader *mClearSinglePS;
+    ID3D11PixelShader *mClearMultiplePS;
+    ID3D11RasterizerState *mClearScissorRS;
+    ID3D11RasterizerState *mClearNoScissorRS;
+
+    // Sync query
+    ID3D11Query *mSyncQuery;
+
+    ID3D11Device *mDevice;
+    D3D_FEATURE_LEVEL mFeatureLevel;
+    ID3D11DeviceContext *mDeviceContext;
+    IDXGIAdapter *mDxgiAdapter;
+    DXGI_ADAPTER_DESC mAdapterDescription;
+    char mDescription[128];
+    IDXGIFactory *mDxgiFactory;
+
+    // Cached device caps
+    bool mBGRATextureSupport;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_RENDERER11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/Renderer11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11ShaderExecutable11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,109 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader
+// executable implementation details.
+
+#include &quot;libGLESv2/renderer/d3d11/ShaderExecutable11.h&quot;
+
+#include &quot;common/debug.h&quot;
+
+namespace rx
+{
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable)
+    : ShaderExecutable(function, length)
+{
+    mPixelExecutable = executable;
+    mVertexExecutable = NULL;
+    mGeometryExecutable = NULL;
+
+    mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable)
+    : ShaderExecutable(function, length)
+{
+    mVertexExecutable = executable;
+    mPixelExecutable = NULL;
+    mGeometryExecutable = NULL;
+
+    mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable)
+    : ShaderExecutable(function, length)
+{
+    mGeometryExecutable = executable;
+    mVertexExecutable = NULL;
+    mPixelExecutable = NULL;
+
+    mConstantBuffer = NULL;
+}
+
+ShaderExecutable11::~ShaderExecutable11()
+{
+    if (mVertexExecutable)
+    {
+        mVertexExecutable-&gt;Release();
+    }
+    if (mPixelExecutable)
+    {
+        mPixelExecutable-&gt;Release();
+    }
+    if (mGeometryExecutable)
+    {
+        mGeometryExecutable-&gt;Release();
+    }
+    
+    if (mConstantBuffer)
+    {
+        mConstantBuffer-&gt;Release();
+    }
+}
+
+ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable));
+    return static_cast&lt;ShaderExecutable11*&gt;(executable);
+}
+
+ID3D11VertexShader *ShaderExecutable11::getVertexShader() const
+{
+    return mVertexExecutable;
+}
+
+ID3D11PixelShader *ShaderExecutable11::getPixelShader() const
+{
+    return mPixelExecutable;
+}
+
+ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const
+{
+    return mGeometryExecutable;
+}
+
+ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount)
+{
+    if (!mConstantBuffer &amp;&amp; registerCount &gt; 0)
+    {
+        D3D11_BUFFER_DESC constantBufferDescription = {0};
+        constantBufferDescription.ByteWidth = registerCount * sizeof(float[4]);
+        constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC;
+        constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
+        constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        constantBufferDescription.MiscFlags = 0;
+        constantBufferDescription.StructureByteStride = 0;
+
+        HRESULT result = device-&gt;CreateBuffer(&amp;constantBufferDescription, NULL, &amp;mConstantBuffer);
+        ASSERT(SUCCEEDED(result));
+    }
+
+    return mConstantBuffer;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11ShaderExecutable11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+#define LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
+
+#include &quot;libGLESv2/renderer/ShaderExecutable.h&quot;
+
+namespace rx
+{
+
+class ShaderExecutable11 : public ShaderExecutable
+{
+  public:
+    ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable);
+    ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable);
+    ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable);
+
+    virtual ~ShaderExecutable11();
+
+    static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutable *executable);
+
+    ID3D11PixelShader *getPixelShader() const;
+    ID3D11VertexShader *getVertexShader() const;
+    ID3D11GeometryShader *getGeometryShader() const;
+
+    ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11);
+
+    ID3D11PixelShader *mPixelExecutable;
+    ID3D11VertexShader *mVertexExecutable;
+    ID3D11GeometryShader *mGeometryExecutable;
+
+    ID3D11Buffer *mConstantBuffer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11SwapChain11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,657 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain.
+
+#include &quot;libGLESv2/renderer/d3d11/SwapChain11.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h&quot;
+
+namespace rx
+{
+
+SwapChain11::SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+                         GLenum backBufferFormat, GLenum depthBufferFormat)
+    : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+{
+    mSwapChain = NULL;
+    mBackBufferTexture = NULL;
+    mBackBufferRTView = NULL;
+    mOffscreenTexture = NULL;
+    mOffscreenRTView = NULL;
+    mOffscreenSRView = NULL;
+    mDepthStencilTexture = NULL;
+    mDepthStencilDSView = NULL;
+    mQuadVB = NULL;
+    mPassThroughSampler = NULL;
+    mPassThroughIL = NULL;
+    mPassThroughVS = NULL;
+    mPassThroughPS = NULL;
+    mWidth = -1;
+    mHeight = -1;
+    mSwapInterval = 0;
+    mAppCreatedShareHandle = mShareHandle != NULL;
+    mPassThroughResourcesInit = false;
+}
+
+SwapChain11::~SwapChain11()
+{
+    release();
+}
+
+void SwapChain11::release()
+{
+    SafeRelease(mSwapChain);
+    SafeRelease(mBackBufferTexture);
+    SafeRelease(mBackBufferRTView);
+    SafeRelease(mOffscreenTexture);
+    SafeRelease(mOffscreenRTView);
+    SafeRelease(mOffscreenSRView);
+    SafeRelease(mDepthStencilTexture);
+    SafeRelease(mDepthStencilDSView);
+    SafeRelease(mQuadVB);
+    SafeRelease(mPassThroughSampler);
+    SafeRelease(mPassThroughIL);
+    SafeRelease(mPassThroughVS);
+    SafeRelease(mPassThroughPS);
+
+    if (!mAppCreatedShareHandle)
+    {
+        mShareHandle = NULL;
+    }
+}
+
+void SwapChain11::releaseOffscreenTexture()
+{
+    SafeRelease(mOffscreenTexture);
+    SafeRelease(mOffscreenRTView);
+    SafeRelease(mOffscreenSRView);
+    SafeRelease(mDepthStencilTexture);
+    SafeRelease(mDepthStencilDSView);
+}
+
+EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight)
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+
+    ASSERT(device != NULL);
+
+    // D3D11 does not allow zero size textures
+    ASSERT(backbufferWidth &gt;= 1);
+    ASSERT(backbufferHeight &gt;= 1);
+
+    // Preserve the render target content
+    ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture;
+    if (previousOffscreenTexture)
+    {
+        previousOffscreenTexture-&gt;AddRef();
+    }
+    const int previousWidth = mWidth;
+    const int previousHeight = mHeight;
+
+    releaseOffscreenTexture();
+
+    // If the app passed in a share handle, open the resource
+    // See EGL_ANGLE_d3d_share_handle_client_buffer
+    if (mAppCreatedShareHandle)
+    {
+        ID3D11Resource *tempResource11;
+        HRESULT result = device-&gt;OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&amp;tempResource11);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to open the swap chain pbuffer share handle: %08lX&quot;, result);
+            release();
+            return EGL_BAD_PARAMETER;
+        }
+
+        result = tempResource11-&gt;QueryInterface(__uuidof(ID3D11Texture2D), (void**)&amp;mOffscreenTexture);
+        tempResource11-&gt;Release();
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to query texture2d interface in pbuffer share handle: %08lX&quot;, result);
+            release();
+            return EGL_BAD_PARAMETER;
+        }
+
+        // Validate offscreen texture parameters
+        D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+        mOffscreenTexture-&gt;GetDesc(&amp;offscreenTextureDesc);
+
+        if (offscreenTextureDesc.Width != (UINT)backbufferWidth
+            || offscreenTextureDesc.Height != (UINT)backbufferHeight
+            || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat)
+            || offscreenTextureDesc.MipLevels != 1
+            || offscreenTextureDesc.ArraySize != 1)
+        {
+            ERR(&quot;Invalid texture parameters in the shared offscreen texture pbuffer&quot;);
+            release();
+            return EGL_BAD_PARAMETER;
+        }
+    }
+    else
+    {
+        const bool useSharedResource = !mWindow &amp;&amp; mRenderer-&gt;getShareHandleSupport();
+
+        D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0};
+        offscreenTextureDesc.Width = backbufferWidth;
+        offscreenTextureDesc.Height = backbufferHeight;
+        offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+        offscreenTextureDesc.MipLevels = 1;
+        offscreenTextureDesc.ArraySize = 1;
+        offscreenTextureDesc.SampleDesc.Count = 1;
+        offscreenTextureDesc.SampleDesc.Quality = 0;
+        offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT;
+        offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
+        offscreenTextureDesc.CPUAccessFlags = 0;
+        offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0;
+
+        HRESULT result = device-&gt;CreateTexture2D(&amp;offscreenTextureDesc, NULL, &amp;mOffscreenTexture);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Could not create offscreen texture: %08lX&quot;, result);
+            release();
+
+            if (d3d11::isDeviceLostError(result))
+            {
+                return EGL_CONTEXT_LOST;
+            }
+            else
+            {
+                return EGL_BAD_ALLOC;
+            }
+        }
+
+        d3d11::SetDebugName(mOffscreenTexture, &quot;Offscreen texture&quot;);
+
+        // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client
+        if (useSharedResource)
+        {
+            IDXGIResource *offscreenTextureResource = NULL;
+            result = mOffscreenTexture-&gt;QueryInterface(__uuidof(IDXGIResource), (void**)&amp;offscreenTextureResource);
+
+            // Fall back to no share handle on failure
+            if (FAILED(result))
+            {
+                ERR(&quot;Could not query offscreen texture resource: %08lX&quot;, result);
+            }
+            else
+            {
+                result = offscreenTextureResource-&gt;GetSharedHandle(&amp;mShareHandle);
+                offscreenTextureResource-&gt;Release();
+
+                if (FAILED(result))
+                {
+                    mShareHandle = NULL;
+                    ERR(&quot;Could not get offscreen texture shared handle: %08lX&quot;, result);
+                }
+            }
+        }
+    }
+        
+    HRESULT result = device-&gt;CreateRenderTargetView(mOffscreenTexture, NULL, &amp;mOffscreenRTView);
+
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mOffscreenRTView, &quot;Offscreen render target&quot;);
+
+    result = device-&gt;CreateShaderResourceView(mOffscreenTexture, NULL, &amp;mOffscreenSRView);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mOffscreenSRView, &quot;Offscreen shader resource&quot;);
+
+    if (mDepthBufferFormat != GL_NONE)
+    {
+        D3D11_TEXTURE2D_DESC depthStencilDesc = {0};
+        depthStencilDesc.Width = backbufferWidth;
+        depthStencilDesc.Height = backbufferHeight;
+        depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat);
+        depthStencilDesc.MipLevels = 1;
+        depthStencilDesc.ArraySize = 1;
+        depthStencilDesc.SampleDesc.Count = 1;
+        depthStencilDesc.SampleDesc.Quality = 0;
+        depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
+        depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+        depthStencilDesc.CPUAccessFlags = 0;
+        depthStencilDesc.MiscFlags = 0;
+
+        result = device-&gt;CreateTexture2D(&amp;depthStencilDesc, NULL, &amp;mDepthStencilTexture);
+        if (FAILED(result))
+        {
+            ERR(&quot;Could not create depthstencil surface for new swap chain: 0x%08X&quot;, result);
+            release();
+
+            if (d3d11::isDeviceLostError(result))
+            {
+                return EGL_CONTEXT_LOST;
+            }
+            else
+            {
+                return EGL_BAD_ALLOC;
+            }
+        }
+        d3d11::SetDebugName(mDepthStencilTexture, &quot;Depth stencil texture&quot;);
+
+        result = device-&gt;CreateDepthStencilView(mDepthStencilTexture, NULL, &amp;mDepthStencilDSView);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mDepthStencilDSView, &quot;Depth stencil view&quot;);
+    }
+
+    mWidth = backbufferWidth;
+    mHeight = backbufferHeight;
+
+    if (previousOffscreenTexture != NULL)
+    {
+        D3D11_BOX sourceBox = {0};
+        sourceBox.left = 0;
+        sourceBox.right = std::min(previousWidth, mWidth);
+        sourceBox.top = std::max(previousHeight - mHeight, 0);
+        sourceBox.bottom = previousHeight;
+        sourceBox.front = 0;
+        sourceBox.back = 1;
+
+        ID3D11DeviceContext *deviceContext = mRenderer-&gt;getDeviceContext();
+        const int yoffset = std::max(mHeight - previousHeight, 0);
+        deviceContext-&gt;CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &amp;sourceBox);
+
+        previousOffscreenTexture-&gt;Release();
+
+        if (mSwapChain)
+        {
+            swapRect(0, 0, mWidth, mHeight);
+        }
+    }
+
+    return EGL_SUCCESS;
+}
+
+EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight)
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+
+    if (device == NULL)
+    {
+        return EGL_BAD_ACCESS;
+    }
+
+    // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+    if (backbufferWidth &lt; 1 || backbufferHeight &lt; 1)
+    {
+        return EGL_SUCCESS;
+    }
+
+    // Can only call resize if we have already created our swap buffer and resources
+    ASSERT(mSwapChain &amp;&amp; mBackBufferTexture &amp;&amp; mBackBufferRTView);
+
+    SafeRelease(mBackBufferTexture);
+    SafeRelease(mBackBufferRTView);
+
+    // Resize swap chain
+    DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+    HRESULT result = mSwapChain-&gt;ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Error resizing swap chain buffers: 0x%08X&quot;, result);
+        release();
+
+        if (d3d11::isDeviceLostError(result))
+        {
+            return EGL_CONTEXT_LOST;
+        }
+        else
+        {
+            return EGL_BAD_ALLOC;
+        }
+    }
+
+    result = mSwapChain-&gt;GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&amp;mBackBufferTexture);
+    ASSERT(SUCCEEDED(result));
+    if (SUCCEEDED(result))
+    {
+        d3d11::SetDebugName(mBackBufferTexture, &quot;Back buffer texture&quot;);
+    }
+
+    result = device-&gt;CreateRenderTargetView(mBackBufferTexture, NULL, &amp;mBackBufferRTView);
+    ASSERT(SUCCEEDED(result));
+    if (SUCCEEDED(result))
+    {
+        d3d11::SetDebugName(mBackBufferRTView, &quot;Back buffer render target&quot;);
+    }
+
+    return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+}
+
+EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+
+    if (device == NULL)
+    {
+        return EGL_BAD_ACCESS;
+    }
+
+    // Release specific resources to free up memory for the new render target, while the
+    // old render target still exists for the purpose of preserving its contents.
+    SafeRelease(mSwapChain);
+    SafeRelease(mBackBufferTexture);
+    SafeRelease(mBackBufferRTView);
+
+    mSwapInterval = static_cast&lt;unsigned int&gt;(swapInterval);
+    if (mSwapInterval &gt; 4)
+    {
+        // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range
+        return EGL_BAD_PARAMETER;
+    }
+
+    // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains
+    if (backbufferWidth &lt; 1 || backbufferHeight &lt; 1)
+    {
+        releaseOffscreenTexture();
+        return EGL_SUCCESS;
+    }
+
+    if (mWindow)
+    {
+        IDXGIFactory *factory = mRenderer-&gt;getDxgiFactory();
+
+        DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
+        swapChainDesc.BufferCount = 2;
+        swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat);
+        swapChainDesc.BufferDesc.Width = backbufferWidth;
+        swapChainDesc.BufferDesc.Height = backbufferHeight;
+        swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
+        swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
+        swapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
+        swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
+        swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+        swapChainDesc.Flags = 0;
+        swapChainDesc.OutputWindow = mWindow;
+        swapChainDesc.SampleDesc.Count = 1;
+        swapChainDesc.SampleDesc.Quality = 0;
+        swapChainDesc.Windowed = TRUE;
+
+        HRESULT result = factory-&gt;CreateSwapChain(device, &amp;swapChainDesc, &amp;mSwapChain);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Could not create additional swap chains or offscreen surfaces: %08lX&quot;, result);
+            release();
+
+            if (d3d11::isDeviceLostError(result))
+            {
+                return EGL_CONTEXT_LOST;
+            }
+            else
+            {
+                return EGL_BAD_ALLOC;
+            }
+        }
+
+        result = mSwapChain-&gt;GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&amp;mBackBufferTexture);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mBackBufferTexture, &quot;Back buffer texture&quot;);
+
+        result = device-&gt;CreateRenderTargetView(mBackBufferTexture, NULL, &amp;mBackBufferRTView);
+        ASSERT(SUCCEEDED(result));
+        d3d11::SetDebugName(mBackBufferRTView, &quot;Back buffer render target&quot;);
+    }
+
+    // If we are resizing the swap chain, we don't wish to recreate all the static resources
+    if (!mPassThroughResourcesInit)
+    {
+        mPassThroughResourcesInit = true;
+        initPassThroughResources();
+    }
+
+    return resetOffscreenTexture(backbufferWidth, backbufferHeight);
+}
+
+void SwapChain11::initPassThroughResources()
+{
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+
+    ASSERT(device != NULL);
+
+    // Make sure our resources are all not allocated, when we create
+    ASSERT(mQuadVB == NULL &amp;&amp; mPassThroughSampler == NULL);
+    ASSERT(mPassThroughIL == NULL &amp;&amp; mPassThroughVS == NULL &amp;&amp; mPassThroughPS == NULL);
+
+    D3D11_BUFFER_DESC vbDesc;
+    vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4;
+    vbDesc.Usage = D3D11_USAGE_DYNAMIC;
+    vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+    vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+    vbDesc.MiscFlags = 0;
+    vbDesc.StructureByteStride = 0;
+
+    HRESULT result = device-&gt;CreateBuffer(&amp;vbDesc, NULL, &amp;mQuadVB);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mQuadVB, &quot;Swap chain quad vertex buffer&quot;);
+
+    D3D11_SAMPLER_DESC samplerDesc;
+    samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+    samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
+    samplerDesc.MipLODBias = 0.0f;
+    samplerDesc.MaxAnisotropy = 0;
+    samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
+    samplerDesc.BorderColor[0] = 0.0f;
+    samplerDesc.BorderColor[1] = 0.0f;
+    samplerDesc.BorderColor[2] = 0.0f;
+    samplerDesc.BorderColor[3] = 0.0f;
+    samplerDesc.MinLOD = 0;
+    samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;
+
+    result = device-&gt;CreateSamplerState(&amp;samplerDesc, &amp;mPassThroughSampler);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mPassThroughSampler, &quot;Swap chain pass through sampler&quot;);
+
+    D3D11_INPUT_ELEMENT_DESC quadLayout[] =
+    {
+        { &quot;POSITION&quot;, 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { &quot;TEXCOORD&quot;, 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+    };
+
+    result = device-&gt;CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &amp;mPassThroughIL);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mPassThroughIL, &quot;Swap chain pass through layout&quot;);
+
+    result = device-&gt;CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &amp;mPassThroughVS);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mPassThroughVS, &quot;Swap chain pass through vertex shader&quot;);
+
+    result = device-&gt;CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &amp;mPassThroughPS);
+    ASSERT(SUCCEEDED(result));
+    d3d11::SetDebugName(mPassThroughPS, &quot;Swap chain pass through pixel shader&quot;);
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+    if (!mSwapChain)
+    {
+        return EGL_SUCCESS;
+    }
+
+    ID3D11Device *device = mRenderer-&gt;getDevice();
+    ID3D11DeviceContext *deviceContext = mRenderer-&gt;getDeviceContext();
+
+    // Set vertices
+    D3D11_MAPPED_SUBRESOURCE mappedResource;
+    HRESULT result = deviceContext-&gt;Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
+    if (FAILED(result))
+    {
+        return EGL_BAD_ACCESS;
+    }
+
+    d3d11::PositionTexCoordVertex *vertices = static_cast&lt;d3d11::PositionTexCoordVertex*&gt;(mappedResource.pData);
+
+    // Create a quad in homogeneous coordinates
+    float x1 = (x / float(mWidth)) * 2.0f - 1.0f;
+    float y1 = (y / float(mHeight)) * 2.0f - 1.0f;
+    float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f;
+    float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f;
+
+    float u1 = x / float(mWidth);
+    float v1 = y / float(mHeight);
+    float u2 = (x + width) / float(mWidth);
+    float v2 = (y + height) / float(mHeight);
+
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[0], x1, y1, u1, v1);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[1], x1, y2, u1, v2);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[2], x2, y1, u2, v1);
+    d3d11::SetPositionTexCoordVertex(&amp;vertices[3], x2, y2, u2, v2);
+
+    deviceContext-&gt;Unmap(mQuadVB, 0);
+
+    static UINT stride = sizeof(d3d11::PositionTexCoordVertex);
+    static UINT startIdx = 0;
+    deviceContext-&gt;IASetVertexBuffers(0, 1, &amp;mQuadVB, &amp;stride, &amp;startIdx);
+
+    // Apply state
+    deviceContext-&gt;OMSetDepthStencilState(NULL, 0xFFFFFFFF);
+
+    static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
+    deviceContext-&gt;OMSetBlendState(NULL, blendFactor, 0xFFFFFFF);
+
+    deviceContext-&gt;RSSetState(NULL);
+
+    // Apply shaders
+    deviceContext-&gt;IASetInputLayout(mPassThroughIL);
+    deviceContext-&gt;IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+    deviceContext-&gt;VSSetShader(mPassThroughVS, NULL, 0);
+    deviceContext-&gt;PSSetShader(mPassThroughPS, NULL, 0);
+    deviceContext-&gt;GSSetShader(NULL, NULL, 0);
+
+    // Apply render targets
+    mRenderer-&gt;setOneTimeRenderTarget(mBackBufferRTView);
+
+    // Set the viewport
+    D3D11_VIEWPORT viewport;
+    viewport.TopLeftX = 0;
+    viewport.TopLeftY = 0;
+    viewport.Width = mWidth;
+    viewport.Height = mHeight;
+    viewport.MinDepth = 0.0f;
+    viewport.MaxDepth = 1.0f;
+    deviceContext-&gt;RSSetViewports(1, &amp;viewport);
+
+    // Apply textures
+    deviceContext-&gt;PSSetShaderResources(0, 1, &amp;mOffscreenSRView);
+    deviceContext-&gt;PSSetSamplers(0, 1, &amp;mPassThroughSampler);
+
+    // Draw
+    deviceContext-&gt;Draw(4, 0);
+
+#if ANGLE_FORCE_VSYNC_OFF
+    result = mSwapChain-&gt;Present(0, 0);
+#else
+    result = mSwapChain-&gt;Present(mSwapInterval, 0);
+#endif
+
+    if (result == DXGI_ERROR_DEVICE_REMOVED)
+    {
+        HRESULT removedReason = device-&gt;GetDeviceRemovedReason();
+        ERR(&quot;Present failed: the D3D11 device was removed: 0x%08X&quot;, removedReason);
+        return EGL_CONTEXT_LOST;
+    }
+    else if (result == DXGI_ERROR_DEVICE_RESET)
+    {
+        ERR(&quot;Present failed: the D3D11 device was reset from a bad command.&quot;);
+        return EGL_CONTEXT_LOST;
+    }
+    else if (FAILED(result))
+    {
+        ERR(&quot;Present failed with error code 0x%08X&quot;, result);
+    }
+
+    // Unbind
+    static ID3D11ShaderResourceView *const nullSRV = NULL;
+    deviceContext-&gt;PSSetShaderResources(0, 1, &amp;nullSRV);
+
+    mRenderer-&gt;unapplyRenderTargets();
+    mRenderer-&gt;markAllStateDirty();
+
+    return EGL_SUCCESS;
+}
+
+// Increments refcount on texture.
+// caller must Release() the returned texture
+ID3D11Texture2D *SwapChain11::getOffscreenTexture()
+{
+    if (mOffscreenTexture)
+    {
+        mOffscreenTexture-&gt;AddRef();
+    }
+
+    return mOffscreenTexture;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11RenderTargetView *SwapChain11::getRenderTarget()
+{
+    if (mOffscreenRTView)
+    {
+        mOffscreenRTView-&gt;AddRef();
+    }
+
+    return mOffscreenRTView;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource()
+{
+    if (mOffscreenSRView)
+    {
+        mOffscreenSRView-&gt;AddRef();
+    }
+
+    return mOffscreenSRView;
+}
+
+// Increments refcount on view.
+// caller must Release() the returned view
+ID3D11DepthStencilView *SwapChain11::getDepthStencil()
+{
+    if (mDepthStencilDSView)
+    {
+        mDepthStencilDSView-&gt;AddRef();
+    }
+
+    return mDepthStencilDSView;
+}
+
+ID3D11Texture2D *SwapChain11::getDepthStencilTexture()
+{
+    if (mDepthStencilTexture)
+    {
+        mDepthStencilTexture-&gt;AddRef();
+    }
+
+    return mDepthStencilTexture;
+}
+
+SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain));
+    return static_cast&lt;rx::SwapChain11*&gt;(swapChain);
+}
+
+void SwapChain11::recreate()
+{
+    // possibly should use this method instead of reset
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11SwapChain11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain.
+
+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;libGLESv2/renderer/SwapChain.h&quot;
+
+namespace rx
+{
+class Renderer11;
+
+class SwapChain11 : public SwapChain
+{
+  public:
+    SwapChain11(Renderer11 *renderer, HWND window, HANDLE shareHandle,
+                GLenum backBufferFormat, GLenum depthBufferFormat);
+    virtual ~SwapChain11();
+
+    EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
+    virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
+    virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+    virtual void recreate();
+
+    virtual ID3D11Texture2D *getOffscreenTexture();
+    virtual ID3D11RenderTargetView *getRenderTarget();
+    virtual ID3D11ShaderResourceView *getRenderTargetShaderResource();
+
+    virtual ID3D11Texture2D *getDepthStencilTexture();
+    virtual ID3D11DepthStencilView *getDepthStencil();
+
+    EGLint getWidth() const { return mWidth; }
+    EGLint getHeight() const { return mHeight; }
+
+    static SwapChain11 *makeSwapChain11(SwapChain *swapChain);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(SwapChain11);
+
+    void release();
+    void initPassThroughResources();
+    void releaseOffscreenTexture();
+    EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight);
+
+    Renderer11 *mRenderer;
+    EGLint mHeight;
+    EGLint mWidth;
+    bool mAppCreatedShareHandle;
+    unsigned int mSwapInterval;
+    bool mPassThroughResourcesInit;
+
+    IDXGISwapChain *mSwapChain;
+
+    ID3D11Texture2D *mBackBufferTexture;
+    ID3D11RenderTargetView *mBackBufferRTView;
+
+    ID3D11Texture2D *mOffscreenTexture;
+    ID3D11RenderTargetView *mOffscreenRTView;
+    ID3D11ShaderResourceView *mOffscreenSRView;
+
+    ID3D11Texture2D *mDepthStencilTexture;
+    ID3D11DepthStencilView *mDepthStencilDSView;
+
+    ID3D11Buffer *mQuadVB;
+    ID3D11SamplerState *mPassThroughSampler;
+    ID3D11InputLayout *mPassThroughIL;
+    ID3D11VertexShader *mPassThroughVS;
+    ID3D11PixelShader *mPassThroughPS;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/SwapChain11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11TextureStorage11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,667 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
+
+#include &quot;libGLESv2/renderer/d3d11/TextureStorage11.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/RenderTarget11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/SwapChain11.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+
+#include &quot;libGLESv2/utilities.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+
+namespace rx
+{
+
+TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags)
+    : mBindFlags(bindFlags),
+      mLodOffset(0),
+      mMipLevels(0),
+      mTexture(NULL),
+      mTextureFormat(DXGI_FORMAT_UNKNOWN),
+      mShaderResourceFormat(DXGI_FORMAT_UNKNOWN),
+      mRenderTargetFormat(DXGI_FORMAT_UNKNOWN),
+      mDepthStencilFormat(DXGI_FORMAT_UNKNOWN),
+      mSRV(NULL),
+      mTextureWidth(0),
+      mTextureHeight(0)
+{
+    mRenderer = Renderer11::makeRenderer11(renderer);
+}
+
+TextureStorage11::~TextureStorage11()
+{
+}
+
+TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage));
+    return static_cast&lt;TextureStorage11*&gt;(storage);
+}
+
+DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable)
+{
+    UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
+    
+    if (d3d11::IsDepthStencilFormat(format))
+    {
+        bindFlags |= D3D11_BIND_DEPTH_STENCIL;
+    }
+    else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) &amp;&amp; (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+    {
+        bindFlags |= D3D11_BIND_RENDER_TARGET;
+    }
+    return bindFlags;
+}
+
+bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format)
+{
+    switch(format)
+    {
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+      case DXGI_FORMAT_A8_UNORM:
+      case DXGI_FORMAT_R32G32B32A32_FLOAT:
+      case DXGI_FORMAT_R16G16B16A16_FLOAT:
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+      case DXGI_FORMAT_R8_UNORM:
+      case DXGI_FORMAT_R8G8_UNORM:
+      case DXGI_FORMAT_R16_FLOAT:
+      case DXGI_FORMAT_R16G16_FLOAT:
+        return true;
+      case DXGI_FORMAT_BC1_UNORM:
+      case DXGI_FORMAT_BC2_UNORM: 
+      case DXGI_FORMAT_BC3_UNORM:
+      case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices
+        return false;
+      default:
+        UNREACHABLE();
+        return false;
+    }
+}
+
+UINT TextureStorage11::getBindFlags() const
+{
+    return mBindFlags;
+}
+
+ID3D11Texture2D *TextureStorage11::getBaseTexture() const
+{
+    return mTexture;
+}
+
+int TextureStorage11::getLodOffset() const
+{
+    return mLodOffset;
+}
+
+bool TextureStorage11::isRenderTarget() const
+{
+    return (mBindFlags &amp; (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
+}
+    
+bool TextureStorage11::isManaged() const
+{
+    return false;
+}
+
+int TextureStorage11::levelCount()
+{
+    int levels = 0;
+    if (getBaseTexture())
+    {
+        levels = mMipLevels - getLodOffset();
+    }
+    return levels;
+}
+
+UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex)
+{
+    UINT index = 0;
+    if (getBaseTexture())
+    {
+        index = D3D11CalcSubresource(level, faceIndex, mMipLevels);
+    }
+    return index;
+}
+
+bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource,
+                                              int level, int face, GLint xoffset, GLint yoffset,
+                                              GLsizei width, GLsizei height)
+{
+    if (srcTexture)
+    {
+        // Round up the width and height to the nearest multiple of dimension alignment
+        unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat);
+        width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment;
+        height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment;
+
+        D3D11_BOX srcBox;
+        srcBox.left = xoffset;
+        srcBox.top = yoffset;
+        srcBox.right = xoffset + width;
+        srcBox.bottom = yoffset + height;
+        srcBox.front = 0;
+        srcBox.back = 1;
+
+        ID3D11DeviceContext *context = mRenderer-&gt;getDeviceContext();
+        
+        ASSERT(getBaseTexture());
+        context-&gt;CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face),
+                                       xoffset, yoffset, 0, srcTexture, sourceSubresource, &amp;srcBox);
+        return true;
+    }
+
+    return false;
+}
+
+void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest)
+{
+    if (source &amp;&amp; dest)
+    {
+        ID3D11ShaderResourceView *sourceSRV = source-&gt;getShaderResourceView();
+        ID3D11RenderTargetView *destRTV = dest-&gt;getRenderTargetView();
+
+        if (sourceSRV &amp;&amp; destRTV)
+        {
+            gl::Rectangle sourceArea;
+            sourceArea.x = 0;
+            sourceArea.y = 0;
+            sourceArea.width = source-&gt;getWidth();
+            sourceArea.height = source-&gt;getHeight();
+
+            gl::Rectangle destArea;
+            destArea.x = 0;
+            destArea.y = 0;
+            destArea.width = dest-&gt;getWidth();
+            destArea.height = dest-&gt;getHeight();
+
+            mRenderer-&gt;copyTexture(sourceSRV, sourceArea, source-&gt;getWidth(), source-&gt;getHeight(),
+                                   destRTV, destArea, dest-&gt;getWidth(), dest-&gt;getHeight(),
+                                   GL_RGBA);
+        }
+    }
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain)
+    : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)
+{
+    mTexture = swapchain-&gt;getOffscreenTexture();
+    mSRV = swapchain-&gt;getRenderTargetShaderResource();
+
+    for (unsigned int i = 0; i &lt; gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        mRenderTarget[i] = NULL;
+    }
+
+    D3D11_TEXTURE2D_DESC texDesc;
+    mTexture-&gt;GetDesc(&amp;texDesc);
+    mMipLevels = texDesc.MipLevels;
+    mTextureFormat = texDesc.Format;
+    mTextureWidth = texDesc.Width;
+    mTextureHeight = texDesc.Height;
+
+    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+    mSRV-&gt;GetDesc(&amp;srvDesc);
+    mShaderResourceFormat = srvDesc.Format;
+
+    ID3D11RenderTargetView* offscreenRTV = swapchain-&gt;getRenderTarget();
+    D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+    offscreenRTV-&gt;GetDesc(&amp;rtvDesc);
+    mRenderTargetFormat = rtvDesc.Format;
+    offscreenRTV-&gt;Release();
+
+    mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+}
+
+TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+    : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+{
+    for (unsigned int i = 0; i &lt; gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        mRenderTarget[i] = NULL;
+    }
+
+    DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+    if (d3d11::IsDepthStencilFormat(convertedFormat))
+    {
+        mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+        mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
+        mDepthStencilFormat = convertedFormat;
+        mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
+    }
+    else
+    {
+        mTextureFormat = convertedFormat;
+        mShaderResourceFormat = convertedFormat;
+        mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+        mRenderTargetFormat = convertedFormat;
+    }
+
+    // if the width or height is not positive this should be treated as an incomplete texture
+    // we handle that here by skipping the d3d texture creation
+    if (width &gt; 0 &amp;&amp; height &gt; 0)
+    {
+        // adjust size if needed for compressed textures
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &amp;width, &amp;height, &amp;mLodOffset);
+
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+
+        D3D11_TEXTURE2D_DESC desc;
+        desc.Width = width;      // Compressed texture size constraints?
+        desc.Height = height;
+        desc.MipLevels = (levels &gt; 0) ? levels + mLodOffset : 0;
+        desc.ArraySize = 1;
+        desc.Format = mTextureFormat;
+        desc.SampleDesc.Count = 1;
+        desc.SampleDesc.Quality = 0;
+        desc.Usage = D3D11_USAGE_DEFAULT;
+        desc.BindFlags = getBindFlags();
+        desc.CPUAccessFlags = 0;
+        desc.MiscFlags = 0;
+
+        HRESULT result = device-&gt;CreateTexture2D(&amp;desc, NULL, &amp;mTexture);
+
+        // this can happen from windows TDR
+        if (d3d11::isDeviceLostError(result))
+        {
+            mRenderer-&gt;notifyDeviceLost();
+            gl::error(GL_OUT_OF_MEMORY);
+        }
+        else if (FAILED(result))
+        {
+            ASSERT(result == E_OUTOFMEMORY);
+            ERR(&quot;Creating image failed.&quot;);
+            gl::error(GL_OUT_OF_MEMORY);
+        }
+        else
+        {
+            mTexture-&gt;GetDesc(&amp;desc);
+            mMipLevels = desc.MipLevels;
+            mTextureWidth = desc.Width;
+            mTextureHeight = desc.Height;
+        }
+    }
+}
+
+TextureStorage11_2D::~TextureStorage11_2D()
+{
+    if (mTexture)
+    {
+        mTexture-&gt;Release();
+        mTexture = NULL;
+    }
+
+    if (mSRV)
+    {
+        mSRV-&gt;Release();
+        mSRV = NULL;
+    }
+
+    for (unsigned int i = 0; i &lt; gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
+    {
+        delete mRenderTarget[i];
+        mRenderTarget[i] = NULL;
+    }
+}
+
+TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage));
+    return static_cast&lt;TextureStorage11_2D*&gt;(storage);
+}
+
+RenderTarget *TextureStorage11_2D::getRenderTarget(int level)
+{
+    if (level &gt;= 0 &amp;&amp; level &lt; static_cast&lt;int&gt;(mMipLevels))
+    {
+        if (!mRenderTarget[level])
+        {
+            ID3D11Device *device = mRenderer-&gt;getDevice();
+            HRESULT result;
+
+            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+            srvDesc.Format = mShaderResourceFormat;
+            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+            srvDesc.Texture2D.MostDetailedMip = level;
+            srvDesc.Texture2D.MipLevels = 1;
+
+            ID3D11ShaderResourceView *srv;
+            result = device-&gt;CreateShaderResourceView(mTexture, &amp;srvDesc, &amp;srv);
+
+            if (result == E_OUTOFMEMORY)
+            {
+                return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+            }
+            ASSERT(SUCCEEDED(result));
+
+            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+            {
+                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+                rtvDesc.Format = mRenderTargetFormat;
+                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+                rtvDesc.Texture2D.MipSlice = level;
+
+                ID3D11RenderTargetView *rtv;
+                result = device-&gt;CreateRenderTargetView(mTexture, &amp;rtvDesc, &amp;rtv);
+
+                if (result == E_OUTOFMEMORY)
+                {
+                    srv-&gt;Release();
+                    return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+                }
+                ASSERT(SUCCEEDED(result));
+
+                // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+                // also needs to keep a reference to the texture.
+                mTexture-&gt;AddRef();
+
+                mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
+                                                          std::max(mTextureWidth &gt;&gt; level, 1U),
+                                                          std::max(mTextureHeight &gt;&gt; level, 1U));
+            }
+            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+            {
+                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+                dsvDesc.Format = mDepthStencilFormat;
+                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+                dsvDesc.Texture2D.MipSlice = level;
+                dsvDesc.Flags = 0;
+
+                ID3D11DepthStencilView *dsv;
+                result = device-&gt;CreateDepthStencilView(mTexture, &amp;dsvDesc, &amp;dsv);
+
+                if (result == E_OUTOFMEMORY)
+                {
+                    srv-&gt;Release();
+                    return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+                }
+                ASSERT(SUCCEEDED(result));
+
+                // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+                // also needs to keep a reference to the texture.
+                mTexture-&gt;AddRef();
+
+                mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
+                                                          std::max(mTextureWidth &gt;&gt; level, 1U),
+                                                          std::max(mTextureHeight &gt;&gt; level, 1U));
+            }
+            else
+            {
+                UNREACHABLE();
+            }
+        }
+
+        return mRenderTarget[level];
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+ID3D11ShaderResourceView *TextureStorage11_2D::getSRV()
+{
+    if (!mSRV)
+    {
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+
+        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+        srvDesc.Format = mShaderResourceFormat;
+        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
+        srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+        srvDesc.Texture2D.MostDetailedMip = 0;
+
+        HRESULT result = device-&gt;CreateShaderResourceView(mTexture, &amp;srvDesc, &amp;mSRV);
+
+        if (result == E_OUTOFMEMORY)
+        {
+            return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;ID3D11ShaderResourceView*&gt;(NULL));
+        }
+        ASSERT(SUCCEEDED(result));
+    }
+
+    return mSRV;
+}
+
+void TextureStorage11_2D::generateMipmap(int level)
+{
+    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1));
+    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level));
+
+    generateMipmapLayer(source, dest);
+}
+
+TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+    : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat), usage, forceRenderable))
+{
+    for (unsigned int i = 0; i &lt; 6; i++)
+    {
+        for (unsigned int j = 0; j &lt; gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
+        {
+            mRenderTarget[i][j] = NULL;
+        }
+    }
+
+    DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat);
+    if (d3d11::IsDepthStencilFormat(convertedFormat))
+    {
+        mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat);
+        mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat);
+        mDepthStencilFormat = convertedFormat;
+        mRenderTargetFormat = DXGI_FORMAT_UNKNOWN;
+    }
+    else
+    {
+        mTextureFormat = convertedFormat;
+        mShaderResourceFormat = convertedFormat;
+        mDepthStencilFormat = DXGI_FORMAT_UNKNOWN;
+        mRenderTargetFormat = convertedFormat;
+    }
+
+    // if the size is not positive this should be treated as an incomplete texture
+    // we handle that here by skipping the d3d texture creation
+    if (size &gt; 0)
+    {
+        // adjust size if needed for compressed textures
+        int height = size;
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &amp;size, &amp;height, &amp;mLodOffset);
+
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+
+        D3D11_TEXTURE2D_DESC desc;
+        desc.Width = size;
+        desc.Height = size;
+        desc.MipLevels = (levels &gt; 0) ? levels + mLodOffset : 0;
+        desc.ArraySize = 6;
+        desc.Format = mTextureFormat;
+        desc.SampleDesc.Count = 1;
+        desc.SampleDesc.Quality = 0;
+        desc.Usage = D3D11_USAGE_DEFAULT;
+        desc.BindFlags = getBindFlags();
+        desc.CPUAccessFlags = 0;
+        desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
+
+        HRESULT result = device-&gt;CreateTexture2D(&amp;desc, NULL, &amp;mTexture);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == E_OUTOFMEMORY);
+            ERR(&quot;Creating image failed.&quot;);
+            gl::error(GL_OUT_OF_MEMORY);
+        }
+        else
+        {
+            mTexture-&gt;GetDesc(&amp;desc);
+            mMipLevels = desc.MipLevels;
+            mTextureWidth = desc.Width;
+            mTextureHeight = desc.Height;
+        }
+    }
+}
+
+TextureStorage11_Cube::~TextureStorage11_Cube()
+{
+    if (mTexture)
+    {
+        mTexture-&gt;Release();
+        mTexture = NULL;
+    }
+
+    if (mSRV)
+    {
+        mSRV-&gt;Release();
+        mSRV = NULL;
+    }
+
+    for (unsigned int i = 0; i &lt; 6; i++)
+    {
+        for (unsigned int j = 0; j &lt; gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++)
+        {
+            delete mRenderTarget[i][j];
+            mRenderTarget[i][j] = NULL;
+        }
+    }
+}
+
+TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage));
+    return static_cast&lt;TextureStorage11_Cube*&gt;(storage);
+}
+
+RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level)
+{
+    unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget);
+    if (level &gt;= 0 &amp;&amp; level &lt; static_cast&lt;int&gt;(mMipLevels))
+    {
+        if (!mRenderTarget[faceIdx][level])
+        {
+            ID3D11Device *device = mRenderer-&gt;getDevice();
+            HRESULT result;
+
+            D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+            srvDesc.Format = mShaderResourceFormat;
+            srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube
+            srvDesc.Texture2DArray.MostDetailedMip = level;
+            srvDesc.Texture2DArray.MipLevels = 1;
+            srvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+            srvDesc.Texture2DArray.ArraySize = 1;
+
+            ID3D11ShaderResourceView *srv;
+            result = device-&gt;CreateShaderResourceView(mTexture, &amp;srvDesc, &amp;srv);
+
+            if (result == E_OUTOFMEMORY)
+            {
+                return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+            }
+            ASSERT(SUCCEEDED(result));
+
+            if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN)
+            {
+                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
+                rtvDesc.Format = mRenderTargetFormat;
+                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
+                rtvDesc.Texture2DArray.MipSlice = level;
+                rtvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+                rtvDesc.Texture2DArray.ArraySize = 1;
+
+                ID3D11RenderTargetView *rtv;
+                result = device-&gt;CreateRenderTargetView(mTexture, &amp;rtvDesc, &amp;rtv);
+
+                if (result == E_OUTOFMEMORY)
+                {
+                    srv-&gt;Release();
+                    return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+                }
+                ASSERT(SUCCEEDED(result));
+
+                // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+                // also needs to keep a reference to the texture.
+                mTexture-&gt;AddRef();
+
+                mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv,
+                                                                   std::max(mTextureWidth &gt;&gt; level, 1U),
+                                                                   std::max(mTextureHeight &gt;&gt; level, 1U));
+            }
+            else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN)
+            {
+                D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
+                dsvDesc.Format = mRenderTargetFormat;
+                dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
+                dsvDesc.Texture2DArray.MipSlice = level;
+                dsvDesc.Texture2DArray.FirstArraySlice = faceIdx;
+                dsvDesc.Texture2DArray.ArraySize = 1;
+
+                ID3D11DepthStencilView *dsv;
+                result = device-&gt;CreateDepthStencilView(mTexture, &amp;dsvDesc, &amp;dsv);
+
+                if (result == E_OUTOFMEMORY)
+                {
+                    srv-&gt;Release();
+                    return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;RenderTarget*&gt;(NULL));
+                }
+                ASSERT(SUCCEEDED(result));
+
+                // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11
+                // also needs to keep a reference to the texture.
+                mTexture-&gt;AddRef();
+
+                mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv,
+                                                                   std::max(mTextureWidth &gt;&gt; level, 1U),
+                                                                   std::max(mTextureHeight &gt;&gt; level, 1U));
+            }
+            else
+            {
+                UNREACHABLE();
+            }
+        }
+
+        return mRenderTarget[faceIdx][level];
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV()
+{
+    if (!mSRV)
+    {
+        ID3D11Device *device = mRenderer-&gt;getDevice();
+
+        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
+        srvDesc.Format = mShaderResourceFormat;
+        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
+        srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels);
+        srvDesc.TextureCube.MostDetailedMip = 0;
+
+        HRESULT result = device-&gt;CreateShaderResourceView(mTexture, &amp;srvDesc, &amp;mSRV);
+
+        if (result == E_OUTOFMEMORY)
+        {
+            return gl::error(GL_OUT_OF_MEMORY, static_cast&lt;ID3D11ShaderResourceView*&gt;(NULL));
+        }
+        ASSERT(SUCCEEDED(result));
+    }
+
+    return mSRV;
+}
+
+void TextureStorage11_Cube::generateMipmap(int face, int level)
+{
+    RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1));
+    RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level));
+
+    generateMipmapLayer(source, dest);
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11TextureStorage11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,120 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived
+// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
+
+#include &quot;libGLESv2/Texture.h&quot;
+#include &quot;libGLESv2/renderer/TextureStorage.h&quot;
+
+namespace rx
+{
+class RenderTarget;
+class RenderTarget11;
+class Renderer;
+class Renderer11;
+class SwapChain11;
+
+class TextureStorage11 : public TextureStorage
+{
+  public:
+    TextureStorage11(Renderer *renderer, UINT bindFlags);
+    virtual ~TextureStorage11();
+
+    static TextureStorage11 *makeTextureStorage11(TextureStorage *storage);
+
+    static DWORD GetTextureBindFlags(DXGI_FORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+    static bool IsTextureFormatRenderable(DXGI_FORMAT format);
+
+    UINT getBindFlags() const;
+
+    virtual ID3D11Texture2D *getBaseTexture() const;
+    virtual ID3D11ShaderResourceView *getSRV() = 0;
+    virtual RenderTarget *getRenderTarget() { return getRenderTarget(0); }
+    virtual RenderTarget *getRenderTarget(int level) { return NULL; }
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return getRenderTarget(faceTarget, 0); }
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level) { return NULL; }
+
+    virtual void generateMipmap(int level) {};
+    virtual void generateMipmap(int face, int level) {};
+
+    virtual int getLodOffset() const;
+    virtual bool isRenderTarget() const;
+    virtual bool isManaged() const;
+    virtual int levelCount();
+    UINT getSubresourceIndex(int level, int faceTarget);
+
+    bool updateSubresourceLevel(ID3D11Texture2D *texture, unsigned int sourceSubresource, int level,
+                                int faceTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+  protected:
+    void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest);
+
+    Renderer11 *mRenderer;
+    int mLodOffset;
+    unsigned int mMipLevels;
+
+    ID3D11Texture2D *mTexture;
+    DXGI_FORMAT mTextureFormat;
+    DXGI_FORMAT mShaderResourceFormat;
+    DXGI_FORMAT mRenderTargetFormat;
+    DXGI_FORMAT mDepthStencilFormat;
+    unsigned int mTextureWidth;
+    unsigned int mTextureHeight;
+
+    ID3D11ShaderResourceView *mSRV;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage11);
+
+    const UINT mBindFlags;
+};
+
+class TextureStorage11_2D : public TextureStorage11
+{
+  public:
+    TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain);
+    TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+    virtual ~TextureStorage11_2D();
+
+    static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage);
+
+    virtual ID3D11ShaderResourceView *getSRV();
+    virtual RenderTarget *getRenderTarget(int level);
+
+    virtual void generateMipmap(int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D);
+
+    RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+class TextureStorage11_Cube : public TextureStorage11
+{
+  public:
+    TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+    virtual ~TextureStorage11_Cube();
+
+    static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage);
+
+    virtual ID3D11ShaderResourceView *getSRV();
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level);
+
+    virtual void generateMipmap(int face, int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube);
+
+    RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/TextureStorage11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11VertexBuffer11cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,440 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation.
+
+#include &quot;libGLESv2/renderer/d3d11/VertexBuffer11.h&quot;
+#include &quot;libGLESv2/renderer/BufferStorage.h&quot;
+
+#include &quot;libGLESv2/Buffer.h&quot;
+#include &quot;libGLESv2/renderer/d3d11/Renderer11.h&quot;
+#include &quot;libGLESv2/Context.h&quot;
+
+namespace rx
+{
+
+VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer)
+{
+    mBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+}
+
+VertexBuffer11::~VertexBuffer11()
+{
+    if (mBuffer)
+    {
+        mBuffer-&gt;Release();
+        mBuffer = NULL;
+    }
+}
+
+bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage)
+{
+    if (mBuffer)
+    {
+        mBuffer-&gt;Release();
+        mBuffer = NULL;
+    }
+
+    updateSerial();
+
+    if (size &gt; 0)
+    {
+        ID3D11Device* dxDevice = mRenderer-&gt;getDevice();
+
+        D3D11_BUFFER_DESC bufferDesc;
+        bufferDesc.ByteWidth = size;
+        bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
+        bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
+        bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
+        bufferDesc.MiscFlags = 0;
+        bufferDesc.StructureByteStride = 0;
+
+        HRESULT result = dxDevice-&gt;CreateBuffer(&amp;bufferDesc, NULL, &amp;mBuffer);
+        if (FAILED(result))
+        {
+            return false;
+        }
+    }
+
+    mBufferSize = size;
+    mDynamicUsage = dynamicUsage;
+    return true;
+}
+
+VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer));
+    return static_cast&lt;VertexBuffer11*&gt;(vetexBuffer);
+}
+
+bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &amp;attrib, GLint start, GLsizei count,
+                                           GLsizei instances, unsigned int offset)
+{
+    if (mBuffer)
+    {
+        gl::Buffer *buffer = attrib.mBoundBuffer.get();
+
+        int inputStride = attrib.stride();
+        const VertexConverter &amp;converter = getVertexConversion(attrib);
+
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext-&gt;Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            ERR(&quot;Vertex buffer map failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        char* output = reinterpret_cast&lt;char*&gt;(mappedResource.pData) + offset;
+
+        const char *input = NULL;
+        if (buffer)
+        {
+            BufferStorage *storage = buffer-&gt;getStorage();
+            input = static_cast&lt;const char*&gt;(storage-&gt;getData()) + static_cast&lt;int&gt;(attrib.mOffset);
+        }
+        else
+        {
+            input = static_cast&lt;const char*&gt;(attrib.mPointer);
+        }
+
+        if (instances == 0 || attrib.mDivisor == 0)
+        {
+            input += inputStride * start;
+        }
+
+        converter.conversionFunc(input, inputStride, count, output);
+
+        dxContext-&gt;Unmap(mBuffer, 0);
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset)
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext-&gt;Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            ERR(&quot;Vertex buffer map failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        char* bufferData = static_cast&lt;char*&gt;(mappedResource.pData);
+        memcpy(bufferData + offset, data, size);
+
+        dxContext-&gt;Unmap(mBuffer, 0);
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &amp;attrib, GLsizei count,
+                                      GLsizei instances, unsigned int *outSpaceRequired) const
+{
+    unsigned int elementSize = getVertexConversion(attrib).outputElementSize;
+
+    unsigned int elementCount = 0;
+    if (instances == 0 || attrib.mDivisor == 0)
+    {
+        elementCount = count;
+    }
+    else
+    {
+        if (static_cast&lt;unsigned int&gt;(instances) &lt; std::numeric_limits&lt;unsigned int&gt;::max() - (attrib.mDivisor - 1))
+        {
+            // Round up
+            elementCount = (static_cast&lt;unsigned int&gt;(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor;
+        }
+        else
+        {
+            elementCount = instances / attrib.mDivisor;
+        }
+    }
+
+    if (elementSize &lt;= std::numeric_limits&lt;unsigned int&gt;::max() / elementCount)
+    {
+        if (outSpaceRequired)
+        {
+            *outSpaceRequired = elementSize * elementCount;
+        }
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &amp;attrib) const
+{
+    return !getVertexConversion(attrib).identity;
+}
+
+unsigned int VertexBuffer11::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+bool VertexBuffer11::setBufferSize(unsigned int size)
+{
+    if (size &gt; mBufferSize)
+    {
+        return initialize(size, mDynamicUsage);
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool VertexBuffer11::discard()
+{
+    if (mBuffer)
+    {
+        ID3D11DeviceContext *dxContext = mRenderer-&gt;getDeviceContext();
+
+        D3D11_MAPPED_SUBRESOURCE mappedResource;
+        HRESULT result = dxContext-&gt;Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &amp;mappedResource);
+        if (FAILED(result))
+        {
+            ERR(&quot;Vertex buffer map failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        dxContext-&gt;Unmap(mBuffer, 0);
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &amp;attrib) const
+{
+    return getVertexConversion(attrib).outputElementSize;
+}
+
+DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &amp;attrib) const
+{
+    return getVertexConversion(attrib).dxgiFormat;
+}
+
+ID3D11Buffer *VertexBuffer11::getBuffer() const
+{
+    return mBuffer;
+}
+
+template &lt;typename T, unsigned int componentCount, bool widen, bool normalized&gt;
+static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output)
+{
+    unsigned int attribSize = sizeof(T) * componentCount;
+
+    if (attribSize == stride &amp;&amp; !widen)
+    {
+        memcpy(output, input, count * attribSize);
+    }
+    else
+    {
+        unsigned int outputStride = widen ? 4 : componentCount;
+        T defaultVal = normalized ? std::numeric_limits&lt;T&gt;::max() : T(1);
+
+        for (unsigned int i = 0; i &lt; count; i++)
+        {
+            const T *offsetInput = reinterpret_cast&lt;const T*&gt;(reinterpret_cast&lt;const char*&gt;(input) + i * stride);
+            T *offsetOutput = reinterpret_cast&lt;T*&gt;(output) + i * outputStride;
+
+            for (unsigned int j = 0; j &lt; componentCount; j++)
+            {
+                offsetOutput[j] = offsetInput[j];
+            }
+
+            if (widen)
+            {
+                offsetOutput[3] = defaultVal;
+            }
+        }
+    }
+}
+
+template &lt;unsigned int componentCount&gt;
+static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output)
+{
+    static const float divisor = 1.0f / (1 &lt;&lt; 16);
+
+    for (unsigned int i = 0; i &lt; count; i++)
+    {
+        const GLfixed* offsetInput = reinterpret_cast&lt;const GLfixed*&gt;(reinterpret_cast&lt;const char*&gt;(input) + stride * i);
+        float* offsetOutput = reinterpret_cast&lt;float*&gt;(output) + i * componentCount;
+
+        for (unsigned int j = 0; j &lt; componentCount; j++)
+        {
+            offsetOutput[j] = static_cast&lt;float&gt;(offsetInput[j]) * divisor;
+        }
+    }
+}
+
+template &lt;typename T, unsigned int componentCount, bool normalized&gt;
+static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output)
+{
+    typedef std::numeric_limits&lt;T&gt; NL;
+
+    for (unsigned int i = 0; i &lt; count; i++)
+    {
+        const T *offsetInput = reinterpret_cast&lt;const T*&gt;(reinterpret_cast&lt;const char*&gt;(input) + stride * i);
+        float *offsetOutput = reinterpret_cast&lt;float*&gt;(output) + i * componentCount;
+
+        for (unsigned int j = 0; j &lt; componentCount; j++)
+        {
+            if (normalized)
+            {
+                if (NL::is_signed)
+                {
+                    const float divisor = 1.0f / (2 * static_cast&lt;float&gt;(NL::max()) + 1);
+                    offsetOutput[j] = (2 * static_cast&lt;float&gt;(offsetInput[j]) + 1) * divisor;
+                }
+                else
+                {
+                    offsetOutput[j] =  static_cast&lt;float&gt;(offsetInput[j]) / NL::max();
+                }
+            }
+            else
+            {
+                offsetOutput[j] =  static_cast&lt;float&gt;(offsetInput[j]);
+            }
+        }
+    }
+}
+
+const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] =
+{
+    { // GL_BYTE
+        { // unnormalized
+            { &amp;copyToFloatVertexData&lt;GLbyte, 1, false&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyToFloatVertexData&lt;GLbyte, 2, false&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyToFloatVertexData&lt;GLbyte, 3, false&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyToFloatVertexData&lt;GLbyte, 4, false&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyVertexData&lt;GLbyte, 1, false, true&gt;, true, DXGI_FORMAT_R8_SNORM, 1 },
+            { &amp;copyVertexData&lt;GLbyte, 2, false, true&gt;, true, DXGI_FORMAT_R8G8_SNORM, 2 },
+            { &amp;copyVertexData&lt;GLbyte, 3, true, true&gt;, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
+            { &amp;copyVertexData&lt;GLbyte, 4, false, true&gt;, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 },
+        },
+    },
+    { // GL_UNSIGNED_BYTE
+        { // unnormalized
+            { &amp;copyToFloatVertexData&lt;GLubyte, 1, false&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyToFloatVertexData&lt;GLubyte, 2, false&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyToFloatVertexData&lt;GLubyte, 3, false&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyToFloatVertexData&lt;GLubyte, 4, false&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyVertexData&lt;GLubyte, 1, false, true&gt;, true, DXGI_FORMAT_R8_UNORM, 1 },
+            { &amp;copyVertexData&lt;GLubyte, 2, false, true&gt;, true, DXGI_FORMAT_R8G8_UNORM, 2 },
+            { &amp;copyVertexData&lt;GLubyte, 3, true, true&gt;, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
+            { &amp;copyVertexData&lt;GLubyte, 4, false, true&gt;, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 },
+        },
+    },
+    { // GL_SHORT
+        { // unnormalized
+            { &amp;copyToFloatVertexData&lt;GLshort, 1, false&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyToFloatVertexData&lt;GLshort, 2, false&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyToFloatVertexData&lt;GLshort, 3, false&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyToFloatVertexData&lt;GLshort, 4, false&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyVertexData&lt;GLshort, 1, false, true&gt;, true, DXGI_FORMAT_R16_SNORM, 2 },
+            { &amp;copyVertexData&lt;GLshort, 2, false, true&gt;, true, DXGI_FORMAT_R16G16_SNORM, 4 },
+            { &amp;copyVertexData&lt;GLshort, 3, true, true&gt;, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
+            { &amp;copyVertexData&lt;GLshort, 4, false, true&gt;, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 },
+        },
+    },
+    { // GL_UNSIGNED_SHORT
+        { // unnormalized
+            { &amp;copyToFloatVertexData&lt;GLushort, 1, false&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyToFloatVertexData&lt;GLushort, 2, false&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyToFloatVertexData&lt;GLushort, 3, false&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyToFloatVertexData&lt;GLushort, 4, false&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyVertexData&lt;GLushort, 1, false, true&gt;, true, DXGI_FORMAT_R16_UNORM, 2 },
+            { &amp;copyVertexData&lt;GLushort, 2, false, true&gt;, true, DXGI_FORMAT_R16G16_UNORM, 4 },
+            { &amp;copyVertexData&lt;GLushort, 3, true, true&gt;, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
+            { &amp;copyVertexData&lt;GLushort, 4, false, true&gt;, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 },
+        },
+    },
+    { // GL_FIXED
+        { // unnormalized
+            { &amp;copyFixedVertexData&lt;1&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyFixedVertexData&lt;2&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyFixedVertexData&lt;3&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyFixedVertexData&lt;4&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyFixedVertexData&lt;1&gt;, false, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyFixedVertexData&lt;2&gt;, false, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyFixedVertexData&lt;3&gt;, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyFixedVertexData&lt;4&gt;, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+    },
+    { // GL_FLOAT
+        { // unnormalized
+            { &amp;copyVertexData&lt;GLfloat, 1, false, false&gt;, true, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyVertexData&lt;GLfloat, 2, false, false&gt;, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyVertexData&lt;GLfloat, 3, false, false&gt;, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyVertexData&lt;GLfloat, 4, false, false&gt;, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+        { // normalized
+            { &amp;copyVertexData&lt;GLfloat, 1, false, false&gt;, true, DXGI_FORMAT_R32_FLOAT, 4 },
+            { &amp;copyVertexData&lt;GLfloat, 2, false, false&gt;, true, DXGI_FORMAT_R32G32_FLOAT, 8 },
+            { &amp;copyVertexData&lt;GLfloat, 3, false, false&gt;, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 },
+            { &amp;copyVertexData&lt;GLfloat, 4, false, false&gt;, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 },
+        },
+    },
+};
+
+const VertexBuffer11::VertexConverter &amp;VertexBuffer11::getVertexConversion(const gl::VertexAttribute &amp;attribute)
+{
+    unsigned int typeIndex = 0;
+    switch (attribute.mType)
+    {
+      case GL_BYTE:             typeIndex = 0; break;
+      case GL_UNSIGNED_BYTE:    typeIndex = 1; break;
+      case GL_SHORT:            typeIndex = 2; break;
+      case GL_UNSIGNED_SHORT:   typeIndex = 3; break;
+      case GL_FIXED:            typeIndex = 4; break;
+      case GL_FLOAT:            typeIndex = 5; break;
+      default:                  UNREACHABLE(); break;
+    }
+
+    return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1];
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11VertexBuffer11h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
+
+#include &quot;libGLESv2/renderer/VertexBuffer.h&quot;
+
+namespace rx
+{
+class Renderer11;
+
+class VertexBuffer11 : public VertexBuffer
+{
+  public:
+    explicit VertexBuffer11(rx::Renderer11 *const renderer);
+    virtual ~VertexBuffer11();
+
+    virtual bool initialize(unsigned int size, bool dynamicUsage);
+
+    static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer);
+
+    virtual bool storeVertexAttributes(const gl::VertexAttribute &amp;attrib, GLint start, GLsizei count, GLsizei instances,
+                                       unsigned int offset);
+    virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset);
+
+    virtual bool getSpaceRequired(const gl::VertexAttribute &amp;attrib, GLsizei count, GLsizei instances,
+                                  unsigned int *outSpaceRequired) const;
+
+    virtual bool requiresConversion(const gl::VertexAttribute &amp;attrib) const;
+
+    virtual unsigned int getBufferSize() const;
+    virtual bool setBufferSize(unsigned int size);
+    virtual bool discard();
+
+    unsigned int getVertexSize(const gl::VertexAttribute &amp;attrib) const;
+    DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &amp;attrib) const;
+
+    ID3D11Buffer *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexBuffer11);
+
+    rx::Renderer11 *const mRenderer;
+
+    ID3D11Buffer *mBuffer;
+    unsigned int mBufferSize;
+    bool mDynamicUsage;
+
+    typedef void (*VertexConversionFunction)(const void *, unsigned int, unsigned int, void *);
+    struct VertexConverter
+    {
+        VertexConversionFunction conversionFunc;
+        bool identity;
+        DXGI_FORMAT dxgiFormat;
+        unsigned int outputElementSize;
+    };
+
+    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+    // This table is used to generate mAttributeTypes.
+    static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1]
+
+    static const VertexConverter &amp;getVertexConversion(const gl::VertexAttribute &amp;attribute);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/VertexBuffer11.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11renderer11_utilscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,688 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer11_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#include &quot;libGLESv2/renderer/d3d11/renderer11_utils.h&quot;
+
+#include &quot;common/debug.h&quot;
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha)
+{
+    D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO;
+
+    switch (glBlend)
+    {
+      case GL_ZERO:                     d3dBlend = D3D11_BLEND_ZERO;                break;
+      case GL_ONE:                      d3dBlend = D3D11_BLEND_ONE;                 break;
+      case GL_SRC_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR);           break;
+      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR);   break;
+      case GL_DST_COLOR:                d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR);         break;
+      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break;
+      case GL_SRC_ALPHA:                d3dBlend = D3D11_BLEND_SRC_ALPHA;           break;
+      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3D11_BLEND_INV_SRC_ALPHA;       break;
+      case GL_DST_ALPHA:                d3dBlend = D3D11_BLEND_DEST_ALPHA;          break;
+      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3D11_BLEND_INV_DEST_ALPHA;      break;
+      case GL_CONSTANT_COLOR:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
+      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
+      case GL_CONSTANT_ALPHA:           d3dBlend = D3D11_BLEND_BLEND_FACTOR;        break;
+      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR;    break;
+      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT;       break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlend;
+}
+
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp)
+{
+    D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD;
+
+    switch (glBlendOp)
+    {
+      case GL_FUNC_ADD:              d3dBlendOp = D3D11_BLEND_OP_ADD;           break;
+      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3D11_BLEND_OP_SUBTRACT;      break;
+      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT;  break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlendOp;
+}
+
+UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+    UINT8 mask = 0;
+    if (red)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_RED;
+    }
+    if (green)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_GREEN;
+    }
+    if (blue)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_BLUE;
+    }
+    if (alpha)
+    {
+        mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA;
+    }
+    return mask;
+}
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode)
+{
+    D3D11_CULL_MODE cull = D3D11_CULL_NONE;
+
+    if (cullEnabled)
+    {
+        switch (cullMode)
+        {
+          case GL_FRONT:            cull = D3D11_CULL_FRONT;    break;
+          case GL_BACK:             cull = D3D11_CULL_BACK;     break;
+          case GL_FRONT_AND_BACK:   cull = D3D11_CULL_NONE;     break;
+          default: UNREACHABLE();
+        }
+    }
+    else
+    {
+        cull = D3D11_CULL_NONE;
+    }
+
+    return cull;
+}
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison)
+{
+    D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER;
+    switch (comparison)
+    {
+      case GL_NEVER:    d3dComp = D3D11_COMPARISON_NEVER;           break;
+      case GL_ALWAYS:   d3dComp = D3D11_COMPARISON_ALWAYS;          break;
+      case GL_LESS:     d3dComp = D3D11_COMPARISON_LESS;            break;
+      case GL_LEQUAL:   d3dComp = D3D11_COMPARISON_LESS_EQUAL;      break;
+      case GL_EQUAL:    d3dComp = D3D11_COMPARISON_EQUAL;           break;
+      case GL_GREATER:  d3dComp = D3D11_COMPARISON_GREATER;         break;
+      case GL_GEQUAL:   d3dComp = D3D11_COMPARISON_GREATER_EQUAL;   break;
+      case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL;       break;
+      default: UNREACHABLE();
+    }
+
+    return d3dComp;
+}
+
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled)
+{
+    return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO;
+}
+
+UINT8 ConvertStencilMask(GLuint stencilmask)
+{
+    return static_cast&lt;UINT8&gt;(stencilmask);
+}
+
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp)
+{
+    D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP;
+
+    switch (stencilOp)
+    {
+      case GL_ZERO:      d3dStencilOp = D3D11_STENCIL_OP_ZERO;      break;
+      case GL_KEEP:      d3dStencilOp = D3D11_STENCIL_OP_KEEP;      break;
+      case GL_REPLACE:   d3dStencilOp = D3D11_STENCIL_OP_REPLACE;   break;
+      case GL_INCR:      d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT;  break;
+      case GL_DECR:      d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT;  break;
+      case GL_INVERT:    d3dStencilOp = D3D11_STENCIL_OP_INVERT;    break;
+      case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR;      break;
+      case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR;      break;
+      default: UNREACHABLE();
+    }
+
+    return d3dStencilOp;
+}
+
+D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy)
+{
+    if (maxAnisotropy &gt; 1.0f)
+    {
+        return D3D11_ENCODE_ANISOTROPIC_FILTER(false);
+    }
+    else
+    {
+        D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT;
+        D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT;
+        switch (minFilter)
+        {
+          case GL_NEAREST:                dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR:                 dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR_MIPMAP_NEAREST:  dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_NEAREST_MIPMAP_LINEAR:  dxMin = D3D11_FILTER_TYPE_POINT;  dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+          case GL_LINEAR_MIPMAP_LINEAR:   dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break;
+          default:                        UNREACHABLE();
+        }
+
+        D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT;
+        switch (magFilter)
+        {
+          case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT;  break;
+          case GL_LINEAR:  dxMag = D3D11_FILTER_TYPE_LINEAR; break;
+          default:         UNREACHABLE();
+        }
+
+        return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false);
+    }
+}
+
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap)
+{
+    switch (wrap)
+    {
+      case GL_REPEAT:          return D3D11_TEXTURE_ADDRESS_WRAP;
+      case GL_CLAMP_TO_EDGE:   return D3D11_TEXTURE_ADDRESS_CLAMP;
+      case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR;
+      default:                 UNREACHABLE();
+    }
+
+    return D3D11_TEXTURE_ADDRESS_WRAP;
+}
+
+FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset)
+{
+    return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast&lt;float&gt;(lodOffset) : -FLT_MAX;
+}
+
+FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset)
+{
+    return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast&lt;float&gt;(lodOffset) : FLT_MAX;
+}
+
+}
+
+namespace d3d11_gl
+{
+
+GLenum ConvertBackBufferFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES;
+      case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA8_OES;
+}
+
+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_UNKNOWN: return GL_NONE;
+      case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16;
+      case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_DEPTH24_STENCIL8_OES;
+}
+
+GLenum ConvertRenderbufferFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+        return GL_BGRA8_EXT;
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+        return GL_RGBA8_OES;
+      case DXGI_FORMAT_D16_UNORM:
+        return GL_DEPTH_COMPONENT16;
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:
+        return GL_DEPTH24_STENCIL8_OES;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA8_OES;
+}
+
+GLenum ConvertTextureInternalFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+        return GL_RGBA8_OES;
+      case DXGI_FORMAT_A8_UNORM:
+        return GL_ALPHA8_EXT;
+      case DXGI_FORMAT_BC1_UNORM:
+        return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+      case DXGI_FORMAT_BC2_UNORM:
+        return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
+      case DXGI_FORMAT_BC3_UNORM:
+        return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
+      case DXGI_FORMAT_R32G32B32A32_FLOAT:
+        return GL_RGBA32F_EXT;
+      case DXGI_FORMAT_R32G32B32_FLOAT:
+        return GL_RGB32F_EXT;
+      case DXGI_FORMAT_R16G16B16A16_FLOAT:
+        return GL_RGBA16F_EXT;
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+        return GL_BGRA8_EXT;
+      case DXGI_FORMAT_R8_UNORM:
+        return GL_R8_EXT;
+      case DXGI_FORMAT_R8G8_UNORM:
+        return GL_RG8_EXT;
+      case DXGI_FORMAT_R16_FLOAT:
+        return GL_R16F_EXT;
+      case DXGI_FORMAT_R16G16_FLOAT:
+        return GL_RG16F_EXT;
+      case DXGI_FORMAT_D16_UNORM:
+        return GL_DEPTH_COMPONENT16;
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:
+        return GL_DEPTH24_STENCIL8_OES;
+      case DXGI_FORMAT_UNKNOWN:
+        return GL_NONE;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA8_OES;
+}
+
+}
+
+namespace gl_d3d11
+{
+
+DXGI_FORMAT ConvertRenderbufferFormat(GLenum format)
+{
+    switch (format)
+    {
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8_OES:
+      case GL_RGB565:
+      case GL_RGB8_OES:
+        return DXGI_FORMAT_R8G8B8A8_UNORM;
+      case GL_BGRA8_EXT:
+        return DXGI_FORMAT_B8G8R8A8_UNORM;
+      case GL_DEPTH_COMPONENT16:
+        return DXGI_FORMAT_D16_UNORM;
+      case GL_STENCIL_INDEX8:
+      case GL_DEPTH24_STENCIL8_OES:
+        return DXGI_FORMAT_D24_UNORM_S8_UINT;
+      default:
+        UNREACHABLE();
+    }
+
+    return DXGI_FORMAT_R8G8B8A8_UNORM;
+}
+
+DXGI_FORMAT ConvertTextureFormat(GLenum internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_RGB565:
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGB8_OES:
+      case GL_RGBA8_OES:
+      case GL_LUMINANCE8_EXT:
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        return DXGI_FORMAT_R8G8B8A8_UNORM;
+      case GL_ALPHA8_EXT:
+        return DXGI_FORMAT_A8_UNORM;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        return DXGI_FORMAT_BC1_UNORM;
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+        return DXGI_FORMAT_BC2_UNORM;
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+        return DXGI_FORMAT_BC3_UNORM;
+      case GL_RGBA32F_EXT:
+      case GL_ALPHA32F_EXT:
+      case GL_LUMINANCE_ALPHA32F_EXT:
+        return DXGI_FORMAT_R32G32B32A32_FLOAT;
+      case GL_RGB32F_EXT:
+      case GL_LUMINANCE32F_EXT:
+        return DXGI_FORMAT_R32G32B32A32_FLOAT;
+      case GL_RGBA16F_EXT:
+      case GL_ALPHA16F_EXT:
+      case GL_LUMINANCE_ALPHA16F_EXT:
+      case GL_RGB16F_EXT:
+      case GL_LUMINANCE16F_EXT:
+        return DXGI_FORMAT_R16G16B16A16_FLOAT;
+      case GL_BGRA8_EXT:
+        return DXGI_FORMAT_B8G8R8A8_UNORM;
+      case GL_R8_EXT:
+        return DXGI_FORMAT_R8_UNORM;
+      case GL_RG8_EXT:
+        return DXGI_FORMAT_R8G8_UNORM;
+      case GL_R16F_EXT:
+        return DXGI_FORMAT_R16_FLOAT;
+      case GL_RG16F_EXT:
+        return DXGI_FORMAT_R16G16_FLOAT;
+      case GL_DEPTH_COMPONENT16:
+        return DXGI_FORMAT_D16_UNORM;
+      case GL_DEPTH_COMPONENT32_OES:
+      case GL_DEPTH24_STENCIL8_OES:
+        return DXGI_FORMAT_D24_UNORM_S8_UINT;
+      case GL_NONE:
+        return DXGI_FORMAT_UNKNOWN;
+      default:
+        UNREACHABLE();
+    }
+
+    return DXGI_FORMAT_R8G8B8A8_UNORM;
+}
+
+}
+
+namespace d3d11
+{
+
+void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v)
+{
+    vertex-&gt;x = x;
+    vertex-&gt;y = y;
+    vertex-&gt;u = u;
+    vertex-&gt;v = v;
+}
+
+void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z,
+                                 const gl::Color &amp;color)
+{
+    vertex-&gt;x = x;
+    vertex-&gt;y = y;
+    vertex-&gt;z = z;
+    vertex-&gt;r = color.red;
+    vertex-&gt;g = color.green;
+    vertex-&gt;b = color.blue;
+    vertex-&gt;a = color.alpha;
+}
+
+size_t ComputePixelSizeBits(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_R1_UNORM:
+        return 1;
+
+      case DXGI_FORMAT_A8_UNORM:
+      case DXGI_FORMAT_R8_SINT:
+      case DXGI_FORMAT_R8_SNORM:
+      case DXGI_FORMAT_R8_TYPELESS:
+      case DXGI_FORMAT_R8_UINT:
+      case DXGI_FORMAT_R8_UNORM:
+        return 8;
+
+      case DXGI_FORMAT_B5G5R5A1_UNORM:
+      case DXGI_FORMAT_B5G6R5_UNORM:
+      case DXGI_FORMAT_D16_UNORM:
+      case DXGI_FORMAT_R16_FLOAT:
+      case DXGI_FORMAT_R16_SINT:
+      case DXGI_FORMAT_R16_SNORM:
+      case DXGI_FORMAT_R16_TYPELESS:
+      case DXGI_FORMAT_R16_UINT:
+      case DXGI_FORMAT_R16_UNORM:
+      case DXGI_FORMAT_R8G8_SINT:
+      case DXGI_FORMAT_R8G8_SNORM:
+      case DXGI_FORMAT_R8G8_TYPELESS:
+      case DXGI_FORMAT_R8G8_UINT:
+      case DXGI_FORMAT_R8G8_UNORM:
+        return 16;
+
+      case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+      case DXGI_FORMAT_B8G8R8X8_UNORM:
+      case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:
+      case DXGI_FORMAT_D32_FLOAT:
+      case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+      case DXGI_FORMAT_G8R8_G8B8_UNORM:
+      case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
+      case DXGI_FORMAT_R10G10B10A2_TYPELESS:
+      case DXGI_FORMAT_R10G10B10A2_UINT:
+      case DXGI_FORMAT_R10G10B10A2_UNORM:
+      case DXGI_FORMAT_R11G11B10_FLOAT:
+      case DXGI_FORMAT_R16G16_FLOAT:
+      case DXGI_FORMAT_R16G16_SINT:
+      case DXGI_FORMAT_R16G16_SNORM:
+      case DXGI_FORMAT_R16G16_TYPELESS:
+      case DXGI_FORMAT_R16G16_UINT:
+      case DXGI_FORMAT_R16G16_UNORM:
+      case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
+      case DXGI_FORMAT_R24G8_TYPELESS:
+      case DXGI_FORMAT_R32_FLOAT:
+      case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
+      case DXGI_FORMAT_R32_SINT:
+      case DXGI_FORMAT_R32_TYPELESS:
+      case DXGI_FORMAT_R32_UINT:
+      case DXGI_FORMAT_R8G8_B8G8_UNORM:
+      case DXGI_FORMAT_R8G8B8A8_SINT:
+      case DXGI_FORMAT_R8G8B8A8_SNORM:
+      case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+      case DXGI_FORMAT_R8G8B8A8_UINT:
+      case DXGI_FORMAT_R8G8B8A8_UNORM:
+      case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+      case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+      case DXGI_FORMAT_B8G8R8A8_UNORM:
+      case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+      case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
+      case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
+      case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
+        return 32;
+
+      case DXGI_FORMAT_R16G16B16A16_FLOAT:
+      case DXGI_FORMAT_R16G16B16A16_SINT:
+      case DXGI_FORMAT_R16G16B16A16_SNORM:
+      case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+      case DXGI_FORMAT_R16G16B16A16_UINT:
+      case DXGI_FORMAT_R16G16B16A16_UNORM:
+      case DXGI_FORMAT_R32G32_FLOAT:
+      case DXGI_FORMAT_R32G32_SINT:
+      case DXGI_FORMAT_R32G32_TYPELESS:
+      case DXGI_FORMAT_R32G32_UINT:
+      case DXGI_FORMAT_R32G8X24_TYPELESS:
+        return 64;
+
+      case DXGI_FORMAT_R32G32B32_FLOAT:
+      case DXGI_FORMAT_R32G32B32_SINT:
+      case DXGI_FORMAT_R32G32B32_TYPELESS:
+      case DXGI_FORMAT_R32G32B32_UINT:
+        return 96;
+
+      case DXGI_FORMAT_R32G32B32A32_FLOAT:
+      case DXGI_FORMAT_R32G32B32A32_SINT:
+      case DXGI_FORMAT_R32G32B32A32_TYPELESS:
+      case DXGI_FORMAT_R32G32B32A32_UINT:
+        return 128;
+
+      case DXGI_FORMAT_BC1_TYPELESS:
+      case DXGI_FORMAT_BC1_UNORM:
+      case DXGI_FORMAT_BC1_UNORM_SRGB:
+      case DXGI_FORMAT_BC4_SNORM:
+      case DXGI_FORMAT_BC4_TYPELESS:
+      case DXGI_FORMAT_BC4_UNORM:
+        return 4;
+
+      case DXGI_FORMAT_BC2_TYPELESS:
+      case DXGI_FORMAT_BC2_UNORM:
+      case DXGI_FORMAT_BC2_UNORM_SRGB:
+      case DXGI_FORMAT_BC3_TYPELESS:
+      case DXGI_FORMAT_BC3_UNORM:
+      case DXGI_FORMAT_BC3_UNORM_SRGB:
+      case DXGI_FORMAT_BC5_SNORM:
+      case DXGI_FORMAT_BC5_TYPELESS:
+      case DXGI_FORMAT_BC5_UNORM:
+      case DXGI_FORMAT_BC6H_SF16:
+      case DXGI_FORMAT_BC6H_TYPELESS:
+      case DXGI_FORMAT_BC6H_UF16:
+      case DXGI_FORMAT_BC7_TYPELESS:
+      case DXGI_FORMAT_BC7_UNORM:
+      case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return 8;
+
+      default:
+        return 0;
+    }
+}
+
+size_t ComputeBlockSizeBits(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_BC1_TYPELESS:
+      case DXGI_FORMAT_BC1_UNORM:
+      case DXGI_FORMAT_BC1_UNORM_SRGB:
+      case DXGI_FORMAT_BC4_SNORM:
+      case DXGI_FORMAT_BC4_TYPELESS:
+      case DXGI_FORMAT_BC4_UNORM:
+      case DXGI_FORMAT_BC2_TYPELESS:
+      case DXGI_FORMAT_BC2_UNORM:
+      case DXGI_FORMAT_BC2_UNORM_SRGB:
+      case DXGI_FORMAT_BC3_TYPELESS:
+      case DXGI_FORMAT_BC3_UNORM:
+      case DXGI_FORMAT_BC3_UNORM_SRGB:
+      case DXGI_FORMAT_BC5_SNORM:
+      case DXGI_FORMAT_BC5_TYPELESS:
+      case DXGI_FORMAT_BC5_UNORM:
+      case DXGI_FORMAT_BC6H_SF16:
+      case DXGI_FORMAT_BC6H_TYPELESS:
+      case DXGI_FORMAT_BC6H_UF16:
+      case DXGI_FORMAT_BC7_TYPELESS:
+      case DXGI_FORMAT_BC7_UNORM:
+      case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return ComputePixelSizeBits(format) * 16;
+      default:
+        UNREACHABLE();
+        return 0;
+    }
+}
+
+bool IsCompressed(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_BC1_TYPELESS:
+      case DXGI_FORMAT_BC1_UNORM:
+      case DXGI_FORMAT_BC1_UNORM_SRGB:
+      case DXGI_FORMAT_BC4_SNORM:
+      case DXGI_FORMAT_BC4_TYPELESS:
+      case DXGI_FORMAT_BC4_UNORM:
+      case DXGI_FORMAT_BC2_TYPELESS:
+      case DXGI_FORMAT_BC2_UNORM:
+      case DXGI_FORMAT_BC2_UNORM_SRGB:
+      case DXGI_FORMAT_BC3_TYPELESS:
+      case DXGI_FORMAT_BC3_UNORM:
+      case DXGI_FORMAT_BC3_UNORM_SRGB:
+      case DXGI_FORMAT_BC5_SNORM:
+      case DXGI_FORMAT_BC5_TYPELESS:
+      case DXGI_FORMAT_BC5_UNORM:
+      case DXGI_FORMAT_BC6H_SF16:
+      case DXGI_FORMAT_BC6H_TYPELESS:
+      case DXGI_FORMAT_BC6H_UF16:
+      case DXGI_FORMAT_BC7_TYPELESS:
+      case DXGI_FORMAT_BC7_UNORM:
+      case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return true;
+      case DXGI_FORMAT_UNKNOWN:
+        UNREACHABLE();
+        return false;
+      default:
+        return false;
+    }
+}
+
+unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_BC1_TYPELESS:
+      case DXGI_FORMAT_BC1_UNORM:
+      case DXGI_FORMAT_BC1_UNORM_SRGB:
+      case DXGI_FORMAT_BC4_SNORM:
+      case DXGI_FORMAT_BC4_TYPELESS:
+      case DXGI_FORMAT_BC4_UNORM:
+      case DXGI_FORMAT_BC2_TYPELESS:
+      case DXGI_FORMAT_BC2_UNORM:
+      case DXGI_FORMAT_BC2_UNORM_SRGB:
+      case DXGI_FORMAT_BC3_TYPELESS:
+      case DXGI_FORMAT_BC3_UNORM:
+      case DXGI_FORMAT_BC3_UNORM_SRGB:
+      case DXGI_FORMAT_BC5_SNORM:
+      case DXGI_FORMAT_BC5_TYPELESS:
+      case DXGI_FORMAT_BC5_UNORM:
+      case DXGI_FORMAT_BC6H_SF16:
+      case DXGI_FORMAT_BC6H_TYPELESS:
+      case DXGI_FORMAT_BC6H_UF16:
+      case DXGI_FORMAT_BC7_TYPELESS:
+      case DXGI_FORMAT_BC7_UNORM:
+      case DXGI_FORMAT_BC7_UNORM_SRGB:
+        return 4;
+      case DXGI_FORMAT_UNKNOWN:
+        UNREACHABLE();
+        return 1;
+      default:
+        return 1;
+    }
+}
+
+bool IsDepthStencilFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
+      case DXGI_FORMAT_D32_FLOAT:
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:
+      case DXGI_FORMAT_D16_UNORM:
+        return true;
+      default:
+        return false;
+    }
+}
+
+DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS;
+      case DXGI_FORMAT_D32_FLOAT:            return DXGI_FORMAT_R32_TYPELESS;
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:    return DXGI_FORMAT_R24G8_TYPELESS;
+      case DXGI_FORMAT_D16_UNORM:            return DXGI_FORMAT_R16_TYPELESS;
+      default: UNREACHABLE();                return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format)
+{
+    switch (format)
+    {
+      case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
+      case DXGI_FORMAT_D32_FLOAT:            return DXGI_FORMAT_R32_UINT;
+      case DXGI_FORMAT_D24_UNORM_S8_UINT:    return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
+      case DXGI_FORMAT_D16_UNORM:            return DXGI_FORMAT_R16_UNORM;
+      default: UNREACHABLE();                return DXGI_FORMAT_UNKNOWN;
+    }
+}
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name)
+{
+#if defined(_DEBUG)
+    return resource-&gt;SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name);
+#else
+    return S_OK;
+#endif
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11renderer11_utilsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,95 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer11_utils.h: Conversion functions and other utility routines
+// specific to the D3D11 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H
+
+#include &quot;libGLESv2/angletypes.h&quot;
+
+namespace gl_d3d11
+{
+
+D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha);
+D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp);
+UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha);
+
+D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode);
+
+D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison);
+D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled);
+UINT8 ConvertStencilMask(GLuint stencilmask);
+D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp);
+
+D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy);
+D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap);
+FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset);
+FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset);
+
+DXGI_FORMAT ConvertRenderbufferFormat(GLenum format);
+DXGI_FORMAT ConvertTextureFormat(GLenum format);
+}
+
+namespace d3d11_gl
+{
+
+GLenum ConvertBackBufferFormat(DXGI_FORMAT format);
+GLenum ConvertDepthStencilFormat(DXGI_FORMAT format);
+GLenum ConvertRenderbufferFormat(DXGI_FORMAT format);
+GLenum ConvertTextureInternalFormat(DXGI_FORMAT format);
+
+}
+
+namespace d3d11
+{
+
+struct PositionTexCoordVertex
+{
+    float x, y;
+    float u, v;
+};
+void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v);
+
+struct PositionDepthColorVertex
+{
+    float x, y, z;
+    float r, g, b, a;
+};
+void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z,
+                                 const gl::Color &amp;color);
+
+size_t ComputePixelSizeBits(DXGI_FORMAT format);
+size_t ComputeBlockSizeBits(DXGI_FORMAT format);
+
+bool IsCompressed(DXGI_FORMAT format);
+unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format);
+
+bool IsDepthStencilFormat(DXGI_FORMAT format);
+DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format);
+DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format);
+
+HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name);
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+    switch (errorCode)
+    {
+      case DXGI_ERROR_DEVICE_HUNG:
+      case DXGI_ERROR_DEVICE_REMOVED:
+      case DXGI_ERROR_DEVICE_RESET:
+      case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
+      case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE:
+        return true;
+      default:
+        return false;
+    }
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/renderer11_utils.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersClear11hlsl"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+void VS_Clear( in float3  inPosition :    POSITION,  in float4  inColor : COLOR,
+              out float4 outPosition : SV_POSITION, out float4 outColor : COLOR)
+{
+    outPosition = float4(inPosition, 1.0f);
+    outColor = inColor;
+}
+
+// Assume we are in SM4+, which has 8 color outputs
+struct PS_OutputMultiple
+{
+        float4 color0 : SV_TARGET0;
+        float4 color1 : SV_TARGET1;
+        float4 color2 : SV_TARGET2;
+        float4 color3 : SV_TARGET3;
+        float4 color4 : SV_TARGET4;
+        float4 color5 : SV_TARGET5;
+        float4 color6 : SV_TARGET6;
+        float4 color7 : SV_TARGET7;
+};
+
+PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR)
+{
+        PS_OutputMultiple outColor;
+        outColor.color0 = inColor;
+        outColor.color1 = inColor;
+        outColor.color2 = inColor;
+        outColor.color3 = inColor;
+        outColor.color4 = inColor;
+        outColor.color5 = inColor;
+        outColor.color6 = inColor;
+        outColor.color7 = inColor;
+        return outColor;
+}
+
+float4 PS_ClearSingle(in float4 inPosition : SV_Position, in float4 inColor : COLOR) : SV_Target0
+{
+        return inColor;
+}
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersPassthrough11hlsl"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+Texture2D Texture : register(t0);
+SamplerState Sampler : register(s0);
+
+void VS_Passthrough( in float2  inPosition :    POSITION,  in float2  inTexCoord : TEXCOORD0,
+                    out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0)
+{
+    outPosition = float4(inPosition, 0.0f, 1.0f);
+    outTexCoord = inTexCoord;
+}
+
+float4 PS_PassthroughRGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return Texture.Sample(Sampler, inTexCoord).rgba;
+}
+
+float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f);
+}
+
+float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f);
+}
+
+float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0
+{
+    return Texture.Sample(Sampler, inTexCoord).rrra;
+}
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclear11vsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,131 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xyz         0     NONE   float   xyz 
+// COLOR                    0   xyzw        1     NONE   float   xyzw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// COLOR                    0   xyzw        1     NONE   float   xyzw
+//
+vs_4_0
+dcl_input v0.xyz
+dcl_input v1.xyzw
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xyzw
+mov o0.xyz, v0.xyzx
+mov o0.w, l(1.000000)
+mov o1.xyzw, v1.xyzw
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Clear[] =
+{
+     68,  88,  66,  67,  97,   5, 
+     13, 163, 160, 254,  95, 127, 
+     30, 194, 121, 144, 236, 185, 
+     59,  29,   1,   0,   0,   0, 
+     48,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 220,   0, 
+      0,   0,  48,   1,   0,   0, 
+    180,   1,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  51, 
+     48,  46,  57,  50,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     72,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   7,   7,   0,   0, 
+     65,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,  15,  15,   0,   0, 
+     80,  79,  83,  73,  84,  73, 
+     79,  78,   0,  67,  79,  76, 
+     79,  82,   0, 171,  79,  83, 
+     71,  78,  76,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  67,  79,  76,  79, 
+     82,   0, 171, 171,  83,  72, 
+     68,  82, 124,   0,   0,   0, 
+     64,   0,   1,   0,  31,   0, 
+      0,   0,  95,   0,   0,   3, 
+    114,  16,  16,   0,   0,   0, 
+      0,   0,  95,   0,   0,   3, 
+    242,  16,  16,   0,   1,   0, 
+      0,   0, 103,   0,   0,   4, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   1,   0,   0,   0, 
+     54,   0,   0,   5, 114,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70,  18,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      1,   0,   0,   0,  70,  30, 
+     16,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   4,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclearmultiple11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,196 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// COLOR                    0   xyzw        1     NONE   float   xyzw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+// SV_TARGET                1   xyzw        1   TARGET   float   xyzw
+// SV_TARGET                2   xyzw        2   TARGET   float   xyzw
+// SV_TARGET                3   xyzw        3   TARGET   float   xyzw
+// SV_TARGET                4   xyzw        4   TARGET   float   xyzw
+// SV_TARGET                5   xyzw        5   TARGET   float   xyzw
+// SV_TARGET                6   xyzw        6   TARGET   float   xyzw
+// SV_TARGET                7   xyzw        7   TARGET   float   xyzw
+//
+ps_4_0
+dcl_input_ps linear v1.xyzw
+dcl_output o0.xyzw
+dcl_output o1.xyzw
+dcl_output o2.xyzw
+dcl_output o3.xyzw
+dcl_output o4.xyzw
+dcl_output o5.xyzw
+dcl_output o6.xyzw
+dcl_output o7.xyzw
+mov o0.xyzw, v1.xyzw
+mov o1.xyzw, v1.xyzw
+mov o2.xyzw, v1.xyzw
+mov o3.xyzw, v1.xyzw
+mov o4.xyzw, v1.xyzw
+mov o5.xyzw, v1.xyzw
+mov o6.xyzw, v1.xyzw
+mov o7.xyzw, v1.xyzw
+ret 
+// Approximately 9 instruction slots used
+#endif
+
+const BYTE g_PS_ClearMultiple[] =
+{
+     68,  88,  66,  67,  92,  54, 
+    120, 105, 166, 196, 132, 158, 
+    209,  33, 185, 122,   8, 189, 
+    145, 114,   1,   0,   0,   0, 
+     88,   3,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 224,   0, 
+      0,   0, 188,   1,   0,   0, 
+    220,   2,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  51, 
+     48,  46,  57,  50,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     76,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,  15,  15,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     67,  79,  76,  79,  82,   0, 
+    171, 171,  79,  83,  71,  78, 
+    212,   0,   0,   0,   8,   0, 
+      0,   0,   8,   0,   0,   0, 
+    200,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   3,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   4,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   5,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   5,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   6,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   6,   0, 
+      0,   0,  15,   0,   0,   0, 
+    200,   0,   0,   0,   7,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   7,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82,  24,   1, 
+      0,   0,  64,   0,   0,   0, 
+     70,   0,   0,   0,  98,  16, 
+      0,   3, 242,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      3,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      4,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      5,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      6,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      7,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  30, 
+     16,   0,   1,   0,   0,   0, 
+     54,   0,   0,   5, 242,  32, 
+     16,   0,   1,   0,   0,   0, 
+     70,  30,  16,   0,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+    242,  32,  16,   0,   2,   0, 
+      0,   0,  70,  30,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      3,   0,   0,   0,  70,  30, 
+     16,   0,   1,   0,   0,   0, 
+     54,   0,   0,   5, 242,  32, 
+     16,   0,   4,   0,   0,   0, 
+     70,  30,  16,   0,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+    242,  32,  16,   0,   5,   0, 
+      0,   0,  70,  30,  16,   0, 
+      1,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      6,   0,   0,   0,  70,  30, 
+     16,   0,   1,   0,   0,   0, 
+     54,   0,   0,   5, 242,  32, 
+     16,   0,   7,   0,   0,   0, 
+     70,  30,  16,   0,   1,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   9,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   9,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      9,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledclearsingle11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,110 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// COLOR                    0   xyzw        1     NONE   float   xyzw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_input_ps linear v1.xyzw
+dcl_output o0.xyzw
+mov o0.xyzw, v1.xyzw
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_ClearSingle[] =
+{
+     68,  88,  66,  67,  13, 152, 
+     32,  49, 222, 236,  92,  20, 
+    188,  71,  88,  46, 163, 241, 
+    188, 238,   1,   0,   0,   0, 
+    208,   1,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 224,   0, 
+      0,   0,  20,   1,   0,   0, 
+     84,   1,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  51, 
+     48,  46,  57,  50,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     76,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,  15,  15,   0,   0, 
+     83,  86,  95,  80, 111, 115, 
+    105, 116, 105, 111, 110,   0, 
+     67,  79,  76,  79,  82,   0, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  97, 114, 
+    103, 101, 116,   0, 171, 171, 
+     83,  72,  68,  82,  56,   0, 
+      0,   0,  64,   0,   0,   0, 
+     14,   0,   0,   0,  98,  16, 
+      0,   3, 242,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  30, 
+     16,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthrough11vsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,134 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xy          0     NONE   float   xy  
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+vs_4_0
+dcl_input v0.xy
+dcl_input v1.xy
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xy
+mov o0.xy, v0.xyxx
+mov o0.zw, l(0,0,0,1.000000)
+mov o1.xy, v1.xyxx
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_VS_Passthrough[] =
+{
+     68,  88,  66,  67, 197, 214, 
+    184,  85, 240,  94,  71,  48, 
+    165,  34, 142, 233,   0, 135, 
+    193, 178,   1,   0,   0,   0, 
+     68,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    140,   0,   0,   0, 224,   0, 
+      0,   0,  56,   1,   0,   0, 
+    200,   1,   0,   0,  82,  68, 
+     69,  70,  80,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    254, 255,   0,   1,   0,   0, 
+     28,   0,   0,   0,  77, 105, 
+     99, 114, 111, 115, 111, 102, 
+    116,  32,  40,  82,  41,  32, 
+     72,  76,  83,  76,  32,  83, 
+    104,  97, 100, 101, 114,  32, 
+     67, 111, 109, 112, 105, 108, 
+    101, 114,  32,  57,  46,  51, 
+     48,  46,  57,  50,  48,  48, 
+     46,  49,  54,  51,  56,  52, 
+      0, 171,  73,  83,  71,  78, 
+     76,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   3,   3,   0,   0, 
+     65,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,   3,   0,   0, 
+     80,  79,  83,  73,  84,  73, 
+     79,  78,   0,  84,  69,  88, 
+     67,  79,  79,  82,  68,   0, 
+    171, 171,  79,  83,  71,  78, 
+     80,   0,   0,   0,   2,   0, 
+      0,   0,   8,   0,   0,   0, 
+     56,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     68,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   3,  12,   0,   0, 
+     83,  86,  95,  80,  79,  83, 
+     73,  84,  73,  79,  78,   0, 
+     84,  69,  88,  67,  79,  79, 
+     82,  68,   0, 171, 171, 171, 
+     83,  72,  68,  82, 136,   0, 
+      0,   0,  64,   0,   1,   0, 
+     34,   0,   0,   0,  95,   0, 
+      0,   3,  50,  16,  16,   0, 
+      0,   0,   0,   0,  95,   0, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0, 103,   0, 
+      0,   4, 242,  32,  16,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+     50,  32,  16,   0,   1,   0, 
+      0,   0,  54,   0,   0,   5, 
+     50,  32,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   8, 194,  32,  16,   0, 
+      0,   0,   0,   0,   2,  64, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 128,  63, 
+     54,   0,   0,   5,  50,  32, 
+     16,   0,   1,   0,   0,   0, 
+     70,  16,  16,   0,   1,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      4,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughlum11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// Texture                           texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyz, r0.xxxx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLum[] =
+{
+     68,  88,  66,  67, 244,   9, 
+    213, 147,  19, 249,  70, 111, 
+    157,  92, 243, 160,  40, 144, 
+    238, 221,   1,   0,   0,   0, 
+    128,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0,  52,   1, 
+      0,   0, 104,   1,   0,   0, 
+      4,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    108,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  57, 
+     46,  51,  48,  46,  57,  50, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 148,   0, 
+      0,   0,  64,   0,   0,   0, 
+     37,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 114,  32,  16,   0, 
+      0,   0,   0,   0,   6,   0, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   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,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughlumalpha11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,148 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// Texture                           texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyzw, r0.xxxw
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughLumAlpha[] =
+{
+     68,  88,  66,  67, 185,  14, 
+     84, 223, 192,  42,  16, 133, 
+     46, 100,  95, 221, 183,  97, 
+    192,  23,   1,   0,   0,   0, 
+    108,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0,  52,   1, 
+      0,   0, 104,   1,   0,   0, 
+    240,   1,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    108,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  57, 
+     46,  51,  48,  46,  57,  50, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 128,   0, 
+      0,   0,  64,   0,   0,   0, 
+     32,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,  12, 
+     16,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      3,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      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,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughrgb11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,152 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// Texture                           texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mov o0.xyz, r0.xyzx
+mov o0.w, l(1.000000)
+ret 
+// Approximately 4 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGB[] =
+{
+     68,  88,  66,  67, 125, 186, 
+    250, 242, 113, 255,  59, 239, 
+    119, 158, 237,  78, 220,  43, 
+    160,  46,   1,   0,   0,   0, 
+    128,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0,  52,   1, 
+      0,   0, 104,   1,   0,   0, 
+      4,   2,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    108,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  57, 
+     46,  51,  48,  46,  57,  50, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 148,   0, 
+      0,   0,  64,   0,   0,   0, 
+     37,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      1,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5, 114,  32,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5, 130,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   4,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   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,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shaderscompiledpassthroughrgba11psh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,141 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+//
+///
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Sampler                           sampler      NA          NA    0        1
+// Texture                           texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_POSITION              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_TARGET                0   xyzw        0   TARGET   float   xyzw
+//
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+sample o0.xyzw, v1.xyxx, t0.xyzw, s0
+ret 
+// Approximately 2 instruction slots used
+#endif
+
+const BYTE g_PS_PassthroughRGBA[] =
+{
+     68,  88,  66,  67, 151, 152, 
+      8, 102, 174, 135,  76,  57, 
+    100, 146,  59,  74, 205,  35, 
+    206,  21,   1,   0,   0,   0, 
+     80,   2,   0,   0,   5,   0, 
+      0,   0,  52,   0,   0,   0, 
+    220,   0,   0,   0,  52,   1, 
+      0,   0, 104,   1,   0,   0, 
+    212,   1,   0,   0,  82,  68, 
+     69,  70, 160,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     28,   0,   0,   0,   0,   4, 
+    255, 255,   0,   1,   0,   0, 
+    108,   0,   0,   0,  92,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   0,   0, 
+    100,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   0,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0,  83,  97, 109, 112, 
+    108, 101, 114,   0,  84, 101, 
+    120, 116, 117, 114, 101,   0, 
+     77, 105,  99, 114, 111, 115, 
+    111, 102, 116,  32,  40,  82, 
+     41,  32,  72,  76,  83,  76, 
+     32,  83, 104,  97, 100, 101, 
+    114,  32,  67, 111, 109, 112, 
+    105, 108, 101, 114,  32,  57, 
+     46,  51,  48,  46,  57,  50, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
+     71,  78,  80,   0,   0,   0, 
+      2,   0,   0,   0,   8,   0, 
+      0,   0,  56,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  68,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   3,   3, 
+      0,   0,  83,  86,  95,  80, 
+     79,  83,  73,  84,  73,  79, 
+     78,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0, 171, 
+    171, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  65,  82, 
+     71,  69,  84,   0, 171, 171, 
+     83,  72,  68,  82, 100,   0, 
+      0,   0,  64,   0,   0,   0, 
+     25,   0,   0,   0,  90,   0, 
+      0,   3,   0,  96,  16,   0, 
+      0,   0,   0,   0,  88,  24, 
+      0,   4,   0, 112,  16,   0, 
+      0,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   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,   1,   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,   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
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d11shadersgenerate_shadersbat"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,18 @@
</span><ins>+@ECHO OFF
+REM
+REM Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+REM Use of this source code is governed by a BSD-style license that can be
+REM found in the LICENSE file.
+REM
+
+PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.0\bin\x86;%DXSDK_DIR%\Utilities\bin\x86
+
+fxc /E VS_Passthrough /T vs_4_0 /Fh compiled/passthrough11vs.h Passthrough11.hlsl
+fxc /E PS_PassthroughRGBA /T ps_4_0 /Fh compiled/passthroughrgba11ps.h Passthrough11.hlsl
+fxc /E PS_PassthroughRGB /T ps_4_0 /Fh compiled/passthroughrgb11ps.h Passthrough11.hlsl
+fxc /E PS_PassthroughLum /T ps_4_0 /Fh compiled/passthroughlum11ps.h Passthrough11.hlsl
+fxc /E PS_PassthroughLumAlpha /T ps_4_0 /Fh compiled/passthroughlumalpha11ps.h Passthrough11.hlsl
+
+fxc /E VS_Clear /T vs_4_0 /Fh compiled/clear11vs.h Clear11.hlsl
+fxc /E PS_ClearSingle /T ps_4_0 /Fh compiled/clearsingle11ps.h Clear11.hlsl
+fxc /E PS_ClearMultiple /T ps_4_0 /Fh compiled/clearmultiple11ps.h Clear11.hlsl
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d11/shaders/generate_shaders.bat
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Blitcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,595 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// 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.
+//
+
+// Blit.cpp: Surface copy utility class.
+
+#include &quot;libGLESv2/renderer/d3d9/Blit.h&quot;
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/TextureStorage9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/RenderTarget9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+
+namespace
+{
+#include &quot;libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h&quot;
+
+const BYTE* const g_shaderCode[] =
+{
+    g_vs20_standardvs,
+    g_vs20_flipyvs,
+    g_ps20_passthroughps,
+    g_ps20_luminanceps,
+    g_ps20_componentmaskps
+};
+
+const size_t g_shaderSize[] =
+{
+    sizeof(g_vs20_standardvs),
+    sizeof(g_vs20_flipyvs),
+    sizeof(g_ps20_passthroughps),
+    sizeof(g_ps20_luminanceps),
+    sizeof(g_ps20_componentmaskps)
+};
+}
+
+namespace rx
+{
+Blit::Blit(rx::Renderer9 *renderer)
+  : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL)
+{
+    initGeometry();
+    memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
+}
+
+Blit::~Blit()
+{
+    if (mSavedStateBlock) mSavedStateBlock-&gt;Release();
+    if (mQuadVertexBuffer) mQuadVertexBuffer-&gt;Release();
+    if (mQuadVertexDeclaration) mQuadVertexDeclaration-&gt;Release();
+
+    for (int i = 0; i &lt; SHADER_COUNT; i++)
+    {
+        if (mCompiledShaders[i])
+        {
+            mCompiledShaders[i]-&gt;Release();
+        }
+    }
+}
+
+void Blit::initGeometry()
+{
+    static const float quad[] =
+    {
+        -1, -1,
+        -1,  1,
+         1, -1,
+         1,  1
+    };
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    HRESULT result = device-&gt;CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &amp;mQuadVertexBuffer, NULL);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    void *lockPtr = NULL;
+    result = mQuadVertexBuffer-&gt;Lock(0, 0, &amp;lockPtr, 0);
+
+    if (FAILED(result) || lockPtr == NULL)
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    memcpy(lockPtr, quad, sizeof(quad));
+    mQuadVertexBuffer-&gt;Unlock();
+
+    static const D3DVERTEXELEMENT9 elements[] =
+    {
+        { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
+        D3DDECL_END()
+    };
+
+    result = device-&gt;CreateVertexDeclaration(elements, &amp;mQuadVertexDeclaration);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+}
+
+template &lt;class D3DShaderType&gt;
+bool Blit::setShader(ShaderId source, const char *profile,
+                     D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length),
+                     HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*))
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    D3DShaderType *shader;
+
+    if (mCompiledShaders[source] != NULL)
+    {
+        shader = static_cast&lt;D3DShaderType*&gt;(mCompiledShaders[source]);
+    }
+    else
+    {
+        const BYTE* shaderCode = g_shaderCode[source];
+        size_t shaderSize = g_shaderSize[source];
+
+        shader = (mRenderer-&gt;*createShader)(reinterpret_cast&lt;const DWORD*&gt;(shaderCode), shaderSize);
+        if (!shader)
+        {
+            ERR(&quot;Failed to create shader for blit operation&quot;);
+            return false;
+        }
+
+        mCompiledShaders[source] = shader;
+    }
+
+    HRESULT hr = (device-&gt;*setShader)(shader);
+
+    if (FAILED(hr))
+    {
+        ERR(&quot;Failed to set shader for blit operation&quot;);
+        return false;
+    }
+
+    return true;
+}
+
+bool Blit::setVertexShader(ShaderId shader)
+{
+    return setShader&lt;IDirect3DVertexShader9&gt;(shader, &quot;vs_2_0&quot;, &amp;rx::Renderer9::createVertexShader, &amp;IDirect3DDevice9::SetVertexShader);
+}
+
+bool Blit::setPixelShader(ShaderId shader)
+{
+    return setShader&lt;IDirect3DPixelShader9&gt;(shader, &quot;ps_2_0&quot;, &amp;rx::Renderer9::createPixelShader, &amp;IDirect3DDevice9::SetPixelShader);
+}
+
+RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
+{
+    D3DSURFACE_DESC desc;
+    surface-&gt;GetDesc(&amp;desc);
+
+    RECT rect;
+    rect.left = 0;
+    rect.top = 0;
+    rect.right = desc.Width;
+    rect.bottom = desc.Height;
+
+    return rect;
+}
+
+bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+{
+    IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source));
+    if (!texture)
+    {
+        return false;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    saveState();
+
+    device-&gt;SetTexture(0, texture);
+    device-&gt;SetRenderTarget(0, dest);
+
+    setVertexShader(SHADER_VS_STANDARD);
+    setPixelShader(SHADER_PS_PASSTHROUGH);
+
+    setCommonBlitState();
+    device-&gt;SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
+    device-&gt;SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
+
+    setViewport(getSurfaceRect(dest), 0, 0);
+
+    render();
+
+    texture-&gt;Release();
+
+    restoreState();
+
+    return true;
+}
+
+bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+    RenderTarget9 *renderTarget = NULL;
+    IDirect3DSurface9 *source = NULL;
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getColorbuffer(0);
+
+    if (colorbuffer)
+    {
+        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer-&gt;getRenderTarget());
+    }
+    
+    if (renderTarget)
+    {
+        source = renderTarget-&gt;getSurface();
+    }
+
+    if (!source)
+    {
+        ERR(&quot;Failed to retrieve the render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage-&gt;getStorageInstance());
+    IDirect3DSurface9 *destSurface = storage9-&gt;getSurfaceLevel(level, true);
+    bool result = false;
+        
+    if (destSurface)
+    {
+        result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+        destSurface-&gt;Release();
+    }
+
+    source-&gt;Release();
+    return result;
+}
+
+bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+    RenderTarget9 *renderTarget = NULL;
+    IDirect3DSurface9 *source = NULL;
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getColorbuffer(0);
+
+    if (colorbuffer)
+    {
+        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer-&gt;getRenderTarget());
+    }
+    
+    if (renderTarget)
+    {
+        source = renderTarget-&gt;getSurface();
+    }
+
+    if (!source)
+    {
+        ERR(&quot;Failed to retrieve the render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY, false);
+    }
+
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage-&gt;getStorageInstance());
+    IDirect3DSurface9 *destSurface = storage9-&gt;getCubeMapSurface(target, level, true);
+    bool result = false;
+
+    if (destSurface)
+    {
+        result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
+        destSurface-&gt;Release();
+    }
+
+    source-&gt;Release();
+    return result;
+}
+
+bool Blit::copy(IDirect3DSurface9 *source, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+{
+    if (!dest)
+    {
+        return false;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    D3DSURFACE_DESC sourceDesc;
+    D3DSURFACE_DESC destDesc;
+    source-&gt;GetDesc(&amp;sourceDesc);
+    dest-&gt;GetDesc(&amp;destDesc);
+
+    if (sourceDesc.Format == destDesc.Format &amp;&amp; destDesc.Usage &amp; D3DUSAGE_RENDERTARGET &amp;&amp;
+        d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat))   // Can use StretchRect
+    {
+        RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)};
+        HRESULT result = device-&gt;StretchRect(source, &amp;sourceRect, dest, &amp;destRect, D3DTEXF_POINT);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+    }
+    else
+    {
+        return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
+    }
+    return true;
+}
+
+bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
+{
+    IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect);
+    if (!texture)
+    {
+        return false;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    saveState();
+
+    device-&gt;SetTexture(0, texture);
+    device-&gt;SetRenderTarget(0, dest);
+
+    setViewport(sourceRect, xoffset, yoffset);
+
+    setCommonBlitState();
+    if (setFormatConvertShaders(destFormat))
+    {
+        render();
+    }
+
+    texture-&gt;Release();
+
+    restoreState();
+
+    return true;
+}
+
+bool Blit::setFormatConvertShaders(GLenum destFormat)
+{
+    bool okay = setVertexShader(SHADER_VS_STANDARD);
+
+    switch (destFormat)
+    {
+      default: UNREACHABLE();
+      case GL_RGBA:
+      case GL_BGRA_EXT:
+      case GL_RGB:
+      case GL_ALPHA:
+        okay = okay &amp;&amp; setPixelShader(SHADER_PS_COMPONENTMASK);
+        break;
+
+      case GL_LUMINANCE:
+      case GL_LUMINANCE_ALPHA:
+        okay = okay &amp;&amp; setPixelShader(SHADER_PS_LUMINANCE);
+        break;
+    }
+
+    if (!okay)
+    {
+        return false;
+    }
+
+    enum { X = 0, Y = 1, Z = 2, W = 3 };
+
+    // The meaning of this constant depends on the shader that was selected.
+    // See the shader assembly code above for details.
+    float psConst0[4] = { 0, 0, 0, 0 };
+
+    switch (destFormat)
+    {
+      default: UNREACHABLE();
+      case GL_RGBA:
+      case GL_BGRA_EXT:
+        psConst0[X] = 1;
+        psConst0[Z] = 1;
+        break;
+
+      case GL_RGB:
+        psConst0[X] = 1;
+        psConst0[W] = 1;
+        break;
+
+      case GL_ALPHA:
+        psConst0[Z] = 1;
+        break;
+
+      case GL_LUMINANCE:
+        psConst0[Y] = 1;
+        break;
+
+      case GL_LUMINANCE_ALPHA:
+        psConst0[X] = 1;
+        break;
+    }
+
+    mRenderer-&gt;getDevice()-&gt;SetPixelShaderConstantF(0, psConst0, 1);
+
+    return true;
+}
+
+IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &amp;sourceRect)
+{
+    if (!surface)
+    {
+        return NULL;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    D3DSURFACE_DESC sourceDesc;
+    surface-&gt;GetDesc(&amp;sourceDesc);
+
+    // Copy the render target into a texture
+    IDirect3DTexture9 *texture;
+    HRESULT result = device-&gt;CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &amp;texture, NULL);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+    }
+
+    IDirect3DSurface9 *textureSurface;
+    result = texture-&gt;GetSurfaceLevel(0, &amp;textureSurface);
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        texture-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+    }
+
+    mRenderer-&gt;endScene();
+    result = device-&gt;StretchRect(surface, &amp;sourceRect, textureSurface, NULL, D3DTEXF_NONE);
+
+    textureSurface-&gt;Release();
+
+    if (FAILED(result))
+    {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+        texture-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL);
+    }
+
+    return texture;
+}
+
+void Blit::setViewport(const RECT &amp;sourceRect, GLint xoffset, GLint yoffset)
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    D3DVIEWPORT9 vp;
+    vp.X      = xoffset;
+    vp.Y      = yoffset;
+    vp.Width  = sourceRect.right - sourceRect.left;
+    vp.Height = sourceRect.bottom - sourceRect.top;
+    vp.MinZ   = 0.0f;
+    vp.MaxZ   = 1.0f;
+    device-&gt;SetViewport(&amp;vp);
+
+    float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
+    device-&gt;SetVertexShaderConstantF(0, halfPixelAdjust, 1);
+}
+
+void Blit::setCommonBlitState()
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    device-&gt;SetDepthStencilSurface(NULL);
+
+    device-&gt;SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+    device-&gt;SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+    device-&gt;SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+    device-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
+    device-&gt;SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+
+    device-&gt;SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+    device-&gt;SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+    device-&gt;SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
+    device-&gt;SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+    device-&gt;SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+
+    RECT scissorRect = {0};   // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle
+    device-&gt;SetScissorRect(&amp;scissorRect);
+
+    for(int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        device-&gt;SetStreamSourceFreq(i, 1);
+    }
+}
+
+void Blit::render()
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    HRESULT hr = device-&gt;SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float));
+    hr = device-&gt;SetVertexDeclaration(mQuadVertexDeclaration);
+
+    mRenderer-&gt;startScene();
+    hr = device-&gt;DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
+}
+
+void Blit::saveState()
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    HRESULT hr;
+
+    device-&gt;GetDepthStencilSurface(&amp;mSavedDepthStencil);
+    device-&gt;GetRenderTarget(0, &amp;mSavedRenderTarget);
+
+    if (mSavedStateBlock == NULL)
+    {
+        hr = device-&gt;BeginStateBlock();
+        ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+
+        setCommonBlitState();
+
+        static const float dummyConst[4] = { 0, 0, 0, 0 };
+
+        device-&gt;SetVertexShader(NULL);
+        device-&gt;SetVertexShaderConstantF(0, dummyConst, 1);
+        device-&gt;SetPixelShader(NULL);
+        device-&gt;SetPixelShaderConstantF(0, dummyConst, 1);
+
+        D3DVIEWPORT9 dummyVp;
+        dummyVp.X = 0;
+        dummyVp.Y = 0;
+        dummyVp.Width = 1;
+        dummyVp.Height = 1;
+        dummyVp.MinZ = 0;
+        dummyVp.MaxZ = 1;
+
+        device-&gt;SetViewport(&amp;dummyVp);
+
+        device-&gt;SetTexture(0, NULL);
+
+        device-&gt;SetStreamSource(0, mQuadVertexBuffer, 0, 0);
+
+        device-&gt;SetVertexDeclaration(mQuadVertexDeclaration);
+
+        hr = device-&gt;EndStateBlock(&amp;mSavedStateBlock);
+        ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+    }
+
+    ASSERT(mSavedStateBlock != NULL);
+
+    if (mSavedStateBlock != NULL)
+    {
+        hr = mSavedStateBlock-&gt;Capture();
+        ASSERT(SUCCEEDED(hr));
+    }
+}
+
+void Blit::restoreState()
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    device-&gt;SetDepthStencilSurface(mSavedDepthStencil);
+    if (mSavedDepthStencil != NULL)
+    {
+        mSavedDepthStencil-&gt;Release();
+        mSavedDepthStencil = NULL;
+    }
+
+    device-&gt;SetRenderTarget(0, mSavedRenderTarget);
+    if (mSavedRenderTarget != NULL)
+    {
+        mSavedRenderTarget-&gt;Release();
+        mSavedRenderTarget = NULL;
+    }
+
+    ASSERT(mSavedStateBlock != NULL);
+
+    if (mSavedStateBlock != NULL)
+    {
+        mSavedStateBlock-&gt;Apply();
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Blith"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+//
+// 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.
+//
+
+// Blit.cpp: Surface copy utility class.
+
+#ifndef LIBGLESV2_BLIT_H_
+#define LIBGLESV2_BLIT_H_
+
+#include &quot;common/angleutils.h&quot;
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer9;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Blit
+{
+  public:
+    explicit Blit(Renderer9 *renderer);
+    ~Blit();
+
+    // Copy from source surface to dest surface.
+    // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
+    bool copy(gl::Framebuffer *framebuffer, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+    bool copy(gl::Framebuffer *framebuffer, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+
+    // Copy from source surface to dest surface.
+    // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
+    // 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 &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+
+    // 2x2 box filter sample from source to dest.
+    // Requires that source is RGB(A) and dest has the same format as source.
+    bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+
+  private:
+    rx::Renderer9 *mRenderer;
+
+    IDirect3DVertexBuffer9 *mQuadVertexBuffer;
+    IDirect3DVertexDeclaration9 *mQuadVertexDeclaration;
+
+    void initGeometry();
+
+    bool setFormatConvertShaders(GLenum destFormat);
+
+    bool copy(IDirect3DSurface9 *source, const RECT &amp;sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
+    IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &amp;sourceRect);
+    void setViewport(const RECT &amp;sourceRect, GLint xoffset, GLint yoffset);
+    void setCommonBlitState();
+    RECT getSurfaceRect(IDirect3DSurface9 *surface) const;
+
+    // This enum is used to index mCompiledShaders and mShaderSource.
+    enum ShaderId
+    {
+        SHADER_VS_STANDARD,
+        SHADER_VS_FLIPY,
+        SHADER_PS_PASSTHROUGH,
+        SHADER_PS_LUMINANCE,
+        SHADER_PS_COMPONENTMASK,
+        SHADER_COUNT
+    };
+
+    // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown.
+    IUnknown *mCompiledShaders[SHADER_COUNT];
+
+    template &lt;class D3DShaderType&gt;
+    bool setShader(ShaderId source, const char *profile,
+                   D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length),
+                   HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*));
+
+    bool setVertexShader(ShaderId shader);
+    bool setPixelShader(ShaderId shader);
+    void render();
+
+    void saveState();
+    void restoreState();
+    IDirect3DStateBlock9 *mSavedStateBlock;
+    IDirect3DSurface9 *mSavedRenderTarget;
+    IDirect3DSurface9 *mSavedDepthStencil;
+
+    DISALLOW_COPY_AND_ASSIGN(Blit);
+};
+}
+
+#endif   // LIBGLESV2_BLIT_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Blit.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9BufferStorage9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,78 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage9.cpp Defines the BufferStorage9 class.
+
+#include &quot;libGLESv2/renderer/d3d9/BufferStorage9.h&quot;
+#include &quot;common/debug.h&quot;
+
+namespace rx
+{
+
+BufferStorage9::BufferStorage9()
+{
+    mMemory = NULL;
+    mAllocatedSize = 0;
+    mSize = 0;
+}
+
+BufferStorage9::~BufferStorage9()
+{
+    delete[] mMemory;
+}
+
+BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage));
+    return static_cast&lt;BufferStorage9*&gt;(bufferStorage);
+}
+
+void *BufferStorage9::getData()
+{
+    return mMemory;
+}
+
+void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset)
+{
+    if (!mMemory || offset + size &gt; mAllocatedSize)
+    {
+        unsigned int newAllocatedSize = offset + size;
+        void *newMemory = new char[newAllocatedSize];
+
+        if (offset &gt; 0 &amp;&amp; mMemory &amp;&amp; mAllocatedSize &gt; 0)
+        {
+            memcpy(newMemory, mMemory, std::min(offset, mAllocatedSize));
+        }
+
+        delete[] mMemory;
+        mMemory = newMemory;
+        mAllocatedSize = newAllocatedSize;
+    }
+
+    mSize = std::max(mSize, offset + size);
+    if (data)
+    {
+        memcpy(reinterpret_cast&lt;char*&gt;(mMemory) + offset, data, size);
+    }
+}
+
+void BufferStorage9::clear()
+{
+    mSize = 0;
+}
+
+unsigned int BufferStorage9::getSize() const
+{
+    return mSize;
+}
+
+bool BufferStorage9::supportsDirectBinding() const
+{
+    return false;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9BufferStorage9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,42 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// BufferStorage9.h Defines the BufferStorage9 class.
+
+#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
+#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
+
+#include &quot;libGLESv2/renderer/BufferStorage.h&quot;
+
+namespace rx
+{
+
+class BufferStorage9 : public BufferStorage
+{
+  public:
+    BufferStorage9();
+    virtual ~BufferStorage9();
+
+    static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage);
+
+    virtual void *getData();
+    virtual void setData(const void* data, unsigned int size, unsigned int offset);
+    virtual void clear();
+    virtual unsigned int getSize() const;
+    virtual bool supportsDirectBinding() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(BufferStorage9);
+
+    void *mMemory;
+    unsigned int mAllocatedSize;
+
+    unsigned int mSize;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/BufferStorage9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Fence9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,135 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence9.cpp: Defines the rx::Fence9 class.
+
+#include &quot;libGLESv2/renderer/d3d9/Fence9.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+namespace rx
+{
+
+Fence9::Fence9(rx::Renderer9 *renderer)
+{
+    mRenderer = renderer;
+    mQuery = NULL;
+}
+
+Fence9::~Fence9()
+{
+    if (mQuery)
+    {
+        mRenderer-&gt;freeEventQuery(mQuery);
+        mQuery = NULL;
+    }
+}
+
+GLboolean Fence9::isFence()
+{
+    // GL_NV_fence spec:
+    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence.
+    return mQuery != NULL;
+}
+
+void Fence9::setFence(GLenum condition)
+{
+    if (!mQuery)
+    {
+        mQuery = mRenderer-&gt;allocateEventQuery();
+        if (!mQuery)
+        {
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    HRESULT result = mQuery-&gt;Issue(D3DISSUE_END);
+    ASSERT(SUCCEEDED(result));
+
+    setCondition(condition);
+    setStatus(GL_FALSE);
+}
+
+GLboolean Fence9::testFence()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION, GL_TRUE);
+    }
+
+    HRESULT result = mQuery-&gt;GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+    if (d3d9::isDeviceLostError(result))
+    {
+        mRenderer-&gt;notifyDeviceLost();
+        return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+    }
+
+    ASSERT(result == S_OK || result == S_FALSE);
+    setStatus(result == S_OK);
+    return getStatus();
+}
+
+void Fence9::finishFence()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    while (!testFence())
+    {
+        Sleep(0);
+    }
+}
+
+void Fence9::getFenceiv(GLenum pname, GLint *params)
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    switch (pname)
+    {
+        case GL_FENCE_STATUS_NV:
+        {
+            // GL_NV_fence spec:
+            // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV
+            // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
+            if (getStatus())
+            {
+                params[0] = GL_TRUE;
+                return;
+            }
+            
+            HRESULT result = mQuery-&gt;GetData(NULL, 0, 0);
+
+            if (d3d9::isDeviceLostError(result))
+            {
+                params[0] = GL_TRUE;
+                mRenderer-&gt;notifyDeviceLost();
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+
+            ASSERT(result == S_OK || result == S_FALSE);
+            setStatus(result == S_OK);
+            params[0] = getStatus();
+
+            break;
+        }
+        case GL_FENCE_CONDITION_NV:
+            params[0] = getCondition();
+            break;
+        default:
+            return gl::error(GL_INVALID_ENUM);
+            break;
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Fence9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl.
+
+#ifndef LIBGLESV2_RENDERER_FENCE9_H_
+#define LIBGLESV2_RENDERER_FENCE9_H_
+
+#include &quot;libGLESv2/renderer/FenceImpl.h&quot;
+
+namespace rx
+{
+class Renderer9;
+
+class Fence9 : public FenceImpl
+{
+  public:
+    explicit Fence9(rx::Renderer9 *renderer);
+    virtual ~Fence9();
+
+    GLboolean isFence();
+    void setFence(GLenum condition);
+    GLboolean testFence();
+    void finishFence();
+    void getFenceiv(GLenum pname, GLint *params);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Fence9);
+
+    rx::Renderer9 *mRenderer;
+    IDirect3DQuery9 *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_FENCE9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Fence9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Image9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,732 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#include &quot;libGLESv2/renderer/d3d9/Image9.h&quot;
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/RenderTarget9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/TextureStorage9.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/generatemip.h&quot;
+
+namespace rx
+{
+
+Image9::Image9()
+{
+    mSurface = NULL;
+    mRenderer = NULL;
+
+    mD3DPool = D3DPOOL_SYSTEMMEM;
+    mD3DFormat = D3DFMT_UNKNOWN;
+}
+
+Image9::~Image9()
+{
+    if (mSurface)
+    {
+        mSurface-&gt;Release();
+    }
+}
+
+void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface)
+{
+    D3DSURFACE_DESC destDesc;
+    HRESULT result = destSurface-&gt;GetDesc(&amp;destDesc);
+    ASSERT(SUCCEEDED(result));
+
+    D3DSURFACE_DESC sourceDesc;
+    result = sourceSurface-&gt;GetDesc(&amp;sourceDesc);
+    ASSERT(SUCCEEDED(result));
+
+    ASSERT(sourceDesc.Format == destDesc.Format);
+    ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width);
+    ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height);
+
+    D3DLOCKED_RECT sourceLocked = {0};
+    result = sourceSurface-&gt;LockRect(&amp;sourceLocked, NULL, D3DLOCK_READONLY);
+    ASSERT(SUCCEEDED(result));
+
+    D3DLOCKED_RECT destLocked = {0};
+    result = destSurface-&gt;LockRect(&amp;destLocked, NULL, 0);
+    ASSERT(SUCCEEDED(result));
+
+    const unsigned char *sourceData = reinterpret_cast&lt;const unsigned char*&gt;(sourceLocked.pBits);
+    unsigned char *destData = reinterpret_cast&lt;unsigned char*&gt;(destLocked.pBits);
+
+    if (sourceData &amp;&amp; destData)
+    {
+        switch (sourceDesc.Format)
+        {
+          case D3DFMT_L8:
+            GenerateMip&lt;L8&gt;(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+            break;
+          case D3DFMT_A8L8:
+            GenerateMip&lt;A8L8&gt;(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+            break;
+          case D3DFMT_A8R8G8B8:
+          case D3DFMT_X8R8G8B8:
+            GenerateMip&lt;A8R8G8B8&gt;(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+            break;
+          case D3DFMT_A16B16G16R16F:
+            GenerateMip&lt;A16B16G16R16F&gt;(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+            break;
+          case D3DFMT_A32B32G32R32F:
+            GenerateMip&lt;A32B32G32R32F&gt;(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch);
+            break;
+          default:
+            UNREACHABLE();
+            break;
+        }
+
+        destSurface-&gt;UnlockRect();
+        sourceSurface-&gt;UnlockRect();
+    }
+}
+
+Image9 *Image9::makeImage9(Image *img)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img));
+    return static_cast&lt;rx::Image9*&gt;(img);
+}
+
+void Image9::generateMipmap(Image9 *dest, Image9 *source)
+{
+    IDirect3DSurface9 *sourceSurface = source-&gt;getSurface();
+    if (sourceSurface == NULL)
+        return gl::error(GL_OUT_OF_MEMORY);
+
+    IDirect3DSurface9 *destSurface = dest-&gt;getSurface();
+    generateMip(destSurface, sourceSurface);
+
+    dest-&gt;markDirty();
+}
+
+void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source)
+{
+    D3DLOCKED_RECT sourceLock = {0};
+    D3DLOCKED_RECT destLock = {0};
+    
+    source-&gt;LockRect(&amp;sourceLock, NULL, 0);
+    dest-&gt;LockRect(&amp;destLock, NULL, 0);
+    
+    if (sourceLock.pBits &amp;&amp; destLock.pBits)
+    {
+        D3DSURFACE_DESC desc;
+        source-&gt;GetDesc(&amp;desc);
+
+        int rows = d3d9::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height;
+        int bytes = d3d9::ComputeRowSize(desc.Format, desc.Width);
+        ASSERT(bytes &lt;= sourceLock.Pitch &amp;&amp; bytes &lt;= destLock.Pitch);
+
+        for(int i = 0; i &lt; rows; i++)
+        {
+            memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes);
+        }
+
+        source-&gt;UnlockRect();
+        dest-&gt;UnlockRect();
+    }
+    else UNREACHABLE();
+}
+
+bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease)
+{
+    if (mWidth != width ||
+        mHeight != height ||
+        mInternalFormat != internalformat ||
+        forceRelease)
+    {
+        mRenderer = Renderer9::makeRenderer9(renderer);
+
+        mWidth = width;
+        mHeight = height;
+        mInternalFormat = internalformat;
+        // compute the d3d format that will be used
+        mD3DFormat = mRenderer-&gt;ConvertTextureInternalFormat(internalformat);
+        mActualFormat = d3d9_gl::GetEquivalentFormat(mD3DFormat);
+
+        if (mSurface)
+        {
+            mSurface-&gt;Release();
+            mSurface = NULL;
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+void Image9::createSurface()
+{
+    if(mSurface)
+    {
+        return;
+    }
+
+    IDirect3DTexture9 *newTexture = NULL;
+    IDirect3DSurface9 *newSurface = NULL;
+    const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM;
+    const D3DFORMAT d3dFormat = getD3DFormat();
+    ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures
+
+    if (mWidth != 0 &amp;&amp; mHeight != 0)
+    {
+        int levelToFetch = 0;
+        GLsizei requestWidth = mWidth;
+        GLsizei requestHeight = mHeight;
+        gl::MakeValidSize(true, gl::IsCompressed(mInternalFormat), &amp;requestWidth, &amp;requestHeight, &amp;levelToFetch);
+
+        IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+        HRESULT result = device-&gt;CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat,
+                                                    poolToUse, &amp;newTexture, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            ERR(&quot;Creating image surface failed.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        newTexture-&gt;GetSurfaceLevel(levelToFetch, &amp;newSurface);
+        newTexture-&gt;Release();
+    }
+
+    mSurface = newSurface;
+    mDirty = false;
+    mD3DPool = poolToUse;
+}
+
+HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect)
+{
+    createSurface();
+
+    HRESULT result = D3DERR_INVALIDCALL;
+
+    if (mSurface)
+    {
+        result = mSurface-&gt;LockRect(lockedRect, rect, 0);
+        ASSERT(SUCCEEDED(result));
+
+        mDirty = true;
+    }
+
+    return result;
+}
+
+void Image9::unlock()
+{
+    if (mSurface)
+    {
+        HRESULT result = mSurface-&gt;UnlockRect();
+        ASSERT(SUCCEEDED(result));
+    }
+}
+
+bool Image9::isRenderableFormat() const
+{    
+    return TextureStorage9::IsTextureFormatRenderable(getD3DFormat());
+}
+
+D3DFORMAT Image9::getD3DFormat() const
+{
+    // this should only happen if the image hasn't been redefined first
+    // which would be a bug by the caller
+    ASSERT(mD3DFormat != D3DFMT_UNKNOWN);
+
+    return mD3DFormat;
+}
+
+IDirect3DSurface9 *Image9::getSurface()
+{
+    createSurface();
+
+    return mSurface;
+}
+
+void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level)
+{
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage-&gt;getStorageInstance());
+    setManagedSurface(storage9-&gt;getSurfaceLevel(level, false));
+}
+
+void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level)
+{
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage-&gt;getStorageInstance());
+    setManagedSurface(storage9-&gt;getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false));
+}
+
+void Image9::setManagedSurface(IDirect3DSurface9 *surface)
+{
+    D3DSURFACE_DESC desc;
+    surface-&gt;GetDesc(&amp;desc);
+    ASSERT(desc.Pool == D3DPOOL_MANAGED);
+
+    if ((GLsizei)desc.Width == mWidth &amp;&amp; (GLsizei)desc.Height == mHeight)
+    {
+        if (mSurface)
+        {
+            copyLockableSurfaces(surface, mSurface);
+            mSurface-&gt;Release();
+        }
+
+        mSurface = surface;
+        mD3DPool = desc.Pool;
+    }
+}
+
+bool Image9::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    ASSERT(getSurface() != NULL);
+    TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage-&gt;getStorageInstance());
+    return updateSurface(storage9-&gt;getSurfaceLevel(level, true), xoffset, yoffset, width, height);
+}
+
+bool Image9::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    ASSERT(getSurface() != NULL);
+    TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage-&gt;getStorageInstance());
+    return updateSurface(storage9-&gt;getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height);
+}
+
+bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
+{
+    if (!destSurface)
+        return false;
+
+    IDirect3DSurface9 *sourceSurface = getSurface();
+
+    if (sourceSurface &amp;&amp; sourceSurface != destSurface)
+    {
+        RECT rect;
+        rect.left = xoffset;
+        rect.top = yoffset;
+        rect.right = xoffset + width;
+        rect.bottom = yoffset + height;
+
+        POINT point = {rect.left, rect.top};
+
+        IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+        if (mD3DPool == D3DPOOL_MANAGED)
+        {
+            D3DSURFACE_DESC desc;
+            sourceSurface-&gt;GetDesc(&amp;desc);
+
+            IDirect3DSurface9 *surf = 0;
+            HRESULT result = device-&gt;CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &amp;surf, NULL);
+
+            if (SUCCEEDED(result))
+            {
+                copyLockableSurfaces(surf, sourceSurface);
+                result = device-&gt;UpdateSurface(surf, &amp;rect, destSurface, &amp;point);
+                ASSERT(SUCCEEDED(result));
+                surf-&gt;Release();
+            }
+        }
+        else
+        {
+            // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools 
+            HRESULT result = device-&gt;UpdateSurface(sourceSurface, &amp;rect, destSurface, &amp;point);
+            ASSERT(SUCCEEDED(result));
+        }
+    }
+
+    destSurface-&gt;Release();
+    return true;
+}
+
+// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
+// into the target pixel rectangle.
+void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                      GLint unpackAlignment, const void *input)
+{
+    RECT lockRect =
+    {
+        xoffset, yoffset,
+        xoffset + width, yoffset + height
+    };
+
+    D3DLOCKED_RECT locked;
+    HRESULT result = lock(&amp;locked, &amp;lockRect);
+    if (FAILED(result))
+    {
+        return;
+    }
+
+
+    GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment);
+
+    switch (mInternalFormat)
+    {
+      case GL_ALPHA8_EXT:
+        if (gl::supportsSSE2())
+        {
+            loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        else
+        {
+            loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        break;
+      case GL_LUMINANCE8_EXT:
+        loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8);
+        break;
+      case GL_ALPHA32F_EXT:
+        loadAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE32F_EXT:
+        loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_ALPHA16F_EXT:
+        loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE16F_EXT:
+        loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8);
+        break;
+      case GL_LUMINANCE_ALPHA32F_EXT:
+        loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_LUMINANCE_ALPHA16F_EXT:
+        loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB8_OES:
+        loadRGBUByteDataToBGRX(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB565:
+        loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA8_OES:
+        if (gl::supportsSSE2())
+        {
+            loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        else
+        {
+            loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        }
+        break;
+      case GL_RGBA4:
+        loadRGBA4444DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB5_A1:
+        loadRGBA5551DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_BGRA8_EXT:
+        loadBGRADataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D
+      case GL_RGB32F_EXT:
+        loadRGBFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGB16F_EXT:
+        loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA32F_EXT:
+        loadRGBAFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      case GL_RGBA16F_EXT:
+        loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits);
+        break;
+      default: UNREACHABLE(); 
+    }
+
+    unlock();
+}
+
+void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                const void *input)
+{
+    ASSERT(xoffset % 4 == 0);
+    ASSERT(yoffset % 4 == 0);
+
+    RECT lockRect = {
+        xoffset, yoffset,
+        xoffset + width, yoffset + height
+    };
+
+    D3DLOCKED_RECT locked;
+    HRESULT result = lock(&amp;locked, &amp;lockRect);
+    if (FAILED(result))
+    {
+        return;
+    }
+
+    GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat);
+    GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat);
+    int rows = inputSize / inputPitch;
+    for (int i = 0; i &lt; rows; ++i)
+    {
+        memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch);
+    }
+
+    unlock();
+}
+
+// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
+void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source)
+{
+    RenderTarget9 *renderTarget = NULL;
+    IDirect3DSurface9 *surface = NULL;
+    gl::Renderbuffer *colorbuffer = source-&gt;getColorbuffer(0);
+
+    if (colorbuffer)
+    {
+        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer-&gt;getRenderTarget());
+    }
+    
+    if (renderTarget)
+    {
+        surface = renderTarget-&gt;getSurface();
+    }
+
+    if (!surface)
+    {
+        ERR(&quot;Failed to retrieve the render target.&quot;);
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    IDirect3DSurface9 *renderTargetData = NULL;
+    D3DSURFACE_DESC description;
+    surface-&gt;GetDesc(&amp;description);
+    
+    HRESULT result = device-&gt;CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &amp;renderTargetData, NULL);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not create matching destination surface.&quot;);
+        surface-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    result = device-&gt;GetRenderTargetData(surface, renderTargetData);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;GetRenderTargetData unexpectedly failed.&quot;);
+        renderTargetData-&gt;Release();
+        surface-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    RECT sourceRect = {x, y, x + width, y + height};
+    RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height};
+
+    D3DLOCKED_RECT sourceLock = {0};
+    result = renderTargetData-&gt;LockRect(&amp;sourceLock, &amp;sourceRect, 0);
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Failed to lock the source surface (rectangle might be invalid).&quot;);
+        renderTargetData-&gt;Release();
+        surface-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    D3DLOCKED_RECT destLock = {0};
+    result = lock(&amp;destLock, &amp;destRect);
+    
+    if (FAILED(result))
+    {
+        ERR(&quot;Failed to lock the destination surface (rectangle might be invalid).&quot;);
+        renderTargetData-&gt;UnlockRect();
+        renderTargetData-&gt;Release();
+        surface-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    if (destLock.pBits &amp;&amp; sourceLock.pBits)
+    {
+        unsigned char *source = (unsigned char*)sourceLock.pBits;
+        unsigned char *dest = (unsigned char*)destLock.pBits;
+
+        switch (description.Format)
+        {
+          case D3DFMT_X8R8G8B8:
+          case D3DFMT_A8R8G8B8:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_X8R8G8B8:
+              case D3DFMT_A8R8G8B8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    memcpy(dest, source, 4 * width);
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_L8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        dest[x] = source[x * 4 + 2];
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_A8L8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        dest[x * 2 + 0] = source[x * 4 + 2];
+                        dest[x * 2 + 1] = source[x * 4 + 3];
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          case D3DFMT_R5G6B5:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_X8R8G8B8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned short rgb = ((unsigned short*)source)[x];
+                        unsigned char red = (rgb &amp; 0xF800) &gt;&gt; 8;
+                        unsigned char green = (rgb &amp; 0x07E0) &gt;&gt; 3;
+                        unsigned char blue = (rgb &amp; 0x001F) &lt;&lt; 3;
+                        dest[x + 0] = blue | (blue &gt;&gt; 5);
+                        dest[x + 1] = green | (green &gt;&gt; 6);
+                        dest[x + 2] = red | (red &gt;&gt; 5);
+                        dest[x + 3] = 0xFF;
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_L8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] &amp; 0xF8;
+                        dest[x] = red | (red &gt;&gt; 5);
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          case D3DFMT_A1R5G5B5:
+            switch(getD3DFormat())
+            {
+              case D3DFMT_X8R8G8B8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned short argb = ((unsigned short*)source)[x];
+                        unsigned char red = (argb &amp; 0x7C00) &gt;&gt; 7;
+                        unsigned char green = (argb &amp; 0x03E0) &gt;&gt; 2;
+                        unsigned char blue = (argb &amp; 0x001F) &lt;&lt; 3;
+                        dest[x + 0] = blue | (blue &gt;&gt; 5);
+                        dest[x + 1] = green | (green &gt;&gt; 5);
+                        dest[x + 2] = red | (red &gt;&gt; 5);
+                        dest[x + 3] = 0xFF;
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_A8R8G8B8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned short argb = ((unsigned short*)source)[x];
+                        unsigned char red = (argb &amp; 0x7C00) &gt;&gt; 7;
+                        unsigned char green = (argb &amp; 0x03E0) &gt;&gt; 2;
+                        unsigned char blue = (argb &amp; 0x001F) &lt;&lt; 3;
+                        unsigned char alpha = (signed short)argb &gt;&gt; 15;
+                        dest[x + 0] = blue | (blue &gt;&gt; 5);
+                        dest[x + 1] = green | (green &gt;&gt; 5);
+                        dest[x + 2] = red | (red &gt;&gt; 5);
+                        dest[x + 3] = alpha;
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_L8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] &amp; 0x7C;
+                        dest[x] = (red &lt;&lt; 1) | (red &gt;&gt; 4);
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              case D3DFMT_A8L8:
+                for(int y = 0; y &lt; height; y++)
+                {
+                    for(int x = 0; x &lt; width; x++)
+                    {
+                        unsigned char red = source[x * 2 + 1] &amp; 0x7C;
+                        dest[x * 2 + 0] = (red &lt;&lt; 1) | (red &gt;&gt; 4);
+                        dest[x * 2 + 1] = (signed char)source[x * 2 + 1] &gt;&gt; 7;
+                    }
+
+                    source += sourceLock.Pitch;
+                    dest += destLock.Pitch;
+                }
+                break;
+              default:
+                UNREACHABLE();
+            }
+            break;
+          default:
+            UNREACHABLE();
+        }
+    }
+
+    unlock();
+    renderTargetData-&gt;UnlockRect();
+
+    renderTargetData-&gt;Release();
+    surface-&gt;Release();
+
+    mDirty = true;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Image9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Image9.h: Defines the rx::Image9 class, which acts as the interface to
+// the actual underlying surfaces of a Texture.
+
+#ifndef LIBGLESV2_RENDERER_IMAGE9_H_
+#define LIBGLESV2_RENDERER_IMAGE9_H_
+
+#include &quot;libGLESv2/renderer/Image.h&quot;
+#include &quot;common/debug.h&quot;
+
+namespace gl
+{
+class Framebuffer;
+}
+
+namespace rx
+{
+class Renderer;
+class Renderer9;
+class TextureStorageInterface2D;
+class TextureStorageInterfaceCube;
+
+class Image9 : public Image
+{
+  public:
+    Image9();
+    ~Image9();
+
+    static Image9 *makeImage9(Image *img);
+
+    static void generateMipmap(Image9 *dest, Image9 *source);
+    static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface);
+    static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source);
+
+    virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease);
+
+    virtual bool isRenderableFormat() const;
+    D3DFORMAT getD3DFormat() const;
+
+    virtual bool isDirty() const {return mSurface &amp;&amp; mDirty;}
+    IDirect3DSurface9 *getSurface();
+
+    virtual void setManagedSurface(TextureStorageInterface2D *storage, int level);
+    virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level);
+    virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+    virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+    virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                  GLint unpackAlignment, const void *input);
+    virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+                                    const void *input);
+
+    virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Image9);
+
+    void createSurface();
+    void setManagedSurface(IDirect3DSurface9 *surface);
+    bool updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
+
+    HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect);
+    void unlock();
+    
+    Renderer9 *mRenderer;
+
+    D3DPOOL mD3DPool;   // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable.
+    D3DFORMAT mD3DFormat;
+
+    IDirect3DSurface9 *mSurface;
+};
+}
+
+#endif   // LIBGLESV2_RENDERER_IMAGE9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Image9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9IndexBuffer9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,207 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation.
+
+#include &quot;libGLESv2/renderer/d3d9/IndexBuffer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+namespace rx
+{
+
+IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer)
+{
+    mIndexBuffer = NULL;
+    mBufferSize = 0;
+    mIndexType = 0;
+    mDynamic = false;
+}
+
+IndexBuffer9::~IndexBuffer9()
+{
+    if (mIndexBuffer)
+    {
+        mIndexBuffer-&gt;Release();
+        mIndexBuffer = NULL;
+    }
+}
+
+bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic)
+{
+    if (mIndexBuffer)
+    {
+        mIndexBuffer-&gt;Release();
+        mIndexBuffer = NULL;
+    }
+
+    updateSerial();
+
+    if (bufferSize &gt; 0)
+    {
+        D3DFORMAT format;
+        if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE)
+        {
+            format = D3DFMT_INDEX16;
+        }
+        else if (indexType == GL_UNSIGNED_INT)
+        {
+            if (mRenderer-&gt;get32BitIndexSupport())
+            {
+                format = D3DFMT_INDEX32;
+            }
+            else
+            {
+                ERR(&quot;Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices.&quot;);
+                return false;
+            }
+        }
+        else
+        {
+            ERR(&quot;Invalid index type %u.&quot;, indexType);
+            return false;
+        }
+
+        DWORD usageFlags = D3DUSAGE_WRITEONLY;
+        if (dynamic)
+        {
+            usageFlags |= D3DUSAGE_DYNAMIC;
+        }
+
+        HRESULT result = mRenderer-&gt;createIndexBuffer(bufferSize, usageFlags, format, &amp;mIndexBuffer);
+        if (FAILED(result))
+        {
+            ERR(&quot;Failed to create an index buffer of size %u, result: 0x%08x.&quot;, mBufferSize, result);
+            return false;
+        }
+    }
+
+    mBufferSize = bufferSize;
+    mIndexType = indexType;
+    mDynamic = dynamic;
+
+    return true;
+}
+
+IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer));
+    return static_cast&lt;IndexBuffer9*&gt;(indexBuffer);
+}
+
+bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory)
+{
+    if (mIndexBuffer)
+    {
+        DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0;
+
+        void *mapPtr = NULL;
+        HRESULT result = mIndexBuffer-&gt;Lock(offset, size, &amp;mapPtr, lockFlags);
+        if (FAILED(result))
+        {
+            ERR(&quot;Index buffer lock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        *outMappedMemory = mapPtr;
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool IndexBuffer9::unmapBuffer()
+{
+    if (mIndexBuffer)
+    {
+        HRESULT result = mIndexBuffer-&gt;Unlock();
+        if (FAILED(result))
+        {
+            ERR(&quot;Index buffer unlock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+GLenum IndexBuffer9::getIndexType() const
+{
+    return mIndexType;
+}
+
+unsigned int IndexBuffer9::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType)
+{
+    if (bufferSize &gt; mBufferSize || indexType != mIndexType)
+    {
+        return initialize(bufferSize, indexType, mDynamic);
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool IndexBuffer9::discard()
+{
+    if (mIndexBuffer)
+    {
+        void *dummy;
+        HRESULT result;
+
+        result = mIndexBuffer-&gt;Lock(0, 1, &amp;dummy, D3DLOCK_DISCARD);
+        if (FAILED(result))
+        {
+            ERR(&quot;Discard lock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        result = mIndexBuffer-&gt;Unlock();
+        if (FAILED(result))
+        {
+            ERR(&quot;Discard unlock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Index buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+D3DFORMAT IndexBuffer9::getIndexFormat() const
+{
+    switch (mIndexType)
+    {
+      case GL_UNSIGNED_BYTE:    return D3DFMT_INDEX16;
+      case GL_UNSIGNED_SHORT:   return D3DFMT_INDEX16;
+      case GL_UNSIGNED_INT:     return D3DFMT_INDEX32;
+      default: UNREACHABLE();   return D3DFMT_UNKNOWN;
+    }
+}
+
+IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const
+{
+    return mIndexBuffer;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9IndexBuffer9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,53 @@
</span><ins>+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Indexffer9.h: Defines the D3D9 IndexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+#define LIBGLESV2_RENDERER_INDEXBUFFER9_H_
+
+#include &quot;libGLESv2/renderer/IndexBuffer.h&quot;
+
+namespace rx
+{
+class Renderer9;
+
+class IndexBuffer9 : public IndexBuffer
+{
+  public:
+    explicit IndexBuffer9(Renderer9 *const renderer);
+    virtual ~IndexBuffer9();
+
+    virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic);
+
+    static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer);
+
+    virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory);
+    virtual bool unmapBuffer();
+
+    virtual GLenum getIndexType() const;
+    virtual unsigned int getBufferSize() const;
+    virtual bool setSize(unsigned int bufferSize, GLenum indexType);
+
+    virtual bool discard();
+
+    D3DFORMAT getIndexFormat() const;
+    IDirect3DIndexBuffer9 *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(IndexBuffer9);
+
+    rx::Renderer9 *const mRenderer;
+
+    IDirect3DIndexBuffer9 *mIndexBuffer;
+    unsigned int mBufferSize;
+    GLenum mIndexType;
+    bool mDynamic;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_INDEXBUFFER9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/IndexBuffer9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Query9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,125 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+
+#include &quot;libGLESv2/renderer/d3d9/Query9.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+namespace rx
+{
+
+Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type)
+{
+    mRenderer = renderer;
+    mQuery = NULL;
+}
+
+Query9::~Query9()
+{
+    if (mQuery)
+    {
+        mQuery-&gt;Release();
+        mQuery = NULL;
+    }
+}
+
+void Query9::begin()
+{
+    if (mQuery == NULL)
+    {
+        if (FAILED(mRenderer-&gt;getDevice()-&gt;CreateQuery(D3DQUERYTYPE_OCCLUSION, &amp;mQuery)))
+        {
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    HRESULT result = mQuery-&gt;Issue(D3DISSUE_BEGIN);
+    ASSERT(SUCCEEDED(result));
+}
+
+void Query9::end()
+{
+    if (mQuery == NULL)
+    {
+        return gl::error(GL_INVALID_OPERATION);
+    }
+
+    HRESULT result = mQuery-&gt;Issue(D3DISSUE_END);
+    ASSERT(SUCCEEDED(result));
+
+    mStatus = GL_FALSE;
+    mResult = GL_FALSE;
+}
+
+GLuint Query9::getResult()
+{
+    if (mQuery != NULL)
+    {
+        while (!testQuery())
+        {
+            Sleep(0);
+            // explicitly check for device loss
+            // some drivers seem to return S_FALSE even if the device is lost
+            // instead of D3DERR_DEVICELOST like they should
+            if (mRenderer-&gt;testDeviceLost(true))
+            {
+                return gl::error(GL_OUT_OF_MEMORY, 0);
+            }
+        }
+    }
+
+    return mResult;
+}
+
+GLboolean Query9::isResultAvailable()
+{
+    if (mQuery != NULL)
+    {
+        testQuery();
+    }
+
+    return mStatus;
+}
+
+GLboolean Query9::testQuery()
+{
+    if (mQuery != NULL &amp;&amp; mStatus != GL_TRUE)
+    {
+        DWORD numPixels = 0;
+
+        HRESULT hres = mQuery-&gt;GetData(&amp;numPixels, sizeof(DWORD), D3DGETDATA_FLUSH);
+        if (hres == S_OK)
+        {
+            mStatus =  GL_TRUE;
+
+            switch (getType())
+            {
+              case GL_ANY_SAMPLES_PASSED_EXT:
+              case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
+                mResult = (numPixels &gt; 0) ? GL_TRUE : GL_FALSE;
+                break;
+              default:
+                ASSERT(false);
+            }
+        }
+        else if (d3d9::isDeviceLostError(hres))
+        {
+            mRenderer-&gt;notifyDeviceLost();
+            return gl::error(GL_OUT_OF_MEMORY, GL_TRUE);
+        }
+
+        return mStatus;
+    }
+
+    return GL_TRUE; // prevent blocking when query is null
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Query9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+//
+// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl.
+
+#ifndef LIBGLESV2_RENDERER_QUERY9_H_
+#define LIBGLESV2_RENDERER_QUERY9_H_
+
+#include &quot;libGLESv2/renderer/QueryImpl.h&quot;
+
+namespace rx
+{
+class Renderer9;
+
+class Query9 : public QueryImpl
+{
+  public:
+    Query9(rx::Renderer9 *renderer, GLenum type);
+    virtual ~Query9();
+
+    void begin();
+    void end();
+    GLuint getResult();
+    GLboolean isResultAvailable();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Query9);
+
+    GLboolean testQuery();
+
+    rx::Renderer9 *mRenderer;
+    IDirect3DQuery9 *mQuery;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_QUERY9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Query9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9RenderTarget9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,113 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9
+// pointers retained by renderbuffers.
+
+#include &quot;libGLESv2/renderer/d3d9/RenderTarget9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/main.h&quot;
+
+namespace rx
+{
+
+RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface)
+{
+    mRenderer = Renderer9::makeRenderer9(renderer);
+    mRenderTarget = surface;
+
+    if (mRenderTarget)
+    {
+        D3DSURFACE_DESC description;
+        mRenderTarget-&gt;GetDesc(&amp;description);
+
+        mWidth = description.Width;
+        mHeight = description.Height;
+        
+        mInternalFormat = d3d9_gl::GetEquivalentFormat(description.Format);
+        mActualFormat = d3d9_gl::GetEquivalentFormat(description.Format);
+        mSamples = d3d9_gl::GetSamplesFromMultisampleType(description.MultiSampleType);
+    }
+}
+
+RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples)
+{
+    mRenderer = Renderer9::makeRenderer9(renderer);
+    mRenderTarget = NULL;
+
+    D3DFORMAT requestedFormat = gl_d3d9::ConvertRenderbufferFormat(format);
+    int supportedSamples = mRenderer-&gt;getNearestSupportedSamples(requestedFormat, samples);
+
+    if (supportedSamples == -1)
+    {
+        gl::error(GL_OUT_OF_MEMORY);
+
+        return;
+    }
+
+    HRESULT result = D3DERR_INVALIDCALL;
+    
+    if (width &gt; 0 &amp;&amp; height &gt; 0)
+    {
+        if (requestedFormat == D3DFMT_D24S8)
+        {
+            result = mRenderer-&gt;getDevice()-&gt;CreateDepthStencilSurface(width, height, requestedFormat,
+                                                                       gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples),
+                                                                       0, FALSE, &amp;mRenderTarget, NULL);
+        }
+        else
+        {
+            result = mRenderer-&gt;getDevice()-&gt;CreateRenderTarget(width, height, requestedFormat, 
+                                                                gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples),
+                                                                0, FALSE, &amp;mRenderTarget, NULL);
+        }
+
+        if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+        {
+            gl::error(GL_OUT_OF_MEMORY);
+
+            return;
+        }
+
+        ASSERT(SUCCEEDED(result));
+    }
+
+    mWidth = width;
+    mHeight = height;
+    mInternalFormat = format;
+    mSamples = supportedSamples;
+    mActualFormat = d3d9_gl::GetEquivalentFormat(requestedFormat);
+}
+
+RenderTarget9::~RenderTarget9()
+{
+    if (mRenderTarget)
+    {
+        mRenderTarget-&gt;Release();
+    }
+}
+
+RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target));
+    return static_cast&lt;rx::RenderTarget9*&gt;(target);
+}
+
+IDirect3DSurface9 *RenderTarget9::getSurface()
+{
+    // Caller is responsible for releasing the returned surface reference.
+    if (mRenderTarget)
+    {
+        mRenderTarget-&gt;AddRef();
+    }
+
+    return mRenderTarget;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9RenderTarget9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers
+// retained by Renderbuffers.
+
+#ifndef LIBGLESV2_RENDERER_RENDERTARGET9_H_
+#define LIBGLESV2_RENDERER_RENDERTARGET9_H_
+
+#include &quot;libGLESv2/renderer/RenderTarget.h&quot;
+
+namespace rx
+{
+class Renderer;
+class Renderer9;
+
+class RenderTarget9 : public RenderTarget
+{
+  public:
+    RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface);
+    RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples);
+    virtual ~RenderTarget9();
+
+    static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget);
+    IDirect3DSurface9 *getSurface();
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(RenderTarget9);
+
+    IDirect3DSurface9 *mRenderTarget;
+
+    Renderer9 *mRenderer;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERTARGET9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/RenderTarget9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Renderer9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,3287 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer.
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/Buffer.h&quot;
+#include &quot;libGLESv2/Texture.h&quot;
+#include &quot;libGLESv2/Framebuffer.h&quot;
+#include &quot;libGLESv2/Renderbuffer.h&quot;
+#include &quot;libGLESv2/ProgramBinary.h&quot;
+#include &quot;libGLESv2/renderer/IndexDataManager.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/ShaderExecutable9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/SwapChain9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/TextureStorage9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Image9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Blit.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/RenderTarget9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/VertexBuffer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/IndexBuffer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/BufferStorage9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Query9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Fence9.h&quot;
+
+#include &quot;libEGL/Display.h&quot;
+
+#include &quot;third_party/trace_event/trace_event.h&quot;
+
+// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros
+#define REF_RAST 0
+
+// The &quot;Debug This Pixel...&quot; 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 &quot;ANGLE_ENABLE_D3D9EX=0&quot; 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 rx
+{
+static const D3DFORMAT RenderTargetFormats[] =
+    {
+        D3DFMT_A1R5G5B5,
+    //  D3DFMT_A2R10G10B10,   // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+        D3DFMT_A8R8G8B8,
+        D3DFMT_R5G6B5,
+    //  D3DFMT_X1R5G5B5,      // Has no compatible OpenGL ES renderbuffer format
+        D3DFMT_X8R8G8B8
+    };
+
+static const D3DFORMAT DepthStencilFormats[] =
+    {
+        D3DFMT_UNKNOWN,
+    //  D3DFMT_D16_LOCKABLE,
+        D3DFMT_D32,
+    //  D3DFMT_D15S1,
+        D3DFMT_D24S8,
+        D3DFMT_D24X8,
+    //  D3DFMT_D24X4S4,
+        D3DFMT_D16,
+    //  D3DFMT_D32F_LOCKABLE,
+    //  D3DFMT_D24FS8
+    };
+
+enum
+{
+    MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256,
+    MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32,
+    MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224,
+    MAX_VARYING_VECTORS_SM2 = 8,
+    MAX_VARYING_VECTORS_SM3 = 10,
+
+    MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4
+};
+
+Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice)
+{
+    mD3d9Module = NULL;
+
+    mD3d9 = NULL;
+    mD3d9Ex = NULL;
+    mDevice = NULL;
+    mDeviceEx = NULL;
+    mDeviceWindow = NULL;
+    mBlit = NULL;
+
+    mAdapter = D3DADAPTER_DEFAULT;
+
+    #if REF_RAST == 1 || defined(FORCE_REF_RAST)
+        mDeviceType = D3DDEVTYPE_REF;
+    #else
+        mDeviceType = D3DDEVTYPE_HAL;
+    #endif
+
+    mDeviceLost = false;
+
+    mMaxSupportedSamples = 0;
+
+    mMaskedClearSavedState = NULL;
+
+    mVertexDataManager = NULL;
+    mIndexDataManager = NULL;
+    mLineLoopIB = NULL;
+
+    mMaxNullColorbufferLRU = 0;
+    for (int i = 0; i &lt; NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+    {
+        mNullColorbufferCache[i].lruCount = 0;
+        mNullColorbufferCache[i].width = 0;
+        mNullColorbufferCache[i].height = 0;
+        mNullColorbufferCache[i].buffer = NULL;
+    }
+}
+
+Renderer9::~Renderer9()
+{
+    if (mDevice)
+    {
+        // If the device is lost, reset it first to prevent leaving the driver in an unstable state
+        if (testDeviceLost(false))
+        {
+            resetDevice();
+        }
+    }
+
+    deinitialize();
+}
+
+void Renderer9::deinitialize()
+{
+    releaseDeviceResources();
+
+    SafeRelease(mDevice);
+    SafeRelease(mDeviceEx);
+    SafeRelease(mD3d9);
+    SafeRelease(mD3d9Ex);
+
+    if (mDeviceWindow)
+    {
+        DestroyWindow(mDeviceWindow);
+        mDeviceWindow = NULL;
+    }
+
+    if (mD3d9Module)
+    {
+        mD3d9Module = NULL;
+    }
+
+    while (!mMultiSampleSupport.empty())
+    {
+        delete [] mMultiSampleSupport.begin()-&gt;second;
+        mMultiSampleSupport.erase(mMultiSampleSupport.begin());
+    }
+}
+
+Renderer9 *Renderer9::makeRenderer9(Renderer *renderer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer));
+    return static_cast&lt;rx::Renderer9*&gt;(renderer);
+}
+
+EGLint Renderer9::initialize()
+{
+    if (!initializeCompiler())
+    {
+        return EGL_NOT_INITIALIZED;
+    }
+
+    if (mSoftwareDevice)
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;GetModuleHandle_swiftshader&quot;);
+        mD3d9Module = GetModuleHandle(TEXT(&quot;swiftshader_d3d9.dll&quot;));
+    }
+    else
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;GetModuleHandle_d3d9&quot;);
+        mD3d9Module = GetModuleHandle(TEXT(&quot;d3d9.dll&quot;));
+    }
+
+    if (mD3d9Module == NULL)
+    {
+        ERR(&quot;No D3D9 module found - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+    Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast&lt;Direct3DCreate9ExFunc&gt;(GetProcAddress(mD3d9Module, &quot;Direct3DCreate9Ex&quot;));
+
+    // Use Direct3D9Ex if available. Among other things, this version is less
+    // inclined to report a lost context, for example when the user switches
+    // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
+    if (ANGLE_ENABLE_D3D9EX &amp;&amp; Direct3DCreate9ExPtr &amp;&amp; SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &amp;mD3d9Ex)))
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;D3d9Ex_QueryInterface&quot;);
+        ASSERT(mD3d9Ex);
+        mD3d9Ex-&gt;QueryInterface(IID_IDirect3D9, reinterpret_cast&lt;void**&gt;(&amp;mD3d9));
+        ASSERT(mD3d9);
+    }
+    else
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;Direct3DCreate9&quot;);
+        mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+    }
+
+    if (!mD3d9)
+    {
+        ERR(&quot;Could not create D3D9 device - aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    if (mDc != NULL)
+    {
+    //  UNIMPLEMENTED();   // FIXME: Determine which adapter index the device context corresponds to
+    }
+
+    HRESULT result;
+
+    // Give up on getting device caps after about one second.
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;GetDeviceCaps&quot;);
+        for (int i = 0; i &lt; 10; ++i)
+        {
+            result = mD3d9-&gt;GetDeviceCaps(mAdapter, mDeviceType, &amp;mDeviceCaps);
+            if (SUCCEEDED(result))
+            {
+                break;
+            }
+            else if (result == D3DERR_NOTAVAILABLE)
+            {
+                Sleep(100);   // Give the driver some time to initialize/recover
+            }
+            else if (FAILED(result))   // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from
+            {
+                ERR(&quot;failed to get device caps (0x%x)\n&quot;, result);
+                return EGL_NOT_INITIALIZED;
+            }
+        }
+    }
+
+    if (mDeviceCaps.PixelShaderVersion &lt; D3DPS_VERSION(2, 0))
+    {
+        ERR(&quot;Renderer does not support PS 2.0. aborting!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported.
+    // This is required by Texture2D::convertToRenderTarget.
+    if ((mDeviceCaps.DevCaps2 &amp; D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0)
+    {
+        ERR(&quot;Renderer does not support stretctrect from textures!\n&quot;);
+        return EGL_NOT_INITIALIZED;
+    }
+
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;GetAdapterIdentifier&quot;);
+        mD3d9-&gt;GetAdapterIdentifier(mAdapter, 0, &amp;mAdapterIdentifier);
+    }
+
+    // ATI cards on XP have problems with non-power-of-two textures.
+    mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps &amp; D3DPTEXTURECAPS_POW2) &amp;&amp;
+        !(mDeviceCaps.TextureCaps &amp; D3DPTEXTURECAPS_CUBEMAP_POW2) &amp;&amp;
+        !(mDeviceCaps.TextureCaps &amp; D3DPTEXTURECAPS_NONPOW2CONDITIONAL) &amp;&amp;
+        !(getComparableOSVersion() &lt; versionWindowsVista &amp;&amp; mAdapterIdentifier.VendorId == VENDOR_ID_AMD);
+
+    // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec
+    mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps &amp; D3DPRASTERCAPS_ANISOTROPY) &amp;&amp; (mDeviceCaps.MaxAnisotropy &gt;= 2));
+
+    mMinSwapInterval = 4;
+    mMaxSwapInterval = 0;
+
+    if (mDeviceCaps.PresentationIntervals &amp; D3DPRESENT_INTERVAL_IMMEDIATE)
+    {
+        mMinSwapInterval = std::min(mMinSwapInterval, 0);
+        mMaxSwapInterval = std::max(mMaxSwapInterval, 0);
+    }
+    if (mDeviceCaps.PresentationIntervals &amp; D3DPRESENT_INTERVAL_ONE)
+    {
+        mMinSwapInterval = std::min(mMinSwapInterval, 1);
+        mMaxSwapInterval = std::max(mMaxSwapInterval, 1);
+    }
+    if (mDeviceCaps.PresentationIntervals &amp; D3DPRESENT_INTERVAL_TWO)
+    {
+        mMinSwapInterval = std::min(mMinSwapInterval, 2);
+        mMaxSwapInterval = std::max(mMaxSwapInterval, 2);
+    }
+    if (mDeviceCaps.PresentationIntervals &amp; D3DPRESENT_INTERVAL_THREE)
+    {
+        mMinSwapInterval = std::min(mMinSwapInterval, 3);
+        mMaxSwapInterval = std::max(mMaxSwapInterval, 3);
+    }
+    if (mDeviceCaps.PresentationIntervals &amp; D3DPRESENT_INTERVAL_FOUR)
+    {
+        mMinSwapInterval = std::min(mMinSwapInterval, 4);
+        mMaxSwapInterval = std::max(mMaxSwapInterval, 4);
+    }
+
+    int max = 0;
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;getMultiSampleSupport&quot;);
+        for (unsigned int i = 0; i &lt; ArraySize(RenderTargetFormats); ++i)
+        {
+            bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+            getMultiSampleSupport(RenderTargetFormats[i], multisampleArray);
+            mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray;
+
+            for (int j = D3DMULTISAMPLE_16_SAMPLES; j &gt;= 0; --j)
+            {
+                if (multisampleArray[j] &amp;&amp; j != D3DMULTISAMPLE_NONMASKABLE &amp;&amp; j &gt; max)
+                {
+                    max = j;
+                }
+            }
+        }
+    }
+
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;getMultiSampleSupport2&quot;);
+        for (unsigned int i = 0; i &lt; ArraySize(DepthStencilFormats); ++i)
+        {
+            if (DepthStencilFormats[i] == D3DFMT_UNKNOWN)
+                continue;
+
+            bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+            getMultiSampleSupport(DepthStencilFormats[i], multisampleArray);
+            mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray;
+
+            for (int j = D3DMULTISAMPLE_16_SAMPLES; j &gt;= 0; --j)
+            {
+                if (multisampleArray[j] &amp;&amp; j != D3DMULTISAMPLE_NONMASKABLE &amp;&amp; j &gt; max)
+                {
+                    max = j;
+                }
+            }
+        }
+    }
+
+    mMaxSupportedSamples = max;
+
+    static const TCHAR windowName[] = TEXT(&quot;AngleHiddenWindow&quot;);
+    static const TCHAR className[] = TEXT(&quot;STATIC&quot;);
+
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;CreateWindowEx&quot;);
+        mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
+    }
+
+    D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+    DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
+
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;D3d9_CreateDevice&quot;);
+        result = mD3d9-&gt;CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &amp;presentParameters, &amp;mDevice);
+    }
+    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST)
+    {
+        return EGL_BAD_ALLOC;
+    }
+
+    if (FAILED(result))
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;D3d9_CreateDevice2&quot;);
+        result = mD3d9-&gt;CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &amp;presentParameters, &amp;mDevice);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST);
+            return EGL_BAD_ALLOC;
+        }
+    }
+
+    if (mD3d9Ex)
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;mDevice_QueryInterface&quot;);
+        result = mDevice-&gt;QueryInterface(IID_IDirect3DDevice9Ex, (void**) &amp;mDeviceEx);
+        ASSERT(SUCCEEDED(result));
+    }
+
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;ShaderCache initialize&quot;);
+        mVertexShaderCache.initialize(mDevice);
+        mPixelShaderCache.initialize(mDevice);
+    }
+
+    // Check occlusion query support
+    IDirect3DQuery9 *occlusionQuery = NULL;
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;device_CreateQuery&quot;);
+        if (SUCCEEDED(mDevice-&gt;CreateQuery(D3DQUERYTYPE_OCCLUSION, &amp;occlusionQuery)) &amp;&amp; occlusionQuery)
+        {
+            occlusionQuery-&gt;Release();
+            mOcclusionQuerySupport = true;
+        }
+        else
+        {
+            mOcclusionQuerySupport = false;
+        }
+    }
+
+    // Check event query support
+    IDirect3DQuery9 *eventQuery = NULL;
+    {
+        TRACE_EVENT0(&quot;gpu&quot;, &quot;device_CreateQuery2&quot;);
+        if (SUCCEEDED(mDevice-&gt;CreateQuery(D3DQUERYTYPE_EVENT, &amp;eventQuery)) &amp;&amp; eventQuery)
+        {
+            eventQuery-&gt;Release();
+            mEventQuerySupport = true;
+        }
+        else
+        {
+            mEventQuerySupport = false;
+        }
+    }
+
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9-&gt;GetAdapterDisplayMode(mAdapter, &amp;currentDisplayMode);
+
+    // Check vertex texture support
+    // Only Direct3D 10 ready devices support all the necessary vertex texture formats.
+    // We test this using D3D9 by checking support for the R16F format.
+    mVertexTextureSupport = mDeviceCaps.PixelShaderVersion &gt;= D3DPS_VERSION(3, 0) &amp;&amp;
+                            SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+                                                               D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F));
+
+    // Check depth texture support
+    // we use INTZ for depth textures in Direct3D9
+    // we also want NULL texture support to ensure the we can make depth-only FBOs
+    // see http://aras-p.info/texts/D3D9GPUHacks.html
+    mDepthTextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+                                                              D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)) &amp;&amp;
+                           SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format,
+                                                              D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL));
+
+    // Check 32 bit floating point texture support
+    mFloat32FilterSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                               D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &amp;&amp;
+                            SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+
+    mFloat32RenderSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                               D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &amp;&amp;
+                            SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+
+    if (!mFloat32FilterSupport &amp;&amp; !mFloat32RenderSupport)
+    {
+        mFloat32TextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                                    D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) &amp;&amp;
+                                 SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F));
+    }
+    else
+    {
+        mFloat32TextureSupport = true;
+    }
+
+    // Check 16 bit floating point texture support
+    mFloat16FilterSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                               D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &amp;&amp;
+                            SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER,
+                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+
+    mFloat16RenderSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                               D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &amp;&amp;
+                            SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET,
+                                                               D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+
+    if (!mFloat16FilterSupport &amp;&amp; !mFloat16RenderSupport)
+    {
+        mFloat16TextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                                    D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) &amp;&amp;
+                                 SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0,
+                                                                    D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F));
+    }
+    else
+    {
+        mFloat16TextureSupport = true;
+    }
+
+    // Check DXT texture support
+    mDXT1TextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
+    mDXT3TextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3));
+    mDXT5TextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5));
+
+    // Check luminance[alpha] texture support
+    mLuminanceTextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8));
+    mLuminanceAlphaTextureSupport = SUCCEEDED(mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8));
+
+    initializeDevice();
+
+    return EGL_SUCCESS;
+}
+
+// do any one-time device initialization
+// NOTE: this is also needed after a device lost/reset
+// to reset the scene status and ensure the default states are reset.
+void Renderer9::initializeDevice()
+{
+    // Permanent non-default states
+    mDevice-&gt;SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
+    mDevice-&gt;SetRenderState(D3DRS_LASTPIXEL, FALSE);
+
+    if (mDeviceCaps.PixelShaderVersion &gt;= D3DPS_VERSION(3, 0))
+    {
+        mDevice-&gt;SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&amp;)mDeviceCaps.MaxPointSize);
+    }
+    else
+    {
+        mDevice-&gt;SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000);   // 1.0f
+    }
+
+    markAllStateDirty();
+
+    mSceneStarted = false;
+
+    ASSERT(!mBlit &amp;&amp; !mVertexDataManager &amp;&amp; !mIndexDataManager);
+    mBlit = new Blit(this);
+    mVertexDataManager = new rx::VertexDataManager(this);
+    mIndexDataManager = new rx::IndexDataManager(this);
+}
+
+D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters()
+{
+    D3DPRESENT_PARAMETERS presentParameters = {0};
+
+    // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+    presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferCount = 1;
+    presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+    presentParameters.BackBufferWidth = 1;
+    presentParameters.BackBufferHeight = 1;
+    presentParameters.EnableAutoDepthStencil = FALSE;
+    presentParameters.Flags = 0;
+    presentParameters.hDeviceWindow = mDeviceWindow;
+    presentParameters.MultiSampleQuality = 0;
+    presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
+    presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
+    presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    presentParameters.Windowed = TRUE;
+
+    return presentParameters;
+}
+
+int Renderer9::generateConfigs(ConfigDesc **configDescList)
+{
+    D3DDISPLAYMODE currentDisplayMode;
+    mD3d9-&gt;GetAdapterDisplayMode(mAdapter, &amp;currentDisplayMode);
+
+    unsigned int numRenderFormats = ArraySize(RenderTargetFormats);
+    unsigned int numDepthFormats = ArraySize(DepthStencilFormats);
+    (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats];
+    int numConfigs = 0;
+
+    for (unsigned int formatIndex = 0; formatIndex &lt; numRenderFormats; formatIndex++)
+    {
+        D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex];
+
+        HRESULT result = mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+
+        if (SUCCEEDED(result))
+        {
+            for (unsigned int depthStencilIndex = 0; depthStencilIndex &lt; numDepthFormats; depthStencilIndex++)
+            {
+                D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex];
+                HRESULT result = D3D_OK;
+
+                if(depthStencilFormat != D3DFMT_UNKNOWN)
+                {
+                    result = mD3d9-&gt;CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+                }
+
+                if (SUCCEEDED(result))
+                {
+                    if(depthStencilFormat != D3DFMT_UNKNOWN)
+                    {
+                        result = mD3d9-&gt;CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+                    }
+
+                    if (SUCCEEDED(result))
+                    {
+                        ConfigDesc newConfig;
+                        newConfig.renderTargetFormat = d3d9_gl::ConvertBackBufferFormat(renderTargetFormat);
+                        newConfig.depthStencilFormat = d3d9_gl::ConvertDepthStencilFormat(depthStencilFormat);
+                        newConfig.multiSample = 0; // FIXME: enumerate multi-sampling
+                        newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat);
+
+                        (*configDescList)[numConfigs++] = newConfig;
+                    }
+                }
+            }
+        }
+    }
+
+    return numConfigs;
+}
+
+void Renderer9::deleteConfigs(ConfigDesc *configDescList)
+{
+    delete [] (configDescList);
+}
+
+void Renderer9::startScene()
+{
+    if (!mSceneStarted)
+    {
+        long result = mDevice-&gt;BeginScene();
+        if (SUCCEEDED(result)) {
+            // This is defensive checking against the device being
+            // lost at unexpected times.
+            mSceneStarted = true;
+        }
+    }
+}
+
+void Renderer9::endScene()
+{
+    if (mSceneStarted)
+    {
+        // EndScene can fail if the device was lost, for example due
+        // to a TDR during a draw call.
+        mDevice-&gt;EndScene();
+        mSceneStarted = false;
+    }
+}
+
+void Renderer9::sync(bool block)
+{
+    HRESULT result;
+
+    IDirect3DQuery9* query = allocateEventQuery();
+    if (!query)
+    {
+        return;
+    }
+
+    result = query-&gt;Issue(D3DISSUE_END);
+    ASSERT(SUCCEEDED(result));
+
+    do
+    {
+        result = query-&gt;GetData(NULL, 0, D3DGETDATA_FLUSH);
+
+        if(block &amp;&amp; result == S_FALSE)
+        {
+            // Keep polling, but allow other threads to do something useful first
+            Sleep(0);
+            // explicitly check for device loss
+            // some drivers seem to return S_FALSE even if the device is lost
+            // instead of D3DERR_DEVICELOST like they should
+            if (testDeviceLost(false))
+            {
+                result = D3DERR_DEVICELOST;
+            }
+        }
+    }
+    while(block &amp;&amp; result == S_FALSE);
+
+    freeEventQuery(query);
+
+    if (d3d9::isDeviceLostError(result))
+    {
+        notifyDeviceLost();
+    }
+}
+
+SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat)
+{
+    return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat);
+}
+
+IDirect3DQuery9* Renderer9::allocateEventQuery()
+{
+    IDirect3DQuery9 *query = NULL;
+
+    if (mEventQueryPool.empty())
+    {
+        HRESULT result = mDevice-&gt;CreateQuery(D3DQUERYTYPE_EVENT, &amp;query);
+        ASSERT(SUCCEEDED(result));
+    }
+    else
+    {
+        query = mEventQueryPool.back();
+        mEventQueryPool.pop_back();
+    }
+
+    return query;
+}
+
+void Renderer9::freeEventQuery(IDirect3DQuery9* query)
+{
+    if (mEventQueryPool.size() &gt; 1000)
+    {
+        query-&gt;Release();
+    }
+    else
+    {
+        mEventQueryPool.push_back(query);
+    }
+}
+
+IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length)
+{
+    return mVertexShaderCache.create(function, length);
+}
+
+IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length)
+{
+    return mPixelShaderCache.create(function, length);
+}
+
+HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer)
+{
+    D3DPOOL Pool = getBufferPool(Usage);
+    return mDevice-&gt;CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL);
+}
+
+VertexBuffer *Renderer9::createVertexBuffer()
+{
+    return new VertexBuffer9(this);
+}
+
+HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer)
+{
+    D3DPOOL Pool = getBufferPool(Usage);
+    return mDevice-&gt;CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL);
+}
+
+IndexBuffer *Renderer9::createIndexBuffer()
+{
+    return new IndexBuffer9(this);
+}
+
+BufferStorage *Renderer9::createBufferStorage()
+{
+    return new BufferStorage9();
+}
+
+QueryImpl *Renderer9::createQuery(GLenum type)
+{
+    return new Query9(this, type);
+}
+
+FenceImpl *Renderer9::createFence()
+{
+    return new Fence9(this);
+}
+
+void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &amp;samplerState)
+{
+    bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates;
+    gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates;
+
+    if (forceSetSamplers[index] || memcmp(&amp;samplerState, &amp;appliedSamplers[index], sizeof(gl::SamplerState)) != 0)
+    {
+        int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+        int d3dSampler = index + d3dSamplerOffset;
+
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS));
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT));
+
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy));
+        D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
+        gl_d3d9::ConvertMinFilter(samplerState.minFilter, &amp;d3dMinFilter, &amp;d3dMipFilter, samplerState.maxAnisotropy);
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter);
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter);
+        mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset);
+        if (mSupportsTextureFilterAnisotropy)
+        {
+            mDevice-&gt;SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy);
+        }
+    }
+
+    forceSetSamplers[index] = false;
+    appliedSamplers[index] = samplerState;
+}
+
+void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture)
+{
+    int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0;
+    int d3dSampler = index + d3dSamplerOffset;
+    IDirect3DBaseTexture9 *d3dTexture = NULL;
+    unsigned int serial = 0;
+    bool forceSetTexture = false;
+
+    unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials;
+
+    if (texture)
+    {
+        TextureStorageInterface *texStorage = texture-&gt;getNativeTexture();
+        if (texStorage)
+        {
+            TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage-&gt;getStorageInstance());
+            d3dTexture = storage9-&gt;getBaseTexture();
+        }
+        // If we get NULL back from getBaseTexture here, something went wrong
+        // in the texture class and we're unexpectedly missing the d3d texture
+        ASSERT(d3dTexture != NULL);
+
+        serial = texture-&gt;getTextureSerial();
+        forceSetTexture = texture-&gt;hasDirtyImages();
+    }
+
+    if (forceSetTexture || appliedSerials[index] != serial)
+    {
+        mDevice-&gt;SetTexture(d3dSampler, d3dTexture);
+    }
+
+    appliedSerials[index] = serial;
+}
+
+void Renderer9::setRasterizerState(const gl::RasterizerState &amp;rasterState)
+{
+    bool rasterStateChanged = mForceSetRasterState || memcmp(&amp;rasterState, &amp;mCurRasterState, sizeof(gl::RasterizerState)) != 0;
+
+    if (rasterStateChanged)
+    {
+        // Set the cull mode
+        if (rasterState.cullFace)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace));
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+        }
+
+        if (rasterState.polygonOffsetFill)
+        {
+            if (mCurDepthSize &gt; 0)
+            {
+                mDevice-&gt;SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&amp;rasterState.polygonOffsetFactor);
+
+                float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast&lt;int&gt;(mCurDepthSize));
+                mDevice-&gt;SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&amp;depthBias);
+            }
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
+            mDevice-&gt;SetRenderState(D3DRS_DEPTHBIAS, 0);
+        }
+
+        mCurRasterState = rasterState;
+    }
+
+    mForceSetRasterState = false;
+}
+
+void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState, const gl::Color &amp;blendColor, unsigned int sampleMask)
+{
+    bool blendStateChanged = mForceSetBlendState || memcmp(&amp;blendState, &amp;mCurBlendState, sizeof(gl::BlendState)) != 0;
+    bool blendColorChanged = mForceSetBlendState || memcmp(&amp;blendColor, &amp;mCurBlendColor, sizeof(gl::Color)) != 0;
+    bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask;
+
+    if (blendStateChanged || blendColorChanged)
+    {
+        if (blendState.blend)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+            if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA &amp;&amp; blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA &amp;&amp;
+                blendState.destBlendRGB != GL_CONSTANT_ALPHA &amp;&amp; blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA)
+            {
+                mDevice-&gt;SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor));
+            }
+            else
+            {
+                mDevice-&gt;SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm&lt;8&gt;(blendColor.alpha),
+                                                                         gl::unorm&lt;8&gt;(blendColor.alpha),
+                                                                         gl::unorm&lt;8&gt;(blendColor.alpha),
+                                                                         gl::unorm&lt;8&gt;(blendColor.alpha)));
+            }
+
+            mDevice-&gt;SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB));
+            mDevice-&gt;SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB));
+            mDevice-&gt;SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB));
+
+            if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha ||
+                blendState.destBlendRGB != blendState.destBlendAlpha ||
+                blendState.blendEquationRGB != blendState.blendEquationAlpha)
+            {
+                mDevice-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+
+                mDevice-&gt;SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha));
+                mDevice-&gt;SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha));
+                mDevice-&gt;SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha));
+            }
+            else
+            {
+                mDevice-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE);
+            }
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+        }
+
+        if (blendState.sampleAlphaToCoverage)
+        {
+            FIXME(&quot;Sample alpha to coverage is unimplemented.&quot;);
+        }
+
+        // Set the color mask
+        bool zeroColorMaskAllowed = getAdapterVendor() != VENDOR_ID_AMD;
+        // Apparently some ATI cards have a bug where a draw with a zero color
+        // write mask can cause later draws to have incorrect results. Instead,
+        // set a nonzero color write mask but modify the blend state so that no
+        // drawing is done.
+        // http://code.google.com/p/angleproject/issues/detail?id=169
+
+        DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
+                                                    blendState.colorMaskBlue, blendState.colorMaskAlpha);
+        if (colorMask == 0 &amp;&amp; !zeroColorMaskAllowed)
+        {
+            // Enable green channel, but set blending so nothing will be drawn.
+            mDevice-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN);
+            mDevice-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
+
+            mDevice-&gt;SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
+            mDevice-&gt;SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
+            mDevice-&gt;SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, colorMask);
+        }
+
+        mDevice-&gt;SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE);
+
+        mCurBlendState = blendState;
+        mCurBlendColor = blendColor;
+    }
+
+    if (sampleMaskChanged)
+    {
+        // Set the multisample mask
+        mDevice-&gt;SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+        mDevice-&gt;SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast&lt;DWORD&gt;(sampleMask));
+
+        mCurSampleMask = sampleMask;
+    }
+
+    mForceSetBlendState = false;
+}
+
+void Renderer9::setDepthStencilState(const gl::DepthStencilState &amp;depthStencilState, int stencilRef,
+                                     int stencilBackRef, bool frontFaceCCW)
+{
+    bool depthStencilStateChanged = mForceSetDepthStencilState ||
+                                    memcmp(&amp;depthStencilState, &amp;mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0;
+    bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef ||
+                             stencilBackRef != mCurStencilBackRef;
+    bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW;
+
+    if (depthStencilStateChanged)
+    {
+        if (depthStencilState.depthTest)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
+            mDevice-&gt;SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc));
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+        }
+
+        mCurDepthStencilState = depthStencilState;
+    }
+
+    if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged)
+    {
+        if (depthStencilState.stencilTest &amp;&amp; mCurStencilSize &gt; 0)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_STENCILENABLE, TRUE);
+            mDevice-&gt;SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
+
+            // FIXME: Unsupported by D3D9
+            const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF;
+            const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK;
+            const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK;
+            if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask ||
+                stencilRef != stencilBackRef ||
+                depthStencilState.stencilMask != depthStencilState.stencilBackMask)
+            {
+                ERR(&quot;Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.&quot;);
+                return gl::error(GL_INVALID_OPERATION);
+            }
+
+            // get the maximum size of the stencil ref
+            unsigned int maxStencil = (1 &lt;&lt; mCurStencilSize) - 1;
+
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
+                                    depthStencilState.stencilWritemask);
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+                                    gl_d3d9::ConvertComparison(depthStencilState.stencilFunc));
+
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+                                    (stencilRef &lt; (int)maxStencil) ? stencilRef : maxStencil);
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
+                                    depthStencilState.stencilMask);
+
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail));
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail));
+            mDevice-&gt;SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass));
+
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK,
+                                    depthStencilState.stencilBackWritemask);
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC,
+                                    gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc));
+
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF,
+                                    (stencilBackRef &lt; (int)maxStencil) ? stencilBackRef : maxStencil);
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK,
+                                    depthStencilState.stencilBackMask);
+
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail));
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail));
+            mDevice-&gt;SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS,
+                                    gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass));
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_STENCILENABLE, FALSE);
+        }
+
+        mDevice-&gt;SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE);
+
+        mCurStencilRef = stencilRef;
+        mCurStencilBackRef = stencilBackRef;
+        mCurFrontFaceCCW = frontFaceCCW;
+    }
+
+    mForceSetDepthStencilState = false;
+}
+
+void Renderer9::setScissorRectangle(const gl::Rectangle &amp;scissor, bool enabled)
+{
+    bool scissorChanged = mForceSetScissor ||
+                          memcmp(&amp;scissor, &amp;mCurScissor, sizeof(gl::Rectangle)) != 0 ||
+                          enabled != mScissorEnabled;
+
+    if (scissorChanged)
+    {
+        if (enabled)
+        {
+            RECT rect;
+            rect.left = gl::clamp(scissor.x, 0, static_cast&lt;int&gt;(mRenderTargetDesc.width));
+            rect.top = gl::clamp(scissor.y, 0, static_cast&lt;int&gt;(mRenderTargetDesc.height));
+            rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast&lt;int&gt;(mRenderTargetDesc.width));
+            rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast&lt;int&gt;(mRenderTargetDesc.height));
+            mDevice-&gt;SetScissorRect(&amp;rect);
+        }
+
+        mDevice-&gt;SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE);
+
+        mScissorEnabled = enabled;
+        mCurScissor = scissor;
+    }
+
+    mForceSetScissor = false;
+}
+
+bool Renderer9::setViewport(const gl::Rectangle &amp;viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+                            bool ignoreViewport)
+{
+    gl::Rectangle actualViewport = viewport;
+    float actualZNear = gl::clamp01(zNear);
+    float actualZFar = gl::clamp01(zFar);
+    if (ignoreViewport)
+    {
+        actualViewport.x = 0;
+        actualViewport.y = 0;
+        actualViewport.width = mRenderTargetDesc.width;
+        actualViewport.height = mRenderTargetDesc.height;
+        actualZNear = 0.0f;
+        actualZFar = 1.0f;
+    }
+
+    D3DVIEWPORT9 dxViewport;
+    dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast&lt;int&gt;(mRenderTargetDesc.width));
+    dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast&lt;int&gt;(mRenderTargetDesc.height));
+    dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast&lt;int&gt;(mRenderTargetDesc.width) - static_cast&lt;int&gt;(dxViewport.X));
+    dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast&lt;int&gt;(mRenderTargetDesc.height) - static_cast&lt;int&gt;(dxViewport.Y));
+    dxViewport.MinZ = actualZNear;
+    dxViewport.MaxZ = actualZFar;
+
+    if (dxViewport.Width &lt;= 0 || dxViewport.Height &lt;= 0)
+    {
+        return false;   // Nothing to render
+    }
+
+    float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f);
+
+    bool viewportChanged = mForceSetViewport || memcmp(&amp;actualViewport, &amp;mCurViewport, sizeof(gl::Rectangle)) != 0 ||
+                           actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront;
+    if (viewportChanged)
+    {
+        mDevice-&gt;SetViewport(&amp;dxViewport);
+
+        mCurViewport = actualViewport;
+        mCurNear = actualZNear;
+        mCurFar = actualZFar;
+        mCurDepthFront = depthFront;
+
+        dx_VertexConstants vc = {0};
+        dx_PixelConstants pc = {0};
+
+        vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width;
+        vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height;
+        vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width;
+        vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height;
+
+        pc.viewCoords[0] = actualViewport.width  * 0.5f;
+        pc.viewCoords[1] = actualViewport.height * 0.5f;
+        pc.viewCoords[2] = actualViewport.x + (actualViewport.width  * 0.5f);
+        pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f);
+
+        pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f;
+        pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f;
+        pc.depthFront[2] = depthFront;
+
+        vc.depthRange[0] = actualZNear;
+        vc.depthRange[1] = actualZFar;
+        vc.depthRange[2] = actualZFar - actualZNear;
+
+        pc.depthRange[0] = actualZNear;
+        pc.depthRange[1] = actualZFar;
+        pc.depthRange[2] = actualZFar - actualZNear;
+
+        if (memcmp(&amp;vc, &amp;mVertexConstants, sizeof(dx_VertexConstants)) != 0)
+        {
+            mVertexConstants = vc;
+            mDxUniformsDirty = true;
+        }
+
+        if (memcmp(&amp;pc, &amp;mPixelConstants, sizeof(dx_PixelConstants)) != 0)
+        {
+            mPixelConstants = pc;
+            mDxUniformsDirty = true;
+        }
+    }
+
+    mForceSetViewport = false;
+    return true;
+}
+
+bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count)
+{
+    switch (mode)
+    {
+      case GL_POINTS:
+        mPrimitiveType = D3DPT_POINTLIST;
+        mPrimitiveCount = count;
+        break;
+      case GL_LINES:
+        mPrimitiveType = D3DPT_LINELIST;
+        mPrimitiveCount = count / 2;
+        break;
+      case GL_LINE_LOOP:
+        mPrimitiveType = D3DPT_LINESTRIP;
+        mPrimitiveCount = count - 1;   // D3D doesn't support line loops, so we draw the last line separately
+        break;
+      case GL_LINE_STRIP:
+        mPrimitiveType = D3DPT_LINESTRIP;
+        mPrimitiveCount = count - 1;
+        break;
+      case GL_TRIANGLES:
+        mPrimitiveType = D3DPT_TRIANGLELIST;
+        mPrimitiveCount = count / 3;
+        break;
+      case GL_TRIANGLE_STRIP:
+        mPrimitiveType = D3DPT_TRIANGLESTRIP;
+        mPrimitiveCount = count - 2;
+        break;
+      case GL_TRIANGLE_FAN:
+        mPrimitiveType = D3DPT_TRIANGLEFAN;
+        mPrimitiveCount = count - 2;
+        break;
+      default:
+        return gl::error(GL_INVALID_ENUM, false);
+    }
+
+    return mPrimitiveCount &gt; 0;
+}
+
+
+gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer)
+{
+    if (!depthbuffer)
+    {
+        ERR(&quot;Unexpected null depthbuffer for depth-only FBO.&quot;);
+        return NULL;
+    }
+
+    GLsizei width  = depthbuffer-&gt;getWidth();
+    GLsizei height = depthbuffer-&gt;getHeight();
+
+    // search cached nullcolorbuffers
+    for (int i = 0; i &lt; NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+    {
+        if (mNullColorbufferCache[i].buffer != NULL &amp;&amp;
+            mNullColorbufferCache[i].width == width &amp;&amp;
+            mNullColorbufferCache[i].height == height)
+        {
+            mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU;
+            return mNullColorbufferCache[i].buffer;
+        }
+    }
+
+    gl::Renderbuffer *nullbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0));
+
+    // add nullbuffer to the cache
+    NullColorbufferCacheEntry *oldest = &amp;mNullColorbufferCache[0];
+    for (int i = 1; i &lt; NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+    {
+        if (mNullColorbufferCache[i].lruCount &lt; oldest-&gt;lruCount)
+        {
+            oldest = &amp;mNullColorbufferCache[i];
+        }
+    }
+
+    delete oldest-&gt;buffer;
+    oldest-&gt;buffer = nullbuffer;
+    oldest-&gt;lruCount = ++mMaxNullColorbufferLRU;
+    oldest-&gt;width = width;
+    oldest-&gt;height = height;
+
+    return nullbuffer;
+}
+
+bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer)
+{
+    // if there is no color attachment we must synthesize a NULL colorattachment
+    // to keep the D3D runtime happy.  This should only be possible if depth texturing.
+    gl::Renderbuffer *renderbufferObject = NULL;
+    if (framebuffer-&gt;getColorbufferType(0) != GL_NONE)
+    {
+        renderbufferObject = framebuffer-&gt;getColorbuffer(0);
+    }
+    else
+    {
+        renderbufferObject = getNullColorbuffer(framebuffer-&gt;getDepthbuffer());
+    }
+    if (!renderbufferObject)
+    {
+        ERR(&quot;unable to locate renderbuffer for FBO.&quot;);
+        return false;
+    }
+
+    bool renderTargetChanged = false;
+    unsigned int renderTargetSerial = renderbufferObject-&gt;getSerial();
+    if (renderTargetSerial != mAppliedRenderTargetSerial)
+    {
+        // Apply the render target on the device
+        IDirect3DSurface9 *renderTargetSurface = NULL;
+
+        RenderTarget *renderTarget = renderbufferObject-&gt;getRenderTarget();
+        if (renderTarget)
+        {
+            renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)-&gt;getSurface();
+        }
+
+        if (!renderTargetSurface)
+        {
+            ERR(&quot;render target pointer unexpectedly null.&quot;);
+            return false;   // Context must be lost
+        }
+
+        mDevice-&gt;SetRenderTarget(0, renderTargetSurface);
+        renderTargetSurface-&gt;Release();
+
+        mAppliedRenderTargetSerial = renderTargetSerial;
+        renderTargetChanged = true;
+    }
+
+    gl::Renderbuffer *depthStencil = NULL;
+    unsigned int depthbufferSerial = 0;
+    unsigned int stencilbufferSerial = 0;
+    if (framebuffer-&gt;getDepthbufferType() != GL_NONE)
+    {
+        depthStencil = framebuffer-&gt;getDepthbuffer();
+        if (!depthStencil)
+        {
+            ERR(&quot;Depth stencil pointer unexpectedly null.&quot;);
+            return false;
+        }
+
+        depthbufferSerial = depthStencil-&gt;getSerial();
+    }
+    else if (framebuffer-&gt;getStencilbufferType() != GL_NONE)
+    {
+        depthStencil = framebuffer-&gt;getStencilbuffer();
+        if (!depthStencil)
+        {
+            ERR(&quot;Depth stencil pointer unexpectedly null.&quot;);
+            return false;
+        }
+
+        stencilbufferSerial = depthStencil-&gt;getSerial();
+    }
+
+    if (depthbufferSerial != mAppliedDepthbufferSerial ||
+        stencilbufferSerial != mAppliedStencilbufferSerial ||
+        !mDepthStencilInitialized)
+    {
+        unsigned int depthSize = 0;
+        unsigned int stencilSize = 0;
+
+        // Apply the depth stencil on the device
+        if (depthStencil)
+        {
+            IDirect3DSurface9 *depthStencilSurface = NULL;
+            RenderTarget *depthStencilRenderTarget = depthStencil-&gt;getDepthStencil();
+
+            if (depthStencilRenderTarget)
+            {
+                depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)-&gt;getSurface();
+            }
+
+            if (!depthStencilSurface)
+            {
+                ERR(&quot;depth stencil pointer unexpectedly null.&quot;);
+                return false;   // Context must be lost
+            }
+
+            mDevice-&gt;SetDepthStencilSurface(depthStencilSurface);
+            depthStencilSurface-&gt;Release();
+
+            depthSize = depthStencil-&gt;getDepthSize();
+            stencilSize = depthStencil-&gt;getStencilSize();
+        }
+        else
+        {
+            mDevice-&gt;SetDepthStencilSurface(NULL);
+        }
+
+        if (!mDepthStencilInitialized || depthSize != mCurDepthSize)
+        {
+            mCurDepthSize = depthSize;
+            mForceSetRasterState = true;
+        }
+
+        if (!mDepthStencilInitialized || stencilSize != mCurStencilSize)
+        {
+            mCurStencilSize = stencilSize;
+            mForceSetDepthStencilState = true;
+        }
+
+        mAppliedDepthbufferSerial = depthbufferSerial;
+        mAppliedStencilbufferSerial = stencilbufferSerial;
+        mDepthStencilInitialized = true;
+    }
+
+    if (renderTargetChanged || !mRenderTargetDescInitialized)
+    {
+        mForceSetScissor = true;
+        mForceSetViewport = true;
+
+        mRenderTargetDesc.width = renderbufferObject-&gt;getWidth();
+        mRenderTargetDesc.height = renderbufferObject-&gt;getHeight();
+        mRenderTargetDesc.format = renderbufferObject-&gt;getActualFormat();
+        mRenderTargetDescInitialized = true;
+    }
+
+    return true;
+}
+
+GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances)
+{
+    TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS];
+    GLenum err = mVertexDataManager-&gt;prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances);
+    if (err != GL_NO_ERROR)
+    {
+        return err;
+    }
+    
+    return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &amp;mRepeatDraw);
+}
+
+// Applies the indices and element array bindings to the Direct3D 9 device
+GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
+{
+    GLenum err = mIndexDataManager-&gt;prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo);
+
+    if (err == GL_NO_ERROR)
+    {
+        // Directly binding the storage buffer is not supported for d3d9
+        ASSERT(indexInfo-&gt;storage == NULL);
+
+        if (indexInfo-&gt;serial != mAppliedIBSerial)
+        {
+            IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo-&gt;indexBuffer);
+
+            mDevice-&gt;SetIndices(indexBuffer-&gt;getBuffer());
+            mAppliedIBSerial = indexInfo-&gt;serial;
+        }
+    }
+
+    return err;
+}
+
+void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances)
+{
+    startScene();
+        
+    if (mode == GL_LINE_LOOP)
+    {
+        drawLineLoop(count, GL_NONE, NULL, 0, NULL);
+    }
+    else if (instances &gt; 0)
+    {
+        StaticIndexBufferInterface *countingIB = mIndexDataManager-&gt;getCountingIndices(count);
+        if (countingIB)
+        {
+            if (mAppliedIBSerial != countingIB-&gt;getSerial())
+            {
+                IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB-&gt;getIndexBuffer());
+
+                mDevice-&gt;SetIndices(indexBuffer-&gt;getBuffer());
+                mAppliedIBSerial = countingIB-&gt;getSerial();
+            }
+
+            for (int i = 0; i &lt; mRepeatDraw; i++)
+            {
+                mDevice-&gt;DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount);
+            }
+        }
+        else
+        {
+            ERR(&quot;Could not create a counting index buffer for glDrawArraysInstanced.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+    else   // Regular case
+    {
+        mDevice-&gt;DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount);
+    }
+}
+
+void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &amp;indexInfo, GLsizei /*instances*/)
+{
+    startScene();
+
+    if (mode == GL_POINTS)
+    {
+        drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+    }
+    else if (mode == GL_LINE_LOOP)
+    {
+        drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer);
+    }
+    else
+    {
+        for (int i = 0; i &lt; mRepeatDraw; i++)
+        {
+            GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
+            mDevice-&gt;DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount);
+        }
+    }
+}
+
+void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+    // Get the raw indices for an indexed draw
+    if (type != GL_NONE &amp;&amp; elementArrayBuffer)
+    {
+        gl::Buffer *indexBuffer = elementArrayBuffer;
+        BufferStorage *storage = indexBuffer-&gt;getStorage();
+        intptr_t offset = reinterpret_cast&lt;intptr_t&gt;(indices);
+        indices = static_cast&lt;const GLubyte*&gt;(storage-&gt;getData()) + offset;
+    }
+
+    unsigned int startIndex = 0;
+
+    if (get32BitIndexSupport())
+    {
+        if (!mLineLoopIB)
+        {
+            mLineLoopIB = new StreamingIndexBufferInterface(this);
+            if (!mLineLoopIB-&gt;reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
+            {
+                delete mLineLoopIB;
+                mLineLoopIB = NULL;
+
+                ERR(&quot;Could not create a 32-bit looping index buffer for GL_LINE_LOOP.&quot;);
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+        }
+
+        if (static_cast&lt;unsigned int&gt;(count) + 1 &gt; (std::numeric_limits&lt;unsigned int&gt;::max() / sizeof(unsigned int)))
+        {
+            ERR(&quot;Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        // Checked by Renderer9::applyPrimitiveType
+        ASSERT(count &gt;= 0);
+
+        const unsigned int spaceNeeded = (static_cast&lt;unsigned int&gt;(count) + 1) * sizeof(unsigned int);
+        if (!mLineLoopIB-&gt;reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT))
+        {
+            ERR(&quot;Could not reserve enough space in looping index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        void* mappedMemory = NULL;
+        unsigned int offset = 0;
+        if (!mLineLoopIB-&gt;mapBuffer(spaceNeeded, &amp;mappedMemory, &amp;offset))
+        {
+            ERR(&quot;Could not map index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        startIndex = static_cast&lt;unsigned int&gt;(offset) / 4;
+        unsigned int *data = reinterpret_cast&lt;unsigned int*&gt;(mappedMemory);
+
+        switch (type)
+        {
+          case GL_NONE:   // Non-indexed draw
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = i;
+            }
+            data[count] = 0;
+            break;
+          case GL_UNSIGNED_BYTE:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLubyte*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLubyte*&gt;(indices)[0];
+            break;
+          case GL_UNSIGNED_SHORT:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLushort*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLushort*&gt;(indices)[0];
+            break;
+          case GL_UNSIGNED_INT:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLuint*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLuint*&gt;(indices)[0];
+            break;
+          default: UNREACHABLE();
+        }
+
+        if (!mLineLoopIB-&gt;unmapBuffer())
+        {
+            ERR(&quot;Could not unmap index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+    else
+    {
+        if (!mLineLoopIB)
+        {
+            mLineLoopIB = new StreamingIndexBufferInterface(this);
+            if (!mLineLoopIB-&gt;reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
+            {
+                delete mLineLoopIB;
+                mLineLoopIB = NULL;
+
+                ERR(&quot;Could not create a 16-bit looping index buffer for GL_LINE_LOOP.&quot;);
+                return gl::error(GL_OUT_OF_MEMORY);
+            }
+        }
+
+        // Checked by Renderer9::applyPrimitiveType
+        ASSERT(count &gt;= 0);
+
+        if (static_cast&lt;unsigned int&gt;(count) + 1 &gt; (std::numeric_limits&lt;unsigned short&gt;::max() / sizeof(unsigned short)))
+        {
+            ERR(&quot;Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        const unsigned int spaceNeeded = (static_cast&lt;unsigned int&gt;(count) + 1) * sizeof(unsigned short);
+        if (!mLineLoopIB-&gt;reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT))
+        {
+            ERR(&quot;Could not reserve enough space in looping index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        void* mappedMemory = NULL;
+        unsigned int offset;
+        if (mLineLoopIB-&gt;mapBuffer(spaceNeeded, &amp;mappedMemory, &amp;offset))
+        {
+            ERR(&quot;Could not map index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+
+        startIndex = static_cast&lt;unsigned int&gt;(offset) / 2;
+        unsigned short *data = reinterpret_cast&lt;unsigned short*&gt;(mappedMemory);
+
+        switch (type)
+        {
+          case GL_NONE:   // Non-indexed draw
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = i;
+            }
+            data[count] = 0;
+            break;
+          case GL_UNSIGNED_BYTE:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLubyte*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLubyte*&gt;(indices)[0];
+            break;
+          case GL_UNSIGNED_SHORT:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLushort*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLushort*&gt;(indices)[0];
+            break;
+          case GL_UNSIGNED_INT:
+            for (int i = 0; i &lt; count; i++)
+            {
+                data[i] = static_cast&lt;const GLuint*&gt;(indices)[i];
+            }
+            data[count] = static_cast&lt;const GLuint*&gt;(indices)[0];
+            break;
+          default: UNREACHABLE();
+        }
+
+        if (!mLineLoopIB-&gt;unmapBuffer())
+        {
+            ERR(&quot;Could not unmap index buffer for GL_LINE_LOOP.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    if (mAppliedIBSerial != mLineLoopIB-&gt;getSerial())
+    {
+        IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB-&gt;getIndexBuffer());
+
+        mDevice-&gt;SetIndices(indexBuffer-&gt;getBuffer());
+        mAppliedIBSerial = mLineLoopIB-&gt;getSerial();
+    }
+
+    mDevice-&gt;DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count);
+}
+
+template &lt;typename T&gt;
+static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex)
+{
+    for (int i = 0; i &lt; count; i++)
+    {
+        unsigned int indexValue = static_cast&lt;unsigned int&gt;(static_cast&lt;const T*&gt;(indices)[i]) - minIndex;
+        device-&gt;DrawPrimitive(D3DPT_POINTLIST, indexValue, 1);
+    }
+}
+
+void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer)
+{
+    // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call
+    // for each individual point. This call is not expected to happen often.
+
+    if (elementArrayBuffer)
+    {
+        BufferStorage *storage = elementArrayBuffer-&gt;getStorage();
+        intptr_t offset = reinterpret_cast&lt;intptr_t&gt;(indices);
+        indices = static_cast&lt;const GLubyte*&gt;(storage-&gt;getData()) + offset;
+    }
+
+    switch (type)
+    {
+        case GL_UNSIGNED_BYTE:  drawPoints&lt;GLubyte&gt;(mDevice, count, indices, minIndex);  break;
+        case GL_UNSIGNED_SHORT: drawPoints&lt;GLushort&gt;(mDevice, count, indices, minIndex); break;
+        case GL_UNSIGNED_INT:   drawPoints&lt;GLuint&gt;(mDevice, count, indices, minIndex);   break;
+        default: UNREACHABLE();
+    }
+}
+
+void Renderer9::applyShaders(gl::ProgramBinary *programBinary)
+{
+    unsigned int programBinarySerial = programBinary-&gt;getSerial();
+    if (programBinarySerial != mAppliedProgramBinarySerial)
+    {
+        ShaderExecutable *vertexExe = programBinary-&gt;getVertexExecutable();
+        ShaderExecutable *pixelExe = programBinary-&gt;getPixelExecutable();
+
+        IDirect3DVertexShader9 *vertexShader = NULL;
+        if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)-&gt;getVertexShader();
+
+        IDirect3DPixelShader9 *pixelShader = NULL;
+        if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)-&gt;getPixelShader();
+
+        mDevice-&gt;SetPixelShader(pixelShader);
+        mDevice-&gt;SetVertexShader(vertexShader);
+        programBinary-&gt;dirtyAllUniforms();
+        mDxUniformsDirty = true;
+
+        mAppliedProgramBinarySerial = programBinarySerial;
+    }
+}
+
+void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray)
+{
+    for (std::vector&lt;gl::Uniform*&gt;::const_iterator ub = uniformArray-&gt;begin(), ue = uniformArray-&gt;end(); ub != ue; ++ub)
+    {
+        gl::Uniform *targetUniform = *ub;
+
+        if (targetUniform-&gt;dirty)
+        {
+            GLfloat *f = (GLfloat*)targetUniform-&gt;data;
+            GLint *i = (GLint*)targetUniform-&gt;data;
+
+            switch (targetUniform-&gt;type)
+            {
+              case GL_SAMPLER_2D:
+              case GL_SAMPLER_CUBE:
+                break;
+              case GL_BOOL:
+              case GL_BOOL_VEC2:
+              case GL_BOOL_VEC3:
+              case GL_BOOL_VEC4:
+                applyUniformnbv(targetUniform, i);
+                break;
+              case GL_FLOAT:
+              case GL_FLOAT_VEC2:
+              case GL_FLOAT_VEC3:
+              case GL_FLOAT_VEC4:
+              case GL_FLOAT_MAT2:
+              case GL_FLOAT_MAT3:
+              case GL_FLOAT_MAT4:
+                applyUniformnfv(targetUniform, f);
+                break;
+              case GL_INT:
+              case GL_INT_VEC2:
+              case GL_INT_VEC3:
+              case GL_INT_VEC4:
+                applyUniformniv(targetUniform, i);
+                break;
+              default:
+                UNREACHABLE();
+            }
+
+            targetUniform-&gt;dirty = false;
+        }
+    }
+
+    // Driver uniforms
+    if (mDxUniformsDirty)
+    {
+        mDevice-&gt;SetVertexShaderConstantF(0, (float*)&amp;mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4]));
+        mDevice-&gt;SetPixelShaderConstantF(0, (float*)&amp;mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4]));
+        mDxUniformsDirty = false;
+    }
+}
+
+void Renderer9::applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v)
+{
+    if (targetUniform-&gt;psRegisterIndex &gt;= 0)
+    {
+        mDevice-&gt;SetPixelShaderConstantF(targetUniform-&gt;psRegisterIndex, v, targetUniform-&gt;registerCount);
+    }
+
+    if (targetUniform-&gt;vsRegisterIndex &gt;= 0)
+    {
+        mDevice-&gt;SetVertexShaderConstantF(targetUniform-&gt;vsRegisterIndex, v, targetUniform-&gt;registerCount);
+    }
+}
+
+void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v)
+{
+    ASSERT(targetUniform-&gt;registerCount &lt;= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+    GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+    for (unsigned int i = 0; i &lt; targetUniform-&gt;registerCount; i++)
+    {
+        vector[i][0] = (GLfloat)v[4 * i + 0];
+        vector[i][1] = (GLfloat)v[4 * i + 1];
+        vector[i][2] = (GLfloat)v[4 * i + 2];
+        vector[i][3] = (GLfloat)v[4 * i + 3];
+    }
+
+    applyUniformnfv(targetUniform, (GLfloat*)vector);
+}
+
+void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v)
+{
+    ASSERT(targetUniform-&gt;registerCount &lt;= MAX_VERTEX_CONSTANT_VECTORS_D3D9);
+    GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4];
+
+    for (unsigned int i = 0; i &lt; targetUniform-&gt;registerCount; i++)
+    {
+        vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f;
+        vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f;
+        vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f;
+        vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f;
+    }
+
+    applyUniformnfv(targetUniform, (GLfloat*)vector);
+}
+
+void Renderer9::clear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer)
+{
+    D3DCOLOR color = D3DCOLOR_ARGB(gl::unorm&lt;8&gt;(clearParams.colorClearValue.alpha),
+                                   gl::unorm&lt;8&gt;(clearParams.colorClearValue.red),
+                                   gl::unorm&lt;8&gt;(clearParams.colorClearValue.green),
+                                   gl::unorm&lt;8&gt;(clearParams.colorClearValue.blue));
+    float depth = gl::clamp01(clearParams.depthClearValue);
+    int stencil = clearParams.stencilClearValue &amp; 0x000000FF;
+
+    unsigned int stencilUnmasked = 0x0;
+    if ((clearParams.mask &amp; GL_STENCIL_BUFFER_BIT) &amp;&amp; frameBuffer-&gt;hasStencil())
+    {
+        unsigned int stencilSize = gl::GetStencilSize(frameBuffer-&gt;getStencilbuffer()-&gt;getActualFormat());
+        stencilUnmasked = (0x1 &lt;&lt; stencilSize) - 1;
+    }
+
+    bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha;
+
+    const bool needMaskedStencilClear = (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT) &amp;&amp;
+                                        (clearParams.stencilWriteMask &amp; stencilUnmasked) != stencilUnmasked;
+    const bool needMaskedColorClear = (clearParams.mask &amp; GL_COLOR_BUFFER_BIT) &amp;&amp;
+                                      !(clearParams.colorMaskRed &amp;&amp; clearParams.colorMaskGreen &amp;&amp;
+                                        clearParams.colorMaskBlue &amp;&amp; alphaUnmasked);
+
+    if (needMaskedColorClear || needMaskedStencilClear)
+    {
+        // State which is altered in all paths from this point to the clear call is saved.
+        // State which is altered in only some paths will be flagged dirty in the case that
+        //  that path is taken.
+        HRESULT hr;
+        if (mMaskedClearSavedState == NULL)
+        {
+            hr = mDevice-&gt;BeginStateBlock();
+            ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+
+            mDevice-&gt;SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+            mDevice-&gt;SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+            mDevice-&gt;SetRenderState(D3DRS_ZENABLE, FALSE);
+            mDevice-&gt;SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+            mDevice-&gt;SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+            mDevice-&gt;SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+            mDevice-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+            mDevice-&gt;SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+            mDevice-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILENABLE, FALSE);
+            mDevice-&gt;SetPixelShader(NULL);
+            mDevice-&gt;SetVertexShader(NULL);
+            mDevice-&gt;SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
+            mDevice-&gt;SetStreamSource(0, NULL, 0, 0);
+            mDevice-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+            mDevice-&gt;SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+            mDevice-&gt;SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+            mDevice-&gt;SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+            mDevice-&gt;SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+            mDevice-&gt;SetRenderState(D3DRS_TEXTUREFACTOR, color);
+            mDevice-&gt;SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+            for(int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+            {
+                mDevice-&gt;SetStreamSourceFreq(i, 1);
+            }
+
+            hr = mDevice-&gt;EndStateBlock(&amp;mMaskedClearSavedState);
+            ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
+        }
+
+        ASSERT(mMaskedClearSavedState != NULL);
+
+        if (mMaskedClearSavedState != NULL)
+        {
+            hr = mMaskedClearSavedState-&gt;Capture();
+            ASSERT(SUCCEEDED(hr));
+        }
+
+        mDevice-&gt;SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+        mDevice-&gt;SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
+        mDevice-&gt;SetRenderState(D3DRS_ZENABLE, FALSE);
+        mDevice-&gt;SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+        mDevice-&gt;SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+        mDevice-&gt;SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+        mDevice-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+        mDevice-&gt;SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+
+        if (clearParams.mask &amp; GL_COLOR_BUFFER_BIT)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_COLORWRITEENABLE,
+                                    gl_d3d9::ConvertColorMask(clearParams.colorMaskRed,
+                                                              clearParams.colorMaskGreen,
+                                                              clearParams.colorMaskBlue,
+                                                              clearParams.colorMaskAlpha));
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, 0);
+        }
+
+        if (stencilUnmasked != 0x0 &amp;&amp; (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT))
+        {
+            mDevice-&gt;SetRenderState(D3DRS_STENCILENABLE, TRUE);
+            mDevice-&gt;SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILREF, stencil);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE);
+            mDevice-&gt;SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+        }
+        else
+        {
+            mDevice-&gt;SetRenderState(D3DRS_STENCILENABLE, FALSE);
+        }
+
+        mDevice-&gt;SetPixelShader(NULL);
+        mDevice-&gt;SetVertexShader(NULL);
+        mDevice-&gt;SetFVF(D3DFVF_XYZRHW);
+        mDevice-&gt;SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
+        mDevice-&gt;SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+        mDevice-&gt;SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+        mDevice-&gt;SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
+        mDevice-&gt;SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR);
+        mDevice-&gt;SetRenderState(D3DRS_TEXTUREFACTOR, color);
+        mDevice-&gt;SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF);
+
+        for(int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+        {
+            mDevice-&gt;SetStreamSourceFreq(i, 1);
+        }
+
+        float quad[4][4];   // A quadrilateral covering the target, aligned to match the edges
+        quad[0][0] = -0.5f;
+        quad[0][1] = mRenderTargetDesc.height - 0.5f;
+        quad[0][2] = 0.0f;
+        quad[0][3] = 1.0f;
+
+        quad[1][0] = mRenderTargetDesc.width - 0.5f;
+        quad[1][1] = mRenderTargetDesc.height - 0.5f;
+        quad[1][2] = 0.0f;
+        quad[1][3] = 1.0f;
+
+        quad[2][0] = -0.5f;
+        quad[2][1] = -0.5f;
+        quad[2][2] = 0.0f;
+        quad[2][3] = 1.0f;
+
+        quad[3][0] = mRenderTargetDesc.width - 0.5f;
+        quad[3][1] = -0.5f;
+        quad[3][2] = 0.0f;
+        quad[3][3] = 1.0f;
+
+        startScene();
+        mDevice-&gt;DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4]));
+
+        if (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT)
+        {
+            mDevice-&gt;SetRenderState(D3DRS_ZENABLE, TRUE);
+            mDevice-&gt;SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+            mDevice-&gt;Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil);
+        }
+
+        if (mMaskedClearSavedState != NULL)
+        {
+            mMaskedClearSavedState-&gt;Apply();
+        }
+    }
+    else if (clearParams.mask)
+    {
+        DWORD dxClearFlags = 0;
+        if (clearParams.mask &amp; GL_COLOR_BUFFER_BIT)
+        {
+            dxClearFlags |= D3DCLEAR_TARGET;
+        }
+        if (clearParams.mask &amp; GL_DEPTH_BUFFER_BIT)
+        {
+            dxClearFlags |= D3DCLEAR_ZBUFFER;
+        }
+        if (clearParams.mask &amp; GL_STENCIL_BUFFER_BIT)
+        {
+            dxClearFlags |= D3DCLEAR_STENCIL;
+        }
+
+        mDevice-&gt;Clear(0, NULL, dxClearFlags, color, depth, stencil);
+    }
+}
+
+void Renderer9::markAllStateDirty()
+{
+    mAppliedRenderTargetSerial = 0;
+    mAppliedDepthbufferSerial = 0;
+    mAppliedStencilbufferSerial = 0;
+    mDepthStencilInitialized = false;
+    mRenderTargetDescInitialized = false;
+
+    mForceSetDepthStencilState = true;
+    mForceSetRasterState = true;
+    mForceSetScissor = true;
+    mForceSetViewport = true;
+    mForceSetBlendState = true;
+
+    for (unsigned int i = 0; i &lt; gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
+    {
+        mForceSetVertexSamplerStates[i] = true;
+        mCurVertexTextureSerials[i] = 0;
+    }
+    for (unsigned int i = 0; i &lt; gl::MAX_TEXTURE_IMAGE_UNITS; i++)
+    {
+        mForceSetPixelSamplerStates[i] = true;
+        mCurPixelTextureSerials[i] = 0;
+    }
+
+    mAppliedIBSerial = 0;
+    mAppliedProgramBinarySerial = 0;
+    mDxUniformsDirty = true;
+
+    mVertexDeclarationCache.markStateDirty();
+}
+
+void Renderer9::releaseDeviceResources()
+{
+    while (!mEventQueryPool.empty())
+    {
+        mEventQueryPool.back()-&gt;Release();
+        mEventQueryPool.pop_back();
+    }
+
+    SafeRelease(mMaskedClearSavedState);
+
+    mVertexShaderCache.clear();
+    mPixelShaderCache.clear();
+
+    SafeDelete(mBlit);
+    SafeDelete(mVertexDataManager);
+    SafeDelete(mIndexDataManager);
+    SafeDelete(mLineLoopIB);
+
+    for (int i = 0; i &lt; NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++)
+    {
+        SafeDelete(mNullColorbufferCache[i].buffer);
+    }
+
+}
+
+
+void Renderer9::notifyDeviceLost()
+{
+    mDeviceLost = true;
+    mDisplay-&gt;notifyDeviceLost();
+}
+
+bool Renderer9::isDeviceLost()
+{
+    return mDeviceLost;
+}
+
+// set notify to true to broadcast a message to all contexts of the device loss
+bool Renderer9::testDeviceLost(bool notify)
+{
+    HRESULT status = getDeviceStatusCode();
+    bool isLost = FAILED(status);
+
+    if (isLost)
+    {
+        // ensure we note the device loss --
+        // we'll probably get this done again by notifyDeviceLost
+        // but best to remember it!
+        // Note that we don't want to clear the device loss status here
+        // -- this needs to be done by resetDevice
+        mDeviceLost = true;
+        if (notify)
+        {
+            notifyDeviceLost();
+        }
+    }
+
+    return isLost;
+}
+
+HRESULT Renderer9::getDeviceStatusCode()
+{
+    HRESULT status = D3D_OK;
+
+    if (mDeviceEx)
+    {
+        status = mDeviceEx-&gt;CheckDeviceState(NULL);
+    }
+    else if (mDevice)
+    {
+        status = mDevice-&gt;TestCooperativeLevel();
+    }
+
+    return status;
+}
+
+bool Renderer9::testDeviceResettable()
+{
+    // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted
+    // DEVICEREMOVED indicates the device has been stopped and must be recreated
+    switch (getDeviceStatusCode())
+    {
+      case D3DERR_DEVICENOTRESET:
+      case D3DERR_DEVICEHUNG:
+        return true;
+      case D3DERR_DEVICELOST:
+        return (mDeviceEx != NULL);
+      case D3DERR_DEVICEREMOVED:
+        ASSERT(mDeviceEx != NULL);
+        return isRemovedDeviceResettable();
+      default:
+        return false;
+    }
+}
+
+bool Renderer9::resetDevice()
+{
+    releaseDeviceResources();
+
+    D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters();
+
+    HRESULT result = D3D_OK;
+    bool lost = testDeviceLost(false);
+    bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED);
+
+    // Device Removed is a feature which is only present with D3D9Ex
+    ASSERT(mDeviceEx != NULL || !removedDevice);
+
+    for (int attempts = 3; lost &amp;&amp; attempts &gt; 0; attempts--)
+    {
+        if (removedDevice)
+        {
+            // Device removed, which may trigger on driver reinstallation,
+            // may cause a longer wait other reset attempts before the
+            // system is ready to handle creating a new device.
+            Sleep(800);
+            lost = !resetRemovedDevice();
+        }
+        else if (mDeviceEx)
+        {
+            Sleep(500);   // Give the graphics driver some CPU time
+            result = mDeviceEx-&gt;ResetEx(&amp;presentParameters, NULL);
+            lost = testDeviceLost(false);
+        }
+        else
+        {
+            result = mDevice-&gt;TestCooperativeLevel();
+            while (result == D3DERR_DEVICELOST)
+            {
+                Sleep(100);   // Give the graphics driver some CPU time
+                result = mDevice-&gt;TestCooperativeLevel();
+            }
+
+            if (result == D3DERR_DEVICENOTRESET)
+            {
+                result = mDevice-&gt;Reset(&amp;presentParameters);
+            }
+            lost = testDeviceLost(false);
+        }
+    }
+
+    if (FAILED(result))
+    {
+        ERR(&quot;Reset/ResetEx failed multiple times: 0x%08X&quot;, result);
+        return false;
+    }
+
+    if (removedDevice &amp;&amp; lost)
+    {
+        ERR(&quot;Device lost reset failed multiple times&quot;);
+        return false;
+    }
+
+    // If the device was removed, we already finished re-initialization in resetRemovedDevice
+    if (!removedDevice)
+    {
+        // reset device defaults
+        initializeDevice();
+    }
+
+    mDeviceLost = false;
+
+    return true;
+}
+
+bool Renderer9::isRemovedDeviceResettable() const
+{
+    bool success = false;
+
+#ifdef ANGLE_ENABLE_D3D9EX
+    IDirect3D9Ex *d3d9Ex = NULL;
+    typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+    Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast&lt;Direct3DCreate9ExFunc&gt;(GetProcAddress(mD3d9Module, &quot;Direct3DCreate9Ex&quot;));
+
+    if (Direct3DCreate9ExPtr &amp;&amp; SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &amp;d3d9Ex)))
+    {
+        D3DCAPS9 deviceCaps;
+        HRESULT result = d3d9Ex-&gt;GetDeviceCaps(mAdapter, mDeviceType, &amp;deviceCaps);
+        success = SUCCEEDED(result);
+    }
+
+    SafeRelease(d3d9Ex);
+#else
+    ASSERT(UNREACHABLE());
+#endif
+
+    return success;
+}
+
+bool Renderer9::resetRemovedDevice()
+{
+    // From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx:
+    // The hardware adapter has been removed. Application must destroy the device, do enumeration of
+    // adapters and create another Direct3D device. If application continues rendering without
+    // calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only.
+    deinitialize();
+    return (initialize() == EGL_SUCCESS);
+}
+
+DWORD Renderer9::getAdapterVendor() const
+{
+    return mAdapterIdentifier.VendorId;
+}
+
+std::string Renderer9::getRendererDescription() const
+{
+    std::ostringstream rendererString;
+
+    rendererString &lt;&lt; mAdapterIdentifier.Description;
+    if (getShareHandleSupport())
+    {
+        rendererString &lt;&lt; &quot; Direct3D9Ex&quot;;
+    }
+    else
+    {
+        rendererString &lt;&lt; &quot; Direct3D9&quot;;
+    }
+
+    rendererString &lt;&lt; &quot; vs_&quot; &lt;&lt; D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) &lt;&lt; &quot;_&quot; &lt;&lt; D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion);
+    rendererString &lt;&lt; &quot; ps_&quot; &lt;&lt; D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) &lt;&lt; &quot;_&quot; &lt;&lt; D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion);
+
+    return rendererString.str();
+}
+
+GUID Renderer9::getAdapterIdentifier() const
+{
+    return mAdapterIdentifier.DeviceIdentifier;
+}
+
+void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
+{
+    for (int multiSampleIndex = 0; multiSampleIndex &lt;= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
+    {
+        HRESULT result = mD3d9-&gt;CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
+                                                           TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+
+        multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
+    }
+}
+
+bool Renderer9::getBGRATextureSupport() const
+{
+    // DirectX 9 always supports BGRA
+    return true;
+}
+
+bool Renderer9::getDXT1TextureSupport()
+{
+    return mDXT1TextureSupport;
+}
+
+bool Renderer9::getDXT3TextureSupport()
+{
+    return mDXT3TextureSupport;
+}
+
+bool Renderer9::getDXT5TextureSupport()
+{
+    return mDXT5TextureSupport;
+}
+
+bool Renderer9::getDepthTextureSupport() const
+{
+    return mDepthTextureSupport;
+}
+
+bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable)
+{
+    *filtering = mFloat32FilterSupport;
+    *renderable = mFloat32RenderSupport;
+    return mFloat32TextureSupport;
+}
+
+bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable)
+{
+    *filtering = mFloat16FilterSupport;
+    *renderable = mFloat16RenderSupport;
+    return mFloat16TextureSupport;
+}
+
+bool Renderer9::getLuminanceTextureSupport()
+{
+    return mLuminanceTextureSupport;
+}
+
+bool Renderer9::getLuminanceAlphaTextureSupport()
+{
+    return mLuminanceAlphaTextureSupport;
+}
+
+bool Renderer9::getTextureFilterAnisotropySupport() const
+{
+    return mSupportsTextureFilterAnisotropy;
+}
+
+float Renderer9::getTextureMaxAnisotropy() const
+{
+    if (mSupportsTextureFilterAnisotropy)
+    {
+        return static_cast&lt;float&gt;(mDeviceCaps.MaxAnisotropy);
+    }
+    return 1.0f;
+}
+
+bool Renderer9::getEventQuerySupport()
+{
+    return mEventQuerySupport;
+}
+
+unsigned int Renderer9::getMaxVertexTextureImageUnits() const
+{
+    META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 &lt;= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+    return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0;
+}
+
+unsigned int Renderer9::getMaxCombinedTextureImageUnits() const
+{
+    return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits();
+}
+
+unsigned int Renderer9::getReservedVertexUniformVectors() const
+{
+    return 2;   // dx_ViewAdjust and dx_DepthRange.
+}
+
+unsigned int Renderer9::getReservedFragmentUniformVectors() const
+{
+    return 3;   // dx_ViewCoords, dx_DepthFront and dx_DepthRange.
+}
+
+unsigned int Renderer9::getMaxVertexUniformVectors() const
+{
+    return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors();
+}
+
+unsigned int Renderer9::getMaxFragmentUniformVectors() const
+{
+    const int maxPixelConstantVectors = (getMajorShaderModel() &gt;= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2;
+
+    return maxPixelConstantVectors - getReservedFragmentUniformVectors();
+}
+
+unsigned int Renderer9::getMaxVaryingVectors() const
+{
+    return (getMajorShaderModel() &gt;= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2;
+}
+
+bool Renderer9::getNonPower2TextureSupport() const
+{
+    return mSupportsNonPower2Textures;
+}
+
+bool Renderer9::getOcclusionQuerySupport() const
+{
+    return mOcclusionQuerySupport;
+}
+
+bool Renderer9::getInstancingSupport() const
+{
+    return mDeviceCaps.PixelShaderVersion &gt;= D3DPS_VERSION(3, 0);
+}
+
+bool Renderer9::getShareHandleSupport() const
+{
+    // PIX doesn't seem to support using share handles, so disable them.
+    return (mD3d9Ex != NULL) &amp;&amp; !gl::perfActive();
+}
+
+bool Renderer9::getDerivativeInstructionSupport() const
+{
+    return (mDeviceCaps.PS20Caps.Caps &amp; D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0;
+}
+
+bool Renderer9::getPostSubBufferSupport() const
+{
+    return true;
+}
+
+int Renderer9::getMajorShaderModel() const
+{
+    return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion);
+}
+
+float Renderer9::getMaxPointSize() const
+{
+    // Point size clamped at 1.0f for SM2
+    return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f;
+}
+
+int Renderer9::getMaxViewportDimension() const
+{
+    int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()),
+                                       (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE);
+    return maxTextureDimension;
+}
+
+int Renderer9::getMaxTextureWidth() const
+{
+    return (int)mDeviceCaps.MaxTextureWidth;
+}
+
+int Renderer9::getMaxTextureHeight() const
+{
+    return (int)mDeviceCaps.MaxTextureHeight;
+}
+
+bool Renderer9::get32BitIndexSupport() const
+{
+    return mDeviceCaps.MaxVertexIndex &gt;= (1 &lt;&lt; 16);
+}
+
+DWORD Renderer9::getCapsDeclTypes() const
+{
+    return mDeviceCaps.DeclTypes;
+}
+
+int Renderer9::getMinSwapInterval() const
+{
+    return mMinSwapInterval;
+}
+
+int Renderer9::getMaxSwapInterval() const
+{
+    return mMaxSwapInterval;
+}
+
+int Renderer9::getMaxSupportedSamples() const
+{
+    return mMaxSupportedSamples;
+}
+
+int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+{
+    if (requested == 0)
+    {
+        return requested;
+    }
+
+    std::map&lt;D3DFORMAT, bool *&gt;::const_iterator itr = mMultiSampleSupport.find(format);
+    if (itr == mMultiSampleSupport.end())
+    {
+        if (format == D3DFMT_UNKNOWN)
+            return 0;
+        return -1;
+    }
+
+    for (int i = requested; i &lt;= D3DMULTISAMPLE_16_SAMPLES; ++i)
+    {
+        if (itr-&gt;second[i] &amp;&amp; i != D3DMULTISAMPLE_NONMASKABLE)
+        {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+unsigned int Renderer9::getMaxRenderTargets() const
+{
+    // we do not support MRT in d3d9
+    return 1;
+}
+
+D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLint internalformat)
+{
+    switch (internalformat)
+    {
+      case GL_DEPTH_COMPONENT16:
+      case GL_DEPTH_COMPONENT32_OES:
+      case GL_DEPTH24_STENCIL8_OES:
+        return D3DFMT_INTZ;
+      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        return D3DFMT_DXT1;
+      case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
+        return D3DFMT_DXT3;
+      case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
+        return D3DFMT_DXT5;
+      case GL_RGBA32F_EXT:
+      case GL_RGB32F_EXT:
+      case GL_ALPHA32F_EXT:
+      case GL_LUMINANCE32F_EXT:
+      case GL_LUMINANCE_ALPHA32F_EXT:
+        return D3DFMT_A32B32G32R32F;
+      case GL_RGBA16F_EXT:
+      case GL_RGB16F_EXT:
+      case GL_ALPHA16F_EXT:
+      case GL_LUMINANCE16F_EXT:
+      case GL_LUMINANCE_ALPHA16F_EXT:
+        return D3DFMT_A16B16G16R16F;
+      case GL_LUMINANCE8_EXT:
+        if (getLuminanceTextureSupport())
+        {
+            return D3DFMT_L8;
+        }
+        break;
+      case GL_LUMINANCE8_ALPHA8_EXT:
+        if (getLuminanceAlphaTextureSupport())
+        {
+            return D3DFMT_A8L8;
+        }
+        break;
+      case GL_RGB8_OES:
+      case GL_RGB565:
+        return D3DFMT_X8R8G8B8;
+    }
+
+    return D3DFMT_A8R8G8B8;
+}
+
+bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source)
+{
+    bool result = false;
+
+    if (source &amp;&amp; dest)
+    {
+        TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source-&gt;getStorageInstance());
+        TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest-&gt;getStorageInstance());
+
+        int levels = source9-&gt;levelCount();
+        for (int i = 0; i &lt; levels; ++i)
+        {
+            IDirect3DSurface9 *srcSurf = source9-&gt;getSurfaceLevel(i, false);
+            IDirect3DSurface9 *dstSurf = dest9-&gt;getSurfaceLevel(i, false);
+            
+            result = copyToRenderTarget(dstSurf, srcSurf, source9-&gt;isManaged());
+
+            if (srcSurf) srcSurf-&gt;Release();
+            if (dstSurf) dstSurf-&gt;Release();
+
+            if (!result)
+                return false;
+        }
+    }
+
+    return result;
+}
+
+bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source)
+{
+    bool result = false;
+
+    if (source &amp;&amp; dest)
+    {
+        TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source-&gt;getStorageInstance());
+        TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest-&gt;getStorageInstance());
+        int levels = source9-&gt;levelCount();
+        for (int f = 0; f &lt; 6; f++)
+        {
+            for (int i = 0; i &lt; levels; i++)
+            {
+                IDirect3DSurface9 *srcSurf = source9-&gt;getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
+                IDirect3DSurface9 *dstSurf = dest9-&gt;getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
+
+                result = copyToRenderTarget(dstSurf, srcSurf, source9-&gt;isManaged());
+
+                if (srcSurf) srcSurf-&gt;Release();
+                if (dstSurf) dstSurf-&gt;Release();
+
+                if (!result)
+                    return false;
+            }
+        }
+    }
+
+    return result;
+}
+
+D3DPOOL Renderer9::getBufferPool(DWORD usage) const
+{
+    if (mD3d9Ex != NULL)
+    {
+        return D3DPOOL_DEFAULT;
+    }
+    else
+    {
+        if (!(usage &amp; D3DUSAGE_DYNAMIC))
+        {
+            return D3DPOOL_MANAGED;
+        }
+    }
+
+    return D3DPOOL_DEFAULT;
+}
+
+bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                          GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level)
+{
+    RECT rect;
+    rect.left = sourceRect.x;
+    rect.top = sourceRect.y;
+    rect.right = sourceRect.x + sourceRect.width;
+    rect.bottom = sourceRect.y + sourceRect.height;
+
+    return mBlit-&gt;copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level);
+}
+
+bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                          GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level)
+{
+    RECT rect;
+    rect.left = sourceRect.x;
+    rect.top = sourceRect.y;
+    rect.right = sourceRect.x + sourceRect.width;
+    rect.bottom = sourceRect.y + sourceRect.height;
+
+    return mBlit-&gt;copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level);
+}
+
+bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &amp;readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &amp;drawRect,
+                         bool blitRenderTarget, bool blitDepthStencil)
+{
+    endScene();
+
+    if (blitRenderTarget)
+    {
+        gl::Renderbuffer *readBuffer = readFramebuffer-&gt;getColorbuffer(0);
+        gl::Renderbuffer *drawBuffer = drawFramebuffer-&gt;getColorbuffer(0);
+        RenderTarget9 *readRenderTarget = NULL;
+        RenderTarget9 *drawRenderTarget = NULL;
+        IDirect3DSurface9* readSurface = NULL;
+        IDirect3DSurface9* drawSurface = NULL;
+
+        if (readBuffer)
+        {
+            readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer-&gt;getRenderTarget());
+        }
+        if (drawBuffer)
+        {
+            drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer-&gt;getRenderTarget());
+        }
+
+        if (readRenderTarget)
+        {
+            readSurface = readRenderTarget-&gt;getSurface();
+        }
+        if (drawRenderTarget)
+        {
+            drawSurface = drawRenderTarget-&gt;getSurface();
+        }
+
+        if (!readSurface || !drawSurface)
+        {
+            ERR(&quot;Failed to retrieve the render target.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        RECT srcRect;
+        srcRect.left = readRect.x;
+        srcRect.right = readRect.x + readRect.width;
+        srcRect.top = readRect.y;
+        srcRect.bottom = readRect.y + readRect.height;
+
+        RECT dstRect;
+        dstRect.left = drawRect.x;
+        dstRect.right = drawRect.x + drawRect.width;
+        dstRect.top = drawRect.y;
+        dstRect.bottom = drawRect.y + drawRect.height;
+
+        HRESULT result = mDevice-&gt;StretchRect(readSurface, &amp;srcRect, drawSurface, &amp;dstRect, D3DTEXF_NONE);
+
+        readSurface-&gt;Release();
+        drawSurface-&gt;Release();
+
+        if (FAILED(result))
+        {
+            ERR(&quot;BlitFramebufferANGLE failed: StretchRect returned %x.&quot;, result);
+            return false;
+        }
+    }
+
+    if (blitDepthStencil)
+    {
+        gl::Renderbuffer *readBuffer = readFramebuffer-&gt;getDepthOrStencilbuffer();
+        gl::Renderbuffer *drawBuffer = drawFramebuffer-&gt;getDepthOrStencilbuffer();
+        RenderTarget9 *readDepthStencil = NULL;
+        RenderTarget9 *drawDepthStencil = NULL;
+        IDirect3DSurface9* readSurface = NULL;
+        IDirect3DSurface9* drawSurface = NULL;
+
+        if (readBuffer)
+        {
+            readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer-&gt;getDepthStencil());
+        }
+        if (drawBuffer)
+        {
+            drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer-&gt;getDepthStencil());
+        }
+
+        if (readDepthStencil)
+        {
+            readSurface = readDepthStencil-&gt;getSurface();
+        }
+        if (drawDepthStencil)
+        {
+            drawSurface = drawDepthStencil-&gt;getSurface();
+        }
+
+        if (!readSurface || !drawSurface)
+        {
+            ERR(&quot;Failed to retrieve the render target.&quot;);
+            return gl::error(GL_OUT_OF_MEMORY, false);
+        }
+
+        HRESULT result = mDevice-&gt;StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE);
+
+        readSurface-&gt;Release();
+        drawSurface-&gt;Release();
+
+        if (FAILED(result))
+        {
+            ERR(&quot;BlitFramebufferANGLE failed: StretchRect returned %x.&quot;, result);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, 
+                           GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels)
+{
+    RenderTarget9 *renderTarget = NULL;
+    IDirect3DSurface9 *surface = NULL;
+    gl::Renderbuffer *colorbuffer = framebuffer-&gt;getColorbuffer(0);
+
+    if (colorbuffer)
+    {
+        renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer-&gt;getRenderTarget());
+    }
+    
+    if (renderTarget)
+    {
+        surface = renderTarget-&gt;getSurface();
+    }
+
+    if (!surface)
+    {
+        // context must be lost
+        return;
+    }
+
+    D3DSURFACE_DESC desc;
+    surface-&gt;GetDesc(&amp;desc);
+
+    if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
+    {
+        UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
+        surface-&gt;Release();
+        return gl::error(GL_OUT_OF_MEMORY);
+    }
+
+    HRESULT result;
+    IDirect3DSurface9 *systemSurface = NULL;
+    bool directToPixels = !packReverseRowOrder &amp;&amp; packAlignment &lt;= 4 &amp;&amp; getShareHandleSupport() &amp;&amp;
+                          x == 0 &amp;&amp; y == 0 &amp;&amp; UINT(width) == desc.Width &amp;&amp; UINT(height) == desc.Height &amp;&amp;
+                          desc.Format == D3DFMT_A8R8G8B8 &amp;&amp; format == GL_BGRA_EXT &amp;&amp; type == GL_UNSIGNED_BYTE;
+    if (directToPixels)
+    {
+        // Use the pixels ptr as a shared handle to write directly into client's memory
+        result = mDevice-&gt;CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+                                                      D3DPOOL_SYSTEMMEM, &amp;systemSurface, &amp;pixels);
+        if (FAILED(result))
+        {
+            // Try again without the shared handle
+            directToPixels = false;
+        }
+    }
+
+    if (!directToPixels)
+    {
+        result = mDevice-&gt;CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format,
+                                                      D3DPOOL_SYSTEMMEM, &amp;systemSurface, NULL);
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            surface-&gt;Release();
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    result = mDevice-&gt;GetRenderTargetData(surface, systemSurface);
+    surface-&gt;Release();
+    surface = NULL;
+
+    if (FAILED(result))
+    {
+        systemSurface-&gt;Release();
+
+        // It turns out that D3D will sometimes produce more error
+        // codes than those documented.
+        if (d3d9::isDeviceLostError(result))
+        {
+            notifyDeviceLost();
+            return gl::error(GL_OUT_OF_MEMORY);
+        }
+        else
+        {
+            UNREACHABLE();
+            return;
+        }
+
+    }
+
+    if (directToPixels)
+    {
+        systemSurface-&gt;Release();
+        return;
+    }
+
+    RECT rect;
+    rect.left = gl::clamp(x, 0L, static_cast&lt;LONG&gt;(desc.Width));
+    rect.top = gl::clamp(y, 0L, static_cast&lt;LONG&gt;(desc.Height));
+    rect.right = gl::clamp(x + width, 0L, static_cast&lt;LONG&gt;(desc.Width));
+    rect.bottom = gl::clamp(y + height, 0L, static_cast&lt;LONG&gt;(desc.Height));
+
+    D3DLOCKED_RECT lock;
+    result = systemSurface-&gt;LockRect(&amp;lock, &amp;rect, D3DLOCK_READONLY);
+
+    if (FAILED(result))
+    {
+        UNREACHABLE();
+        systemSurface-&gt;Release();
+
+        return;   // No sensible error to generate
+    }
+
+    unsigned char *dest = (unsigned char*)pixels;
+    unsigned short *dest16 = (unsigned short*)pixels;
+
+    unsigned char *source;
+    int inputPitch;
+    if (packReverseRowOrder)
+    {
+        source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1);
+        inputPitch = -lock.Pitch;
+    }
+    else
+    {
+        source = (unsigned char*)lock.pBits;
+        inputPitch = lock.Pitch;
+    }
+
+    unsigned int fastPixelSize = 0;
+
+    if (desc.Format == D3DFMT_A8R8G8B8 &amp;&amp;
+        format == GL_BGRA_EXT &amp;&amp;
+        type == GL_UNSIGNED_BYTE)
+    {
+        fastPixelSize = 4;
+    }
+    else if ((desc.Format == D3DFMT_A4R4G4B4 &amp;&amp;
+             format == GL_BGRA_EXT &amp;&amp;
+             type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) ||
+             (desc.Format == D3DFMT_A1R5G5B5 &amp;&amp;
+             format == GL_BGRA_EXT &amp;&amp;
+             type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT))
+    {
+        fastPixelSize = 2;
+    }
+    else if (desc.Format == D3DFMT_A16B16G16R16F &amp;&amp;
+             format == GL_RGBA &amp;&amp;
+             type == GL_HALF_FLOAT_OES)
+    {
+        fastPixelSize = 8;
+    }
+    else if (desc.Format == D3DFMT_A32B32G32R32F &amp;&amp;
+             format == GL_RGBA &amp;&amp;
+             type == GL_FLOAT)
+    {
+        fastPixelSize = 16;
+    }
+
+    for (int j = 0; j &lt; rect.bottom - rect.top; j++)
+    {
+        if (fastPixelSize != 0)
+        {
+            // Fast path for formats which require no translation:
+            // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE
+            // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT
+            // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT
+            // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES
+            // D3DFMT_A32B32G32R32F to RGBA/FLOAT
+            // 
+            // Note that buffers with no alpha go through the slow path below.
+            memcpy(dest + j * outputPitch,
+                   source + j * inputPitch,
+                   (rect.right - rect.left) * fastPixelSize);
+            continue;
+        }
+        else if (desc.Format == D3DFMT_A8R8G8B8 &amp;&amp;
+                 format == GL_RGBA &amp;&amp;
+                 type == GL_UNSIGNED_BYTE)
+        {
+            // Fast path for swapping red with blue
+            for (int i = 0; i &lt; rect.right - rect.left; i++)
+            {
+                unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+                *(unsigned int*)(dest + 4 * i + j * outputPitch) =
+                    (argb &amp; 0xFF00FF00) |       // Keep alpha and green
+                    (argb &amp; 0x00FF0000) &gt;&gt; 16 | // Move red to blue
+                    (argb &amp; 0x000000FF) &lt;&lt; 16;  // Move blue to red
+            }
+            continue;
+        }
+
+        for (int i = 0; i &lt; rect.right - rect.left; i++)
+        {
+            float r;
+            float g;
+            float b;
+            float a;
+
+            switch (desc.Format)
+            {
+              case D3DFMT_R5G6B5:
+                {
+                    unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+                    a = 1.0f;
+                    b = (rgb &amp; 0x001F) * (1.0f / 0x001F);
+                    g = (rgb &amp; 0x07E0) * (1.0f / 0x07E0);
+                    r = (rgb &amp; 0xF800) * (1.0f / 0xF800);
+                }
+                break;
+              case D3DFMT_A1R5G5B5:
+                {
+                    unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
+
+                    a = (argb &amp; 0x8000) ? 1.0f : 0.0f;
+                    b = (argb &amp; 0x001F) * (1.0f / 0x001F);
+                    g = (argb &amp; 0x03E0) * (1.0f / 0x03E0);
+                    r = (argb &amp; 0x7C00) * (1.0f / 0x7C00);
+                }
+                break;
+              case D3DFMT_A8R8G8B8:
+                {
+                    unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+                    a = (argb &amp; 0xFF000000) * (1.0f / 0xFF000000);
+                    b = (argb &amp; 0x000000FF) * (1.0f / 0x000000FF);
+                    g = (argb &amp; 0x0000FF00) * (1.0f / 0x0000FF00);
+                    r = (argb &amp; 0x00FF0000) * (1.0f / 0x00FF0000);
+                }
+                break;
+              case D3DFMT_X8R8G8B8:
+                {
+                    unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+                    a = 1.0f;
+                    b = (xrgb &amp; 0x000000FF) * (1.0f / 0x000000FF);
+                    g = (xrgb &amp; 0x0000FF00) * (1.0f / 0x0000FF00);
+                    r = (xrgb &amp; 0x00FF0000) * (1.0f / 0x00FF0000);
+                }
+                break;
+              case D3DFMT_A2R10G10B10:
+                {
+                    unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
+
+                    a = (argb &amp; 0xC0000000) * (1.0f / 0xC0000000);
+                    b = (argb &amp; 0x000003FF) * (1.0f / 0x000003FF);
+                    g = (argb &amp; 0x000FFC00) * (1.0f / 0x000FFC00);
+                    r = (argb &amp; 0x3FF00000) * (1.0f / 0x3FF00000);
+                }
+                break;
+              case D3DFMT_A32B32G32R32F:
+                {
+                    // float formats in D3D are stored rgba, rather than the other way round
+                    r = *((float*)(source + 16 * i + j * inputPitch) + 0);
+                    g = *((float*)(source + 16 * i + j * inputPitch) + 1);
+                    b = *((float*)(source + 16 * i + j * inputPitch) + 2);
+                    a = *((float*)(source + 16 * i + j * inputPitch) + 3);
+                }
+                break;
+              case D3DFMT_A16B16G16R16F:
+                {
+                    // float formats in D3D are stored rgba, rather than the other way round
+                    r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0));
+                    g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1));
+                    b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2));
+                    a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3));
+                }
+                break;
+              default:
+                UNIMPLEMENTED();   // FIXME
+                UNREACHABLE();
+                return;
+            }
+
+            switch (format)
+            {
+              case GL_RGBA:
+                switch (type)
+                {
+                  case GL_UNSIGNED_BYTE:
+                    dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
+                    dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+                    dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
+                    dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+                    break;
+                  default: UNREACHABLE();
+                }
+                break;
+              case GL_BGRA_EXT:
+                switch (type)
+                {
+                  case GL_UNSIGNED_BYTE:
+                    dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+                    dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+                    dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+                    dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+                    break;
+                  case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+                    // According to the desktop GL spec in the &quot;Transfer of Pixel Rectangles&quot; section
+                    // this type is packed as follows:
+                    //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+                    //  --------------------------------------------------------------------------------
+                    // |       4th         |        3rd         |        2nd        |   1st component   |
+                    //  --------------------------------------------------------------------------------
+                    // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+                    dest16[i + j * outputPitch / sizeof(unsigned short)] =
+                        ((unsigned short)(15 * a + 0.5f) &lt;&lt; 12)|
+                        ((unsigned short)(15 * r + 0.5f) &lt;&lt; 8) |
+                        ((unsigned short)(15 * g + 0.5f) &lt;&lt; 4) |
+                        ((unsigned short)(15 * b + 0.5f) &lt;&lt; 0);
+                    break;
+                  case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+                    // According to the desktop GL spec in the &quot;Transfer of Pixel Rectangles&quot; section
+                    // this type is packed as follows:
+                    //   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
+                    //  --------------------------------------------------------------------------------
+                    // | 4th |          3rd           |           2nd          |      1st component     |
+                    //  --------------------------------------------------------------------------------
+                    // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+                    dest16[i + j * outputPitch / sizeof(unsigned short)] =
+                        ((unsigned short)(     a + 0.5f) &lt;&lt; 15) |
+                        ((unsigned short)(31 * r + 0.5f) &lt;&lt; 10) |
+                        ((unsigned short)(31 * g + 0.5f) &lt;&lt; 5) |
+                        ((unsigned short)(31 * b + 0.5f) &lt;&lt; 0);
+                    break;
+                  default: UNREACHABLE();
+                }
+                break;
+              case GL_RGB:
+                switch (type)
+                {
+                  case GL_UNSIGNED_SHORT_5_6_5:
+                    dest16[i + j * outputPitch / sizeof(unsigned short)] = 
+                        ((unsigned short)(31 * b + 0.5f) &lt;&lt; 0) |
+                        ((unsigned short)(63 * g + 0.5f) &lt;&lt; 5) |
+                        ((unsigned short)(31 * r + 0.5f) &lt;&lt; 11);
+                    break;
+                  case GL_UNSIGNED_BYTE:
+                    dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
+                    dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+                    dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
+                    break;
+                  default: UNREACHABLE();
+                }
+                break;
+              default: UNREACHABLE();
+            }
+        }
+    }
+
+    systemSurface-&gt;UnlockRect();
+
+    systemSurface-&gt;Release();
+}
+
+RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth)
+{
+    SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
+    IDirect3DSurface9 *surface = NULL;
+    if (depth)
+    {
+        surface = swapChain9-&gt;getDepthStencil();
+    }
+    else
+    {
+        surface = swapChain9-&gt;getRenderTarget();
+    }
+
+    RenderTarget9 *renderTarget = new RenderTarget9(this, surface);
+
+    return renderTarget;
+}
+
+RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth)
+{
+    RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples);
+    return renderTarget;
+}
+
+ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type)
+{
+    ShaderExecutable9 *executable = NULL;
+
+    switch (type)
+    {
+      case rx::SHADER_VERTEX:
+        {
+            IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length);
+            if (vshader)
+            {
+                executable = new ShaderExecutable9(function, length, vshader);
+            }
+        }
+        break;
+      case rx::SHADER_PIXEL:
+        {
+            IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length);
+            if (pshader)
+            {
+                executable = new ShaderExecutable9(function, length, pshader);
+            }
+        }
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+
+    return executable;
+}
+
+ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &amp;infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround)
+{
+    const char *profile = NULL;
+
+    switch (type)
+    {
+      case rx::SHADER_VERTEX:
+        profile = getMajorShaderModel() &gt;= 3 ? &quot;vs_3_0&quot; : &quot;vs_2_0&quot;;
+        break;
+      case rx::SHADER_PIXEL:
+        profile = getMajorShaderModel() &gt;= 3 ? &quot;ps_3_0&quot; : &quot;ps_2_0&quot;;
+        break;
+      default:
+        UNREACHABLE();
+        return NULL;
+    }
+
+    // ANGLE issue 486:
+    // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization
+    UINT optimizationFlags = (workaround == ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ? D3DCOMPILE_SKIP_OPTIMIZATION : ANGLE_COMPILE_OPTIMIZATION_LEVEL);
+
+    ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true);
+    if (!binary)
+        return NULL;
+
+    ShaderExecutable *executable = loadExecutable(binary-&gt;GetBufferPointer(), binary-&gt;GetBufferSize(), type);
+    binary-&gt;Release();
+
+    return executable;
+}
+
+bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
+{
+    return mBlit-&gt;boxFilter(source, dest);
+}
+
+D3DPOOL Renderer9::getTexturePool(DWORD usage) const
+{
+    if (mD3d9Ex != NULL)
+    {
+        return D3DPOOL_DEFAULT;
+    }
+    else
+    {
+        if (!(usage &amp; (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET)))
+        {
+            return D3DPOOL_MANAGED;
+        }
+    }
+
+    return D3DPOOL_DEFAULT;
+}
+
+bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
+{
+    if (source &amp;&amp; dest)
+    {
+        HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+
+        if (fromManaged)
+        {
+            D3DSURFACE_DESC desc;
+            source-&gt;GetDesc(&amp;desc);
+
+            IDirect3DSurface9 *surf = 0;
+            result = mDevice-&gt;CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &amp;surf, NULL);
+
+            if (SUCCEEDED(result))
+            {
+                Image9::copyLockableSurfaces(surf, source);
+                result = mDevice-&gt;UpdateSurface(surf, NULL, dest, NULL);
+                surf-&gt;Release();
+            }
+        }
+        else
+        {
+            endScene();
+            result = mDevice-&gt;StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
+        }
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            return false;
+        }
+    }
+
+    return true;
+}
+
+Image *Renderer9::createImage()
+{
+    return new Image9();
+}
+
+void Renderer9::generateMipmap(Image *dest, Image *src)
+{
+    Image9 *src9 = Image9::makeImage9(src);
+    Image9 *dst9 = Image9::makeImage9(dest);
+    Image9::generateMipmap(dst9, src9);
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain)
+{
+    SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain);
+    return new TextureStorage9_2D(this, swapChain9);
+}
+
+TextureStorage *Renderer9::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+{
+    return new TextureStorage9_2D(this, levels, internalformat, usage, forceRenderable, width, height);
+}
+
+TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+{
+    return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size);
+}
+
+bool Renderer9::getLUID(LUID *adapterLuid) const
+{
+    adapterLuid-&gt;HighPart = 0;
+    adapterLuid-&gt;LowPart = 0;
+
+    if (mD3d9Ex)
+    {
+        mD3d9Ex-&gt;GetAdapterLUID(mAdapter, adapterLuid);
+        return true;
+    }
+
+    return false;
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9Renderer9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,356 @@
</span><ins>+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Renderer9.h: Defines a back-end specific class for the D3D9 renderer.
+
+#ifndef LIBGLESV2_RENDERER_RENDERER9_H_
+#define LIBGLESV2_RENDERER_RENDERER9_H_
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;libGLESv2/mathutil.h&quot;
+#include &quot;libGLESv2/renderer/ShaderCache.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/VertexDeclarationCache.h&quot;
+#include &quot;libGLESv2/renderer/Renderer.h&quot;
+#include &quot;libGLESv2/renderer/RenderTarget.h&quot;
+
+namespace gl
+{
+class Renderbuffer;
+}
+
+namespace rx
+{
+class VertexDataManager;
+class IndexDataManager;
+class StreamingIndexBufferInterface;
+struct TranslatedAttribute;
+
+class Renderer9 : public Renderer
+{
+  public:
+    Renderer9(egl::Display *display, HDC hDc, bool softwareDevice);
+    virtual ~Renderer9();
+
+    static Renderer9 *makeRenderer9(Renderer *renderer);
+
+    virtual EGLint initialize();
+    virtual bool resetDevice();
+
+    virtual int generateConfigs(ConfigDesc **configDescList);
+    virtual void deleteConfigs(ConfigDesc *configDescList);
+
+    void startScene();
+    void endScene();
+
+    virtual void sync(bool block);
+
+    virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat);
+
+    IDirect3DQuery9* allocateEventQuery();
+    void freeEventQuery(IDirect3DQuery9* query);
+
+    // resource creation
+    IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length);
+    IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length);
+    HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer);
+    HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer);
+#if 0
+    void *createTexture2D();
+    void *createTextureCube();
+    void *createQuery();
+    void *createIndexBuffer();
+    void *createVertexbuffer();
+
+    // state setup
+    void applyShaders();
+    void applyConstants();
+#endif
+    virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &amp;sampler);
+    virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture);
+
+    virtual void setRasterizerState(const gl::RasterizerState &amp;rasterState);
+    virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &amp;blendState, const gl::Color &amp;blendColor,
+                               unsigned int sampleMask);
+    virtual void setDepthStencilState(const gl::DepthStencilState &amp;depthStencilState, int stencilRef,
+                                      int stencilBackRef, bool frontFaceCCW);
+
+    virtual void setScissorRectangle(const gl::Rectangle &amp;scissor, bool enabled);
+    virtual bool setViewport(const gl::Rectangle &amp;viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace,
+                             bool ignoreViewport);
+
+    virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer);
+    virtual void applyShaders(gl::ProgramBinary *programBinary);
+    virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray);
+    virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount);
+    virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances);
+    virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo);
+
+    virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances);
+    virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &amp;indexInfo, GLsizei instances);
+
+    virtual void clear(const gl::ClearParameters &amp;clearParams, gl::Framebuffer *frameBuffer);
+
+    virtual void markAllStateDirty();
+
+    // lost device
+    void notifyDeviceLost();
+    virtual bool isDeviceLost();
+    virtual bool testDeviceLost(bool notify);
+    virtual bool testDeviceResettable();
+
+    // Renderer capabilities
+    IDirect3DDevice9 *getDevice() { return mDevice; }
+    virtual DWORD getAdapterVendor() const;
+    virtual std::string getRendererDescription() const;
+    virtual GUID getAdapterIdentifier() const;
+
+    virtual bool getBGRATextureSupport() const;
+    virtual bool getDXT1TextureSupport();
+    virtual bool getDXT3TextureSupport();
+    virtual bool getDXT5TextureSupport();
+    virtual bool getEventQuerySupport();
+    virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable);
+    virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable);
+    virtual bool getLuminanceTextureSupport();
+    virtual bool getLuminanceAlphaTextureSupport();
+    virtual unsigned int getMaxVertexTextureImageUnits() const;
+    virtual unsigned int getMaxCombinedTextureImageUnits() const;
+    virtual unsigned int getReservedVertexUniformVectors() const;
+    virtual unsigned int getReservedFragmentUniformVectors() const;
+    virtual unsigned int getMaxVertexUniformVectors() const;
+    virtual unsigned int getMaxFragmentUniformVectors() const;
+    virtual unsigned int getMaxVaryingVectors() const;
+    virtual bool getNonPower2TextureSupport() const;
+    virtual bool getDepthTextureSupport() const;
+    virtual bool getOcclusionQuerySupport() const;
+    virtual bool getInstancingSupport() const;
+    virtual bool getTextureFilterAnisotropySupport() const;
+    virtual float getTextureMaxAnisotropy() const;
+    virtual bool getShareHandleSupport() const;
+    virtual bool getDerivativeInstructionSupport() const;
+    virtual bool getPostSubBufferSupport() const;
+
+    virtual int getMajorShaderModel() const;
+    virtual float getMaxPointSize() const;
+    virtual int getMaxViewportDimension() const;
+    virtual int getMaxTextureWidth() const;
+    virtual int getMaxTextureHeight() const;
+    virtual bool get32BitIndexSupport() const;
+    DWORD getCapsDeclTypes() const;
+    virtual int getMinSwapInterval() const;
+    virtual int getMaxSwapInterval() const;
+
+    virtual GLsizei getMaxSupportedSamples() const;
+    int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
+    
+    virtual unsigned int getMaxRenderTargets() const;
+
+    D3DFORMAT ConvertTextureInternalFormat(GLint internalformat);
+
+    // Pixel operations
+    virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source);
+    virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source);
+
+    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level);
+    virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &amp;sourceRect, GLenum destFormat,
+                           GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level);
+
+    virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &amp;readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &amp;drawRect,
+                          bool blitRenderTarget, bool blitDepthStencil);
+    virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+                            GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels);
+
+    // RenderTarget creation
+    virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth);
+    virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth);
+
+    // Shader operations
+    virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type);
+    virtual ShaderExecutable *compileToExecutable(gl::InfoLog &amp;infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround);
+
+    // Image operations
+    virtual Image *createImage();
+    virtual void generateMipmap(Image *dest, Image *source);
+    virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain);
+    virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+    virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+
+    // Buffer creation
+    virtual VertexBuffer *createVertexBuffer();
+    virtual IndexBuffer *createIndexBuffer();
+    virtual BufferStorage *createBufferStorage();
+
+    // Query and Fence creation
+    virtual QueryImpl *createQuery(GLenum type);
+    virtual FenceImpl *createFence();
+
+    // D3D9-renderer specific methods
+    bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest);
+
+    D3DPOOL getTexturePool(DWORD usage) const;
+
+    virtual bool getLUID(LUID *adapterLuid) const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Renderer9);
+
+    void deinitialize();
+
+    void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v);
+    void applyUniformniv(gl::Uniform *targetUniform, const GLint *v);
+    void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v);
+
+    void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+    void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer);
+
+    void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
+    bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+    gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer);
+
+    D3DPOOL getBufferPool(DWORD usage) const;
+
+    HMODULE mD3d9Module;
+    HDC mDc;
+
+    void initializeDevice();
+    D3DPRESENT_PARAMETERS getDefaultPresentParameters();
+    void releaseDeviceResources();
+
+    HRESULT getDeviceStatusCode();
+    bool isRemovedDeviceResettable() const;
+    bool resetRemovedDevice();
+
+    UINT mAdapter;
+    D3DDEVTYPE mDeviceType;
+    bool mSoftwareDevice;   // FIXME: Deprecate
+    IDirect3D9 *mD3d9;  // Always valid after successful initialization.
+    IDirect3D9Ex *mD3d9Ex;  // Might be null if D3D9Ex is not supported.
+    IDirect3DDevice9 *mDevice;
+    IDirect3DDevice9Ex *mDeviceEx;  // Might be null if D3D9Ex is not supported.
+
+    Blit *mBlit;
+
+    HWND mDeviceWindow;
+
+    bool mDeviceLost;
+    D3DCAPS9 mDeviceCaps;
+    D3DADAPTER_IDENTIFIER9 mAdapterIdentifier;
+
+    D3DPRIMITIVETYPE mPrimitiveType;
+    int mPrimitiveCount;
+    GLsizei mRepeatDraw;
+
+    bool mSceneStarted;
+    bool mSupportsNonPower2Textures;
+    bool mSupportsTextureFilterAnisotropy;
+    int mMinSwapInterval;
+    int mMaxSwapInterval;
+
+    bool mOcclusionQuerySupport;
+    bool mEventQuerySupport;
+    bool mVertexTextureSupport;
+
+    bool mDepthTextureSupport;
+
+    bool mFloat32TextureSupport;
+    bool mFloat32FilterSupport;
+    bool mFloat32RenderSupport;
+
+    bool mFloat16TextureSupport;
+    bool mFloat16FilterSupport;
+    bool mFloat16RenderSupport;
+
+    bool mDXT1TextureSupport;
+    bool mDXT3TextureSupport;
+    bool mDXT5TextureSupport;
+
+    bool mLuminanceTextureSupport;
+    bool mLuminanceAlphaTextureSupport;
+
+    std::map&lt;D3DFORMAT, bool *&gt; mMultiSampleSupport;
+    GLsizei mMaxSupportedSamples;
+
+    // current render target states
+    unsigned int mAppliedRenderTargetSerial;
+    unsigned int mAppliedDepthbufferSerial;
+    unsigned int mAppliedStencilbufferSerial;
+    bool mDepthStencilInitialized;
+    bool mRenderTargetDescInitialized;
+    rx::RenderTarget::Desc mRenderTargetDesc;
+    unsigned int mCurStencilSize;
+    unsigned int mCurDepthSize;
+
+    IDirect3DStateBlock9 *mMaskedClearSavedState;
+
+    // previously set render states
+    bool mForceSetDepthStencilState;
+    gl::DepthStencilState mCurDepthStencilState;
+    int mCurStencilRef;
+    int mCurStencilBackRef;
+    bool mCurFrontFaceCCW;
+
+    bool mForceSetRasterState;
+    gl::RasterizerState mCurRasterState;
+
+    bool mForceSetScissor;
+    gl::Rectangle mCurScissor;
+    bool mScissorEnabled;
+
+    bool mForceSetViewport;
+    gl::Rectangle mCurViewport;
+    float mCurNear;
+    float mCurFar;
+    float mCurDepthFront;
+
+    bool mForceSetBlendState;
+    gl::BlendState mCurBlendState;
+    gl::Color mCurBlendColor;
+    GLuint mCurSampleMask;
+
+    // Currently applied sampler states
+    bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+
+    bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+    gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+    // Currently applied textures
+    unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
+    unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS];
+
+    unsigned int mAppliedIBSerial;
+    unsigned int mAppliedProgramBinarySerial;
+    
+    rx::dx_VertexConstants mVertexConstants;
+    rx::dx_PixelConstants mPixelConstants;
+    bool mDxUniformsDirty;
+
+    // A pool of event queries that are currently unused.
+    std::vector&lt;IDirect3DQuery9*&gt; mEventQueryPool;
+    VertexShaderCache mVertexShaderCache;
+    PixelShaderCache mPixelShaderCache;
+
+    VertexDataManager *mVertexDataManager;
+    VertexDeclarationCache mVertexDeclarationCache;
+
+    IndexDataManager *mIndexDataManager;
+    StreamingIndexBufferInterface *mLineLoopIB;
+
+    enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 };
+    struct NullColorbufferCacheEntry
+    {
+        UINT lruCount;
+        int width;
+        int height;
+        gl::Renderbuffer *buffer;
+    } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES];
+    UINT mMaxNullColorbufferLRU;
+
+};
+
+}
+#endif // LIBGLESV2_RENDERER_RENDERER9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/Renderer9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9ShaderExecutable9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader
+// executable implementation details.
+
+#include &quot;libGLESv2/renderer/d3d9/ShaderExecutable9.h&quot;
+
+#include &quot;common/debug.h&quot;
+
+namespace rx
+{
+
+ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable)
+    : ShaderExecutable(function, length)
+{
+    mPixelExecutable = executable;
+    mVertexExecutable = NULL;
+}
+
+ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable)
+    : ShaderExecutable(function, length)
+{
+    mVertexExecutable = executable;
+    mPixelExecutable = NULL;
+}
+
+ShaderExecutable9::~ShaderExecutable9()
+{
+    if (mVertexExecutable)
+    {
+        mVertexExecutable-&gt;Release();
+    }
+    if (mPixelExecutable)
+    {
+        mPixelExecutable-&gt;Release();
+    }
+}
+
+ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable));
+    return static_cast&lt;ShaderExecutable9*&gt;(executable);
+}
+
+IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const
+{
+    return mVertexExecutable;
+}
+
+IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const
+{
+    return mPixelExecutable;
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9ShaderExecutable9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader
+// executable implementation details.
+
+#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+#define LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
+
+#include &quot;libGLESv2/renderer/ShaderExecutable.h&quot;
+
+namespace rx
+{
+
+class ShaderExecutable9 : public ShaderExecutable
+{
+  public:
+    ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable);
+    ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable);
+    virtual ~ShaderExecutable9();
+
+    static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutable *executable);
+
+    IDirect3DPixelShader9 *getPixelShader() const;
+    IDirect3DVertexShader9 *getVertexShader() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(ShaderExecutable9);
+
+    IDirect3DPixelShader9 *mPixelExecutable;
+    IDirect3DVertexShader9 *mVertexExecutable;
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9SwapChain9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,445 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain.
+
+#include &quot;libGLESv2/renderer/d3d9/SwapChain9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+namespace rx
+{
+
+SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+                       GLenum backBufferFormat, GLenum depthBufferFormat)
+    : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat)
+{
+    mSwapChain = NULL;
+    mBackBuffer = NULL;
+    mDepthStencil = NULL;
+    mRenderTarget = NULL;
+    mOffscreenTexture = NULL;
+    mWidth = -1;
+    mHeight = -1;
+    mSwapInterval = -1;
+}
+
+SwapChain9::~SwapChain9()
+{
+    release();
+}
+
+void SwapChain9::release()
+{
+    if (mSwapChain)
+    {
+        mSwapChain-&gt;Release();
+        mSwapChain = NULL;
+    }
+
+    if (mBackBuffer)
+    {
+        mBackBuffer-&gt;Release();
+        mBackBuffer = NULL;
+    }
+
+    if (mDepthStencil)
+    {
+        mDepthStencil-&gt;Release();
+        mDepthStencil = NULL;
+    }
+
+    if (mRenderTarget)
+    {
+        mRenderTarget-&gt;Release();
+        mRenderTarget = NULL;
+    }
+
+    if (mOffscreenTexture)
+    {
+        mOffscreenTexture-&gt;Release();
+        mOffscreenTexture = NULL;
+    }
+
+    if (mWindow)
+        mShareHandle = NULL;
+}
+
+static DWORD convertInterval(EGLint interval)
+{
+#if ANGLE_FORCE_VSYNC_OFF
+    return D3DPRESENT_INTERVAL_IMMEDIATE;
+#else
+    switch(interval)
+    {
+      case 0: return D3DPRESENT_INTERVAL_IMMEDIATE;
+      case 1: return D3DPRESENT_INTERVAL_ONE;
+      case 2: return D3DPRESENT_INTERVAL_TWO;
+      case 3: return D3DPRESENT_INTERVAL_THREE;
+      case 4: return D3DPRESENT_INTERVAL_FOUR;
+      default: UNREACHABLE();
+    }
+
+    return D3DPRESENT_INTERVAL_DEFAULT;
+#endif
+}
+
+EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight)
+{
+    // D3D9 does not support resizing swap chains without recreating them
+    return reset(backbufferWidth, backbufferHeight, mSwapInterval);
+}
+
+EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval)
+{
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    if (device == NULL)
+    {
+        return EGL_BAD_ACCESS;
+    }
+
+    // Evict all non-render target textures to system memory and release all resources
+    // before reallocating them to free up as much video memory as possible.
+    device-&gt;EvictManagedResources();
+
+    HRESULT result;
+
+    // Release specific resources to free up memory for the new render target, while the
+    // old render target still exists for the purpose of preserving its contents.
+    if (mSwapChain)
+    {
+        mSwapChain-&gt;Release();
+        mSwapChain = NULL;
+    }
+
+    if (mBackBuffer)
+    {
+        mBackBuffer-&gt;Release();
+        mBackBuffer = NULL;
+    }
+
+    if (mOffscreenTexture)
+    {
+        mOffscreenTexture-&gt;Release();
+        mOffscreenTexture = NULL;
+    }
+
+    if (mDepthStencil)
+    {
+        mDepthStencil-&gt;Release();
+        mDepthStencil = NULL;
+    }
+
+    HANDLE *pShareHandle = NULL;
+    if (!mWindow &amp;&amp; mRenderer-&gt;getShareHandleSupport())
+    {
+        pShareHandle = &amp;mShareHandle;
+    }
+
+    result = device-&gt;CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET,
+                                   gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT,
+                                   &amp;mOffscreenTexture, pShareHandle);
+    if (FAILED(result))
+    {
+        ERR(&quot;Could not create offscreen texture: %08lX&quot;, result);
+        release();
+
+        if (d3d9::isDeviceLostError(result))
+        {
+            return EGL_CONTEXT_LOST;
+        }
+        else
+        {
+            return EGL_BAD_ALLOC;
+        }
+    }
+
+    IDirect3DSurface9 *oldRenderTarget = mRenderTarget;
+
+    result = mOffscreenTexture-&gt;GetSurfaceLevel(0, &amp;mRenderTarget);
+    ASSERT(SUCCEEDED(result));
+
+    if (oldRenderTarget)
+    {
+        RECT rect =
+        {
+            0, 0,
+            mWidth, mHeight
+        };
+
+        if (rect.right &gt; static_cast&lt;LONG&gt;(backbufferWidth))
+        {
+            rect.right = backbufferWidth;
+        }
+
+        if (rect.bottom &gt; static_cast&lt;LONG&gt;(backbufferHeight))
+        {
+            rect.bottom = backbufferHeight;
+        }
+
+        mRenderer-&gt;endScene();
+
+        result = device-&gt;StretchRect(oldRenderTarget, &amp;rect, mRenderTarget, &amp;rect, D3DTEXF_NONE);
+        ASSERT(SUCCEEDED(result));
+
+        oldRenderTarget-&gt;Release();
+    }
+
+    if (mWindow)
+    {
+        D3DPRESENT_PARAMETERS presentParameters = {0};
+        presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat);
+        presentParameters.BackBufferCount = 1;
+        presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat);
+        presentParameters.EnableAutoDepthStencil = FALSE;
+        presentParameters.Flags = 0;
+        presentParameters.hDeviceWindow = mWindow;
+        presentParameters.MultiSampleQuality = 0;                  // FIXME: Unimplemented
+        presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;   // FIXME: Unimplemented
+        presentParameters.PresentationInterval = convertInterval(swapInterval);
+        presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+        presentParameters.Windowed = TRUE;
+        presentParameters.BackBufferWidth = backbufferWidth;
+        presentParameters.BackBufferHeight = backbufferHeight;
+
+        // http://crbug.com/140239
+        // http://crbug.com/143434
+        //
+        // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width
+        // when using the integrated Intel. This rounds the width up rather than down.
+        //
+        // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID
+        // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur.
+        if (mRenderer-&gt;getAdapterVendor() == VENDOR_ID_INTEL)
+        {
+            presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64;
+        }
+
+        result = device-&gt;CreateAdditionalSwapChain(&amp;presentParameters, &amp;mSwapChain);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST);
+
+            ERR(&quot;Could not create additional swap chains or offscreen surfaces: %08lX&quot;, result);
+            release();
+
+            if (d3d9::isDeviceLostError(result))
+            {
+                return EGL_CONTEXT_LOST;
+            }
+            else
+            {
+                return EGL_BAD_ALLOC;
+            }
+        }
+
+        result = mSwapChain-&gt;GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &amp;mBackBuffer);
+        ASSERT(SUCCEEDED(result));
+        InvalidateRect(mWindow, NULL, FALSE);
+    }
+
+    if (mDepthBufferFormat != GL_NONE)
+    {
+        result = device-&gt;CreateDepthStencilSurface(backbufferWidth, backbufferHeight,
+                                                   gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat),
+                                                   D3DMULTISAMPLE_NONE, 0, FALSE, &amp;mDepthStencil, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL);
+
+            ERR(&quot;Could not create depthstencil surface for new swap chain: 0x%08X&quot;, result);
+            release();
+
+            if (d3d9::isDeviceLostError(result))
+            {
+                return EGL_CONTEXT_LOST;
+            }
+            else
+            {
+                return EGL_BAD_ALLOC;
+            }
+        }
+    }
+
+    mWidth = backbufferWidth;
+    mHeight = backbufferHeight;
+    mSwapInterval = swapInterval;
+
+    return EGL_SUCCESS;
+}
+
+// parameters should be validated/clamped by caller
+EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height)
+{
+    if (!mSwapChain)
+    {
+        return EGL_SUCCESS;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+
+    // Disable all pipeline operations
+    device-&gt;SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
+    device-&gt;SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
+    device-&gt;SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+    device-&gt;SetRenderState(D3DRS_STENCILENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_CLIPPLANEENABLE, 0);
+    device-&gt;SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED);
+    device-&gt;SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE);
+    device-&gt;SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+    device-&gt;SetPixelShader(NULL);
+    device-&gt;SetVertexShader(NULL);
+
+    device-&gt;SetRenderTarget(0, mBackBuffer);
+    device-&gt;SetDepthStencilSurface(NULL);
+
+    device-&gt;SetTexture(0, mOffscreenTexture);
+    device-&gt;SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+    device-&gt;SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+    device-&gt;SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+    device-&gt;SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+    device-&gt;SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
+    device-&gt;SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+    device-&gt;SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
+    device-&gt;SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
+
+    for (UINT streamIndex = 0; streamIndex &lt; gl::MAX_VERTEX_ATTRIBS; streamIndex++)
+    {
+        device-&gt;SetStreamSourceFreq(streamIndex, 1);
+    }
+
+    D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f};
+    device-&gt;SetViewport(&amp;viewport);
+
+    float x1 = x - 0.5f;
+    float y1 = (mHeight - y - height) - 0.5f;
+    float x2 = (x + width) - 0.5f;
+    float y2 = (mHeight - y) - 0.5f;
+
+    float u1 = x / float(mWidth);
+    float v1 = y / float(mHeight);
+    float u2 = (x + width) / float(mWidth);
+    float v2 = (y + height) / float(mHeight);
+
+    float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2},
+                        {x2, y1, 0.0f, 1.0f, u2, v2},
+                        {x2, y2, 0.0f, 1.0f, u2, v1},
+                        {x1, y2, 0.0f, 1.0f, u1, v1}};   // x, y, z, rhw, u, v
+
+    mRenderer-&gt;startScene();
+    device-&gt;DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
+    mRenderer-&gt;endScene();
+
+    device-&gt;SetTexture(0, NULL);
+
+    RECT rect =
+    {
+        x, mHeight - y - height,
+        x + width, mHeight - y
+    };
+
+    HRESULT result = mSwapChain-&gt;Present(&amp;rect, &amp;rect, NULL, NULL, 0);
+
+    mRenderer-&gt;markAllStateDirty();
+
+    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR)
+    {
+        return EGL_BAD_ALLOC;
+    }
+
+    // http://crbug.com/313210
+    // If our swap failed, trigger a device lost event. Resetting will work around an AMD-specific
+    // device removed bug with lost contexts when reinstalling drivers.
+    if (FAILED(result))
+    {
+        mRenderer-&gt;notifyDeviceLost();
+        return EGL_CONTEXT_LOST;
+    }
+
+    return EGL_SUCCESS;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *SwapChain9::getRenderTarget()
+{
+    if (mRenderTarget)
+    {
+        mRenderTarget-&gt;AddRef();
+    }
+
+    return mRenderTarget;
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *SwapChain9::getDepthStencil()
+{
+    if (mDepthStencil)
+    {
+        mDepthStencil-&gt;AddRef();
+    }
+
+    return mDepthStencil;
+}
+
+// Increments refcount on texture.
+// caller must Release() the returned texture
+IDirect3DTexture9 *SwapChain9::getOffscreenTexture()
+{
+    if (mOffscreenTexture)
+    {
+        mOffscreenTexture-&gt;AddRef();
+    }
+
+    return mOffscreenTexture;
+}
+
+SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain));
+    return static_cast&lt;rx::SwapChain9*&gt;(swapChain);
+}
+
+void SwapChain9::recreate()
+{
+    if (!mSwapChain)
+    {
+        return;
+    }
+
+    IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+    if (device == NULL)
+    {
+        return;
+    }
+
+    D3DPRESENT_PARAMETERS presentParameters;
+    HRESULT result = mSwapChain-&gt;GetPresentParameters(&amp;presentParameters);
+    ASSERT(SUCCEEDED(result));
+
+    IDirect3DSwapChain9* newSwapChain = NULL;
+    result = device-&gt;CreateAdditionalSwapChain(&amp;presentParameters, &amp;newSwapChain);
+    if (FAILED(result))
+    {
+        return;
+    }
+
+    mSwapChain-&gt;Release();
+    mSwapChain = newSwapChain;
+
+    mBackBuffer-&gt;Release();
+    result = mSwapChain-&gt;GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &amp;mBackBuffer);
+    ASSERT(SUCCEEDED(result));
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9SwapChain9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain.
+
+#ifndef LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+#define LIBGLESV2_RENDERER_SWAPCHAIN9_H_
+
+#include &quot;common/angleutils.h&quot;
+#include &quot;libGLESv2/renderer/SwapChain.h&quot;
+
+namespace rx
+{
+class Renderer9;
+
+class SwapChain9 : public SwapChain
+{
+  public:
+    SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle,
+               GLenum backBufferFormat, GLenum depthBufferFormat);
+    virtual ~SwapChain9();
+
+    EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight);
+    virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval);
+    virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height);
+    virtual void recreate();
+
+    virtual IDirect3DSurface9 *getRenderTarget();
+    virtual IDirect3DSurface9 *getDepthStencil();
+    virtual IDirect3DTexture9 *getOffscreenTexture();
+
+    static SwapChain9 *makeSwapChain9(SwapChain *swapChain);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(SwapChain9);
+
+    void release();
+
+    Renderer9 *mRenderer;
+    EGLint mHeight;
+    EGLint mWidth;
+    EGLint mSwapInterval;
+
+    IDirect3DSwapChain9 *mSwapChain;
+    IDirect3DSurface9 *mBackBuffer;
+    IDirect3DSurface9 *mRenderTarget;
+    IDirect3DSurface9 *mDepthStencil;
+    IDirect3DTexture9* mOffscreenTexture;
+};
+
+}
+#endif // LIBGLESV2_RENDERER_SWAPCHAIN9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/SwapChain9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9TextureStorage9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,328 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#include &quot;libGLESv2/main.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/TextureStorage9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/SwapChain9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/RenderTarget9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/Texture.h&quot;
+
+namespace rx
+{
+TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage)
+    : mLodOffset(0),
+      mRenderer(Renderer9::makeRenderer9(renderer)),
+      mD3DUsage(usage),
+      mD3DPool(mRenderer-&gt;getTexturePool(usage))
+{
+}
+
+TextureStorage9::~TextureStorage9()
+{
+}
+
+TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9*, storage));
+    return static_cast&lt;TextureStorage9*&gt;(storage);
+}
+
+DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable)
+{
+    DWORD d3dusage = 0;
+
+    if (d3dfmt == D3DFMT_INTZ)
+    {
+        d3dusage |= D3DUSAGE_DEPTHSTENCIL;
+    }
+    else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) &amp;&amp; (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE)))
+    {
+        d3dusage |= D3DUSAGE_RENDERTARGET;
+    }
+    return d3dusage;
+}
+
+bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format)
+{
+    if (format == D3DFMT_INTZ)
+    {
+        return true;
+    }
+    switch(format)
+    {
+      case D3DFMT_L8:
+      case D3DFMT_A8L8:
+      case D3DFMT_DXT1:
+      case D3DFMT_DXT3:
+      case D3DFMT_DXT5:
+        return false;
+      case D3DFMT_A8R8G8B8:
+      case D3DFMT_X8R8G8B8:
+      case D3DFMT_A16B16G16R16F:
+      case D3DFMT_A32B32G32R32F:
+        return true;
+      default:
+        UNREACHABLE();
+    }
+
+    return false;
+}
+
+bool TextureStorage9::isRenderTarget() const
+{
+    return (mD3DUsage &amp; (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0;
+}
+
+bool TextureStorage9::isManaged() const
+{
+    return (mD3DPool == D3DPOOL_MANAGED);
+}
+
+D3DPOOL TextureStorage9::getPool() const
+{
+    return mD3DPool;
+}
+
+DWORD TextureStorage9::getUsage() const
+{
+    return mD3DUsage;
+}
+
+int TextureStorage9::getLodOffset() const
+{
+    return mLodOffset;
+}
+
+int TextureStorage9::levelCount()
+{
+    return getBaseTexture() ? getBaseTexture()-&gt;GetLevelCount() - getLodOffset() : 0;
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET)
+{
+    IDirect3DTexture9 *surfaceTexture = swapchain-&gt;getOffscreenTexture();
+    mTexture = surfaceTexture;
+    mRenderTarget = NULL;
+
+    initializeRenderTarget();
+}
+
+TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height)
+    : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)-&gt;ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+    mTexture = NULL;
+    mRenderTarget = NULL;
+    // if the width or height is not positive this should be treated as an incomplete texture
+    // we handle that here by skipping the d3d texture creation
+    if (width &gt; 0 &amp;&amp; height &gt; 0)
+    {
+        IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &amp;width, &amp;height, &amp;mLodOffset);
+        HRESULT result = device-&gt;CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(),
+                                               mRenderer-&gt;ConvertTextureInternalFormat(internalformat), getPool(), &amp;mTexture, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    initializeRenderTarget();
+}
+
+TextureStorage9_2D::~TextureStorage9_2D()
+{
+    if (mTexture)
+    {
+        mTexture-&gt;Release();
+    }
+
+    delete mRenderTarget;
+}
+
+TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_2D*, storage));
+    return static_cast&lt;TextureStorage9_2D*&gt;(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty)
+{
+    IDirect3DSurface9 *surface = NULL;
+
+    if (mTexture)
+    {
+        HRESULT result = mTexture-&gt;GetSurfaceLevel(level + mLodOffset, &amp;surface);
+        ASSERT(SUCCEEDED(result));
+
+        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+        if (level + mLodOffset != 0 &amp;&amp; isManaged() &amp;&amp; dirty)
+        {
+            mTexture-&gt;AddDirtyRect(NULL);
+        }
+    }
+
+    return surface;
+}
+
+RenderTarget *TextureStorage9_2D::getRenderTarget()
+{
+    return mRenderTarget;
+}
+
+void TextureStorage9_2D::generateMipmap(int level)
+{
+    IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false);
+    IDirect3DSurface9 *lower = getSurfaceLevel(level, true);
+
+    if (upper != NULL &amp;&amp; lower != NULL)
+    {
+        mRenderer-&gt;boxFilter(upper, lower);
+    }
+
+    if (upper != NULL) upper-&gt;Release();
+    if (lower != NULL) lower-&gt;Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const
+{
+    return mTexture;
+}
+
+void TextureStorage9_2D::initializeRenderTarget()
+{
+    ASSERT(mRenderTarget == NULL);
+
+    if (mTexture != NULL &amp;&amp; isRenderTarget())
+    {
+        IDirect3DSurface9 *surface = getSurfaceLevel(0, false);
+
+        mRenderTarget = new RenderTarget9(mRenderer, surface);
+    }
+}
+
+TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size)
+    : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)-&gt;ConvertTextureInternalFormat(internalformat), usage, forceRenderable))
+{
+    mTexture = NULL;
+    for (int i = 0; i &lt; 6; ++i)
+    {
+        mRenderTarget[i] = NULL;
+    }
+
+    // if the size is not positive this should be treated as an incomplete texture
+    // we handle that here by skipping the d3d texture creation
+    if (size &gt; 0)
+    {
+        IDirect3DDevice9 *device = mRenderer-&gt;getDevice();
+        int height = size;
+        gl::MakeValidSize(false, gl::IsCompressed(internalformat), &amp;size, &amp;height, &amp;mLodOffset);
+        HRESULT result = device-&gt;CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(),
+                                                   mRenderer-&gt;ConvertTextureInternalFormat(internalformat), getPool(), &amp;mTexture, NULL);
+
+        if (FAILED(result))
+        {
+            ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+            gl::error(GL_OUT_OF_MEMORY);
+        }
+    }
+
+    initializeRenderTarget();
+}
+
+TextureStorage9_Cube::~TextureStorage9_Cube()
+{
+    if (mTexture)
+    {
+        mTexture-&gt;Release();
+    }
+
+    for (int i = 0; i &lt; 6; ++i)
+    {
+        delete mRenderTarget[i];
+    }
+}
+
+TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStorage *storage)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_Cube*, storage));
+    return static_cast&lt;TextureStorage9_Cube*&gt;(storage);
+}
+
+// Increments refcount on surface.
+// caller must Release() the returned surface
+IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
+{
+    IDirect3DSurface9 *surface = NULL;
+
+    if (mTexture)
+    {
+        D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget);
+        HRESULT result = mTexture-&gt;GetCubeMapSurface(face, level + mLodOffset, &amp;surface);
+        ASSERT(SUCCEEDED(result));
+
+        // With managed textures the driver needs to be informed of updates to the lower mipmap levels
+        if (level != 0 &amp;&amp; isManaged() &amp;&amp; dirty)
+        {
+            mTexture-&gt;AddDirtyRect(face, NULL);
+        }
+    }
+
+    return surface;
+}
+
+RenderTarget *TextureStorage9_Cube::getRenderTarget(GLenum faceTarget)
+{
+    return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)];
+}
+
+void TextureStorage9_Cube::generateMipmap(int face, int level)
+{
+    IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false);
+    IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true);
+
+    if (upper != NULL &amp;&amp; lower != NULL)
+    {
+        mRenderer-&gt;boxFilter(upper, lower);
+    }
+
+    if (upper != NULL) upper-&gt;Release();
+    if (lower != NULL) lower-&gt;Release();
+}
+
+IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const
+{
+    return mTexture;
+}
+
+void TextureStorage9_Cube::initializeRenderTarget()
+{
+    if (mTexture != NULL &amp;&amp; isRenderTarget())
+    {
+        IDirect3DSurface9 *surface = NULL;
+
+        for (int i = 0; i &lt; 6; ++i)
+        {
+            ASSERT(mRenderTarget[i] == NULL);
+
+            surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false);
+
+            mRenderTarget[i] = new RenderTarget9(mRenderer, surface);
+        }
+    }
+}
+
+}
</ins><span class="cx">\ No newline at end of file
</span><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9TextureStorage9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,109 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived
+// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the
+// D3D9 texture.
+
+#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
+#include &quot;libGLESv2/renderer/TextureStorage.h&quot;
+#include &quot;common/debug.h&quot;
+
+namespace rx
+{
+class Renderer9;
+class SwapChain9;
+class RenderTarget;
+class RenderTarget9;
+class Blit;
+
+class TextureStorage9 : public TextureStorage
+{
+  public:
+    TextureStorage9(Renderer *renderer, DWORD usage);
+    virtual ~TextureStorage9();
+
+    static TextureStorage9 *makeTextureStorage9(TextureStorage *storage);
+
+    static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable);
+    static bool IsTextureFormatRenderable(D3DFORMAT format);
+
+    D3DPOOL getPool() const;
+    DWORD getUsage() const;
+
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
+    virtual RenderTarget *getRenderTarget() { return NULL; }
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return NULL; }
+    virtual void generateMipmap(int level) {};
+    virtual void generateMipmap(int face, int level) {};
+
+    virtual int getLodOffset() const;
+    virtual bool isRenderTarget() const;
+    virtual bool isManaged() const;
+    virtual int levelCount();
+
+  protected:
+    int mLodOffset;
+    Renderer9 *mRenderer;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage9);
+
+    const DWORD mD3DUsage;
+    const D3DPOOL mD3DPool;
+};
+
+class TextureStorage9_2D : public TextureStorage9
+{
+  public:
+    TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain);
+    TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height);
+    virtual ~TextureStorage9_2D();
+
+    static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage);
+
+    IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
+    virtual RenderTarget *getRenderTarget();
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+    virtual void generateMipmap(int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D);
+
+    void initializeRenderTarget();
+
+    IDirect3DTexture9 *mTexture;
+    RenderTarget9 *mRenderTarget;
+};
+
+class TextureStorage9_Cube : public TextureStorage9
+{
+  public:
+    TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size);
+    virtual ~TextureStorage9_Cube();
+
+    static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage);
+
+    IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
+    virtual RenderTarget *getRenderTarget(GLenum faceTarget);
+    virtual IDirect3DBaseTexture9 *getBaseTexture() const;
+    virtual void generateMipmap(int face, int level);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube);
+
+    void initializeRenderTarget();
+
+    IDirect3DCubeTexture9 *mTexture;
+    RenderTarget9 *mRenderTarget[6];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_
+
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/TextureStorage9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexBuffer9cpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,530 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation.
+
+#include &quot;libGLESv2/renderer/d3d9/VertexBuffer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/vertexconversion.h&quot;
+#include &quot;libGLESv2/renderer/BufferStorage.h&quot;
+#include &quot;libGLESv2/Context.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/Renderer9.h&quot;
+
+#include &quot;libGLESv2/Buffer.h&quot;
+
+namespace rx
+{
+
+bool VertexBuffer9::mTranslationsInitialized = false;
+VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer)
+{
+    mVertexBuffer = NULL;
+    mBufferSize = 0;
+    mDynamicUsage = false;
+
+    if (!mTranslationsInitialized)
+    {
+        initializeTranslations(renderer-&gt;getCapsDeclTypes());
+        mTranslationsInitialized = true;
+    }
+}
+
+VertexBuffer9::~VertexBuffer9()
+{
+    if (mVertexBuffer)
+    {
+        mVertexBuffer-&gt;Release();
+        mVertexBuffer = NULL;
+    }
+}
+
+bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage)
+{
+    if (mVertexBuffer)
+    {
+        mVertexBuffer-&gt;Release();
+        mVertexBuffer = NULL;
+    }
+
+    updateSerial();
+
+    if (size &gt; 0)
+    {
+        DWORD flags = D3DUSAGE_WRITEONLY;
+        if (dynamicUsage)
+        {
+            flags |= D3DUSAGE_DYNAMIC;
+        }
+
+        HRESULT result = mRenderer-&gt;createVertexBuffer(size, flags, &amp;mVertexBuffer);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Out of memory allocating a vertex buffer of size %lu.&quot;, size);
+            return false;
+        }
+    }
+
+    mBufferSize = size;
+    mDynamicUsage = dynamicUsage;
+    return true;
+}
+
+VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer)
+{
+    ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer));
+    return static_cast&lt;VertexBuffer9*&gt;(vertexBuffer);
+}
+
+bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &amp;attrib, GLint start, GLsizei count,
+                                             GLsizei instances, unsigned int offset)
+{
+    if (mVertexBuffer)
+    {
+        gl::Buffer *buffer = attrib.mBoundBuffer.get();
+
+        int inputStride = attrib.stride();
+        int elementSize = attrib.typeSize();
+        const FormatConverter &amp;converter = formatConverter(attrib);
+
+        DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+        void *mapPtr = NULL;
+
+        unsigned int mapSize;
+        if (!spaceRequired(attrib, count, instances, &amp;mapSize))
+        {
+            return false;
+        }
+
+        HRESULT result = mVertexBuffer-&gt;Lock(offset, mapSize, &amp;mapPtr, lockFlags);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Lock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        const char *input = NULL;
+        if (buffer)
+        {
+            BufferStorage *storage = buffer-&gt;getStorage();
+            input = static_cast&lt;const char*&gt;(storage-&gt;getData()) + static_cast&lt;int&gt;(attrib.mOffset);
+        }
+        else
+        {
+            input = static_cast&lt;const char*&gt;(attrib.mPointer);
+        }
+
+        if (instances == 0 || attrib.mDivisor == 0)
+        {
+            input += inputStride * start;
+        }
+
+        if (converter.identity &amp;&amp; inputStride == elementSize)
+        {
+            memcpy(mapPtr, input, count * inputStride);
+        }
+        else
+        {
+            converter.convertArray(input, inputStride, count, mapPtr);
+        }
+
+        mVertexBuffer-&gt;Unlock();
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset)
+{
+    if (mVertexBuffer)
+    {
+        DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0;
+
+        void *mapPtr = NULL;
+        HRESULT result = mVertexBuffer-&gt;Lock(offset, size, &amp;mapPtr, lockFlags);
+
+        if (FAILED(result))
+        {
+            ERR(&quot;Lock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        memcpy(mapPtr, data, size);
+
+        mVertexBuffer-&gt;Unlock();
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &amp;attrib, GLsizei count, GLsizei instances,
+                                     unsigned int *outSpaceRequired) const
+{
+    return spaceRequired(attrib, count, instances, outSpaceRequired);
+}
+
+bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &amp;attrib) const
+{
+    return !formatConverter(attrib).identity;
+}
+
+unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &amp;attrib) const
+{
+    unsigned int spaceRequired;
+    return getSpaceRequired(attrib, 1, 0, &amp;spaceRequired) ? spaceRequired : 0;
+}
+
+D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &amp;attrib) const
+{
+    return formatConverter(attrib).d3dDeclType;
+}
+
+unsigned int VertexBuffer9::getBufferSize() const
+{
+    return mBufferSize;
+}
+
+bool VertexBuffer9::setBufferSize(unsigned int size)
+{
+    if (size &gt; mBufferSize)
+    {
+        return initialize(size, mDynamicUsage);
+    }
+    else
+    {
+        return true;
+    }
+}
+
+bool VertexBuffer9::discard()
+{
+    if (mVertexBuffer)
+    {
+        void *dummy;
+        HRESULT result;
+
+        result = mVertexBuffer-&gt;Lock(0, 1, &amp;dummy, D3DLOCK_DISCARD);
+        if (FAILED(result))
+        {
+            ERR(&quot;Discard lock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        result = mVertexBuffer-&gt;Unlock();
+        if (FAILED(result))
+        {
+            ERR(&quot;Discard unlock failed with error 0x%08x&quot;, result);
+            return false;
+        }
+
+        return true;
+    }
+    else
+    {
+        ERR(&quot;Vertex buffer not initialized.&quot;);
+        return false;
+    }
+}
+
+IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const
+{
+    return mVertexBuffer;
+}
+
+// Mapping from OpenGL-ES vertex attrib type to D3D decl type:
+//
+// BYTE                 SHORT (Cast)
+// BYTE-norm            FLOAT (Normalize) (can't be exactly represented as SHORT-norm)
+// UNSIGNED_BYTE        UBYTE4 (Identity) or SHORT (Cast)
+// UNSIGNED_BYTE-norm   UBYTE4N (Identity) or FLOAT (Normalize)
+// SHORT                SHORT (Identity)
+// SHORT-norm           SHORT-norm (Identity) or FLOAT (Normalize)
+// UNSIGNED_SHORT       FLOAT (Cast)
+// UNSIGNED_SHORT-norm  USHORT-norm (Identity) or FLOAT (Normalize)
+// FIXED (not in WebGL) FLOAT (FixedToFloat)
+// FLOAT                FLOAT (Identity)
+
+// GLToCType maps from GL type (as GLenum) to the C typedef.
+template &lt;GLenum GLType&gt; struct GLToCType { };
+
+template &lt;&gt; struct GLToCType&lt;GL_BYTE&gt;           { typedef GLbyte type;      };
+template &lt;&gt; struct GLToCType&lt;GL_UNSIGNED_BYTE&gt;  { typedef GLubyte type;     };
+template &lt;&gt; struct GLToCType&lt;GL_SHORT&gt;          { typedef GLshort type;     };
+template &lt;&gt; struct GLToCType&lt;GL_UNSIGNED_SHORT&gt; { typedef GLushort type;    };
+template &lt;&gt; struct GLToCType&lt;GL_FIXED&gt;          { typedef GLuint type;      };
+template &lt;&gt; struct GLToCType&lt;GL_FLOAT&gt;          { 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 &lt;unsigned int D3DType&gt; struct D3DToCType { };
+
+template &lt;&gt; struct D3DToCType&lt;D3DVT_FLOAT&gt; { typedef float type; };
+template &lt;&gt; struct D3DToCType&lt;D3DVT_SHORT&gt; { typedef short type; };
+template &lt;&gt; struct D3DToCType&lt;D3DVT_SHORT_NORM&gt; { typedef short type; };
+template &lt;&gt; struct D3DToCType&lt;D3DVT_UBYTE&gt; { typedef unsigned char type; };
+template &lt;&gt; struct D3DToCType&lt;D3DVT_UBYTE_NORM&gt; { typedef unsigned char type; };
+template &lt;&gt; struct D3DToCType&lt;D3DVT_USHORT_NORM&gt; { 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 &lt;unsigned int type, int size&gt; struct WidenRule { };
+
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_FLOAT, size&gt;          : NoWiden&lt;size&gt; { };
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_SHORT, size&gt;          : WidenToEven&lt;size&gt; { };
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_SHORT_NORM, size&gt;     : WidenToEven&lt;size&gt; { };
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_UBYTE, size&gt;          : WidenToFour&lt;size&gt; { };
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_UBYTE_NORM, size&gt;     : WidenToFour&lt;size&gt; { };
+template &lt;int size&gt; struct WidenRule&lt;D3DVT_USHORT_NORM, size&gt;    : WidenToEven&lt;size&gt; { };
+
+// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type &amp; size combination.
+template &lt;unsigned int d3dtype, int size&gt; struct VertexTypeFlags { };
+
+template &lt;unsigned int _capflag, unsigned int _declflag&gt;
+struct VertexTypeFlagsHelper
+{
+    enum { capflag = _capflag };
+    enum { declflag = _declflag };
+};
+
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_FLOAT, 1&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_FLOAT1&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_FLOAT, 2&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_FLOAT2&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_FLOAT, 3&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_FLOAT3&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_FLOAT, 4&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_FLOAT4&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_SHORT, 2&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_SHORT2&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_SHORT, 4&gt; : VertexTypeFlagsHelper&lt;0, D3DDECLTYPE_SHORT4&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_SHORT_NORM, 2&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_SHORT_NORM, 4&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_UBYTE, 4&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_UBYTE_NORM, 4&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_USHORT_NORM, 2&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N&gt; { };
+template &lt;&gt; struct VertexTypeFlags&lt;D3DVT_USHORT_NORM, 4&gt; : VertexTypeFlagsHelper&lt;D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N&gt; { };
+
+
+// VertexTypeMapping maps GL type &amp; normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums).
+template &lt;GLenum GLtype, bool normalized&gt; struct VertexTypeMapping { };
+
+template &lt;D3DVertexType Preferred, D3DVertexType Fallback = Preferred&gt;
+struct VertexTypeMappingBase
+{
+    enum { preferred = Preferred };
+    enum { fallback = Fallback };
+};
+
+template &lt;&gt; struct VertexTypeMapping&lt;GL_BYTE, false&gt;                        : VertexTypeMappingBase&lt;D3DVT_SHORT&gt; { };                       // Cast
+template &lt;&gt; struct VertexTypeMapping&lt;GL_BYTE, true&gt;                         : VertexTypeMappingBase&lt;D3DVT_FLOAT&gt; { };                       // Normalize
+template &lt;&gt; struct VertexTypeMapping&lt;GL_UNSIGNED_BYTE, false&gt;               : VertexTypeMappingBase&lt;D3DVT_UBYTE, D3DVT_FLOAT&gt; { };          // Identity, Cast
+template &lt;&gt; struct VertexTypeMapping&lt;GL_UNSIGNED_BYTE, true&gt;                : VertexTypeMappingBase&lt;D3DVT_UBYTE_NORM, D3DVT_FLOAT&gt; { };     // Identity, Normalize
+template &lt;&gt; struct VertexTypeMapping&lt;GL_SHORT, false&gt;                       : VertexTypeMappingBase&lt;D3DVT_SHORT&gt; { };                       // Identity
+template &lt;&gt; struct VertexTypeMapping&lt;GL_SHORT, true&gt;                        : VertexTypeMappingBase&lt;D3DVT_SHORT_NORM, D3DVT_FLOAT&gt; { };     // Cast, Normalize
+template &lt;&gt; struct VertexTypeMapping&lt;GL_UNSIGNED_SHORT, false&gt;              : VertexTypeMappingBase&lt;D3DVT_FLOAT&gt; { };                       // Cast
+template &lt;&gt; struct VertexTypeMapping&lt;GL_UNSIGNED_SHORT, true&gt;               : VertexTypeMappingBase&lt;D3DVT_USHORT_NORM, D3DVT_FLOAT&gt; { };    // Cast, Normalize
+template &lt;bool normalized&gt; struct VertexTypeMapping&lt;GL_FIXED, normalized&gt;   : VertexTypeMappingBase&lt;D3DVT_FLOAT&gt; { };                       // FixedToFloat
+template &lt;bool normalized&gt; struct VertexTypeMapping&lt;GL_FLOAT, normalized&gt;   : VertexTypeMappingBase&lt;D3DVT_FLOAT&gt; { };                       // Identity
+
+
+// Given a GL type &amp; 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&lt;T,T&gt; knows it's an identity mapping).
+template &lt;GLenum fromType, bool normalized, unsigned int toType&gt;
+struct ConversionRule : Cast&lt;typename GLToCType&lt;fromType&gt;::type, typename D3DToCType&lt;toType&gt;::type&gt; { };
+
+// All conversions from normalized types to float use the Normalize operator.
+template &lt;GLenum fromType&gt; struct ConversionRule&lt;fromType, true, D3DVT_FLOAT&gt; : Normalize&lt;typename GLToCType&lt;fromType&gt;::type&gt; { };
+
+// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules.
+template &lt;&gt; struct ConversionRule&lt;GL_FIXED, true, D3DVT_FLOAT&gt;  : FixedToFloat&lt;GLint, 16&gt; { };
+template &lt;&gt; struct ConversionRule&lt;GL_FIXED, false, D3DVT_FLOAT&gt; : FixedToFloat&lt;GLint, 16&gt; { };
+
+// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1)
+// whether it is normalized or not.
+template &lt;class T, bool normalized&gt; struct DefaultVertexValuesStage2 { };
+
+template &lt;class T&gt; struct DefaultVertexValuesStage2&lt;T, true&gt;  : NormalizedDefaultValues&lt;T&gt; { };
+template &lt;class T&gt; struct DefaultVertexValuesStage2&lt;T, false&gt; : SimpleDefaultValues&lt;T&gt; { };
+
+// Work out the default value rule for a D3D type (expressed as the C type) and
+template &lt;class T, bool normalized&gt; struct DefaultVertexValues : DefaultVertexValuesStage2&lt;T, normalized&gt; { };
+template &lt;bool normalized&gt; struct DefaultVertexValues&lt;float, normalized&gt; : SimpleDefaultValues&lt;float&gt; { };
+
+// 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 &lt;class T&gt; struct UsePreferred { enum { type = T::preferred }; };
+template &lt;class T&gt; 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 &lt;GLenum fromType, bool normalized, int size, template &lt;class T&gt; class PreferenceRule&gt;
+struct Converter
+    : VertexDataConverter&lt;typename GLToCType&lt;fromType&gt;::type,
+                          WidenRule&lt;PreferenceRule&lt; VertexTypeMapping&lt;fromType, normalized&gt; &gt;::type, size&gt;,
+                          ConversionRule&lt;fromType,
+                                         normalized,
+                                         PreferenceRule&lt; VertexTypeMapping&lt;fromType, normalized&gt; &gt;::type&gt;,
+                          DefaultVertexValues&lt;typename D3DToCType&lt;PreferenceRule&lt; VertexTypeMapping&lt;fromType, normalized&gt; &gt;::type&gt;::type, normalized &gt; &gt;
+{
+private:
+    enum { d3dtype = PreferenceRule&lt; VertexTypeMapping&lt;fromType, normalized&gt; &gt;::type };
+    enum { d3dsize = WidenRule&lt;d3dtype, size&gt;::finalWidth };
+
+public:
+    enum { capflag = VertexTypeFlags&lt;d3dtype, d3dsize&gt;::capflag };
+    enum { declflag = VertexTypeFlags&lt;d3dtype, d3dsize&gt;::declflag };
+};
+
+// Initialize a TranslationInfo
+#define TRANSLATION(type, norm, size, preferred)                                    \
+    {                                                                               \
+        Converter&lt;type, norm, size, preferred&gt;::identity,                           \
+        Converter&lt;type, norm, size, preferred&gt;::finalSize,                          \
+        Converter&lt;type, norm, size, preferred&gt;::convertArray,                       \
+        static_cast&lt;D3DDECLTYPE&gt;(Converter&lt;type, norm, size, preferred&gt;::declflag)  \
+    }
+
+#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size)    \
+    {                                                       \
+        Converter&lt;type, norm, size, UsePreferred&gt;::capflag, \
+        TRANSLATION(type, norm, size, UsePreferred),        \
+        TRANSLATION(type, norm, size, UseFallback)          \
+    }
+
+#define TRANSLATIONS_FOR_TYPE(type)                                                                                                                                                                         \
+    {                                                                                                                                                                                                       \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) },     \
+    }
+
+#define TRANSLATIONS_FOR_TYPE_NO_NORM(type)                                                                                                                                                                 \
+    {                                                                                                                                                                                                       \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+        { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \
+    }
+
+const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1]
+{
+    TRANSLATIONS_FOR_TYPE(GL_BYTE),
+    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE),
+    TRANSLATIONS_FOR_TYPE(GL_SHORT),
+    TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT),
+    TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED),
+    TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT)
+};
+
+void VertexBuffer9::initializeTranslations(DWORD declTypes)
+{
+    for (unsigned int i = 0; i &lt; NUM_GL_VERTEX_ATTRIB_TYPES; i++)
+    {
+        for (unsigned int j = 0; j &lt; 2; j++)
+        {
+            for (unsigned int k = 0; k &lt; 4; k++)
+            {
+                if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes &amp; mPossibleTranslations[i][j][k].capsFlag) != 0)
+                {
+                    mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion;
+                }
+                else
+                {
+                    mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion;
+                }
+            }
+        }
+    }
+}
+
+unsigned int VertexBuffer9::typeIndex(GLenum type)
+{
+    switch (type)
+    {
+      case GL_BYTE: return 0;
+      case GL_UNSIGNED_BYTE: return 1;
+      case GL_SHORT: return 2;
+      case GL_UNSIGNED_SHORT: return 3;
+      case GL_FIXED: return 4;
+      case GL_FLOAT: return 5;
+
+      default: UNREACHABLE(); return 5;
+    }
+}
+
+const VertexBuffer9::FormatConverter &amp;VertexBuffer9::formatConverter(const gl::VertexAttribute &amp;attribute)
+{
+    return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1];
+}
+
+bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &amp;attrib, std::size_t count, GLsizei instances,
+                                  unsigned int *outSpaceRequired)
+{
+    unsigned int elementSize = formatConverter(attrib).outputElementSize;
+
+    if (attrib.mArrayEnabled)
+    {
+        unsigned int elementCount = 0;
+        if (instances == 0 || attrib.mDivisor == 0)
+        {
+            elementCount = count;
+        }
+        else
+        {
+            if (static_cast&lt;unsigned int&gt;(instances) &lt; std::numeric_limits&lt;unsigned int&gt;::max() - (attrib.mDivisor - 1))
+            {
+                // Round up
+                elementCount = (static_cast&lt;unsigned int&gt;(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor;
+            }
+            else
+            {
+                elementCount = static_cast&lt;unsigned int&gt;(instances) / attrib.mDivisor;
+            }
+        }
+
+        if (elementSize &lt;= std::numeric_limits&lt;unsigned int&gt;::max() / elementCount)
+        {
+            if (outSpaceRequired)
+            {
+                *outSpaceRequired = elementSize * elementCount;
+            }
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+    else
+    {
+        const unsigned int elementSize = 4;
+        if (outSpaceRequired)
+        {
+            *outSpaceRequired = elementSize * 4;
+        }
+        return true;
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexBuffer9h"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
+
+#include &quot;libGLESv2/renderer/VertexBuffer.h&quot;
+
+namespace rx
+{
+class Renderer9;
+
+class VertexBuffer9 : public VertexBuffer
+{
+  public:
+    explicit VertexBuffer9(rx::Renderer9 *const renderer);
+    virtual ~VertexBuffer9();
+
+    virtual bool initialize(unsigned int size, bool dynamicUsage);
+
+    static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer);
+
+    virtual bool storeVertexAttributes(const gl::VertexAttribute &amp;attrib, GLint start, GLsizei count, GLsizei instances,
+                                       unsigned int offset);
+    virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset);
+
+    virtual bool getSpaceRequired(const gl::VertexAttribute &amp;attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const;
+
+    virtual bool requiresConversion(const gl::VertexAttribute &amp;attrib) const;
+
+    unsigned int getVertexSize(const gl::VertexAttribute &amp;attrib) const;
+    D3DDECLTYPE getDeclType(const gl::VertexAttribute &amp;attrib) const;
+
+    virtual unsigned int getBufferSize() const;
+    virtual bool setBufferSize(unsigned int size);
+    virtual bool discard();
+
+    IDirect3DVertexBuffer9 *getBuffer() const;
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(VertexBuffer9);
+
+    rx::Renderer9 *const mRenderer;
+
+    IDirect3DVertexBuffer9 *mVertexBuffer;
+    unsigned int mBufferSize;
+    bool mDynamicUsage;
+
+    // Attribute format conversion
+    enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 };
+
+    struct FormatConverter
+    {
+        bool identity;
+        std::size_t outputElementSize;
+        void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out);
+        D3DDECLTYPE d3dDeclType;
+    };
+
+    static bool mTranslationsInitialized;
+    static void initializeTranslations(DWORD declTypes);
+
+    // [GL types as enumerated by typeIndex()][normalized][size - 1]
+    static FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+    struct TranslationDescription
+    {
+        DWORD capsFlag;
+        FormatConverter preferredConversion;
+        FormatConverter fallbackConversion;
+    };
+
+    // This table is used to generate mFormatConverters.
+    // [GL types as enumerated by typeIndex()][normalized][size - 1]
+    static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4];
+
+    static unsigned int typeIndex(GLenum type);
+    static const FormatConverter &amp;formatConverter(const gl::VertexAttribute &amp;attribute);
+
+    static bool spaceRequired(const gl::VertexAttribute &amp;attrib, std::size_t count, GLsizei instances,
+                              unsigned int *outSpaceRequired);
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexBuffer9.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexDeclarationCachecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,217 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations.
+
+#include &quot;libGLESv2/ProgramBinary.h&quot;
+#include &quot;libGLESv2/Context.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/VertexBuffer9.h&quot;
+#include &quot;libGLESv2/renderer/d3d9/VertexDeclarationCache.h&quot;
+
+namespace rx
+{
+
+VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0)
+{
+    for (int i = 0; i &lt; NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        mVertexDeclCache[i].vertexDeclaration = NULL;
+        mVertexDeclCache[i].lruCount = 0;
+    }
+
+    for (int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        mAppliedVBs[i].serial = 0;
+    }
+
+    mLastSetVDecl = NULL;
+    mInstancingEnabled = true;
+}
+
+VertexDeclarationCache::~VertexDeclarationCache()
+{
+    for (int i = 0; i &lt; NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        if (mVertexDeclCache[i].vertexDeclaration)
+        {
+            mVertexDeclCache[i].vertexDeclaration-&gt;Release();
+        }
+    }
+}
+
+GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw)
+{
+    *repeatDraw = 1;
+
+    int indexedAttribute = gl::MAX_VERTEX_ATTRIBS;
+    int instancedAttribute = gl::MAX_VERTEX_ATTRIBS;
+
+    if (instances &gt; 0)
+    {
+        // Find an indexed attribute to be mapped to D3D stream 0
+        for (int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+        {
+            if (attributes[i].active)
+            {
+                if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS &amp;&amp; attributes[i].divisor == 0)
+                {
+                    indexedAttribute = i;
+                }
+                else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS &amp;&amp; attributes[i].divisor != 0)
+                {
+                    instancedAttribute = i;
+                }
+                if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS &amp;&amp; instancedAttribute != gl::MAX_VERTEX_ATTRIBS)
+                    break;   // Found both an indexed and instanced attribute
+            }
+        }
+
+        if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS)
+        {
+            return GL_INVALID_OPERATION;
+        }
+    }
+
+    D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1];
+    D3DVERTEXELEMENT9 *element = &amp;elements[0];
+
+    for (int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        if (attributes[i].active)
+        {
+            // Directly binding the storage buffer is not supported for d3d9
+            ASSERT(attributes[i].storage == NULL);
+
+            int stream = i;
+
+            if (instances &gt; 0)
+            {
+                // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced.
+                if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
+                {
+                    *repeatDraw = instances;
+                }
+                else
+                {
+                    if (i == indexedAttribute)
+                    {
+                        stream = 0;
+                    }
+                    else if (i == 0)
+                    {
+                        stream = indexedAttribute;
+                    }
+
+                    UINT frequency = 1;
+                    
+                    if (attributes[i].divisor == 0)
+                    {
+                        frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances;
+                    }
+                    else
+                    {
+                        frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor;
+                    }
+                    
+                    device-&gt;SetStreamSourceFreq(stream, frequency);
+                    mInstancingEnabled = true;
+                }
+            }
+
+            VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer);
+
+            if (mAppliedVBs[stream].serial != attributes[i].serial ||
+                mAppliedVBs[stream].stride != attributes[i].stride ||
+                mAppliedVBs[stream].offset != attributes[i].offset)
+            {
+                device-&gt;SetStreamSource(stream, vertexBuffer-&gt;getBuffer(), attributes[i].offset, attributes[i].stride);
+                mAppliedVBs[stream].serial = attributes[i].serial;
+                mAppliedVBs[stream].stride = attributes[i].stride;
+                mAppliedVBs[stream].offset = attributes[i].offset;
+            }
+
+            element-&gt;Stream = stream;
+            element-&gt;Offset = 0;
+            element-&gt;Type = attributes[i].attribute-&gt;mArrayEnabled ? vertexBuffer-&gt;getDeclType(*attributes[i].attribute) : D3DDECLTYPE_FLOAT4;
+            element-&gt;Method = D3DDECLMETHOD_DEFAULT;
+            element-&gt;Usage = D3DDECLUSAGE_TEXCOORD;
+            element-&gt;UsageIndex = programBinary-&gt;getSemanticIndex(i);
+            element++;
+        }
+    }
+
+    if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS)
+    {
+        if (mInstancingEnabled)
+        {
+            for (int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+            {
+                device-&gt;SetStreamSourceFreq(i, 1);
+            }
+
+            mInstancingEnabled = false;
+        }
+    }
+
+    static const D3DVERTEXELEMENT9 end = D3DDECL_END();
+    *(element++) = end;
+
+    for (int i = 0; i &lt; NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        VertexDeclCacheEntry *entry = &amp;mVertexDeclCache[i];
+        if (memcmp(entry-&gt;cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 &amp;&amp; entry-&gt;vertexDeclaration)
+        {
+            entry-&gt;lruCount = ++mMaxLru;
+            if(entry-&gt;vertexDeclaration != mLastSetVDecl)
+            {
+                device-&gt;SetVertexDeclaration(entry-&gt;vertexDeclaration);
+                mLastSetVDecl = entry-&gt;vertexDeclaration;
+            }
+
+            return GL_NO_ERROR;
+        }
+    }
+
+    VertexDeclCacheEntry *lastCache = mVertexDeclCache;
+
+    for (int i = 0; i &lt; NUM_VERTEX_DECL_CACHE_ENTRIES; i++)
+    {
+        if (mVertexDeclCache[i].lruCount &lt; lastCache-&gt;lruCount)
+        {
+            lastCache = &amp;mVertexDeclCache[i];
+        }
+    }
+
+    if (lastCache-&gt;vertexDeclaration != NULL)
+    {
+        lastCache-&gt;vertexDeclaration-&gt;Release();
+        lastCache-&gt;vertexDeclaration = NULL;
+        // mLastSetVDecl is set to the replacement, so we don't have to worry
+        // about it.
+    }
+
+    memcpy(lastCache-&gt;cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9));
+    device-&gt;CreateVertexDeclaration(elements, &amp;lastCache-&gt;vertexDeclaration);
+    device-&gt;SetVertexDeclaration(lastCache-&gt;vertexDeclaration);
+    mLastSetVDecl = lastCache-&gt;vertexDeclaration;
+    lastCache-&gt;lruCount = ++mMaxLru;
+
+    return GL_NO_ERROR;
+}
+
+void VertexDeclarationCache::markStateDirty()
+{
+    for (int i = 0; i &lt; gl::MAX_VERTEX_ATTRIBS; i++)
+    {
+        mAppliedVBs[i].serial = 0;
+    }
+
+    mLastSetVDecl = NULL;
+    mInstancingEnabled = true;   // Forces it to be disabled when not used
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9VertexDeclarationCacheh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,58 @@
</span><ins>+//
+// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations.
+
+#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
+
+#include &quot;libGLESv2/renderer/VertexDataManager.h&quot;
+
+namespace gl
+{
+class VertexDataManager;
+}
+
+namespace rx
+{
+
+class VertexDeclarationCache
+{
+  public:
+    VertexDeclarationCache();
+    ~VertexDeclarationCache();
+
+    GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw);
+
+    void markStateDirty();
+
+  private:
+    UINT mMaxLru;
+
+    enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 };
+
+    struct VBData
+    {
+        unsigned int serial;
+        unsigned int stride;
+        unsigned int offset;
+    };
+
+    VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS];
+    IDirect3DVertexDeclaration9 *mLastSetVDecl;
+    bool mInstancingEnabled;
+
+    struct VertexDeclCacheEntry
+    {
+        D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1];
+        UINT lruCount;
+        IDirect3DVertexDeclaration9 *vertexDeclaration;
+    } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES];
+};
+
+}
+
+#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9renderer9_utilscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,500 @@
</span><ins>+#include &quot;precompiled.h&quot;
+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer9_utils.cpp: Conversion functions and other utility routines
+// specific to the D3D9 renderer.
+
+#include &quot;libGLESv2/renderer/d3d9/renderer9_utils.h&quot;
+#include &quot;libGLESv2/mathutil.h&quot;
+#include &quot;libGLESv2/Context.h&quot;
+
+#include &quot;common/debug.h&quot;
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison)
+{
+    D3DCMPFUNC d3dComp = D3DCMP_ALWAYS;
+    switch (comparison)
+    {
+      case GL_NEVER:    d3dComp = D3DCMP_NEVER;        break;
+      case GL_ALWAYS:   d3dComp = D3DCMP_ALWAYS;       break;
+      case GL_LESS:     d3dComp = D3DCMP_LESS;         break;
+      case GL_LEQUAL:   d3dComp = D3DCMP_LESSEQUAL;    break;
+      case GL_EQUAL:    d3dComp = D3DCMP_EQUAL;        break;
+      case GL_GREATER:  d3dComp = D3DCMP_GREATER;      break;
+      case GL_GEQUAL:   d3dComp = D3DCMP_GREATEREQUAL; break;
+      case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL;     break;
+      default: UNREACHABLE();
+    }
+
+    return d3dComp;
+}
+
+D3DCOLOR ConvertColor(gl::Color color)
+{
+    return D3DCOLOR_RGBA(gl::unorm&lt;8&gt;(color.red),
+                         gl::unorm&lt;8&gt;(color.green),
+                         gl::unorm&lt;8&gt;(color.blue),
+                         gl::unorm&lt;8&gt;(color.alpha));
+}
+
+D3DBLEND ConvertBlendFunc(GLenum blend)
+{
+    D3DBLEND d3dBlend = D3DBLEND_ZERO;
+
+    switch (blend)
+    {
+      case GL_ZERO:                     d3dBlend = D3DBLEND_ZERO;           break;
+      case GL_ONE:                      d3dBlend = D3DBLEND_ONE;            break;
+      case GL_SRC_COLOR:                d3dBlend = D3DBLEND_SRCCOLOR;       break;
+      case GL_ONE_MINUS_SRC_COLOR:      d3dBlend = D3DBLEND_INVSRCCOLOR;    break;
+      case GL_DST_COLOR:                d3dBlend = D3DBLEND_DESTCOLOR;      break;
+      case GL_ONE_MINUS_DST_COLOR:      d3dBlend = D3DBLEND_INVDESTCOLOR;   break;
+      case GL_SRC_ALPHA:                d3dBlend = D3DBLEND_SRCALPHA;       break;
+      case GL_ONE_MINUS_SRC_ALPHA:      d3dBlend = D3DBLEND_INVSRCALPHA;    break;
+      case GL_DST_ALPHA:                d3dBlend = D3DBLEND_DESTALPHA;      break;
+      case GL_ONE_MINUS_DST_ALPHA:      d3dBlend = D3DBLEND_INVDESTALPHA;   break;
+      case GL_CONSTANT_COLOR:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
+      case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+      case GL_CONSTANT_ALPHA:           d3dBlend = D3DBLEND_BLENDFACTOR;    break;
+      case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break;
+      case GL_SRC_ALPHA_SATURATE:       d3dBlend = D3DBLEND_SRCALPHASAT;    break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlend;
+}
+
+D3DBLENDOP ConvertBlendOp(GLenum blendOp)
+{
+    D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD;
+
+    switch (blendOp)
+    {
+      case GL_FUNC_ADD:              d3dBlendOp = D3DBLENDOP_ADD;         break;
+      case GL_FUNC_SUBTRACT:         d3dBlendOp = D3DBLENDOP_SUBTRACT;    break;
+      case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break;
+      default: UNREACHABLE();
+    }
+
+    return d3dBlendOp;
+}
+
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp)
+{
+    D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP;
+
+    switch (stencilOp)
+    {
+      case GL_ZERO:      d3dStencilOp = D3DSTENCILOP_ZERO;    break;
+      case GL_KEEP:      d3dStencilOp = D3DSTENCILOP_KEEP;    break;
+      case GL_REPLACE:   d3dStencilOp = D3DSTENCILOP_REPLACE; break;
+      case GL_INCR:      d3dStencilOp = D3DSTENCILOP_INCRSAT; break;
+      case GL_DECR:      d3dStencilOp = D3DSTENCILOP_DECRSAT; break;
+      case GL_INVERT:    d3dStencilOp = D3DSTENCILOP_INVERT;  break;
+      case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR;    break;
+      case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR;    break;
+      default: UNREACHABLE();
+    }
+
+    return d3dStencilOp;
+}
+
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap)
+{
+    D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP;
+
+    switch (wrap)
+    {
+      case GL_REPEAT:            d3dWrap = D3DTADDRESS_WRAP;   break;
+      case GL_CLAMP_TO_EDGE:     d3dWrap = D3DTADDRESS_CLAMP;  break;
+      case GL_MIRRORED_REPEAT:   d3dWrap = D3DTADDRESS_MIRROR; break;
+      default: UNREACHABLE();
+    }
+
+    return d3dWrap;
+}
+
+D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace)
+{
+    D3DCULL cull = D3DCULL_CCW;
+    switch (cullFace)
+    {
+      case GL_FRONT:
+        cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW);
+        break;
+      case GL_BACK:
+        cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW);
+        break;
+      case GL_FRONT_AND_BACK:
+        cull = D3DCULL_NONE; // culling will be handled during draw
+        break;
+      default: UNREACHABLE();
+    }
+
+    return cull;
+}
+
+D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace)
+{
+    D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X;
+
+    switch (cubeFace)
+    {
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+        face = D3DCUBEMAP_FACE_POSITIVE_X;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+        face = D3DCUBEMAP_FACE_NEGATIVE_X;
+        break;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+        face = D3DCUBEMAP_FACE_POSITIVE_Y;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+        face = D3DCUBEMAP_FACE_NEGATIVE_Y;
+        break;
+      case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+        face = D3DCUBEMAP_FACE_POSITIVE_Z;
+        break;
+      case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        face = D3DCUBEMAP_FACE_NEGATIVE_Z;
+        break;
+      default: UNREACHABLE();
+    }
+
+    return face;
+}
+
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha)
+{
+    return (red   ? D3DCOLORWRITEENABLE_RED   : 0) |
+           (green ? D3DCOLORWRITEENABLE_GREEN : 0) |
+           (blue  ? D3DCOLORWRITEENABLE_BLUE  : 0) |
+           (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0);
+}
+
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy)
+{
+    if (maxAnisotropy &gt; 1.0f)
+    {
+        return D3DTEXF_ANISOTROPIC;
+    }
+
+    D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT;
+    switch (magFilter)
+    {
+      case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT;  break;
+      case GL_LINEAR:  d3dMagFilter = D3DTEXF_LINEAR; break;
+      default: UNREACHABLE();
+    }
+
+    return d3dMagFilter;
+}
+
+void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy)
+{
+    switch (minFilter)
+    {
+      case GL_NEAREST:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_NONE;
+        break;
+      case GL_LINEAR:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_NONE;
+        break;
+      case GL_NEAREST_MIPMAP_NEAREST:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_POINT;
+        break;
+      case GL_LINEAR_MIPMAP_NEAREST:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_POINT;
+        break;
+      case GL_NEAREST_MIPMAP_LINEAR:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_LINEAR;
+        break;
+      case GL_LINEAR_MIPMAP_LINEAR:
+        *d3dMinFilter = D3DTEXF_LINEAR;
+        *d3dMipFilter = D3DTEXF_LINEAR;
+        break;
+      default:
+        *d3dMinFilter = D3DTEXF_POINT;
+        *d3dMipFilter = D3DTEXF_NONE;
+        UNREACHABLE();
+    }
+
+    if (maxAnisotropy &gt; 1.0f)
+    {
+        *d3dMinFilter = D3DTEXF_ANISOTROPIC;
+    }
+}
+
+D3DFORMAT ConvertRenderbufferFormat(GLenum format)
+{
+    switch (format)
+    {
+      case GL_NONE:                 return D3DFMT_NULL;
+      case GL_RGBA4:
+      case GL_RGB5_A1:
+      case GL_RGBA8_OES:            return D3DFMT_A8R8G8B8;
+      case GL_RGB565:               return D3DFMT_R5G6B5;
+      case GL_RGB8_OES:             return D3DFMT_X8R8G8B8;
+      case GL_DEPTH_COMPONENT16:
+      case GL_STENCIL_INDEX8:       
+      case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
+      default: UNREACHABLE();       return D3DFMT_A8R8G8B8;
+    }
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
+{
+    if (samples &lt;= 1)
+        return D3DMULTISAMPLE_NONE;
+    else
+        return (D3DMULTISAMPLE_TYPE)samples;
+}
+
+}
+
+namespace d3d9_gl
+{
+
+unsigned int GetStencilSize(D3DFORMAT stencilFormat)
+{
+    if (stencilFormat == D3DFMT_INTZ)
+    {
+        return 8;
+    }
+    switch(stencilFormat)
+    {
+      case D3DFMT_D24FS8:
+      case D3DFMT_D24S8:
+        return 8;
+      case D3DFMT_D24X4S4:
+        return 4;
+      case D3DFMT_D15S1:
+        return 1;
+      case D3DFMT_D16_LOCKABLE:
+      case D3DFMT_D32:
+      case D3DFMT_D24X8:
+      case D3DFMT_D32F_LOCKABLE:
+      case D3DFMT_D16:
+        return 0;
+    //case D3DFMT_D32_LOCKABLE:  return 0;   // DirectX 9Ex only
+    //case D3DFMT_S8_LOCKABLE:   return 8;   // DirectX 9Ex only
+      default:
+        return 0;
+    }
+}
+
+unsigned int GetAlphaSize(D3DFORMAT colorFormat)
+{
+    switch (colorFormat)
+    {
+      case D3DFMT_A16B16G16R16F:
+        return 16;
+      case D3DFMT_A32B32G32R32F:
+        return 32;
+      case D3DFMT_A2R10G10B10:
+        return 2;
+      case D3DFMT_A8R8G8B8:
+        return 8;
+      case D3DFMT_A1R5G5B5:
+        return 1;
+      case D3DFMT_X8R8G8B8:
+      case D3DFMT_R5G6B5:
+        return 0;
+      default:
+        return 0;
+    }
+}
+
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
+{
+    if (type == D3DMULTISAMPLE_NONMASKABLE)
+        return 0;
+    else
+        return type;
+}
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format)
+{
+    switch (d3dformat)
+    {
+      case D3DFMT_L8:
+        return (format == GL_LUMINANCE);
+      case D3DFMT_A8L8:
+        return (format == GL_LUMINANCE_ALPHA);
+      case D3DFMT_DXT1:
+        return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
+      case D3DFMT_DXT3:
+        return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE);
+      case D3DFMT_DXT5:
+        return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE);
+      case D3DFMT_A8R8G8B8:
+      case D3DFMT_A16B16G16R16F:
+      case D3DFMT_A32B32G32R32F:
+        return (format == GL_RGBA || format == GL_BGRA_EXT);
+      case D3DFMT_X8R8G8B8:
+        return (format == GL_RGB);
+      default:
+        if (d3dformat == D3DFMT_INTZ &amp;&amp; gl::IsDepthTexture(format))
+            return true;
+        return false;
+    }
+}
+
+GLenum ConvertBackBufferFormat(D3DFORMAT format)
+{
+    switch (format)
+    {
+      case D3DFMT_A4R4G4B4: return GL_RGBA4;
+      case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+      case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+      case D3DFMT_R5G6B5:   return GL_RGB565;
+      case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA4;
+}
+
+GLenum ConvertDepthStencilFormat(D3DFORMAT format)
+{
+    if (format == D3DFMT_INTZ)
+    {
+        return GL_DEPTH24_STENCIL8_OES;
+    }
+    switch (format)
+    {
+      case D3DFMT_D16:
+      case D3DFMT_D24X8:
+        return GL_DEPTH_COMPONENT16;
+      case D3DFMT_D24S8:
+        return GL_DEPTH24_STENCIL8_OES;
+      case D3DFMT_UNKNOWN:
+        return GL_NONE;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_DEPTH24_STENCIL8_OES;
+}
+
+GLenum ConvertRenderTargetFormat(D3DFORMAT format)
+{
+    if (format == D3DFMT_INTZ)
+    {
+        return GL_DEPTH24_STENCIL8_OES;
+    }
+    
+    switch (format)
+    {
+      case D3DFMT_A4R4G4B4: return GL_RGBA4;
+      case D3DFMT_A8R8G8B8: return GL_RGBA8_OES;
+      case D3DFMT_A1R5G5B5: return GL_RGB5_A1;
+      case D3DFMT_R5G6B5:   return GL_RGB565;
+      case D3DFMT_X8R8G8B8: return GL_RGB8_OES;
+      case D3DFMT_D16:
+      case D3DFMT_D24X8:
+        return GL_DEPTH_COMPONENT16;
+      case D3DFMT_D24S8:
+        return GL_DEPTH24_STENCIL8_OES;
+      case D3DFMT_UNKNOWN:
+        return GL_NONE;
+      default:
+        UNREACHABLE();
+    }
+
+    return GL_RGBA4;
+}
+
+GLenum GetEquivalentFormat(D3DFORMAT format)
+{
+    if (format == D3DFMT_INTZ)
+        return GL_DEPTH24_STENCIL8_OES;
+    if (format == D3DFMT_NULL)
+        return GL_NONE;
+
+    switch (format)
+    {
+      case D3DFMT_A4R4G4B4:             return GL_RGBA4;
+      case D3DFMT_A8R8G8B8:             return GL_RGBA8_OES;
+      case D3DFMT_A1R5G5B5:             return GL_RGB5_A1;
+      case D3DFMT_R5G6B5:               return GL_RGB565;
+      case D3DFMT_X8R8G8B8:             return GL_RGB8_OES;
+      case D3DFMT_D16:                  return GL_DEPTH_COMPONENT16;
+      case D3DFMT_D24S8:                return GL_DEPTH24_STENCIL8_OES;
+      case D3DFMT_UNKNOWN:              return GL_NONE;
+      case D3DFMT_DXT1:                 return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+      case D3DFMT_DXT3:                 return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
+      case D3DFMT_DXT5:                 return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
+      case D3DFMT_A32B32G32R32F:        return GL_RGBA32F_EXT;
+      case D3DFMT_A16B16G16R16F:        return GL_RGBA16F_EXT;
+      case D3DFMT_L8:                   return GL_LUMINANCE8_EXT;
+      case D3DFMT_A8L8:                 return GL_LUMINANCE8_ALPHA8_EXT;
+      default:              UNREACHABLE();
+        return GL_NONE;
+    }
+}
+
+}
+
+namespace d3d9
+{
+
+bool IsCompressedFormat(D3DFORMAT surfaceFormat)
+{
+    switch(surfaceFormat)
+    {
+      case D3DFMT_DXT1:
+      case D3DFMT_DXT2:
+      case D3DFMT_DXT3:
+      case D3DFMT_DXT4:
+      case D3DFMT_DXT5:
+        return true;
+      default:
+        return false;
+    }
+}
+
+size_t ComputeRowSize(D3DFORMAT format, unsigned int width)
+{
+    if (format == D3DFMT_INTZ)
+    {
+        return 4 * width;
+    }
+    switch (format)
+    {
+      case D3DFMT_L8:
+          return 1 * width;
+      case D3DFMT_A8L8:
+          return 2 * width;
+      case D3DFMT_X8R8G8B8:
+      case D3DFMT_A8R8G8B8:
+        return 4 * width;
+      case D3DFMT_A16B16G16R16F:
+        return 8 * width;
+      case D3DFMT_A32B32G32R32F:
+        return 16 * width;
+      case D3DFMT_DXT1:
+        return 8 * ((width + 3) / 4);
+      case D3DFMT_DXT3:
+      case D3DFMT_DXT5:
+        return 16 * ((width + 3) / 4);
+      default:
+        UNREACHABLE();
+        return 0;
+    }
+}
+
+}
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9renderer9_utilsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+//
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// renderer9_utils.h: Conversion functions and other utility routines 
+// specific to the D3D9 renderer
+
+#ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+#define LIBGLESV2_RENDERER_RENDERER9_UTILS_H
+
+#include &quot;libGLESv2/utilities.h&quot;
+
+const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')));
+const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L')));
+
+namespace gl_d3d9
+{
+
+D3DCMPFUNC ConvertComparison(GLenum comparison);
+D3DCOLOR ConvertColor(gl::Color color);
+D3DBLEND ConvertBlendFunc(GLenum blend);
+D3DBLENDOP ConvertBlendOp(GLenum blendOp);
+D3DSTENCILOP ConvertStencilOp(GLenum stencilOp);
+D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap);
+D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace);
+D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace);
+DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha);
+D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy);
+void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy);
+D3DFORMAT ConvertRenderbufferFormat(GLenum format);
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
+
+}
+
+namespace d3d9_gl
+{
+
+GLuint GetAlphaSize(D3DFORMAT colorFormat);
+GLuint GetStencilSize(D3DFORMAT stencilFormat);
+
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
+
+bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format);
+GLenum ConvertBackBufferFormat(D3DFORMAT format);
+GLenum ConvertDepthStencilFormat(D3DFORMAT format);
+GLenum ConvertRenderTargetFormat(D3DFORMAT format);
+GLenum GetEquivalentFormat(D3DFORMAT format);
+
+}
+
+namespace d3d9
+{
+bool IsCompressedFormat(D3DFORMAT format);
+size_t ComputeRowSize(D3DFORMAT format, unsigned int width);
+
+inline bool isDeviceLostError(HRESULT errorCode)
+{
+    switch (errorCode)
+    {
+      case D3DERR_DRIVERINTERNALERROR:
+      case D3DERR_DEVICELOST:
+      case D3DERR_DEVICEHUNG:
+      case D3DERR_DEVICEREMOVED:
+        return true;
+      default:
+        return false;
+    }
+}
+
+}
+
+#endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/renderer9_utils.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersBlitps"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.ps (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.ps                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.ps        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+//
+// 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.
+//
+
+sampler2D tex : s0;
+
+uniform float4 mode : c0;
+
+// Passthrough Pixel Shader
+// Outputs texture 0 sampled at texcoord 0.
+float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR
+{
+        return tex2D(tex, texcoord.xy);
+};
+
+// Luminance Conversion Pixel Shader
+// Outputs sample(tex0, tc0).rrra.
+// For LA output (pass A) set C0.X = 1, C0.Y = 0.
+// For L output (A = 1) set C0.X = 0, C0.Y = 1.
+float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR
+{
+        float4 tmp = tex2D(tex, texcoord.xy);
+        tmp.w = tmp.w * mode.x + mode.y;
+        return tmp.xxxw;
+};
+
+// RGB/A Component Mask Pixel Shader
+// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1.
+// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1.
+// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0.
+float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR
+{
+        float4 tmp = tex2D(tex, texcoord.xy);
+        tmp.xyz = tmp.xyz * mode.x;
+        tmp.w = tmp.w * mode.z + mode.w;
+        return tmp;
+};
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersBlitvs"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.vs (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.vs                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/Blit.vs        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+//
+// 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.
+//
+
+struct VS_OUTPUT
+{
+    float4 position : POSITION;
+    float4 texcoord : TEXCOORD0;
+};
+
+uniform float4 halfPixelSize : c0;
+
+// Standard Vertex Shader
+// Input 0 is the homogenous position.
+// Outputs the homogenous position as-is.
+// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right.
+// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0.
+VS_OUTPUT standardvs(in float4 position : POSITION)
+{
+    VS_OUTPUT Out;
+
+    Out.position = position + halfPixelSize;
+    Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);
+
+    return Out;
+};
+
+// Flip Y Vertex Shader
+// Input 0 is the homogenous position.
+// Outputs the homogenous position as-is.
+// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right.
+// C0.XY must be the half-pixel width and height. C0.ZW must be 0.
+VS_OUTPUT flipyvs(in float4 position : POSITION)
+{
+    VS_OUTPUT Out;
+
+    Out.position = position + halfPixelSize;
+    Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0);
+
+    return Out;
+};
</ins></span></pre></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledcomponentmaskpsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+///
+// Parameters:
+//
+//   float4 mode;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mode         c0       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mul r1.xyz, r0, c0.x
+    mad r1.w, r0.w, c0.z, c0.w
+    mov oC0, r1
+
+// approximately 4 instruction slots used (1 texture, 3 arithmetic)
+#endif
+
+const BYTE g_ps20_componentmaskps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     44,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0, 119,   0, 
+      0,   0,   0,   2, 255, 255, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+    112,   0,   0,   0,  68,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,  76,   0, 
+      0,   0,   0,   0,   0,   0, 
+     92,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     96,   0,   0,   0,   0,   0, 
+      0,   0, 109, 111, 100, 101, 
+      0, 171, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 116, 101, 120,   0, 
+      4,   0,  12,   0,   1,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 112, 115, 
+     95,  50,  95,  48,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  57,  46, 
+     51,  48,  46,  57,  50,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   5,   0,   0,   3, 
+      1,   0,   7, 128,   0,   0, 
+    228, 128,   0,   0,   0, 160, 
+      4,   0,   0,   4,   1,   0, 
+      8, 128,   0,   0, 255, 128, 
+      0,   0, 170, 160,   0,   0, 
+    255, 160,   1,   0,   0,   2, 
+      0,   8,  15, 128,   1,   0, 
+    228, 128, 255, 255,   0,   0
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledflipyvsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+///
+// Parameters:
+//
+//   float4 halfPixelSize;
+//
+//
+// Registers:
+//
+//   Name          Reg   Size
+//   ------------- ----- ----
+//   halfPixelSize c0       1
+//
+
+    vs_2_0
+    def c1, 0.5, 1, 0, 0
+    dcl_position v0
+    add oPos, v0, c0
+    mad oT0, v0, c1.xxyy, c1.xxzz
+
+// approximately 2 instruction slots used
+#endif
+
+const BYTE g_vs20_flipyvs[] =
+{
+      0,   2, 254, 255, 254, 255, 
+     36,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0,  87,   0, 
+      0,   0,   0,   2, 254, 255, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+     80,   0,   0,   0,  48,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+    104,  97, 108, 102,  80, 105, 
+    120, 101, 108,  83, 105, 122, 
+    101,   0, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 118, 115,  95,  50, 
+     95,  48,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  51,  48, 
+     46,  57,  50,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  81,   0,   0,   5, 
+      1,   0,  15, 160,   0,   0, 
+      0,  63,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  31,   0,   0,   2, 
+      0,   0,   0, 128,   0,   0, 
+     15, 144,   2,   0,   0,   3, 
+      0,   0,  15, 192,   0,   0, 
+    228, 144,   0,   0, 228, 160, 
+      4,   0,   0,   4,   0,   0, 
+     15, 224,   0,   0, 228, 144, 
+      1,   0,  80, 160,   1,   0, 
+    160, 160, 255, 255,   0,   0
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledluminancepsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+///
+// Parameters:
+//
+//   float4 mode;
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   mode         c0       1
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mad r1.w, r0.w, c0.x, c0.y
+    mov r1.xyz, r0.x
+    mov oC0, r1
+
+// approximately 4 instruction slots used (1 texture, 3 arithmetic)
+#endif
+
+const BYTE g_ps20_luminanceps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     44,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0, 119,   0, 
+      0,   0,   0,   2, 255, 255, 
+      2,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+    112,   0,   0,   0,  68,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,  76,   0, 
+      0,   0,   0,   0,   0,   0, 
+     92,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     96,   0,   0,   0,   0,   0, 
+      0,   0, 109, 111, 100, 101, 
+      0, 171, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 116, 101, 120,   0, 
+      4,   0,  12,   0,   1,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 112, 115, 
+     95,  50,  95,  48,   0,  77, 
+    105,  99, 114, 111, 115, 111, 
+    102, 116,  32,  40,  82,  41, 
+     32,  72,  76,  83,  76,  32, 
+     83, 104,  97, 100, 101, 114, 
+     32,  67, 111, 109, 112, 105, 
+    108, 101, 114,  32,  57,  46, 
+     51,  48,  46,  57,  50,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   4,   0,   0,   4, 
+      1,   0,   8, 128,   0,   0, 
+    255, 128,   0,   0,   0, 160, 
+      0,   0,  85, 160,   1,   0, 
+      0,   2,   1,   0,   7, 128, 
+      0,   0,   0, 128,   1,   0, 
+      0,   2,   0,   8,  15, 128, 
+      1,   0, 228, 128, 255, 255, 
+      0,   0
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledpassthroughpsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,62 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+///
+// Parameters:
+//
+//   sampler2D tex;
+//
+//
+// Registers:
+//
+//   Name         Reg   Size
+//   ------------ ----- ----
+//   tex          s0       1
+//
+
+    ps_2_0
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mov oC0, r0
+
+// approximately 2 instruction slots used (1 texture, 1 arithmetic)
+#endif
+
+const BYTE g_ps20_passthroughps[] =
+{
+      0,   2, 255, 255, 254, 255, 
+     33,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0,  75,   0, 
+      0,   0,   0,   2, 255, 255, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+     68,   0,   0,   0,  48,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,  52,   0, 
+      0,   0,   0,   0,   0,   0, 
+    116, 101, 120,   0,   4,   0, 
+     12,   0,   1,   0,   1,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 112, 115,  95,  50, 
+     95,  48,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  51,  48, 
+     46,  57,  50,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  31,   0,   0,   2, 
+      0,   0,   0, 128,   0,   0, 
+      3, 176,  31,   0,   0,   2, 
+      0,   0,   0, 144,   0,   8, 
+     15, 160,  66,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+    228, 176,   0,   8, 228, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shaderscompiledstandardvsh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,67 @@
</span><ins>+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.16384
+//
+///
+// Parameters:
+//
+//   float4 halfPixelSize;
+//
+//
+// Registers:
+//
+//   Name          Reg   Size
+//   ------------- ----- ----
+//   halfPixelSize c0       1
+//
+
+    vs_2_0
+    def c1, 0.5, -0.5, 1, 0
+    dcl_position v0
+    add oPos, v0, c0
+    mad oT0, v0, c1.xyzz, c1.xxww
+
+// approximately 2 instruction slots used
+#endif
+
+const BYTE g_vs20_standardvs[] =
+{
+      0,   2, 254, 255, 254, 255, 
+     36,   0,  67,  84,  65,  66, 
+     28,   0,   0,   0,  87,   0, 
+      0,   0,   0,   2, 254, 255, 
+      1,   0,   0,   0,  28,   0, 
+      0,   0,   0,   1,   0,   0, 
+     80,   0,   0,   0,  48,   0, 
+      0,   0,   2,   0,   0,   0, 
+      1,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+    104,  97, 108, 102,  80, 105, 
+    120, 101, 108,  83, 105, 122, 
+    101,   0, 171, 171,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0, 118, 115,  95,  50, 
+     95,  48,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  57,  46,  51,  48, 
+     46,  57,  50,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  81,   0,   0,   5, 
+      1,   0,  15, 160,   0,   0, 
+      0,  63,   0,   0,   0, 191, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,  31,   0,   0,   2, 
+      0,   0,   0, 128,   0,   0, 
+     15, 144,   2,   0,   0,   3, 
+      0,   0,  15, 192,   0,   0, 
+    228, 144,   0,   0, 228, 160, 
+      4,   0,   0,   4,   0,   0, 
+     15, 224,   0,   0, 228, 144, 
+      1,   0, 164, 160,   1,   0, 
+    240, 160, 255, 255,   0,   0
+};
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9shadersgenerate_shadersbat"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,14 @@
</span><ins>+@ECHO OFF
+REM
+REM Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
+REM Use of this source code is governed by a BSD-style license that can be
+REM found in the LICENSE file.
+REM
+
+PATH %PATH%;%ProgramFiles(x86)%\Windows Kits\8.0\bin\x86;%DXSDK_DIR%\Utilities\bin\x86
+
+fxc /E standardvs /T vs_2_0 /Fh compiled/standardvs.h Blit.vs
+fxc /E flipyvs /T vs_2_0 /Fh compiled/flipyvs.h Blit.vs
+fxc /E passthroughps /T ps_2_0 /Fh compiled/passthroughps.h Blit.ps
+fxc /E luminanceps /T ps_2_0 /Fh compiled/luminanceps.h Blit.ps
+fxc /E componentmaskps /T ps_2_0 /Fh compiled/componentmaskps.h Blit.ps
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/shaders/generate_shaders.bat
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
<a id="trunkSourceThirdPartyANGLEsrclibGLESv2rendererd3d9vertexconversionh"></a>
<div class="addfile"><h4>Added: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/vertexconversion.h (0 => 164567)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/vertexconversion.h                                (rev 0)
+++ trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/vertexconversion.h        2014-02-24 00:58:19 UTC (rev 164567)
</span><span class="lines">@@ -0,0 +1,203 @@
</span><ins>+//
+// 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_
+
+namespace rx
+{
+
+// 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 &lt;class T&gt;
+struct Identity
+{
+    static const bool identity = true;
+
+    typedef T OutputType;
+
+    static T convert(T x)
+    {
+        return x;
+    }
+};
+
+template &lt;class FromT, class ToT&gt;
+struct Cast
+{
+    static const bool identity = false;
+
+    typedef ToT OutputType;
+
+    static ToT convert(FromT x)
+    {
+        return static_cast&lt;ToT&gt;(x);
+    }
+};
+
+template &lt;class T&gt;
+struct Cast&lt;T, T&gt;
+{
+    static const bool identity = true;
+
+    typedef T OutputType;
+
+    static T convert(T x)
+    {
+        return static_cast&lt;T&gt;(x);
+    }
+};
+
+template &lt;class T&gt;
+struct Normalize
+{
+    static const bool identity = false;
+
+    typedef float OutputType;
+
+    static float convert(T x)
+    {
+        typedef std::numeric_limits&lt;T&gt; NL;
+        float f = static_cast&lt;float&gt;(x);
+
+        if (NL::is_signed)
+        {
+            // const float =&gt; VC2008 computes it at compile time
+            // static const float =&gt; 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&lt;float&gt;(NL::max())+1);
+            return (2*f+1)*divisor;
+        }
+        else
+        {
+            return f/NL::max();
+        }
+    }
+};
+
+template &lt;class FromType, std::size_t ScaleBits&gt;
+struct FixedToFloat
+{
+    static const bool identity = false;
+
+    typedef float OutputType;
+
+    static float convert(FromType x)
+    {
+        const float divisor = 1.0f / static_cast&lt;float&gt;(static_cast&lt;FromType&gt;(1) &lt;&lt; ScaleBits);
+        return static_cast&lt;float&gt;(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 &lt;std::size_t N&gt;
+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 &lt;std::size_t N&gt;
+struct WidenToEven
+{
+    static const std::size_t initialWidth = N;
+    static const std::size_t finalWidth = N+(N&amp;1);
+};
+
+template &lt;std::size_t N&gt;
+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 &lt;class T&gt;
+struct SimpleDefaultValues
+{
+    static T zero() { return static_cast&lt;T&gt;(0); }
+    static T one() { return static_cast&lt;T&gt;(1); }
+};
+
+// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value.
+template &lt;class T&gt;
+struct NormalizedDefaultValues
+{
+    static T zero() { return static_cast&lt;T&gt;(0); }
+    static T one() { return std::numeric_limits&lt;T&gt;::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 &lt;class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues&lt;InT&gt; &gt;
+struct VertexDataConverter
+{
+    typedef typename Converter::OutputType OutputType;
+    typedef InT InputType;
+
+    static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) &amp;&amp; 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 &lt; n; i++)
+        {
+            const InputType *ein = pointerAddBytes(in, i * stride);
+
+            copyComponent(out, ein, 0, static_cast&lt;OutputType&gt;(DefaultValueRule::zero()));
+            copyComponent(out, ein, 1, static_cast&lt;OutputType&gt;(DefaultValueRule::zero()));
+            copyComponent(out, ein, 2, static_cast&lt;OutputType&gt;(DefaultValueRule::zero()));
+            copyComponent(out, ein, 3, static_cast&lt;OutputType&gt;(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&lt;const InputType*&gt;(in), stride, n, static_cast&lt;OutputType*&gt;(out));
+    }
+
+  private:
+    // Advance the given pointer by a number of bytes (not pointed-to elements).
+    template &lt;class T&gt;
+    static T *pointerAddBytes(T *basePtr, std::size_t numBytes)
+    {
+        return reinterpret_cast&lt;T *&gt;(reinterpret_cast&lt;uintptr_t&gt;(basePtr) + numBytes);
+    }
+
+    static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue)
+    {
+        if (WidenRule::finalWidth &gt; elementindex)
+        {
+            if (WidenRule::initialWidth &gt; elementindex)
+            {
+                out[elementindex] = Converter::convert(in[elementindex]);
+            }
+            else
+            {
+                out[elementindex] = defaultvalue;
+            }
+        }
+    }
+};
+
+}
+
+#endif   // LIBGLESV2_VERTEXCONVERSION_H_
</ins><span class="cx">Property changes on: trunk/Source/ThirdParty/ANGLE/src/libGLESv2/renderer/d3d9/vertexconversion.h
</span><span class="cx">___________________________________________________________________
</span></span></pre></div>
<a id="svnkeywords"></a>
<div class="addfile"><h4>Added: svn:keywords</h4></div>
<a id="svneolstyle"></a>
<div class="addfile"><h4>Added: svn:eol-style</h4></div>
</div>

</body>
</html>