Mesa (master): r600g/winsys: overhaul resource range/blocks.

Dave Airlie airlied at kemper.freedesktop.org
Mon Jun 6 23:44:44 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Mon Jun  6 18:00:36 2011 +1000

r600g/winsys: overhaul resource range/blocks.

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 at redhat.com>

---

 src/gallium/drivers/r600/r600.h                    |    4 +
 src/gallium/winsys/r600/drm/evergreen_hw_context.c |   50 ++++-----
 src/gallium/winsys/r600/drm/r600_hw_context.c      |  118 ++++++++++++++------
 src/gallium/winsys/r600/drm/r600_priv.h            |    3 +-
 4 files changed, 110 insertions(+), 65 deletions(-)

diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 5d6240a..cc70600 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -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 {
diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
index 701d4e9..7072461 100644
--- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
+++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
@@ -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)
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c
index 41d32d8..1fd6d34 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -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)
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index 1790f77..3e0fd6d 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -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
  */




More information about the mesa-commit mailing list