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:
parent
4fe6c85526
commit
4566383ae4
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 ||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) |
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue