[Mesa-dev] [PATCH 9/9] r600g/compute: avoid demoting items when reading/writing

Bruno Jiménez brunojimen at gmail.com
Fri Jun 13 13:35:38 PDT 2014


All the *Enqueue* functions that read/write buffers (except
clEnqueueCopyBuffer) would map the associated resource, making
it to be demoted if it was in the pool.

But we possitively know that this transfer will end before
any kernel is launched, so there's no need to demote it.

NOTE: As a proof of concept I have used PIPE_TRANSFER_MAP_DIRECTLY,
but it collides with OpenCL 1.2 CL_MAP_WRITE_INVALIDATE_REGION,
so we will have to find another bitfield to use.
---
 src/gallium/drivers/r600/evergreen_compute.c        | 20 +++++++++++++++-----
 src/gallium/state_trackers/clover/api/transfer.cpp  |  4 ++--
 src/gallium/state_trackers/clover/core/resource.cpp |  2 ++
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index e5967b5..794cbe6 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -967,18 +967,28 @@ void *r600_compute_global_transfer_map(
 	struct r600_resource_global* buffer =
 		(struct r600_resource_global*)resource;
 
-	struct pipe_resource *dst;
+	struct pipe_resource *dst =
+		(struct pipe_resource *) buffer->chunk->real_buffer;
 	unsigned offset = box->x;
 
+	/* If the item is already in the pool, and we are going
+	 * to read/write it, map it directly without demoting it */
 	if (buffer->chunk->start_in_dw != -1) {
-		compute_memory_demote_item(pool, buffer->chunk, ctx_);
+		if (usage & PIPE_TRANSFER_MAP_DIRECTLY) {
+			dst = (struct pipe_resource *) buffer->chunk->pool->bo;
+			offset += (buffer->chunk->start_in_dw * 4);
+		}
+		else {
+			compute_memory_demote_item(pool, buffer->chunk, ctx_);
+			dst = (struct pipe_resource *) buffer->chunk->real_buffer;
+		}
 	}
 
-	dst = (struct pipe_resource*)buffer->chunk->real_buffer;
-
-	if (usage & PIPE_TRANSFER_READ)
+	if ((usage & PIPE_TRANSFER_READ) && !(usage & PIPE_TRANSFER_MAP_DIRECTLY))
 		buffer->chunk->status |= ITEM_MAPPED_FOR_READING;
 
+	usage &= ~PIPE_TRANSFER_MAP_DIRECTLY;
+
 	COMPUTE_DBG(rctx->screen, "* r600_compute_global_transfer_map()\n"
 			"level = %u, usage = %u, box(x = %u, y = %u, z = %u "
 			"width = %u, height = %u, depth = %u)\n", level, usage,
diff --git a/src/gallium/state_trackers/clover/api/transfer.cpp b/src/gallium/state_trackers/clover/api/transfer.cpp
index 404ceb0..032542e 100644
--- a/src/gallium/state_trackers/clover/api/transfer.cpp
+++ b/src/gallium/state_trackers/clover/api/transfer.cpp
@@ -174,8 +174,8 @@ namespace {
       static mapping
       get(command_queue &q, T obj, cl_map_flags flags,
           size_t offset, size_t size) {
-         return { q, obj->resource(q), flags, true,
-                  {{ offset }}, {{ size, 1, 1 }} };
+         return { q, obj->resource(q), flags | PIPE_TRANSFER_MAP_DIRECTLY,
+                  true, {{ offset }}, {{ size, 1, 1 }} };
       }
    };
 
diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp
index 7b8a40a..bda9847 100644
--- a/src/gallium/state_trackers/clover/core/resource.cpp
+++ b/src/gallium/state_trackers/clover/core/resource.cpp
@@ -174,6 +174,8 @@ mapping::mapping(command_queue &q, resource &r,
    pctx(q.pipe) {
    unsigned usage = ((flags & CL_MAP_WRITE ? PIPE_TRANSFER_WRITE : 0 ) |
                      (flags & CL_MAP_READ ? PIPE_TRANSFER_READ : 0 ) |
+                     (flags & PIPE_TRANSFER_MAP_DIRECTLY ?
+                              PIPE_TRANSFER_MAP_DIRECTLY : 0 ) |
                      (!blocking ? PIPE_TRANSFER_UNSYNCHRONIZED : 0));
 
    p = pctx->transfer_map(pctx, r.pipe, 0, usage,
-- 
2.0.0



More information about the mesa-dev mailing list