Implement gl_FragDepth for GLES SL 3.0
Makes it an error to access gl_FragDepthEXT in #version 300 es shader.
TODO:
Lacks the feature to make "#extension GL_EXT_frag_depth : require" an
error for #version 300 es.
Reland of: https://chromium-review.googlesource.com/#/c/287570
BUG=angleproject:1102
TEST=angle_unittest
Change-Id: I064d918d65f37539cb1e14f12173ca5591a4ea3f
Reviewed-on: https://chromium-review.googlesource.com/301711
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/BaseTypes.h b/src/compiler/translator/BaseTypes.h
index 2adb1d3..0ed6d0e 100644
--- a/src/compiler/translator/BaseTypes.h
+++ b/src/compiler/translator/BaseTypes.h
@@ -324,7 +324,10 @@
// built-ins written by fragment shader
EvqFragColor,
EvqFragData,
- EvqFragDepth,
+
+ EvqFragDepth, // gl_FragDepth for ESSL300.
+ EvqFragDepthEXT, // gl_FragDepthEXT for ESSL100, EXT_frag_depth.
+
EvqSecondaryFragColorEXT, // EXT_blend_func_extended
EvqSecondaryFragDataEXT, // EXT_blend_func_extended
@@ -389,48 +392,47 @@
//
inline const char* getQualifierString(TQualifier q)
{
+ // clang-format off
switch(q)
{
- case EvqTemporary: return "Temporary"; break;
- case EvqGlobal: return "Global"; break;
- case EvqConst: return "const"; break;
- case EvqAttribute: return "attribute"; break;
- case EvqVaryingIn: return "varying"; break;
- case EvqVaryingOut: return "varying"; break;
- case EvqUniform: return "uniform"; break;
- case EvqVertexIn: return "in"; break;
- case EvqFragmentOut: return "out"; break;
- case EvqVertexOut: return "out"; break;
- case EvqFragmentIn: return "in"; break;
- case EvqIn: return "in"; break;
- case EvqOut: return "out"; break;
- case EvqInOut: return "inout"; break;
- case EvqConstReadOnly: return "const"; break;
- case EvqInstanceID: return "InstanceID"; break;
- case EvqPosition: return "Position"; break;
- case EvqPointSize: return "PointSize"; break;
- case EvqFragCoord: return "FragCoord"; break;
- case EvqFrontFacing: return "FrontFacing"; break;
- case EvqPointCoord: return "PointCoord"; break;
- case EvqFragColor: return "FragColor"; break;
- case EvqFragData: return "FragData"; break;
- case EvqFragDepth: return "FragDepth"; break;
- case EvqSecondaryFragColorEXT:
- return "SecondaryFragColorEXT";
- break;
- case EvqSecondaryFragDataEXT:
- return "SecondaryFragDataEXT";
- break;
- case EvqLastFragColor: return "LastFragColor"; break;
- case EvqLastFragData: return "LastFragData"; break;
- case EvqSmoothOut: return "smooth out"; break;
- case EvqCentroidOut: return "centroid out"; break;
- case EvqFlatOut: return "flat out"; break;
- case EvqSmoothIn: return "smooth in"; break;
- case EvqFlatIn: return "flat in"; break;
- case EvqCentroidIn: return "centroid in"; break;
- default: UNREACHABLE(); return "unknown qualifier";
+ case EvqTemporary: return "Temporary";
+ case EvqGlobal: return "Global";
+ case EvqConst: return "const";
+ case EvqAttribute: return "attribute";
+ case EvqVaryingIn: return "varying";
+ case EvqVaryingOut: return "varying";
+ case EvqUniform: return "uniform";
+ case EvqVertexIn: return "in";
+ case EvqFragmentOut: return "out";
+ case EvqVertexOut: return "out";
+ case EvqFragmentIn: return "in";
+ case EvqIn: return "in";
+ case EvqOut: return "out";
+ case EvqInOut: return "inout";
+ case EvqConstReadOnly: return "const";
+ case EvqInstanceID: return "InstanceID";
+ case EvqPosition: return "Position";
+ case EvqPointSize: return "PointSize";
+ case EvqFragCoord: return "FragCoord";
+ case EvqFrontFacing: return "FrontFacing";
+ case EvqPointCoord: return "PointCoord";
+ case EvqFragColor: return "FragColor";
+ case EvqFragData: return "FragData";
+ case EvqFragDepthEXT: return "FragDepth";
+ case EvqFragDepth: return "FragDepth";
+ case EvqSecondaryFragColorEXT: return "SecondaryFragColorEXT";
+ case EvqSecondaryFragDataEXT: return "SecondaryFragDataEXT";
+ case EvqLastFragColor: return "LastFragColor";
+ case EvqLastFragData: return "LastFragData";
+ case EvqSmoothOut: return "smooth out";
+ case EvqCentroidOut: return "centroid out";
+ case EvqFlatOut: return "flat out";
+ case EvqSmoothIn: return "smooth in";
+ case EvqFlatIn: return "flat in";
+ case EvqCentroidIn: return "centroid in";
+ default: UNREACHABLE(); return "unknown qualifier";
}
+ // clang-format on
}
inline const char* getMatrixPackingString(TLayoutMatrixPacking mpq)
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index a5e51dc..2f51aad 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -523,10 +523,18 @@
if (resources.EXT_frag_depth)
{
- symbolTable.insert(ESSL1_BUILTINS, "GL_EXT_frag_depth", new TVariable(NewPoolTString("gl_FragDepthEXT"),
- TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium, EvqFragDepth, 1)));
+ symbolTable.insert(
+ ESSL1_BUILTINS, "GL_EXT_frag_depth",
+ new TVariable(
+ NewPoolTString("gl_FragDepthEXT"),
+ TType(EbtFloat, resources.FragmentPrecisionHigh ? EbpHigh : EbpMedium,
+ EvqFragDepthEXT, 1)));
}
+ symbolTable.insert(ESSL3_BUILTINS,
+ new TVariable(NewPoolTString("gl_FragDepth"),
+ TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+
if (resources.EXT_shader_framebuffer_fetch || resources.NV_shader_framebuffer_fetch)
{
TType lastFragData(EbtFloat, EbpMedium, EvqLastFragData, 4, 1, true);
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index d6b9a55..117c34a 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1386,7 +1386,7 @@
mUsesInstanceID = true;
out << name;
}
- else if (name == "gl_FragDepthEXT")
+ else if (name == "gl_FragDepthEXT" || name == "gl_FragDepth")
{
mUsesFragDepth = true;
out << "gl_Depth";
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index 07a9dcd..7413dc3 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -151,6 +151,7 @@
mLastFragDataAdded(false),
mFragColorAdded(false),
mFragDataAdded(false),
+ mFragDepthEXTAdded(false),
mFragDepthAdded(false),
mSecondaryFragColorEXTAdded(false),
mSecondaryFragDataEXTAdded(false),
@@ -405,8 +406,8 @@
mFragDataAdded = true;
}
return;
- case EvqFragDepth:
- if (!mFragDepthAdded)
+ case EvqFragDepthEXT:
+ if (!mFragDepthEXTAdded)
{
OutputVariable info;
const char kName[] = "gl_FragDepthEXT";
@@ -420,6 +421,21 @@
->getType());
info.staticUse = true;
mOutputVariables->push_back(info);
+ mFragDepthEXTAdded = true;
+ }
+ return;
+ case EvqFragDepth:
+ if (!mFragDepthAdded)
+ {
+ OutputVariable info;
+ const char kName[] = "gl_FragDepth";
+ info.name = kName;
+ info.mappedName = kName;
+ info.type = GL_FLOAT;
+ info.arraySize = 0;
+ info.precision = GL_HIGH_FLOAT;
+ info.staticUse = true;
+ mOutputVariables->push_back(info);
mFragDepthAdded = true;
}
return;
diff --git a/src/compiler/translator/VariableInfo.h b/src/compiler/translator/VariableInfo.h
index 7fbcec4..9498e9b 100644
--- a/src/compiler/translator/VariableInfo.h
+++ b/src/compiler/translator/VariableInfo.h
@@ -58,6 +58,7 @@
bool mLastFragDataAdded;
bool mFragColorAdded;
bool mFragDataAdded;
+ bool mFragDepthEXTAdded;
bool mFragDepthAdded;
bool mSecondaryFragColorEXTAdded;
bool mSecondaryFragDataEXTAdded;