gallium: move pipe_draw_info::index_bias to pipe_draw_start_count_bias
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Sun, 11 Apr 2021 14:26:29 +0000 (10:26 -0400)
committerMarge Bot <eric+marge@anholt.net>
Fri, 30 Apr 2021 03:59:19 +0000 (03:59 +0000)
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>

57 files changed:
src/gallium/auxiliary/cso_cache/cso_context.c
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/driver_ddebug/dd_draw.c
src/gallium/auxiliary/driver_trace/tr_dump_state.c
src/gallium/auxiliary/indices/u_primconvert.c
src/gallium/auxiliary/util/u_draw.c
src/gallium/auxiliary/util/u_draw.h
src/gallium/auxiliary/util/u_dump.h
src/gallium/auxiliary/util/u_dump_state.c
src/gallium/auxiliary/util/u_threaded_context.c
src/gallium/auxiliary/util/u_vbuf.c
src/gallium/drivers/d3d12/d3d12_draw.cpp
src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/freedreno/a3xx/fd3_draw.c
src/gallium/drivers/freedreno/a4xx/fd4_draw.c
src/gallium/drivers/freedreno/a5xx/fd5_draw.c
src/gallium/drivers/freedreno/a6xx/fd6_draw.c
src/gallium/drivers/freedreno/ir3/ir3_const.h
src/gallium/drivers/iris/iris_draw.c
src/gallium/drivers/iris/iris_state.c
src/gallium/drivers/lima/lima_draw.c
src/gallium/drivers/nouveau/nv30/nv30_push.c
src/gallium/drivers/nouveau/nv30/nv30_vbo.c
src/gallium/drivers/nouveau/nv50/nv50_push.c
src/gallium/drivers/nouveau/nv50/nv50_vbo.c
src/gallium/drivers/nouveau/nvc0/nvc0_vbo.c
src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c
src/gallium/drivers/panfrost/pan_context.c
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r600/r600_state_common.c
src/gallium/drivers/radeonsi/si_pipe.h
src/gallium/drivers/radeonsi/si_state_draw.cpp
src/gallium/drivers/svga/svga_draw_elements.c
src/gallium/drivers/svga/svga_pipe_draw.c
src/gallium/drivers/svga/svga_swtnl_backend.c
src/gallium/drivers/swr/swr_draw.cpp
src/gallium/drivers/swr/swr_state.cpp
src/gallium/drivers/v3d/v3dx_draw.c
src/gallium/drivers/vc4/vc4_draw.c
src/gallium/drivers/virgl/virgl_encode.c
src/gallium/drivers/zink/zink_draw.c
src/gallium/frontends/lavapipe/lvp_cmd_buffer.c
src/gallium/frontends/lavapipe/lvp_execute.c
src/gallium/frontends/lavapipe/lvp_private.h
src/gallium/frontends/nine/device9.c
src/gallium/frontends/nine/nine_state.c
src/gallium/include/pipe/p_context.h
src/gallium/include/pipe/p_state.h
src/gallium/tests/graw/tri-instanced.c
src/mesa/main/dd.h
src/mesa/main/draw.c
src/mesa/main/draw.h
src/mesa/state_tracker/st_draw.c
src/mesa/state_tracker/st_draw_feedback.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_save_api.c
src/mesa/vbo/vbo_save_draw.c

index da4bc3c..64c48d0 100644 (file)
@@ -1469,6 +1469,7 @@ cso_draw_arrays(struct cso_context *cso, uint mode, uint start, uint count)
 
    draw.start = start;
    draw.count = count;
+   draw.index_bias = 0;
 
    cso_draw_vbo(cso, &info, NULL, draw);
 }
@@ -1492,6 +1493,7 @@ cso_draw_arrays_instanced(struct cso_context *cso, uint mode,
 
    draw.start = start;
    draw.count = count;
+   draw.index_bias = 0;
 
    cso_draw_vbo(cso, &info, NULL, draw);
 }
index 551a8b9..11980fe 100644 (file)
@@ -153,6 +153,7 @@ draw_pt_arrays(struct draw_context *draw,
       } else
          draw_pt_split_prim(prim, &first, &incr);
       count = draw_pt_trim_count(draw_info[i].count, first, incr);
+      draw->pt.user.eltBias = draw->pt.user.eltSize ? draw_info[i].index_bias : 0;
       if (count >= first)
          frontend->run( frontend, draw_info[i].start, count );
 
@@ -245,7 +246,7 @@ void draw_pt_destroy( struct draw_context *draw )
  * Debug- print the first 'count' vertices.
  */
 static void
-draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
+draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count, int index_bias)
 {
    uint i;
 
@@ -282,9 +283,9 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
             assert(0);
             return;
          }
