Add compute program compilation and linking support
Compute shaders can be now compiled and linked to create programs.
Some tests are added to verify successful and unsuccessful compute
shader linking.
The patch also replaces std::array<int, 3> with a custom struct
WorkGroupSize.
BUG=angleproject:1442
TEST=angle_end2end_tests
TEST=angle_unittests
Change-Id: I4ab0ac05755d0167a6d2a798f8d7f1516cf54d84
Reviewed-on: https://chromium-review.googlesource.com/366740
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Olli Etuaho <oetuaho@nvidia.com>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 5a0e1ba..2c2c4e7 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -101,54 +101,69 @@
{
preLink();
- // Set the transform feedback state
- std::vector<const GLchar *> transformFeedbackVaryings;
- for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
+ if (mState.getAttachedComputeShader())
{
- transformFeedbackVaryings.push_back(tfVarying.c_str());
- }
+ const ShaderGL *computeShaderGL = GetImplAs<ShaderGL>(mState.getAttachedComputeShader());
- if (transformFeedbackVaryings.empty())
- {
- if (mFunctions->transformFeedbackVaryings)
- {
- mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
- mState.getTransformFeedbackBufferMode());
- }
+ mFunctions->attachShader(mProgramID, computeShaderGL->getShaderID());
+
+ // Link and verify
+ mFunctions->linkProgram(mProgramID);
+
+ // Detach the shaders
+ mFunctions->detachShader(mProgramID, computeShaderGL->getShaderID());
}
else
{
- ASSERT(mFunctions->transformFeedbackVaryings);
- mFunctions->transformFeedbackVaryings(
- mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()),
- &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
- }
-
- const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mState.getAttachedVertexShader());
- const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader());
-
- // Attach the shaders
- mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
- mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
-
- // Bind attribute locations to match the GL layer.
- for (const sh::Attribute &attribute : mState.getAttributes())
- {
- if (!attribute.staticUse)
+ // Set the transform feedback state
+ std::vector<const GLchar *> transformFeedbackVaryings;
+ for (const auto &tfVarying : mState.getTransformFeedbackVaryingNames())
{
- continue;
+ transformFeedbackVaryings.push_back(tfVarying.c_str());
}
- mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
+ if (transformFeedbackVaryings.empty())
+ {
+ if (mFunctions->transformFeedbackVaryings)
+ {
+ mFunctions->transformFeedbackVaryings(mProgramID, 0, nullptr,
+ mState.getTransformFeedbackBufferMode());
+ }
+ }
+ else
+ {
+ ASSERT(mFunctions->transformFeedbackVaryings);
+ mFunctions->transformFeedbackVaryings(
+ mProgramID, static_cast<GLsizei>(transformFeedbackVaryings.size()),
+ &transformFeedbackVaryings[0], mState.getTransformFeedbackBufferMode());
+ }
+
+ const ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(mState.getAttachedVertexShader());
+ const ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(mState.getAttachedFragmentShader());
+
+ // Attach the shaders
+ mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
+ mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
+
+ // Bind attribute locations to match the GL layer.
+ for (const sh::Attribute &attribute : mState.getAttributes())
+ {
+ if (!attribute.staticUse)
+ {
+ continue;
+ }
+
+ mFunctions->bindAttribLocation(mProgramID, attribute.location, attribute.name.c_str());
+ }
+
+ // Link and verify
+ mFunctions->linkProgram(mProgramID);
+
+ // Detach the shaders
+ mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
+ mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
}
- // Link and verify
- mFunctions->linkProgram(mProgramID);
-
- // Detach the shaders
- mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
- mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
-
// Verify the link
if (!checkLinkStatus(infoLog))
{