1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2014 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci#include "glheader.h" 25bf215546Sopenharmony_ci#include "bufferobj.h" 26bf215546Sopenharmony_ci#include "context.h" 27bf215546Sopenharmony_ci#include "state.h" 28bf215546Sopenharmony_ci#include "api_exec_decl.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_state.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "state_tracker/st_context.h" 33bf215546Sopenharmony_ci#include "state_tracker/st_cb_bitmap.h" 34bf215546Sopenharmony_ci#include "state_tracker/st_util.h" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistatic bool 37bf215546Sopenharmony_cicheck_valid_to_compute(struct gl_context *ctx, const char *function) 38bf215546Sopenharmony_ci{ 39bf215546Sopenharmony_ci if (!_mesa_has_compute_shaders(ctx)) { 40bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 41bf215546Sopenharmony_ci "unsupported function (%s) called", 42bf215546Sopenharmony_ci function); 43bf215546Sopenharmony_ci return false; 44bf215546Sopenharmony_ci } 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders: 47bf215546Sopenharmony_ci * 48bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated if there is no active program 49bf215546Sopenharmony_ci * for the compute shader stage." 50bf215546Sopenharmony_ci */ 51bf215546Sopenharmony_ci if (ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE] == NULL) { 52bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 53bf215546Sopenharmony_ci "%s(no active compute shader)", 54bf215546Sopenharmony_ci function); 55bf215546Sopenharmony_ci return false; 56bf215546Sopenharmony_ci } 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_ci return true; 59bf215546Sopenharmony_ci} 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_cistatic bool 62bf215546Sopenharmony_civalidate_DispatchCompute(struct gl_context *ctx, struct pipe_grid_info *info) 63bf215546Sopenharmony_ci{ 64bf215546Sopenharmony_ci if (!check_valid_to_compute(ctx, "glDispatchCompute")) 65bf215546Sopenharmony_ci return GL_FALSE; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 68bf215546Sopenharmony_ci /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders: 69bf215546Sopenharmony_ci * 70bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated if any of num_groups_x, 71bf215546Sopenharmony_ci * num_groups_y and num_groups_z are greater than or equal to the 72bf215546Sopenharmony_ci * maximum work group count for the corresponding dimension." 73bf215546Sopenharmony_ci * 74bf215546Sopenharmony_ci * However, the "or equal to" portions appears to be a specification 75bf215546Sopenharmony_ci * bug. In all other areas, the specification appears to indicate that 76bf215546Sopenharmony_ci * the number of workgroups can match the MAX_COMPUTE_WORK_GROUP_COUNT 77bf215546Sopenharmony_ci * value. For example, under DispatchComputeIndirect: 78bf215546Sopenharmony_ci * 79bf215546Sopenharmony_ci * "If any of num_groups_x, num_groups_y or num_groups_z is greater than 80bf215546Sopenharmony_ci * the value of MAX_COMPUTE_WORK_GROUP_COUNT for the corresponding 81bf215546Sopenharmony_ci * dimension then the results are undefined." 82bf215546Sopenharmony_ci * 83bf215546Sopenharmony_ci * Additionally, the OpenGLES 3.1 specification does not contain "or 84bf215546Sopenharmony_ci * equal to" as an error condition. 85bf215546Sopenharmony_ci */ 86bf215546Sopenharmony_ci if (info->grid[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { 87bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 88bf215546Sopenharmony_ci "glDispatchCompute(num_groups_%c)", 'x' + i); 89bf215546Sopenharmony_ci return GL_FALSE; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci } 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 94bf215546Sopenharmony_ci * 95bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated by DispatchCompute if the active 96bf215546Sopenharmony_ci * program for the compute shader stage has a variable work group size." 97bf215546Sopenharmony_ci */ 98bf215546Sopenharmony_ci struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 99bf215546Sopenharmony_ci if (prog->info.workgroup_size_variable) { 100bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 101bf215546Sopenharmony_ci "glDispatchCompute(variable work group size forbidden)"); 102bf215546Sopenharmony_ci return GL_FALSE; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci return GL_TRUE; 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cistatic bool 109bf215546Sopenharmony_civalidate_DispatchComputeGroupSizeARB(struct gl_context *ctx, 110bf215546Sopenharmony_ci struct pipe_grid_info *info) 111bf215546Sopenharmony_ci{ 112bf215546Sopenharmony_ci if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB")) 113bf215546Sopenharmony_ci return GL_FALSE; 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 116bf215546Sopenharmony_ci * 117bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated by 118bf215546Sopenharmony_ci * DispatchComputeGroupSizeARB if the active program for the compute 119bf215546Sopenharmony_ci * shader stage has a fixed work group size." 120bf215546Sopenharmony_ci */ 121bf215546Sopenharmony_ci struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 122bf215546Sopenharmony_ci if (!prog->info.workgroup_size_variable) { 123bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 124bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(fixed work group size " 125bf215546Sopenharmony_ci "forbidden)"); 126bf215546Sopenharmony_ci return GL_FALSE; 127bf215546Sopenharmony_ci } 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 130bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 131bf215546Sopenharmony_ci * 132bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated if any of num_groups_x, 133bf215546Sopenharmony_ci * num_groups_y and num_groups_z are greater than or equal to the 134bf215546Sopenharmony_ci * maximum work group count for the corresponding dimension." 135bf215546Sopenharmony_ci */ 136bf215546Sopenharmony_ci if (info->grid[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { 137bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 138bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i); 139bf215546Sopenharmony_ci return GL_FALSE; 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 143bf215546Sopenharmony_ci * 144bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if 145bf215546Sopenharmony_ci * any of <group_size_x>, <group_size_y>, or <group_size_z> is less than 146bf215546Sopenharmony_ci * or equal to zero or greater than the maximum local work group size 147bf215546Sopenharmony_ci * for compute shaders with variable group size 148bf215546Sopenharmony_ci * (MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB) in the corresponding 149bf215546Sopenharmony_ci * dimension." 150bf215546Sopenharmony_ci * 151bf215546Sopenharmony_ci * However, the "less than" is a spec bug because they are declared as 152bf215546Sopenharmony_ci * unsigned integers. 153bf215546Sopenharmony_ci */ 154bf215546Sopenharmony_ci if (info->block[i] == 0 || 155bf215546Sopenharmony_ci info->block[i] > ctx->Const.MaxComputeVariableGroupSize[i]) { 156bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 157bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i); 158bf215546Sopenharmony_ci return GL_FALSE; 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci } 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 163bf215546Sopenharmony_ci * 164bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if 165bf215546Sopenharmony_ci * the product of <group_size_x>, <group_size_y>, and <group_size_z> exceeds 166bf215546Sopenharmony_ci * the implementation-dependent maximum local work group invocation count 167bf215546Sopenharmony_ci * for compute shaders with variable group size 168bf215546Sopenharmony_ci * (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)." 169bf215546Sopenharmony_ci */ 170bf215546Sopenharmony_ci uint64_t total_invocations = info->block[0] * info->block[1]; 171bf215546Sopenharmony_ci if (total_invocations <= UINT32_MAX) { 172bf215546Sopenharmony_ci /* Only bother multiplying the third value if total still fits in 173bf215546Sopenharmony_ci * 32-bit, since MaxComputeVariableGroupInvocations is also 32-bit. 174bf215546Sopenharmony_ci */ 175bf215546Sopenharmony_ci total_invocations *= info->block[2]; 176bf215546Sopenharmony_ci } 177bf215546Sopenharmony_ci if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) { 178bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 179bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(product of local_sizes " 180bf215546Sopenharmony_ci "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB " 181bf215546Sopenharmony_ci "(%u * %u * %u > %u))", 182bf215546Sopenharmony_ci info->block[0], info->block[1], info->block[2], 183bf215546Sopenharmony_ci ctx->Const.MaxComputeVariableGroupInvocations); 184bf215546Sopenharmony_ci return GL_FALSE; 185bf215546Sopenharmony_ci } 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci /* The NV_compute_shader_derivatives spec says: 188bf215546Sopenharmony_ci * 189bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if 190bf215546Sopenharmony_ci * the active program for the compute shader stage has a compute shader 191bf215546Sopenharmony_ci * using the "derivative_group_quadsNV" layout qualifier and 192bf215546Sopenharmony_ci * <group_size_x> or <group_size_y> is not a multiple of two. 193bf215546Sopenharmony_ci * 194bf215546Sopenharmony_ci * An INVALID_VALUE error is generated by DispatchComputeGroupSizeARB if 195bf215546Sopenharmony_ci * the active program for the compute shader stage has a compute shader 196bf215546Sopenharmony_ci * using the "derivative_group_linearNV" layout qualifier and the product 197bf215546Sopenharmony_ci * of <group_size_x>, <group_size_y>, and <group_size_z> is not a multiple 198bf215546Sopenharmony_ci * of four." 199bf215546Sopenharmony_ci */ 200bf215546Sopenharmony_ci if (prog->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS && 201bf215546Sopenharmony_ci ((info->block[0] & 1) || (info->block[1] & 1))) { 202bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 203bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(derivative_group_quadsNV " 204bf215546Sopenharmony_ci "requires group_size_x (%d) and group_size_y (%d) to be " 205bf215546Sopenharmony_ci "divisble by 2)", info->block[0], info->block[1]); 206bf215546Sopenharmony_ci return GL_FALSE; 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci if (prog->info.cs.derivative_group == DERIVATIVE_GROUP_LINEAR && 210bf215546Sopenharmony_ci total_invocations & 3) { 211bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 212bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(derivative_group_linearNV " 213bf215546Sopenharmony_ci "requires product of group sizes (%"PRIu64") to be divisible " 214bf215546Sopenharmony_ci "by 4)", total_invocations); 215bf215546Sopenharmony_ci return GL_FALSE; 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci return GL_TRUE; 219bf215546Sopenharmony_ci} 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_cistatic bool 222bf215546Sopenharmony_civalid_dispatch_indirect(struct gl_context *ctx, GLintptr indirect) 223bf215546Sopenharmony_ci{ 224bf215546Sopenharmony_ci GLsizei size = 3 * sizeof(GLuint); 225bf215546Sopenharmony_ci const uint64_t end = (uint64_t) indirect + size; 226bf215546Sopenharmony_ci const char *name = "glDispatchComputeIndirect"; 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci if (!check_valid_to_compute(ctx, name)) 229bf215546Sopenharmony_ci return GL_FALSE; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders: 232bf215546Sopenharmony_ci * 233bf215546Sopenharmony_ci * "An INVALID_VALUE error is generated if indirect is negative or is not a 234bf215546Sopenharmony_ci * multiple of four." 235bf215546Sopenharmony_ci */ 236bf215546Sopenharmony_ci if (indirect & (sizeof(GLuint) - 1)) { 237bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 238bf215546Sopenharmony_ci "%s(indirect is not aligned)", name); 239bf215546Sopenharmony_ci return GL_FALSE; 240bf215546Sopenharmony_ci } 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci if (indirect < 0) { 243bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 244bf215546Sopenharmony_ci "%s(indirect is less than zero)", name); 245bf215546Sopenharmony_ci return GL_FALSE; 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci /* From the OpenGL 4.3 Core Specification, Chapter 19, Compute Shaders: 249bf215546Sopenharmony_ci * 250bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated if no buffer is bound to the 251bf215546Sopenharmony_ci * DRAW_INDIRECT_BUFFER binding, or if the command would source data 252bf215546Sopenharmony_ci * beyond the end of the buffer object." 253bf215546Sopenharmony_ci */ 254bf215546Sopenharmony_ci if (!ctx->DispatchIndirectBuffer) { 255bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 256bf215546Sopenharmony_ci "%s: no buffer bound to DISPATCH_INDIRECT_BUFFER", name); 257bf215546Sopenharmony_ci return GL_FALSE; 258bf215546Sopenharmony_ci } 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci if (_mesa_check_disallowed_mapping(ctx->DispatchIndirectBuffer)) { 261bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 262bf215546Sopenharmony_ci "%s(DISPATCH_INDIRECT_BUFFER is mapped)", name); 263bf215546Sopenharmony_ci return GL_FALSE; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci if (ctx->DispatchIndirectBuffer->Size < end) { 267bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 268bf215546Sopenharmony_ci "%s(DISPATCH_INDIRECT_BUFFER too small)", name); 269bf215546Sopenharmony_ci return GL_FALSE; 270bf215546Sopenharmony_ci } 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 273bf215546Sopenharmony_ci * 274bf215546Sopenharmony_ci * "An INVALID_OPERATION error is generated if the active program for the 275bf215546Sopenharmony_ci * compute shader stage has a variable work group size." 276bf215546Sopenharmony_ci */ 277bf215546Sopenharmony_ci struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 278bf215546Sopenharmony_ci if (prog->info.workgroup_size_variable) { 279bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 280bf215546Sopenharmony_ci "%s(variable work group size forbidden)", name); 281bf215546Sopenharmony_ci return GL_FALSE; 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci return GL_TRUE; 285bf215546Sopenharmony_ci} 286bf215546Sopenharmony_ci 287bf215546Sopenharmony_cistatic void 288bf215546Sopenharmony_ciprepare_compute(struct gl_context *ctx) 289bf215546Sopenharmony_ci{ 290bf215546Sopenharmony_ci struct st_context *st = st_context(ctx); 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci st_flush_bitmap_cache(st); 293bf215546Sopenharmony_ci st_invalidate_readpix_cache(st); 294bf215546Sopenharmony_ci 295bf215546Sopenharmony_ci if (ctx->NewState) 296bf215546Sopenharmony_ci _mesa_update_state(ctx); 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci if ((st->dirty | ctx->NewDriverState) & st->active_states & 299bf215546Sopenharmony_ci ST_PIPELINE_COMPUTE_STATE_MASK || 300bf215546Sopenharmony_ci st->compute_shader_may_be_dirty) 301bf215546Sopenharmony_ci st_validate_state(st, ST_PIPELINE_COMPUTE); 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cistatic ALWAYS_INLINE void 306bf215546Sopenharmony_cidispatch_compute(GLuint num_groups_x, GLuint num_groups_y, 307bf215546Sopenharmony_ci GLuint num_groups_z, bool no_error) 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 310bf215546Sopenharmony_ci struct pipe_grid_info info = { 0 }; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 315bf215546Sopenharmony_ci _mesa_debug(ctx, "glDispatchCompute(%d, %d, %d)\n", 316bf215546Sopenharmony_ci num_groups_x, num_groups_y, num_groups_z); 317bf215546Sopenharmony_ci 318bf215546Sopenharmony_ci info.grid[0] = num_groups_x; 319bf215546Sopenharmony_ci info.grid[1] = num_groups_y; 320bf215546Sopenharmony_ci info.grid[2] = num_groups_z; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci if (!no_error && !validate_DispatchCompute(ctx, &info)) 323bf215546Sopenharmony_ci return; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u) 326bf215546Sopenharmony_ci return; 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci struct gl_program *prog = 329bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 330bf215546Sopenharmony_ci info.block[0] = prog->info.workgroup_size[0]; 331bf215546Sopenharmony_ci info.block[1] = prog->info.workgroup_size[1]; 332bf215546Sopenharmony_ci info.block[2] = prog->info.workgroup_size[2]; 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci prepare_compute(ctx); 335bf215546Sopenharmony_ci ctx->pipe->launch_grid(ctx->pipe, &info); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 338bf215546Sopenharmony_ci _mesa_flush(ctx); 339bf215546Sopenharmony_ci} 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_civoid GLAPIENTRY 342bf215546Sopenharmony_ci_mesa_DispatchCompute_no_error(GLuint num_groups_x, GLuint num_groups_y, 343bf215546Sopenharmony_ci GLuint num_groups_z) 344bf215546Sopenharmony_ci{ 345bf215546Sopenharmony_ci dispatch_compute(num_groups_x, num_groups_y, num_groups_z, true); 346bf215546Sopenharmony_ci} 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_civoid GLAPIENTRY 349bf215546Sopenharmony_ci_mesa_DispatchCompute(GLuint num_groups_x, 350bf215546Sopenharmony_ci GLuint num_groups_y, 351bf215546Sopenharmony_ci GLuint num_groups_z) 352bf215546Sopenharmony_ci{ 353bf215546Sopenharmony_ci dispatch_compute(num_groups_x, num_groups_y, num_groups_z, false); 354bf215546Sopenharmony_ci} 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_cistatic ALWAYS_INLINE void 357bf215546Sopenharmony_cidispatch_compute_indirect(GLintptr indirect, bool no_error) 358bf215546Sopenharmony_ci{ 359bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 362bf215546Sopenharmony_ci 363bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 364bf215546Sopenharmony_ci _mesa_debug(ctx, "glDispatchComputeIndirect(%ld)\n", (long) indirect); 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_ci if (!no_error && !valid_dispatch_indirect(ctx, indirect)) 367bf215546Sopenharmony_ci return; 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_ci struct pipe_grid_info info = { 0 }; 370bf215546Sopenharmony_ci info.indirect_offset = indirect; 371bf215546Sopenharmony_ci info.indirect = ctx->DispatchIndirectBuffer->buffer; 372bf215546Sopenharmony_ci 373bf215546Sopenharmony_ci struct gl_program *prog = 374bf215546Sopenharmony_ci ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; 375bf215546Sopenharmony_ci info.block[0] = prog->info.workgroup_size[0]; 376bf215546Sopenharmony_ci info.block[1] = prog->info.workgroup_size[1]; 377bf215546Sopenharmony_ci info.block[2] = prog->info.workgroup_size[2]; 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci prepare_compute(ctx); 380bf215546Sopenharmony_ci ctx->pipe->launch_grid(ctx->pipe, &info); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 383bf215546Sopenharmony_ci _mesa_flush(ctx); 384bf215546Sopenharmony_ci} 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ciextern void GLAPIENTRY 387bf215546Sopenharmony_ci_mesa_DispatchComputeIndirect_no_error(GLintptr indirect) 388bf215546Sopenharmony_ci{ 389bf215546Sopenharmony_ci dispatch_compute_indirect(indirect, true); 390bf215546Sopenharmony_ci} 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ciextern void GLAPIENTRY 393bf215546Sopenharmony_ci_mesa_DispatchComputeIndirect(GLintptr indirect) 394bf215546Sopenharmony_ci{ 395bf215546Sopenharmony_ci dispatch_compute_indirect(indirect, false); 396bf215546Sopenharmony_ci} 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_cistatic ALWAYS_INLINE void 399bf215546Sopenharmony_cidispatch_compute_group_size(GLuint num_groups_x, GLuint num_groups_y, 400bf215546Sopenharmony_ci GLuint num_groups_z, GLuint group_size_x, 401bf215546Sopenharmony_ci GLuint group_size_y, GLuint group_size_z, 402bf215546Sopenharmony_ci bool no_error) 403bf215546Sopenharmony_ci{ 404bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 405bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 408bf215546Sopenharmony_ci _mesa_debug(ctx, 409bf215546Sopenharmony_ci "glDispatchComputeGroupSizeARB(%d, %d, %d, %d, %d, %d)\n", 410bf215546Sopenharmony_ci num_groups_x, num_groups_y, num_groups_z, 411bf215546Sopenharmony_ci group_size_x, group_size_y, group_size_z); 412bf215546Sopenharmony_ci 413bf215546Sopenharmony_ci struct pipe_grid_info info = { 0 }; 414bf215546Sopenharmony_ci info.grid[0] = num_groups_x; 415bf215546Sopenharmony_ci info.grid[1] = num_groups_y; 416bf215546Sopenharmony_ci info.grid[2] = num_groups_z; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci info.block[0] = group_size_x; 419bf215546Sopenharmony_ci info.block[1] = group_size_y; 420bf215546Sopenharmony_ci info.block[2] = group_size_z; 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci if (!no_error && 423bf215546Sopenharmony_ci !validate_DispatchComputeGroupSizeARB(ctx, &info)) 424bf215546Sopenharmony_ci return; 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u) 427bf215546Sopenharmony_ci return; 428bf215546Sopenharmony_ci 429bf215546Sopenharmony_ci prepare_compute(ctx); 430bf215546Sopenharmony_ci ctx->pipe->launch_grid(ctx->pipe, &info); 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) 433bf215546Sopenharmony_ci _mesa_flush(ctx); 434bf215546Sopenharmony_ci} 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_civoid GLAPIENTRY 437bf215546Sopenharmony_ci_mesa_DispatchComputeGroupSizeARB_no_error(GLuint num_groups_x, 438bf215546Sopenharmony_ci GLuint num_groups_y, 439bf215546Sopenharmony_ci GLuint num_groups_z, 440bf215546Sopenharmony_ci GLuint group_size_x, 441bf215546Sopenharmony_ci GLuint group_size_y, 442bf215546Sopenharmony_ci GLuint group_size_z) 443bf215546Sopenharmony_ci{ 444bf215546Sopenharmony_ci dispatch_compute_group_size(num_groups_x, num_groups_y, num_groups_z, 445bf215546Sopenharmony_ci group_size_x, group_size_y, group_size_z, 446bf215546Sopenharmony_ci true); 447bf215546Sopenharmony_ci} 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_civoid GLAPIENTRY 450bf215546Sopenharmony_ci_mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, 451bf215546Sopenharmony_ci GLuint num_groups_z, GLuint group_size_x, 452bf215546Sopenharmony_ci GLuint group_size_y, GLuint group_size_z) 453bf215546Sopenharmony_ci{ 454bf215546Sopenharmony_ci dispatch_compute_group_size(num_groups_x, num_groups_y, num_groups_z, 455bf215546Sopenharmony_ci group_size_x, group_size_y, group_size_z, 456bf215546Sopenharmony_ci false); 457bf215546Sopenharmony_ci} 458