From d11d018ce38b76a580242d64e61e8e30dad035e8 Mon Sep 17 00:00:00 2001 From: Jordan Justen Date: Thu, 17 Sep 2015 11:14:45 -0700 Subject: mesa/cs: Implement glDispatchComputeIndirect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jordan Justen Reviewed-by: Kristian Høgsberg --- src/mesa/main/api_validate.c | 64 ++++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/api_validate.h | 4 +++ src/mesa/main/compute.c | 10 +++---- src/mesa/main/dd.h | 1 + 4 files changed, 73 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index b46226abf78..a46c1944e96 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -926,3 +926,67 @@ _mesa_validate_DispatchCompute(struct gl_context *ctx, return GL_TRUE; } + +static GLboolean +valid_dispatch_indirect(struct gl_context *ctx, + GLintptr indirect, + GLsizei size, const char *name) +{ + GLintptr end = (GLintptr)indirect + size; + + if (!check_valid_to_compute(ctx, name)) + return GL_FALSE; + + /* From the ARB_compute_shader specification: + * + * "An INVALID_OPERATION error is generated [...] if is less + * than zero or not a multiple of the size, in basic machine units, of + * uint." + */ + if ((GLintptr)indirect & (sizeof(GLuint) - 1)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(indirect is not aligned)", name); + return GL_FALSE; + } + + if ((GLintptr)indirect < 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(indirect is less than zero)", name); + return GL_FALSE; + } + + if (!_mesa_is_bufferobj(ctx->DispatchIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s: no buffer bound to DISPATCH_INDIRECT_BUFFER", name); + return GL_FALSE; + } + + if (_mesa_check_disallowed_mapping(ctx->DispatchIndirectBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(DISPATCH_INDIRECT_BUFFER is mapped)", name); + return GL_FALSE; + } + + /* From the ARB_compute_shader specification: + * + * "An INVALID_OPERATION error is generated if this command sources data + * beyond the end of the buffer object [...]" + */ + if (ctx->DispatchIndirectBuffer->Size < end) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(DISPATCH_INDIRECT_BUFFER too small)", name); + return GL_FALSE; + } + + return GL_TRUE; +} + +GLboolean +_mesa_validate_DispatchComputeIndirect(struct gl_context *ctx, + GLintptr indirect) +{ + FLUSH_CURRENT(ctx, 0); + + return valid_dispatch_indirect(ctx, indirect, 3 * sizeof(GLuint), + "glDispatchComputeIndirect"); +} diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h index ef2c7949a42..5d030a7ba37 100644 --- a/src/mesa/main/api_validate.h +++ b/src/mesa/main/api_validate.h @@ -109,5 +109,9 @@ extern GLboolean _mesa_validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups); +extern GLboolean +_mesa_validate_DispatchComputeIndirect(struct gl_context *ctx, + GLintptr indirect); + #endif diff --git a/src/mesa/main/compute.c b/src/mesa/main/compute.c index f67ffbb6bfa..a0120cf0c64 100644 --- a/src/mesa/main/compute.c +++ b/src/mesa/main/compute.c @@ -45,10 +45,8 @@ _mesa_DispatchComputeIndirect(GLintptr indirect) { GET_CURRENT_CONTEXT(ctx); - if (ctx->Extensions.ARB_compute_shader) { - assert(!"TODO"); - } else { - _mesa_error(ctx, GL_INVALID_OPERATION, - "unsupported function (glDispatchComputeIndirect) called"); - } + if (!_mesa_validate_DispatchComputeIndirect(ctx, indirect)) + return; + + ctx->Driver.DispatchComputeIndirect(ctx, indirect); } diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 2c746fc45de..88f37273e1e 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1021,6 +1021,7 @@ struct dd_function_table { */ /*@{*/ void (*DispatchCompute)(struct gl_context *ctx, const GLuint *num_groups); + void (*DispatchComputeIndirect)(struct gl_context *ctx, GLintptr indirect); /*@}*/ }; -- cgit v1.2.3