Mesa (main): gallium: add PIPE_CAP_MULTI_DRAW_INDIRECT_PARTIAL_STRIDE
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Apr 21 02:57:26 UTC 2022
Module: Mesa
Branch: main
Commit: 0f28da9cd4779f705ebe18061e98e9e53be5c1ff
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0f28da9cd4779f705ebe18061e98e9e53be5c1ff
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Wed Apr 13 16:32:04 2022 -0400
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 at amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15963>
---
docs/gallium/screen.rst | 2 ++
src/gallium/auxiliary/util/u_screen.c | 2 ++
src/gallium/include/pipe/p_defines.h | 1 +
src/mesa/state_tracker/st_context.c | 2 ++
src/mesa/state_tracker/st_context.h | 1 +
src/mesa/state_tracker/st_draw.c | 24 ++++++++++++++++++++++++
6 files changed, 32 insertions(+)
diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst
index 266e54cf82e..274b16e2bf7 100644
--- a/docs/gallium/screen.rst
+++ b/docs/gallium/screen.rst
@@ -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
diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
index 617a9dbf38a..6ab60a639e7 100644
--- a/src/gallium/auxiliary/util/u_screen.c
+++ b/src/gallium/auxiliary/util/u_screen.c
@@ -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 */
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 582d61a538c..50e0404a1e9 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -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,
diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c
index b3a12d4a77e..a73cd0a0c6d 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -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 =
diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
index 4c8c838ad10..1498884b31e 100644
--- a/src/mesa/state_tracker/st_context.h
+++ b/src/mesa/state_tracker/st_context.h
@@ -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;
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index e121564d3be..cd0b8d6e8b2 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -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;
More information about the mesa-commit
mailing list