Mesa (master): r600g: decrease CPU time on set buffer resources

Dave Airlie airlied at kemper.freedesktop.org
Thu Jun 2 05:17:50 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Thu Jun  2 15:03:52 2011 +1000

r600g: decrease CPU time on set buffer resources

This splits the initialisation and the setting of values in the resource
buffers. We only should end up initialising once and updateing with new values
when needed.

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

---

 src/gallium/drivers/r600/evergreen_state.c   |   24 ++++++++++++--
 src/gallium/drivers/r600/r600.h              |   15 +++++++++
 src/gallium/drivers/r600/r600_pipe.h         |   14 ++++++--
 src/gallium/drivers/r600/r600_state.c        |   22 +++++++++++--
 src/gallium/drivers/r600/r600_state_common.c |   41 ++++++++++++++++++-------
 5 files changed, 92 insertions(+), 24 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 27f88f1..9bef3f8 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1769,11 +1769,13 @@ void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx)
 	return rstate;
 }
 
-void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
-					struct r600_pipe_state *rstate,
-					struct r600_resource *rbuffer,
-					unsigned offset, unsigned stride)
+void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
+					 struct r600_pipe_state *rstate,
+					 struct r600_resource *rbuffer,
+					 unsigned offset, unsigned stride)
 {
+	rstate->id = R600_PIPE_STATE_RESOURCE;
+	rstate->nregs = 0;
 	r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
 				offset, 0xFFFFFFFF, rbuffer->bo);
 	r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
@@ -1796,3 +1798,17 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
 	r600_pipe_state_add_reg(rstate, R_03001C_RESOURCE0_WORD7,
 				0xC0000000, 0xFFFFFFFF, NULL);
 }
+
+
+void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate,
+					struct r600_resource *rbuffer,
+					unsigned offset, unsigned stride)
+{
+	rstate->nregs = 0;
+	r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo);
+	r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1);
+	r600_pipe_state_mod_reg(rstate, S_030008_ENDIAN_SWAP(r600_endian_swap(32)) |
+				S_030008_STRIDE(stride));
+	rstate->nregs = 8;
+
+}
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index df02787..50a0753 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -319,4 +319,19 @@ void _r600_pipe_state_add_reg(struct r600_context *ctx,
 
 #define r600_pipe_state_add_reg(state, offset, value, mask, bo) _r600_pipe_state_add_reg(&rctx->ctx, state, offset, value, mask, CTX_RANGE_ID(offset), CTX_BLOCK_ID(offset), bo)
 
+static inline void r600_pipe_state_mod_reg(struct r600_pipe_state *state,
+					   u32 value)
+{
+	state->regs[state->nregs].value = value;
+	state->nregs++;
+}
+
+static inline void r600_pipe_state_mod_reg_bo(struct r600_pipe_state *state,
+					   u32 value, struct r600_bo *bo)
+{
+	state->regs[state->nregs].value = value;
+	state->regs[state->nregs].bo = bo;
+	state->nregs++;
+}
+
 #endif
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index ae809a2..05381c2 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -221,8 +221,11 @@ void evergreen_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader
 void evergreen_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve);
 void *evergreen_create_db_flush_dsa(struct r600_pipe_context *rctx);
 void evergreen_polygon_offset_update(struct r600_pipe_context *rctx);
-void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
-					struct r600_pipe_state *rstate,
+void evergreen_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
+				    struct r600_pipe_state *rstate,
+				    struct r600_resource *rbuffer,
+				    unsigned offset, unsigned stride);
+void evergreen_pipe_mod_buffer_resource(struct r600_pipe_state *rstate,
 					struct r600_resource *rbuffer,
 					unsigned offset, unsigned stride);
 
@@ -262,8 +265,11 @@ void r600_pipe_shader_vs(struct pipe_context *ctx, struct r600_pipe_shader *shad
 void r600_fetch_shader(struct pipe_context *ctx, struct r600_vertex_element *ve);
 void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx);
 void r600_polygon_offset_update(struct r600_pipe_context *rctx);
-void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
-				   struct r600_pipe_state *rstate,
+void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
+				    struct r600_pipe_state *rstate,
+				    struct r600_resource *rbuffer,
+				    unsigned offset, unsigned stride);
+void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate,
 				   struct r600_resource *rbuffer,
 				   unsigned offset, unsigned stride);
 
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index f1fbfa5..3043c5e 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1481,11 +1481,13 @@ void *r600_create_db_flush_dsa(struct r600_pipe_context *rctx)
 	return rstate;
 }
 
