Mesa (master): util/primconvert: Handle indirect and multi-draw
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Sat Mar 27 19:47:57 UTC 2021
Module: Mesa
Branch: master
Commit: ea2c47390ad5a3c22154bbbad2233179913dda71
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=ea2c47390ad5a3c22154bbbad2233179913dda71
Author: Rob Clark <robdclark at chromium.org>
Date: Sun Mar 21 11:08:14 2021 -0700
util/primconvert: Handle indirect and multi-draw
Indirect handling was completely missing. And even though we have to
emulate multi-draw, this pushes it out of the fast/hot path in the
driver's draw_vbo()
Signed-off-by: Rob Clark <robdclark at chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9742>
---
src/gallium/auxiliary/indices/u_primconvert.c | 30 +++++++++++++++++++++++++-
src/gallium/auxiliary/indices/u_primconvert.h | 4 +++-
src/gallium/drivers/d3d12/d3d12_draw.cpp | 2 +-
src/gallium/drivers/etnaviv/etnaviv_context.c | 2 +-
src/gallium/drivers/freedreno/freedreno_draw.c | 11 +---------
src/gallium/drivers/panfrost/pan_context.c | 2 +-
src/gallium/drivers/v3d/v3dx_draw.c | 2 +-
src/gallium/drivers/vc4/vc4_draw.c | 2 +-
src/gallium/drivers/virgl/virgl_context.c | 2 +-
src/gallium/drivers/zink/zink_draw.c | 7 +-----
10 files changed, 40 insertions(+), 24 deletions(-)
diff --git a/src/gallium/auxiliary/indices/u_primconvert.c b/src/gallium/auxiliary/indices/u_primconvert.c
index e270ec495c9..084182451ca 100644
--- a/src/gallium/auxiliary/indices/u_primconvert.c
+++ b/src/gallium/auxiliary/indices/u_primconvert.c
@@ -44,6 +44,7 @@
#include "util/u_draw.h"
#include "util/u_inlines.h"
#include "util/u_memory.h"
+#include "util/u_prim.h"
#include "util/u_prim_restart.h"
#include "util/u_upload_mgr.h"
@@ -98,7 +99,9 @@ util_primconvert_save_rasterizer_state(struct primconvert_context *pc,
void
util_primconvert_draw_vbo(struct primconvert_context *pc,
const struct pipe_draw_info *info,
- const struct pipe_draw_start_count *draw)
+ const struct pipe_draw_indirect_info *indirect,
+ const struct pipe_draw_start_count *draws,
+ unsigned num_draws)
{
struct pipe_draw_info new_info;
struct pipe_draw_start_count new_draw;
@@ -109,6 +112,31 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
void *dst;
unsigned ib_offset;
+ /* indirect emulated prims is not possible, as we need to know
+ * draw start/count, so we must emulate. Too bad, so sad, but
+ * we are already off the fast-path here.
+ */
+ if (indirect && indirect->buffer) {
+ /* num_draws is only applicable for direct draws: */
+ assert(num_draws == 1);
+ util_draw_indirect(pc->pipe, info, indirect);
+ return;
+ }
+
+ if (num_draws > 1) {
+ util_draw_multi(pc->pipe, info, indirect, draws, num_draws);
+ return;
+ }
+
+ const struct pipe_draw_start_count *draw = &draws[0];
+
+ /* Filter out degenerate primitives, u_upload_alloc() will assert
+ * on size==0 so just bail:
+ */
+ if (!info->primitive_restart &&
+ !u_trim_pipe_prim(info->mode, (unsigned*)&draw->count))
+ return;
+
util_draw_init_info(&new_info);
new_info.index_bounds_valid = info->index_bounds_valid;
new_info.min_index = info->min_index;
diff --git a/src/gallium/auxiliary/indices/u_primconvert.h b/src/gallium/auxiliary/indices/u_primconvert.h
index 0aa2ba15146..f8750856da2 100644
--- a/src/gallium/auxiliary/indices/u_primconvert.h
+++ b/src/gallium/auxiliary/indices/u_primconvert.h
@@ -47,6 +47,8 @@ void util_primconvert_save_rasterizer_state(struct primconvert_context *pc,
*rast);
void util_primconvert_draw_vbo(struct primconvert_context *pc,
const struct pipe_draw_info *info,
- const struct pipe_draw_start_count *draw);
+ const struct pipe_draw_indirect_info *indirect,
+ const struct pipe_draw_start_count *draws,
+ unsigned num_draws);
#endif /* U_PRIMCONVERT_H_ */
diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp
index f7e564378fe..309a870160f 100644
--- a/src/gallium/drivers/d3d12/d3d12_draw.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp
@@ -453,7 +453,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
ctx->initial_api_prim = dinfo->mode;
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->gfx_pipeline_state.rast->base);
- util_primconvert_draw_vbo(ctx->primconvert, dinfo, &draws[0]);
+ util_primconvert_draw_vbo(ctx->primconvert, dinfo, indirect, draws, num_draws);
return;
}
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index 7eb2c0a39cc..2fae69da0c6 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -254,7 +254,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (!(ctx->prim_hwsupport & (1 << info->mode))) {
struct primconvert_context *primconvert = ctx->primconvert;
util_primconvert_save_rasterizer_state(primconvert, ctx->rasterizer);
- util_primconvert_draw_vbo(primconvert, info, &draws[0]);
+ util_primconvert_draw_vbo(primconvert, info, indirect, draws, num_draws);
return;
}
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index 7e38b34447a..399bd1a2060 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -289,19 +289,10 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
/* emulate unsupported primitives: */
if (!fd_supported_prim(ctx, info->mode)) {
- if (num_draws > 1) {
- util_draw_multi(pctx, info, indirect, draws, num_draws);
- return;
- }
-
- if (!indirect && !info->primitive_restart &&
- !u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count))
- return;
-
if (ctx->streamout.num_targets > 0)
mesa_loge("stream-out with emulated prims");
util_primconvert_save_rasterizer_state(ctx->primconvert, ctx->rasterizer);
- util_primconvert_draw_vbo(ctx->primconvert, info, &draws[0]);
+ util_primconvert_draw_vbo(ctx->primconvert, info, indirect, draws, num_draws);
return;
}
diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index 855e694b1b6..fb976977ce4 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -491,7 +491,7 @@ panfrost_direct_draw(struct panfrost_context *ctx,
}
util_primconvert_save_rasterizer_state(ctx->primconvert, &ctx->rasterizer->base);
- util_primconvert_draw_vbo(ctx->primconvert, info, draw);
+ util_primconvert_draw_vbo(ctx->primconvert, info, NULL, draw, 1);
return;
}
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index 5a708ad8ffd..0b151b38515 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -1135,7 +1135,7 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (info->mode >= PIPE_PRIM_QUADS && info->mode <= PIPE_PRIM_POLYGON) {
util_primconvert_save_rasterizer_state(v3d->primconvert, &v3d->rasterizer->base);
- util_primconvert_draw_vbo(v3d->primconvert, info, &draws[0]);
+ util_primconvert_draw_vbo(v3d->primconvert, info, indirect, draws, num_draws);
perf_debug("Fallback conversion for %d %s vertices\n",
draws[0].count, u_prim_name(info->mode));
return;
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index 9c1466cab74..77e7159c2dc 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -318,7 +318,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
info = &local_info;
} else {
util_primconvert_save_rasterizer_state(vc4->primconvert, &vc4->rasterizer->base);
- util_primconvert_draw_vbo(vc4->primconvert, info, &draws[0]);
+ util_primconvert_draw_vbo(vc4->primconvert, info, indirect, draws, num_draws);
perf_debug("Fallback conversion for %d %s vertices\n",
draws[0].count, u_prim_name(info->mode));
return;
diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c
index dcbff1d7984..17afd77a9fc 100644
--- a/src/gallium/drivers/virgl/virgl_context.c
+++ b/src/gallium/drivers/virgl/virgl_context.c
@@ -884,7 +884,7 @@ static void virgl_draw_vbo(struct pipe_context *ctx,
if (!(rs->caps.caps.v1.prim_mask & (1 << dinfo->mode))) {
util_primconvert_save_rasterizer_state(vctx->primconvert, &vctx->rs_state.rs);
- util_primconvert_draw_vbo(vctx->primconvert, dinfo, &draws[0]);
+ util_primconvert_draw_vbo(vctx->primconvert, dinfo, indirect, draws, num_draws);
return;
}
if (info.index_size) {
diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c
index e5d8f21f6e0..150fed5c12b 100644
--- a/src/gallium/drivers/zink/zink_draw.c
+++ b/src/gallium/drivers/zink/zink_draw.c
@@ -860,12 +860,7 @@ zink_draw_vbo(struct pipe_context *pctx,
(dinfo->mode == PIPE_PRIM_TRIANGLE_FAN && !screen->have_triangle_fans) ||
dinfo->mode == PIPE_PRIM_LINE_LOOP) {
util_primconvert_save_rasterizer_state(ctx->primconvert, &rast_state->base);
- for (unsigned i = 0; i < num_draws; i++) {
- /* TODO: is there actually a way to correctly handle this? no other driver does... */
- if (!u_trim_pipe_prim(dinfo->mode, (unsigned *)&draws[i].count))
- continue;
- util_primconvert_draw_vbo(ctx->primconvert, dinfo, &draws[i]);
- }
+ util_primconvert_draw_vbo(ctx->primconvert, dinfo, dindirect, draws, num_draws);
return;
}
if (ctx->gfx_pipeline_state.vertices_per_patch != dinfo->vertices_per_patch)
More information about the mesa-commit
mailing list