diff options
author | Samuel Pitoiset <[email protected]> | 2016-09-07 21:52:08 +0200 |
---|---|---|
committer | Samuel Pitoiset <[email protected]> | 2016-10-07 00:18:57 +0200 |
commit | 45ab63c0cb274b20a7ae1f390b123e13a5b46c98 (patch) | |
tree | 9961670819d37c96c6da45262ab302bf4f19cb64 /src/mesa/main/api_validate.c | |
parent | a063f3084acfaf9a63ab8af004d94c592b19b8a0 (diff) |
mesa/main: add support for ARB_compute_variable_groups_size
v5: - replace fixed_local_size by !LocalSizeVariable (Nicolai)
v4: - slightly indent spec quotes (Nicolai)
- drop useless _mesa_has_compute_shaders() check (Nicolai)
- move the fixed local size outside of the loop (Nicolai)
- add missing check for invalid use of work group count
v2: - update formatting spec quotations (Ian)
- move the total_invocations check outside of the loop (Ian)
Signed-off-by: Samuel Pitoiset <[email protected]>
Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/mesa/main/api_validate.c')
-rw-r--r-- | src/mesa/main/api_validate.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 05691d25da0..c3c5a696928 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -1285,6 +1285,7 @@ GLboolean _mesa_validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups) { + struct gl_shader_program *prog; int i; FLUSH_CURRENT(ctx, 0); @@ -1317,6 +1318,101 @@ _mesa_validate_DispatchCompute(struct gl_context *ctx, } } + /* 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." + */ + prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (prog->Comp.LocalSizeVariable) { + _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) +{ + struct gl_shader_program *prog; + 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." + */ + prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (!prog->Comp.LocalSizeVariable) { + _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; } @@ -1326,6 +1422,7 @@ valid_dispatch_indirect(struct gl_context *ctx, GLsizei size, const char *name) { const uint64_t end = (uint64_t) indirect + size; + struct gl_shader_program *prog; if (!check_valid_to_compute(ctx, name)) return GL_FALSE; @@ -1371,6 +1468,18 @@ valid_dispatch_indirect(struct gl_context *ctx, 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." + */ + prog = ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + if (prog->Comp.LocalSizeVariable) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(variable work group size forbidden)", name); + return GL_FALSE; + } + return GL_TRUE; } |