[Mesa-dev] [PATCH 02/10] gallium/radeon: reallocate suballocated buffers when exported

Marek Olšák maraeo at gmail.com
Sat Jul 8 00:42:11 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

This should fix exports of suballocated buffers.
---
 src/gallium/drivers/radeon/r600_buffer_common.c |  3 ++-
 src/gallium/drivers/radeon/r600_texture.c       | 26 +++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/src/gallium/drivers/radeon/r600_buffer_common.c b/src/gallium/drivers/radeon/r600_buffer_common.c
index 40d763b..dd1c209 100644
--- a/src/gallium/drivers/radeon/r600_buffer_common.c
+++ b/src/gallium/drivers/radeon/r600_buffer_common.c
@@ -281,27 +281,28 @@ void r600_replace_buffer_storage(struct pipe_context *ctx,
 				 struct pipe_resource *dst,
 				 struct pipe_resource *src)
 {
 	struct r600_common_context *rctx = (struct r600_common_context *)ctx;
 	struct r600_resource *rdst = r600_resource(dst);
 	struct r600_resource *rsrc = r600_resource(src);
 	uint64_t old_gpu_address = rdst->gpu_address;
 
 	pb_reference(&rdst->buf, rsrc->buf);
 	rdst->gpu_address = rsrc->gpu_address;
+	rdst->b.b.bind = rsrc->b.b.bind;
+	rdst->flags = rsrc->flags;
 
 	assert(rdst->vram_usage == rsrc->vram_usage);
 	assert(rdst->gart_usage == rsrc->gart_usage);
 	assert(rdst->bo_size == rsrc->bo_size);
 	assert(rdst->bo_alignment == rsrc->bo_alignment);
 	assert(rdst->domains == rsrc->domains);
-	assert(rdst->flags == rsrc->flags);
 
 	rctx->rebind_buffer(ctx, dst, old_gpu_address);
 }
 
 void r600_invalidate_resource(struct pipe_context *ctx,
 			      struct pipe_resource *resource)
 {
 	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
 	struct r600_resource *rbuffer = r600_resource(resource);
 
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index f5f7d10..3aac3c7 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -611,20 +611,46 @@ static boolean r600_texture_get_handle(struct pipe_screen* screen,
 			stride = rtex->surface.u.gfx9.surf_pitch *
 				 rtex->surface.bpe;
 			slice_size = rtex->surface.u.gfx9.surf_slice_size;
 		} else {
 			offset = rtex->surface.u.legacy.level[0].offset;
 			stride = rtex->surface.u.legacy.level[0].nblk_x *
 				 rtex->surface.bpe;
 			slice_size = rtex->surface.u.legacy.level[0].slice_size;
 		}
 	} else {
+		/* Move a suballocated buffer into a non-suballocated allocation. */
+		if (rscreen->ws->buffer_is_suballocated(res->buf)) {
+			assert(!res->b.is_shared);
+
+			/* Allocate a new buffer with PIPE_BIND_SHARED. */
+			struct pipe_resource templ = res->b.b;
+			templ.bind |= PIPE_BIND_SHARED;
+
+			struct pipe_resource *newb =
+				screen->resource_create(screen, &templ);
+			if (!newb)
+				return false;
+
+			/* Copy the old buffer contents to the new one. */
+			struct pipe_box box;
+			u_box_1d(0, newb->width0, &box);
+			rctx->b.resource_copy_region(&rctx->b, newb, 0, 0, 0, 0,
+						     &res->b.b, 0, &box);
+			/* Move the new buffer storage to the old pipe_resource. */
+			r600_replace_buffer_storage(&rctx->b, &res->b.b, newb);
+			pipe_resource_reference(&newb, NULL);
+
+			assert(res->b.b.bind & PIPE_BIND_SHARED);
+			assert(res->flags & RADEON_FLAG_NO_SUBALLOC);
+		}
+
 		/* Buffers */
 		offset = 0;
 		stride = 0;
 		slice_size = 0;
 	}
 
 	if (res->b.is_shared) {
 		/* USAGE_EXPLICIT_FLUSH must be cleared if at least one user
 		 * doesn't set it.
 		 */
-- 
2.7.4



More information about the mesa-dev mailing list