gallium/util: Upload manager optimizations
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>
This commit is contained in:
parent
6d58029bf0
commit
cf4cd8592a
|
@ -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.
|
/* Release old buffer.
|
||||||
*
|
*
|
||||||
* This must usually be called prior to firing the command stream
|
* 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 )
|
void u_upload_flush( struct u_upload_mgr *upload )
|
||||||
{
|
{
|
||||||
/* Unmap and unreference the upload buffer. */
|
/* Unmap and unreference the upload buffer. */
|
||||||
if (upload->transfer) {
|
u_upload_unmap(upload);
|
||||||
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;
|
|
||||||
}
|
|
||||||
pipe_resource_reference( &upload->buffer, NULL );
|
pipe_resource_reference( &upload->buffer, NULL );
|
||||||
upload->size = 0;
|
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 < upload->buffer->width0);
|
||||||
assert(offset + size <= upload->buffer->width0);
|
assert(offset + size <= upload->buffer->width0);
|
||||||
assert(size);
|
assert(size);
|
||||||
|
|
|
@ -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
|
* This must usually be called prior to firing the command stream
|
||||||
* which references the upload buffer, as many memory managers either
|
* which references the upload buffer, as many memory managers either
|
||||||
* don't like firing a mapped buffer or cause subsequent maps of a
|
* 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
|
* fired buffer to wait.
|
||||||
* buffer.
|
|
||||||
*/
|
*/
|
||||||
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.
|
||||||
|
|
Loading…
Reference in New Issue