Mesa (main): zink: start adding C++ draw templates

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 20 00:37:34 UTC 2021


Module: Mesa
Branch: main
Commit: cfcc2ff03fdda14c218c96c658eb81642df3ad44
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=cfcc2ff03fdda14c218c96c658eb81642df3ad44

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Tue May 11 14:48:56 2021 -0400

zink: start adding C++ draw templates

templated draw functions enable moving some checks/calculations/code
into template conditionals, which are resolved in advance of the draw call,
reducing draw overhead

Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11964>

---

 src/gallium/drivers/zink/meson.build               |  2 +-
 src/gallium/drivers/zink/zink_context.c            |  7 ++-
 src/gallium/drivers/zink/zink_context.h            | 36 ++++++++------
 .../drivers/zink/{zink_draw.c => zink_draw.cpp}    | 55 ++++++++++++++++++----
 src/gallium/drivers/zink/zink_inlines.h            | 12 +++++
 src/gallium/drivers/zink/zink_program.c            |  1 +
 6 files changed, 88 insertions(+), 25 deletions(-)

diff --git a/src/gallium/drivers/zink/meson.build b/src/gallium/drivers/zink/meson.build
index f3fbd5cbdac..28aae9cdfc4 100644
--- a/src/gallium/drivers/zink/meson.build
+++ b/src/gallium/drivers/zink/meson.build
@@ -29,7 +29,7 @@ files_libzink = files(
   'zink_context.c',
   'zink_descriptors.c',
   'zink_descriptors_lazy.c',
-  'zink_draw.c',
+  'zink_draw.cpp',
   'zink_fence.c',
   'zink_format.c',
   'zink_framebuffer.c',
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 9b8acbea4bd..f7e0c38249b 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -36,6 +36,7 @@
 #include "zink_screen.h"
 #include "zink_state.h"
 #include "zink_surface.h"
+#include "zink_inlines.h"
 
 #include "util/u_blitter.h"
 #include "util/u_debug.h"
@@ -3420,6 +3421,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->compute_pipeline_state.dirty = true;
    ctx->fb_changed = ctx->rp_changed = true;
 
+   zink_init_draw_functions(ctx);
+
    ctx->base.screen = pscreen;
    ctx->base.priv = priv;
 
@@ -3463,7 +3466,6 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    ctx->base.clear_render_target = zink_clear_render_target;
    ctx->base.clear_depth_stencil = zink_clear_depth_stencil;
 
-   ctx->base.draw_vbo = zink_draw_vbo;
    ctx->base.launch_grid = zink_launch_grid;
    ctx->base.fence_server_sync = zink_fence_server_sync;
    ctx->base.flush = zink_flush;
@@ -3567,6 +3569,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    }
    p_atomic_inc(&screen->base.num_contexts);
 
+   zink_select_draw_vbo(ctx);
+
    if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) {
       return &ctx->base;
    }
@@ -3579,6 +3583,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
    if (tc && (struct zink_context*)tc != ctx) {
       tc->bytes_mapped_limit = screen->total_mem / 4;
       ctx->base.set_context_param = zink_set_context_param;
+      ctx->multidraw = screen->info.have_EXT_multi_draw;
    }
 
    return (struct pipe_context*)tc;
diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h
index ea6d4fa2059..3c177046785 100644
--- a/src/gallium/drivers/zink/zink_context.h
+++ b/src/gallium/drivers/zink/zink_context.h
@@ -136,6 +136,19 @@ struct zink_descriptor_surface {
    bool is_buffer;
 };
 
+typedef void (*pipe_draw_vbo_func)(struct pipe_context *pipe,
+                                   const struct pipe_draw_info *info,
+                                   unsigned drawid_offset,
+                                   const struct pipe_draw_indirect_info *indirect,
+                                   const struct pipe_draw_start_count_bias *draws,
+                                   unsigned num_draws);
+
+
+typedef enum {
+   ZINK_NO_MULTIDRAW,
+   ZINK_MULTIDRAW,
+} zink_multidraw;
+
 struct zink_context {
    struct pipe_context base;
    struct threaded_context *tc;
@@ -143,6 +156,9 @@ struct zink_context {
    struct slab_child_pool transfer_pool_unsync;
    struct blitter_context *blitter;
 
+   zink_multidraw multidraw;
+   pipe_draw_vbo_func draw_vbo[2]; //multidraw
+
    struct pipe_device_reset_callback reset;
 
    uint32_t curr_batch; //the current batch id
@@ -362,6 +378,11 @@ zink_pipeline_flags_from_pipe_stage(enum pipe_shader_type pstage)
    }
 }
 
