ES31: Add DispatchComputeIndirect suport for OpenGL backend
BUG=angleproject:2270
TEST=dEQP-GLES31.functional.compute.indirect_dispatch.*
Change-Id: Id062a80188b2a37f28833aaae8e6d31bac382276
Reviewed-on: https://chromium-review.googlesource.com/802763
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/validationES31.cpp b/src/libANGLE/validationES31.cpp
index 61d1adb..8403f68 100644
--- a/src/libANGLE/validationES31.cpp
+++ b/src/libANGLE/validationES31.cpp
@@ -1384,16 +1384,9 @@
const State &state = context->getGLState();
Program *program = state.getProgram();
- if (program == nullptr)
+ if (program == nullptr || !program->hasLinkedComputeShader())
{
- context->handleError(InvalidOperation()
- << "No active program object for the compute shader stage.");
- return false;
- }
-
- if (!program->hasLinkedComputeShader())
- {
- context->handleError(InvalidOperation() << "Program contains no compute shaders.");
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
return false;
}
@@ -1425,8 +1418,50 @@
bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
{
- UNIMPLEMENTED();
- return false;
+ if (context->getClientVersion() < ES_3_1)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
+ return false;
+ }
+
+ const State &state = context->getGLState();
+ Program *program = state.getProgram();
+
+ if (program == nullptr || !program->hasLinkedComputeShader())
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoActiveProgramWithComputeShader);
+ return false;
+ }
+
+ gl::Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
+ if (!dispatchIndirectBuffer)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), DispatchIndirectBufferNotBound);
+ return false;
+ }
+
+ if (indirect < 0)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
+ return false;
+ }
+
+ if ((indirect & (sizeof(GLuint) - 1)) != 0)
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), OffsetMustBeMultipleOfUint);
+ return false;
+ }
+
+ CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
+ auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
+ if (!checkedSum.IsValid() ||
+ checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
+ {
+ ANGLE_VALIDATION_ERR(context, InvalidOperation(), InsufficientBufferSize);
+ return false;
+ }
+
+ return true;
}
bool ValidateBindImageTexture(Context *context,