[Mesa-dev] [PATCH 10/10] gallium/radeon: lower memory usage during texture transfers

Marek Olšák maraeo at gmail.com
Thu May 19 10:59:18 UTC 2016


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

This improves throughput by keeping TTM overhead down.

Some piglit tests such as texelFetch and streaming-texture-leak will
use less memory now.
---
 src/gallium/drivers/radeon/r600_pipe_common.h |  1 +
 src/gallium/drivers/radeon/r600_texture.c     | 32 +++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/radeon/r600_pipe_common.h b/src/gallium/drivers/radeon/r600_pipe_common.h
index ccdf22a..4cdc69a 100644
--- a/src/gallium/drivers/radeon/r600_pipe_common.h
+++ b/src/gallium/drivers/radeon/r600_pipe_common.h
@@ -496,6 +496,7 @@ struct r600_common_context {
 	/* Misc stats. */
 	unsigned			num_draw_calls;
 	unsigned			num_dma_calls;
+	uint64_t			num_alloc_tex_transfer_bytes;
 
 	/* Render condition. */
 	struct r600_atom		render_cond_atom;
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 1333a25..1f973cc 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -1302,9 +1302,11 @@ static bool r600_can_invalidate_texture(struct r600_common_screen *rscreen,
 						 box->depth);
 }
 
-static void r600_texture_invalidate_storage(struct r600_common_screen *rscreen,
+static void r600_texture_invalidate_storage(struct r600_common_context *rctx,
 					    struct r600_texture *rtex)
 {
+	struct r600_common_screen *rscreen = rctx->screen;
+
 	/* There is no point in discarding depth and tiled buffers. */
 	assert(!rtex->is_depth);
 	assert(rtex->surface.level[0].mode == RADEON_SURF_MODE_LINEAR_ALIGNED);
@@ -1319,6 +1321,8 @@ static void r600_texture_invalidate_storage(struct r600_common_screen *rscreen,
 
 	r600_dirty_all_framebuffer_states(rscreen);
 	p_atomic_inc(&rscreen->dirty_tex_descriptor_counter);
+
+	rctx->num_alloc_tex_transfer_bytes += rtex->size;
 }
 
 static void *r600_texture_transfer_map(struct pipe_context *ctx,
@@ -1378,8 +1382,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
 			/* It's busy. */
 			if (r600_can_invalidate_texture(rctx->screen, rtex,
 							usage, box))
-				r600_texture_invalidate_storage(rctx->screen,
-								rtex);
+				r600_texture_invalidate_storage(rctx, rtex);
 			else
 				use_staging_texture = true;
 		}
@@ -1499,6 +1502,7 @@ static void *r600_texture_transfer_map(struct pipe_context *ctx,
 static void r600_texture_transfer_unmap(struct pipe_context *ctx,
 					struct pipe_transfer* transfer)
 {
+	struct r600_common_context *rctx = (struct r600_common_context*)ctx;
 	struct r600_transfer *rtransfer = (struct r600_transfer*)transfer;
 	struct pipe_resource *texture = transfer->resource;
 	struct r600_texture *rtex = (struct r600_texture*)texture;
@@ -1514,8 +1518,28 @@ static void r600_texture_transfer_unmap(struct pipe_context *ctx,
 		}
 	}
 
-	if (rtransfer->staging)
+	if (rtransfer->staging) {
+		rctx->num_alloc_tex_transfer_bytes += rtransfer->staging->buf->size;
 		pipe_resource_reference((struct pipe_resource**)&rtransfer->staging, NULL);
+	}
+
+	/* Heuristic for {upload, draw, upload, draw, ..}:
+	 *
+	 * Flush the gfx IB if we've allocated too much texture storage.
+	 *
+	 * The idea is that we don't want to build IBs that use too much
+	 * memory and put pressure on the kernel memory manager and we also
+	 * want to make temporary and invalidated buffers go idle ASAP to
+	 * decrease the total memory usage or make them reusable. The memory
+	 * usage will be slightly higher than given here because of the buffer
+	 * cache in the winsys.
+	 *
+	 * The result is that the kernel memory manager is never a bottleneck.
+	 */
+	if (rctx->num_alloc_tex_transfer_bytes > rctx->screen->info.vram_size / 4) {
+		rctx->gfx.flush(rctx, RADEON_FLUSH_ASYNC, NULL);
+		rctx->num_alloc_tex_transfer_bytes = 0;
+	}
 
 	FREE(transfer);
 }
-- 
2.7.4



More information about the mesa-dev mailing list