gallium: add PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE

GL spec states that the stride for indirect multidraws:
* cannot be negative
* can be zero
* must be a multiple of 4

some drivers can't support strides which are not a multiple of the
size of the indirect struct being used, however, so rewrite those to
direct draws

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15963>
This commit is contained in:
Mike Blumenkrantz 2022-04-13 16:32:04 -04:00 committed by Marge Bot
parent ec12491620
commit 0f28da9cd4
6 changed files with 32 additions and 0 deletions

View File

@ -248,6 +248,8 @@ The integer capabilities:
* ``PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS``: Whether the driver supports
taking the number of indirect draws from a separate parameter
buffer, see pipe_draw_indirect_info::indirect_draw_count.
* ``PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE``: Whether the driver supports
indirect draws with an arbitrary stride.
* ``PIPE_CAP_FS_FINE_DERIVATIVE``: Whether the fragment shader supports
the FINE versions of DDX/DDY.
* ``PIPE_CAP_VENDOR_ID``: The vendor ID of the underlying hardware. If it's

View File

@ -253,6 +253,8 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen,
case PIPE_CAP_FS_POINT_IS_SYSVAL:
case PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL:
return 0;
case PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE:
return 1;
case PIPE_CAP_SHADER_BUFFER_OFFSET_ALIGNMENT:
/* Enables GL_ARB_shader_storage_buffer_object */

View File

@ -859,6 +859,7 @@ enum pipe_cap
PIPE_CAP_SHADER_PACK_HALF_FLOAT,
PIPE_CAP_MULTI_DRAW_INDIRECT,
PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS,
PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE,
PIPE_CAP_FS_POSITION_IS_SYSVAL,
PIPE_CAP_FS_POINT_IS_SYSVAL,
PIPE_CAP_FS_FACE_IS_INTEGER_SYSVAL,

View File

@ -609,6 +609,8 @@ st_create_context_priv(struct gl_context *ctx, struct pipe_context *pipe,
screen->get_param(screen, PIPE_CAP_SHADER_PACK_HALF_FLOAT);
st->has_multi_draw_indirect =
screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT);
st->has_indirect_partial_stride =
screen->get_param(screen, PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE);
st->has_single_pipe_stat =
screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE);
st->has_indep_blend_func =

View File

@ -150,6 +150,7 @@ struct st_context
boolean has_shareable_shaders;
boolean has_half_float_packing;
boolean has_multi_draw_indirect;
boolean has_indirect_partial_stride;
boolean has_single_pipe_stat;
boolean has_indep_blend_func;
boolean needs_rgb_dst_alpha_override;

View File

@ -217,6 +217,21 @@ st_draw_gallium_multimode(struct gl_context *ctx,
}
}
static void
rewrite_partial_stride_indirect(struct st_context *st,
const struct pipe_draw_info *info,
const struct pipe_draw_indirect_info *indirect,
const struct pipe_draw_start_count_bias draw)
{
unsigned draw_count = 0;
struct u_indirect_params *new_draws = util_draw_indirect_read(st->pipe, info, indirect, &draw_count);
if (!new_draws)
return;
for (unsigned i = 0; i < draw_count; i++)
cso_draw_vbo(st->cso_context, &new_draws[i].info, i, NULL, new_draws[i].draw);
free(new_draws);
}
void
st_indirect_draw_vbo(struct gl_context *ctx,
GLuint mode,
@ -276,6 +291,15 @@ st_indirect_draw_vbo(struct gl_context *ctx,
} else {
indirect.draw_count = draw_count;
indirect.stride = stride;
if (!st->has_indirect_partial_stride && stride &&
(draw_count > 1 || indirect_draw_count)) {
/* DrawElementsIndirectCommand or DrawArraysIndirectCommand */
const size_t struct_size = info.index_size ? sizeof(uint32_t) * 5 : sizeof(uint32_t) * 4;
if (indirect.stride && indirect.stride < struct_size) {
rewrite_partial_stride_indirect(st, &info, &indirect, draw);
return;
}
}
if (indirect_draw_count) {
indirect.indirect_draw_count =
indirect_draw_count->buffer;