translator: Reject shaders that use both FragColor+FragData.
*re-land with fix for unused var in release*
We checked this at link time in the D3D back-end, but this
restriction applies to all shaders.
TEST=dEQP-GLES2.functional.shaders.fragdata.*
BUG=angleproject:995
BUG=478572
Change-Id: I63258f4de47e658812822f31601cc235f48c0826
Reviewed-on: https://chromium-review.googlesource.com/271470
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 784032d..a9e9516 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1049,6 +1049,27 @@
{
recover();
}
+
+ // Reject shaders using both gl_FragData and gl_FragColor
+ TQualifier qualifier = variable->getType().getQualifier();
+ if (qualifier == EvqFragData)
+ {
+ mUsesFragData = true;
+ }
+ else if (qualifier == EvqFragColor)
+ {
+ mUsesFragColor = true;
+ }
+
+ // This validation is not quite correct - it's only an error to write to
+ // both FragData and FragColor. For simplicity, and because users shouldn't
+ // be rewarded for reading from undefined varaibles, return an error
+ // if they are both referenced, rather than assigned.
+ if (mUsesFragData && mUsesFragColor)
+ {
+ error(location, "cannot use both gl_FragData and gl_FragColor", name->c_str());
+ recover();
+ }
}
if (!variable)
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index bdf290c..d7885d8 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -56,7 +56,9 @@
mDirectiveHandler(ext, mDiagnostics, mShaderVersion, debugShaderPrecisionSupported),
mPreprocessor(&mDiagnostics, &mDirectiveHandler),
mScanner(nullptr),
- mDeferredSingleDeclarationErrorCheck(false)
+ mDeferredSingleDeclarationErrorCheck(false),
+ mUsesFragData(false),
+ mUsesFragColor(false)
{
}
@@ -73,6 +75,7 @@
const char *extraInfo="");
void warning(const TSourceLoc &loc, const char *reason, const char *token,
const char *extraInfo="");
+
void recover();
TIntermNode *getTreeRoot() const { return mTreeRoot; }
void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
@@ -339,6 +342,8 @@
TDirectiveHandler mDirectiveHandler;
pp::Preprocessor mPreprocessor;
void *mScanner;
+ bool mUsesFragData; // track if we are using both gl_FragData and gl_FragColor
+ bool mUsesFragColor;
};
int PaParseStrings(