Mesa (master): r600g: make all viewport states use single atom

Marek Olšák mareko at kemper.freedesktop.org
Thu Sep 3 16:07:27 UTC 2015


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

Author: Grazvydas Ignotas <notasas at gmail.com>
Date:   Thu Sep  3 01:54:29 2015 +0300

r600g: make all viewport states use single atom

Similarly to scissor states, we can use single atom to track all viewport
states. This will allow to simplify dirty atom handling later.

Signed-off-by: Marek Olšák <marek.olsak at amd.com>

---

 src/gallium/drivers/r600/evergreen_state.c   |    7 ++---
 src/gallium/drivers/r600/r600_blit.c         |    2 +-
 src/gallium/drivers/r600/r600_hw_context.c   |    8 ++---
 src/gallium/drivers/r600/r600_pipe.h         |    8 ++---
 src/gallium/drivers/r600/r600_state.c        |    6 +---
 src/gallium/drivers/r600/r600_state_common.c |   41 ++++++++++++++++----------
 6 files changed, 38 insertions(+), 34 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 3a7f583..5212db3 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -3450,7 +3450,7 @@ fallback:
 void evergreen_init_state_functions(struct r600_context *rctx)
 {
 	unsigned id = 4;
-	int i;
+
 	/* !!!
 	 *  To avoid GPU lockup registers must be emited in a specific order
 	 * (no kidding ...). The order below is important and have been
@@ -3503,10 +3503,7 @@ void evergreen_init_state_functions(struct r600_context *rctx)
 	r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, evergreen_emit_polygon_offset, 6);
 	r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0);
 	r600_init_atom(rctx, &rctx->scissor.atom, id++, evergreen_emit_scissor_state, 0);
-	for (i = 0; i < R600_MAX_VIEWPORTS; i++) {
-		r600_init_atom(rctx, &rctx->viewport[i].atom, id++, r600_emit_viewport_state, 8);
-		rctx->viewport[i].idx = i;
-	}
+	r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 0);
 	r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
 	r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, evergreen_emit_vertex_fetch_shader, 5);
 	r600_add_atom(rctx, &rctx->b.streamout.begin_atom, id++);
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c
index 8774cb5..d1370cd 100644
--- a/src/gallium/drivers/r600/r600_blit.c
+++ b/src/gallium/drivers/r600/r600_blit.c
@@ -65,7 +65,7 @@ static void r600_blitter_begin(struct pipe_context *ctx, enum r600_blitter_op op
 	util_blitter_save_rasterizer(rctx->blitter, rctx->rasterizer_state.cso);
 
 	if (op & R600_SAVE_FRAGMENT_STATE) {
-		util_blitter_save_viewport(rctx->blitter, &rctx->viewport[0].state);
+		util_blitter_save_viewport(rctx->blitter, &rctx->viewport.state[0]);
 		util_blitter_save_scissor(rctx->blitter, &rctx->scissor.scissor[0]);
 		util_blitter_save_fragment_shader(rctx->blitter, rctx->ps_shader);
 		util_blitter_save_blend(rctx->blitter, rctx->blend_state.cso);
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index c540325..092f261 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -287,7 +287,7 @@ void r600_context_gfx_flush(void *context, unsigned flags,
 void r600_begin_new_cs(struct r600_context *ctx)
 {
 	unsigned shader;
-	int i;
+
 	ctx->b.flags = 0;
 	ctx->b.gtt = 0;
 	ctx->b.vram = 0;
@@ -311,9 +311,9 @@ void r600_begin_new_cs(struct r600_context *ctx)
 	ctx->scissor.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
 	ctx->scissor.atom.num_dw = R600_MAX_VIEWPORTS * 4;
 	r600_mark_atom_dirty(ctx, &ctx->scissor.atom);
-	for (i = 0; i < R600_MAX_VIEWPORTS; i++) {
-		r600_mark_atom_dirty(ctx, &ctx->viewport[i].atom);
-	}
+	ctx->viewport.dirty_mask = (1 << R600_MAX_VIEWPORTS) - 1;
+	ctx->viewport.atom.num_dw = R600_MAX_VIEWPORTS * 8;
+	r600_mark_atom_dirty(ctx, &ctx->viewport.atom);
 	if (ctx->b.chip_class < EVERGREEN) {
 		r600_mark_atom_dirty(ctx, &ctx->config_state.atom);
 	}
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index e09bee1..bf6bd76 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -38,7 +38,7 @@
 
 #include "tgsi/tgsi_scan.h"
 
-#define R600_NUM_ATOMS 60
+#define R600_NUM_ATOMS 45
 
 #define R600_MAX_VIEWPORTS 16
 
@@ -208,8 +208,8 @@ struct r600_stencil_ref_state {
 
 struct r600_viewport_state {
 	struct r600_atom atom;
-	struct pipe_viewport_state state;
-	int idx;
+	struct pipe_viewport_state state[R600_MAX_VIEWPORTS];
+	uint32_t dirty_mask;
 };
 
 struct r600_shader_stages_state {
@@ -463,7 +463,7 @@ struct r600_context {
 	struct r600_config_state	config_state;
 	struct r600_stencil_ref_state	stencil_ref;
 	struct r600_vgt_state		vgt_state;
-	struct r600_viewport_state	viewport[R600_MAX_VIEWPORTS];
+	struct r600_viewport_state	viewport;
 	/* Shaders and shader resources. */
 	struct r600_cso_state		vertex_fetch_shader;
 	struct r600_shader_state	vertex_shader;
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index c3db143..6724cc0 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -3032,7 +3032,6 @@ fallback:
 void r600_init_state_functions(struct r600_context *rctx)
 {
 	unsigned id = 4;
-	int i;
 
 	/* !!!
 	 *  To avoid GPU lockup registers must be emited in a specific order
@@ -3081,10 +3080,7 @@ void r600_init_state_functions(struct r600_context *rctx)
 	r600_init_atom(rctx, &rctx->poly_offset_state.atom, id++, r600_emit_polygon_offset, 6);
 	r600_init_atom(rctx, &rctx->rasterizer_state.atom, id++, r600_emit_cso_state, 0);
 	r600_init_atom(rctx, &rctx->scissor.atom, id++, r600_emit_scissor_state, 0);
-	for (i = 0;i < R600_MAX_VIEWPORTS; i++) {
-		r600_init_atom(rctx, &rctx->viewport[i].atom, id++, r600_emit_viewport_state, 8);
-		rctx->viewport[i].idx = i;
-	}
+	r600_init_atom(rctx, &rctx->viewport.atom, id++, r600_emit_viewport_state, 0);
 	r600_init_atom(rctx, &rctx->config_state.atom, id++, r600_emit_config_state, 3);
 	r600_init_atom(rctx, &rctx->stencil_ref.atom, id++, r600_emit_stencil_ref, 4);
 	r600_init_atom(rctx, &rctx->vertex_fetch_shader.atom, id++, r600_emit_vertex_fetch_shader, 5);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 0b3fe85..1f96ed6 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -704,28 +704,39 @@ static void r600_set_viewport_states(struct pipe_context *ctx,
                                      const struct pipe_viewport_state *state)
 {
 	struct r600_context *rctx = (struct r600_context *)ctx;
+	struct r600_viewport_state *rstate = &rctx->viewport;
 	int i;
 
-	for (i = start_slot; i < start_slot + num_viewports; i++) {
-		rctx->viewport[i].state = state[i - start_slot];
-		r600_mark_atom_dirty(rctx, &rctx->viewport[i].atom);
-	}
+	for (i = start_slot; i < start_slot + num_viewports; i++)
+		rstate->state[i] = state[i - start_slot];
+	rstate->dirty_mask |= ((1 << num_viewports) - 1) << start_slot;
+	rstate->atom.num_dw = util_bitcount(rstate->dirty_mask) * 8;
+	r600_mark_atom_dirty(rctx, &rctx->viewport.atom);
 }
 
 void r600_emit_viewport_state(struct r600_context *rctx, struct r600_atom *atom)
 {
 	struct radeon_winsys_cs *cs = rctx->b.rings.gfx.cs;
-	struct r600_viewport_state *rstate = (struct r600_viewport_state *)atom;
-	struct pipe_viewport_state *state = &rstate->state;
-	int offset = rstate->idx * 6 * 4;
-
-	radeon_set_context_reg_seq(cs, R_02843C_PA_CL_VPORT_XSCALE_0 + offset, 6);
-	radeon_emit(cs, fui(state->scale[0]));     /* R_02843C_PA_CL_VPORT_XSCALE_0  */
-	radeon_emit(cs, fui(state->translate[0])); /* R_028440_PA_CL_VPORT_XOFFSET_0 */
-	radeon_emit(cs, fui(state->scale[1]));     /* R_028444_PA_CL_VPORT_YSCALE_0  */
-	radeon_emit(cs, fui(state->translate[1])); /* R_028448_PA_CL_VPORT_YOFFSET_0 */
-	radeon_emit(cs, fui(state->scale[2]));     /* R_02844C_PA_CL_VPORT_ZSCALE_0  */
-	radeon_emit(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */
+	struct r600_viewport_state *rstate = &rctx->viewport;
+	struct pipe_viewport_state *state;
+	uint32_t dirty_mask;
+	unsigned i, offset;
+
+	dirty_mask = rstate->dirty_mask;
+	while (dirty_mask != 0) {
+		i = u_bit_scan(&dirty_mask);
+		offset = i * 6 * 4;
+		radeon_set_context_reg_seq(cs, R_02843C_PA_CL_VPORT_XSCALE_0 + offset, 6);
+		state = &rstate->state[i];
+		radeon_emit(cs, fui(state->scale[0]));     /* R_02843C_PA_CL_VPORT_XSCALE_0  */
+		radeon_emit(cs, fui(state->translate[0])); /* R_028440_PA_CL_VPORT_XOFFSET_0 */
+		radeon_emit(cs, fui(state->scale[1]));     /* R_028444_PA_CL_VPORT_YSCALE_0  */
+		radeon_emit(cs, fui(state->translate[1])); /* R_028448_PA_CL_VPORT_YOFFSET_0 */
+		radeon_emit(cs, fui(state->scale[2]));     /* R_02844C_PA_CL_VPORT_ZSCALE_0  */
+		radeon_emit(cs, fui(state->translate[2])); /* R_028450_PA_CL_VPORT_ZOFFSET_0 */
+	}
+	rstate->dirty_mask = 0;
+	rstate->atom.num_dw = 0;
 }
 
 /* Compute the key for the hw shader variant */




More information about the mesa-commit mailing list