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