Constant fold compute shader local work group size
gl_WorkGroupSize should be written into the AST as a constant node
instead of a symbol node. In correct shaders, local size is guaranteed
to have been declared before any references to gl_WorkGroupSize -
otherwise the shader translator was already generating an error.
This ensures that work group size can be used to size arrays as
specified and also works around a crash issue on NVIDIA Linux OpenGL
driver.
BUG=angleproject:1442
TEST=angle_unittests
Change-Id: I9b1a4bff16ecf2c3db1511c3702756346cdd2f6b
Reviewed-on: https://chromium-review.googlesource.com/418735
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index 3066df4..8807eee 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1471,6 +1471,25 @@
const TConstantUnion *constArray = variable->getConstPointer();
return intermediate.addConstantUnion(constArray, variable->getType(), location);
}
+ else if (variable->getType().getQualifier() == EvqWorkGroupSize &&
+ mComputeShaderLocalSizeDeclared)
+ {
+ // gl_WorkGroupSize can be used to size arrays according to the ESSL 3.10.4 spec, so it
+ // needs to be added to the AST as a constant and not as a symbol.
+ sh::WorkGroupSize workGroupSize = getComputeShaderLocalSize();
+ TConstantUnion *constArray = new TConstantUnion[3];
+ for (size_t i = 0; i < 3; ++i)
+ {
+ constArray[i].setUConst(static_cast<unsigned int>(workGroupSize[i]));
+ }
+
+ ASSERT(variable->getType().getBasicType() == EbtUInt);
+ ASSERT(variable->getType().getObjectSize() == 3);
+
+ TType type(variable->getType());
+ type.setQualifier(EvqConst);
+ return intermediate.addConstantUnion(constArray, type, location);
+ }
else
{
return intermediate.addSymbol(variable->getUniqueId(), variable->getName(),