+void
+zink_init_draw_functions(struct zink_context *ctx);
+
+void
+zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info);
 #ifdef __cplusplus
 }
 #endif
@@ -408,17 +429,6 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res);
 void
 zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res);
 
-void
-zink_draw_vbo(struct pipe_context *pctx,
-              const struct pipe_draw_info *dinfo,
-              unsigned drawid_offset,
-              const struct pipe_draw_indirect_info *indirect,
-              const struct pipe_draw_start_count_bias *draws,
-              unsigned num_draws);
-
-void
-zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info);
-
 void
 zink_copy_buffer(struct zink_context *ctx, struct zink_batch *batch, struct zink_resource *dst, struct zink_resource *src,
                  unsigned dst_offset, unsigned src_offset, unsigned size);
@@ -448,8 +458,4 @@ zink_buffer_view_reference(struct zink_screen *screen,
 }
 #endif
 
-#ifdef __cplusplus
-}
-#endif
-
 #endif
diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.cpp
similarity index 95%
rename from src/gallium/drivers/zink/zink_draw.c
rename to src/gallium/drivers/zink/zink_draw.cpp
index fc0c300fdec..f5f44187259 100644
--- a/src/gallium/drivers/zink/zink_draw.c
+++ b/src/gallium/drivers/zink/zink_draw.cpp
@@ -270,6 +270,7 @@ draw_indexed_need_index_buffer_unref(struct zink_context *ctx,
    }
 }
 
