[Mesa-dev] [PATCH 7/8] radeonsi: move sync handling into new state handler

Christian König deathsimple at vodafone.de
Wed Aug 8 04:05:07 PDT 2012


So we can remove all the old atom handling.

Signed-off-by: Christian König <deathsimple at vodafone.de>
---
 src/gallium/drivers/radeonsi/Makefile.sources    |    4 +-
 src/gallium/drivers/radeonsi/r600_hw_context.c   |   34 +++++-----
 src/gallium/drivers/radeonsi/r600_state_common.c |   77 ----------------------
 src/gallium/drivers/radeonsi/radeonsi_pipe.c     |    4 --
 src/gallium/drivers/radeonsi/radeonsi_pipe.h     |   52 ---------------
 src/gallium/drivers/radeonsi/radeonsi_pm4.c      |   43 +++++++-----
 src/gallium/drivers/radeonsi/radeonsi_pm4.h      |    3 +
 src/gallium/drivers/radeonsi/si_commands.c       |   39 +++++++++++
 src/gallium/drivers/radeonsi/si_state.h          |    4 ++
 src/gallium/drivers/radeonsi/si_state_draw.c     |   12 ++--
 10 files changed, 100 insertions(+), 172 deletions(-)
 delete mode 100644 src/gallium/drivers/radeonsi/r600_state_common.c
 create mode 100644 src/gallium/drivers/radeonsi/si_commands.c

diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
index 630afb8..f1b4936 100644
--- a/src/gallium/drivers/radeonsi/Makefile.sources
+++ b/src/gallium/drivers/radeonsi/Makefile.sources
@@ -9,8 +9,8 @@ C_SOURCES := \
 	r600_texture.c \
 	evergreen_hw_context.c \
 	r600_translate.c \
-	r600_state_common.c \
 	radeonsi_pm4.c \
 	si_state.c \
 	si_state_streamout.c \
