util/draw: replace assertions with conditionals in util_draw_max_index()
authorBrian Paul <brianp@vmware.com>
Sat, 12 Nov 2011 18:50:32 +0000 (11:50 -0700)
committerBrian Paul <brianp@vmware.com>
Tue, 15 Nov 2011 14:49:26 +0000 (07:49 -0700)
Don't assert/die if a VBO is too small.  Return zero instead.  For
debug builds, emit a warning message since this is an unusual situation
that might indicate that there's a bug in the app.

Note that util_draw_max_index() now returns max_index+1 instead of
max_index.  This lets us return zero to indicate that one of the VBOs
is too small to draw anything.

Fixes a failure with the new piglit vbo-too-small test.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/draw/draw_pt.c
src/gallium/auxiliary/util/u_draw.c

index e0eda67c1a2aa6cfc37f9194156ae50e43881f6d..080e03dd46fd31a9b87ee655e547c7cf24cb5131 100644 (file)
@@ -422,6 +422,7 @@ draw_vbo(struct draw_context *draw,
 {
    unsigned reduced_prim = u_reduced_prim(info->mode);
    unsigned instance;
+   unsigned index_limit;
 
    assert(info->instance_count > 0);
    if (info->indexed)
@@ -470,11 +471,20 @@ draw_vbo(struct draw_context *draw,
    if (0)
       draw_print_arrays(draw, info->mode, info->start, MIN2(info->count, 20));
 
-   draw->pt.max_index = util_draw_max_index(draw->pt.vertex_buffer,
-                                            draw->pt.nr_vertex_buffers,
-                                            draw->pt.vertex_element,
-                                            draw->pt.nr_vertex_elements,
-                                            info);
+   index_limit = util_draw_max_index(draw->pt.vertex_buffer,
+                                     draw->pt.nr_vertex_buffers,
+                                     draw->pt.vertex_element,
+                                     draw->pt.nr_vertex_elements,
+                                     info);
+
+   if (index_limit == 0) {
+      /* one of the buffers is too small to do any valid drawing */
+      debug_warning("draw: VBO too small to draw anything\n");
+      return;
+   }
+
+   draw->pt.max_index = index_limit - 1;
+
 
    /*
     * TODO: We could use draw->pt.max_index to further narrow
index 20837be5e594628c948e1e5ef1e2847894ef11c9..d16575b7340000c09b88bda7fd259201247b49ea 100644 (file)
 
 
 /**
- * Returns the largest legal index value for the current set of bound vertex
- * buffers.  Regardless of any other consideration, all vertex lookups need to
- * be clamped to 0..max_index to prevent an out-of-bound access.
+ * Returns the largest legal index value plus one for the current set
+ * of bound vertex buffers.  Regardless of any other consideration,
+ * all vertex lookups need to be clamped to 0..max_index-1 to prevent
+ * an out-of-bound access.
+ *
+ * Note that if zero is returned it means that one or more buffers is
+ * too small to contain any valid vertex data.
  */
 unsigned
 util_draw_max_index(
@@ -48,7 +52,7 @@ util_draw_max_index(
    unsigned max_index;
    unsigned i;
 
-   max_index = ~0;
+   max_index = ~0U - 1;
    for (i = 0; i < nr_vertex_elements; i++) {
       const struct pipe_vertex_element *element =
          &vertex_elements[i];
@@ -68,13 +72,25 @@ util_draw_max_index(
       assert(format_desc->block.bits % 8 == 0);
       format_size = format_desc->block.bits/8;
 
-      assert(buffer_size - buffer->buffer_offset <= buffer_size);
+      if (buffer->buffer_offset >= buffer_size) {
+         /* buffer is too small */
+         return 0;
+      }
+
       buffer_size -= buffer->buffer_offset;
 
-      assert(buffer_size - element->src_offset <= buffer_size);
+      if (element->src_offset >= buffer_size) {
+         /* buffer is too small */
+         return 0;
+      }
+
       buffer_size -= element->src_offset;
 
-      assert(buffer_size - format_size <= buffer_size);
+      if (format_size > buffer_size) {
+         /* buffer is too small */
+         return 0;
+      }
+
       buffer_size -= format_size;
 
       if (buffer->stride != 0) {
@@ -95,5 +111,5 @@ util_draw_max_index(
       }
    }
 
-   return max_index;
+   return max_index + 1;
 }