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,