-	si_state_draw.c
+	si_state_draw.c \
+	si_commands.c
diff --git a/src/gallium/drivers/radeonsi/r600_hw_context.c b/src/gallium/drivers/radeonsi/r600_hw_context.c
index 6765ef8..5480cb5 100644
--- a/src/gallium/drivers/radeonsi/r600_hw_context.c
+++ b/src/gallium/drivers/radeonsi/r600_hw_context.c
@@ -119,17 +119,11 @@ err:
 void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
 			boolean count_draw_in)
 {
-	struct r600_atom *state;
-
 	/* The number of dwords we already used in the CS so far. */
 	num_dw += ctx->cs->cdw;
 
 	if (count_draw_in) {
 		/* The number of dwords all the dirty states would take. */
-		LIST_FOR_EACH_ENTRY(state, &ctx->dirty_states, head) {
-			num_dw += state->num_dw;
-		}
-
 		num_dw += ctx->pm4_dirty_cdwords;
 
 		/* The upper-bound of how much a draw command would take. */
@@ -159,20 +153,25 @@ void r600_need_cs_space(struct r600_context *ctx, unsigned num_dw,
 	}
 }
 
-static void r600_flush_framebuffer(struct r600_context *ctx, bool flush_now)
+static void r600_flush_framebuffer(struct r600_context *ctx)
 {
+	struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+
 	if (!(ctx->flags & R600_CONTEXT_DST_CACHES_DIRTY))
 		return;
 
-	ctx->atom_surface_sync.flush_flags |=
-		r600_get_cb_flush_flags(ctx) |
-		(ctx->framebuffer.zsbuf ? S_0085F0_DB_ACTION_ENA(1) | S_0085F0_DB_DEST_BASE_ENA(1) : 0);
-
-	if (flush_now) {
-		r600_emit_atom(ctx, &ctx->atom_surface_sync.atom);
-	} else {
-		r600_atom_dirty(ctx, &ctx->atom_surface_sync.atom);
-	}
+	si_cmd_surface_sync(pm4, S_0085F0_CB0_DEST_BASE_ENA(1) |
+				S_0085F0_CB1_DEST_BASE_ENA(1) |
+				S_0085F0_CB2_DEST_BASE_ENA(1) |
+				S_0085F0_CB3_DEST_BASE_ENA(1) |
+				S_0085F0_CB4_DEST_BASE_ENA(1) |
+				S_0085F0_CB5_DEST_BASE_ENA(1) |
+				S_0085F0_CB6_DEST_BASE_ENA(1) |
+				S_0085F0_CB7_DEST_BASE_ENA(1) |
+				S_0085F0_DB_ACTION_ENA(1) |
+				S_0085F0_DB_DEST_BASE_ENA(1));
+	si_pm4_emit(ctx, pm4);
+	si_pm4_free_state(ctx, pm4, ~0);
 
 	ctx->flags &= ~R600_CONTEXT_DST_CACHES_DIRTY;
 }
@@ -180,7 +179,6 @@ static void r600_flush_framebuffer(struct r600_context *ctx, bool flush_now)
 void r600_context_flush(struct r600_context *ctx, unsigned flags)
 {
 	struct radeon_winsys_cs *cs = ctx->cs;
-	struct r600_block *enable_block = NULL;
 	bool queries_suspended = false;
 
 #if 0
@@ -203,7 +201,7 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
 	}
 #endif
 
-	r600_flush_framebuffer(ctx, true);
+	r600_flush_framebuffer(ctx);
 
 	/* partial flush is needed to avoid lockups on some chips with user fences */
 	cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
diff --git a/src/gallium/drivers/radeonsi/r600_state_common.c b/src/gallium/drivers/radeonsi/r600_state_common.c
deleted file mode 100644
index aa58406..0000000
--- a/src/gallium/drivers/radeonsi/r600_state_common.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright 2010 Red Hat Inc.
- *           2010 Jerome Glisse
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors: Dave Airlie <airlied at redhat.com>
- *          Jerome Glisse <jglisse at redhat.com>
- */
-#include "util/u_blitter.h"
-#include "util/u_memory.h"
-#include "util/u_format.h"
-#include "pipebuffer/pb_buffer.h"
-#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_parse.h"
-#include "r600_hw_context_priv.h"
-#include "radeonsi_pipe.h"
-#include "sid.h"
-#include "si_state.h"
-
-static void r600_emit_surface_sync(struct r600_context *rctx, struct r600_atom *atom)
-{
-	struct radeon_winsys_cs *cs = rctx->cs;
-	struct r600_atom_surface_sync *a = (struct r600_atom_surface_sync*)atom;
-
-	cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
-	cs->buf[cs->cdw++] = a->flush_flags;  /* CP_COHER_CNTL */
-	cs->buf[cs->cdw++] = 0xffffffff;      /* CP_COHER_SIZE */
-	cs->buf[cs->cdw++] = 0;               /* CP_COHER_BASE */
-	cs->buf[cs->cdw++] = 0x0000000A;      /* POLL_INTERVAL */
-
-	a->flush_flags = 0;
-}
-
-static void r600_init_atom(struct r600_atom *atom,
-			   void (*emit)(struct r600_context *ctx, struct r600_atom *state),
-			   unsigned num_dw,
-			   enum r600_atom_flags flags)
-{
-	atom->emit = emit;
-	atom->num_dw = num_dw;
-	atom->flags = flags;
-}
-
-void r600_init_common_atoms(struct r600_context *rctx)
-{
-	r600_init_atom(&rctx->atom_surface_sync.atom,	r600_emit_surface_sync,		5, EMIT_EARLY);
-}
-
-unsigned r600_get_cb_flush_flags(struct r600_context *rctx)
-{
-	unsigned flags = 0;
-
-	if (rctx->framebuffer.nr_cbufs) {
-		flags |= S_0085F0_CB_ACTION_ENA(1) |
-			 (((1 << rctx->framebuffer.nr_cbufs) - 1) << S_0085F0_CB0_DEST_BASE_ENA_SHIFT);
-	}
-
-	return flags;
-}
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
index ad7e595..c8f3486 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -210,8 +210,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 	rctx->context.create_video_decoder = vl_create_decoder;
 	rctx->context.create_video_buffer = vl_video_buffer_create;
 
-	r600_init_common_atoms(rctx);
-
 	switch (rctx->chip_class) {
 	case TAHITI:
 		si_init_state_functions(rctx);
@@ -247,8 +245,6 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
 		return NULL;
 	}
 
-	LIST_INITHEAD(&rctx->dirty_states);
-
 	r600_get_backend_mask(rctx); /* this emits commands and must be last */
 
 	return &rctx->context;
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index d613585..c926ff8 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
@@ -50,30 +50,6 @@
 #define R600_BIG_ENDIAN 0
 #endif
 
-enum r600_atom_flags {
-	/* When set, atoms are added at the beginning of the dirty list
-	 * instead of the end. */
-	EMIT_EARLY = (1 << 0)
-};
-
-/* This encapsulates a state or an operation which can emitted into the GPU
- * command stream. It's not limited to states only, it can be used for anything
- * that wants to write commands into the CS (e.g. cache flushes). */
-struct r600_atom {
-	void (*emit)(struct r600_context *ctx, struct r600_atom *state);
-
-	unsigned		num_dw;
-	enum r600_atom_flags	flags;
-	bool			dirty;
-
-	struct list_head	head;
-};
-
-struct r600_atom_surface_sync {
-	struct r600_atom atom;
-	unsigned flush_flags; /* CP_COHER_CNTL */
-};
-
 struct r600_pipe_fences {
 	struct si_resource		*bo;
 	unsigned			*data;
@@ -171,10 +147,6 @@ struct r600_context {
 
 	unsigned default_ps_gprs, default_vs_gprs;
 
-	/* States based on r600_state. */
-	struct list_head		dirty_states;
-	struct r600_atom_surface_sync	atom_surface_sync;
-
 	/* Below are variables from the old r600_context.
 	 */
 	struct radeon_winsys_cs	*cs;
@@ -209,26 +181,6 @@ struct r600_context {
 	union si_state	emitted;
 };
 
-static INLINE void r600_emit_atom(struct r600_context *rctx, struct r600_atom *atom)
-{
-	atom->emit(rctx, atom);
-	atom->dirty = false;
-	if (atom->head.next && atom->head.prev)
-		LIST_DELINIT(&atom->head);
-}
-
-static INLINE void r600_atom_dirty(struct r600_context *rctx, struct r600_atom *state)
-{
-	if (!state->dirty) {
-		if (state->flags & EMIT_EARLY) {
-			LIST_ADD(&state->head, &rctx->dirty_states);
-		} else {
-			LIST_ADDTAIL(&state->head, &rctx->dirty_states);
-		}
-		state->dirty = true;
-	}
-}
-
 /* r600_blit.c */
 void r600_init_blit_functions(struct r600_context *rctx);
 void r600_blit_uncompress_depth(struct pipe_context *ctx, struct r600_resource_texture *texture);
@@ -267,10 +219,6 @@ void r600_translate_index_buffer(struct r600_context *r600,
 				 struct pipe_index_buffer *ib,
 				 unsigned count);
 
-/* r600_state_common.c */
-void r600_init_common_atoms(struct r600_context *rctx);
-unsigned r600_get_cb_flush_flags(struct r600_context *rctx);
-
 /*
  * common helpers
  */
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pm4.c b/src/gallium/drivers/radeonsi/radeonsi_pm4.c
index da680dc..13fe99b 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pm4.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pm4.c
@@ -131,7 +131,7 @@ void si_pm4_free_state(struct r600_context *rctx,
 	if (state == NULL)
 		return;
 
-	if (rctx->emitted.array[idx] == state) {
+	if (idx != ~0 && rctx->emitted.array[idx] == state) {
 		rctx->emitted.array[idx] = NULL;
 	}
 
@@ -141,10 +141,24 @@ void si_pm4_free_state(struct r600_context *rctx,
 	FREE(state);
 }
 
+uint32_t si_pm4_sync_flags(struct r600_context *rctx)
+{
+	uint32_t cp_coher_cntl = 0;
+
+	for (int i = 0; i < NUMBER_OF_STATES; ++i) {
+		struct si_pm4_state *state = rctx->queued.array[i];
+
+		if (!state || rctx->emitted.array[i] == state)
+			continue;
+
+		cp_coher_cntl |= state->cp_coher_cntl;
+	}
+	return cp_coher_cntl;
+}
+
 unsigned si_pm4_dirty_dw(struct r600_context *rctx)
 {
 	unsigned count = 0;
-	uint32_t cp_coher_cntl = 0;
 
 	for (int i = 0; i < NUMBER_OF_STATES; ++i) {
 		struct si_pm4_state *state = rctx->queued.array[i];
@@ -153,33 +167,32 @@ unsigned si_pm4_dirty_dw(struct r600_context *rctx)
 			continue;
 
 		count += state->ndw;
-		cp_coher_cntl |= state->cp_coher_cntl;
 	}
 
-	//TODO
-	rctx->atom_surface_sync.flush_flags |= cp_coher_cntl;
-	r600_atom_dirty(rctx, &rctx->atom_surface_sync.atom);
 	return count;
 }
 
-void si_pm4_emit_dirty(struct r600_context *rctx)
+void si_pm4_emit(struct r600_context *rctx, struct si_pm4_state *state)
 {
 	struct radeon_winsys_cs *cs = rctx->cs;
+	for (int i = 0; i < state->nbo; ++i) {
+		r600_context_bo_reloc(rctx, state->bo[i],
+				      state->bo_usage[i]);
+	}
 
+	memcpy(&cs->buf[cs->cdw], state->pm4, state->ndw * 4);
+	cs->cdw += state->ndw;
+}
+
+void si_pm4_emit_dirty(struct r600_context *rctx)
+{
 	for (int i = 0; i < NUMBER_OF_STATES; ++i) {
 		struct si_pm4_state *state = rctx->queued.array[i];
 
 		if (!state || rctx->emitted.array[i] == state)
 			continue;
 
-		for (int j = 0; j < state->nbo; ++j) {
-			r600_context_bo_reloc(rctx, state->bo[j],
-					      state->bo_usage[j]);
-		}
-
-		memcpy(&cs->buf[cs->cdw], state->pm4, state->ndw * 4);
-		cs->cdw += state->ndw;
-
+		si_pm4_emit(rctx, state);
 		rctx->emitted.array[i] = state;
 	}
 }
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pm4.h b/src/gallium/drivers/radeonsi/radeonsi_pm4.h
index bbddfd0..803bb8f 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pm4.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_pm4.h
@@ -73,7 +73,10 @@ void si_pm4_inval_zsbuf_cache(struct si_pm4_state *state);
 void si_pm4_free_state(struct r600_context *rctx,
 		       struct si_pm4_state *state,
 		       unsigned idx);
+
+uint32_t si_pm4_sync_flags(struct r600_context *rctx);
 unsigned si_pm4_dirty_dw(struct r600_context *rctx);
+void si_pm4_emit(struct r600_context *rctx, struct si_pm4_state *state);
 void si_pm4_emit_dirty(struct r600_context *rctx);
 void si_pm4_reset_emitted(struct r600_context *rctx);
 
diff --git a/src/gallium/drivers/radeonsi/si_commands.c b/src/gallium/drivers/radeonsi/si_commands.c
new file mode 100644
index 0000000..e9492b8
--- /dev/null
+++ b/src/gallium/drivers/radeonsi/si_commands.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2012 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *      Christian König <christian.koenig at amd.com>
+ */
+
+#include "radeonsi_pipe.h"
+#include "radeonsi_pm4.h"
+#include "sid.h"
+
+void si_cmd_surface_sync(struct si_pm4_state *pm4, uint32_t cp_coher_cntl)
+{
+	si_pm4_cmd_begin(pm4, PKT3_SURFACE_SYNC);
+	si_pm4_cmd_add(pm4, cp_coher_cntl);	/* CP_COHER_CNTL */
+	si_pm4_cmd_add(pm4, 0xffffffff);	/* CP_COHER_SIZE */
+	si_pm4_cmd_add(pm4, 0);			/* CP_COHER_BASE */
+	si_pm4_cmd_add(pm4, 0x0000000A);	/* POLL_INTERVAL */
+	si_pm4_cmd_end(pm4, false);
+}
diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h
index a69722c..475432d 100644
--- a/src/gallium/drivers/radeonsi/si_state.h
+++ b/src/gallium/drivers/radeonsi/si_state.h
@@ -70,6 +70,7 @@ struct si_vertex_element
 
 union si_state {
 	struct {
+		struct si_pm4_state		*sync;
 		struct si_pm4_state		*init;
 		struct si_state_blend		*blend;
 		struct si_pm4_state		*blend_color;
@@ -148,4 +149,7 @@ void si_set_so_targets(struct pipe_context *ctx,
 /* si_state_draw.c */
 void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo);
 
+/* si_commands.c */
+void si_cmd_surface_sync(struct si_pm4_state *pm4, uint32_t cp_coher_cntl);
+
 #endif
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index 6670483..2510f34 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -459,7 +459,7 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 	struct pipe_draw_info info = *dinfo;
 	struct r600_draw rdraw = {};
 	struct pipe_index_buffer ib = {};
-	struct r600_atom *state = NULL, *next_state = NULL;
+	uint32_t cp_coher_cntl;
 
 	if ((!info.count && (info.indexed || !info.count_from_stream_output)) ||
 	    (info.indexed && !rctx->index_buffer.buffer)) {
@@ -517,14 +517,18 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *dinfo)
 	rdraw.db_render_override = dsa->db_render_override;
 	rdraw.db_render_control = dsa->db_render_control;
 
+	cp_coher_cntl = si_pm4_sync_flags(rctx);
+	if (cp_coher_cntl) {
+		struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+		si_cmd_surface_sync(pm4, cp_coher_cntl);
+		si_pm4_set_state(rctx, sync, pm4);
+	}
+
 	/* Emit states. */
 	rctx->pm4_dirty_cdwords += si_pm4_dirty_dw(rctx);
 
 	r600_need_cs_space(rctx, 0, TRUE);
 
-	LIST_FOR_EACH_ENTRY_SAFE(state, next_state, &rctx->dirty_states, head) {
-		r600_emit_atom(rctx, state);
-	}
 	si_pm4_emit_dirty(rctx);
 	rctx->pm4_dirty_cdwords = 0;
 
-- 
1.7.9.5



More information about the mesa-dev mailing list