r600g/winsys: overhaul resource range/blocks.
authorDave Airlie <airlied@redhat.com>
Mon, 6 Jun 2011 08:00:36 +0000 (18:00 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 6 Jun 2011 23:32:29 +0000 (09:32 +1000)
There isn't much point taking the overhead of range/block lookups on resources
we aren't going to be getting resource registers at wierd offsets.

Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/r600.h
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 5d6240aef243961e2434218d93f17513cce05160..cc70600610ed40ca306fa43bded10a51dc4717d2 100644 (file)
@@ -267,6 +267,10 @@ struct r600_context {
        unsigned                num_dest_buffers;
        unsigned                flags;
        boolean                 predicate_drawing;
+       struct r600_range ps_resources;
+       struct r600_range vs_resources;
+       struct r600_range fs_resources;
+       int num_ps_resources, num_vs_resources, num_fs_resources;
 };
 
 struct r600_draw {
index 701d4e9401f7cf149818339418bf98511f959d3d..7072461dc59722a147908a162e30fd3f73662995 100644 (file)
@@ -817,7 +817,7 @@ static const struct r600_reg cayman_context_reg_list[] = {
 };
 
 /* SHADER RESOURCE R600/R700 */
-static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset)
+static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride)
 {
        struct r600_reg r600_shader_resource[] = {
                {R_030000_RESOURCE0_WORD0, 0, 0, 0},
@@ -831,10 +831,7 @@ static int evergreen_state_resource_init(struct r600_context *ctx, u32 offset)
        };
        unsigned nreg = Elements(r600_shader_resource);
 
-       for (int i = 0; i < nreg; i++) {
-               r600_shader_resource[i].offset += offset;
-       }
-       return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, EVERGREEN_RESOURCE_OFFSET);
+       return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, EVERGREEN_RESOURCE_OFFSET);
 }
 
 /* SHADER SAMPLER R600/R700 */
@@ -960,24 +957,19 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon)
                if (r)
                        goto out_err;
        }
-       /* PS RESOURCE */
-       for (int j = 0, offset = 0; j < 176; j++, offset += 0x20) {
-               r = evergreen_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
-       /* VS RESOURCE */
-       for (int j = 0, offset = 0x1600; j < 160; j++, offset += 0x20) {
-               r = evergreen_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
-       /* FS RESOURCE */
-       for (int j = 0, offset = 0x7C00; j < 16; j++, offset += 0x20) {
-               r = evergreen_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
+
+       ctx->num_ps_resources = 176;
+       ctx->num_vs_resources = 160;
+       ctx->num_fs_resources = 16;
+       r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 176, 0x20);
+       if (r)
+               goto out_err;
+       r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1600, 160, 0x20);
+       if (r)
+               goto out_err;
+       r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x7C00, 16, 0x20);
+       if (r)
+               goto out_err;
 
        /* PS loop const */
        evergreen_loop_const_init(ctx, 0);
@@ -1025,23 +1017,23 @@ out_err:
 
 void evergreen_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x20 * rid;
+       struct r600_block *block = ctx->ps_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 void evergreen_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x1600 + 0x20 * rid;
+       struct r600_block *block = ctx->vs_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 void evergreen_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_030000_SQ_TEX_RESOURCE_WORD0_0 + 0x7C00 + 0x20 * rid;
+       struct r600_block *block = ctx->fs_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 static inline void evergreen_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)
index 41d32d85776f421e9b0d6d04340baa42ddf444fb..1fd6d34479836c2edac9caf3e55ca8c5a5da1ec6 100644 (file)
@@ -561,7 +561,31 @@ static const struct r600_reg r600_context_reg_list[] = {
 };
 
 /* SHADER RESOURCE R600/R700 */
