Merged EXT_frag_depth changes into dx11proto branch

BUG=429

Review URL: https://codereview.appspot.com/9738048

git-svn-id: http://angleproject.googlecode.com/svn/branches/dx11proto@2419 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index f0459b5..722ac64 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -218,6 +218,7 @@
     int OES_EGL_image_external;
     int ARB_texture_rectangle;
     int EXT_draw_buffers;
+    int EXT_frag_depth;
 
     // Set to 1 if highp precision is supported in the fragment language.
     // Default is 0.
diff --git a/src/compiler/BaseTypes.h b/src/compiler/BaseTypes.h
index 0a3adfd..1631f4f 100644
--- a/src/compiler/BaseTypes.h
+++ b/src/compiler/BaseTypes.h
@@ -108,6 +108,7 @@
     // built-ins written by fragment shader
     EvqFragColor,
     EvqFragData,
+    EvqFragDepth,
 
     // end of list
     EvqLast
@@ -139,6 +140,7 @@
     case EvqFrontFacing:    return "FrontFacing";    break;
     case EvqFragColor:      return "FragColor";      break;
     case EvqFragData:       return "FragData";      break;
+    case EvqFragDepth:      return "FragDepth";     break;
     default:                return "unknown qualifier";
     }
 }
diff --git a/src/compiler/Initialize.cpp b/src/compiler/Initialize.cpp
index 3b71b72..d0ca47a 100644
--- a/src/compiler/Initialize.cpp
+++ b/src/compiler/Initialize.cpp
@@ -546,6 +546,10 @@
         if (spec != SH_CSS_SHADERS_SPEC) {
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragColor"),                   TType(EbtFloat, EbpMedium, EvqFragColor,   4)));
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData,    4)));
+            if (resources.EXT_frag_depth) {
+                symbolTable.insert(*new TVariable(NewPoolTString("gl_FragDepthEXT"),            TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
+                symbolTable.relateToExtension("gl_FragDepthEXT", "GL_EXT_frag_depth");
+            }
         } else {
             symbolTable.insert(*new TVariable(NewPoolTString("css_MixColor"),                   TType(EbtFloat, EbpMedium, EvqGlobal,      4)));
             symbolTable.insert(*new TVariable(NewPoolTString("css_ColorMatrix"),                TType(EbtFloat, EbpMedium, EvqGlobal,      4, true)));
@@ -663,4 +667,6 @@
         extBehavior["GL_ARB_texture_rectangle"] = EBhUndefined;
     if (resources.EXT_draw_buffers)
         extBehavior["GL_EXT_draw_buffers"] = EBhUndefined;
+    if (resources.EXT_frag_depth)
+        extBehavior["GL_EXT_frag_depth"] = EBhUndefined;
 }
diff --git a/src/compiler/OutputGLSL.cpp b/src/compiler/OutputGLSL.cpp
index 206f403..10a451c 100644
--- a/src/compiler/OutputGLSL.cpp
+++ b/src/compiler/OutputGLSL.cpp
@@ -19,3 +19,17 @@
 {
     return false;
 }
+
+void TOutputGLSL::visitSymbol(TIntermSymbol* node)
+{
+    TInfoSinkBase& out = objSink();
+
+    if (node->getSymbol() == "gl_FragDepthEXT")
+    {
+        out << "gl_FragDepth";
+    }
+    else
+    {
+        TOutputGLSLBase::visitSymbol(node);
+    }
+}
diff --git a/src/compiler/OutputGLSL.h b/src/compiler/OutputGLSL.h
index 199b6f3..fa68ac8 100644
--- a/src/compiler/OutputGLSL.h
+++ b/src/compiler/OutputGLSL.h
@@ -20,6 +20,7 @@
 
 protected:
     virtual bool writeVariablePrecision(TPrecision);
+    virtual void visitSymbol(TIntermSymbol* node);
 };
 
 #endif  // CROSSCOMPILERGLSL_OUTPUTGLSL_H_
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 781d309..c6c6e33 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -55,6 +55,7 @@
     mUsesPointCoord = false;
     mUsesFrontFacing = false;
     mUsesPointSize = false;
+    mUsesFragDepth = false;
     mUsesXor = false;
     mUsesMod1 = false;
     mUsesMod2v = false;
@@ -230,6 +231,11 @@
         }
         out << "};\n";
 
+        if (mUsesFragDepth)
+        {
+            out << "static float gl_Depth = 0.0;\n";
+        }
+
         if (mUsesFragCoord)
         {
             out << "static float4 gl_FragCoord = float4(0, 0, 0, 0);\n";
@@ -844,6 +850,11 @@
         out << "#define GL_USES_POINT_SIZE\n";
     }
 
