Add an option in ANGLE shader translator to initialize gl_Position to vec4(0.0, 0.0, 0.0, 1.0).

This is to work around driver bugs where shader compile or program link would fail incorrectly if gl_Position is not set in vertex shader.

At the moment at least Linux NVIDIA driver has this bug.

ANGLEBUG=472
R=alokp@chromium.org, kbr@chromium.org

Review URL: https://codereview.appspot.com/13509043
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 0a91f9b..4afa73d 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -8,6 +8,7 @@
 #include "compiler/DetectCallDepth.h"
 #include "compiler/ForLoopUnroll.h"
 #include "compiler/Initialize.h"
+#include "compiler/InitializeGLPosition.h"
 #include "compiler/InitializeParseContext.h"
 #include "compiler/MapLongVariableNames.h"
 #include "compiler/ParseHelper.h"
@@ -196,6 +197,11 @@
         if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
             mapLongVariableNames(root);
 
+        if (success && shaderType == SH_VERTEX_SHADER && (compileOptions & SH_INIT_GL_POSITION)) {
+            InitializeGLPosition initGLPosition;
+            root->traverse(&initGLPosition);
+        }
+
         if (success && (compileOptions & SH_VARIABLES)) {
             collectVariables(root);
             if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
diff --git a/src/compiler/InitializeGLPosition.cpp b/src/compiler/InitializeGLPosition.cpp
new file mode 100644
index 0000000..e0193e3
--- /dev/null
+++ b/src/compiler/InitializeGLPosition.cpp
@@ -0,0 +1,61 @@
+//
+// 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 "compiler/InitializeGLPosition.h"
+#include "compiler/debug.h"
+
+bool InitializeGLPosition::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    bool visitChildren = !mCodeInserted;
+    switch (node->getOp())
+    {
+      case EOpSequence: break;
+      case EOpFunction:
+      {
+        // Function definition.
+        ASSERT(visit == PreVisit);
+        if (node->getName() == "main(")
+        {
+            TIntermSequence &sequence = node->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]->getAsAggregate();
+            }
+            ASSERT(body);
+            insertCode(body->getSequence());
+            mCodeInserted = true;
+        }
+        break;
+      }
+      default: visitChildren = false; break;
+    }
+    return visitChildren;
+}
+
+void InitializeGLPosition::insertCode(TIntermSequence& sequence)
+{
+    TIntermBinary *binary = new TIntermBinary(EOpAssign);
+    sequence.insert(sequence.begin(), binary);
+
+    TIntermSymbol *left = new TIntermSymbol(
+        0, "gl_Position", TType(EbtFloat, EbpUndefined, EvqPosition, 4));
+    binary->setLeft(left);
+
+    ConstantUnion *u = new ConstantUnion[4];
+    for (int ii = 0; ii < 3; ++ii)
+        u[ii].setFConst(0.0f);
+    u[3].setFConst(1.0f);
+    TIntermConstantUnion *right = new TIntermConstantUnion(
+        u, TType(EbtFloat, EbpUndefined, EvqConst, 4));
+    binary->setRight(right);
+}
diff --git a/src/compiler/InitializeGLPosition.h b/src/compiler/InitializeGLPosition.h
new file mode 100644
index 0000000..1b11075
--- /dev/null
+++ b/src/compiler/InitializeGLPosition.h
@@ -0,0 +1,33 @@
+//
+// 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_GL_POSITION_H_
+#define COMPILER_INITIALIZE_GL_POSITION_H_
+
+#include "compiler/intermediate.h"
+
+class InitializeGLPosition : public TIntermTraverser
+{
+public:
+    InitializeGLPosition() : mCodeInserted(false) { }
+
+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:
+    // Insert AST node in the beginning of main() for "gl_Position = vec4(0.0, 0.0, 0.0, 1.0);".
+    void insertCode(TIntermSequence& sequence);
+
+    bool mCodeInserted;
+};
+
+#endif  // COMPILER_INITIALIZE_GL_POSITION_H_
diff --git a/src/compiler/translator_common.vcxproj b/src/compiler/translator_common.vcxproj
index 6d5054c..78f5f79 100644
--- a/src/compiler/translator_common.vcxproj
+++ b/src/compiler/translator_common.vcxproj
@@ -150,6 +150,7 @@
     <ClCompile Include="InfoSink.cpp" />
     <ClCompile Include="Initialize.cpp" />
     <ClCompile Include="InitializeDll.cpp" />
+    <ClCompile Include="InitializeGLPosition.cpp" />
     <ClCompile Include="InitializeParseContext.cpp" />
     <ClCompile Include="Intermediate.cpp" />
     <ClCompile Include="intermOut.cpp" />
@@ -244,6 +245,7 @@
     <ClInclude Include="Initialize.h" />
     <ClInclude Include="InitializeDll.h" />
     <ClInclude Include="InitializeGlobals.h" />
+    <ClInclude Include="InitializeGLPosition.h" />
     <ClInclude Include="InitializeParseContext.h" />
     <ClInclude Include="intermediate.h" />
     <ClInclude Include="localintermediate.h" />
diff --git a/src/compiler/translator_common.vcxproj.filters b/src/compiler/translator_common.vcxproj.filters
index d81e524..7de9493 100644
--- a/src/compiler/translator_common.vcxproj.filters
+++ b/src/compiler/translator_common.vcxproj.filters
@@ -146,6 +146,9 @@
     <ClCompile Include="BlockLayoutEncoder.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="InitializeGLPosition.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="BaseTypes.h">
@@ -274,6 +277,9 @@
     <ClInclude Include="BlockLayoutEncoder.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="InitializeGLPosition.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="glslang.l">