-static int r600_state_resource_init(struct r600_context *ctx, u32 offset)
+int r600_resource_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride, struct r600_reg *reg, int nreg, unsigned offset_base)
+{
+       int i;
+       struct r600_block *block;
+       range->blocks = calloc(nblocks, sizeof(struct r600_block *));
+       if (range->blocks == NULL)
+               return -ENOMEM;
+
+       reg[0].offset += offset;
+       for (i = 0; i < nblocks; i++) {
+               block = calloc(1, sizeof(struct r600_block));
+               if (block == NULL) {
+                       return -ENOMEM;
+               }
+               ctx->nblocks++;
+               range->blocks[i] = block;
+               r600_init_block(ctx, block, reg, 0, nreg, PKT3_SET_RESOURCE, offset_base);
+
+               reg[0].offset += stride;
+       }
+       return 0;
+}
+
+      
+static int r600_resource_range_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride)
 {
        struct r600_reg r600_shader_resource[] = {
                {R_038000_RESOURCE0_WORD0, 0, 0, 0},
@@ -574,10 +598,7 @@ static int r600_state_resource_init(struct r600_context *ctx, u32 offset)
        };
        unsigned nreg = Elements(r600_shader_resource);
 
-       for (int i = 0; i < nreg; i++) {
-               r600_shader_resource[i].offset += offset;
-       }
-       return r600_context_add_block(ctx, r600_shader_resource, nreg, PKT3_SET_RESOURCE, R600_RESOURCE_OFFSET);
+       return r600_resource_init(ctx, range, offset, nblocks, stride, r600_shader_resource, nreg, R600_RESOURCE_OFFSET);
 }
 
 /* SHADER SAMPLER R600/R700 */
@@ -639,6 +660,22 @@ static void r600_context_clear_fenced_bo(struct r600_context *ctx)
        }
 }
 
+static void r600_free_resource_range(struct r600_context *ctx, struct r600_range *range, int nblocks)
+{
+       struct r600_block *block;
+       int i;
+       for (i = 0; i < nblocks; i++) {
+               block = range->blocks[i];
+               if (block) {
+                       for (int k = 1; k <= block->nbo; k++)
+                               r600_bo_reference(ctx->radeon, &block->reloc[k].bo, NULL);
+                       free(block);
+               }
+       }
+       free(range->blocks);
+
+}
+
 /* initialize */
 void r600_context_fini(struct r600_context *ctx)
 {
@@ -663,6 +700,9 @@ void r600_context_fini(struct r600_context *ctx)
                }
                free(ctx->range[i].blocks);
        }
+       r600_free_resource_range(ctx, &ctx->ps_resources, ctx->num_ps_resources);
+       r600_free_resource_range(ctx, &ctx->vs_resources, ctx->num_vs_resources);
+       r600_free_resource_range(ctx, &ctx->fs_resources, ctx->num_fs_resources);
        free(ctx->range);
        free(ctx->blocks);
        free(ctx->reloc);
@@ -673,13 +713,26 @@ void r600_context_fini(struct r600_context *ctx)
        memset(ctx, 0, sizeof(struct r600_context));
 }
 
+static void r600_add_resource_block(struct r600_context *ctx, struct r600_range *range, int num_blocks, int *index)
+{
+       int c = *index;
+       for (int j = 0; j < num_blocks; j++) {
+               if (!range->blocks[j])
+                       continue;
+
+               ctx->blocks[c++] = range->blocks[j];
+       }
+       *index = c;
+}
+
 int r600_setup_block_table(struct r600_context *ctx)
 {
        /* setup block table */
+       int c = 0;
        ctx->blocks = calloc(ctx->nblocks, sizeof(void*));
        if (!ctx->blocks)
                return -ENOMEM;
-       for (int i = 0, c = 0; i < NUM_RANGES; i++) {
+       for (int i = 0; i < NUM_RANGES; i++) {
                if (!ctx->range[i].blocks)
                        continue;
                for (int j = 0, add; j < (1 << HASH_SHIFT); j++) {
@@ -700,6 +753,10 @@ int r600_setup_block_table(struct r600_context *ctx)
                        }
                }
        }
+
+       r600_add_resource_block(ctx, &ctx->ps_resources, ctx->num_ps_resources, &c);
+       r600_add_resource_block(ctx, &ctx->vs_resources, ctx->num_vs_resources, &c);
+       r600_add_resource_block(ctx, &ctx->fs_resources, ctx->num_fs_resources, &c);
        return 0;
 }
 
