r300g: fix random pixels appearing / incomplete rendering
authorMarek Olšák <maraeo@gmail.com>
Sat, 19 Jun 2010 17:44:06 +0000 (19:44 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sat, 19 Jun 2010 18:26:16 +0000 (20:26 +0200)
This should fix the FDO bug #28612.

Also, these piglit tests have been fixed:
- fbo-copypix
- scissor-copypixels
- copytexsubimage
- texredefine

Finally, 2 flushes in the transfer path are no longer needed.

src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_transfer.c

index 50372d28c139809b3ec6c5597fe2a4d7b9fbe212..e2c40d823d423fea9bf6f7fdb2036a1234aa8eb2 100644 (file)
@@ -276,6 +276,20 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
 
     BEGIN_CS(size);
 
+    /* Set up scissors.
+     * By writing to the SC registers, SC & US assert idle. */
+    OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
+    if (r300->screen->caps.is_r500) {
+        OUT_CS(0);
+        OUT_CS(((fb->width  - 1) << R300_SCISSORS_X_SHIFT) |
+               ((fb->height - 1) << R300_SCISSORS_Y_SHIFT));
+    } else {
+        OUT_CS((1440 << R300_SCISSORS_X_SHIFT) |
+               (1440 << R300_SCISSORS_Y_SHIFT));
+        OUT_CS(((fb->width  + 1440-1) << R300_SCISSORS_X_SHIFT) |
+               ((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 |
@@ -284,6 +298,11 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         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);
+
     /* NUM_MULTIWRITES replicates COLOR[0] to all colorbuffers, which is not
      * what we usually want. */
     if (r300->screen->caps.is_r500) {
@@ -321,18 +340,6 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
         OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
         OUT_CS_RELOC(surf->buffer, surf->pitch, 0, surf->domain, 0);
     }
-
-    OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
-    if (r300->screen->caps.is_r500) {
-        OUT_CS(0);
-        OUT_CS(((fb->width  - 1) << R300_SCISSORS_X_SHIFT) |
-               ((fb->height - 1) << R300_SCISSORS_Y_SHIFT));
-    } else {
-        OUT_CS((1440 << R300_SCISSORS_X_SHIFT) |
-               (1440 << R300_SCISSORS_Y_SHIFT));
-        OUT_CS(((fb->width  + 1440-1) << R300_SCISSORS_X_SHIFT) |
-               ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT));
-    }
     END_CS;
 }
 
index 488e23a91726985be94c66629e70fea6695bbb90..256184aac9e95fc062cae5eb5408491f576ced0f 100644 (file)
@@ -709,7 +709,7 @@ static void
     memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
 
     r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
-                          (state->zsbuf ? 10 : 0) + 9;
+                          (state->zsbuf ? 10 : 0) + 11;
 
     /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {
index 4f37fabb28984dcaa4212070bf8ff8b231b2aac8..d41f2588369d87a5fd93b38ab99e28c424f79503 100644 (file)
@@ -57,22 +57,11 @@ static void r300_copy_from_tiled_texture(struct pipe_context *ctx,
     subdst.face = 0;
     subdst.level = 0;
 
-    /* XXX if we don't flush before copying the texture and mapping it,
-     * we get wrong pixels, i.e. it's like latest draw calls didn't happen,
-     * including this blit. Tests: e.g. piglit/provoking-vertex
-     *
-     * Since the flush immediately before mapping is implicit (the buffer is
-     * always referenced in resource_copy_region), every read transfer costs
-     * 2 flushes. That sucks. */
-    ctx->flush(ctx, 0, NULL);
-
     ctx->resource_copy_region(ctx, &r300transfer->detiled_texture->b.b, subdst,
                              0, 0, 0,
                              tex, transfer->sr,
                              transfer->box.x, transfer->box.y, transfer->box.z,
                              transfer->box.width, transfer->box.height);
-
-    /* Flushing after the copy is implicit, issued by winsys. */
 }
 
 /* Copy a detiled texture to a tiled one. */
@@ -91,9 +80,6 @@ static void r300_copy_into_tiled_texture(struct pipe_context *ctx,
                              &r300transfer->detiled_texture->b.b, subsrc,
                              0, 0, 0,
                              transfer->box.width, transfer->box.height);
-
-    /* XXX this flush fixes a few piglit tests (e.g. glean/pixelFormats). */
-    ctx->flush(ctx, 0, NULL);
 }
 
 struct pipe_transfer*