gallium: move pipe_draw_info::index_bias to pipe_draw_start_count_bias

this moves index_bias into the multidraw struct, enabling draws where the value
changes to be merged; the draw_info struct member is renamed and moved to the end
of the struct for tc use

u_vbuf still has some checks to split draws if index_bias changes, maybe
this can be removed at some point?

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10166>
This commit is contained in:
Mike Blumenkrantz 2021-04-11 10:26:29 -04:00 committed by Marge Bot
parent 4fe6c85526
commit 4566383ae4
57 changed files with 275 additions and 288 deletions

View File

@ -1469,6 +1469,7 @@ cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
draw.start = start;
draw.count = count;
draw.index_bias = 0;
cso_draw_vbo(cso, &info, NULL, draw);
}
@ -1492,6 +1493,7 @@ cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
draw.start = start;
draw.count = count;
draw.index_bias = 0;
cso_draw_vbo(cso, &info, NULL, draw);
}

View File

@ -153,6 +153,7 @@ draw_pt_arrays(struct draw_context *draw,
} else
draw_pt_split_prim(prim, &first, &incr);
count = draw_pt_trim_count(draw_info[i].count, first, incr);
draw->pt.user.eltBias = draw->pt.user.eltSize ? draw_info[i].index_bias : 0;
if (count >= first)
frontend->run( frontend, draw_info[i].start, count );
@ -245,7 +246,7 @@ void draw_pt_destroy( struct draw_context *draw )
* Debug- print the first 'count' vertices.
*/
static void
draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count, int index_bias)
{
uint i;
@ -282,9 +283,9 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
assert(0);
return;
}
ii += draw->pt.user.eltBias;
ii += index_bias;
debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i,
draw->pt.user.eltBias, ii);
index_bias, ii);
}
else {
/* non-indexed arrays */
@ -358,22 +359,20 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
static inline void
prim_restart_loop(struct draw_context *draw,
const struct pipe_draw_info *info,
unsigned start,
unsigned count,
const struct pipe_draw_start_count_bias *draw_info,
const void *elements)
{
const unsigned elt_max = draw->pt.user.eltMax;
struct pipe_draw_start_count_bias cur;
cur.start = start;
struct pipe_draw_start_count_bias cur = *draw_info;
cur.count = 0;
/* The largest index within a loop using the i variable as the index.
* Used for overflow detection */
const unsigned MAX_LOOP_IDX = 0xffffffff;
for (unsigned j = 0; j < count; j++) {
for (unsigned j = 0; j < draw_info->count; j++) {
unsigned restart_idx = 0;
unsigned i = draw_overflow_uadd(start, j, MAX_LOOP_IDX);
unsigned i = draw_overflow_uadd(draw_info->start, j, MAX_LOOP_IDX);
switch (draw->pt.user.eltSize) {
case 1:
restart_idx = ((const uint8_t*)elements)[i];
@ -424,7 +423,7 @@ draw_pt_arrays_restart(struct draw_context *draw,
if (draw->pt.user.eltSize) {
/* indexed prims (draw_elements) */
for (unsigned i = 0; i < num_draws; i++)
prim_restart_loop(draw, info, draw_info[i].start, draw_info[i].count, draw->pt.user.elts);
prim_restart_loop(draw, info, &draw_info[i], draw->pt.user.elts);
}
else {
/* Non-indexed prims (draw_arrays).
@ -536,7 +535,6 @@ draw_vbo(struct draw_context *draw,
if (info->index_size)
assert(draw->pt.user.elts);
draw->pt.user.eltBias = use_info->index_size ? use_info->index_bias : 0;
draw->pt.user.min_index = use_info->index_bounds_valid ? use_info->min_index : 0;
draw->pt.user.max_index = use_info->index_bounds_valid ? use_info->max_index : ~0;
draw->pt.user.eltSize = use_info->index_size ? draw->pt.user.eltSizeIB : 0;
@ -578,7 +576,7 @@ draw_vbo(struct draw_context *draw,
if (0) {
for (unsigned i = 0; i < num_draws; i++)
draw_print_arrays(draw, use_info->mode, use_draws[i].start, MIN2(use_draws[i].count, 20));
draw_print_arrays(draw, use_info->mode, use_draws[i].start, MIN2(use_draws[i].count, 20), use_draws[i].index_bias);
}
index_limit = util_draw_max_index(draw->pt.vertex_buffer,

View File

@ -358,7 +358,7 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info,
int sh, i;
DUMP(draw_info, info);
DUMP(draw_start_count, draw);
DUMP(draw_start_count_bias, draw);
if (indirect) {
if (indirect->buffer)
DUMP_M(resource, indirect, buffer);

View File

@ -800,7 +800,6 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
trace_dump_member(uint, state, vertices_per_patch);
trace_dump_member(int, state, index_bias);
trace_dump_member(uint, state, min_index);
trace_dump_member(uint, state, max_index);
@ -819,6 +818,7 @@ void trace_dump_draw_start_count(const struct pipe_draw_start_count_bias *state)
trace_dump_struct_begin("pipe_draw_start_count_bias");
trace_dump_member(uint, state, start);
trace_dump_member(uint, state, count);
trace_dump_member(int, state, index_bias);
trace_dump_struct_end();
}

View File

@ -141,7 +141,6 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
new_info.index_bounds_valid = info->index_bounds_valid;
new_info.min_index = info->min_index;
new_info.max_index = info->max_index;
new_info.index_bias = info->index_size ? info->index_bias : 0;
new_info.start_instance = info->start_instance;
new_info.instance_count = info->instance_count;
new_info.primitive_restart = info->primitive_restart;
@ -181,6 +180,7 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
u_upload_alloc(pc->pipe->stream_uploader, 0, new_info.index_size * new_draw.count, 4,
&ib_offset, &new_info.index.resource, &dst);
new_draw.start = ib_offset / new_info.index_size;
new_draw.index_bias = info->index_size ? draw->index_bias : 0;
if (info->index_size) {
trans_func(src, draw->start, draw->count, new_draw.count, info->restart_index, dst);

View File

@ -181,7 +181,7 @@ util_draw_indirect(struct pipe_context *pipe,
draw.count = params[0];
info.instance_count = params[1];
draw.start = params[2];
info.index_bias = info_in->index_size ? params[3] : 0;
draw.index_bias = info_in->index_size ? params[3] : 0;
info.start_instance = info_in->index_size ? params[4] : params[3];
info.drawid = i;

View File

@ -64,6 +64,7 @@ util_draw_arrays(struct pipe_context *pipe,
draw.start = start;
draw.count = count;
draw.index_bias = 0;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}
@ -84,7 +85,7 @@ util_draw_elements(struct pipe_context *pipe,
info.has_user_indices = true;
info.index_size = index_size;
info.mode = mode;
info.index_bias = index_bias;
draw.index_bias = index_bias;
draw.start = start;
draw.count = count;
@ -113,6 +114,7 @@ util_draw_arrays_instanced(struct pipe_context *pipe,
draw.start = start;
draw.count = count;
draw.index_bias = 0;
pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
}
@ -136,7 +138,7 @@ util_draw_elements_instanced(struct pipe_context *pipe,
info.has_user_indices = true;
info.index_size = index_size;
info.mode = mode;
info.index_bias = index_bias;
draw.index_bias = index_bias;
info.start_instance = start_instance;
info.instance_count = instance_count;

View File

@ -201,7 +201,7 @@ void
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state);
void
util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count_bias *state);
util_dump_draw_start_count_bias(FILE *stream, const struct pipe_draw_start_count_bias *state);
void
util_dump_draw_indirect_info(FILE *stream,

View File

@ -917,7 +917,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
util_dump_member(stream, uint, state, vertices_per_patch);
util_dump_member(stream, int, state, index_bias);
util_dump_member(stream, uint, state, min_index);
util_dump_member(stream, uint, state, max_index);
@ -935,11 +934,12 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
}
void
util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count_bias *state)
util_dump_draw_start_count_bias(FILE *stream, const struct pipe_draw_start_count_bias *state)
{
util_dump_struct_begin(stream, "pipe_draw_start_count_bias");
util_dump_member(stream, uint, state, start);
util_dump_member(stream, uint, state, count);
util_dump_member(stream, int, state, index_bias);
util_dump_struct_end(stream);
}

View File

@ -119,7 +119,8 @@ simplify_draw_info(struct pipe_draw_info *info)
info->has_user_indices = false;
info->index_bounds_valid = false;
info->take_index_buffer_ownership = false;
info->_pad = 0;
info->index_bias_varies = false;
info->_pad2 = 0;
/* This shouldn't be set when merging single draws. */
info->increment_draw_id = false;
@ -132,7 +133,6 @@ simplify_draw_info(struct pipe_draw_info *info)
info->restart_index = 0;
} else {
assert(!info->primitive_restart);
info->index_bias = 0;
info->primitive_restart = false;
info->restart_index = 0;
info->index.resource = NULL;
@ -142,12 +142,14 @@ simplify_draw_info(struct pipe_draw_info *info)
static bool
is_next_call_a_mergeable_draw(struct tc_draw_single *first_info,
struct tc_call *next,
struct tc_draw_single **next_info)
struct tc_draw_single **next_info,
int *index_bias)
{
if (next->call_id != TC_CALL_draw_single)
return false;
*next_info = (struct tc_draw_single*)&next->payload;
*index_bias = (*next_info)->info._pad2;
simplify_draw_info(&(*next_info)->info);
STATIC_ASSERT(offsetof(struct pipe_draw_info, min_index) ==
@ -183,14 +185,17 @@ tc_batch_execute(void *job, UNUSED int thread_index)
struct tc_call *next = first + first->num_call_slots;
struct tc_draw_single *first_info =
(struct tc_draw_single*)&first->payload;
struct tc_draw_single *next_info;
struct tc_draw_single *next_info = NULL;
int first_index_bias = first_info->info._pad2;
int index_bias = 0;
bool index_bias_varies = false;
simplify_draw_info(&first_info->info);
/* If at least 2 consecutive draw calls can be merged... */
if (next != last && next->call_id == TC_CALL_draw_single &&
first_info->info.drawid == 0 &&
is_next_call_a_mergeable_draw(first_info, next, &next_info)) {
is_next_call_a_mergeable_draw(first_info, next, &next_info, &index_bias)) {
/* Merge up to 256 draw calls. */
struct pipe_draw_start_count_bias multi[256];
unsigned num_draws = 2;
@ -198,8 +203,11 @@ tc_batch_execute(void *job, UNUSED int thread_index)
/* u_threaded_context stores start/count in min/max_index for single draws. */
multi[0].start = first_info->info.min_index;
multi[0].count = first_info->info.max_index;
multi[0].index_bias = first_index_bias;
multi[1].start = next_info->info.min_index;
multi[1].count = next_info->info.max_index;
multi[1].index_bias = index_bias;
index_bias_varies = first_index_bias != index_bias;
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
@ -207,21 +215,30 @@ tc_batch_execute(void *job, UNUSED int thread_index)
/* Find how many other draws can be merged. */
next = next + next->num_call_slots;
for (; next != last && num_draws < ARRAY_SIZE(multi) &&
is_next_call_a_mergeable_draw(first_info, next, &next_info);
is_next_call_a_mergeable_draw(first_info, next, &next_info, &index_bias);
next += next->num_call_slots, num_draws++) {
/* u_threaded_context stores start/count in min/max_index for single draws. */
multi[num_draws].start = next_info->info.min_index;
multi[num_draws].count = next_info->info.max_index;
multi[num_draws].index_bias = index_bias;
index_bias_varies |= first_index_bias != index_bias;
if (next_info->info.index_size)
pipe_resource_reference(&next_info->info.index.resource, NULL);
}
first_info->info.index_bias_varies = index_bias_varies;
pipe->draw_vbo(pipe, &first_info->info, NULL, multi, num_draws);
if (first_info->info.index_size)
pipe_resource_reference(&first_info->info.index.resource, NULL);
iter = next;
continue;
} else {
/* reset original index_bias from before simplify_draw_info() */
first_info->info._pad2 = first_index_bias;
if (next != last && next->call_id == TC_CALL_draw_single && first_info->info.drawid == 0 && next_info)
/* in this case, simplify_draw_info() will have zeroed the data here as well */
next_info->info._pad2 = index_bias;
}
}
@ -2389,16 +2406,17 @@ tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
/* u_threaded_context stores start/count in min/max_index for single draws. */
/* Drivers using u_threaded_context shouldn't use min/max_index. */
struct pipe_draw_start_count_bias *draw =
(struct pipe_draw_start_count_bias *)&info->info.min_index;
STATIC_ASSERT(offsetof(struct pipe_draw_start_count_bias, start) == 0);
STATIC_ASSERT(offsetof(struct pipe_draw_start_count_bias, count) == 4);
struct pipe_draw_start_count_bias draw;
draw.start = info->info.min_index;
draw.count = info->info.max_index;
draw.index_bias = info->info._pad2;
info->info.index_bounds_valid = false;
info->info.has_user_indices = false;
info->info.take_index_buffer_ownership = false;
pipe->draw_vbo(pipe, &info->info, NULL, draw, 1);
pipe->draw_vbo(pipe, &info->info, NULL, &draw, 1);
if (info->info.index_size)
pipe_resource_reference(&info->info.index.resource, NULL);
}
@ -2512,6 +2530,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
/* u_threaded_context stores start/count in min/max_index for single draws. */
p->info.min_index = offset >> util_logbase2(index_size);
p->info.max_index = draws[0].count;
p->info._pad2 = draws[0].index_bias;
} else {
/* Non-indexed call or indexed with a real index buffer. */
struct tc_draw_single *p =
@ -2524,6 +2543,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
/* u_threaded_context stores start/count in min/max_index for single draws. */
p->info.min_index = draws[0].start;
p->info.max_index = draws[0].count;
p->info._pad2 = draws[0].index_bias;
}
return;
}
@ -2585,6 +2605,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
if (!count) {
p->slot[i].start = 0;
p->slot[i].count = 0;
p->slot[i].index_bias = 0;
continue;
}
@ -2594,6 +2615,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
(draws[i + total_offset].start << index_size_shift), size);
p->slot[i].start = (buffer_offset + offset) >> index_size_shift;
p->slot[i].count = count;
p->slot[i].index_bias = draws[i + total_offset].index_bias;
offset += size;
}

View File

@ -1293,7 +1293,7 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
draw.count = indirect_data[offset + 0];
info->instance_count = indirect_data[offset + 1];
draw.start = indirect_data[offset + 2];
info->index_bias = indirect_data[offset + 3];
draw.index_bias = indirect_data[offset + 3];
info->start_instance = indirect_data[offset + 4];
u_vbuf_draw_vbo(mgr, info, NULL, draw);
@ -1400,7 +1400,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
* The driver will not look at these values because indirect != NULL.
* These values determine the user buffer bounds to upload.
*/
new_info.index_bias = index_bias0;
new_draw.index_bias = index_bias0;
new_info.index_bounds_valid = true;
new_info.min_index = ~0u;
new_info.max_index = 0;
@ -1510,7 +1510,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
assert(min_index <= max_index);
start_vertex = min_index + new_info.index_bias;
start_vertex = min_index + new_draw.index_bias;
num_vertices = max_index + 1 - min_index;
/* Primitive restart doesn't work when unrolling indices.
@ -1550,7 +1550,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
if (unroll_indices) {
new_info.index_size = 0;
new_info.index_bias = 0;
new_draw.index_bias = 0;
new_info.index_bounds_valid = true;
new_info.min_index = 0;
new_info.max_index = new_draw.count - 1;

View File

@ -190,7 +190,7 @@ fill_state_vars(struct d3d12_context *ctx,
size += 4;
break;
case D3D12_STATE_VAR_FIRST_VERTEX:
ptr[0] = dinfo->index_size ? dinfo->index_bias : draw->start;
ptr[0] = dinfo->index_size ? draw->index_bias : draw->start;
size += 4;
break;
case D3D12_STATE_VAR_DEPTH_TRANSFORM:
@ -716,7 +716,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
if (dinfo->index_size > 0)
ctx->cmdlist->DrawIndexedInstanced(draws[0].count, dinfo->instance_count,
draws[0].start, dinfo->index_bias,
draws[0].start, draws[0].index_bias,
dinfo->start_instance);
else
ctx->cmdlist->DrawInstanced(draws[0].count, dinfo->instance_count,

View File

@ -381,10 +381,10 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
if (screen->specs.halti >= 2) {
/* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count,
draws[0].count, info->index_size ? info->index_bias : draws[0].start);
draws[0].count, info->index_size ? draws->index_bias : draws[0].start);
} else {
if (info->index_size)
etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, draws->index_bias);
else
etna_draw_primitives(ctx->stream, draw_mode, draws[0].start, prims);
}

View File

@ -69,14 +69,14 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
OUT_RING(ring, info->index_bounds_valid
? add_sat(info->min_index,
info->index_size ? info->index_bias : 0)
info->index_size ? emit->draw->index_bias : 0)
: 0); /* VFD_INDEX_MIN */
OUT_RING(ring, info->index_bounds_valid
? add_sat(info->max_index,
info->index_size ? info->index_bias : 0)
info->index_size ? emit->draw->index_bias : 0)
: ~0); /* VFD_INDEX_MAX */
OUT_RING(ring, info->start_instance); /* VFD_INSTANCEID_OFFSET */
OUT_RING(ring, info->index_size ? info->index_bias
OUT_RING(ring, info->index_size ? emit->draw->index_bias
: emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);

View File

@ -52,7 +52,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd4_emit_vertex_bufs(ring, emit);
OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
OUT_RING(ring, info->index_size ? info->index_bias
OUT_RING(ring, info->index_size ? emit->draw->index_bias
: emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->start_instance); /* ??? UNKNOWN_2209 */

View File

@ -52,7 +52,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
fd5_emit_vertex_bufs(ring, emit);
OUT_PKT4(ring, REG_A5XX_VFD_INDEX_OFFSET, 2);
OUT_RING(ring, info->index_size ? info->index_bias
OUT_RING(ring, info->index_size ? emit->draw->index_bias
: emit->draw->start); /* VFD_INDEX_OFFSET */
OUT_RING(ring, info->start_instance); /* VFD_INSTANCE_START_OFFSET */

View File

@ -302,7 +302,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
}
}
uint32_t index_start = info->index_size ? info->index_bias : draw->start;
uint32_t index_start = info->index_size ? draw->index_bias : draw->start;
if (ctx->last.dirty || (ctx->last.index_start != index_start)) {
OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 1);
OUT_RING(ring, index_start); /* VFD_INDEX_OFFSET */

View File

@ -474,7 +474,7 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v,
uint32_t offset = const_state->offsets.driver_param;
uint32_t vertex_params[IR3_DP_VS_COUNT] = {
[IR3_DP_DRAWID] = 0, /* filled by hw (CP_DRAW_INDIRECT_MULTI) */
[IR3_DP_VTXID_BASE] = info->index_size ? info->index_bias : draw->start,
[IR3_DP_VTXID_BASE] = info->index_size ? draw->index_bias : draw->start,
[IR3_DP_INSTID_BASE] = info->start_instance,
[IR3_DP_VTXCNT_MAX] = ctx->streamout.max_tf_vtx,
};

View File

@ -132,7 +132,7 @@ iris_update_draw_parameters(struct iris_context *ice,
changed = true;
ice->draw.params_valid = false;
} else {
int firstvertex = info->index_size ? info->index_bias : draw->start;
int firstvertex = info->index_size ? draw->index_bias : draw->start;
if (!ice->draw.params_valid ||
ice->draw.params.firstvertex != firstvertex ||

View File

@ -6801,7 +6801,7 @@ iris_upload_render_state(struct iris_context *ice,
prim.StartVertexLocation = sc->start;
if (draw->index_size) {
prim.BaseVertexLocation += draw->index_bias;
prim.BaseVertexLocation += sc->index_bias;
}
}
}

View File

@ -830,7 +830,7 @@ lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_i
lima_job_add_bo(job, LIMA_PIPE_GP, res->bo, LIMA_SUBMIT_BO_READ);
unsigned start = info->index_size ? (ctx->min_index + info->index_bias) : draw->start;
unsigned start = info->index_size ? (ctx->min_index + draw->index_bias) : draw->start;
attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
+ start * pvb->stride;
attribute[n++] = (pvb->stride << 11) |

View File

@ -200,7 +200,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
{
struct push_context ctx;
unsigned i, index_size;
bool apply_bias = info->index_size && info->index_bias;
bool apply_bias = info->index_size && draw->index_bias;
ctx.push = nv30->base.pushbuf;
ctx.translate = nv30->vertex->translate;
@ -220,7 +220,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
vb->buffer_offset, NOUVEAU_BO_RD);
if (apply_bias)
data += info->index_bias * vb->stride;
data += draw->index_bias * vb->stride;
ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
}

View File

@ -647,7 +647,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nv30_draw_elements(nv30, shorten, info,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
info->instance_count, draws[0].index_bias, info->index_size);
}
nv30_state_release(nv30);

View File

@ -246,14 +246,14 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
unsigned i, index_size;
unsigned inst_count = info->instance_count;
unsigned vert_count = draw->count;
bool apply_bias = info->index_size && info->index_bias;
bool apply_bias = info->index_size && draw->index_bias;
ctx.push = nv50->base.pushbuf;
ctx.translate = nv50->vertex->translate;
ctx.need_vertex_id = nv50->screen->base.class_3d >= NV84_3D_CLASS &&
nv50->vertprog->vp.need_vertex_id && (nv50->vertex->num_elements < 32);
ctx.index_bias = info->index_size ? info->index_bias : 0;
ctx.index_bias = info->index_size ? draw->index_bias : 0;
ctx.instance_id = 0;
/* For indexed draws, gl_VertexID must be emitted for every vertex. */
@ -276,7 +276,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
data = vb->buffer.user;
if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i))))
data += (ptrdiff_t)(info->index_size ? info->index_bias : 0) * vb->stride;
data += (ptrdiff_t)(info->index_size ? draw->index_bias : 0) * vb->stride;
ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
}

