mesa: move DispatchCompute() validation to compute.c
authorTimothy Arceri <tarceri@itsqueeze.com>
Mon, 15 May 2017 01:08:13 +0000 (11:08 +1000)
committerTimothy Arceri <tarceri@itsqueeze.com>
Wed, 17 May 2017 00:12:04 +0000 (10:12 +1000)
This is the only place it is used so there is no reason for it to be
in api_validate.c

Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
src/mesa/main/api_validate.c
src/mesa/main/api_validate.h
src/mesa/main/compute.c

index cbb2361552e2fce8e67a3f0262bcf7aef4c80bf0..850dedae7a42df3a5007d7a9774904efdddb9561 100644 (file)
@@ -1363,237 +1363,3 @@ _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx,
    return valid_draw_indirect_parameters(
          ctx, "glMultiDrawElementsIndirectCountARB", drawcount);
 }
-
-static bool
-check_valid_to_compute(struct gl_context *ctx, const char *function)
-{
-   if (!_mesa_has_compute_shaders(ctx)) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "unsupported function (%s) called",
-                  function);
-      return false;
-   }
-
-   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
-    *
-    * "An INVALID_OPERATION error is generated if there is no active program
-    *  for the compute shader stage."
-    */
-   if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s(no active compute shader)",
-                  function);
-      return false;
-   }
-
-   return true;
-}
-
-GLboolean
-_mesa_validate_DispatchCompute(struct gl_context *ctx,
-                               const GLuint *num_groups)
-{
-   int i;
-   FLUSH_CURRENT(ctx, 0);
-
-   if (!check_valid_to_compute(ctx, "glDispatchCompute"))
-      return GL_FALSE;
-
-   for (i = 0; i < 3; i++) {
-      /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
-       *
-       * "An INVALID_VALUE error is generated if any of num_groups_x,
-       *  num_groups_y and num_groups_z are greater than or equal to the
-       *  maximum work group count for the corresponding dimension."
-       *
-       * However, the "or equal to" portions appears to be a specification
-       * bug. In all other areas, the specification appears to indicate that
-       * the number of workgroups can match the MAX_COMPUTE_WORK_GROUP_COUNT
-       * value. For example, under DispatchComputeIndirect:
-       *
-       * "If any of num_groups_x, num_groups_y or num_groups_z is greater than
-       *  the value of MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding
-       *  dimension then the results are undefined."
-       *
-       * Additionally, the OpenGLES 3.1 specification does not contain "or
-       * equal to" as an error condition.
-       */
-      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glDispatchCompute(num_groups_%c)", 'x' + i);
-         return GL_FALSE;
-      }
-   }
-
-   /* The ARB_compute_variable_group_size spec says:
-    *
-    * "An INVALID_OPERATION error is generated by DispatchCompute if the active
-    *  program for the compute shader stage has a variable work group size."
-    */
-   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (prog->info.cs.local_size_variable) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glDispatchCompute(variable work group size forbidden)");
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-GLboolean
-_mesa_validate_DispatchComputeGroupSizeARB(struct gl_context *ctx,
-                                           const GLuint *num_groups,
-                                           const GLuint *group_size)
-{
-   GLuint total_invocations = 1;
-   int i;
-
-   FLUSH_CURRENT(ctx, 0);
-
-   if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB"))
-      return GL_FALSE;
-
-   /* The ARB_compute_variable_group_size spec says:
-    *
-    * "An INVALID_OPERATION error is generated by
-    *  DispatchComputeGroupSizeARB if the active program for the compute
-    *  shader stage has a fixed work group size."
-    */
-   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (!prog->info.cs.local_size_variable) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glDispatchComputeGroupSizeARB(fixed work group size "
-                  "forbidden)");
-      return GL_FALSE;
-   }
-
-   for (i = 0; i < 3; i++) {
-      /* The ARB_compute_variable_group_size spec says:
-       *
-       * "An INVALID_VALUE error is generated if any of num_groups_x,
-       *  num_groups_y and num_groups_z are greater than or equal to the
-       *  maximum work group count for the corresponding dimension."
-       */
-      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i);
-         return GL_FALSE;
-      }
-
-      /* The ARB_compute_variable_group_size spec says:
-       *
-       * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
-       *  any of <group_size_x>, <group_size_y>, or <group_size_z> is less than
-       *  or equal to zero or greater than the maximum local work group size
-       *  for compute shaders with variable group size
-       *  (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding
-       *  dimension."
-       *
-       * However, the "less than" is a spec bug because they are declared as
-       * unsigned integers.
-       */
-      if (group_size[i] == 0 ||
-          group_size[i] > ctx->Const.MaxComputeVariableGroupSize[i]) {
-         _mesa_error(ctx, GL_INVALID_VALUE,
-                     "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i);
-         return GL_FALSE;
-      }
-
-      total_invocations *= group_size[i];
-   }
-
-   /* The ARB_compute_variable_group_size spec says:
-    *
-    * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
-    *  the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds
-    *  the implementation-dependent maximum local work group invocation count
-    *  for compute shaders with variable group size
-    *  (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)."
-    */
-   if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "glDispatchComputeGroupSizeARB(product of local_sizes "
-                  "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB "
-                  "(%d > %d))", total_invocations,
-                  ctx->Const.MaxComputeVariableGroupInvocations);
-      return GL_FALSE;
-   }
-
-   return GL_TRUE;
-}
-
-static GLboolean
-valid_dispatch_indirect(struct gl_context *ctx,
-                        GLintptr indirect,
-                        GLsizei size, const char *name)
-{
-   const uint64_t end = (uint64_t) indirect + size;
-
-   if (!check_valid_to_compute(ctx, name))
-      return GL_FALSE;
-
-   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
-    *
-    * "An INVALID_VALUE error is generated if indirect is negative or is not a
-    *  multiple of four."
-    */
-   if (indirect & (sizeof(GLuint) - 1)) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "%s(indirect is not aligned)", name);
-      return GL_FALSE;
-   }
-
-   if (indirect < 0) {
-      _mesa_error(ctx, GL_INVALID_VALUE,
-                  "%s(indirect is less than zero)", name);
-      return GL_FALSE;
-   }
-
-   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
-    *
-    * "An INVALID_OPERATION error is generated if no buffer is bound to the
-    *  DRAW_INDIRECT_BUFFER binding, or if the command would source data
-    *  beyond the end of the buffer object."
-    */
-   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;
-   }
-
-   if (ctx->DispatchIndirectBuffer->Size < end) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s(DISPATCH_INDIRECT_BUFFER too small)", name);
-      return GL_FALSE;
-   }
-
-   /* The ARB_compute_variable_group_size spec says:
-    *
-    * "An INVALID_OPERATION error is generated if the active program for the
-    *  compute shader stage has a variable work group size."
-    */
-   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
-   if (prog->info.cs.local_size_variable) {
-      _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "%s(variable work group size forbidden)", 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 88c51bf9137ee7343207777a9a26d25225ffced1..7a181153fb748579fe4bc3ab9f11aaf9b6d84308 100644 (file)
@@ -128,17 +128,4 @@ _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx,
                                               GLsizei maxdrawcount,
                                               GLsizei stride);
 
