[Mesa-dev] [PATCH] gallium/radeon: never use staging buffers with AMD_pinned_memory

Nicolai Hähnle nhaehnle at gmail.com
Wed Apr 12 10:44:16 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

---
 src/gallium/drivers/radeon/r600_buffer_common.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 10036af..0e93404 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -320,25 +320,39 @@ static bool r600_can_dma_copy_buffer(struct r600_common_context *rctx,
 
 static void *r600_buffer_transfer_map(struct pipe_context *ctx,
                                       struct pipe_resource *resource,
                                       unsigned level,
                                       unsigned usage,
                                       const struct pipe_box *box,
                                       struct pipe_transfer **ptransfer)
 {
 	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
 	struct r600_common_screen *rscreen = (struct r600_common_screen*)ctx->screen;
-        struct r600_resource *rbuffer = r600_resource(resource);
-        uint8_t *data;
+	struct r600_resource *rbuffer = r600_resource(resource);
+	uint8_t *data;
 
 	assert(box->x + box->width <= resource->width0);
 
+	/* From GL_AMD_pinned_memory issues:
+	 *
+	 *     4) Is glMapBuffer on a shared buffer guaranteed to return the
+	 *        same system address which was specified at creation time?
+	 *
+	 *        RESOLVED: NO. The GL implementation might return a different
+	 *        virtual mapping of that memory, although the same physical
+	 *        page will be used.
+	 *
+	 * So don't ever use staging buffers.
+	 */
+	if (rscreen->ws->buffer_is_user_ptr(rbuffer->buf))
+		usage |= PIPE_TRANSFER_PERSISTENT;
+
 	/* See if the buffer range being mapped has never been initialized,
 	 * in which case it can be mapped unsynchronized. */
 	if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
 	    usage & PIPE_TRANSFER_WRITE &&
 	    !rbuffer->is_shared &&
 	    !util_ranges_intersect(&rbuffer->valid_buffer_range, box->x, box->x + box->width)) {
 		usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
 	}
 
 	/* If discarding the entire range, discard the whole resource instead. */
-- 
2.9.3



More information about the mesa-dev mailing list