+    if (mUsesFragDepth)
+    {
+        out << "#define GL_USES_FRAG_DEPTH\n";
+    }
+
     if (mUsesDepthRange)
     {
         out << "#define GL_USES_DEPTH_RANGE\n";
@@ -1171,6 +1182,11 @@
         mUsesPointSize = true;
         out << name;
     }
+    else if (name == "gl_FragDepthEXT")
+    {
+        mUsesFragDepth = true;
+        out << "gl_Depth";
+    }
     else
     {
         TQualifier qualifier = node->getQualifier();
diff --git a/src/compiler/OutputHLSL.h b/src/compiler/OutputHLSL.h
index 749a346..b33b1f5 100644
--- a/src/compiler/OutputHLSL.h
+++ b/src/compiler/OutputHLSL.h
@@ -108,6 +108,7 @@
     bool mUsesPointCoord;
     bool mUsesFrontFacing;
     bool mUsesPointSize;
+    bool mUsesFragDepth;
     bool mUsesXor;
     bool mUsesMod1;
     bool mUsesMod2v;
diff --git a/src/compiler/ParseHelper.cpp b/src/compiler/ParseHelper.cpp
index 040deb1..76855f1 100644
--- a/src/compiler/ParseHelper.cpp
+++ b/src/compiler/ParseHelper.cpp
@@ -925,6 +925,27 @@
     return static_cast<const TFunction*>(symbol);
 }
 
+bool TParseContext::isVariableBuiltIn(const TVariable* var)
+{
+    bool builtIn = false;
+    // First find by unmangled name to check whether the function name has been
+    // hidden by a variable name or struct typename.
+    const TSymbol* symbol = symbolTable.find(var->getName(), &builtIn);
+    if (symbol == 0) {
+        symbol = symbolTable.find(var->getMangledName(), &builtIn);
+    }
+
+    if (symbol == 0) {
+        return false;
+    }
+
+    if (!symbol->isVariable()) {
+        return false;
+    }
+
+    return builtIn;
+}
+
 //
 // Initializers show up in several places in the grammar.  Have one set of
 // code to handle them here.
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index b938b7d..289ec2f 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -105,6 +105,7 @@
     bool containsSampler(TType& type);
     bool areAllChildConst(TIntermAggregate* aggrNode);
     const TFunction* findFunction(const TSourceLoc& line, TFunction* pfnCall, bool *builtIn = 0);
+    bool isVariableBuiltIn(const TVariable* pVar);
     bool executeInitializer(const TSourceLoc& line, TString& identifier, TPublicType& pType,
                             TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable = 0);
 
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 92f3931..3f63703 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -127,6 +127,7 @@
     resources->OES_EGL_image_external = 0;
     resources->ARB_texture_rectangle = 0;
     resources->EXT_draw_buffers = 0;
+    resources->EXT_frag_depth = 0;
 
     // Disable highp precision in fragment shader by default.
     resources->FragmentPrecisionHigh = 0;
diff --git a/src/compiler/SymbolTable.cpp b/src/compiler/SymbolTable.cpp
index 1e34f1a..f6b6ab6 100644
--- a/src/compiler/SymbolTable.cpp
+++ b/src/compiler/SymbolTable.cpp
@@ -223,10 +223,8 @@
 void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
 {
     for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
-        if (it->second->isFunction()) {
-            TFunction* function = static_cast<TFunction*>(it->second);
-            if (function->getName() == name)
-                function->relateToExtension(ext);
-        }
+        TSymbol* symbol = it->second;
+        if (symbol->getName() == name)
+            symbol->relateToExtension(ext);
     }
 }
diff --git a/src/compiler/SymbolTable.h b/src/compiler/SymbolTable.h
index 5006973..f6e1959 100644
--- a/src/compiler/SymbolTable.h
+++ b/src/compiler/SymbolTable.h
@@ -50,13 +50,16 @@
     virtual bool isVariable() const { return false; }
     void setUniqueId(int id) { uniqueId = id; }
     int getUniqueId() const { return uniqueId; }
-    virtual void dump(TInfoSink &infoSink) const = 0;	
+    virtual void dump(TInfoSink &infoSink) const = 0;
+    void relateToExtension(const TString& ext) { extension = ext; }
+    const TString& getExtension() const { return extension; }
 
 private:
     DISALLOW_COPY_AND_ASSIGN(TSymbol);
 
     const TString *name;
     unsigned int uniqueId;      // For real comparing during code generation
