gallium/util: Upload manager optimizations
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 10 Mar 2011 13:53:46 +0000 (14:53 +0100)
committerThomas Hellstrom <thellstrom@vmware.com>
Fri, 1 Jul 2011 11:30:36 +0000 (13:30 +0200)
Make sure that the upload manager doesn't upload data that's not
dirty. This speeds up the viewperf test proe-04/1 a factor 5 or so on svga.

Also introduce an u_upload_unmap() function that can be used
instead of u_upload_flush() so that we can pack
even more data in upload buffers. With this we can basically reuse the
upload buffer across flushes.

Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
src/gallium/auxiliary/util/u_upload_mgr.c
src/gallium/auxiliary/util/u_upload_mgr.h

index 9562acb821024f4db40e6b41a166dc884bb331c5..d36697db4ec80cb5e69bf2222cc3d28e676a479f 100644 (file)
@@ -72,6 +72,22 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
    return upload;
 }
 
    return upload;
 }
 
+void u_upload_unmap( struct u_upload_mgr *upload )
+{
+   if (upload->transfer) {
+      struct pipe_box *box = &upload->transfer->box;
+      if (upload->offset > box->x) {
+
+         pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
+                                        box->x, upload->offset - box->x);
+      }
+      pipe_transfer_unmap(upload->pipe, upload->transfer);
+      pipe_transfer_destroy(upload->pipe, upload->transfer);
+      upload->transfer = NULL;
+      upload->map = NULL;
+   }
+}
+
 /* Release old buffer.
  * 
  * This must usually be called prior to firing the command stream
 /* Release old buffer.
  * 
  * This must usually be called prior to firing the command stream
@@ -84,15 +100,7 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
 void u_upload_flush( struct u_upload_mgr *upload )
 {
    /* Unmap and unreference the upload buffer. */
 void u_upload_flush( struct u_upload_mgr *upload )
 {
    /* Unmap and unreference the upload buffer. */
-   if (upload->transfer) {
-      if (upload->offset) {
-         pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
-                                        0, upload->offset);
-      }
-      pipe_transfer_unmap(upload->pipe, upload->transfer);
-      pipe_transfer_destroy(upload->pipe, upload->transfer);
-      upload->transfer = NULL;
-   }
+   u_upload_unmap(upload);
    pipe_resource_reference( &upload->buffer, NULL );
    upload->size = 0;
 }
    pipe_resource_reference( &upload->buffer, NULL );
    upload->size = 0;
 }
@@ -172,6 +180,15 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
 
    offset = MAX2(upload->offset, alloc_offset);
 
 
    offset = MAX2(upload->offset, alloc_offset);
 
+   if (!upload->map) {
+      upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
+                                         offset, upload->size - offset,
+                                         PIPE_TRANSFER_WRITE |
+                                         PIPE_TRANSFER_FLUSH_EXPLICIT |
+                                         PIPE_TRANSFER_UNSYNCHRONIZED,
+                                         &upload->transfer);
+   }
+
    assert(offset < upload->buffer->width0);
    assert(offset + size <= upload->buffer->width0);
    assert(size);
    assert(offset < upload->buffer->width0);
    assert(offset + size <= upload->buffer->width0);
    assert(size);
index c9a2ffeb572074460298549851d8517fc9382f9f..98915139801bd41391a8a217ca44c9044b2cf117 100644 (file)
@@ -56,15 +56,27 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
  */
 void u_upload_destroy( struct u_upload_mgr *upload );
 
  */
 void u_upload_destroy( struct u_upload_mgr *upload );
 
-/* Unmap and release old buffer.
+/* Unmap and release old upload buffer.
  * 
  * 
+ * This is like u_upload_unmap() except the upload buffer is released for
+ * recycling. This should be called on real hardware flushes on systems
+ * that don't support the PIPE_TRANSFER_UNSYNCHRONIZED flag, as otherwise
+ * the next u_upload_buffer will cause a sync on the buffer.
+ */
+
+void u_upload_flush( struct u_upload_mgr *upload );
+
+/**
+ * Unmap upload buffer
+ *
+ * \param upload           Upload manager
+ *
  * This must usually be called prior to firing the command stream
  * which references the upload buffer, as many memory managers either
  * don't like firing a mapped buffer or cause subsequent maps of a
  * This must usually be called prior to firing the command stream
  * which references the upload buffer, as many memory managers either
  * don't like firing a mapped buffer or cause subsequent maps of a
- * fired buffer to wait.  For now, it's easiest just to grab a new
- * buffer.
+ * fired buffer to wait.
  */
  */
-void u_upload_flush( struct u_upload_mgr *upload );
+void u_upload_unmap( struct u_upload_mgr *upload );
 
 /**
  * Sub-allocate new memory from the upload buffer.
 
 /**
  * Sub-allocate new memory from the upload buffer.