summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/radeonsi/Makefile.sources4
-rw-r--r--src/gallium/drivers/radeonsi/r600_hw_context.c34
-rw-r--r--src/gallium/drivers/radeonsi/r600_state_common.c77
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.c4
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.h52
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pm4.c43
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pm4.h3
-rw-r--r--src/gallium/drivers/radeonsi/si_commands.c39
-rw-r--r--src/gallium/drivers/radeonsi/si_state.h4
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c12
10 files changed, 100 insertions, 172 deletions
diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
index 630afb8db53..f1b4936ff4d 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 6765ef82e8a..5480cb51c70 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 aa58406c8be..00000000000
--- 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 <[email protected]>
- * Jerome Glisse <[email protected]>
- */
-#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 8356fda7c49..79a3d801b5e 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
@@ -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 =
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
index 1cb16b673bc..cca4f02f44e 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;
@@ -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
*/
diff --git a/src/gallium/drivers/radeonsi/radeonsi_pm4.c b/src/gallium/drivers/radeonsi/radeonsi_pm4.c
index da680dc1ee1..13fe99be3bd 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 bbddfd01a2d..803bb8f572d 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 00000000000..e9492b8e81e
--- /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 <[email protected]>
+ */
+
+#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 a69722c975b..475432d54fb 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 40ca95751b9..e3573697d95 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -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;