Make all fragment shader out variables require location layout qualifier
Make all fragment shader out variables require location layout
qualifier. Previously, the last variable did not need a location layout
qualifier if the previous variables had those.
TEST=angle_unittests
BUG=angleproject:1070
Change-Id: I3763b8ca38b1e14ee8456a54592c01e0fd89692c
Reviewed-on: https://chromium-review.googlesource.com/286101
Tested-by: Kimmo Kinnunen <kkinnunen@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/ValidateOutputs.cpp b/src/compiler/translator/ValidateOutputs.cpp
index 614d790..daa903a 100644
--- a/src/compiler/translator/ValidateOutputs.cpp
+++ b/src/compiler/translator/ValidateOutputs.cpp
@@ -14,7 +14,7 @@
mSink(sink),
mMaxDrawBuffers(maxDrawBuffers),
mNumErrors(0),
- mHasUnspecifiedOutputLocation(false)
+ mUnspecifiedOutputLocationCount(0)
{
}
@@ -32,14 +32,15 @@
{
const TType &type = symbol->getType();
const int location = type.getLayoutQualifier().location;
+ const bool isUnspecifiedOutputLocation = location == -1;
- if (mHasUnspecifiedOutputLocation)
+ if (mUnspecifiedOutputLocationCount > 0 || (isUnspecifiedOutputLocation && !mOutputMap.empty()))
{
error(symbol->getLine(), "must explicitly specify all locations when using multiple fragment outputs", name.c_str());
}
- else if (location == -1)
+ else if (isUnspecifiedOutputLocation)
{
- mHasUnspecifiedOutputLocation = true;
+ ++mUnspecifiedOutputLocationCount;
}
else
{
diff --git a/src/compiler/translator/ValidateOutputs.h b/src/compiler/translator/ValidateOutputs.h
index 1538e0f..9d75a4a 100644
--- a/src/compiler/translator/ValidateOutputs.h
+++ b/src/compiler/translator/ValidateOutputs.h
@@ -26,7 +26,7 @@
TInfoSinkBase& mSink;
int mMaxDrawBuffers;
int mNumErrors;
- bool mHasUnspecifiedOutputLocation;
+ bool mUnspecifiedOutputLocationCount;
typedef std::map<int, TIntermSymbol*> OutputMap;
OutputMap mOutputMap;
diff --git a/src/tests/compiler_tests/MalformedShader_test.cpp b/src/tests/compiler_tests/MalformedShader_test.cpp
index 9a9a46d..cee1335 100644
--- a/src/tests/compiler_tests/MalformedShader_test.cpp
+++ b/src/tests/compiler_tests/MalformedShader_test.cpp
@@ -689,6 +689,64 @@
}
}
+// If there is more than one output, the location must be specified for all outputs.
+// (ESSL 3.00.04 section 4.3.8.2)
+TEST_F(MalformedShaderTest, TwoOutputsNoLayoutQualifiers)
+{
+ const std::string &shaderString =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "uniform vec4 u;\n"
+ "out vec4 my_FragColor;\n"
+ "out vec4 my_SecondaryFragColor;\n"
+ "void main() {\n"
+ " my_FragColor = vec4(1.0);\n"
+ " my_SecondaryFragColor = vec4(0.5);\n"
+ "}\n";
+ if (compile(shaderString))
+ {
+ FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
+ }
+}
+
+// (ESSL 3.00.04 section 4.3.8.2)
+TEST_F(MalformedShaderTest, TwoOutputsFirstLayoutQualifier)
+{
+ const std::string &shaderString =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "uniform vec4 u;\n"
+ "layout(location = 0) out vec4 my_FragColor;\n"
+ "out vec4 my_SecondaryFragColor;\n"
+ "void main() {\n"
+ " my_FragColor = vec4(1.0);\n"
+ " my_SecondaryFragColor = vec4(0.5);\n"
+ "}\n";
+ if (compile(shaderString))
+ {
+ FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
+ }
+}
+
+// (ESSL 3.00.04 section 4.3.8.2)
+TEST_F(MalformedShaderTest, TwoOutputsSecondLayoutQualifier)
+{
+ const std::string &shaderString =
+ "#version 300 es\n"
+ "precision mediump float;\n"
+ "uniform vec4 u;\n"
+ "out vec4 my_FragColor;\n"
+ "layout(location = 0) out vec4 my_SecondaryFragColor;\n"
+ "void main() {\n"
+ " my_FragColor = vec4(1.0);\n"
+ " my_SecondaryFragColor = vec4(0.5);\n"
+ "}\n";
+ if (compile(shaderString))
+ {
+ FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
+ }
+}
+
// Uniforms can be arrays (ESSL 3.00 section 4.3.5)
TEST_F(MalformedShaderTest, UniformArray)
{