+template <zink_multidraw HAS_MULTIDRAW>
 ALWAYS_INLINE static void
 draw_indexed(struct zink_context *ctx,
              const struct pipe_draw_info *dinfo,
@@ -290,12 +291,12 @@ draw_indexed(struct zink_context *ctx,
    } else {
       if (needs_drawid)
          update_drawid(ctx, draw_id);
-      if (zink_screen(ctx->base.screen)->info.have_EXT_multi_draw)
+      if (HAS_MULTIDRAW) {
          zink_screen(ctx->base.screen)->vk.CmdDrawMultiIndexedEXT(cmdbuf, num_draws, (const VkMultiDrawIndexedInfoEXT*)draws,
                                                                    dinfo->instance_count,
                                                                    dinfo->start_instance, sizeof(struct pipe_draw_start_count_bias),
                                                                    dinfo->index_bias_varies ? NULL : &draws[0].index_bias);
-      else {
+      } else {
          for (unsigned i = 0; i < num_draws; i++)
             vkCmdDrawIndexed(cmdbuf,
                draws[i].count, dinfo->instance_count,
@@ -304,6 +305,7 @@ draw_indexed(struct zink_context *ctx,
    }
 }
 
+template <zink_multidraw HAS_MULTIDRAW>
 ALWAYS_INLINE static void
 draw(struct zink_context *ctx,
      const struct pipe_draw_info *dinfo,
@@ -322,7 +324,7 @@ draw(struct zink_context *ctx,
    } else {
       if (needs_drawid)
          update_drawid(ctx, draw_id);
-      if (zink_screen(ctx->base.screen)->info.have_EXT_multi_draw)
+      if (HAS_MULTIDRAW)
          zink_screen(ctx->base.screen)->vk.CmdDrawMultiEXT(cmdbuf, num_draws, (const VkMultiDrawInfoEXT*)draws,
                                                             dinfo->instance_count, dinfo->start_instance,
                                                             sizeof(struct pipe_draw_start_count_bias));
@@ -392,6 +394,7 @@ update_barriers(struct zink_context *ctx, bool is_compute)
    }
 }
 
+template <zink_multidraw HAS_MULTIDRAW>
 void
 zink_draw_vbo(struct pipe_context *pctx,
               const struct pipe_draw_info *dinfo,
@@ -422,8 +425,8 @@ zink_draw_vbo(struct pipe_context *pctx,
    if (!dindirect || !dindirect->buffer)
       ctx->drawid_broken = BITSET_TEST(ctx->gfx_stages[PIPE_SHADER_VERTEX]->nir->info.system_values_read, SYSTEM_VALUE_DRAW_ID) &&
                            (drawid_offset != 0 ||
-                           (!screen->info.have_EXT_multi_draw && num_draws > 1) ||
-                           (screen->info.have_EXT_multi_draw && num_draws > 1 && !dinfo->increment_draw_id));
+                           (!HAS_MULTIDRAW && num_draws > 1) ||
+                           (HAS_MULTIDRAW && num_draws > 1 && !dinfo->increment_draw_id));
    if (drawid_broken != ctx->drawid_broken)
       ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_VERTEX);
    ctx->gfx_pipeline_state.vertices_per_patch = dinfo->vertices_per_patch;
@@ -692,7 +695,7 @@ zink_draw_vbo(struct pipe_context *pctx,
          if (need_index_buffer_unref)
             draw_indexed_need_index_buffer_unref(ctx, dinfo, draws, num_draws, draw_id, needs_drawid);
          else
-            draw_indexed(ctx, dinfo, draws, num_draws, draw_id, needs_drawid);
+            draw_indexed<HAS_MULTIDRAW>(ctx, dinfo, draws, num_draws, draw_id, needs_drawid);
       }
    } else {
       if (so_target && screen->info.tf_props.transformFeedbackDraw) {
@@ -718,7 +721,7 @@ zink_draw_vbo(struct pipe_context *pctx,
          } else
             vkCmdDrawIndirect(batch->state->cmdbuf, indirect->obj->buffer, dindirect->offset, dindirect->draw_count, dindirect->stride);
       } else {
-         draw(ctx, dinfo, draws, num_draws, draw_id, needs_drawid);
+         draw<HAS_MULTIDRAW>(ctx, dinfo, draws, num_draws, draw_id, needs_drawid);
       }
    }
 
@@ -764,7 +767,7 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
       vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
    ctx->pipeline_changed[1] = false;
 
-   if (BITSET_TEST(ctx->curr_compute->shader->nir->info.system_values_read, SYSTEM_VALUE_WORK_DIM))
+   if (BITSET_TEST(ctx->compute_stage->nir->info.system_values_read, SYSTEM_VALUE_WORK_DIM))
       vkCmdPushConstants(batch->state->cmdbuf, ctx->curr_compute->base.layout, VK_SHADER_STAGE_COMPUTE_BIT,
                          offsetof(struct zink_cs_push_constant, work_dim), sizeof(uint32_t),
                          &info->work_dim);
@@ -779,3 +782,39 @@ zink_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
    /* check memory usage and flush/stall as needed to avoid oom */
    zink_maybe_flush_or_stall(ctx);
 }
+
+template <zink_multidraw HAS_MULTIDRAW>
+static void
+init_multidraw_functions(struct zink_context *ctx)
+{
+   ctx->draw_vbo[HAS_MULTIDRAW] = zink_draw_vbo<HAS_MULTIDRAW>;
+}
+
+static void
+init_all_draw_functions(struct zink_context *ctx)
+{
+   init_multidraw_functions<ZINK_NO_MULTIDRAW>(ctx);
+   init_multidraw_functions<ZINK_MULTIDRAW>(ctx);
+}
+
+static void
+zink_invalid_draw_vbo(struct pipe_context *pipe,
+                      const struct pipe_draw_info *dinfo,
+                      unsigned drawid_offset,
+                      const struct pipe_draw_indirect_info *dindirect,
+                      const struct pipe_draw_start_count_bias *draws,
+                      unsigned num_draws)
+{
+   unreachable("vertex shader not bound");
+}
+
+extern "C"
+void
+zink_init_draw_functions(struct zink_context *ctx)
+{
+   init_all_draw_functions(ctx);
+   /* Bind a fake draw_vbo, so that draw_vbo isn't NULL, which would skip
+    * initialization of callbacks in upper layers (such as u_threaded_context).
+    */
+   ctx->base.draw_vbo = zink_invalid_draw_vbo;
+}
diff --git a/src/gallium/drivers/zink/zink_inlines.h b/src/gallium/drivers/zink/zink_inlines.h
new file mode 100644
index 00000000000..8c8c7d329d6
--- /dev/null
+++ b/src/gallium/drivers/zink/zink_inlines.h
@@ -0,0 +1,12 @@
+#ifndef ZINK_INLINES_H
+#define ZINK_INLINES_H
+
+/* these go here to avoid include hell */
+static inline void
+zink_select_draw_vbo(struct zink_context *ctx)
+{
+   ctx->base.draw_vbo = ctx->draw_vbo[ctx->multidraw];
+   assert(ctx->base.draw_vbo);
+}
+
+#endif
diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c
index 2d6f462b4fa..f9fbaaaeacc 100644
--- a/src/gallium/drivers/zink/zink_program.c
+++ b/src/gallium/drivers/zink/zink_program.c
@@ -30,6 +30,7 @@
 #include "zink_resource.h"
 #include "zink_screen.h"
 #include "zink_state.h"
+#include "zink_inlines.h"
 
 #include "util/hash_table.h"
 #include "util/set.h"



More information about the mesa-commit mailing list