r300g: separate the cache flush from the framebuffer state
authorMarek Olšák <maraeo@gmail.com>
Thu, 24 Jun 2010 02:43:40 +0000 (04:43 +0200)
committerMarek Olšák <maraeo@gmail.com>
Thu, 24 Jun 2010 04:10:47 +0000 (06:10 +0200)
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_emit.h
src/gallium/drivers/r300/r300_state.c

index b35c91a..85190ea 100644 (file)
@@ -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,
index 8d0b4bb..c5c662a 100644 (file)
@@ -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;
index a5fa06a..dd6cc4d 100644 (file)
@@ -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
index 36a2989..16a2b5e 100644 (file)
@@ -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);
index 247a590..f2534e4 100644 (file)
@@ -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);