From 4566383ae4bf28b99576ae9d293c50decc771888 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Sun, 11 Apr 2021 10:26:29 -0400 Subject: [PATCH] gallium: move pipe_draw_info::index_bias to pipe_draw_start_count_bias MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Part-of: --- src/gallium/auxiliary/cso_cache/cso_context.c | 2 + src/gallium/auxiliary/draw/draw_pt.c | 22 ++-- src/gallium/auxiliary/driver_ddebug/dd_draw.c | 2 +- src/gallium/auxiliary/driver_trace/tr_dump_state.c | 2 +- src/gallium/auxiliary/indices/u_primconvert.c | 2 +- src/gallium/auxiliary/util/u_draw.c | 2 +- src/gallium/auxiliary/util/u_draw.h | 6 +- src/gallium/auxiliary/util/u_dump.h | 2 +- src/gallium/auxiliary/util/u_dump_state.c | 4 +- src/gallium/auxiliary/util/u_threaded_context.c | 44 +++++-- src/gallium/auxiliary/util/u_vbuf.c | 8 +- src/gallium/drivers/d3d12/d3d12_draw.cpp | 4 +- src/gallium/drivers/etnaviv/etnaviv_context.c | 4 +- src/gallium/drivers/freedreno/a3xx/fd3_draw.c | 6 +- src/gallium/drivers/freedreno/a4xx/fd4_draw.c | 2 +- src/gallium/drivers/freedreno/a5xx/fd5_draw.c | 2 +- src/gallium/drivers/freedreno/a6xx/fd6_draw.c | 2 +- src/gallium/drivers/freedreno/ir3/ir3_const.h | 2 +- src/gallium/drivers/iris/iris_draw.c | 2 +- src/gallium/drivers/iris/iris_state.c | 2 +- src/gallium/drivers/lima/lima_draw.c | 2 +- src/gallium/drivers/nouveau/nv30/nv30_push.c | 4 +- src/gallium/drivers/nouveau/nv30/nv30_vbo.c | 2 +- src/gallium/drivers/nouveau/nv50/nv50_push.c | 6 +- src/gallium/drivers/nouveau/nv50/nv50_vbo.c | 4 +- src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c | 6 +- .../drivers/nouveau/nvc0/nvc0_vbo_translate.c | 18 +-- src/gallium/drivers/panfrost/pan_context.c | 8 +- src/gallium/drivers/r300/r300_render.c | 30 ++--- src/gallium/drivers/r600/r600_state_common.c | 2 +- src/gallium/drivers/radeonsi/si_pipe.h | 2 +- src/gallium/drivers/radeonsi/si_state_draw.cpp | 129 ++++++++++++++++----- src/gallium/drivers/svga/svga_draw_elements.c | 4 +- src/gallium/drivers/svga/svga_pipe_draw.c | 2 +- src/gallium/drivers/svga/svga_swtnl_backend.c | 2 +- src/gallium/drivers/swr/swr_draw.cpp | 2 +- src/gallium/drivers/swr/swr_state.cpp | 11 +- src/gallium/drivers/v3d/v3dx_draw.c | 4 +- src/gallium/drivers/vc4/vc4_draw.c | 9 +- src/gallium/drivers/virgl/virgl_encode.c | 2 +- src/gallium/drivers/zink/zink_draw.c | 2 +- src/gallium/frontends/lavapipe/lvp_cmd_buffer.c | 2 +- src/gallium/frontends/lavapipe/lvp_execute.c | 1 - src/gallium/frontends/lavapipe/lvp_private.h | 1 - src/gallium/frontends/nine/device9.c | 2 +- src/gallium/frontends/nine/nine_state.c | 6 +- src/gallium/include/pipe/p_context.h | 2 +- src/gallium/include/pipe/p_state.h | 8 +- src/gallium/tests/graw/tri-instanced.c | 1 + src/mesa/main/dd.h | 5 +- src/mesa/main/draw.c | 93 ++++----------- src/mesa/main/draw.h | 1 - src/mesa/state_tracker/st_draw.c | 67 ++--------- src/mesa/state_tracker/st_draw_feedback.c | 2 +- src/mesa/vbo/vbo_exec_draw.c | 1 - src/mesa/vbo/vbo_save_api.c | 1 + src/mesa/vbo/vbo_save_draw.c | 1 - 57 files changed, 277 insertions(+), 290 deletions(-) diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index da4bc3c..64c48d0 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -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); } diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index 551a8b9..11980fe 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -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, diff --git a/src/gallium/auxiliary/driver_ddebug/dd_draw.c b/src/gallium/auxiliary/driver_ddebug/dd_draw.c index a55ce32..e9f481d 100644 --- a/src/gallium/auxiliary/driver_ddebug/dd_draw.c +++ b/src/gallium/auxiliary/driver_ddebug/dd_draw.c @@ -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); diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c index c74b9dc..fff9569 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.c +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -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(); } diff --git a/src/gallium/auxiliary/indices/u_primconvert.c b/src/gallium/auxiliary/indices/u_primconvert.c index ff8bf86..d09dc67 100644 --- a/src/gallium/auxiliary/indices/u_primconvert.c +++ b/src/gallium/auxiliary/indices/u_primconvert.c @@ -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); diff --git a/src/gallium/auxiliary/util/u_draw.c b/src/gallium/auxiliary/util/u_draw.c index 802aa48..36bd2fc 100644 --- a/src/gallium/auxiliary/util/u_draw.c +++ b/src/gallium/auxiliary/util/u_draw.c @@ -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; diff --git a/src/gallium/auxiliary/util/u_draw.h b/src/gallium/auxiliary/util/u_draw.h index 287d2b5..dea30fb 100644 --- a/src/gallium/auxiliary/util/u_draw.h +++ b/src/gallium/auxiliary/util/u_draw.h @@ -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; diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h index a4f1f0a..0e7f4c2 100644 --- a/src/gallium/auxiliary/util/u_dump.h +++ b/src/gallium/auxiliary/util/u_dump.h @@ -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, diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c index 6ef5e0e..ecb9b72 100644 --- a/src/gallium/auxiliary/util/u_dump_state.c +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -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); } diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c index 36b6e3b..b0ec2d4 100644 --- a/src/gallium/auxiliary/util/u_threaded_context.c +++ b/src/gallium/auxiliary/util/u_threaded_context.c @@ -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; } diff --git a/src/gallium/auxiliary/util/u_vbuf.c b/src/gallium/auxiliary/util/u_vbuf.c index 0f140d6..883ca6e 100644 --- a/src/gallium/auxiliary/util/u_vbuf.c +++ b/src/gallium/auxiliary/util/u_vbuf.c @@ -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; diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp b/src/gallium/drivers/d3d12/d3d12_draw.cpp index d37d74f..037403c 100644 --- a/src/gallium/drivers/d3d12/d3d12_draw.cpp +++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp @@ -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, diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index 64c458c..2d5aa9a 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -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); } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c index 5ec3e50..cdf2330 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_draw.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_draw.c @@ -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); diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c index f17a485..5136a9e 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_draw.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_draw.c @@ -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 */ diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c index 9b6fb43..0f59623 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c @@ -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 */ diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c index fd797b4..500e4f7 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c @@ -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 */ diff --git a/src/gallium/drivers/freedreno/ir3/ir3_const.h b/src/gallium/drivers/freedreno/ir3/ir3_const.h index d02fe07..bdef67d 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_const.h +++ b/src/gallium/drivers/freedreno/ir3/ir3_const.h @@ -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, }; diff --git a/src/gallium/drivers/iris/iris_draw.c b/src/gallium/drivers/iris/iris_draw.c index ef5c29d..fb19055 100644 --- a/src/gallium/drivers/iris/iris_draw.c +++ b/src/gallium/drivers/iris/iris_draw.c @@ -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 || diff --git a/src/gallium/drivers/iris/iris_state.c b/src/gallium/drivers/iris/iris_state.c index 60211f9..2b4fd0c 100644 --- a/src/gallium/drivers/iris/iris_state.c +++ b/src/gallium/drivers/iris/iris_state.c @@ -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; } } } diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c index 3abee78..19a38fd 100644 --- a/src/gallium/drivers/lima/lima_draw.c +++ b/src/gallium/drivers/lima/lima_draw.c @@ -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) | diff --git a/src/gallium/drivers/nouveau/nv30/nv30_push.c b/src/gallium/drivers/nouveau/nv30/nv30_push.c index 33ed47a..4bd799c 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_push.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_push.c @@ -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); } diff --git a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c index 892eeb6..b7d56e2 100644 --- a/src/gallium/drivers/nouveau/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nouveau/nv30/nv30_vbo.c @@ -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); diff --git a/src/gallium/drivers/nouveau/nv50/nv50_push.c b/src/gallium/drivers/nouveau/nv50/nv50_push.c index e7709c2..87104e4 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_push.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_push.c @@ -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); } diff --git a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c index ed8c131..8a4dd81 100644 --- a/src/gallium/drivers/nouveau/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nouveau/nv50/nv50_vbo.c @@ -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); diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c index 1e89015..08ce6b3 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c @@ -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, diff --git a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c index badb594..f69c0d8 100644 --- a/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c +++ b/src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c @@ -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) | diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 30c4f13..c2d9379 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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); diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c index 3fc0608..5ef6ee6 100644 --- a/src/gallium/drivers/r300/r300_render.c +++ b/src/gallium/drivers/r300/r300_render.c @@ -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; } diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index 17cd65c..4844c90 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -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; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index 8fed716..ec812d5 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -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) diff --git a/src/gallium/drivers/radeonsi/si_state_draw.cpp b/src/gallium/drivers/radeonsi/si_state_draw.cpp index 3a26dc6..c9da1cf 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.cpp +++ b/src/gallium/drivers/radeonsi/si_state_draw.cpp @@ -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 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)); + 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; + + 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); diff --git a/src/gallium/drivers/svga/svga_draw_elements.c b/src/gallium/drivers/svga/svga_draw_elements.c index b5ac35e..fa165da 100644 --- a/src/gallium/drivers/svga/svga_draw_elements.c +++ b/src/gallium/drivers/svga/svga_draw_elements.c @@ -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, diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index c943c03..35adabf 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -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; diff --git a/src/gallium/drivers/svga/svga_swtnl_backend.c b/src/gallium/drivers/svga/svga_swtnl_backend.c index c0e7266..3c9a524 100644 --- a/src/gallium/drivers/svga/svga_swtnl_backend.c +++ b/src/gallium/drivers/svga/svga_swtnl_backend.c @@ -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) diff --git a/src/gallium/drivers/swr/swr_draw.cpp b/src/gallium/drivers/swr/swr_draw.cpp index fb8bbd4..96c862f 100644 --- a/src/gallium/drivers/swr/swr_draw.cpp +++ b/src/gallium/drivers/swr/swr_draw.cpp @@ -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, diff --git a/src/gallium/drivers/swr/swr_state.cpp b/src/gallium/drivers/swr/swr_state.cpp index 5ee24b5..bea1c1e 100644 --- a/src/gallium/drivers/swr/swr_state.cpp +++ b/src/gallium/drivers/swr/swr_state.cpp @@ -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 diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c index 8b5eed4..c7972f8 100644 --- a/src/gallium/drivers/v3d/v3dx_draw.c +++ b/src/gallium/drivers/v3d/v3dx_draw.c @@ -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; } } diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index dfe2c35..b3d0996 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -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); } diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c index 214d384..8fd302f 100644 --- a/src/gallium/drivers/virgl/virgl_encode.c +++ b/src/gallium/drivers/virgl/virgl_encode.c @@ -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); diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index e457e66..b4c4734 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -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++; } diff --git a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c index 9fc757f..1b2744a 100644 --- a/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c +++ b/src/gallium/frontends/lavapipe/lvp_cmd_buffer.c @@ -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); diff --git a/src/gallium/frontends/lavapipe/lvp_execute.c b/src/gallium/frontends/lavapipe/lvp_execute.c index 76470b3..fcbf2a5 100644 --- a/src/gallium/frontends/lavapipe/lvp_execute.c +++ b/src/gallium/frontends/lavapipe/lvp_execute.c @@ -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) diff --git a/src/gallium/frontends/lavapipe/lvp_private.h b/src/gallium/frontends/lavapipe/lvp_private.h index 4c61ae8..6c2c5c8 100644 --- a/src/gallium/frontends/lavapipe/lvp_private.h +++ b/src/gallium/frontends/lavapipe/lvp_private.h @@ -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; diff --git a/src/gallium/frontends/nine/device9.c b/src/gallium/frontends/nine/device9.c index 49d82bb..5bd6f25 100644 --- a/src/gallium/frontends/nine/device9.c +++ b/src/gallium/frontends/nine/device9.c @@ -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; diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 543ed11..fc3fd8e 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -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; diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index 6364223..52c77b8 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -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 diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 5ecb060..45073c5 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -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) diff --git a/src/gallium/tests/graw/tri-instanced.c b/src/gallium/tests/graw/tri-instanced.c index 2119468..0390c06 100644 --- a/src/gallium/tests/graw/tri-instanced.c +++ b/src/gallium/tests/graw/tri-instanced.c @@ -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; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index afaad3b..045d204 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -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); /** diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 75af188..ce3507e 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -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; - } - } - 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; - } + 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 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); diff --git a/src/mesa/main/draw.h b/src/mesa/main/draw.h index 0fe0950..b65400f 100644 --- a/src/mesa/main/draw.h +++ b/src/mesa/main/draw.h @@ -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 diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index be9e375..da24e76 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -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; - - /* 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; - } + 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; } - break; - - default: - assert(!"invalid parameters in DrawGalliumComplex"); - break; } } diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 0764cc1..efba838 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -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; diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c index d4eb380..4914cec 100644 --- a/src/mesa/vbo/vbo_exec_draw.c +++ b/src/mesa/vbo/vbo_exec_draw.c @@ -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. */ diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c index 9b0d143..1a895a3 100644 --- a/src/mesa/vbo/vbo_save_api.c +++ b/src/mesa/vbo/vbo_save_api.c @@ -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; } diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c index f2d1c89..4a8b9d7 100644 --- a/src/mesa/vbo/vbo_save_draw.c +++ b/src/mesa/vbo/vbo_save_draw.c @@ -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, -- 2.7.4