-extern GLboolean
-_mesa_validate_DispatchCompute(struct gl_context *ctx,
-                               const GLuint *num_groups);
-
-extern GLboolean
-_mesa_validate_DispatchComputeIndirect(struct gl_context *ctx,
-                                       GLintptr indirect);
-
-extern GLboolean
-_mesa_validate_DispatchComputeGroupSizeARB(struct gl_context *ctx,
-                                           const GLuint *num_groups,
-                                           const GLuint *group_size);
-
 #endif
index bb6253906bc53b11b05894a3a6a95548deb347e7..5c84516688490fa416790e4bf49f9c3430e3ce75 100644 (file)
  */
 
 #include "glheader.h"
+#include "bufferobj.h"
 #include "compute.h"
 #include "context.h"
-#include "api_validate.h"
+
+static bool
+check_valid_to_compute(struct gl_context *ctx, const char *function)
+{
+   if (!_mesa_has_compute_shaders(ctx)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "unsupported function (%s) called",
+                  function);
+      return false;
+   }
+
+   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
+    *
+    * "An INVALID_OPERATION error is generated if there is no active program
+    *  for the compute shader stage."
+    */
+   if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(no active compute shader)",
+                  function);
+      return false;
+   }
+
+   return true;
+}
+
+static bool
+validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups)
+{
+   int i;
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!check_valid_to_compute(ctx, "glDispatchCompute"))
+      return GL_FALSE;
+
+   for (i = 0; i < 3; i++) {
+      /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
+       *
+       * "An INVALID_VALUE error is generated if any of num_groups_x,
+       *  num_groups_y and num_groups_z are greater than or equal to the
+       *  maximum work group count for the corresponding dimension."
+       *
+       * However, the "or equal to" portions appears to be a specification
+       * bug. In all other areas, the specification appears to indicate that
+       * the number of workgroups can match the MAX_COMPUTE_WORK_GROUP_COUNT
+       * value. For example, under DispatchComputeIndirect:
+       *
+       * "If any of num_groups_x, num_groups_y or num_groups_z is greater than
+       *  the value of MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding
+       *  dimension then the results are undefined."
+       *
+       * Additionally, the OpenGLES 3.1 specification does not contain "or
+       * equal to" as an error condition.
+       */
+      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDispatchCompute(num_groups_%c)", 'x' + i);
+         return GL_FALSE;
+      }
+   }
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated by DispatchCompute if the active
+    *  program for the compute shader stage has a variable work group size."
+    */
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->info.cs.local_size_variable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glDispatchCompute(variable work group size forbidden)");
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+static bool
+validate_DispatchComputeGroupSizeARB(struct gl_context *ctx,
+                                     const GLuint *num_groups,
+                                     const GLuint *group_size)
+{
+   GLuint total_invocations = 1;
+   int i;
+
+   FLUSH_CURRENT(ctx, 0);
+
+   if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB"))
+      return GL_FALSE;
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated by
+    *  DispatchComputeGroupSizeARB if the active program for the compute
+    *  shader stage has a fixed work group size."
+    */
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (!prog->info.cs.local_size_variable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glDispatchComputeGroupSizeARB(fixed work group size "
+                  "forbidden)");
+      return GL_FALSE;
+   }
+
+   for (i = 0; i < 3; i++) {
+      /* The ARB_compute_variable_group_size spec says:
+       *
+       * "An INVALID_VALUE error is generated if any of num_groups_x,
+       *  num_groups_y and num_groups_z are greater than or equal to the
+       *  maximum work group count for the corresponding dimension."
+       */
+      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i);
+         return GL_FALSE;
+      }
+
+      /* The ARB_compute_variable_group_size spec says:
+       *
+       * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
+       *  any of <group_size_x>, <group_size_y>, or <group_size_z> is less than
+       *  or equal to zero or greater than the maximum local work group size
+       *  for compute shaders with variable group size
+       *  (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding
+       *  dimension."
+       *
+       * However, the "less than" is a spec bug because they are declared as
+       * unsigned integers.
+       */
+      if (group_size[i] == 0 ||
+          group_size[i] > ctx->Const.MaxComputeVariableGroupSize[i]) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i);
+         return GL_FALSE;
+      }
+
+      total_invocations *= group_size[i];
+   }
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
+    *  the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds
+    *  the implementation-dependent maximum local work group invocation count
+    *  for compute shaders with variable group size
+    *  (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)."
+    */
+   if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glDispatchComputeGroupSizeARB(product of local_sizes "
+                  "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB "
+                  "(%d > %d))", total_invocations,
+                  ctx->Const.MaxComputeVariableGroupInvocations);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
+
+static bool
+valid_dispatch_indirect(struct gl_context *ctx,  GLintptr indirect)
+{
+   FLUSH_CURRENT(ctx, 0);
+
+   GLsizei size = 3 * sizeof(GLuint);
+   const uint64_t end = (uint64_t) indirect + size;
+   const char *name = "glDispatchComputeIndirect";
+
+   if (!check_valid_to_compute(ctx, name))
+      return GL_FALSE;
+
+   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
+    *
+    * "An INVALID_VALUE error is generated if indirect is negative or is not a
+    *  multiple of four."
+    */
+   if (indirect & (sizeof(GLuint) - 1)) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(indirect is not aligned)", name);
+      return GL_FALSE;
+   }
+
+   if (indirect < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "%s(indirect is less than zero)", name);
+      return GL_FALSE;
+   }
+
+   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
+    *
+    * "An INVALID_OPERATION error is generated if no buffer is bound to the
+    *  DRAW_INDIRECT_BUFFER binding, or if the command would source data
+    *  beyond the end of the buffer object."
+    */
+   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;
+   }
+
+   if (ctx->DispatchIndirectBuffer->Size < end) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(DISPATCH_INDIRECT_BUFFER too small)", name);
+      return GL_FALSE;
+   }
+
+   /* The ARB_compute_variable_group_size spec says:
+    *
+    * "An INVALID_OPERATION error is generated if the active program for the
+    *  compute shader stage has a variable work group size."
+    */
+   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
+   if (prog->info.cs.local_size_variable) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "%s(variable work group size forbidden)", name);
+      return GL_FALSE;
+   }
+
+   return GL_TRUE;
+}
 
 void GLAPIENTRY
 _mesa_DispatchCompute(GLuint num_groups_x,
@@ -38,7 +263,7 @@ _mesa_DispatchCompute(GLuint num_groups_x,
       _mesa_debug(ctx, "glDispatchCompute(%d, %d, %d)\n",
                   num_groups_x, num_groups_y, num_groups_z);
 
-   if (!_mesa_validate_DispatchCompute(ctx, num_groups))
+   if (!validate_DispatchCompute(ctx, num_groups))
       return;
 
    if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)
@@ -55,7 +280,7 @@ _mesa_DispatchComputeIndirect(GLintptr indirect)
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(ctx, "glDispatchComputeIndirect(%ld)\n", (long) indirect);
 
-   if (!_mesa_validate_DispatchComputeIndirect(ctx, indirect))
+   if (!valid_dispatch_indirect(ctx, indirect))
       return;
 
    ctx->Driver.DispatchComputeIndirect(ctx, indirect);
@@ -76,8 +301,7 @@ _mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y,
                   num_groups_x, num_groups_y, num_groups_z,
                   group_size_x, group_size_y, group_size_z);
 
-   if (!_mesa_validate_DispatchComputeGroupSizeARB(ctx, num_groups,
-                                                   group_size))
+   if (!validate_DispatchComputeGroupSizeARB(ctx, num_groups, group_size))
       return;
 
    if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)