r600g: make range/block act more like a page table
authorDave Airlie <airlied@redhat.com>
Thu, 12 May 2011 05:01:33 +0000 (15:01 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 12 May 2011 23:26:16 +0000 (09:26 +1000)
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@redhat.com>
src/gallium/winsys/r600/drm/evergreen_hw_context.c
src/gallium/winsys/r600/drm/r600_hw_context.c
src/gallium/winsys/r600/drm/r600_priv.h

index e89f457..2a2c37f 100644 (file)
@@ -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;
index e60bf75..595b110 100644 (file)
@@ -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;
index 48c5325..003fca0 100644 (file)
@@ -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);