Flatten "#pragma STDGL invariant(all)" into varying variables.
This is implemented as a compiler option which is enabled by default
when outputting to desktop GLSL version 130 and greater, which does
not support this #pragma in fragment shaders. As a workaround, and for
better compatibility on desktop OpenGL drivers, this pragma is also
flattened into the outputs of vertex shaders, and the inputs of ESSL
1.00 fragment shaders.
TEST=conformance/glsl/misc/shaders-with-invariance.html with --enable-unsafe-es3-apis
BUG=629622, angleproject:1293
Change-Id: Ib040230915e639971505ed496d26e804c9d64e68
Reviewed-on: https://chromium-review.googlesource.com/361792
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@chromium.org>
Commit-Queue: Kenneth Russell <kbr@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 55e74a1..06dc6cd 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -140,7 +140,8 @@
}
TCompiler::TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output)
- : shaderType(type),
+ : variablesCollected(false),
+ shaderType(type),
shaderSpec(spec),
outputType(output),
maxUniformVectors(0),
@@ -408,12 +409,20 @@
return NULL;
}
-bool TCompiler::compile(const char* const shaderStrings[],
- size_t numStrings, int compileOptions)
+bool TCompiler::compile(const char *const shaderStrings[], size_t numStrings, int compileOptionsIn)
{
if (numStrings == 0)
return true;
+ int compileOptions = compileOptionsIn;
+
+ // Apply key workarounds.
+ if (shouldFlattenPragmaStdglInvariantAll())
+ {
+ // This should be harmless to do in all cases, but for the moment, do it only conditionally.
+ compileOptions |= SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL;
+ }
+
TScopedPoolAllocator scopedAlloc(&allocator);
TIntermNode *root = compileTreeImpl(shaderStrings, numStrings, compileOptions);
@@ -577,6 +586,7 @@
expandedUniforms.clear();
varyings.clear();
interfaceBlocks.clear();
+ variablesCollected = false;
builtInFunctionEmulator.Cleanup();
@@ -833,12 +843,16 @@
void TCompiler::collectVariables(TIntermNode* root)
{
- sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
- &interfaceBlocks, hashFunction, symbolTable, extensionBehavior);
- root->traverse(&collect);
+ if (!variablesCollected)
+ {
+ sh::CollectVariables collect(&attributes, &outputVariables, &uniforms, &varyings,
+ &interfaceBlocks, hashFunction, symbolTable, extensionBehavior);
+ root->traverse(&collect);
- // This is for enforcePackingRestriction().
- sh::ExpandUniforms(uniforms, &expandedUniforms);
+ // This is for enforcePackingRestriction().
+ sh::ExpandUniforms(uniforms, &expandedUniforms);
+ variablesCollected = true;
+ }
}
bool TCompiler::enforcePackingRestrictions()
@@ -907,9 +921,26 @@
return builtInFunctionEmulator;
}
-void TCompiler::writePragma()
+void TCompiler::writePragma(int compileOptions)
{
- TInfoSinkBase &sink = infoSink.obj;
- if (mPragma.stdgl.invariantAll)
- sink << "#pragma STDGL invariant(all)\n";
+ if (!(compileOptions & SH_FLATTEN_PRAGMA_STDGL_INVARIANT_ALL))
+ {
+ TInfoSinkBase &sink = infoSink.obj;
+ if (mPragma.stdgl.invariantAll)
+ sink << "#pragma STDGL invariant(all)\n";
+ }
+}
+
+bool TCompiler::isVaryingDefined(const char *varyingName)
+{
+ ASSERT(variablesCollected);
+ for (size_t ii = 0; ii < varyings.size(); ++ii)
+ {
+ if (varyings[ii].name == varyingName)
+ {
+ return true;
+ }
+ }
+
+ return false;
}