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 <thellst...@vmware.com> --- src/gallium/auxiliary/util/u_upload_mgr.c | 41 ++++++++++++++++++++++------ src/gallium/auxiliary/util/u_upload_mgr.h | 10 +++++++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c index dcf800a..7768e13 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.c +++ b/src/gallium/auxiliary/util/u_upload_mgr.c @@ -51,6 +51,7 @@ struct u_upload_mgr { unsigned size; /* Actual size of the upload buffer. */ unsigned offset; /* Aligned offset to the upload buffer, pointing * at the first unused byte. */ + unsigned uploaded_offs; /* Offset below which data is already uploaded */ }; @@ -72,6 +73,22 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, return upload; } +void u_upload_unmap( struct u_upload_mgr *upload ) +{ + if (upload->transfer) { + if (upload->size > upload->uploaded_offs) { + pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, + upload->uploaded_offs, + upload->offset - upload->uploaded_offs); + } + pipe_transfer_unmap(upload->pipe, upload->transfer); + pipe_transfer_destroy(upload->pipe, upload->transfer); + upload->transfer = NULL; + upload->uploaded_offs = upload->offset; + upload->map = NULL; + } +} + /* Release old buffer. * * This must usually be called prior to firing the command stream @@ -84,17 +101,10 @@ 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. */ - if (upload->transfer) { - if (upload->size) { - pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, - 0, upload->size); - } - 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; + upload->uploaded_offs = 0; } @@ -172,6 +182,19 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload, offset = MAX2(upload->offset, alloc_offset); + if (!upload->map) { + upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer, + 0, upload->size, + PIPE_TRANSFER_WRITE | + PIPE_TRANSFER_FLUSH_EXPLICIT | + PIPE_TRANSFER_UNSYNCHRONIZED, + &upload->transfer); + + + assert(offset >= upload->uploaded_offs); + upload->uploaded_offs = offset; + } + assert(offset < upload->buffer->width0); assert(offset + size <= upload->buffer->width0); assert(size); diff --git a/src/gallium/auxiliary/util/u_upload_mgr.h b/src/gallium/auxiliary/util/u_upload_mgr.h index c9a2ffe..02426ea 100644 --- a/src/gallium/auxiliary/util/u_upload_mgr.h +++ b/src/gallium/auxiliary/util/u_upload_mgr.h @@ -67,6 +67,16 @@ void u_upload_destroy( struct u_upload_mgr *upload ); void u_upload_flush( struct u_upload_mgr *upload ); /** + * Unmap upload buffer + * + * \param upload Upload manager + * + * This is like u_upload_flush() except the upload buffer is kept for + * re-use across flushes. Allows us to pack more data into upload buffers. + */ +void u_upload_unmap( struct u_upload_mgr *upload ); + +/** * Sub-allocate new memory from the upload buffer. * * \param upload Upload manager -- 1.6.2.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev