Commit aecfa8e6 by Olli Etuaho Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent 023c2b19
......@@ -1471,6 +1471,25 @@ TIntermTyped *TParseContext::parseVariableIdentifier(const TSourceLoc &location,
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(),
......
......@@ -3111,3 +3111,22 @@ TEST_F(MalformedFragmentShaderGLES31Test, OverqualifyingImageParameter)
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
}
// Test that work group size can be used to size arrays.
// GLSL ES 3.10.4 section 7.1.3 Compute Shader Special Variables
TEST_F(MalformedComputeShaderTest, WorkGroupSizeAsArraySize)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 5, local_size_y = 3, local_size_z = 1) in;\n"
"void main()\n"
"{\n"
" int[gl_WorkGroupSize.x] a = int[5](0, 0, 0, 0, 0);\n"
" int[gl_WorkGroupSize.y] b = int[3](0, 0, 0);\n"
" int[gl_WorkGroupSize.z] c = int[1](0);\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
}
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