summaryrefslogtreecommitdiffstats
path: root/src/mesa
diff options
context:
space:
mode:
authorSamuel Pitoiset <[email protected]>2016-09-07 21:52:08 +0200
committerSamuel Pitoiset <[email protected]>2016-10-07 00:18:57 +0200
commit45ab63c0cb274b20a7ae1f390b123e13a5b46c98 (patch)
tree9961670819d37c96c6da45262ab302bf4f19cb64 /src/mesa
parenta063f3084acfaf9a63ab8af004d94c592b19b8a0 (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')
-rw-r--r--src/mesa/main/api_validate.c109
-rw-r--r--src/mesa/main/api_validate.h4
-rw-r--r--src/mesa/main/compute.c17
-rw-r--r--src/mesa/main/context.c6
-rw-r--r--src/mesa/main/dd.h9
-rw-r--r--src/mesa/main/extensions_table.h1
-rw-r--r--src/mesa/main/get.c10
-rw-r--r--src/mesa/main/get_hash_params.py3
-rw-r--r--src/mesa/main/mtypes.h24
-rw-r--r--src/mesa/main/shaderapi.c1
-rw-r--r--src/mesa/main/shaderobj.c2
11 files changed, 185 insertions, 1 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;
}
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index 2eba834c50d..e94f02e4ba5 100644
--- a/src/mesa/main/api_validate.h
+++ b/src/mesa/main/api_validate.h
@@ -132,5 +132,9 @@ 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
diff --git a/src/mesa/main/compute.c b/src/mesa/main/compute.c
index b052bae7e91..bb6253906bc 100644
--- a/src/mesa/main/compute.c
+++ b/src/mesa/main/compute.c
@@ -66,5 +66,22 @@ _mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y,
GLuint num_groups_z, GLuint group_size_x,
GLuint group_size_y, GLuint group_size_z)
{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z };
+ const GLuint group_size[3] = { group_size_x, group_size_y, group_size_z };
+
+ if (MESA_VERBOSE & VERBOSE_API)
+ _mesa_debug(ctx,
+ "glDispatchComputeGroupSizeARB(%d, %d, %d, %d, %d, %d)\n",
+ 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))
+ return;
+
+ if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u)
+ return;
+ ctx->Driver.DispatchComputeGroupSize(ctx, num_groups, group_size);
}
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 697b5186fb8..47fd4a0919f 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -721,6 +721,12 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api)
consts->MaxTessPatchComponents = MAX_TESS_PATCH_COMPONENTS;
consts->MaxTessControlTotalOutputComponents = MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS;
consts->PrimitiveRestartForPatches = false;
+
+ /** GL_ARB_compute_variable_group_size */
+ consts->MaxComputeVariableGroupSize[0] = 512;
+ consts->MaxComputeVariableGroupSize[1] = 512;
+ consts->MaxComputeVariableGroupSize[2] = 64;
+ consts->MaxComputeVariableGroupInvocations = 512;
}
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 257dc103817..7f5327186ff 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -978,6 +978,15 @@ struct dd_function_table {
/*@}*/
/**
+ * \name GL_ARB_compute_variable_group_size interface
+ */
+ /*@{*/
+ void (*DispatchComputeGroupSize)(struct gl_context *ctx,
+ const GLuint *num_groups,
+ const GLuint *group_size);
+ /*@}*/
+
+ /**
* Query information about memory. Device memory is e.g. VRAM. Staging
* memory is e.g. GART. All sizes are in kilobytes.
*/
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index e7669bbd0fc..b6286fc6d59 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -42,6 +42,7 @@ EXT(ARB_clip_control , ARB_clip_control
EXT(ARB_color_buffer_float , ARB_color_buffer_float , GLL, GLC, x , x , 2004)
EXT(ARB_compressed_texture_pixel_storage , dummy_true , GLL, GLC, x , x , 2011)
EXT(ARB_compute_shader , ARB_compute_shader , GLL, GLC, x , x , 2012)
+EXT(ARB_compute_variable_group_size , ARB_compute_variable_group_size , GLL, GLC, x , x , 2013)
EXT(ARB_conditional_render_inverted , ARB_conditional_render_inverted , GLL, GLC, x , x , 2014)
EXT(ARB_conservative_depth , ARB_conservative_depth , GLL, GLC, x , x , 2011)
EXT(ARB_copy_buffer , dummy_true , GLL, GLC, x , x , 2008)
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 64a4b0e6ccf..bd85befa125 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -490,6 +490,7 @@ EXTRA_EXT(ARB_cull_distance);
EXTRA_EXT(EXT_window_rectangles);
EXTRA_EXT(KHR_blend_equation_advanced_coherent);
EXTRA_EXT(OES_primitive_bounding_box);
+EXTRA_EXT(ARB_compute_variable_group_size);
static const int
extra_ARB_color_buffer_float_or_glcore[] = {
@@ -2293,6 +2294,15 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
goto invalid_value;
v->value_int = ctx->Const.MaxComputeWorkGroupSize[index];
return TYPE_INT;
+
+ /* ARB_compute_variable_group_size */
+ case GL_MAX_COMPUTE_VARIABLE_GROUP_SIZE_ARB:
+ if (!ctx->Extensions.ARB_compute_variable_group_size)
+ goto invalid_enum;
+ if (index >= 3)
+ goto invalid_value;
+ v->value_int = ctx->Const.MaxComputeVariableGroupSize[index];
+ return TYPE_INT;
}
invalid_enum:
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 7520a39b09a..6849b5b7d58 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -942,6 +942,9 @@ descriptor=[
# GL_ARB_cull_distance
[ "MAX_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ],
[ "MAX_COMBINED_CLIP_AND_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ],
+
+# GL_ARB_compute_variable_group_size
+ [ "MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB", "CONTEXT_INT(Const.MaxComputeVariableGroupInvocations), extra_ARB_compute_variable_group_size" ],
]},
# Enums restricted to OpenGL Core profile
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d494872eef9..ab9839c7516 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2078,6 +2078,11 @@ struct gl_compute_program
* Size of shared variables accessed by the compute shader.
*/
unsigned SharedSize;
+
+ /**
+ * Whether a variable work group size has been specified.
+ */
+ bool LocalSizeVariable;
};
@@ -2340,7 +2345,8 @@ struct gl_shader_info
GLbitfield BlendSupport;
/**
- * Compute shader state from ARB_compute_shader layout qualifiers.
+ * Compute shader state from ARB_compute_shader and
+ * ARB_compute_variable_group_size layout qualifiers.
*/
struct {
/**
@@ -2348,6 +2354,12 @@ struct gl_shader_info
* it's not set in this shader.
*/
unsigned LocalSize[3];
+
+ /**
+ * Whether a variable work group size has been specified as defined by
+ * ARB_compute_variable_group_size.
+ */
+ bool LocalSizeVariable;
} Comp;
};
@@ -2826,6 +2838,11 @@ struct gl_shader_program
* Size of shared variables accessed by the compute shader.
*/
unsigned SharedSize;
+
+ /**
+ * Whether a variable work group size has been specified.
+ */
+ bool LocalSizeVariable;
} Comp;
/* post-link info: */
@@ -3783,6 +3800,10 @@ struct gl_constants
GLuint MaxComputeWorkGroupInvocations;
GLuint MaxComputeSharedMemorySize;
+ /** GL_ARB_compute_variable_group_size */
+ GLuint MaxComputeVariableGroupSize[3]; /* Array of x, y, z dimensions */
+ GLuint MaxComputeVariableGroupInvocations;
+
/** GL_ARB_gpu_shader5 */
GLfloat MinFragmentInterpolationOffset;
GLfloat MaxFragmentInterpolationOffset;
@@ -3834,6 +3855,7 @@ struct gl_extensions
GLboolean ARB_clip_control;
GLboolean ARB_color_buffer_float;
GLboolean ARB_compute_shader;
+ GLboolean ARB_compute_variable_group_size;
GLboolean ARB_conditional_render_inverted;
GLboolean ARB_conservative_depth;
GLboolean ARB_copy_image;
diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c
index 1af1c3f5794..c40bb2d69a7 100644
--- a/src/mesa/main/shaderapi.c
+++ b/src/mesa/main/shaderapi.c
@@ -2212,6 +2212,7 @@ _mesa_copy_linked_program_data(gl_shader_stage type,
for (i = 0; i < 3; i++)
dst_cp->LocalSize[i] = src->Comp.LocalSize[i];
dst_cp->SharedSize = src->Comp.SharedSize;
+ dst_cp->LocalSizeVariable = src->Comp.LocalSizeVariable;
break;
}
default:
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index 350b677911e..136ac7b46a6 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -262,6 +262,8 @@ init_shader_program(struct gl_shader_program *prog)
prog->Geom.UsesEndPrimitive = false;
prog->Geom.UsesStreams = false;
+ prog->Comp.LocalSizeVariable = false;
+
prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS;
exec_list_make_empty(&prog->EmptyUniformLocations);