From 93bce03b275f66b6b2db410bbef38954de6a617c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Thu, 24 Jun 2010 04:43:40 +0200 Subject: [PATCH] r300g: separate the cache flush from the framebuffer state --- src/gallium/drivers/r300/r300_context.c | 28 ++++++++++++++++++++- src/gallium/drivers/r300/r300_context.h | 6 +++++ src/gallium/drivers/r300/r300_emit.c | 33 +++++++++++++------------ src/gallium/drivers/r300/r300_emit.h | 2 ++ src/gallium/drivers/r300/r300_state.c | 3 ++- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index b35c91ac5b2..85190eac2b8 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -76,6 +76,7 @@ static void r300_destroy_context(struct pipe_context* context) FREE(r300->blend_color_state.state); FREE(r300->clip_state.state); FREE(r300->fb_state.state); + FREE(r300->gpu_flush.state); FREE(r300->rs_block_state.state); FREE(r300->scissor_state.state); FREE(r300->textures_state.state); @@ -120,6 +121,7 @@ static void r300_setup_atoms(struct r300_context* r300) /* XXX unsorted. */ R300_INIT_ATOM(invariant_state, 71); /* RB3D (unpipelined), ZB (unpipelined), US, SC. */ + R300_INIT_ATOM(gpu_flush, 9); R300_INIT_ATOM(fb_state, 0); R300_INIT_ATOM(ztop_state, 2); R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6); @@ -157,6 +159,7 @@ static void r300_setup_atoms(struct r300_context* r300) r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); r300->clip_state.state = CALLOC_STRUCT(r300_clip_state); r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); + r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state); r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); @@ -180,16 +183,20 @@ static void r300_setup_atoms(struct r300_context* r300) * call and we must initialize the command buffers somehow. */ static void r300_init_states(struct pipe_context *pipe) { + struct r300_context *r300 = r300_context(pipe); struct pipe_blend_color bc = {{0}}; struct pipe_clip_state cs = {{{0}}}; struct pipe_scissor_state ss = {0}; struct r300_clip_state *clip = - (struct r300_clip_state*)r300_context(pipe)->clip_state.state; + (struct r300_clip_state*)r300->clip_state.state; + struct r300_gpu_flush *gpuflush = + (struct r300_gpu_flush*)r300->gpu_flush.state; CB_LOCALS; pipe->set_blend_color(pipe, &bc); pipe->set_scissor_state(pipe, &ss); + /* Initialize the clip state. */ if (r300_context(pipe)->screen->caps.has_tcl) { pipe->set_clip_state(pipe, &cs); } else { @@ -197,6 +204,25 @@ static void r300_init_states(struct pipe_context *pipe) OUT_CB_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); END_CB; } + + /* Initialize the GPU flush. */ + { + BEGIN_CB(gpuflush->cb_flush_clean, 6); + + /* Flush and free renderbuffer caches. */ + OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT, + R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | + R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); + OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, + R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | + R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); + + /* Wait until the GPU is idle. + * This fixes random pixels sometimes appearing probably caused + * by incomplete rendering. */ + OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + END_CB; + } } struct pipe_context* r300_create_context(struct pipe_screen* screen, diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8d0b4bb3d37..c5c662afd0f 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -98,6 +98,10 @@ struct r300_dsa_state { boolean two_sided_stencil_ref; }; +struct r300_gpu_flush { + uint32_t cb_flush_clean[6]; +}; + struct r300_rs_state { /* Original rasterizer state. */ struct pipe_rasterizer_state rs; @@ -461,6 +465,8 @@ struct r300_context { struct r300_atom pvs_flush; /* Texture cache invalidate. */ struct r300_atom texture_cache_inval; + /* GPU flush. */ + struct r300_atom gpu_flush; /* Invariant state. This must be emitted to get the engine started. */ struct r300_atom invariant_state; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index a5fa06a3e8b..dd6cc4d4f84 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -267,11 +267,11 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo END_CS; } -void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) +void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state) { - struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; - struct r300_surface* surf; - unsigned i; + struct r300_gpu_flush *gpuflush = (struct r300_gpu_flush*)state; + struct pipe_framebuffer_state* fb = + (struct pipe_framebuffer_state*)r300->fb_state.state; CS_LOCALS(r300); BEGIN_CS(size); @@ -290,18 +290,19 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT)); } - /* Flush and free renderbuffer caches. */ - OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, - R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | - R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); - OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, - R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | - R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); - - /* Wait until the GPU is idle. - * This fixes random pixels sometimes appearing probably caused - * by incomplete rendering. */ - OUT_CS_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); + /* Flush CB & ZB caches and wait until the 3D engine is idle and clean. */ + OUT_CS_TABLE(gpuflush->cb_flush_clean, 6); + END_CS; +} + +void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) +{ + struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; + struct r300_surface* surf; + unsigned i; + CS_LOCALS(r300); + + BEGIN_CS(size); /* XXX unpipelined regs rb3d_aaresolve_ctl diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h index 36a29894d01..16a2b5e9f17 100644 --- a/src/gallium/drivers/r300/r300_emit.h +++ b/src/gallium/drivers/r300/r300_emit.h @@ -59,6 +59,8 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state); +void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state); + void r300_emit_query_start(struct r300_context *r300, unsigned size, void *state); void r300_emit_query_end(struct r300_context* r300); diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 247a590da51..f2534e473da 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -686,6 +686,7 @@ static void draw_flush(r300->draw); } + r300->gpu_flush.dirty = TRUE; r300->fb_state.dirty = TRUE; /* If nr_cbufs is changed from zero to non-zero or vice versa... */ @@ -703,7 +704,7 @@ static void memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); r300->fb_state.size = - 16 + + 7 + (8 * state->nr_cbufs) + (state->zsbuf ? (r300->screen->caps.has_hiz ? 22 : 18) : 0); -- 2.30.2