st/mesa: fix max_offset computation for base vertex
authorBrian Paul <brianp@vmware.com>
Mon, 2 Apr 2012 18:05:16 +0000 (20:05 +0200)
committerBrian Paul <brianp@vmware.com>
Fri, 6 Apr 2012 20:18:53 +0000 (14:18 -0600)
Add the maximum base vertex offset to max_index for computing the
buffer size.  Fixes a failed assertion in the u_upload_mgr.c code with
the VMware svga driver.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=48141

v2: incorporate Marek's suggestions.

NOTE: This is a candidate for the 8.0 branch.

Reviewed-by: Marek Olšák <maraeo@gmail.com>
src/mesa/state_tracker/st_draw.c

index eb187519ffe6aab093179c8c05d85c342dcf2ce5..0a35ab2be2e9a012a186c75f38930772c59048c9 100644 (file)
@@ -979,6 +979,7 @@ st_draw_vbo(struct gl_context *ctx,
    struct pipe_index_buffer ibuffer;
    struct pipe_draw_info info;
    unsigned i, num_instances = 1;
+   unsigned max_index_plus_base;
    GLboolean new_array =
       st->dirty.st &&
       (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
@@ -987,6 +988,8 @@ st_draw_vbo(struct gl_context *ctx,
    assert(ctx->NewState == 0x0);
 
    if (ib) {
+      int max_base_vertex = 0;
+
       /* Gallium probably doesn't want this in some cases. */
       if (!index_bounds_valid)
          if (!all_varyings_in_vbos(arrays))
@@ -995,7 +998,16 @@ st_draw_vbo(struct gl_context *ctx,
 
       for (i = 0; i < nr_prims; i++) {
          num_instances = MAX2(num_instances, prims[i].num_instances);
+         max_base_vertex = MAX2(max_base_vertex, prims[i].basevertex);
       }
+
+      /* Compute the sum of max_index and max_base_vertex.  That's the value
+       * we need to use when creating buffers.
+       */
+      if (max_index == ~0)
+         max_index_plus_base = max_index;
+      else
+         max_index_plus_base = max_index + max_base_vertex;
    }
    else {
       /* Get min/max index for non-indexed drawing. */
@@ -1007,6 +1019,9 @@ st_draw_vbo(struct gl_context *ctx,
          max_index = MAX2(max_index, prims[i].start + prims[i].count - 1);
          num_instances = MAX2(num_instances, prims[i].num_instances);
       }
+
+      /* The base vertex offset only applies to indexed drawing */
+      max_index_plus_base = max_index;
    }
 
    /* Validate state. */
@@ -1023,7 +1038,8 @@ st_draw_vbo(struct gl_context *ctx,
       st_validate_state(st);
 
       if (new_array) {
-         if (!st_validate_varrays(ctx, arrays, max_index, num_instances)) {
+         if (!st_validate_varrays(ctx, arrays, max_index_plus_base,
+                                  num_instances)) {
             /* probably out of memory, no-op the draw call */
             return;
          }
@@ -1047,7 +1063,7 @@ st_draw_vbo(struct gl_context *ctx,
             unsigned element_size = st->user_attrib[i].element_size;
             unsigned stride = st->user_attrib[i].stride;
             unsigned min_offset = min_index * stride;
-            unsigned max_offset = max_index * stride + element_size;
+            unsigned max_offset = max_index_plus_base * stride + element_size;
 
             assert(max_offset > min_offset);