+    TString extension;
 };
 
 //
@@ -156,9 +159,6 @@
     void relateToOperator(TOperator o) { op = o; }
     TOperator getBuiltInOp() const { return op; }
 
-    void relateToExtension(const TString& ext) { extension = ext; }
-    const TString& getExtension() const { return extension; }
-
     void setDefined() { defined = true; }
     bool isDefined() { return defined; }
 
@@ -175,7 +175,6 @@
     TType returnType;
     TString mangledName;
     TOperator op;
-    TString extension;
     bool defined;
 };
 
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index f85a745..bcb9aec 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -197,7 +197,14 @@
                 context->error(@1, "variable expected", $1.string->c_str());
                 context->recover();
             }
+            
             variable = static_cast<const TVariable*>(symbol);
+
+            if (context->isVariableBuiltIn(variable) && 
+                !variable->getExtension().empty() &&
+                context->extensionErrorCheck(@1, variable->getExtension())) {
+                context->recover();
+            }
         }
 
         // don't delete $1.string, it's used by error recovery, and the pool
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index cd401a9..71ccf94 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -713,27 +713,27 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   179,   179,   180,   183,   219,   222,   235,   240,   245,
-     251,   254,   329,   332,   433,   443,   456,   464,   564,   567,
-     575,   578,   584,   588,   595,   601,   610,   618,   673,   683,
-     686,   696,   706,   727,   728,   729,   734,   735,   743,   754,
-     755,   763,   774,   778,   779,   789,   799,   809,   822,   823,
-     833,   846,   850,   854,   858,   859,   872,   873,   886,   887,
-     900,   901,   918,   919,   932,   933,   934,   935,   936,   940,
-     943,   954,   962,   989,   994,  1008,  1045,  1048,  1055,  1063,
-    1084,  1105,  1115,  1143,  1148,  1158,  1163,  1173,  1176,  1179,
-    1182,  1188,  1195,  1198,  1220,  1238,  1262,  1285,  1289,  1307,
-    1315,  1347,  1367,  1388,  1397,  1420,  1423,  1429,  1437,  1445,
-    1453,  1463,  1470,  1473,  1476,  1482,  1485,  1500,  1504,  1508,
-    1512,  1516,  1521,  1526,  1531,  1536,  1541,  1546,  1551,  1556,
-    1561,  1566,  1571,  1576,  1580,  1584,  1592,  1600,  1604,  1617,
-    1617,  1631,  1631,  1640,  1643,  1659,  1695,  1699,  1705,  1712,
-    1727,  1731,  1735,  1736,  1742,  1743,  1744,  1745,  1746,  1750,
-    1751,  1751,  1751,  1761,  1762,  1766,  1766,  1767,  1767,  1772,
-    1775,  1785,  1788,  1794,  1795,  1799,  1807,  1811,  1821,  1826,
-    1843,  1843,  1848,  1848,  1855,  1855,  1863,  1866,  1872,  1875,
-    1881,  1885,  1892,  1899,  1906,  1913,  1924,  1933,  1937,  1944,
-    1947,  1953,  1953
+       0,   179,   179,   180,   183,   226,   229,   242,   247,   252,
+     258,   261,   336,   339,   440,   450,   463,   471,   571,   574,
+     582,   585,   591,   595,   602,   608,   617,   625,   680,   690,
+     693,   703,   713,   734,   735,   736,   741,   742,   750,   761,
+     762,   770,   781,   785,   786,   796,   806,   816,   829,   830,
+     840,   853,   857,   861,   865,   866,   879,   880,   893,   894,
+     907,   908,   925,   926,   939,   940,   941,   942,   943,   947,
+     950,   961,   969,   996,  1001,  1015,  1052,  1055,  1062,  1070,
+    1091,  1112,  1122,  1150,  1155,  1165,  1170,  1180,  1183,  1186,
+    1189,  1195,  1202,  1205,  1227,  1245,  1269,  1292,  1296,  1314,
+    1322,  1354,  1374,  1395,  1404,  1427,  1430,  1436,  1444,  1452,
+    1460,  1470,  1477,  1480,  1483,  1489,  1492,  1507,  1511,  1515,
+    1519,  1523,  1528,  1533,  1538,  1543,  1548,  1553,  1558,  1563,
+    1568,  1573,  1578,  1583,  1587,  1591,  1599,  1607,  1611,  1624,
+    1624,  1638,  1638,  1647,  1650,  1666,  1702,  1706,  1712,  1719,
+    1734,  1738,  1742,  1743,  1749,  1750,  1751,  1752,  1753,  1757,
+    1758,  1758,  1758,  1768,  1769,  1773,  1773,  1774,  1774,  1779,
+    1782,  1792,  1795,  1801,  1802,  1806,  1814,  1818,  1828,  1833,
+    1850,  1850,  1855,  1855,  1862,  1862,  1870,  1873,  1879,  1882,
+    1888,  1892,  1899,  1906,  1913,  1920,  1931,  1940,  1944,  1951,
+    1954,  1960,  1960
 };
 #endif
 