View File

@ -788,7 +788,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
if (info->index_bounds_valid) {
nv50->vb_elt_first = info->min_index + (info->index_size ? info->index_bias : 0);
nv50->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
nv50->vb_elt_limit = info->max_index - info->min_index;
} else {
nv50->vb_elt_first = 0;
@ -912,7 +912,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nv50_draw_elements(nv50, shorten, info,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
info->instance_count, draws->index_bias, info->index_size);
} else
if (unlikely(indirect && indirect->count_from_stream_output)) {
nva0_draw_stream_output(nv50, info, indirect);

View File

@ -944,7 +944,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
/* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
if (info->index_bounds_valid) {
nvc0->vb_elt_first = info->min_index + (info->index_size ? info->index_bias : 0);
nvc0->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
nvc0->vb_elt_limit = info->max_index - info->min_index;
} else {
nvc0->vb_elt_first = 0;
@ -1032,7 +1032,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
PUSH_DATA (push, NVC0_CB_AUX_DRAW_INFO);
PUSH_DATA (push, info->index_size ? info->index_bias : 0);
PUSH_DATA (push, info->index_size ? draws->index_bias : 0);
PUSH_DATA (push, info->start_instance);
PUSH_DATA (push, info->drawid);
}
@ -1121,7 +1121,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
nvc0_draw_elements(nvc0, shorten, info,
info->mode, draws[0].start, draws[0].count,
info->instance_count, info->index_bias, info->index_size);
info->instance_count, draws->index_bias, info->index_size);
} else {
nvc0_draw_arrays(nvc0,
info->mode, draws[0].start, draws[0].count,

View File

@ -524,7 +524,7 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
sdraw.count = cmd->count;
single.start_instance = cmd->baseInstance;
single.instance_count = cmd->primCount;
single.index_bias = cmd->baseVertex;
sdraw.index_bias = cmd->baseVertex;
} else {
DrawArraysIndirectCommand *cmd = (void *)buf_data;
sdraw.start = cmd->first;
@ -541,7 +541,7 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
PUSH_DATA (push, NVC0_CB_AUX_DRAW_INFO);
PUSH_DATA (push, single.index_bias);
PUSH_DATA (push, sdraw.index_bias);
PUSH_DATA (push, single.start_instance);
PUSH_DATA (push, single.drawid + i);
}
@ -561,7 +561,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
{
struct push_context ctx;
unsigned i, index_size;
unsigned index_bias = info->index_size ? info->index_bias : 0;
unsigned index_bias = info->index_size ? draw->index_bias : 0;
unsigned inst_count = info->instance_count;
unsigned vert_count = draw->count;
unsigned prim;
@ -723,7 +723,7 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
unsigned i;
unsigned a = nvc0->vertex->num_elements;
if (!index_size || info->index_bias)
if (!index_size || draw->index_bias)
index_size = 4;
data = (uint32_t *)nouveau_scratch_get(&nvc0->base,
draw->count * index_size, &va, &bo);
@ -733,24 +733,24 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
nouveau_pushbuf_validate(push);
if (info->index_size) {
if (!info->index_bias) {
if (!draw->index_bias) {
memcpy(data, ctx->idxbuf, draw->count * index_size);
} else {
switch (info->index_size) {
case 1:
copy_indices_u8(data, ctx->idxbuf, info->index_bias, draw->count);
copy_indices_u8(data, ctx->idxbuf, draw->index_bias, draw->count);
break;
case 2:
copy_indices_u16(data, ctx->idxbuf, info->index_bias, draw->count);
copy_indices_u16(data, ctx->idxbuf, draw->index_bias, draw->count);
break;
default:
copy_indices_u32(data, ctx->idxbuf, info->index_bias, draw->count);
copy_indices_u32(data, ctx->idxbuf, draw->index_bias, draw->count);
break;
}
}
} else {
for (i = 0; i < draw->count; ++i)
data[i] = i + (draw->start + info->index_bias);
data[i] = i + (draw->start + draw->index_bias);
}
format = (1 << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |

View File

@ -335,7 +335,7 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch,
if (info->index_size) {
cfg.index_type = panfrost_translate_index_size(info->index_size);
cfg.indices = indices;
cfg.base_vertex_offset = info->index_bias - ctx->offset_start;
cfg.base_vertex_offset = draw->index_bias - ctx->offset_start;
}
}
@ -447,7 +447,7 @@ panfrost_direct_draw(struct panfrost_context *ctx,
/* Take into account a negative bias */
ctx->indirect_draw = false;
ctx->vertex_count = draw->count + (info->index_size ? abs(info->index_bias) : 0);
ctx->vertex_count = draw->count + (info->index_size ? abs(draw->index_bias) : 0);
ctx->instance_count = info->instance_count;
ctx->active_prim = info->mode;
@ -472,7 +472,7 @@ panfrost_direct_draw(struct panfrost_context *ctx,
/* Use the corresponding values */
vertex_count = max_index - min_index + 1;
ctx->offset_start = min_index + info->index_bias;
ctx->offset_start = min_index + draw->index_bias;
} else {
ctx->offset_start = draw->start;
}
@ -623,7 +623,7 @@ panfrost_indirect_draw(struct panfrost_context *ctx,
panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
vs_vary, varyings, attribs, attrib_bufs,
vertex.cpu);
panfrost_draw_emit_tiler(batch, info, NULL, &invocation, shared_mem,
panfrost_draw_emit_tiler(batch, info, draw, &invocation, shared_mem,
index_buf ? index_buf->ptr.gpu : 0,
fs_vary, varyings, pos, psiz, tiler.cpu);

View File

@ -512,7 +512,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
/* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
PREP_INDEXED, NULL, 2+count_dwords, 0, draw->index_bias, -1))
return;
r300_emit_draw_init(r300, info->mode, info->max_index);
@ -528,13 +528,13 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
if (draw->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
(ptr1[i] + info->index_bias));
OUT_CS(((ptr1[i+1] + draw->index_bias) << 16) |
(ptr1[i] + draw->index_bias));
if (draw->count & 1)
OUT_CS(ptr1[i] + info->index_bias);
OUT_CS(ptr1[i] + draw->index_bias);
} else {
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr1[i+1]) << 16) |
@ -552,13 +552,13 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
if (draw->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < draw->count-1; i += 2)
OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
(ptr2[i] + info->index_bias));
OUT_CS(((ptr2[i+1] + draw->index_bias) << 16) |
(ptr2[i] + draw->index_bias));
if (draw->count & 1)
OUT_CS(ptr2[i] + info->index_bias);
OUT_CS(ptr2[i] + draw->index_bias);
} else {
OUT_CS_TABLE(ptr2, count_dwords);
}
@ -572,9 +572,9 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
r300_translate_primitive(info->mode));
if (info->index_bias && !r300->screen->caps.is_r500) {
if (draw->index_bias && !r300->screen->caps.is_r500) {
for (i = 0; i < draw->count; i++)
OUT_CS(ptr4[i] + info->index_bias);
OUT_CS(ptr4[i] + draw->index_bias);
} else {
OUT_CS_TABLE(ptr4, count_dwords);
}
@ -600,8 +600,8 @@ static void r300_draw_elements(struct r300_context *r300,
int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
uint16_t indices3[3];
if (info->index_bias && !r300->screen->caps.is_r500) {
r300_split_index_bias(r300, info->index_bias, &buffer_offset,
if (draw->index_bias && !r300->screen->caps.is_r500) {
r300_split_index_bias(r300, draw->index_bias, &buffer_offset,
&index_offset);
}
@ -635,7 +635,7 @@ static void r300_draw_elements(struct r300_context *r300,
/* 19 dwords for emit_draw_elements. Give up if the function fails. */
if (!r300_prepare_for_rendering(r300,
PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
PREP_INDEXED, indexBuffer, 19, buffer_offset, draw->index_bias,
instance_id))
goto done;
@ -662,7 +662,7 @@ static void r300_draw_elements(struct r300_context *r300,
if (count) {
if (!r300_prepare_for_rendering(r300,
PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
indexBuffer, 19, buffer_offset, info->index_bias,
indexBuffer, 19, buffer_offset, draw->index_bias,
instance_id))
goto done;
}

View File

@ -2223,7 +2223,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
index_offset -= start_offset;
has_user_indices = false;
}
index_bias = info->index_bias;
index_bias = draws->index_bias;
} else {
index_bias = indirect ? 0 : draws[0].start;
}

View File

@ -1656,7 +1656,7 @@ static inline unsigned si_get_minimum_num_gfx_cs_dwords(struct si_context *sctx,
* Also reserve space for stopping queries at the end of IB, because
* the number of active queries is unlimited in theory.
*/
return 2048 + sctx->num_cs_dw_queries_suspend + num_draws * 9;
return 2048 + sctx->num_cs_dw_queries_suspend + num_draws * 10;
}
static inline void si_context_add_resource_size(struct si_context *sctx, struct pipe_resource *r)

View File

@ -1056,6 +1056,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
unsigned sh_base_reg = sctx->shader_pointers.sh_base[PIPE_SHADER_VERTEX];
bool render_cond_bit = sctx->render_cond_enabled;
unsigned drawid_base = info->drawid;
if (indirect) {
assert(num_draws == 1);
@ -1131,7 +1132,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
}
/* Base vertex and start instance. */
int base_vertex = original_index_size ? info->index_bias : draws[0].start;
int base_vertex = original_index_size ? draws[0].index_bias : draws[0].start;
bool set_draw_id = sctx->vs_uses_draw_id;
bool set_base_instance = sctx->vs_uses_base_instance;
@ -1149,23 +1150,23 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
(info->start_instance != sctx->last_start_instance ||
sctx->last_start_instance == SI_START_INSTANCE_UNKNOWN)) ||
(set_draw_id &&
(info->drawid != sctx->last_drawid ||
(drawid_base != sctx->last_drawid ||
sctx->last_drawid == SI_DRAW_ID_UNKNOWN)) ||
sh_base_reg != sctx->last_sh_base_reg) {
if (set_base_instance) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 3);
radeon_emit(cs, base_vertex);
radeon_emit(cs, info->drawid);
radeon_emit(cs, drawid_base);
radeon_emit(cs, info->start_instance);
sctx->last_start_instance = info->start_instance;
sctx->last_drawid = info->drawid;
sctx->last_drawid = drawid_base;
} else if (set_draw_id) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
radeon_emit(cs, base_vertex);
radeon_emit(cs, info->drawid);
radeon_emit(cs, drawid_base);
sctx->last_drawid = info->drawid;
sctx->last_drawid = drawid_base;
} else {
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, base_vertex);
}
@ -1175,7 +1176,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
}
/* Don't update draw_id in the following code if it doesn't increment. */
set_draw_id &= info->increment_draw_id;
bool increment_draw_id = num_draws > 1 && set_draw_id && info->increment_draw_id;
if (index_size) {
if (ALLOW_PRIM_DISCARD_CS && dispatch_prim_discard_cs) {
@ -1192,29 +1193,95 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
return;
}
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
/* NOT_EOP allows merging multiple draws into 1 wave, but only user VGPRs
* can be changed between draws, and GS fast launch must be disabled.
* NOT_EOP doesn't work on gfx9 and older.
*
* Instead of doing this, which evaluates the case conditions repeatedly:
* for (all draws) {
* if (case1);
* else;
* }
*
* Use this structuring to evaluate the case conditions once:
* if (case1) for (all draws);
* else for (all draws);
*
*/
bool index_bias_varies = num_draws > 1 && info->index_bias_varies;
if (i > 0 && set_draw_id) {
unsigned draw_id = info->drawid + i;
if (increment_draw_id) {
if (index_bias_varies) {
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, draw_id);
sctx->last_drawid = draw_id;
if (i > 0) {
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
radeon_emit(cs, draws[i].index_bias);
radeon_emit(cs, drawid_base + i);
}
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
radeon_emit(cs, index_max_size);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
radeon_emit(cs, draws[i].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA); /* NOT_EOP disabled */
}
if (num_draws > 1) {
sctx->last_base_vertex = draws[num_draws - 1].index_bias;
sctx->last_drawid = drawid_base + num_draws - 1;
}
} else {
/* Only DrawID varies. */
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
if (i > 0)
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, drawid_base + i);
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
radeon_emit(cs, index_max_size);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
radeon_emit(cs, draws[i].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA); /* NOT_EOP disabled */
}
if (num_draws > 1)
sctx->last_drawid = drawid_base + num_draws - 1;
}
} else {
if (info->index_bias_varies) {
/* Only BaseVertex varies. */
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
radeon_emit(cs, index_max_size);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
radeon_emit(cs, draws[i].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA |
/* NOT_EOP allows merging multiple draws into 1 wave, but only user VGPRs
* can be changed between draws and GS fast launch must be disabled.
* NOT_EOP doesn't work on gfx9 and older.
*/
S_0287F0_NOT_EOP(GFX_VERSION >= GFX10 &&
!set_draw_id &&
i < num_draws - 1));
if (i > 0)
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, draws[i].index_bias);
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
radeon_emit(cs, index_max_size);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
radeon_emit(cs, draws[i].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA); /* NOT_EOP disabled */
}
if (num_draws > 1)
sctx->last_base_vertex = draws[num_draws - 1].index_bias;
} else {
/* DrawID and BaseVertex are constant. */
for (unsigned i = 0; i < num_draws; i++) {
uint64_t va = index_va + draws[i].start * index_size;
radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
radeon_emit(cs, index_max_size);
radeon_emit(cs, va);
radeon_emit(cs, va >> 32);
radeon_emit(cs, draws[i].count);
radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA |
S_0287F0_NOT_EOP(GFX_VERSION >= GFX10 && i < num_draws - 1));
}
}
}
} else {
/* Set the index buffer for fast launch. The VS prolog will load the indices. */
@ -1233,8 +1300,8 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
radeon_emit(cs, index_va >> 32);
if (i > 0) {
if (set_draw_id) {
unsigned draw_id = info->drawid + i;
if (increment_draw_id) {
unsigned draw_id = drawid_base + i;
radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, draw_id);
sctx->last_drawid = draw_id;
@ -1254,8 +1321,8 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
for (unsigned i = 0; i < num_draws; i++) {
if (i > 0) {
if (set_draw_id) {
unsigned draw_id = info->drawid + i;
if (increment_draw_id) {
unsigned draw_id = drawid_base + i;
radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
radeon_emit(cs, draws[i].start);

View File

@ -278,7 +278,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
ret = svga_hwtnl_simple_draw_range_elements(hwtnl, index_buffer,
info->index_size,
info->index_bias,
draw->index_bias,
info->index_bounds_valid ? info->min_index : 0,
info->index_bounds_valid ? info->max_index : ~0,
gen_prim, index_offset, count,
@ -306,7 +306,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
ret = svga_hwtnl_simple_draw_range_elements(hwtnl,
gen_buf,
gen_size,
info->index_bias,
draw->index_bias,
info->index_bounds_valid ? info->min_index : 0,
info->index_bounds_valid ? info->max_index : ~0,
gen_prim, gen_offset,

View File

@ -262,7 +262,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
* always start from 0 for DrawArrays and does not include baseVertex for
* DrawIndexed.
*/
unsigned index_bias = info->index_size ? info->index_bias : 0;
unsigned index_bias = info->index_size ? draws->index_bias : 0;
if (svga->curr.vertex_id_bias != (draws[0].start + index_bias)) {
svga->curr.vertex_id_bias = draws[0].start + index_bias;
svga->dirty |= SVGA_NEW_VS_CONSTS;

View File

@ -329,7 +329,6 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
.index.user = indices,
.start_instance = 0,
.instance_count = 1,
.index_bias = bias,
.index_bounds_valid = true,
.min_index = svga_render->min_index,
.max_index = svga_render->max_index,
@ -337,6 +336,7 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
const struct pipe_draw_start_count_bias draw = {
.start = 0,
.count = nr_indices,
.index_bias = bias,
};
assert((svga_render->vbuf_offset - svga_render->vdecl_offset)

View File

@ -254,7 +254,7 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
draws[0].count,
info->instance_count,
draws[0].start,
info->index_bias,
draws->index_bias,
info->start_instance);
else
ctx->api.pfnSwrDrawInstanced(ctx->swrContext,

View File

@ -1113,7 +1113,8 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
uint32_t i,
uint32_t *totelems,
uint32_t *base,
uint32_t *size)
uint32_t *size,
int index_bias)
{
/* FIXME: The size is too large - we don't access the full extra stride. */
unsigned elems;
@ -1125,8 +1126,8 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
*size = elems * elem_pitch;
} else if (vb->stride) {
elems = info->max_index - info->min_index + 1;
*totelems = (info->max_index + (info->index_size ? info->index_bias : 0)) + 1;
*base = (info->min_index + (info->index_size ? info->index_bias : 0)) * vb->stride;
*totelems = (info->max_index + (info->index_size ? index_bias : 0)) + 1;
*base = (info->min_index + (info->index_size ? index_bias : 0)) * vb->stride;
*size = elems * elem_pitch;
} else {
*totelems = 1;
@ -1430,9 +1431,9 @@ swr_update_derived(struct pipe_context *pipe,
post_update_dirty_flags |= SWR_NEW_VERTEX;
uint32_t base;
swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems, &base, &size);
swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems, &base, &size, draw->index_bias);
partial_inbounds = 0;
min_vertex_index = info.min_index + (info.index_size ? info.index_bias : 0);
min_vertex_index = info.min_index + (info.index_size ? draw->index_bias : 0);
size = AlignUp(size, 4);
/* If size of client memory copy is too large, don't copy. The

View File

@ -1273,10 +1273,10 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
/* The Base Vertex/Base Instance packet sets those values to nonzero
* for the next draw call only.
*/
if ((info->index_size && info->index_bias) || info->start_instance) {
if ((info->index_size && draws->index_bias) || info->start_instance) {
cl_emit(&job->bcl, BASE_VERTEX_BASE_INSTANCE, base) {
base.base_instance = info->start_instance;
base.base_vertex = info->index_size ? info->index_bias : 0;
base.base_vertex = info->index_size ? draws->index_bias : 0;
}
}

View File

@ -133,6 +133,7 @@ vc4_predraw_check_textures(struct pipe_context *pctx,
static void
vc4_emit_gl_shader_state(struct vc4_context *vc4,
const struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draws,
uint32_t extra_index_bias)
{
struct vc4_job *job = vc4->job;
@ -183,7 +184,7 @@ vc4_emit_gl_shader_state(struct vc4_context *vc4,
};
uint32_t max_index = 0xffff;
unsigned index_bias = info->index_size ? info->index_bias : 0;
unsigned index_bias = info->index_size ? draws->index_bias : 0;
for (int i = 0; i < vtx->num_elements; i++) {
struct pipe_vertex_element *elem = &vtx->pipe[i];
struct pipe_vertex_buffer *vb =
@ -358,7 +359,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
bool needs_drawarrays_shader_state = false;
unsigned index_bias = info->index_size ? info->index_bias : 0;
unsigned index_bias = info->index_size ? draws->index_bias : 0;
if ((vc4->dirty & (VC4_DIRTY_VTXBUF |
VC4_DIRTY_VTXSTATE |
VC4_DIRTY_PRIM_MODE |
@ -371,7 +372,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
vc4->prog.fs->uniform_dirty_bits)) ||
vc4->last_index_bias != index_bias) {
if (info->index_size)
vc4_emit_gl_shader_state(vc4, info, 0);
vc4_emit_gl_shader_state(vc4, info, draws, 0);
else
needs_drawarrays_shader_state = true;
}
@ -467,7 +468,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
uint32_t step;
if (needs_drawarrays_shader_state) {
vc4_emit_gl_shader_state(vc4, info,
vc4_emit_gl_shader_state(vc4, info, draws,
extra_index_bias);
}

View File

@ -752,7 +752,7 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
virgl_encoder_write_dword(ctx->cbuf, info->mode);
virgl_encoder_write_dword(ctx->cbuf, !!info->index_size);
virgl_encoder_write_dword(ctx->cbuf, info->instance_count);
virgl_encoder_write_dword(ctx->cbuf, info->index_size ? info->index_bias : 0);
virgl_encoder_write_dword(ctx->cbuf, info->index_size ? draw->index_bias : 0);
virgl_encoder_write_dword(ctx->cbuf, info->start_instance);
virgl_encoder_write_dword(ctx->cbuf, info->primitive_restart);
virgl_encoder_write_dword(ctx->cbuf, info->primitive_restart ? info->restart_index : 0);

View File

@ -565,7 +565,7 @@ zink_draw_vbo(struct pipe_context *pctx,
update_drawid(ctx, draw_id);
vkCmdDrawIndexed(batch->state->cmdbuf,
draws[i].count, dinfo->instance_count,
need_index_buffer_unref ? 0 : draws[i].start, dinfo->index_bias, dinfo->start_instance);
need_index_buffer_unref ? 0 : draws[i].start, draws[i].index_bias, dinfo->start_instance);
if (dinfo->increment_draw_id)
draw_id++;
}

View File

@ -742,11 +742,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawIndexed(
return;
cmd->u.draw_indexed.instance_count = instanceCount;
cmd->u.draw_indexed.vertex_offset = vertexOffset;
cmd->u.draw_indexed.first_instance = firstInstance;
cmd->u.draw_indexed.draw_count = 1;
cmd->u.draw_indexed.draws[0].start = firstIndex;
cmd->u.draw_indexed.draws[0].count = indexCount;
cmd->u.draw_indexed.draws[0].index_bias = vertexOffset;
cmd->u.draw_indexed.calc_start = true;
cmd_buf_queue(cmd_buffer, cmd);

View File

@ -2140,7 +2140,6 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
state->info.index.resource = state->index_buffer;
state->info.start_instance = cmd->u.draw_indexed.first_instance;
state->info.instance_count = cmd->u.draw_indexed.instance_count;
state->info.index_bias = cmd->u.draw_indexed.vertex_offset;
state->info.view_mask = subpass->view_mask;
if (state->info.primitive_restart)

View File

@ -748,7 +748,6 @@ struct lvp_cmd_draw {
struct lvp_cmd_draw_indexed {
uint32_t instance_count;
uint32_t vertex_offset;
uint32_t first_instance;
bool calc_start;
uint32_t draw_count;

View File

@ -3308,7 +3308,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
draw.instance_count = 1;
draw.index_size = 0;
sc.start = 0;
draw.index_bias = 0;
sc.index_bias = 0;
draw.min_index = 0;
draw.max_index = VertexCount - 1;

View File

@ -2383,7 +2383,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive,
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = 0;
draw.start = StartVertex;
info.index_bias = 0;
draw.index_bias = 0;
info.min_index = draw.start;
info.max_index = draw.start + draw.count - 1;
info.index.resource = NULL;
@ -2408,7 +2408,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive,
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = context->index_size;
draw.start = context->index_offset / context->index_size + StartIndex;
info.index_bias = BaseVertexIndex;
draw.index_bias = BaseVertexIndex;
info.index_bounds_valid = true;
/* These don't include index bias: */
info.min_index = MinVertexIndex;
@ -2438,7 +2438,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf,
init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
info.index_size = index_size;
draw.start = index_offset / info.index_size;
info.index_bias = 0;
draw.index_bias = 0;
info.index_bounds_valid = true;
info.min_index = MinVertexIndex;
info.max_index = MinVertexIndex + NumVertices - 1;

View File

@ -120,7 +120,7 @@ struct pipe_context {
* - PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: Indirect draw count
*
* Differences against glMultiDraw and glMultiMode:
* - "info->mode" and "info->index_bias" are always constant due to the lack
* - "info->mode" and "draws->index_bias" are always constant due to the lack
* of hardware support and CPU performance concerns. Only start and count
* vary.
* - if "info->increment_draw_id" is false, draw_id doesn't change between

View File

@ -756,17 +756,13 @@ struct pipe_draw_info
bool increment_draw_id:1; /**< whether drawid increments for direct draws */
bool take_index_buffer_ownership:1; /**< callee inherits caller's refcount
(no need to reference indexbuf, but still needs to unreference it) */
char _pad:1; /**< padding for memcmp */
bool index_bias_varies:1; /**< true if index_bias varies between draws */
unsigned start_instance; /**< first instance id */
unsigned instance_count; /**< number of instances */
unsigned drawid; /**< id of this draw in a multidraw */
/**
* For indexed drawing, these fields apply after index lookup.
*/
int index_bias; /**< a bias to be added to each index */
int _pad2; /**< padding for memcmp and index_bias reuse */
/**
* Primitive restart enable/index (only applies to indexed drawing)

View File

@ -202,6 +202,7 @@ static void draw( void )
info.mode = PIPE_PRIM_TRIANGLES;
draw.start = 0;
draw.count = 3;
draw.index_bias = 0;
/* draw NUM_INST triangles */
info.instance_count = NUM_INST;

View File

@ -585,16 +585,14 @@ struct dd_function_table {
unsigned num_draws);
/**
* Same as DrawGallium, but base_vertex and mode can also change between draws.
* Same as DrawGallium, but mode can also change between draws.
*
* If index_bias != NULL, index_bias changes for each draw.
* If mode != NULL, mode changes for each draw.
* At least one of them must be non-NULL.
*
* "info" is not const and the following fields can be changed by
* the callee in addition to the fields listed by DrawGallium:
* - info->mode (if mode != NULL)
* - info->index_bias (if index_bias != NULL)
*
* This function exists to decrease complexity of DrawGallium.
*/
@ -602,7 +600,6 @@ struct dd_function_table {
struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draws,
const unsigned char *mode,
const int *base_vertex,
unsigned num_draws);
/**

View File

@ -993,7 +993,7 @@ _mesa_draw_gallium_fallback(struct gl_context *ctx,
prim.end = 1;
prim.start = index_size && info->has_user_indices ? 0 : draws[i].start;
prim.count = draws[i].count;
prim.basevertex = index_size ? info->index_bias : 0;
prim.basevertex = index_size ? draws[i].index_bias : 0;
prim.draw_id = info->drawid + (info->increment_draw_id ? i : 0);
if (!index_size) {
@ -1027,7 +1027,7 @@ _mesa_draw_gallium_fallback(struct gl_context *ctx,
prim[num_prims].end = 1;
prim[num_prims].start = draws[i].start;
prim[num_prims].count = draws[i].count;
prim[num_prims].basevertex = info->index_size ? info->index_bias : 0;
prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0;
prim[num_prims].draw_id = info->drawid + (info->increment_draw_id ? i : 0);
if (!index_size) {
@ -1068,58 +1068,20 @@ _mesa_draw_gallium_complex_fallback(struct gl_context *ctx,
struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draws,
const unsigned char *mode,
const int *base_vertex,
unsigned num_draws)
{
enum {
MODE = 1,
BASE_VERTEX = 2,
};
unsigned mask = (mode ? MODE : 0) | (base_vertex ? BASE_VERTEX : 0);
unsigned i, first;
/* Find consecutive draws where mode and base_vertex don't vary. */
switch (mask) {
case MODE:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || mode[i] != mode[first]) {
info->mode = mode[first];
ctx->Driver.DrawGallium(ctx, info, &draws[first], i - first);
first = i;
}
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || mode[i] != mode[first]) {
info->mode = mode[first];
ctx->Driver.DrawGallium(ctx, info, &draws[first], i - first);
first = i;
}
break;
case BASE_VERTEX:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || base_vertex[i] != base_vertex[first]) {
info->index_bias = base_vertex[first];
ctx->Driver.DrawGallium(ctx, info, &draws[first], i - first);
first = i;
}
}
break;
case MODE | BASE_VERTEX:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws ||
mode[i] != mode[first] ||
base_vertex[i] != base_vertex[first]) {
info->mode = mode[first];
info->index_bias = base_vertex[first];
ctx->Driver.DrawGallium(ctx, info, &draws[first], i - first);
first = i;
}
}
break;
default:
assert(!"invalid parameters in DrawGalliumComplex");
break;
}
}
/**
* Check that element 'j' of the array has reasonable data.
* Map VBO if needed.
@ -1331,8 +1293,9 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
info.index_bounds_valid = true;
info.increment_draw_id = false;
info.take_index_buffer_ownership = false;
info._pad = 0;
info.index_bias_varies = false;
/* Packed section end. */
info._pad2 = 0;
info.start_instance = baseInstance;
info.instance_count = numInstances;
info.drawid = 0;
@ -1660,8 +1623,9 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first,
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
info.take_index_buffer_ownership = false;
info._pad = 0;
info.index_bias_varies = false;
/* Packed section end. */
info._pad2 = 0;
info.start_instance = 0;
info.instance_count = 1;
info.drawid = 0;
@ -1775,13 +1739,13 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
info.index_bounds_valid = index_bounds_valid;
info.increment_draw_id = false;
info.take_index_buffer_ownership = false;
info._pad = 0;
info.index_bias_varies = false;
/* Packed section end. */
info._pad2 = 0;
info.start_instance = baseInstance;
info.instance_count = numInstances;
info.drawid = 0;
info.view_mask = 0;
info.index_bias = basevertex;
info.restart_index = ctx->Array._RestartIndex[index_size_shift];
if (info.has_user_indices) {
@ -1791,6 +1755,7 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
info.index.gl_bo = index_bo;
draw.start = (uintptr_t)indices >> index_size_shift;
}
draw.index_bias = basevertex;
info.min_index = start;
info.max_index = end;
@ -2151,17 +2116,6 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
}
}
/* See if BaseVertex is constant across all draws. */
bool basevertex_is_constant = true;
if (basevertex) {
for (int i = 1; i < primcount; i++) {
if (basevertex[i] != basevertex[0]) {
basevertex_is_constant = false;
break;
}
}
}
struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj;
struct pipe_draw_info info;
@ -2174,8 +2128,9 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
info.take_index_buffer_ownership = false;
info._pad = 0;
info.index_bias_varies = !!basevertex;
/* Packed section end. */
info._pad2 = 0;
info.start_instance = 0;
info.instance_count = 1;
info.drawid = 0;
@ -2206,21 +2161,17 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
draw[i].start =
((uintptr_t)indices[i] - min_index_ptr) >> index_size_shift;
draw[i].count = count[i];
draw[i].index_bias = basevertex ? basevertex[i] : 0;
}
} else {
for (int i = 0; i < primcount; i++) {
draw[i].start = (uintptr_t)indices[i] >> index_size_shift;
draw[i].count = count[i];
draw[i].index_bias = basevertex ? basevertex[i] : 0;
}
}
if (basevertex_is_constant) {
info.index_bias = basevertex ? basevertex[0] : 0;
ctx->Driver.DrawGallium(ctx, &info, draw, primcount);
} else {
ctx->Driver.DrawGalliumComplex(ctx, &info, draw, NULL, basevertex,
primcount);
}
ctx->Driver.DrawGallium(ctx, &info, draw, primcount);
FREE_PRIMS(draw, primcount);
} else {
/* draw[i].start would overflow. Draw one at a time. */
@ -2235,10 +2186,10 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
/* Reset these, because the callee can change them. */
info.index_bounds_valid = false;
info.index_bias = basevertex ? basevertex[i] : 0;
info.drawid = i;
info.index.user = indices[i];
draw.start = 0;
draw.index_bias = basevertex ? basevertex[i] : 0;
draw.count = count[i];
ctx->Driver.DrawGallium(ctx, &info, &draw, 1);

View File

@ -98,7 +98,6 @@ _mesa_draw_gallium_complex_fallback(struct gl_context *ctx,
struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draws,
const unsigned char *mode,
const int *base_vertex,
unsigned num_draws);
void GLAPIENTRY

View File

@ -191,7 +191,6 @@ st_draw_gallium_complex(struct gl_context *ctx,
struct pipe_draw_info *info,
const struct pipe_draw_start_count_bias *draws,
const unsigned char *mode,
const int *base_vertex,
unsigned num_draws)
{
struct st_context *st = st_context(ctx);
@ -201,67 +200,21 @@ st_draw_gallium_complex(struct gl_context *ctx,
if (!prepare_indexed_draw(st, ctx, info, draws, num_draws))
return;
enum {
MODE = 1,
BASE_VERTEX = 2,
};
unsigned mask = (mode ? MODE : 0) | (base_vertex ? BASE_VERTEX : 0);
unsigned i, first;
struct cso_context *cso = st->cso_context;
/* Find consecutive draws where mode and base_vertex don't vary. */
switch (mask) {
case MODE:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || mode[i] != mode[first]) {
info->mode = mode[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || mode[i] != mode[first]) {
info->mode = mode[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
/* We can pass the reference only once. st_buffer_object keeps
* the reference alive for later draws.
*/
info->take_index_buffer_ownership = false;
}
/* We can pass the reference only once. st_buffer_object keeps
* the reference alive for later draws.
*/
info->take_index_buffer_ownership = false;
}
break;
case BASE_VERTEX:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws || base_vertex[i] != base_vertex[first]) {
info->index_bias = base_vertex[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
/* We can pass the reference only once. st_buffer_object keeps
* the reference alive for later draws.
*/
info->take_index_buffer_ownership = false;
}
}
break;
case MODE | BASE_VERTEX:
for (i = 0, first = 0; i <= num_draws; i++) {
if (i == num_draws ||
mode[i] != mode[first] ||
base_vertex[i] != base_vertex[first]) {
info->mode = mode[first];
info->index_bias = base_vertex[first];
cso_multi_draw(cso, info, &draws[first], i - first);
first = i;
/* We can pass the reference only once. st_buffer_object keeps
* the reference alive for later draws.
*/
info->take_index_buffer_ownership = false;
}
}
break;
default:
assert(!"invalid parameters in DrawGalliumComplex");
break;
}
}

View File

@ -451,7 +451,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
d.start = start + prims[i].start;
info.mode = prims[i].mode;
info.index_bias = prims[i].basevertex;
d.index_bias = prims[i].basevertex;
info.drawid = prims[i].draw_id;
if (!ib) {
info.min_index = d.start;

View File

@ -336,7 +336,6 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
ctx->Driver.DrawGalliumComplex(ctx, &exec->vtx.info,
exec->vtx.draw,
exec->vtx.mode,
NULL,
exec->vtx.prim_count);
/* Get new storage -- unless asked not to. */

View File

@ -818,6 +818,7 @@ compile_vertex_list(struct gl_context *ctx)
for (unsigned i = 0; i < merged_prim_count; i++) {
node->merged.start_count[i].start = merged_prims[i].start;
node->merged.start_count[i].count = merged_prims[i].count;
node->merged.start_count[i].index_bias = 0;
if (merged_prim_count > 1)
node->merged.mode[i] = merged_prims[i].mode;
}

View File

@ -238,7 +238,6 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
ctx->Driver.DrawGalliumComplex(ctx, info,
node->merged.start_count,
node->merged.mode,
NULL,
node->merged.num_draws);
} else {
ctx->Driver.DrawGallium(ctx, info,