radeonsi: move sync handling into new state handler
authorChristian König <deathsimple@vodafone.de>
Thu, 2 Aug 2012 14:15:40 +0000 (16:15 +0200)
committerChristian König <deathsimple@vodafone.de>
Sat, 11 Aug 2012 07:58:26 +0000 (09:58 +0200)
So we can remove all the old atom handling.

Signed-off-by: Christian König <deathsimple@vodafone.de>
src/gallium/drivers/radeonsi/Makefile.sources
src/gallium/drivers/radeonsi/r600_hw_context.c
src/gallium/drivers/radeonsi/r600_state_common.c [deleted file]
src/gallium/drivers/radeonsi/radeonsi_pipe.c
src/gallium/drivers/radeonsi/radeonsi_pipe.h
src/gallium/drivers/radeonsi/radeonsi_pm4.c
src/gallium/drivers/radeonsi/radeonsi_pm4.h
src/gallium/drivers/radeonsi/si_commands.c [new file with mode: 0644]
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c

index 630afb8..f1b4936 100644 (file)
@@ -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
index 6765ef8..5480cb5 100644 (file)
@@ -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 (file)
index aa58406..0000000
+++ /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@redhat.com>
- *          Jerome Glisse <jglisse@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;
-}
index 8356fda..79a3d80 100644 (file)
@@ -214,8 +214,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);
@@ -251,8 +249,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 */
 
        rctx->dummy_pixel_shader =
index 1cb16b6..cca4f02 100644 (file)
 #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;
@@ -213,26 +185,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);
@@ -271,10 +223,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
  */
index da680dc..13fe99b 100644 (file)
@@ -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;
        }
 }
index bbddfd0..803bb8f 100644 (file)
@@ -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 (file)
index 0000000..e9492b8
--- /dev/null
@@ -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@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);
+}
index a69722c..475432d 100644 (file)
@@ -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
index 40ca957..e357369 100644 (file)
@@ -466,7 +466,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)) {
@@ -524,14 +524,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;