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