-         ii += draw->pt.user.eltBias;
+         ii += index_bias;
          debug_printf("Element[%u + %u] + %i -> Vertex %u:\n", start, i,
-                      draw->pt.user.eltBias, ii);
+                      index_bias, ii);
       }
       else {
          /* non-indexed arrays */
@@ -358,22 +359,20 @@ draw_print_arrays(struct draw_context *draw, uint prim, int start, uint count)
 static inline void
 prim_restart_loop(struct draw_context *draw,
                   const struct pipe_draw_info *info,
-                  unsigned start,
-                  unsigned count,
+                  const struct pipe_draw_start_count_bias *draw_info,
                   const void *elements)
 {
    const unsigned elt_max = draw->pt.user.eltMax;
-   struct pipe_draw_start_count_bias cur;
-   cur.start = start;
+   struct pipe_draw_start_count_bias cur = *draw_info;
    cur.count = 0;
 
    /* The largest index within a loop using the i variable as the index.
     * Used for overflow detection */
    const unsigned MAX_LOOP_IDX = 0xffffffff;
 
-   for (unsigned j = 0; j < count; j++) {
+   for (unsigned j = 0; j < draw_info->count; j++) {
       unsigned restart_idx = 0;
-      unsigned i = draw_overflow_uadd(start, j, MAX_LOOP_IDX);
+      unsigned i = draw_overflow_uadd(draw_info->start, j, MAX_LOOP_IDX);
       switch (draw->pt.user.eltSize) {
       case 1:
          restart_idx = ((const uint8_t*)elements)[i];
@@ -424,7 +423,7 @@ draw_pt_arrays_restart(struct draw_context *draw,
    if (draw->pt.user.eltSize) {
       /* indexed prims (draw_elements) */
       for (unsigned i = 0; i < num_draws; i++)
-         prim_restart_loop(draw, info, draw_info[i].start, draw_info[i].count, draw->pt.user.elts);
+         prim_restart_loop(draw, info, &draw_info[i], draw->pt.user.elts);
    }
    else {
       /* Non-indexed prims (draw_arrays).
@@ -536,7 +535,6 @@ draw_vbo(struct draw_context *draw,
    if (info->index_size)
       assert(draw->pt.user.elts);
 
-   draw->pt.user.eltBias = use_info->index_size ? use_info->index_bias : 0;
    draw->pt.user.min_index = use_info->index_bounds_valid ? use_info->min_index : 0;
    draw->pt.user.max_index = use_info->index_bounds_valid ? use_info->max_index : ~0;
    draw->pt.user.eltSize = use_info->index_size ? draw->pt.user.eltSizeIB : 0;
@@ -578,7 +576,7 @@ draw_vbo(struct draw_context *draw,
 
    if (0) {
       for (unsigned i = 0; i < num_draws; i++)
-         draw_print_arrays(draw, use_info->mode, use_draws[i].start, MIN2(use_draws[i].count, 20));
+         draw_print_arrays(draw, use_info->mode, use_draws[i].start, MIN2(use_draws[i].count, 20), use_draws[i].index_bias);
    }
 
    index_limit = util_draw_max_index(draw->pt.vertex_buffer,
index a55ce32..e9f481d 100644 (file)
@@ -358,7 +358,7 @@ dd_dump_draw_vbo(struct dd_draw_state *dstate, struct pipe_draw_info *info,
    int sh, i;
 
    DUMP(draw_info, info);
-   DUMP(draw_start_count, draw);
+   DUMP(draw_start_count_bias, draw);
    if (indirect) {
       if (indirect->buffer)
          DUMP_M(resource, indirect, buffer);
index c74b9dc..fff9569 100644 (file)
@@ -800,7 +800,6 @@ void trace_dump_draw_info(const struct pipe_draw_info *state)
 
    trace_dump_member(uint, state, vertices_per_patch);
 
-   trace_dump_member(int,  state, index_bias);
    trace_dump_member(uint, state, min_index);
    trace_dump_member(uint, state, max_index);
 
@@ -819,6 +818,7 @@ void trace_dump_draw_start_count(const struct pipe_draw_start_count_bias *state)
    trace_dump_struct_begin("pipe_draw_start_count_bias");
    trace_dump_member(uint, state, start);
    trace_dump_member(uint, state, count);
+   trace_dump_member(int,  state, index_bias);
    trace_dump_struct_end();
 }
 
index ff8bf86..d09dc67 100644 (file)
@@ -141,7 +141,6 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
    new_info.index_bounds_valid = info->index_bounds_valid;
    new_info.min_index = info->min_index;
    new_info.max_index = info->max_index;
-   new_info.index_bias = info->index_size ? info->index_bias : 0;
    new_info.start_instance = info->start_instance;
    new_info.instance_count = info->instance_count;
    new_info.primitive_restart = info->primitive_restart;
@@ -181,6 +180,7 @@ util_primconvert_draw_vbo(struct primconvert_context *pc,
    u_upload_alloc(pc->pipe->stream_uploader, 0, new_info.index_size * new_draw.count, 4,
                   &ib_offset, &new_info.index.resource, &dst);
    new_draw.start = ib_offset / new_info.index_size;
+   new_draw.index_bias = info->index_size ? draw->index_bias : 0;
 
    if (info->index_size) {
       trans_func(src, draw->start, draw->count, new_draw.count, info->restart_index, dst);
index 802aa48..36bd2fc 100644 (file)
@@ -181,7 +181,7 @@ util_draw_indirect(struct pipe_context *pipe,
       draw.count = params[0];
       info.instance_count = params[1];
       draw.start = params[2];
-      info.index_bias = info_in->index_size ? params[3] : 0;
+      draw.index_bias = info_in->index_size ? params[3] : 0;
       info.start_instance = info_in->index_size ? params[4] : params[3];
       info.drawid = i;
 
index 287d2b5..dea30fb 100644 (file)
@@ -64,6 +64,7 @@ util_draw_arrays(struct pipe_context *pipe,
 
    draw.start = start;
    draw.count = count;
+   draw.index_bias = 0;
 
    pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
 }
@@ -84,7 +85,7 @@ util_draw_elements(struct pipe_context *pipe,
    info.has_user_indices = true;
    info.index_size = index_size;
    info.mode = mode;
-   info.index_bias = index_bias;
+   draw.index_bias = index_bias;
 
    draw.start = start;
    draw.count = count;
@@ -113,6 +114,7 @@ util_draw_arrays_instanced(struct pipe_context *pipe,
 
    draw.start = start;
    draw.count = count;
+   draw.index_bias = 0;
 
    pipe->draw_vbo(pipe, &info, NULL, &draw, 1);
 }
@@ -136,7 +138,7 @@ util_draw_elements_instanced(struct pipe_context *pipe,
    info.has_user_indices = true;
    info.index_size = index_size;
    info.mode = mode;
-   info.index_bias = index_bias;
+   draw.index_bias = index_bias;
    info.start_instance = start_instance;
    info.instance_count = instance_count;
 
index a4f1f0a..0e7f4c2 100644 (file)
@@ -201,7 +201,7 @@ void
 util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state);
 
 void
-util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count_bias *state);
+util_dump_draw_start_count_bias(FILE *stream, const struct pipe_draw_start_count_bias *state);
 
 void
 util_dump_draw_indirect_info(FILE *stream,
index 6ef5e0e..ecb9b72 100644 (file)
@@ -917,7 +917,6 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
 
    util_dump_member(stream, uint, state, vertices_per_patch);
 
-   util_dump_member(stream, int,  state, index_bias);
    util_dump_member(stream, uint, state, min_index);
    util_dump_member(stream, uint, state, max_index);
 
@@ -935,11 +934,12 @@ util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state)
 }
 
 void
-util_dump_draw_start_count(FILE *stream, const struct pipe_draw_start_count_bias *state)
+util_dump_draw_start_count_bias(FILE *stream, const struct pipe_draw_start_count_bias *state)
 {
    util_dump_struct_begin(stream, "pipe_draw_start_count_bias");
    util_dump_member(stream, uint, state, start);
    util_dump_member(stream, uint, state, count);
+   util_dump_member(stream, int,  state, index_bias);
    util_dump_struct_end(stream);
 }
 
index 36b6e3b..b0ec2d4 100644 (file)
@@ -119,7 +119,8 @@ simplify_draw_info(struct pipe_draw_info *info)
    info->has_user_indices = false;
    info->index_bounds_valid = false;
    info->take_index_buffer_ownership = false;
-   info->_pad = 0;
+   info->index_bias_varies = false;
+   info->_pad2 = 0;
 
    /* This shouldn't be set when merging single draws. */
    info->increment_draw_id = false;
@@ -132,7 +133,6 @@ simplify_draw_info(struct pipe_draw_info *info)
          info->restart_index = 0;
    } else {
       assert(!info->primitive_restart);
-      info->index_bias = 0;
       info->primitive_restart = false;
       info->restart_index = 0;
       info->index.resource = NULL;
@@ -142,12 +142,14 @@ simplify_draw_info(struct pipe_draw_info *info)
 static bool
 is_next_call_a_mergeable_draw(struct tc_draw_single *first_info,
                               struct tc_call *next,
-                              struct tc_draw_single **next_info)
+                              struct tc_draw_single **next_info,
+                              int *index_bias)
 {
    if (next->call_id != TC_CALL_draw_single)
       return false;
 
    *next_info = (struct tc_draw_single*)&next->payload;
+   *index_bias = (*next_info)->info._pad2;
    simplify_draw_info(&(*next_info)->info);
 
    STATIC_ASSERT(offsetof(struct pipe_draw_info, min_index) ==
@@ -183,14 +185,17 @@ tc_batch_execute(void *job, UNUSED int thread_index)
          struct tc_call *next = first + first->num_call_slots;
          struct tc_draw_single *first_info =
             (struct tc_draw_single*)&first->payload;
-         struct tc_draw_single *next_info;
+         struct tc_draw_single *next_info = NULL;
+         int first_index_bias = first_info->info._pad2;
+         int index_bias = 0;
+         bool index_bias_varies = false;
 
          simplify_draw_info(&first_info->info);
 
          /* If at least 2 consecutive draw calls can be merged... */
          if (next != last && next->call_id == TC_CALL_draw_single &&
              first_info->info.drawid == 0 &&
-             is_next_call_a_mergeable_draw(first_info, next, &next_info)) {
+             is_next_call_a_mergeable_draw(first_info, next, &next_info, &index_bias)) {
             /* Merge up to 256 draw calls. */
             struct pipe_draw_start_count_bias multi[256];
             unsigned num_draws = 2;
@@ -198,8 +203,11 @@ tc_batch_execute(void *job, UNUSED int thread_index)
             /* u_threaded_context stores start/count in min/max_index for single draws. */
             multi[0].start = first_info->info.min_index;
             multi[0].count = first_info->info.max_index;
+            multi[0].index_bias = first_index_bias;
             multi[1].start = next_info->info.min_index;
             multi[1].count = next_info->info.max_index;
+            multi[1].index_bias = index_bias;
+            index_bias_varies = first_index_bias != index_bias;
 
             if (next_info->info.index_size)
                pipe_resource_reference(&next_info->info.index.resource, NULL);
@@ -207,21 +215,30 @@ tc_batch_execute(void *job, UNUSED int thread_index)
             /* Find how many other draws can be merged. */
             next = next + next->num_call_slots;
             for (; next != last && num_draws < ARRAY_SIZE(multi) &&
-                 is_next_call_a_mergeable_draw(first_info, next, &next_info);
+                 is_next_call_a_mergeable_draw(first_info, next, &next_info, &index_bias);
                  next += next->num_call_slots, num_draws++) {
                /* u_threaded_context stores start/count in min/max_index for single draws. */
                multi[num_draws].start = next_info->info.min_index;
                multi[num_draws].count = next_info->info.max_index;
+               multi[num_draws].index_bias = index_bias;
+               index_bias_varies |= first_index_bias != index_bias;
 
                if (next_info->info.index_size)
                   pipe_resource_reference(&next_info->info.index.resource, NULL);
             }
 
+            first_info->info.index_bias_varies = index_bias_varies;
             pipe->draw_vbo(pipe, &first_info->info, NULL, multi, num_draws);
             if (first_info->info.index_size)
                pipe_resource_reference(&first_info->info.index.resource, NULL);
             iter = next;
             continue;
+         } else {
+            /* reset original index_bias from before simplify_draw_info() */
+            first_info->info._pad2 = first_index_bias;
+            if (next != last && next->call_id == TC_CALL_draw_single && first_info->info.drawid == 0 && next_info)
+               /* in this case, simplify_draw_info() will have zeroed the data here as well */
+               next_info->info._pad2 = index_bias;
          }
       }
 
@@ -2389,16 +2406,17 @@ tc_call_draw_single(struct pipe_context *pipe, union tc_payload *payload)
 
    /* u_threaded_context stores start/count in min/max_index for single draws. */
    /* Drivers using u_threaded_context shouldn't use min/max_index. */
-   struct pipe_draw_start_count_bias *draw =
-      (struct pipe_draw_start_count_bias *)&info->info.min_index;
-   STATIC_ASSERT(offsetof(struct pipe_draw_start_count_bias, start) == 0);
-   STATIC_ASSERT(offsetof(struct pipe_draw_start_count_bias, count) == 4);
+   struct pipe_draw_start_count_bias draw;
+
+   draw.start = info->info.min_index;
+   draw.count = info->info.max_index;
+   draw.index_bias = info->info._pad2;
 
    info->info.index_bounds_valid = false;
    info->info.has_user_indices = false;
    info->info.take_index_buffer_ownership = false;
 
-   pipe->draw_vbo(pipe, &info->info, NULL, draw, 1);
+   pipe->draw_vbo(pipe, &info->info, NULL, &draw, 1);
    if (info->info.index_size)
       pipe_resource_reference(&info->info.index.resource, NULL);
 }
@@ -2512,6 +2530,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
          /* u_threaded_context stores start/count in min/max_index for single draws. */
          p->info.min_index = offset >> util_logbase2(index_size);
          p->info.max_index = draws[0].count;
+         p->info._pad2 = draws[0].index_bias;
       } else {
          /* Non-indexed call or indexed with a real index buffer. */
          struct tc_draw_single *p =
@@ -2524,6 +2543,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
          /* u_threaded_context stores start/count in min/max_index for single draws. */
          p->info.min_index = draws[0].start;
          p->info.max_index = draws[0].count;
+         p->info._pad2 = draws[0].index_bias;
       }
       return;
    }
@@ -2585,6 +2605,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
             if (!count) {
                p->slot[i].start = 0;
                p->slot[i].count = 0;
+               p->slot[i].index_bias = 0;
                continue;
             }
 
@@ -2594,6 +2615,7 @@ tc_draw_vbo(struct pipe_context *_pipe, const struct pipe_draw_info *info,
                    (draws[i + total_offset].start << index_size_shift), size);
             p->slot[i].start = (buffer_offset + offset) >> index_size_shift;
             p->slot[i].count = count;
+            p->slot[i].index_bias = draws[i + total_offset].index_bias;
             offset += size;
          }
 
index 0f140d6..883ca6e 100644 (file)
@@ -1293,7 +1293,7 @@ u_vbuf_split_indexed_multidraw(struct u_vbuf *mgr, struct pipe_draw_info *info,
       draw.count = indirect_data[offset + 0];
       info->instance_count = indirect_data[offset + 1];
       draw.start = indirect_data[offset + 2];
-      info->index_bias = indirect_data[offset + 3];
+      draw.index_bias = indirect_data[offset + 3];
       info->start_instance = indirect_data[offset + 4];
 
       u_vbuf_draw_vbo(mgr, info, NULL, draw);
@@ -1400,7 +1400,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
           * The driver will not look at these values because indirect != NULL.
           * These values determine the user buffer bounds to upload.
           */
-         new_info.index_bias = index_bias0;
+         new_draw.index_bias = index_bias0;
          new_info.index_bounds_valid = true;
          new_info.min_index = ~0u;
          new_info.max_index = 0;
@@ -1510,7 +1510,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
 
          assert(min_index <= max_index);
 
-         start_vertex = min_index + new_info.index_bias;
+         start_vertex = min_index + new_draw.index_bias;
          num_vertices = max_index + 1 - min_index;
 
          /* Primitive restart doesn't work when unrolling indices.
@@ -1550,7 +1550,7 @@ void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info,
 
       if (unroll_indices) {
          new_info.index_size = 0;
-         new_info.index_bias = 0;
+         new_draw.index_bias = 0;
          new_info.index_bounds_valid = true;
          new_info.min_index = 0;
          new_info.max_index = new_draw.count - 1;
index d37d74f..037403c 100644 (file)
@@ -190,7 +190,7 @@ fill_state_vars(struct d3d12_context *ctx,
          size += 4;
          break;
       case D3D12_STATE_VAR_FIRST_VERTEX:
-         ptr[0] = dinfo->index_size ? dinfo->index_bias : draw->start;
+         ptr[0] = dinfo->index_size ? draw->index_bias : draw->start;
          size += 4;
          break;
       case D3D12_STATE_VAR_DEPTH_TRANSFORM:
@@ -716,7 +716,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
 
    if (dinfo->index_size > 0)
       ctx->cmdlist->DrawIndexedInstanced(draws[0].count, dinfo->instance_count,
-                                         draws[0].start, dinfo->index_bias,
+                                         draws[0].start, draws[0].index_bias,
                                          dinfo->start_instance);
    else
       ctx->cmdlist->DrawInstanced(draws[0].count, dinfo->instance_count,
index 64c458c..2d5aa9a 100644 (file)
@@ -381,10 +381,10 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
    if (screen->specs.halti >= 2) {
       /* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
       etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count,
-         draws[0].count, info->index_size ? info->index_bias : draws[0].start);
+         draws[0].count, info->index_size ? draws->index_bias : draws[0].start);
    } else {
       if (info->index_size)
-         etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
+         etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, draws->index_bias);
       else
          etna_draw_primitives(ctx->stream, draw_mode, draws[0].start, prims);
    }
index 5ec3e50..cdf2330 100644 (file)
@@ -69,14 +69,14 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
    OUT_PKT0(ring, REG_A3XX_VFD_INDEX_MIN, 4);
    OUT_RING(ring, info->index_bounds_valid
                      ? add_sat(info->min_index,
-                               info->index_size ? info->index_bias : 0)
+                               info->index_size ? emit->draw->index_bias : 0)
                      : 0); /* VFD_INDEX_MIN */
    OUT_RING(ring, info->index_bounds_valid
                      ? add_sat(info->max_index,
-                               info->index_size ? info->index_bias : 0)
+                               info->index_size ? emit->draw->index_bias : 0)
                      : ~0);              /* VFD_INDEX_MAX */
    OUT_RING(ring, info->start_instance); /* VFD_INSTANCEID_OFFSET */
-   OUT_RING(ring, info->index_size ? info->index_bias
+   OUT_RING(ring, info->index_size ? emit->draw->index_bias
                                    : emit->draw->start); /* VFD_INDEX_OFFSET */
 
    OUT_PKT0(ring, REG_A3XX_PC_RESTART_INDEX, 1);
index f17a485..5136a9e 100644 (file)
@@ -52,7 +52,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
       fd4_emit_vertex_bufs(ring, emit);
 
    OUT_PKT0(ring, REG_A4XX_VFD_INDEX_OFFSET, 2);
-   OUT_RING(ring, info->index_size ? info->index_bias
+   OUT_RING(ring, info->index_size ? emit->draw->index_bias
                                    : emit->draw->start); /* VFD_INDEX_OFFSET */
    OUT_RING(ring, info->start_instance);                 /* ??? UNKNOWN_2209 */
 
index 9b6fb43..0f59623 100644 (file)
@@ -52,7 +52,7 @@ draw_impl(struct fd_context *ctx, struct fd_ringbuffer *ring,
       fd5_emit_vertex_bufs(ring, emit);
 
    OUT_PKT4(ring, REG_A5XX_VFD_INDEX_OFFSET, 2);
-   OUT_RING(ring, info->index_size ? info->index_bias
+   OUT_RING(ring, info->index_size ? emit->draw->index_bias
                                    : emit->draw->start); /* VFD_INDEX_OFFSET */
    OUT_RING(ring, info->start_instance); /* VFD_INSTANCE_START_OFFSET */
 
index fd797b4..500e4f7 100644 (file)
@@ -302,7 +302,7 @@ fd6_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
       }
    }
 
-   uint32_t index_start = info->index_size ? info->index_bias : draw->start;
+       uint32_t index_start = info->index_size ? draw->index_bias : draw->start;
    if (ctx->last.dirty || (ctx->last.index_start != index_start)) {
       OUT_PKT4(ring, REG_A6XX_VFD_INDEX_OFFSET, 1);
       OUT_RING(ring, index_start); /* VFD_INDEX_OFFSET */
index d02fe07..bdef67d 100644 (file)
@@ -474,7 +474,7 @@ ir3_emit_vs_driver_params(const struct ir3_shader_variant *v,
    uint32_t offset = const_state->offsets.driver_param;
    uint32_t vertex_params[IR3_DP_VS_COUNT] = {
       [IR3_DP_DRAWID] = 0, /* filled by hw (CP_DRAW_INDIRECT_MULTI) */
-      [IR3_DP_VTXID_BASE] = info->index_size ? info->index_bias : draw->start,
+      [IR3_DP_VTXID_BASE] = info->index_size ? draw->index_bias : draw->start,
       [IR3_DP_INSTID_BASE] = info->start_instance,
       [IR3_DP_VTXCNT_MAX] = ctx->streamout.max_tf_vtx,
    };
index ef5c29d..fb19055 100644 (file)
@@ -132,7 +132,7 @@ iris_update_draw_parameters(struct iris_context *ice,
          changed = true;
          ice->draw.params_valid = false;
       } else {
-         int firstvertex = info->index_size ? info->index_bias : draw->start;
+         int firstvertex = info->index_size ? draw->index_bias : draw->start;
 
          if (!ice->draw.params_valid ||
              ice->draw.params.firstvertex != firstvertex ||
index 60211f9..2b4fd0c 100644 (file)
@@ -6801,7 +6801,7 @@ iris_upload_render_state(struct iris_context *ice,
          prim.StartVertexLocation = sc->start;
 
          if (draw->index_size) {
-            prim.BaseVertexLocation += draw->index_bias;
+            prim.BaseVertexLocation += sc->index_bias;
          }
       }
    }
index 3abee78..19a38fd 100644 (file)
@@ -830,7 +830,7 @@ lima_update_gp_attribute_info(struct lima_context *ctx, const struct pipe_draw_i
 
       lima_job_add_bo(job, LIMA_PIPE_GP, res->bo, LIMA_SUBMIT_BO_READ);
 
-      unsigned start = info->index_size ? (ctx->min_index + info->index_bias) : draw->start;
+      unsigned start = info->index_size ? (ctx->min_index + draw->index_bias) : draw->start;
       attribute[n++] = res->bo->va + pvb->buffer_offset + pve->src_offset
          + start * pvb->stride;
       attribute[n++] = (pvb->stride << 11) |
index 33ed47a..4bd799c 100644 (file)
@@ -200,7 +200,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
 {
    struct push_context ctx;
    unsigned i, index_size;
-   bool apply_bias = info->index_size && info->index_bias;
+   bool apply_bias = info->index_size && draw->index_bias;
 
    ctx.push = nv30->base.pushbuf;
    ctx.translate = nv30->vertex->translate;
@@ -220,7 +220,7 @@ nv30_push_vbo(struct nv30_context *nv30, const struct pipe_draw_info *info,
                                          vb->buffer_offset, NOUVEAU_BO_RD);
 
       if (apply_bias)
-         data += info->index_bias * vb->stride;
+         data += draw->index_bias * vb->stride;
 
       ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
    }
index 892eeb6..b7d56e2 100644 (file)
@@ -647,7 +647,7 @@ nv30_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
 
       nv30_draw_elements(nv30, shorten, info,
                          info->mode, draws[0].start, draws[0].count,
-                         info->instance_count, info->index_bias, info->index_size);
+                         info->instance_count, draws[0].index_bias, info->index_size);
    }
 
    nv30_state_release(nv30);
index e7709c2..87104e4 100644 (file)
@@ -246,14 +246,14 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
    unsigned i, index_size;
    unsigned inst_count = info->instance_count;
    unsigned vert_count = draw->count;
-   bool apply_bias = info->index_size && info->index_bias;
+   bool apply_bias = info->index_size && draw->index_bias;
 
    ctx.push = nv50->base.pushbuf;
    ctx.translate = nv50->vertex->translate;
 
    ctx.need_vertex_id = nv50->screen->base.class_3d >= NV84_3D_CLASS &&
       nv50->vertprog->vp.need_vertex_id && (nv50->vertex->num_elements < 32);
-   ctx.index_bias = info->index_size ? info->index_bias : 0;
+   ctx.index_bias = info->index_size ? draw->index_bias : 0;
    ctx.instance_id = 0;
 
    /* For indexed draws, gl_VertexID must be emitted for every vertex. */
@@ -276,7 +276,7 @@ nv50_push_vbo(struct nv50_context *nv50, const struct pipe_draw_info *info,
          data = vb->buffer.user;
 
       if (apply_bias && likely(!(nv50->vertex->instance_bufs & (1 << i))))
-         data += (ptrdiff_t)(info->index_size ? info->index_bias : 0) * vb->stride;
+         data += (ptrdiff_t)(info->index_size ? draw->index_bias : 0) * vb->stride;
 
       ctx.translate->set_buffer(ctx.translate, i, data, vb->stride, ~0);
    }
index ed8c131..8a4dd81 100644 (file)
@@ -788,7 +788,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
 
    /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
    if (info->index_bounds_valid) {
-      nv50->vb_elt_first = info->min_index + (info->index_size ? info->index_bias : 0);
+      nv50->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
       nv50->vb_elt_limit = info->max_index - info->min_index;
    } else {
       nv50->vb_elt_first = 0;
@@ -912,7 +912,7 @@ nv50_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
 
       nv50_draw_elements(nv50, shorten, info,
                          info->mode, draws[0].start, draws[0].count,
-                         info->instance_count, info->index_bias, info->index_size);
+                         info->instance_count, draws->index_bias, info->index_size);
    } else
    if (unlikely(indirect && indirect->count_from_stream_output)) {
       nva0_draw_stream_output(nv50, info, indirect);
index 1e89015..08ce6b3 100644 (file)
@@ -944,7 +944,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
 
    /* NOTE: caller must ensure that (min_index + index_bias) is >= 0 */
    if (info->index_bounds_valid) {
-      nvc0->vb_elt_first = info->min_index + (info->index_size ? info->index_bias : 0);
+      nvc0->vb_elt_first = info->min_index + (info->index_size ? draws->index_bias : 0);
       nvc0->vb_elt_limit = info->max_index - info->min_index;
    } else {
       nvc0->vb_elt_first = 0;
@@ -1032,7 +1032,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
       PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
       BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
       PUSH_DATA (push, NVC0_CB_AUX_DRAW_INFO);
-      PUSH_DATA (push, info->index_size ? info->index_bias : 0);
+      PUSH_DATA (push, info->index_size ? draws->index_bias : 0);
       PUSH_DATA (push, info->start_instance);
       PUSH_DATA (push, info->drawid);
    }
@@ -1121,7 +1121,7 @@ nvc0_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
 
       nvc0_draw_elements(nvc0, shorten, info,
                          info->mode, draws[0].start, draws[0].count,
-                         info->instance_count, info->index_bias, info->index_size);
+                         info->instance_count, draws->index_bias, info->index_size);
    } else {
       nvc0_draw_arrays(nvc0,
                        info->mode, draws[0].start, draws[0].count,
index badb594..f69c0d8 100644 (file)
@@ -524,7 +524,7 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
          sdraw.count = cmd->count;
          single.start_instance = cmd->baseInstance;
          single.instance_count = cmd->primCount;
-         single.index_bias = cmd->baseVertex;
+         sdraw.index_bias = cmd->baseVertex;
       } else {
          DrawArraysIndirectCommand *cmd = (void *)buf_data;
          sdraw.start = cmd->first;
@@ -541,7 +541,7 @@ nvc0_push_vbo_indirect(struct nvc0_context *nvc0, const struct pipe_draw_info *i
          PUSH_DATA (push, screen->uniform_bo->offset + NVC0_CB_AUX_INFO(0));
          BEGIN_1IC0(push, NVC0_3D(CB_POS), 1 + 3);
          PUSH_DATA (push, NVC0_CB_AUX_DRAW_INFO);
-         PUSH_DATA (push, single.index_bias);
+         PUSH_DATA (push, sdraw.index_bias);
          PUSH_DATA (push, single.start_instance);
          PUSH_DATA (push, single.drawid + i);
       }
@@ -561,7 +561,7 @@ nvc0_push_vbo(struct nvc0_context *nvc0, const struct pipe_draw_info *info,
 {
    struct push_context ctx;
    unsigned i, index_size;
-   unsigned index_bias = info->index_size ? info->index_bias : 0;
+   unsigned index_bias = info->index_size ? draw->index_bias : 0;
    unsigned inst_count = info->instance_count;
    unsigned vert_count = draw->count;
    unsigned prim;
@@ -723,7 +723,7 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
    unsigned i;
    unsigned a = nvc0->vertex->num_elements;
 
-   if (!index_size || info->index_bias)
+   if (!index_size || draw->index_bias)
       index_size = 4;
    data = (uint32_t *)nouveau_scratch_get(&nvc0->base,
                                           draw->count * index_size, &va, &bo);
@@ -733,24 +733,24 @@ nvc0_push_upload_vertex_ids(struct push_context *ctx,
    nouveau_pushbuf_validate(push);
 
    if (info->index_size) {
-      if (!info->index_bias) {
+      if (!draw->index_bias) {
          memcpy(data, ctx->idxbuf, draw->count * index_size);
       } else {
          switch (info->index_size) {
          case 1:
-            copy_indices_u8(data, ctx->idxbuf, info->index_bias, draw->count);
+            copy_indices_u8(data, ctx->idxbuf, draw->index_bias, draw->count);
             break;
          case 2:
-            copy_indices_u16(data, ctx->idxbuf, info->index_bias, draw->count);
+            copy_indices_u16(data, ctx->idxbuf, draw->index_bias, draw->count);
             break;
          default:
-            copy_indices_u32(data, ctx->idxbuf, info->index_bias, draw->count);
+            copy_indices_u32(data, ctx->idxbuf, draw->index_bias, draw->count);
             break;
          }
       }
    } else {
       for (i = 0; i < draw->count; ++i)
-         data[i] = i + (draw->start + info->index_bias);
+         data[i] = i + (draw->start + draw->index_bias);
    }
 
    format = (1 << NVC0_3D_VERTEX_ATTRIB_FORMAT_BUFFER__SHIFT) |
index 30c4f13..c2d9379 100644 (file)
@@ -335,7 +335,7 @@ panfrost_draw_emit_tiler(struct panfrost_batch *batch,
                 if (info->index_size) {
                         cfg.index_type = panfrost_translate_index_size(info->index_size);
                         cfg.indices = indices;
-                        cfg.base_vertex_offset = info->index_bias - ctx->offset_start;
+                        cfg.base_vertex_offset = draw->index_bias - ctx->offset_start;
                 }
         }
 
@@ -447,7 +447,7 @@ panfrost_direct_draw(struct panfrost_context *ctx,
 
         /* Take into account a negative bias */
         ctx->indirect_draw = false;
-        ctx->vertex_count = draw->count + (info->index_size ? abs(info->index_bias) : 0);
+        ctx->vertex_count = draw->count + (info->index_size ? abs(draw->index_bias) : 0);
         ctx->instance_count = info->instance_count;
         ctx->active_prim = info->mode;
 
@@ -472,7 +472,7 @@ panfrost_direct_draw(struct panfrost_context *ctx,
 
                 /* Use the corresponding values */
                 vertex_count = max_index - min_index + 1;
-                ctx->offset_start = min_index + info->index_bias;
+                ctx->offset_start = min_index + draw->index_bias;
         } else {
                 ctx->offset_start = draw->start;
         }
@@ -623,7 +623,7 @@ panfrost_indirect_draw(struct panfrost_context *ctx,
         panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
                                   vs_vary, varyings, attribs, attrib_bufs,
                                   vertex.cpu);
-        panfrost_draw_emit_tiler(batch, info, NULL, &invocation, shared_mem,
+        panfrost_draw_emit_tiler(batch, info, draw, &invocation, shared_mem,
                                  index_buf ? index_buf->ptr.gpu : 0,
                                  fs_vary, varyings, pos, psiz, tiler.cpu);
 
index 3fc0608..5ef6ee6 100644 (file)
@@ -512,7 +512,7 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
     /* 19 dwords for r300_draw_elements_immediate. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
             PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
-            PREP_INDEXED, NULL, 2+count_dwords, 0, info->index_bias, -1))
+            PREP_INDEXED, NULL, 2+count_dwords, 0, draw->index_bias, -1))
         return;
 
     r300_emit_draw_init(r300, info->mode, info->max_index);
@@ -528,13 +528,13 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
         OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
                r300_translate_primitive(info->mode));
 
-        if (info->index_bias && !r300->screen->caps.is_r500) {
+        if (draw->index_bias && !r300->screen->caps.is_r500) {
             for (i = 0; i < draw->count-1; i += 2)
-                OUT_CS(((ptr1[i+1] + info->index_bias) << 16) |
-                        (ptr1[i]   + info->index_bias));
+                OUT_CS(((ptr1[i+1] + draw->index_bias) << 16) |
+                        (ptr1[i]   + draw->index_bias));
 
             if (draw->count & 1)
-                OUT_CS(ptr1[i] + info->index_bias);
+                OUT_CS(ptr1[i] + draw->index_bias);
         } else {
             for (i = 0; i < draw->count-1; i += 2)
                 OUT_CS(((ptr1[i+1]) << 16) |
@@ -552,13 +552,13 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
         OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (draw->count << 16) |
                r300_translate_primitive(info->mode));
 
-        if (info->index_bias && !r300->screen->caps.is_r500) {
+        if (draw->index_bias && !r300->screen->caps.is_r500) {
             for (i = 0; i < draw->count-1; i += 2)
-                OUT_CS(((ptr2[i+1] + info->index_bias) << 16) |
-                        (ptr2[i]   + info->index_bias));
+                OUT_CS(((ptr2[i+1] + draw->index_bias) << 16) |
+                        (ptr2[i]   + draw->index_bias));
 
             if (draw->count & 1)
-                OUT_CS(ptr2[i] + info->index_bias);
+                OUT_CS(ptr2[i] + draw->index_bias);
         } else {
             OUT_CS_TABLE(ptr2, count_dwords);
         }
@@ -572,9 +572,9 @@ static void r300_draw_elements_immediate(struct r300_context *r300,
                R300_VAP_VF_CNTL__INDEX_SIZE_32bit |
                r300_translate_primitive(info->mode));
 
-        if (info->index_bias && !r300->screen->caps.is_r500) {
+        if (draw->index_bias && !r300->screen->caps.is_r500) {
             for (i = 0; i < draw->count; i++)
-                OUT_CS(ptr4[i] + info->index_bias);
+                OUT_CS(ptr4[i] + draw->index_bias);
         } else {
             OUT_CS_TABLE(ptr4, count_dwords);
         }
@@ -600,8 +600,8 @@ static void r300_draw_elements(struct r300_context *r300,
     int buffer_offset = 0, index_offset = 0; /* for index bias emulation */
     uint16_t indices3[3];
 
-    if (info->index_bias && !r300->screen->caps.is_r500) {
-        r300_split_index_bias(r300, info->index_bias, &buffer_offset,
+    if (draw->index_bias && !r300->screen->caps.is_r500) {
+        r300_split_index_bias(r300, draw->index_bias, &buffer_offset,
                               &index_offset);
     }
 
@@ -635,7 +635,7 @@ static void r300_draw_elements(struct r300_context *r300,
     /* 19 dwords for emit_draw_elements. Give up if the function fails. */
     if (!r300_prepare_for_rendering(r300,
             PREP_EMIT_STATES | PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS |
-            PREP_INDEXED, indexBuffer, 19, buffer_offset, info->index_bias,
+            PREP_INDEXED, indexBuffer, 19, buffer_offset, draw->index_bias,
             instance_id))
         goto done;
 
@@ -662,7 +662,7 @@ static void r300_draw_elements(struct r300_context *r300,
             if (count) {
                 if (!r300_prepare_for_rendering(r300,
                         PREP_VALIDATE_VBOS | PREP_EMIT_VARRAYS | PREP_INDEXED,
-                        indexBuffer, 19, buffer_offset, info->index_bias,
+                        indexBuffer, 19, buffer_offset, draw->index_bias,
                         instance_id))
                     goto done;
             }
index 17cd65c..4844c90 100644 (file)
@@ -2223,7 +2223,7 @@ static void r600_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info
                        index_offset -= start_offset;
                        has_user_indices = false;
                }
-               index_bias = info->index_bias;
+               index_bias = draws->index_bias;
        } else {
                index_bias = indirect ? 0 : draws[0].start;
        }
index 8fed716..ec812d5 100644 (file)
@@ -1656,7 +1656,7 @@ static inline unsigned si_get_minimum_num_gfx_cs_dwords(struct si_context *sctx,
     * Also reserve space for stopping queries at the end of IB, because
     * the number of active queries is unlimited in theory.
     */
-   return 2048 + sctx->num_cs_dw_queries_suspend + num_draws * 9;
+   return 2048 + sctx->num_cs_dw_queries_suspend + num_draws * 10;
 }
 
 static inline void si_context_add_resource_size(struct si_context *sctx, struct pipe_resource *r)
index 3a26dc6..c9da1cf 100644 (file)
@@ -1056,6 +1056,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
 
    unsigned sh_base_reg = sctx->shader_pointers.sh_base[PIPE_SHADER_VERTEX];
    bool render_cond_bit = sctx->render_cond_enabled;
+   unsigned drawid_base = info->drawid;
 
    if (indirect) {
       assert(num_draws == 1);
@@ -1131,7 +1132,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
       }
 
       /* Base vertex and start instance. */
-      int base_vertex = original_index_size ? info->index_bias : draws[0].start;
+      int base_vertex = original_index_size ? draws[0].index_bias : draws[0].start;
 
       bool set_draw_id = sctx->vs_uses_draw_id;
       bool set_base_instance = sctx->vs_uses_base_instance;
@@ -1149,23 +1150,23 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
                   (info->start_instance != sctx->last_start_instance ||
                    sctx->last_start_instance == SI_START_INSTANCE_UNKNOWN)) ||
                  (set_draw_id &&
-                  (info->drawid != sctx->last_drawid ||
+                  (drawid_base != sctx->last_drawid ||
                    sctx->last_drawid == SI_DRAW_ID_UNKNOWN)) ||
                  sh_base_reg != sctx->last_sh_base_reg) {
          if (set_base_instance) {
             radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 3);
             radeon_emit(cs, base_vertex);
-            radeon_emit(cs, info->drawid);
+            radeon_emit(cs, drawid_base);
             radeon_emit(cs, info->start_instance);
 
             sctx->last_start_instance = info->start_instance;
-            sctx->last_drawid = info->drawid;
+            sctx->last_drawid = drawid_base;
          } else if (set_draw_id) {
             radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
             radeon_emit(cs, base_vertex);
-            radeon_emit(cs, info->drawid);
+            radeon_emit(cs, drawid_base);
 
-            sctx->last_drawid = info->drawid;
+            sctx->last_drawid = drawid_base;
          } else {
             radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, base_vertex);
          }
@@ -1175,7 +1176,7 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
       }
 
       /* Don't update draw_id in the following code if it doesn't increment. */
-      set_draw_id &= info->increment_draw_id;
+      bool increment_draw_id = num_draws > 1 && set_draw_id && info->increment_draw_id;
 
       if (index_size) {
          if (ALLOW_PRIM_DISCARD_CS && dispatch_prim_discard_cs) {
@@ -1192,29 +1193,95 @@ static void si_emit_draw_packets(struct si_context *sctx, const struct pipe_draw
             return;
          }
 
-         for (unsigned i = 0; i < num_draws; i++) {
-            uint64_t va = index_va + draws[i].start * index_size;
+         /* NOT_EOP allows merging multiple draws into 1 wave, but only user VGPRs
+          * can be changed between draws, and GS fast launch must be disabled.
+          * NOT_EOP doesn't work on gfx9 and older.
+          *
+          * Instead of doing this, which evaluates the case conditions repeatedly:
+          *  for (all draws) {
+          *    if (case1);
+          *    else;
+          *  }
+          *
+          * Use this structuring to evaluate the case conditions once:
+          *  if (case1) for (all draws);
+          *  else for (all draws);
+          *
+          */
+         bool index_bias_varies = num_draws > 1 && info->index_bias_varies;
 
-            if (i > 0 && set_draw_id) {
-               unsigned draw_id = info->drawid + i;
+         if (increment_draw_id) {
+            if (index_bias_varies) {
+               for (unsigned i = 0; i < num_draws; i++) {
+                  uint64_t va = index_va + draws[i].start * index_size;
 
-               radeon_set_sh_reg(cs, sh_base_reg + SI_SGPR_DRAWID * 4, draw_id);
-               sctx->last_drawid = draw_id;
-            }
+                  if (i > 0) {
+                     radeon_set_sh_reg_seq(cs, sh_base_reg + SI_SGPR_BASE_VERTEX * 4, 2);
+                     radeon_emit(cs, draws[i].index_bias);
+                     radeon_emit(cs, drawid_base + i);
+                  }
 
-            radeon_emit(cs, PKT3(PKT3_DRAW_INDEX_2, 4, render_cond_bit));
-            radeon_emit(cs, index_max_size);
-            radeon_emit(cs, va);
-            radeon_emit(cs, va >> 32);
-            radeon_emit(cs, draws[i].count);
-            radeon_emit(cs, V_0287F0_DI_SRC_SEL_DMA |
-                        /* NOT_EOP 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);
index b5ac35e..fa165da 100644 (file)
@@ -278,7 +278,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
 
       ret = svga_hwtnl_simple_draw_range_elements(hwtnl, index_buffer,
                                                   info->index_size,
-                                                  info->index_bias,
+                                                  draw->index_bias,
                                                   info->index_bounds_valid ? info->min_index : 0,
                                                   info->index_bounds_valid ? info->max_index : ~0,
                                                   gen_prim, index_offset, count,
@@ -306,7 +306,7 @@ svga_hwtnl_draw_range_elements(struct svga_hwtnl *hwtnl,
          ret = svga_hwtnl_simple_draw_range_elements(hwtnl,
                                                      gen_buf,
                                                      gen_size,
-                                                     info->index_bias,
+                                                     draw->index_bias,
                                                      info->index_bounds_valid ? info->min_index : 0,
                                                      info->index_bounds_valid ? info->max_index : ~0,
                                                      gen_prim, gen_offset,
index c943c03..35adabf 100644 (file)
@@ -262,7 +262,7 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
     * always start from 0 for DrawArrays and does not include baseVertex for
     * DrawIndexed.
     */
-   unsigned index_bias = info->index_size ? info->index_bias : 0;
+   unsigned index_bias = info->index_size ? draws->index_bias : 0;
    if (svga->curr.vertex_id_bias != (draws[0].start + index_bias)) {
       svga->curr.vertex_id_bias = draws[0].start + index_bias;
       svga->dirty |= SVGA_NEW_VS_CONSTS;
index c0e7266..3c9a524 100644 (file)
@@ -329,7 +329,6 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
       .index.user = indices,
       .start_instance = 0,
       .instance_count = 1,
-      .index_bias = bias,
       .index_bounds_valid = true,
       .min_index = svga_render->min_index,
       .max_index = svga_render->max_index,
@@ -337,6 +336,7 @@ svga_vbuf_render_draw_elements(struct vbuf_render *render,
    const struct pipe_draw_start_count_bias draw = {
       .start = 0,
       .count = nr_indices,
+      .index_bias = bias,
    };
 
    assert((svga_render->vbuf_offset - svga_render->vdecl_offset)
index fb8bbd4..96c862f 100644 (file)
@@ -254,7 +254,7 @@ swr_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info,
                                           draws[0].count,
                                           info->instance_count,
                                           draws[0].start,
-                                          info->index_bias,
+                                          draws->index_bias,
                                           info->start_instance);
    else
       ctx->api.pfnSwrDrawInstanced(ctx->swrContext,
index 5ee24b5..bea1c1e 100644 (file)
@@ -1113,7 +1113,8 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
                     uint32_t i,
                     uint32_t *totelems,
                     uint32_t *base,
-                    uint32_t *size)
+                    uint32_t *size,
+                    int index_bias)
 {
    /* FIXME: The size is too large - we don't access the full extra stride. */
    unsigned elems;
@@ -1125,8 +1126,8 @@ swr_user_vbuf_range(const struct pipe_draw_info *info,
       *size = elems * elem_pitch;
    } else if (vb->stride) {
       elems = info->max_index - info->min_index + 1;
-      *totelems = (info->max_index + (info->index_size ? info->index_bias : 0)) + 1;
-      *base = (info->min_index + (info->index_size ? info->index_bias : 0)) * vb->stride;
+      *totelems = (info->max_index + (info->index_size ? index_bias : 0)) + 1;
+      *base = (info->min_index + (info->index_size ? index_bias : 0)) * vb->stride;
       *size = elems * elem_pitch;
    } else {
       *totelems = 1;
@@ -1430,9 +1431,9 @@ swr_update_derived(struct pipe_context *pipe,
             post_update_dirty_flags |= SWR_NEW_VERTEX;
 
             uint32_t base;
-            swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems, &base, &size);
+            swr_user_vbuf_range(&info, ctx->velems, vb, i, &elems, &base, &size, draw->index_bias);
             partial_inbounds = 0;
-            min_vertex_index = info.min_index + (info.index_size ? info.index_bias : 0);
+            min_vertex_index = info.min_index + (info.index_size ? draw->index_bias : 0);
 
             size = AlignUp(size, 4);
             /* If size of client memory copy is too large, don't copy. The
index 8b5eed4..c7972f8 100644 (file)
@@ -1273,10 +1273,10 @@ v3d_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
         /* The Base Vertex/Base Instance packet sets those values to nonzero
          * for the next draw call only.
          */
-        if ((info->index_size && info->index_bias) || info->start_instance) {
+        if ((info->index_size && draws->index_bias) || info->start_instance) {
                 cl_emit(&job->bcl, BASE_VERTEX_BASE_INSTANCE, base) {
                         base.base_instance = info->start_instance;
-                        base.base_vertex = info->index_size ? info->index_bias : 0;
+                        base.base_vertex = info->index_size ? draws->index_bias : 0;
                 }
         }
 
index dfe2c35..b3d0996 100644 (file)
@@ -133,6 +133,7 @@ vc4_predraw_check_textures(struct pipe_context *pctx,
 static void
 vc4_emit_gl_shader_state(struct vc4_context *vc4,
                          const struct pipe_draw_info *info,
+                         const struct pipe_draw_start_count_bias *draws,
                          uint32_t extra_index_bias)
 {
         struct vc4_job *job = vc4->job;
@@ -183,7 +184,7 @@ vc4_emit_gl_shader_state(struct vc4_context *vc4,
         };
 
         uint32_t max_index = 0xffff;
-        unsigned index_bias = info->index_size ? info->index_bias : 0;
+        unsigned index_bias = info->index_size ? draws->index_bias : 0;
         for (int i = 0; i < vtx->num_elements; i++) {
                 struct pipe_vertex_element *elem = &vtx->pipe[i];
                 struct pipe_vertex_buffer *vb =
@@ -358,7 +359,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
 
         bool needs_drawarrays_shader_state = false;
 
-        unsigned index_bias = info->index_size ? info->index_bias : 0;
+        unsigned index_bias = info->index_size ? draws->index_bias : 0;
         if ((vc4->dirty & (VC4_DIRTY_VTXBUF |
                            VC4_DIRTY_VTXSTATE |
                            VC4_DIRTY_PRIM_MODE |
@@ -371,7 +372,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
                            vc4->prog.fs->uniform_dirty_bits)) ||
             vc4->last_index_bias != index_bias) {
                 if (info->index_size)
-                        vc4_emit_gl_shader_state(vc4, info, 0);
+                        vc4_emit_gl_shader_state(vc4, info, draws, 0);
                 else
                         needs_drawarrays_shader_state = true;
         }
@@ -467,7 +468,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
                         uint32_t step;
 
                         if (needs_drawarrays_shader_state) {
-                                vc4_emit_gl_shader_state(vc4, info,
+                                vc4_emit_gl_shader_state(vc4, info, draws,
                                                          extra_index_bias);
                         }
 
index 214d384..8fd302f 100644 (file)
@@ -752,7 +752,7 @@ int virgl_encoder_draw_vbo(struct virgl_context *ctx,
    virgl_encoder_write_dword(ctx->cbuf, info->mode);
    virgl_encoder_write_dword(ctx->cbuf, !!info->index_size);
    virgl_encoder_write_dword(ctx->cbuf, info->instance_count);
-   virgl_encoder_write_dword(ctx->cbuf, info->index_size ? info->index_bias : 0);
+   virgl_encoder_write_dword(ctx->cbuf, info->index_size ? draw->index_bias : 0);
    virgl_encoder_write_dword(ctx->cbuf, info->start_instance);
    virgl_encoder_write_dword(ctx->cbuf, info->primitive_restart);
    virgl_encoder_write_dword(ctx->cbuf, info->primitive_restart ? info->restart_index : 0);
index e457e66..b4c4734 100644 (file)
@@ -565,7 +565,7 @@ zink_draw_vbo(struct pipe_context *pctx,
             update_drawid(ctx, draw_id);
             vkCmdDrawIndexed(batch->state->cmdbuf,
                draws[i].count, dinfo->instance_count,
-               need_index_buffer_unref ? 0 : draws[i].start, dinfo->index_bias, dinfo->start_instance);
+               need_index_buffer_unref ? 0 : draws[i].start, draws[i].index_bias, dinfo->start_instance);
             if (dinfo->increment_draw_id)
                draw_id++;
         }
index 9fc757f..1b2744a 100644 (file)
@@ -742,11 +742,11 @@ VKAPI_ATTR void VKAPI_CALL lvp_CmdDrawIndexed(
       return;
 
    cmd->u.draw_indexed.instance_count = instanceCount;
-   cmd->u.draw_indexed.vertex_offset = vertexOffset;
    cmd->u.draw_indexed.first_instance = firstInstance;
    cmd->u.draw_indexed.draw_count = 1;
    cmd->u.draw_indexed.draws[0].start = firstIndex;
    cmd->u.draw_indexed.draws[0].count = indexCount;
+   cmd->u.draw_indexed.draws[0].index_bias = vertexOffset;
    cmd->u.draw_indexed.calc_start = true;
 
    cmd_buf_queue(cmd_buffer, cmd);
index 76470b3..fcbf2a5 100644 (file)
@@ -2140,7 +2140,6 @@ static void handle_draw_indexed(struct lvp_cmd_buffer_entry *cmd,
    state->info.index.resource = state->index_buffer;
    state->info.start_instance = cmd->u.draw_indexed.first_instance;
    state->info.instance_count = cmd->u.draw_indexed.instance_count;
-   state->info.index_bias = cmd->u.draw_indexed.vertex_offset;
    state->info.view_mask = subpass->view_mask;
 
    if (state->info.primitive_restart)
index 4c61ae8..6c2c5c8 100644 (file)
@@ -748,7 +748,6 @@ struct lvp_cmd_draw {
 
 struct lvp_cmd_draw_indexed {
    uint32_t instance_count;
-   uint32_t vertex_offset;
    uint32_t first_instance;
    bool calc_start;
    uint32_t draw_count;
index 49d82bb..5bd6f25 100644 (file)
@@ -3308,7 +3308,7 @@ NineDevice9_ProcessVertices( struct NineDevice9 *This,
     draw.instance_count = 1;
     draw.index_size = 0;
     sc.start = 0;
-    draw.index_bias = 0;
+    sc.index_bias = 0;
     draw.min_index = 0;
     draw.max_index = VertexCount - 1;
 
index 543ed11..fc3fd8e 100644 (file)
@@ -2383,7 +2383,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_primitive,
     init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
     info.index_size = 0;
     draw.start = StartVertex;
-    info.index_bias = 0;
+    draw.index_bias = 0;
     info.min_index = draw.start;
     info.max_index = draw.start + draw.count - 1;
     info.index.resource = NULL;
@@ -2408,7 +2408,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive,
     init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
     info.index_size = context->index_size;
     draw.start = context->index_offset / context->index_size + StartIndex;
-    info.index_bias = BaseVertexIndex;
+    draw.index_bias = BaseVertexIndex;
     info.index_bounds_valid = true;
     /* These don't include index bias: */
     info.min_index = MinVertexIndex;
@@ -2438,7 +2438,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf,
     init_draw_info(&info, &draw, device, PrimitiveType, PrimitiveCount);
     info.index_size = index_size;
     draw.start = index_offset / info.index_size;
-    info.index_bias = 0;
+    draw.index_bias = 0;
     info.index_bounds_valid = true;
     info.min_index = MinVertexIndex;
     info.max_index = MinVertexIndex + NumVertices - 1;
index 6364223..52c77b8 100644 (file)
@@ -120,7 +120,7 @@ struct pipe_context {
     * - PIPE_CAP_MULTI_DRAW_INDIRECT_PARAMS: Indirect draw count
     *
     * Differences against glMultiDraw and glMultiMode:
-    * - "info->mode" and "info->index_bias" are always constant due to the lack
+    * - "info->mode" and "draws->index_bias" are always constant due to the lack
     *   of hardware support and CPU performance concerns. Only start and count
     *   vary.
     * - if "info->increment_draw_id" is false, draw_id doesn't change between
index 5ecb060..45073c5 100644 (file)
@@ -756,17 +756,13 @@ struct pipe_draw_info
    bool increment_draw_id:1;  /**< whether drawid increments for direct draws */
    bool take_index_buffer_ownership:1; /**< callee inherits caller's refcount
          (no need to reference indexbuf, but still needs to unreference it) */
-   char _pad:1;               /**< padding for memcmp */
+   bool index_bias_varies:1;   /**< true if index_bias varies between draws */
 
    unsigned start_instance; /**< first instance id */
    unsigned instance_count; /**< number of instances */
 
    unsigned drawid; /**< id of this draw in a multidraw */
-
-   /**
-    * For indexed drawing, these fields apply after index lookup.
-    */
-   int index_bias; /**< a bias to be added to each index */
+   int _pad2; /**< padding for memcmp and index_bias reuse */
 
    /**
     * Primitive restart enable/index (only applies to indexed drawing)
index 2119468..0390c06 100644 (file)
@@ -202,6 +202,7 @@ static void draw( void )
    info.mode = PIPE_PRIM_TRIANGLES;
    draw.start = 0;
    draw.count = 3;
+   draw.index_bias = 0;
    /* draw NUM_INST triangles */
    info.instance_count = NUM_INST;
 
index afaad3b..045d204 100644 (file)
@@ -585,16 +585,14 @@ struct dd_function_table {
                        unsigned num_draws);
 
    /**
-    * Same as DrawGallium, but base_vertex and mode can also change between draws.
+    * Same as DrawGallium, but mode can also change between draws.
     *
-    * If index_bias != NULL, index_bias changes for each draw.
     * If mode != NULL, mode changes for each draw.
     * At least one of them must be non-NULL.
     *
     * "info" is not const and the following fields can be changed by
     * the callee in addition to the fields listed by DrawGallium:
     * - info->mode (if mode != NULL)
-    * - info->index_bias (if index_bias != NULL)
     *
     * This function exists to decrease complexity of DrawGallium.
     */
@@ -602,7 +600,6 @@ struct dd_function_table {
                               struct pipe_draw_info *info,
                               const struct pipe_draw_start_count_bias *draws,
                               const unsigned char *mode,
-                              const int *base_vertex,
                               unsigned num_draws);
 
    /**
index 75af188..ce3507e 100644 (file)
@@ -993,7 +993,7 @@ _mesa_draw_gallium_fallback(struct gl_context *ctx,
          prim.end = 1;
          prim.start = index_size && info->has_user_indices ? 0 : draws[i].start;
          prim.count = draws[i].count;
-         prim.basevertex = index_size ? info->index_bias : 0;
+         prim.basevertex = index_size ? draws[i].index_bias : 0;
          prim.draw_id = info->drawid + (info->increment_draw_id ? i : 0);
 
          if (!index_size) {
@@ -1027,7 +1027,7 @@ _mesa_draw_gallium_fallback(struct gl_context *ctx,
       prim[num_prims].end = 1;
       prim[num_prims].start = draws[i].start;
       prim[num_prims].count = draws[i].count;
-      prim[num_prims].basevertex = info->index_size ? info->index_bias : 0;
+      prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0;
       prim[num_prims].draw_id = info->drawid + (info->increment_draw_id ? i : 0);
 
       if (!index_size) {
@@ -1068,58 +1068,20 @@ _mesa_draw_gallium_complex_fallback(struct gl_context *ctx,
                                     struct pipe_draw_info *info,
                                     const struct pipe_draw_start_count_bias *draws,
                                     const unsigned char *mode,
-                                    const int *base_vertex,
                                     unsigned num_draws)
 {
-   enum {
-      MODE = 1,
-      BASE_VERTEX = 2,
-   };
-   unsigned mask = (mode ? MODE : 0) | (base_vertex ? BASE_VERTEX : 0);
    unsigned i, first;
-
    /* Find consecutive draws where mode and base_vertex don't vary. */
-   switch (mask) {
-   case MODE:
-      for (i = 0, first = 0; i <= num_draws; i++) {
-         if (i == num_draws || mode[i] != mode[first]) {
-            info->mode = mode[first];
-            ctx->Driver.DrawGallium(ctx, info, &draws[first], i - first);
-            first = i;
-         }
-      }
-      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);
index 0fe0950..b65400f 100644 (file)
@@ -98,7 +98,6 @@ _mesa_draw_gallium_complex_fallback(struct gl_context *ctx,
                                     struct pipe_draw_info *info,
                                     const struct pipe_draw_start_count_bias *draws,
                                     const unsigned char *mode,
-                                    const int *base_vertex,
                                     unsigned num_draws);
 
 void GLAPIENTRY
index be9e375..da24e76 100644 (file)
@@ -191,7 +191,6 @@ st_draw_gallium_complex(struct gl_context *ctx,
                         struct pipe_draw_info *info,
                         const struct pipe_draw_start_count_bias *draws,
                         const unsigned char *mode,
-                        const int *base_vertex,
                         unsigned num_draws)
 {
    struct st_context *st = st_context(ctx);
@@ -201,67 +200,21 @@ st_draw_gallium_complex(struct gl_context *ctx,
    if (!prepare_indexed_draw(st, ctx, info, draws, num_draws))
       return;
 
-   enum {
-      MODE = 1,
-      BASE_VERTEX = 2,
-   };
-   unsigned mask = (mode ? MODE : 0) | (base_vertex ? BASE_VERTEX : 0);
    unsigned i, first;
    struct cso_context *cso = st->cso_context;
 
    /* Find consecutive draws where mode and base_vertex don't vary. */
-   switch (mask) {
-   case MODE:
-      for (i = 0, first = 0; i <= num_draws; i++) {
-         if (i == num_draws || mode[i] != mode[first]) {
-            info->mode = mode[first];
-            cso_multi_draw(cso, info, &draws[first], i - first);
-            first = i;
-
-            /* 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;
    }
 }
 
index 0764cc1..efba838 100644 (file)
@@ -451,7 +451,7 @@ st_feedback_draw_vbo(struct gl_context *ctx,
       d.start = start + prims[i].start;
 
       info.mode = prims[i].mode;
-      info.index_bias = prims[i].basevertex;
+      d.index_bias = prims[i].basevertex;
       info.drawid = prims[i].draw_id;
       if (!ib) {
          info.min_index = d.start;
index d4eb380..4914cec 100644 (file)
@@ -336,7 +336,6 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec)
          ctx->Driver.DrawGalliumComplex(ctx, &exec->vtx.info,
                                         exec->vtx.draw,
                                         exec->vtx.mode,
-                                        NULL,
                                         exec->vtx.prim_count);
 
          /* Get new storage -- unless asked not to. */
index 9b0d143..1a895a3 100644 (file)
@@ -818,6 +818,7 @@ compile_vertex_list(struct gl_context *ctx)
       for (unsigned i = 0; i < merged_prim_count; i++) {
          node->merged.start_count[i].start = merged_prims[i].start;
          node->merged.start_count[i].count = merged_prims[i].count;
+         node->merged.start_count[i].index_bias = 0;
          if (merged_prim_count > 1)
             node->merged.mode[i] = merged_prims[i].mode;
       }
index f2d1c89..4a8b9d7 100644 (file)
@@ -238,7 +238,6 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
                ctx->Driver.DrawGalliumComplex(ctx, info,
                                               node->merged.start_count,
                                               node->merged.mode,
-                                              NULL,
                                               node->merged.num_draws);
             } else {
                ctx->Driver.DrawGallium(ctx, info,