summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/api_validate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main/api_validate.c')
-rw-r--r--src/mesa/main/api_validate.c109
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;
}