gallium/u_vbuf: optimize looping over the list of buffers to upload
authorMarek Olšák <maraeo@gmail.com>
Sun, 28 Oct 2012 19:11:32 +0000 (20:11 +0100)
committerMarek Olšák <maraeo@gmail.com>
Thu, 1 Nov 2012 02:17:58 +0000 (03:17 +0100)
src/gallium/auxiliary/util/u_vbuf.c

index 26ecb7ab51e8a4b45fb2bb93f7d7b4d046e81085..5bd60dc95f0568a881bdd89421d677f2cf0d5b04 100644 (file)
@@ -831,18 +831,18 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
 {
    unsigned i;
    unsigned nr_velems = mgr->ve->count;
-   unsigned nr_vbufs = util_last_bit(mgr->enabled_vb_mask);
    struct pipe_vertex_element *velems =
          mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve;
    unsigned start_offset[PIPE_MAX_ATTRIBS];
-   unsigned end_offset[PIPE_MAX_ATTRIBS] = {0};
+   unsigned end_offset[PIPE_MAX_ATTRIBS];
+   uint32_t buffer_mask = 0;
 
    /* Determine how much data needs to be uploaded. */
    for (i = 0; i < nr_velems; i++) {
       struct pipe_vertex_element *velem = &velems[i];
       unsigned index = velem->vertex_buffer_index;
       struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index];
-      unsigned instance_div, first, size;
+      unsigned instance_div, first, size, index_bit;
 
       /* Skip the buffers generated by translate. */
       if (index == mgr->fallback_vbs[VB_VERTEX] ||
@@ -872,8 +872,10 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
          size = vb->stride * (num_vertices - 1) + mgr->ve->src_format_size[i];
       }
 
+      index_bit = 1 << index;
+
       /* Update offsets. */
-      if (!end_offset[index]) {
+      if (!(buffer_mask & index_bit)) {
          start_offset[index] = first;
          end_offset[index] = first + size;
       } else {
@@ -882,19 +884,20 @@ u_vbuf_upload_buffers(struct u_vbuf *mgr,
          if (first + size > end_offset[index])
             end_offset[index] = first + size;
       }
+
+      buffer_mask |= index_bit;
    }
 
    /* Upload buffers. */
-   for (i = 0; i < nr_vbufs; i++) {
-      unsigned start, end = end_offset[i];
+   while (buffer_mask) {
+      unsigned start, end;
       struct pipe_vertex_buffer *real_vb;
       const uint8_t *ptr;
 
-      if (!end) {
-         continue;
-      }
+      i = u_bit_scan(&buffer_mask);
 
       start = start_offset[i];
+      end = end_offset[i];
       assert(start < end);
 
       real_vb = &mgr->real_vertex_buffer[i];