Mesa (master): r600g/compute: Defer the creation of the temporary resource

Tom Stellard tstellar at kemper.freedesktop.org
Tue Jun 24 16:43:45 UTC 2014


Module: Mesa
Branch: master
Commit: c997007f66d402aea5a76da5b260b49a91c0fce1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c997007f66d402aea5a76da5b260b49a91c0fce1

Author: Bruno Jiménez <brunojimen at gmail.com>
Date:   Thu Jun 19 20:20:02 2014 +0200

r600g/compute: Defer the creation of the temporary resource

For the first use of a buffer, we will only need the temporary
resource in the case that a user wants to write/map to this buffer.

But in the cases where the user creates a buffer to act as an
output of a kernel, then we were creating an unneeded resource,
because it will contain garbage, and would be copied to the pool,
and destroyed when promoting.

This patch avoids the creation and copies of resources in
this case.

Reviewed-by: Tom Stellard <thomas.stellard at amd.com>

---

 src/gallium/drivers/r600/compute_memory_pool.c |   31 ++++++++++++------------
 src/gallium/drivers/r600/evergreen_compute.c   |   17 +++++++++----
 2 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/src/gallium/drivers/r600/compute_memory_pool.c b/src/gallium/drivers/r600/compute_memory_pool.c
index 9cb16f8..fe19d9e 100644
--- a/src/gallium/drivers/r600/compute_memory_pool.c
+++ b/src/gallium/drivers/r600/compute_memory_pool.c
@@ -353,19 +353,21 @@ int compute_memory_promote_item(struct compute_memory_pool *pool,
 	list_add(&item->link, pos);
 	item->start_in_dw = start_in_dw;
 
-	u_box_1d(0, item->size_in_dw * 4, &box);
-
-	rctx->b.b.resource_copy_region(pipe,
-			dst, 0, item->start_in_dw * 4, 0 ,0,
-			src, 0, &box);
-
-	/* We check if the item is mapped for reading.
-	 * In this case, we need to keep the temporary buffer 'alive'
-	 * because it is possible to keep a map active for reading
-	 * while a kernel (that reads from it) executes */
-	if (!(item->status & ITEM_MAPPED_FOR_READING)) {
-		pool->screen->b.b.resource_destroy(screen, src);
-		item->real_buffer = NULL;
+	if (src != NULL) {
+		u_box_1d(0, item->size_in_dw * 4, &box);
+
+		rctx->b.b.resource_copy_region(pipe,
+				dst, 0, item->start_in_dw * 4, 0 ,0,
+				src, 0, &box);
+
+		/* We check if the item is mapped for reading.
+		 * In this case, we need to keep the temporary buffer 'alive'
+		 * because it is possible to keep a map active for reading
+		 * while a kernel (that reads from it) executes */
+		if (!(item->status & ITEM_MAPPED_FOR_READING)) {
+			pool->screen->b.b.resource_destroy(screen, src);
+			item->real_buffer = NULL;
+		}
 	}
 
 	return 0;
@@ -475,8 +477,7 @@ struct compute_memory_item* compute_memory_alloc(
 	new_item->start_in_dw = -1; /* mark pending */
 	new_item->id = pool->next_id++;
 	new_item->pool = pool;
-	new_item->real_buffer = (struct r600_resource*)r600_compute_buffer_alloc_vram(
-							pool->screen, size_in_dw * 4);
+	new_item->real_buffer = NULL;
 
 	list_addtail(&new_item->link, pool->unallocated_list);
 
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 5c115dc..12e9c85 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -970,14 +970,21 @@ void *r600_compute_global_transfer_map(
 	struct r600_resource_global* buffer =
 		(struct r600_resource_global*)resource;
 
-	struct pipe_resource *dst;
+	struct compute_memory_item *item = buffer->chunk;
+	struct pipe_resource *dst = NULL;
 	unsigned offset = box->x;
 
-	if (is_item_in_pool(buffer->chunk)) {
-		compute_memory_demote_item(pool, buffer->chunk, ctx_);
+	if (is_item_in_pool(item)) {
+		compute_memory_demote_item(pool, item, ctx_);
+	}
+	else {
+		if (item->real_buffer == NULL) {
+			item->real_buffer = (struct r600_resource*)
+					r600_compute_buffer_alloc_vram(pool->screen, item->size_in_dw * 4);
+		}
 	}
 
-	dst = (struct pipe_resource*)buffer->chunk->real_buffer;
+	dst = (struct pipe_resource*)item->real_buffer;
 
 	if (usage & PIPE_TRANSFER_READ)
 		buffer->chunk->status |= ITEM_MAPPED_FOR_READING;
@@ -988,7 +995,7 @@ void *r600_compute_global_transfer_map(
 			box->x, box->y, box->z, box->width, box->height,
 			box->depth);
 	COMPUTE_DBG(rctx->screen, "Buffer id = %u offset = "
-		"%u (box.x)\n", buffer->chunk->id, box->x);
+		"%u (box.x)\n", item->id, box->x);
 
 
 	assert(resource->target == PIPE_BUFFER);




More information about the mesa-commit mailing list