util: Move u_debug to utils
[mesa.git] / src / gallium / auxiliary / util / u_draw.c
index 5b3c41231a2ed428f5a0b67ba1a71b31737b6122..a7590f7f043142da1a6d765d9f01b8d344aadc3b 100644 (file)
@@ -27,6 +27,7 @@
 
 
 #include "util/u_debug.h"
+#include "util/u_inlines.h"
 #include "util/u_math.h"
 #include "util/u_format.h"
 #include "util/u_draw.h"
@@ -61,13 +62,13 @@ util_draw_max_index(
       const struct util_format_description *format_desc;
       unsigned format_size;
 
-      if (!buffer->buffer) {
+      if (buffer->is_user_buffer || !buffer->buffer.resource) {
          continue;
       }
 
-      assert(buffer->buffer->height0 == 1);
-      assert(buffer->buffer->depth0 == 1);
-      buffer_size = buffer->buffer->width0;
+      assert(buffer->buffer.resource->height0 == 1);
+      assert(buffer->buffer.resource->depth0 == 1);
+      buffer_size = buffer->buffer.resource->width0;
 
       format_desc = util_format_description(element->src_format);
       assert(format_desc->block.width == 1);
@@ -108,11 +109,60 @@ util_draw_max_index(
          else {
             /* Per-instance data. Simply make sure the state tracker didn't
              * request more instances than those that fit in the buffer */
-            assert((info->start_instance + info->instance_count)/element->instance_divisor
-                   <= (buffer_max_index + 1));
+            if ((info->start_instance + info->instance_count)/element->instance_divisor
+                > (buffer_max_index + 1)) {
+               /* FIXME: We really should stop thinking in terms of maximum
+                * indices/instances and simply start clamping against buffer
+                * size. */
+               debug_printf("%s: too many instances for vertex buffer\n",
+                            __FUNCTION__);
+               return 0;
+            }
          }
       }
    }
 
    return max_index + 1;
 }
+
+
+/* This extracts the draw arguments from the info_in->indirect resource,
+ * puts them into a new instance of pipe_draw_info, and calls draw_vbo on it.
+ */
+void
+util_draw_indirect(struct pipe_context *pipe,
+                   const struct pipe_draw_info *info_in)
+{
+   struct pipe_draw_info info;
+   struct pipe_transfer *transfer;
+   uint32_t *params;
+   const unsigned num_params = info_in->index_size ? 5 : 4;
+
+   assert(info_in->indirect);
+   assert(!info_in->count_from_stream_output);
+
+   memcpy(&info, info_in, sizeof(info));
+
+   params = (uint32_t *)
+      pipe_buffer_map_range(pipe,
+                            info_in->indirect->buffer,
+                            info_in->indirect->offset,
+                            num_params * sizeof(uint32_t),
+                            PIPE_TRANSFER_READ,
+                            &transfer);
+   if (!transfer) {
+      debug_printf("%s: failed to map indirect buffer\n", __FUNCTION__);
+      return;
+   }
+
+   info.count = params[0];
+   info.instance_count = params[1];
+   info.start = params[2];
+   info.index_bias = info_in->index_size ? params[3] : 0;
+   info.start_instance = info_in->index_size ? params[4] : params[3];
+   info.indirect = NULL;
+
+   pipe_buffer_unmap(pipe, transfer);
+
+   pipe->draw_vbo(pipe, &info);
+}