Commit ea2c4739 authored by Rob Clark's avatar Rob Clark 💬 Committed by Marge Bot
Browse files

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's avatarRob Clark <robdclark@chromium.org>
Part-of: <!9742>
parent 180ca32b
Pipeline #291385 passed with stage
in 7 minutes and 36 seconds
......@@ -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;
......
......@@ -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_ */
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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) {
......
......@@ -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)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment