Commit b088360f by Martin Radev Committed by Commit Bot

Add compute shader special variables

Support is added for the compute shader special variables given in OpenGL GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables. Unit tests are added for legal and illegal usage of the special variables. BUG=angleproject:1442 TEST=angle_unittests Change-Id: Idb25811c15c4044c55c611c0e73ef26eb5b3e9d7 Reviewed-on: https://chromium-review.googlesource.com/366661 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 802abe01
...@@ -351,6 +351,12 @@ enum TQualifier ...@@ -351,6 +351,12 @@ enum TQualifier
// GLSL ES 3.1 compute shader special variables // GLSL ES 3.1 compute shader special variables
EvqComputeIn, EvqComputeIn,
EvqNumWorkGroups,
EvqWorkGroupSize,
EvqWorkGroupID,
EvqLocalInvocationID,
EvqGlobalInvocationID,
EvqLocalInvocationIndex,
// end of list // end of list
EvqLast EvqLast
...@@ -496,6 +502,12 @@ inline const char* getQualifierString(TQualifier q) ...@@ -496,6 +502,12 @@ inline const char* getQualifierString(TQualifier q)
case EvqFlatIn: return "flat in"; case EvqFlatIn: return "flat in";
case EvqCentroidIn: return "smooth centroid in"; case EvqCentroidIn: return "smooth centroid in";
case EvqComputeIn: return "in"; case EvqComputeIn: return "in";
case EvqNumWorkGroups: return "NumWorkGroups";
case EvqWorkGroupSize: return "WorkGroupSize";
case EvqWorkGroupID: return "WorkGroupID";
case EvqLocalInvocationID: return "LocalInvocationID";
case EvqGlobalInvocationID: return "GlobalInvocationID";
case EvqLocalInvocationIndex: return "LocalInvocationIndex";
default: UNREACHABLE(); return "unknown qualifier"; default: UNREACHABLE(); return "unknown qualifier";
} }
// clang-format on // clang-format on
......
...@@ -683,8 +683,29 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec, ...@@ -683,8 +683,29 @@ void IdentifyBuiltIns(sh::GLenum type, ShShaderSpec spec,
TType(EbtInt, EbpHigh, EvqVertexID, 1))); TType(EbtInt, EbpHigh, EvqVertexID, 1)));
break; break;
case GL_COMPUTE_SHADER: case GL_COMPUTE_SHADER:
// TODO (mradev): add compute shader built-ins {
break; symbolTable.insert(ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_NumWorkGroups"),
TType(EbtUInt, EbpUndefined, EvqNumWorkGroups, 3)));
symbolTable.insert(ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_WorkGroupSize"),
TType(EbtUInt, EbpUndefined, EvqWorkGroupSize, 3)));
symbolTable.insert(ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_WorkGroupID"),
TType(EbtUInt, EbpUndefined, EvqWorkGroupID, 3)));
symbolTable.insert(ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_LocalInvocationID"),
TType(EbtUInt, EbpUndefined, EvqLocalInvocationID, 3)));
symbolTable.insert(ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_GlobalInvocationID"),
TType(EbtUInt, EbpUndefined, EvqGlobalInvocationID, 3)));
symbolTable.insert(
ESSL3_1_BUILTINS,
new TVariable(NewPoolTString("gl_LocalInvocationIndex"),
TType(EbtUInt, EbpUndefined, EvqLocalInvocationIndex, 1)));
}
break;
default: default:
assert(false && "Language not supported"); assert(false && "Language not supported");
} }
......
...@@ -340,6 +340,24 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn ...@@ -340,6 +340,24 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc &line, const char *op, TIn
case EvqPointCoord: case EvqPointCoord:
message = "can't modify gl_PointCoord"; message = "can't modify gl_PointCoord";
break; break;
case EvqNumWorkGroups:
message = "can't modify gl_NumWorkGroups";
break;
case EvqWorkGroupSize:
message = "can't modify gl_WorkGroupSize";
break;
case EvqWorkGroupID:
message = "can't modify gl_WorkGroupID";
break;
case EvqLocalInvocationID:
message = "can't modify gl_LocalInvocationID";
break;
case EvqGlobalInvocationID:
message = "can't modify gl_GlobalInvocationID";
break;
case EvqLocalInvocationIndex:
message = "can't modify gl_LocalInvocationIndex";
break;
case EvqComputeIn: case EvqComputeIn:
message = "can't modify work group size variable"; message = "can't modify work group size variable";
break; break;
...@@ -1246,6 +1264,15 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, ...@@ -1246,6 +1264,15 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
error(location, errorMessage, name->c_str()); error(location, errorMessage, name->c_str());
recover(); recover();
} }
// GLSL ES 3.1 Revision 4, 7.1.3 Compute Shader Special Variables
if (getShaderType() == GL_COMPUTE_SHADER && !mComputeShaderLocalSizeDeclared &&
qualifier == EvqWorkGroupSize)
{
error(location,
"It is an error to use gl_WorkGroupSize before declaring the local group size",
"gl_WorkGroupSize");
}
} }
if (!variable) if (!variable)
......
...@@ -2243,3 +2243,138 @@ TEST_F(MalformedFragmentShaderGLES31Test, InvalidUseOfLocalSizeX) ...@@ -2243,3 +2243,138 @@ TEST_F(MalformedFragmentShaderGLES31Test, InvalidUseOfLocalSizeX)
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
} }
// It is a compile time error to use the gl_WorkGroupSize constant if
// the local size has not been declared yet.
// GLSL ES 3.10 Revision 4, 7.1.3 Compute Shader Special Variables
TEST_F(MalformedComputeShaderTest, InvalidUsageOfWorkGroupSize)
{
const std::string &shaderString =
"#version 310 es\n"
"void main()\n"
"{\n"
" uvec3 WorkGroupSize = gl_WorkGroupSize;\n"
"}\n"
"layout(local_size_x = 12) in;\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// The test covers the compute shader built-in variables and constants.
TEST_F(MalformedComputeShaderTest, CorrectUsageOfComputeBuiltins)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" uvec3 NumWorkGroups = gl_NumWorkGroups;\n"
" uvec3 WorkGroupSize = gl_WorkGroupSize;\n"
" uvec3 WorkGroupID = gl_WorkGroupID;\n"
" uvec3 GlobalInvocationID = gl_GlobalInvocationID;\n"
" uvec3 LocalInvocationID = gl_LocalInvocationID;\n"
" uint LocalInvocationIndex = gl_LocalInvocationIndex;\n"
"}\n";
if (!compile(shaderString))
{
FAIL() << "Shader compilation failed, expecting success " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableNumWorkGroups)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_NumWorkGroups = uvec3(1); \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableWorkGroupID)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_WorkGroupID = uvec3(1); \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableLocalInvocationID)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_LocalInvocationID = uvec3(1); \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableGlobalInvocationID)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_GlobalInvocationID = uvec3(1); \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableLocalInvocationIndex)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_LocalInvocationIndex = 1; \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// It is illegal to write to a special variable
TEST_F(MalformedComputeShaderTest, SpecialVariableWorkGroupSize)
{
const std::string &shaderString =
"#version 310 es\n"
"layout(local_size_x = 12) in;\n"
"void main()\n"
"{\n"
" gl_WorkGroupSize = uvec3(1); \n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << 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