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 <samuel.pitoiset@gmail.com> Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
parent
a063f3084a
commit
45ab63c0cb
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -977,6 +977,15 @@ struct dd_function_table {
|
|||
void (*DispatchComputeIndirect)(struct gl_context *ctx, GLintptr indirect);
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* \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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue