[Mesa-dev] [PATCH 11/13] gallium/upload_mgr: don't unmap buffers if persistent mappings are supported
Fredrik Höglund
fredrik at kde.org
Thu Jan 30 15:22:14 PST 2014
On Thursday 30 January 2014, Marek Olšák wrote:
> From: Marek Olšák <marek.olsak at amd.com>
>
> ---
> src/gallium/auxiliary/util/u_upload_mgr.c | 65 ++++++++++++++++++++++++-------
> 1 file changed, 51 insertions(+), 14 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
> index 7349d00..ccaab27 100644
> --- a/src/gallium/auxiliary/util/u_upload_mgr.c
> +++ b/src/gallium/auxiliary/util/u_upload_mgr.c
> @@ -44,6 +44,8 @@ struct u_upload_mgr {
> unsigned default_size; /* Minimum size of the upload buffer, in bytes. */
> unsigned alignment; /* Alignment of each sub-allocation. */
> unsigned bind; /* Bitmask of PIPE_BIND_* flags. */
> + unsigned map_flags; /* Bitmask of PIPE_TRANSFER_* flags. */
> + boolean map_persistent; /* If persistent mappings are supported. */
>
> struct pipe_resource *buffer; /* Upload buffer. */
> struct pipe_transfer *transfer; /* Transfer object for the upload buffer. */
> @@ -67,20 +69,39 @@ struct u_upload_mgr *u_upload_create( struct pipe_context *pipe,
> upload->default_size = default_size;
> upload->alignment = alignment;
> upload->bind = bind;
> - upload->buffer = NULL;
> +
> + upload->map_persistent =
> + pipe->screen->get_param(pipe->screen,
> + PIPE_CAP_BUFFER_TRANSFER_PERSISTENT_COHERENT);
> +
> + if (upload->map_persistent) {
> + upload->map_flags = PIPE_TRANSFER_WRITE |
> + PIPE_TRANSFER_PERSISTENT |
> + PIPE_TRANSFER_COHERENT;
> + }
> + else {
> + upload->map_flags = PIPE_TRANSFER_WRITE |
> + PIPE_TRANSFER_UNSYNCHRONIZED |
> + PIPE_TRANSFER_FLUSH_EXPLICIT;
> + }
>
> return upload;
> }
>
> -void u_upload_unmap( struct u_upload_mgr *upload )
> +
> +static void upload_unmap_internal(struct u_upload_mgr *upload, boolean destroying)
> {
> + if (!destroying && upload->map_persistent)
> + return;
> +
> if (upload->transfer) {
> struct pipe_box *box = &upload->transfer->box;
> - if ((int) upload->offset > box->x) {
>
> + if (!upload->map_persistent && (int) 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);
> upload->transfer = NULL;
> upload->map = NULL;
> @@ -88,10 +109,16 @@ void u_upload_unmap( struct u_upload_mgr *upload )
> }
>
>
> +void u_upload_unmap( struct u_upload_mgr *upload )
> +{
> + upload_unmap_internal(upload, FALSE);
> +}
> +
> +
> static void u_upload_release_buffer(struct u_upload_mgr *upload)
> {
> /* Unmap and unreference the upload buffer. */
> - u_upload_unmap(upload);
> + upload_unmap_internal(upload, TRUE);
> pipe_resource_reference( &upload->buffer, NULL );
> upload->size = 0;
> }
> @@ -108,6 +135,8 @@ static enum pipe_error
> u_upload_alloc_buffer( struct u_upload_mgr *upload,
> unsigned min_size )
> {
> + struct pipe_screen *screen = upload->pipe->screen;
> + struct pipe_resource buffer;
> unsigned size;
>
> /* Release the old buffer, if present:
> @@ -118,19 +147,29 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
> */
> size = align(MAX2(upload->default_size, min_size), 4096);
>
> - upload->buffer = pipe_buffer_create( upload->pipe->screen,
> - upload->bind,
> - PIPE_USAGE_STREAM,
> - size );
> + memset(&buffer, 0, sizeof buffer);
> + buffer.target = PIPE_BUFFER;
> + buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
> + buffer.bind = upload->bind;
> + buffer.usage = PIPE_USAGE_STREAM;
> + buffer.width0 = size;
> + buffer.height0 = 1;
> + buffer.depth0 = 1;
> + buffer.array_size = 1;
> +
> + if (upload->map_persistent) {
> + buffer.flags = PIPE_RESOURCE_FLAG_TRANSFER_PERSISTENT |
> + PIPE_RESOURCE_FLAG_TRANSFER_COHERENT;
> + }
> +
> + upload->buffer = screen->resource_create(screen, &buffer);
> if (upload->buffer == NULL) {
> return PIPE_ERROR_OUT_OF_MEMORY;
> }
>
> /* Map the new buffer. */
> upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
> - 0, size,
> - PIPE_TRANSFER_WRITE |
> - PIPE_TRANSFER_FLUSH_EXPLICIT,
> + 0, size, upload->map_flags,
> &upload->transfer);
> if (upload->map == NULL) {
> upload->transfer = NULL;
> @@ -176,9 +215,7 @@ enum pipe_error u_upload_alloc( struct u_upload_mgr *upload,
> 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->map_flags,
> &upload->transfer);
> if (!upload->map) {
> upload->transfer = NULL;
>
Reviewed-by: Fredrik Höglund <fredrik at kde.org>
More information about the mesa-dev
mailing list