aux/vbuf: add fastpath for skipping identical vbuf updates
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Thu, 20 Jan 2022 17:06:05 +0000 (12:06 -0500)
committerMarge Bot <emma+marge@anholt.net>
Tue, 1 Feb 2022 01:17:09 +0000 (01:17 +0000)
the overhead of comparing these is MUCH less than the overhead of queuing a
driver method and performing the update

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14640>

src/gallium/auxiliary/util/u_vbuf.c

index 587a45e..5e4f4f4 100644 (file)
@@ -989,7 +989,7 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
    uint32_t nonzero_stride_vb_mask = 0;
    /* which buffers are unaligned to 2/4 bytes */
    uint32_t unaligned_vb_mask[2] = {0};
-   const uint32_t mask =
+   uint32_t mask =
       ~(((1ull << (count + unbind_num_trailing_slots)) - 1) << start_slot);
 
    if (!bufs) {
@@ -1030,6 +1030,21 @@ void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr,
          continue;
       }
 
+      bool not_user = !vb->is_user_buffer && vb->is_user_buffer == orig_vb->is_user_buffer;
+      /* struct isn't tightly packed: do not use memcmp */
+      if (not_user && orig_vb->stride == vb->stride &&
+          orig_vb->buffer_offset == vb->buffer_offset && orig_vb->buffer.resource == vb->buffer.resource) {
+         mask |= BITFIELD_BIT(dst_index);
+         if (take_ownership) {
+             pipe_vertex_buffer_unreference(orig_vb);
+             /* the pointer was unset in the line above, so copy it back */
+             orig_vb->buffer.resource = vb->buffer.resource;
+         }
+         if (mask == UINT32_MAX)
+            return;
+         continue;
+      }
+
       if (take_ownership) {
          pipe_vertex_buffer_unreference(orig_vb);
          memcpy(orig_vb, vb, sizeof(*vb));