Commit 1c28e1f0 by Jamie Madill

Fix shaders with invariant keyword.

We would trigger assertion failures in Debug mode, and fail to parse and translate correctly in Release. BUG=angle:711 Change-Id: Ibb7f33b288376617598578f48c7bbdbdec044279 Reviewed-on: https://chromium-review.googlesource.com/210822Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarNicolas Capens <capn@chromium.org>
parent f4e39bfd
...@@ -72,37 +72,7 @@ enum TBasicType ...@@ -72,37 +72,7 @@ enum TBasicType
EbtInvariant // used as a type when qualifying a previously declared variable as being invariant EbtInvariant // used as a type when qualifying a previously declared variable as being invariant
}; };
inline const char* getBasicString(TBasicType t) const char* getBasicString(TBasicType t);
{
switch (t)
{
case EbtVoid: return "void"; break;
case EbtFloat: return "float"; break;
case EbtInt: return "int"; break;
case EbtUInt: return "uint"; break;
case EbtBool: return "bool"; break;
case EbtSampler2D: return "sampler2D"; break;
case EbtSampler3D: return "sampler3D"; break;
case EbtSamplerCube: return "samplerCube"; break;
case EbtSamplerExternalOES: return "samplerExternalOES"; break;
case EbtSampler2DRect: return "sampler2DRect"; break;
case EbtSampler2DArray: return "sampler2DArray"; break;
case EbtISampler2D: return "isampler2D"; break;
case EbtISampler3D: return "isampler3D"; break;
case EbtISamplerCube: return "isamplerCube"; break;
case EbtISampler2DArray: return "isampler2DArray"; break;
case EbtUSampler2D: return "usampler2D"; break;
case EbtUSampler3D: return "usampler3D"; break;
case EbtUSamplerCube: return "usamplerCube"; break;
case EbtUSampler2DArray: return "usampler2DArray"; break;
case EbtSampler2DShadow: return "sampler2DShadow"; break;
case EbtSamplerCubeShadow: return "samplerCubeShadow"; break;
case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
case EbtStruct: return "structure"; break;
case EbtInterfaceBlock: return "interface block"; break;
default: return "unknown type";
}
}
inline bool IsSampler(TBasicType type) inline bool IsSampler(TBasicType type)
{ {
......
...@@ -81,9 +81,11 @@ void TOutputGLSLBase::writeVariableType(const TType &type) ...@@ -81,9 +81,11 @@ void TOutputGLSLBase::writeVariableType(const TType &type)
{ {
TInfoSinkBase &out = objSink(); TInfoSinkBase &out = objSink();
TQualifier qualifier = type.getQualifier(); TQualifier qualifier = type.getQualifier();
// TODO(alokp): Validate qualifier for variable declarations. if (qualifier != EvqTemporary && qualifier != EvqGlobal &&
if (qualifier != EvqTemporary && qualifier != EvqGlobal) type.getBasicType() != EbtInvariant)
{
out << type.getQualifierString() << " "; out << type.getQualifierString() << " ";
}
// Declare the struct if we have not done so already. // Declare the struct if we have not done so already.
if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct())) if (type.getBasicType() == EbtStruct && !structDeclared(type.getStruct()))
{ {
......
...@@ -1937,6 +1937,12 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node) ...@@ -1937,6 +1937,12 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
} }
else if (variable && IsVaryingOut(variable->getQualifier())) else if (variable && IsVaryingOut(variable->getQualifier()))
{ {
// Skip translation of invariant declarations
if (variable->getBasicType() == EbtInvariant)
{
return false;
}
for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++) for (TIntermSequence::iterator sit = sequence->begin(); sit != sequence->end(); sit++)
{ {
TIntermSymbol *symbol = (*sit)->getAsSymbolNode(); TIntermSymbol *symbol = (*sit)->getAsSymbolNode();
......
...@@ -13,6 +13,39 @@ ...@@ -13,6 +13,39 @@
#include <algorithm> #include <algorithm>
#include <climits> #include <climits>
const char* getBasicString(TBasicType t)
{
switch (t)
{
case EbtVoid: return "void"; break;
case EbtFloat: return "float"; break;
case EbtInt: return "int"; break;
case EbtUInt: return "uint"; break;
case EbtBool: return "bool"; break;
case EbtSampler2D: return "sampler2D"; break;
case EbtSampler3D: return "sampler3D"; break;
case EbtSamplerCube: return "samplerCube"; break;
case EbtSamplerExternalOES: return "samplerExternalOES"; break;
case EbtSampler2DRect: return "sampler2DRect"; break;
case EbtSampler2DArray: return "sampler2DArray"; break;
case EbtISampler2D: return "isampler2D"; break;
case EbtISampler3D: return "isampler3D"; break;
case EbtISamplerCube: return "isamplerCube"; break;
case EbtISampler2DArray: return "isampler2DArray"; break;
case EbtUSampler2D: return "usampler2D"; break;
case EbtUSampler3D: return "usampler3D"; break;
case EbtUSamplerCube: return "usamplerCube"; break;
case EbtUSampler2DArray: return "usampler2DArray"; break;
case EbtSampler2DShadow: return "sampler2DShadow"; break;
case EbtSamplerCubeShadow: return "samplerCubeShadow"; break;
case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break;
case EbtStruct: return "structure"; break;
case EbtInterfaceBlock: return "interface block"; break;
case EbtInvariant: return "invariant"; break;
default: UNREACHABLE(); return "unknown type";
}
}
TType::TType(const TPublicType &p) TType::TType(const TPublicType &p)
: type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier), : type(p.type), precision(p.precision), qualifier(p.qualifier), layoutQualifier(p.layoutQualifier),
primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize),
......
...@@ -320,6 +320,8 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -320,6 +320,8 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
case EOpDeclaration: case EOpDeclaration:
{ {
const TIntermSequence &sequence = *(node->getSequence()); const TIntermSequence &sequence = *(node->getSequence());
ASSERT(!sequence.empty());
const TIntermTyped &typedNode = *(sequence.front()->getAsTyped()); const TIntermTyped &typedNode = *(sequence.front()->getAsTyped());
TQualifier qualifier = typedNode.getQualifier(); TQualifier qualifier = typedNode.getQualifier();
...@@ -344,14 +346,16 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node) ...@@ -344,14 +346,16 @@ bool CollectVariables::visitAggregate(Visit, TIntermAggregate *node)
visitInfoList(sequence, mUniforms); visitInfoList(sequence, mUniforms);
break; break;
default: default:
visitInfoList(sequence, mVaryings); // do not traverse invariant declarations such as
// "invariant gl_Position;"
if (typedNode.getBasicType() != EbtInvariant)
{
visitInfoList(sequence, mVaryings);
}
break; break;
} }
if (!sequence.empty()) visitChildren = false;
{
visitChildren = false;
}
} }
break; break;
} }
......
...@@ -268,6 +268,8 @@ InterpolationType GetInterpolationType(TQualifier qualifier) ...@@ -268,6 +268,8 @@ InterpolationType GetInterpolationType(TQualifier qualifier)
case EvqFragmentIn: case EvqFragmentIn:
case EvqVaryingIn: case EvqVaryingIn:
case EvqVaryingOut: case EvqVaryingOut:
case EvqInvariantVaryingIn:
case EvqInvariantVaryingOut:
return INTERPOLATION_SMOOTH; return INTERPOLATION_SMOOTH;
case EvqCentroidIn: case EvqCentroidIn:
......
...@@ -205,3 +205,103 @@ TEST_F(GLSLTest, TwoElseIfRewriting) ...@@ -205,3 +205,103 @@ TEST_F(GLSLTest, TwoElseIfRewriting)
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource); GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program); EXPECT_NE(0u, program);
} }
TEST_F(GLSLTest, InvariantVaryingOut)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
varying float v_varying;
void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
);
const std::string vertexShaderSource = SHADER_SOURCE
(
attribute vec4 a_position;
invariant varying float v_varying;
void main() { v_varying = a_position.x; gl_Position = a_position; }
);
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLTest, InvariantVaryingIn)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
invariant varying float v_varying;
void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
);
const std::string vertexShaderSource = SHADER_SOURCE
(
attribute vec4 a_position;
varying float v_varying;
void main() { v_varying = a_position.x; gl_Position = a_position; }
);
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLTest, InvariantVaryingBoth)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
invariant varying float v_varying;
void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
);
const std::string vertexShaderSource = SHADER_SOURCE
(
attribute vec4 a_position;
invariant varying float v_varying;
void main() { v_varying = a_position.x; gl_Position = a_position; }
);
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLTest, InvariantGLPosition)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
varying float v_varying;
void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
);
const std::string vertexShaderSource = SHADER_SOURCE
(
attribute vec4 a_position;
invariant gl_Position;
varying float v_varying;
void main() { v_varying = a_position.x; gl_Position = a_position; }
);
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
TEST_F(GLSLTest, InvariantAll)
{
const std::string fragmentShaderSource = SHADER_SOURCE
(
precision mediump float;
varying float v_varying;
void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
);
const std::string vertexShaderSource =
"#pragma STDGL invariant(all)\n"
"attribute vec4 a_position;\n"
"varying float v_varying;\n"
"void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
GLuint program = compileProgram(vertexShaderSource, fragmentShaderSource);
EXPECT_NE(0u, program);
}
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