mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2025-02-21 18:53:09 +00:00
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:
parent
ec12491620
commit
0f28da9cd4
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user