-void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
-				   struct r600_pipe_state *rstate,
-				   struct r600_resource *rbuffer,
-				   unsigned offset, unsigned stride)
+void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx,
+				    struct r600_pipe_state *rstate,
+				    struct r600_resource *rbuffer,
+				    unsigned offset, unsigned stride)
 {
+	rstate->id = R600_PIPE_STATE_RESOURCE;
+	rstate->nregs = 0;
 	r600_pipe_state_add_reg(rstate, R_038000_RESOURCE0_WORD0,
 				offset, 0xFFFFFFFF, rbuffer->bo);
 	r600_pipe_state_add_reg(rstate, R_038004_RESOURCE0_WORD1,
@@ -1502,3 +1504,15 @@ void r600_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
 	r600_pipe_state_add_reg(rstate, R_038018_RESOURCE0_WORD6,
 				0xC0000000, 0xFFFFFFFF, NULL);
 }
+
+void r600_pipe_mod_buffer_resource(struct r600_pipe_state *rstate,
+				   struct r600_resource *rbuffer,
+				   unsigned offset, unsigned stride)
+{
+	rstate->nregs = 0;
+	r600_pipe_state_mod_reg_bo(rstate, offset, rbuffer->bo);
+	r600_pipe_state_mod_reg(rstate, rbuffer->bo_size - offset - 1);
+	r600_pipe_state_mod_reg(rstate, S_038008_ENDIAN_SWAP(r600_endian_swap(32)) |
+				S_038008_STRIDE(stride));
+	rstate->nregs = 7;
+}
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index db9451f..cbf7ff0 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -410,13 +410,19 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
 		r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer);
 
 		rstate = &rctx->vs_const_buffer_resource[index];
-		rstate->id = R600_PIPE_STATE_RESOURCE;
-		rstate->nregs = 0;
+		if (!rstate->id) {
+			if (rctx->family >= CHIP_CEDAR) {
+				evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			} else {
+				r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			}
+		}
+
 		if (rctx->family >= CHIP_CEDAR) {
-			evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
 			evergreen_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
 		} else {
-			r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
 			r600_context_pipe_state_set_vs_resource(&rctx->ctx, rstate, index);
 		}
 		break;
@@ -432,13 +438,18 @@ void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint index,
 		r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer);
 
 		rstate = &rctx->ps_const_buffer_resource[index];
-		rstate->id = R600_PIPE_STATE_RESOURCE;
-		rstate->nregs = 0;
+		if (!rstate->id) {
+			if (rctx->family >= CHIP_CEDAR) {
+				evergreen_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			} else {
+				r600_pipe_init_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			}
+		}
 		if (rctx->family >= CHIP_CEDAR) {
-			evergreen_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			evergreen_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
 			evergreen_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
 		} else {
-			r600_pipe_set_buffer_resource(rctx, rstate, &rbuffer->r, offset, 16);
+			r600_pipe_mod_buffer_resource(rstate, &rbuffer->r, offset, 16);
 			r600_context_pipe_state_set_ps_resource(&rctx->ctx, rstate, index);
 		}
 		break;
@@ -468,8 +479,6 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
 
 	for (i = 0 ; i < count; i++) {
 		rstate = &rctx->fs_resource[i];
-		rstate->id = R600_PIPE_STATE_RESOURCE;
-		rstate->nregs = 0;
 
 		if (rctx->vertex_elements->vbuffer_need_offset) {
 			/* one resource per vertex elements */
@@ -488,11 +497,19 @@ static void r600_vertex_buffer_update(struct r600_pipe_context *rctx)
 			continue;
 		offset += vertex_buffer->buffer_offset + r600_bo_offset(rbuffer->bo);
 
+		if (!rstate->id) {
+			if (rctx->family >= CHIP_CEDAR) {
+				evergreen_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride);
+			} else {
+				r600_pipe_init_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride);
+			}
+		}
+
 		if (rctx->family >= CHIP_CEDAR) {
-			evergreen_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride);
+			evergreen_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
 			evergreen_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
 		} else {
-			r600_pipe_set_buffer_resource(rctx, rstate, rbuffer, offset, vertex_buffer->stride);
+			r600_pipe_mod_buffer_resource(rstate, rbuffer, offset, vertex_buffer->stride);
 			r600_context_pipe_state_set_fs_resource(&rctx->ctx, rstate, i);
 		}
 	}




More information about the mesa-commit mailing list