Commit 140941d0 by Kimmo Kinnunen Committed by Jamie Madill

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/286101Tested-by: 's avatarKimmo Kinnunen <kkinnunen@nvidia.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 2fdd3da9
...@@ -14,7 +14,7 @@ ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers) ...@@ -14,7 +14,7 @@ ValidateOutputs::ValidateOutputs(TInfoSinkBase& sink, int maxDrawBuffers)
mSink(sink), mSink(sink),
mMaxDrawBuffers(maxDrawBuffers), mMaxDrawBuffers(maxDrawBuffers),
mNumErrors(0), mNumErrors(0),
mHasUnspecifiedOutputLocation(false) mUnspecifiedOutputLocationCount(0)
{ {
} }
...@@ -32,14 +32,15 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol) ...@@ -32,14 +32,15 @@ void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
{ {
const TType &type = symbol->getType(); const TType &type = symbol->getType();
const int location = type.getLayoutQualifier().location; 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()); 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 else
{ {
......
...@@ -26,7 +26,7 @@ class ValidateOutputs : public TIntermTraverser ...@@ -26,7 +26,7 @@ class ValidateOutputs : public TIntermTraverser
TInfoSinkBase& mSink; TInfoSinkBase& mSink;
int mMaxDrawBuffers; int mMaxDrawBuffers;
int mNumErrors; int mNumErrors;
bool mHasUnspecifiedOutputLocation; bool mUnspecifiedOutputLocationCount;
typedef std::map<int, TIntermSymbol*> OutputMap; typedef std::map<int, TIntermSymbol*> OutputMap;
OutputMap mOutputMap; OutputMap mOutputMap;
......
...@@ -689,6 +689,64 @@ TEST_F(MalformedShaderTest, LayoutQualifierInFunctionReturnType) ...@@ -689,6 +689,64 @@ TEST_F(MalformedShaderTest, LayoutQualifierInFunctionReturnType)
} }
} }
// 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) // Uniforms can be arrays (ESSL 3.00 section 4.3.5)
TEST_F(MalformedShaderTest, UniformArray) TEST_F(MalformedShaderTest, UniformArray)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment