1af69d88dSmrg/*
2af69d88dSmrg * Copyright © 2014 Intel Corporation
3af69d88dSmrg *
4af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
5af69d88dSmrg * copy of this software and associated documentation files (the "Software"),
6af69d88dSmrg * to deal in the Software without restriction, including without limitation
7af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the
9af69d88dSmrg * Software is furnished to do so, subject to the following conditions:
10af69d88dSmrg *
11af69d88dSmrg * The above copyright notice and this permission notice (including the next
12af69d88dSmrg * paragraph) shall be included in all copies or substantial portions of the
13af69d88dSmrg * Software.
14af69d88dSmrg *
15af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21af69d88dSmrg * DEALINGS IN THE SOFTWARE.
22af69d88dSmrg */
23af69d88dSmrg
24af69d88dSmrg#include "glheader.h"
2501e04c3fSmrg#include "bufferobj.h"
26af69d88dSmrg#include "compute.h"
27af69d88dSmrg#include "context.h"
28af69d88dSmrg
2901e04c3fSmrgstatic bool
3001e04c3fSmrgcheck_valid_to_compute(struct gl_context *ctx, const char *function)
3101e04c3fSmrg{
3201e04c3fSmrg   if (!_mesa_has_compute_shaders(ctx)) {
3301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
3401e04c3fSmrg                  "unsupported function (%s) called",
3501e04c3fSmrg                  function);
3601e04c3fSmrg      return false;
3701e04c3fSmrg   }
3801e04c3fSmrg
3901e04c3fSmrg   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
4001e04c3fSmrg    *
4101e04c3fSmrg    * "An INVALID_OPERATION error is generated if there is no active program
4201e04c3fSmrg    *  for the compute shader stage."
4301e04c3fSmrg    */
4401e04c3fSmrg   if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) {
4501e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
4601e04c3fSmrg                  "%s(no active compute shader)",
4701e04c3fSmrg                  function);
4801e04c3fSmrg      return false;
4901e04c3fSmrg   }
5001e04c3fSmrg
5101e04c3fSmrg   return true;
5201e04c3fSmrg}
5301e04c3fSmrg
5401e04c3fSmrgstatic bool
5501e04c3fSmrgvalidate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups)
5601e04c3fSmrg{
5701e04c3fSmrg   if (!check_valid_to_compute(ctx, "glDispatchCompute"))
5801e04c3fSmrg      return GL_FALSE;
5901e04c3fSmrg
6001e04c3fSmrg   for (int i = 0; i < 3; i++) {
6101e04c3fSmrg      /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
6201e04c3fSmrg       *
6301e04c3fSmrg       * "An INVALID_VALUE error is generated if any of num_groups_x,
6401e04c3fSmrg       *  num_groups_y and num_groups_z are greater than or equal to the
6501e04c3fSmrg       *  maximum work group count for the corresponding dimension."
6601e04c3fSmrg       *
6701e04c3fSmrg       * However, the "or equal to" portions appears to be a specification
6801e04c3fSmrg       * bug. In all other areas, the specification appears to indicate that
6901e04c3fSmrg       * the number of workgroups can match the MAX_COMPUTE_WORK_GROUP_COUNT
7001e04c3fSmrg       * value. For example, under DispatchComputeIndirect:
7101e04c3fSmrg       *
7201e04c3fSmrg       * "If any of num_groups_x, num_groups_y or num_groups_z is greater than
7301e04c3fSmrg       *  the value of MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding
7401e04c3fSmrg       *  dimension then the results are undefined."
7501e04c3fSmrg       *
7601e04c3fSmrg       * Additionally, the OpenGLES 3.1 specification does not contain "or
7701e04c3fSmrg       * equal to" as an error condition.
7801e04c3fSmrg       */
7901e04c3fSmrg      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
8001e04c3fSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
8101e04c3fSmrg                     "glDispatchCompute(num_groups_%c)", 'x' + i);
8201e04c3fSmrg         return GL_FALSE;
8301e04c3fSmrg      }
8401e04c3fSmrg   }
8501e04c3fSmrg
8601e04c3fSmrg   /* The ARB_compute_variable_group_size spec says:
8701e04c3fSmrg    *
8801e04c3fSmrg    * "An INVALID_OPERATION error is generated by DispatchCompute if the active
8901e04c3fSmrg    *  program for the compute shader stage has a variable work group size."
9001e04c3fSmrg    */
9101e04c3fSmrg   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
927ec681f3Smrg   if (prog->info.workgroup_size_variable) {
9301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
9401e04c3fSmrg                  "glDispatchCompute(variable work group size forbidden)");
9501e04c3fSmrg      return GL_FALSE;
9601e04c3fSmrg   }
9701e04c3fSmrg
9801e04c3fSmrg   return GL_TRUE;
9901e04c3fSmrg}
10001e04c3fSmrg
10101e04c3fSmrgstatic bool
10201e04c3fSmrgvalidate_DispatchComputeGroupSizeARB(struct gl_context *ctx,
10301e04c3fSmrg                                     const GLuint *num_groups,
10401e04c3fSmrg                                     const GLuint *group_size)
10501e04c3fSmrg{
10601e04c3fSmrg   if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB"))
10701e04c3fSmrg      return GL_FALSE;
10801e04c3fSmrg
10901e04c3fSmrg   /* The ARB_compute_variable_group_size spec says:
11001e04c3fSmrg    *
11101e04c3fSmrg    * "An INVALID_OPERATION error is generated by
11201e04c3fSmrg    *  DispatchComputeGroupSizeARB if the active program for the compute
11301e04c3fSmrg    *  shader stage has a fixed work group size."
11401e04c3fSmrg    */
11501e04c3fSmrg   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
1167ec681f3Smrg   if (!prog->info.workgroup_size_variable) {
11701e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
11801e04c3fSmrg                  "glDispatchComputeGroupSizeARB(fixed work group size "
11901e04c3fSmrg                  "forbidden)");
12001e04c3fSmrg      return GL_FALSE;
12101e04c3fSmrg   }
12201e04c3fSmrg
12301e04c3fSmrg   for (int i = 0; i < 3; i++) {
12401e04c3fSmrg      /* The ARB_compute_variable_group_size spec says:
12501e04c3fSmrg       *
12601e04c3fSmrg       * "An INVALID_VALUE error is generated if any of num_groups_x,
12701e04c3fSmrg       *  num_groups_y and num_groups_z are greater than or equal to the
12801e04c3fSmrg       *  maximum work group count for the corresponding dimension."
12901e04c3fSmrg       */
13001e04c3fSmrg      if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) {
13101e04c3fSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
13201e04c3fSmrg                     "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i);
13301e04c3fSmrg         return GL_FALSE;
13401e04c3fSmrg      }
13501e04c3fSmrg
13601e04c3fSmrg      /* The ARB_compute_variable_group_size spec says:
13701e04c3fSmrg       *
13801e04c3fSmrg       * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
13901e04c3fSmrg       *  any of <group_size_x>, <group_size_y>, or <group_size_z> is less than
14001e04c3fSmrg       *  or equal to zero or greater than the maximum local work group size
14101e04c3fSmrg       *  for compute shaders with variable group size
14201e04c3fSmrg       *  (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding
14301e04c3fSmrg       *  dimension."
14401e04c3fSmrg       *
14501e04c3fSmrg       * However, the "less than" is a spec bug because they are declared as
14601e04c3fSmrg       * unsigned integers.
14701e04c3fSmrg       */
14801e04c3fSmrg      if (group_size[i] == 0 ||
14901e04c3fSmrg          group_size[i] > ctx->Const.MaxComputeVariableGroupSize[i]) {
15001e04c3fSmrg         _mesa_error(ctx, GL_INVALID_VALUE,
15101e04c3fSmrg                     "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i);
15201e04c3fSmrg         return GL_FALSE;
15301e04c3fSmrg      }
15401e04c3fSmrg   }
15501e04c3fSmrg
15601e04c3fSmrg   /* The ARB_compute_variable_group_size spec says:
15701e04c3fSmrg    *
15801e04c3fSmrg    * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
15901e04c3fSmrg    *  the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds
16001e04c3fSmrg    *  the implementation-dependent maximum local work group invocation count
16101e04c3fSmrg    *  for compute shaders with variable group size
16201e04c3fSmrg    *  (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)."
16301e04c3fSmrg    */
1647ec681f3Smrg   uint64_t total_invocations = group_size[0] * group_size[1];
1657ec681f3Smrg   if (total_invocations <= UINT32_MAX) {
1667ec681f3Smrg      /* Only bother multiplying the third value if total still fits in
1677ec681f3Smrg       * 32-bit, since MaxComputeVariableGroupInvocations is also 32-bit.
1687ec681f3Smrg       */
1697ec681f3Smrg      total_invocations *= group_size[2];
1707ec681f3Smrg   }
17101e04c3fSmrg   if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) {
17201e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE,
17301e04c3fSmrg                  "glDispatchComputeGroupSizeARB(product of local_sizes "
17401e04c3fSmrg                  "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB "
1757ec681f3Smrg                  "(%u * %u * %u > %u))",
1767ec681f3Smrg                  group_size[0], group_size[1], group_size[2],
17701e04c3fSmrg                  ctx->Const.MaxComputeVariableGroupInvocations);
17801e04c3fSmrg      return GL_FALSE;
17901e04c3fSmrg   }
18001e04c3fSmrg
1817ec681f3Smrg   /* The NV_compute_shader_derivatives spec says:
1827ec681f3Smrg    *
1837ec681f3Smrg    * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
1847ec681f3Smrg    *  the active program for the compute shader stage has a compute shader
1857ec681f3Smrg    *  using the "derivative_group_quadsNV" layout qualifier and
1867ec681f3Smrg    *  <group_size_x> or <group_size_y> is not a multiple of two.
1877ec681f3Smrg    *
1887ec681f3Smrg    *  An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if
1897ec681f3Smrg    *  the active program for the compute shader stage has a compute shader
1907ec681f3Smrg    *  using the "derivative_group_linearNV" layout qualifier and the product
1917ec681f3Smrg    *  of <group_size_x>, <group_size_y>, and <group_size_z> is not a multiple
1927ec681f3Smrg    *  of four."
1937ec681f3Smrg    */
1947ec681f3Smrg   if (prog->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS &&
1957ec681f3Smrg       ((group_size[0] & 1) || (group_size[1] & 1))) {
1967ec681f3Smrg      _mesa_error(ctx, GL_INVALID_VALUE,
1977ec681f3Smrg                  "glDispatchComputeGroupSizeARB(derivative_group_quadsNV "
1987ec681f3Smrg                  "requires group_size_x (%d) and group_size_y (%d) to be "
1997ec681f3Smrg                  "divisble by 2)", group_size[0], group_size[1]);
2007ec681f3Smrg      return GL_FALSE;
2017ec681f3Smrg   }
2027ec681f3Smrg
2037ec681f3Smrg   if (prog->info.cs.derivative_group == DERIVATIVE_GROUP_LINEAR &&
2047ec681f3Smrg       total_invocations & 3) {
2057ec681f3Smrg      _mesa_error(ctx, GL_INVALID_VALUE,
2067ec681f3Smrg                  "glDispatchComputeGroupSizeARB(derivative_group_linearNV "
2077ec681f3Smrg                  "requires product of group sizes (%"PRIu64") to be divisible "
2087ec681f3Smrg                  "by 4)", total_invocations);
2097ec681f3Smrg      return GL_FALSE;
2107ec681f3Smrg   }
2117ec681f3Smrg
21201e04c3fSmrg   return GL_TRUE;
21301e04c3fSmrg}
21401e04c3fSmrg
21501e04c3fSmrgstatic bool
21601e04c3fSmrgvalid_dispatch_indirect(struct gl_context *ctx,  GLintptr indirect)
21701e04c3fSmrg{
21801e04c3fSmrg   GLsizei size = 3 * sizeof(GLuint);
21901e04c3fSmrg   const uint64_t end = (uint64_t) indirect + size;
22001e04c3fSmrg   const char *name = "glDispatchComputeIndirect";
22101e04c3fSmrg
22201e04c3fSmrg   if (!check_valid_to_compute(ctx, name))
22301e04c3fSmrg      return GL_FALSE;
22401e04c3fSmrg
22501e04c3fSmrg   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
22601e04c3fSmrg    *
22701e04c3fSmrg    * "An INVALID_VALUE error is generated if indirect is negative or is not a
22801e04c3fSmrg    *  multiple of four."
22901e04c3fSmrg    */
23001e04c3fSmrg   if (indirect & (sizeof(GLuint) - 1)) {
23101e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE,
23201e04c3fSmrg                  "%s(indirect is not aligned)", name);
23301e04c3fSmrg      return GL_FALSE;
23401e04c3fSmrg   }
23501e04c3fSmrg
23601e04c3fSmrg   if (indirect < 0) {
23701e04c3fSmrg      _mesa_error(ctx, GL_INVALID_VALUE,
23801e04c3fSmrg                  "%s(indirect is less than zero)", name);
23901e04c3fSmrg      return GL_FALSE;
24001e04c3fSmrg   }
24101e04c3fSmrg
24201e04c3fSmrg   /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders:
24301e04c3fSmrg    *
24401e04c3fSmrg    * "An INVALID_OPERATION error is generated if no buffer is bound to the
24501e04c3fSmrg    *  DRAW_INDIRECT_BUFFER binding, or if the command would source data
24601e04c3fSmrg    *  beyond the end of the buffer object."
24701e04c3fSmrg    */
2487ec681f3Smrg   if (!ctx->DispatchIndirectBuffer) {
24901e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
25001e04c3fSmrg                  "%s: no buffer bound to DISPATCH_INDIRECT_BUFFER", name);
25101e04c3fSmrg      return GL_FALSE;
25201e04c3fSmrg   }
25301e04c3fSmrg
25401e04c3fSmrg   if (_mesa_check_disallowed_mapping(ctx->DispatchIndirectBuffer)) {
25501e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
25601e04c3fSmrg                  "%s(DISPATCH_INDIRECT_BUFFER is mapped)", name);
25701e04c3fSmrg      return GL_FALSE;
25801e04c3fSmrg   }
25901e04c3fSmrg
26001e04c3fSmrg   if (ctx->DispatchIndirectBuffer->Size < end) {
26101e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
26201e04c3fSmrg                  "%s(DISPATCH_INDIRECT_BUFFER too small)", name);
26301e04c3fSmrg      return GL_FALSE;
26401e04c3fSmrg   }
26501e04c3fSmrg
26601e04c3fSmrg   /* The ARB_compute_variable_group_size spec says:
26701e04c3fSmrg    *
26801e04c3fSmrg    * "An INVALID_OPERATION error is generated if the active program for the
26901e04c3fSmrg    *  compute shader stage has a variable work group size."
27001e04c3fSmrg    */
27101e04c3fSmrg   struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE];
2727ec681f3Smrg   if (prog->info.workgroup_size_variable) {
27301e04c3fSmrg      _mesa_error(ctx, GL_INVALID_OPERATION,
27401e04c3fSmrg                  "%s(variable work group size forbidden)", name);
27501e04c3fSmrg      return GL_FALSE;
27601e04c3fSmrg   }
27701e04c3fSmrg
27801e04c3fSmrg   return GL_TRUE;
27901e04c3fSmrg}
28001e04c3fSmrg
28101e04c3fSmrgstatic ALWAYS_INLINE void
28201e04c3fSmrgdispatch_compute(GLuint num_groups_x, GLuint num_groups_y,
28301e04c3fSmrg                 GLuint num_groups_z, bool no_error)
28401e04c3fSmrg{
28501e04c3fSmrg   GET_CURRENT_CONTEXT(ctx);
28601e04c3fSmrg   const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z };
28701e04c3fSmrg
2887ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
28901e04c3fSmrg
29001e04c3fSmrg   if (MESA_VERBOSE & VERBOSE_API)
29101e04c3fSmrg      _mesa_debug(ctx, "glDispatchCompute(%d, %d, %d)\n",
29201e04c3fSmrg                  num_groups_x, num_groups_y, num_groups_z);
29301e04c3fSmrg
29401e04c3fSmrg   if (!no_error && !validate_DispatchCompute(ctx, num_groups))
29501e04c3fSmrg      return;
29601e04c3fSmrg
29701e04c3fSmrg   if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)
29801e04c3fSmrg       return;
29901e04c3fSmrg
30001e04c3fSmrg   ctx->Driver.DispatchCompute(ctx, num_groups);
3017ec681f3Smrg
3027ec681f3Smrg   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
3037ec681f3Smrg      _mesa_flush(ctx);
30401e04c3fSmrg}
30501e04c3fSmrg
30601e04c3fSmrgvoid GLAPIENTRY
30701e04c3fSmrg_mesa_DispatchCompute_no_error(GLuint num_groups_x, GLuint num_groups_y,
30801e04c3fSmrg                               GLuint num_groups_z)
30901e04c3fSmrg{
31001e04c3fSmrg   dispatch_compute(num_groups_x, num_groups_y, num_groups_z, true);
31101e04c3fSmrg}
31201e04c3fSmrg
313af69d88dSmrgvoid GLAPIENTRY
314af69d88dSmrg_mesa_DispatchCompute(GLuint num_groups_x,
315af69d88dSmrg                      GLuint num_groups_y,
316af69d88dSmrg                      GLuint num_groups_z)
31701e04c3fSmrg{
31801e04c3fSmrg   dispatch_compute(num_groups_x, num_groups_y, num_groups_z, false);
31901e04c3fSmrg}
32001e04c3fSmrg
32101e04c3fSmrgstatic ALWAYS_INLINE void
32201e04c3fSmrgdispatch_compute_indirect(GLintptr indirect, bool no_error)
323af69d88dSmrg{
324af69d88dSmrg   GET_CURRENT_CONTEXT(ctx);
325af69d88dSmrg
3267ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
32701e04c3fSmrg
32801e04c3fSmrg   if (MESA_VERBOSE & VERBOSE_API)
32901e04c3fSmrg      _mesa_debug(ctx, "glDispatchComputeIndirect(%ld)\n", (long) indirect);
33001e04c3fSmrg
33101e04c3fSmrg   if (!no_error && !valid_dispatch_indirect(ctx, indirect))
33201e04c3fSmrg      return;
33301e04c3fSmrg
33401e04c3fSmrg   ctx->Driver.DispatchComputeIndirect(ctx, indirect);
3357ec681f3Smrg
3367ec681f3Smrg   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
3377ec681f3Smrg      _mesa_flush(ctx);
33801e04c3fSmrg}
33901e04c3fSmrg
34001e04c3fSmrgextern void GLAPIENTRY
34101e04c3fSmrg_mesa_DispatchComputeIndirect_no_error(GLintptr indirect)
34201e04c3fSmrg{
34301e04c3fSmrg   dispatch_compute_indirect(indirect, true);
344af69d88dSmrg}
345af69d88dSmrg
346af69d88dSmrgextern void GLAPIENTRY
347af69d88dSmrg_mesa_DispatchComputeIndirect(GLintptr indirect)
34801e04c3fSmrg{
34901e04c3fSmrg   dispatch_compute_indirect(indirect, false);
35001e04c3fSmrg}
35101e04c3fSmrg
35201e04c3fSmrgstatic ALWAYS_INLINE void
35301e04c3fSmrgdispatch_compute_group_size(GLuint num_groups_x, GLuint num_groups_y,
35401e04c3fSmrg                            GLuint num_groups_z, GLuint group_size_x,
35501e04c3fSmrg                            GLuint group_size_y, GLuint group_size_z,
35601e04c3fSmrg                            bool no_error)
357af69d88dSmrg{
358af69d88dSmrg   GET_CURRENT_CONTEXT(ctx);
35901e04c3fSmrg   const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z };
36001e04c3fSmrg   const GLuint group_size[3] = { group_size_x, group_size_y, group_size_z };
361af69d88dSmrg
3627ec681f3Smrg   FLUSH_VERTICES(ctx, 0, 0);
36301e04c3fSmrg
36401e04c3fSmrg   if (MESA_VERBOSE & VERBOSE_API)
36501e04c3fSmrg      _mesa_debug(ctx,
36601e04c3fSmrg                  "glDispatchComputeGroupSizeARB(%d, %d, %d, %d, %d, %d)\n",
36701e04c3fSmrg                  num_groups_x, num_groups_y, num_groups_z,
36801e04c3fSmrg                  group_size_x, group_size_y, group_size_z);
36901e04c3fSmrg
37001e04c3fSmrg   if (!no_error &&
37101e04c3fSmrg       !validate_DispatchComputeGroupSizeARB(ctx, num_groups, group_size))
37201e04c3fSmrg      return;
37301e04c3fSmrg
37401e04c3fSmrg   if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)
37501e04c3fSmrg       return;
37601e04c3fSmrg
37701e04c3fSmrg   ctx->Driver.DispatchComputeGroupSize(ctx, num_groups, group_size);
3787ec681f3Smrg
3797ec681f3Smrg   if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
3807ec681f3Smrg      _mesa_flush(ctx);
38101e04c3fSmrg}
38201e04c3fSmrg
38301e04c3fSmrgvoid GLAPIENTRY
38401e04c3fSmrg_mesa_DispatchComputeGroupSizeARB_no_error(GLuint num_groups_x,
38501e04c3fSmrg                                           GLuint num_groups_y,
38601e04c3fSmrg                                           GLuint num_groups_z,
38701e04c3fSmrg                                           GLuint group_size_x,
38801e04c3fSmrg                                           GLuint group_size_y,
38901e04c3fSmrg                                           GLuint group_size_z)
39001e04c3fSmrg{
39101e04c3fSmrg   dispatch_compute_group_size(num_groups_x, num_groups_y, num_groups_z,
39201e04c3fSmrg                               group_size_x, group_size_y, group_size_z,
39301e04c3fSmrg                               true);
39401e04c3fSmrg}
39501e04c3fSmrg
39601e04c3fSmrgvoid GLAPIENTRY
39701e04c3fSmrg_mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y,
39801e04c3fSmrg                                  GLuint num_groups_z, GLuint group_size_x,
39901e04c3fSmrg                                  GLuint group_size_y, GLuint group_size_z)
40001e04c3fSmrg{
40101e04c3fSmrg   dispatch_compute_group_size(num_groups_x, num_groups_y, num_groups_z,
40201e04c3fSmrg                               group_size_x, group_size_y, group_size_z,
40301e04c3fSmrg                               false);
404af69d88dSmrg}
405