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;