@@ -756,24 +813,19 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon)
                if (r)
                        goto out_err;
        }
-       /* PS RESOURCE */
-       for (int j = 0, offset = 0; j < 160; j++, offset += 0x1C) {
-               r = r600_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
-       /* VS RESOURCE */
-       for (int j = 0, offset = 0x1180; j < 160; j++, offset += 0x1C) {
-               r = r600_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
-       /* FS RESOURCE */
-       for (int j = 0, offset = 0x2300; j < 16; j++, offset += 0x1C) {
-               r = r600_state_resource_init(ctx, offset);
-               if (r)
-                       goto out_err;
-       }
+
+       ctx->num_ps_resources = 160;
+       ctx->num_vs_resources = 160;
+       ctx->num_fs_resources = 16;
+       r = r600_resource_range_init(ctx, &ctx->ps_resources, 0, 160, 0x1c);
+       if (r)
+               goto out_err;
+       r = r600_resource_range_init(ctx, &ctx->vs_resources, 0x1180, 160, 0x1c);
+       if (r)
+               goto out_err;
+       r = r600_resource_range_init(ctx, &ctx->fs_resources, 0x2300, 16, 0x1c);
+       if (r)
+               goto out_err;
 
        /* PS loop const */
        r600_loop_const_init(ctx, 0);
@@ -985,17 +1037,13 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat
        }
 }
 
-void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned offset)
+void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, struct r600_block *block)
 {
-       struct r600_range *range;
-       struct r600_block *block;
        int i;
        int dirty;
        int num_regs = ctx->radeon->chip_class >= EVERGREEN ? 8 : 7;
        boolean is_vertex;
 
-       range = &ctx->range[CTX_RANGE_ID(offset)];
-       block = range->blocks[CTX_BLOCK_ID(offset)];
        if (state == NULL) {
                block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY);
                if (block->reloc[1].bo)
@@ -1064,23 +1112,23 @@ void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_
 
 void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1C * rid;
+       struct r600_block *block = ctx->ps_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x1180 + 0x1C * rid;
+       struct r600_block *block = ctx->vs_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned rid)
 {
-       unsigned offset = R_038000_SQ_TEX_RESOURCE_WORD0_0 + 0x2300 + 0x1C * rid;
+       struct r600_block *block = ctx->fs_resources.blocks[rid];
 
-       r600_context_pipe_state_set_resource(ctx, state, offset);
+       r600_context_pipe_state_set_resource(ctx, state, block);
 }
 
 static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset)
index 1790f770897813759246d6c23499cd560885d087..3e0fd6d7a717b0890e40c8b23d0eb017a326b48e 100644 (file)
@@ -158,7 +158,7 @@ void r600_context_bo_flush(struct r600_context *ctx, unsigned flush_flags,
 struct r600_bo *r600_context_reg_bo(struct r600_context *ctx, unsigned offset);
 int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, unsigned nreg,
                           unsigned opcode, unsigned offset_base);
-void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, unsigned offset);
+void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_pipe_resource_state *state, struct r600_block *block);
 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);
@@ -167,6 +167,7 @@ void r600_context_reg(struct r600_context *ctx,
                      unsigned offset, unsigned value,
                      unsigned mask);
 void r600_init_cs(struct r600_context *ctx);
+int r600_resource_init(struct r600_context *ctx, struct r600_range *range, unsigned offset, unsigned nblocks, unsigned stride, struct r600_reg *reg, int nreg, unsigned offset_base);
 /*
  * r600_bo.c
  */