mesa/cs: Implement glDispatchComputeIndirect
authorJordan Justen <jordan.l.justen@intel.com>
Thu, 17 Sep 2015 18:14:45 +0000 (11:14 -0700)
committerJordan Justen <jordan.l.justen@intel.com>
Fri, 25 Sep 2015 02:15:13 +0000 (19:15 -0700)
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
src/mesa/main/api_validate.c
src/mesa/main/api_validate.h
src/mesa/main/compute.c
src/mesa/main/dd.h

index b46226abf78b559b7f8a41e1aca82785d880637d..a46c1944e96a174f9eb67989d705c4b38925609e 100644 (file)
@@ -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 <indirect> 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");
+}
index ef2c7949a4287ec8a526f447112dc2079aa4bb71..5d030a7ba370da9f17b30d9cc9f74c9dac17a7a9 100644 (file)
@@ -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
index f67ffbb6bfa8b7553f43fe421546cb88fb4ad58c..a0120cf0c64f3313bfb1bd6cda9d8ec1299f360e 100644 (file)
@@ -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);
 }
index 2c746fc45de2cb7af4b49537cd3f180fdb5b639c..88f37273e1e5ed576e3d1750feb8e1083f21f54d 100644 (file)
@@ -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);
    /*@}*/
 };