From 05f35a50e3ad2b9e3e0dae1c4b1bed7c91908022 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 17 Nov 2020 17:19:06 -0500 Subject: [PATCH] gallium: remove and emulate PIPE_CAP_MULTI_DRAW To remove PIPE_CAP checking in the common code. It's better if drivers lower multi draws even if the hardware doesn't support it beause the multi draw loop can be moved deeper into the driver to remove more overhead. Reviewed-by: Pierre-Eric Pelloux-Prayer Part-of: --- docs/gallium/screen.rst | 1 - src/gallium/auxiliary/util/u_screen.c | 1 - .../auxiliary/util/u_threaded_context.h | 2 -- src/gallium/drivers/d3d12/d3d12_draw.cpp | 11 ++++++++++ src/gallium/drivers/etnaviv/etnaviv_context.c | 11 ++++++++++ .../drivers/freedreno/freedreno_draw.c | 11 ++++++++++ src/gallium/drivers/i915/i915_context.c | 11 ++++++++++ src/gallium/drivers/iris/iris_draw.c | 11 ++++++++++ src/gallium/drivers/lima/lima_draw.c | 11 ++++++++++ src/gallium/drivers/llvmpipe/lp_draw_arrays.c | 11 ++++++++++ src/gallium/drivers/nouveau/nv30/nv30_vbo.c | 11 ++++++++++ src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 11 ++++++++++ src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 11 ++++++++++ src/gallium/drivers/panfrost/pan_context.c | 11 ++++++++++ src/gallium/drivers/r300/r300_render.c | 22 +++++++++++++++++++ src/gallium/drivers/r600/r600_state_common.c | 11 ++++++++++ src/gallium/drivers/radeonsi/si_get.c | 1 - src/gallium/drivers/softpipe/sp_draw_arrays.c | 11 ++++++++++ src/gallium/drivers/svga/svga_pipe_draw.c | 11 ++++++++++ src/gallium/drivers/swr/swr_draw.cpp | 11 ++++++++++ src/gallium/drivers/tegra/tegra_context.c | 11 ++++++++++ src/gallium/drivers/v3d/v3dx_draw.c | 11 ++++++++++ src/gallium/drivers/vc4/vc4_draw.c | 11 ++++++++++ src/gallium/drivers/virgl/virgl_context.c | 11 ++++++++++ src/gallium/drivers/zink/zink_draw.c | 11 ++++++++++ src/gallium/include/pipe/p_context.h | 2 +- src/gallium/include/pipe/p_defines.h | 1 - 27 files changed, 243 insertions(+), 7 deletions(-) diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 654df77dc0c..c619ad66394 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -232,7 +232,6 @@ The integer capabilities: * ``PIPE_CAP_DRAW_INDIRECT``: Whether the driver supports taking draw arguments { count, instance_count, start, index_bias } from a PIPE_BUFFER resource. See pipe_draw_info. -* ``PIPE_CAP_MULTI_DRAW``: Whether the driver supports direct multi draws. * ``PIPE_CAP_MULTI_DRAW_INDIRECT``: Whether the driver supports pipe_draw_info::indirect_stride and ::indirect_count * ``PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS``: Whether the driver supports diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c index 57dd0a1cb55..a95855d9779 100644 --- a/src/gallium/auxiliary/util/u_screen.c +++ b/src/gallium/auxiliary/util/u_screen.c @@ -229,7 +229,6 @@ u_pipe_screen_get_param_defaults(struct pipe_screen *pscreen, case PIPE_CAP_CLEAR_SCISSORED: case PIPE_CAP_DRAW_PARAMETERS: case PIPE_CAP_TGSI_PACK_HALF_FLOAT: - case PIPE_CAP_MULTI_DRAW: case PIPE_CAP_MULTI_DRAW_INDIRECT: case PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: case PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL: diff --git a/src/gallium/auxiliary/util/u_threaded_context.h b/src/gallium/auxiliary/util/u_threaded_context.h index 12cd6534be0..6838f804481 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.h +++ b/src/gallium/auxiliary/util/u_threaded_context.h @@ -145,8 +145,6 @@ * another resource's backing storage. The threaded context uses it to * implement buffer invalidation. This call is always queued. * - * PIPE_CAP_MULTI_DRAW must be supported. - * * * Performance gotchas * ------------------- diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index 4de3b09798b..c1d37f17ede 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -426,6 +426,17 @@ d3d12_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *dinfo; + + for (unsigned i = 0; i < num_draws; i++) { + d3d12_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct d3d12_context *ctx = d3d12_context(pctx); struct d3d12_batch *batch; struct pipe_resource *index_buffer = NULL; diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 58e5340ec0b..7a14de0e421 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -228,6 +228,17 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + etna_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct etna_context *ctx = etna_context(pctx); struct etna_screen *screen = ctx->screen; struct pipe_framebuffer_state *pfb = &ctx->framebuffer_s; diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c index c68bd33b3eb..692c49ce8d8 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.c +++ b/src/gallium/drivers/freedreno/freedreno_draw.c @@ -216,6 +216,17 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + fd_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct fd_context *ctx = fd_context(pctx); /* for debugging problems with indirect draw, it is convenient diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c index c778bb87c7e..e0cf63588fc 100644 --- a/src/gallium/drivers/i915/i915_context.c +++ b/src/gallium/drivers/i915/i915_context.c @@ -56,6 +56,17 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + i915_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct i915_context *i915 = i915_context(pipe); struct draw_context *draw = i915->draw; const void *mapped_indices = NULL; diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c index feec30bcabf..9d85360c70f 100644 --- a/src/gallium/drivers/iris/iris_draw.c +++ b/src/gallium/drivers/iris/iris_draw.c @@ -240,6 +240,17 @@ iris_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + iris_draw_vbo(ctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct iris_context *ice = (struct iris_context *) ctx; struct iris_screen *screen = (struct iris_screen*)ice->ctx.screen; const struct gen_device_info *devinfo = &screen->devinfo; diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 2df0faa643b..a88b1732883 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -1133,6 +1133,17 @@ lima_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + lima_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + /* check if draw mode and vertex/index count match, * otherwise gp will hang */ if (!u_trim_pipe_prim(info->mode, (unsigned*)&draws[0].count)) { diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c index 1bcc7fd6f53..cd38ca9c7c6 100644 --- a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c +++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c @@ -56,6 +56,17 @@ llvmpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + llvmpipe_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct llvmpipe_context *lp = llvmpipe_context(pipe); struct draw_context *draw = lp->draw; const void *mapped_indices = NULL; diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index eb483a86f7d..a041bf022e9 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -549,6 +549,17 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + nv30_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct nv30_context *nv30 = nv30_context(pipe); struct nouveau_pushbuf *push = nv30->base.pushbuf; int i; diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index 351fd27d780..1aaff44dbaf 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c @@ -759,6 +759,17 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + nv50_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct nv50_context *nv50 = nv50_context(pipe); struct nouveau_pushbuf *push = nv50->base.pushbuf; bool tex_dirty = false; diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 3270207c703..5cf02387da3 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -927,6 +927,17 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + nvc0_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct nvc0_context *nvc0 = nvc0_context(pipe); struct nouveau_pushbuf *push = nvc0->base.pushbuf; struct nvc0_screen *screen = nvc0->screen; diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 9c79721855c..66523bc77cf 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -457,6 +457,17 @@ panfrost_draw_vbo( const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + panfrost_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct panfrost_context *ctx = pan_context(pipe); struct panfrost_device *device = pan_device(ctx->base.screen); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 567f468d1f3..e7ffcf11b26 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -791,6 +791,17 @@ static void r300_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *dinfo; + + for (unsigned i = 0; i < num_draws; i++) { + r300_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct r300_context* r300 = r300_context(pipe); struct pipe_draw_info info = *dinfo; struct pipe_draw_start_count draw = draws[0]; @@ -853,6 +864,17 @@ static void r300_swtcl_draw_vbo(struct pipe_context* pipe, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + r300_swtcl_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct r300_context* r300 = r300_context(pipe); struct pipe_draw_start_count draw = draws[0]; diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 3490ca55b81..d7266ecceae 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -2057,6 +2057,17 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + r600_draw_vbo(ctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct r600_context *rctx = (struct r600_context *)ctx; struct pipe_resource *indexbuf = info->has_user_indices ? NULL : info->index.resource; struct radeon_cmdbuf *cs = &rctx->b.gfx.cs; diff --git a/src/gallium/drivers/radeonsi/si_get.c b/src/gallium/drivers/radeonsi/si_get.c index 469443bf7f1..f42543a8256 100644 --- a/src/gallium/drivers/radeonsi/si_get.c +++ b/src/gallium/drivers/radeonsi/si_get.c @@ -164,7 +164,6 @@ static int si_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SHADER_ATOMIC_INT64: case PIPE_CAP_FRONTEND_NOOP: case PIPE_CAP_DEMOTE_TO_HELPER_INVOCATION: - case PIPE_CAP_MULTI_DRAW: case PIPE_CAP_PREFER_REAL_BUFFER_IN_CONSTBUF0: case PIPE_CAP_COMPUTE_SHADER_DERIVATIVES: return 1; diff --git a/src/gallium/drivers/softpipe/sp_draw_arrays.c b/src/gallium/drivers/softpipe/sp_draw_arrays.c index ea6262ef717..588c4cceea9 100644 --- a/src/gallium/drivers/softpipe/sp_draw_arrays.c +++ b/src/gallium/drivers/softpipe/sp_draw_arrays.c @@ -64,6 +64,17 @@ softpipe_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + softpipe_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct softpipe_context *sp = softpipe_context(pipe); struct draw_context *draw = sp->draw; const void *mapped_indices = NULL; diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index 61cd75ba169..db149c37401 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -222,6 +222,17 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + svga_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct svga_context *svga = svga_context(pipe); enum pipe_prim_type reduced_prim = u_reduced_prim(info->mode); unsigned count = draws[0].count; diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index 1fde87bc53b..63ef2f58249 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -42,6 +42,17 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + swr_draw_vbo(pipe, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct swr_context *ctx = swr_context(pipe); if (!indirect && diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c index 63f0b59d9a5..e22b762d454 100644 --- a/src/gallium/drivers/tegra/tegra_context.c +++ b/src/gallium/drivers/tegra/tegra_context.c @@ -51,6 +51,17 @@ tegra_draw_vbo(struct pipe_context *pcontext, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *pinfo; + + for (unsigned i = 0; i < num_draws; i++) { + tegra_draw_vbo(pcontext, &tmp_info, pindirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct tegra_context *context = to_tegra_context(pcontext); struct pipe_draw_indirect_info indirect; struct pipe_draw_info info; diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index e2cca7e7fa2..c0ecc9ec44a 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -1097,6 +1097,17 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + v3d_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct v3d_context *v3d = v3d_context(pctx); if (!indirect && diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index a65dafd4bd5..f2073d82fe4 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -291,6 +291,17 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *info; + + for (unsigned i = 0; i < num_draws; i++) { + vc4_draw_vbo(pctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct vc4_context *vc4 = vc4_context(pctx); struct pipe_draw_info local_info; diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index 83e2f99c00c..a85fa25a16a 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -853,6 +853,17 @@ static void virgl_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *dinfo; + + for (unsigned i = 0; i < num_draws; i++) { + virgl_draw_vbo(ctx, &tmp_info, indirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct virgl_context *vctx = virgl_context(ctx); struct virgl_screen *rs = virgl_screen(ctx->screen); struct virgl_indexbuf ib = {}; diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index 9f5bddbf301..e6e1a94622f 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -213,6 +213,17 @@ zink_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_start_count *draws, unsigned num_draws) { + if (num_draws > 1) { + struct pipe_draw_info tmp_info = *dinfo; + + for (unsigned i = 0; i < num_draws; i++) { + zink_draw_vbo(pctx, &tmp_info, dindirect, &draws[i], 1); + if (tmp_info.increment_draw_id) + tmp_info.drawid++; + } + return; + } + struct zink_context *ctx = zink_context(pctx); struct zink_screen *screen = zink_screen(pctx->screen); struct zink_rasterizer_state *rast_state = ctx->rast_state; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 59657fe0be4..7707eb6f2b6 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -115,7 +115,7 @@ struct pipe_context { * is used instead. * * Caps: - * - PIPE_CAP_MULTI_DRAW: Direct multi draws + * - Always supported: Direct multi draws * - PIPE_CAP_MULTI_DRAW_INDIRECT: Indirect multi draws * - PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: Indirect draw count * diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index f15aba76a42..6fa67f38c71 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -842,7 +842,6 @@ enum pipe_cap PIPE_CAP_CLEAR_SCISSORED, PIPE_CAP_DRAW_PARAMETERS, PIPE_CAP_TGSI_PACK_HALF_FLOAT, - PIPE_CAP_MULTI_DRAW, PIPE_CAP_MULTI_DRAW_INDIRECT, PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS, PIPE_CAP_TGSI_FS_POSITION_IS_SYSVAL,