Mesa (master): r600g: make range/block act more like a page table

Dave Airlie airlied at kemper.freedesktop.org
Thu May 12 23:29:20 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu May 12 15:01:33 2011 +1000

r600g: make range/block act more like a page table

only allocate the blocks ptr in the range if we ever have one,
otherwise don't bother wasting the memory.

valgrind glxinfo
before:
==967==     in use at exit: 419,754 bytes in 706 blocks
==967==   total heap usage: 3,552 allocs, 2,846 frees, 3,550,131 bytes allocated

after:
==5227==     in use at exit: 419,754 bytes in 706 blocks
==5227==   total heap usage: 3,452 allocs, 2,746 frees, 3,140,531 bytes allocate

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/winsys/r600/drm/evergreen_hw_context.c |   23 +------
 src/gallium/winsys/r600/drm/r600_hw_context.c      |   70 ++++++++++++--------
 src/gallium/winsys/r600/drm/r600_priv.h            |    2 +-
 3 files changed, 45 insertions(+), 50 deletions(-)

diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
index e89f457..2a2c37f 100644
--- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
+++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
@@ -518,15 +518,6 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon)
 		goto out_err;
 	}
 
-	/* initialize hash */
-	for (int i = 0; i < NUM_RANGES; i++) {
-		ctx->range[i].blocks = calloc(1 << HASH_SHIFT, sizeof(void*));
-		if (ctx->range[i].blocks == NULL) {
-			r = -ENOMEM;
-			goto out_err;
-		}
-	}
-
 	/* add blocks */
 	r = r600_context_add_block(ctx, evergreen_config_reg_list,
 				   Elements(evergreen_config_reg_list), PKT3_SET_CONFIG_REG, EVERGREEN_CONFIG_REG_OFFSET);
@@ -590,17 +581,9 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon)
 	/* VS loop const */
 	evergreen_loop_const_init(ctx, 32);
 
-	/* setup block table */
-	ctx->blocks = calloc(ctx->nblocks, sizeof(void*));
-	for (int i = 0, c = 0; i < NUM_RANGES; i++) {
-		for (int j = 0; j < (1 << HASH_SHIFT); j++) {
-			if (ctx->range[i].blocks[j]) {
-				assert(c < ctx->nblocks);
-				ctx->blocks[c++] = ctx->range[i].blocks[j];
-				j += (ctx->range[i].blocks[j]->nreg) - 1;
-			}
-		}
-	}
+	r = r600_setup_block_table(ctx);
+	if (r)
+		goto out_err;
 
 	/* allocate cs variables */
 	ctx->nreloc = RADEON_CTX_MAX_PM4;
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index e60bf75..595b110 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -103,6 +103,12 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg,
 		ctx->nblocks++;
 		for (int j = 0; j < n; j++) {
 			range = &ctx->range[CTX_RANGE_ID(ctx, reg[i + j].offset)];
+			/* create block table if it doesn't exist */
+			if (!range->blocks)
+				range->blocks = calloc(1 << HASH_SHIFT, sizeof(void *));
+			if (!range->blocks)
+				return -1;
+
 			range->blocks[CTX_BLOCK_ID(ctx, reg[i + j].offset)] = block;
 		}
 
@@ -612,6 +618,8 @@ void r600_context_fini(struct r600_context *ctx)
 	struct r600_range *range;
 
 	for (int i = 0; i < NUM_RANGES; i++) {
+		if (!ctx->range[i].blocks)
+			continue;
 		for (int j = 0; j < (1 << HASH_SHIFT); j++) {
 			block = ctx->range[i].blocks[j];
 			if (block) {
@@ -637,6 +645,36 @@ void r600_context_fini(struct r600_context *ctx)
 	memset(ctx, 0, sizeof(struct r600_context));
 }
 
+int r600_setup_block_table(struct r600_context *ctx)
+{
+	/* setup block table */
+	ctx->blocks = calloc(ctx->nblocks, sizeof(void*));
+	if (!ctx->blocks)
+		return -ENOMEM;
+	for (int i = 0, c = 0; i < NUM_RANGES; i++) {
+		if (!ctx->range[i].blocks)
+			continue;
+		for (int j = 0, add; j < (1 << HASH_SHIFT); j++) {
+			if (!ctx->range[i].blocks[j])
+				continue;
+
+			add = 1;
+			for (int k = 0; k < c; k++) {
+				if (ctx->blocks[k] == ctx->range[i].blocks[j]) {
+					add = 0;
+					break;
+				}
+			}
+			if (add) {
+				assert(c < ctx->nblocks);
+				ctx->blocks[c++] = ctx->range[i].blocks[j];
+				j += (ctx->range[i].blocks[j]->nreg) - 1;
+			}
+		}
+	}
+	return 0;
+}
+
 int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
 {
 	int r;
@@ -651,15 +689,6 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
 		goto out_err;
 	}
 
-	/* initialize hash */
-	for (int i = 0; i < NUM_RANGES; i++) {
-		ctx->range[i].blocks = calloc(1 << HASH_SHIFT, sizeof(void*));
-		if (ctx->range[i].blocks == NULL) {
-			r = -ENOMEM;
-			goto out_err;
-		}
-	}
-
 	/* add blocks */
 	r = r600_context_add_block(ctx, r600_config_reg_list,
 				   Elements(r600_config_reg_list), PKT3_SET_CONFIG_REG, R600_CONFIG_REG_OFFSET);
@@ -723,26 +752,9 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
 	/* VS loop const */
 	r600_loop_const_init(ctx, 32);
 
-	/* setup block table */
-	ctx->blocks = calloc(ctx->nblocks, sizeof(void*));
-	for (int i = 0, c = 0; i < NUM_RANGES; i++) {
-		for (int j = 0, add; j < (1 << HASH_SHIFT); j++) {
-			if (ctx->range[i].blocks[j]) {
-				add = 1;
-				for (int k = 0; k < c; k++) {
-					if (ctx->blocks[k] == ctx->range[i].blocks[j]) {
-						add = 0;
-						break;
-					}
-				}
-				if (add) {
-					assert(c < ctx->nblocks);
-					ctx->blocks[c++] = ctx->range[i].blocks[j];
-					j += (ctx->range[i].blocks[j]->nreg) - 1;
-				}
-			}
-		}
-	}
+	r = r600_setup_block_table(ctx);
+	if (r)
+		goto out_err;
 
 	/* allocate cs variables */
 	ctx->nreloc = RADEON_CTX_MAX_PM4;
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 48c5325..003fca0 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -159,7 +159,7 @@ void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_
 void r600_context_block_emit_dirty(struct r600_context *ctx, struct r600_block *block);
 void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block,
 			      int dirty, int index);
-
+int r600_setup_block_table(struct r600_context *ctx);
 void r600_context_reg(struct r600_context *ctx,
 		      unsigned offset, unsigned value,
 		      unsigned mask);




More information about the mesa-commit mailing list