@@ -2262,7 +2262,14 @@
                 context->error((yylsp[(1) - (1)]), "variable expected", (yyvsp[(1) - (1)].lex).string->c_str());
                 context->recover();
             }
+            
             variable = static_cast<const TVariable*>(symbol);
+
+            if (context->isVariableBuiltIn(variable) && 
+                !variable->getExtension().empty() &&
+                context->extensionErrorCheck((yylsp[(1) - (1)]), variable->getExtension())) {
+                context->recover();
+            }
         }
 
         // don't delete $1.string, it's used by error recovery, and the pool
diff --git a/src/libGLESv2/Context.cpp b/src/libGLESv2/Context.cpp
index 90ba253..91a5ec5 100644
--- a/src/libGLESv2/Context.cpp
+++ b/src/libGLESv2/Context.cpp
@@ -2582,6 +2582,7 @@
     }
 
     extensionString += "GL_EXT_texture_storage ";
+    extensionString += "GL_EXT_frag_depth ";
 
     // ANGLE-specific extensions
     if (supportsDepthTextures())
diff --git a/src/libGLESv2/ProgramBinary.cpp b/src/libGLESv2/ProgramBinary.cpp
index 27722f1..82aca7a 100644
--- a/src/libGLESv2/ProgramBinary.cpp
+++ b/src/libGLESv2/ProgramBinary.cpp
@@ -1225,6 +1225,7 @@
     std::string varyingSemantic = (mUsesPointSize && shaderModel == 3) ? "COLOR" : "TEXCOORD";
     std::string targetSemantic = (shaderModel >= 4) ? "SV_Target" : "COLOR";
     std::string positionSemantic = (shaderModel >= 4) ? "SV_Position" : "POSITION";
+    std::string depthSemantic = (shaderModel >= 4) ? "SV_Depth" : "DEPTH";
 
     // special varyings that use reserved registers
     int reservedRegisterIndex = registers;
@@ -1479,6 +1480,11 @@
         pixelHLSL += "    float4 gl_Color" + str(renderTargetIndex) + " : " + targetSemantic + str(renderTargetIndex) + ";\n";
     }
 
+    if (fragmentShader->mUsesFragDepth)
+    {
+        pixelHLSL += "    float gl_Depth : " + depthSemantic + ";\n";
+    }
+
     pixelHLSL += "};\n"
                  "\n";
 
@@ -1592,6 +1598,11 @@
         pixelHLSL += "    output.gl_Color" + str(renderTargetIndex) + " = gl_Color[" + str(sourceColorIndex) + "];\n";
     }
 
+    if (fragmentShader->mUsesFragDepth)
+    {
+        pixelHLSL += "    output.gl_Depth = gl_Depth;\n";
+    }
+
     pixelHLSL += "\n"
                  "    return output;\n"
                  "}\n";
diff --git a/src/libGLESv2/Shader.cpp b/src/libGLESv2/Shader.cpp
index 437982d..7dfdd0b 100644
--- a/src/libGLESv2/Shader.cpp
+++ b/src/libGLESv2/Shader.cpp
@@ -247,6 +247,7 @@
             resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
             // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
             resources.FragmentPrecisionHigh = 1;   // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
+            resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
 
             mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
             mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
@@ -305,6 +306,7 @@
         mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
         mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
         mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
+        mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
     }
 }
 
@@ -337,6 +339,7 @@
     mUsesPointSize = false;
     mUsesPointCoord = false;
     mUsesDepthRange = false;
+    mUsesFragDepth = false;
 
     mActiveUniforms.clear();
 }
diff --git a/src/libGLESv2/Shader.h b/src/libGLESv2/Shader.h
index d622ba7..2afe297 100644
--- a/src/libGLESv2/Shader.h
+++ b/src/libGLESv2/Shader.h
@@ -106,6 +106,7 @@
     bool mUsesPointSize;
     bool mUsesPointCoord;
     bool mUsesDepthRange;
+    bool mUsesFragDepth;
 
     static void *mFragmentCompiler;
     static void *mVertexCompiler;