From: Christian König Date: Thu, 2 Aug 2012 14:15:40 +0000 (+0200) Subject: radeonsi: move sync handling into new state handler X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=583c212115795bef65da92761180ce830fafc927;p=mesa.git radeonsi: move sync handling into new state handler So we can remove all the old atom handling. Signed-off-by: Christian König --- 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 - * Jerome Glisse - */ -#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 + */ + +#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;