summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-06-19 19:44:06 +0200
committerMarek Olšák <maraeo@gmail.com>2010-06-19 20:26:16 +0200
commit9b2ebcaf4b94bfc8756f6b216e0e452013616f2c (patch)
tree05806fe50e90951a925230f05ea532b4d5c6fa43
parent4c761843051d7e97be828baad965c13789127dbf (diff)
r300g: fix random pixels appearing / incomplete rendering
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.
-rw-r--r--src/gallium/drivers/r300/r300_emit.c31
-rw-r--r--src/gallium/drivers/r300/r300_state.c2
-rw-r--r--src/gallium/drivers/r300/r300_transfer.c14
3 files changed, 20 insertions, 27 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 50372d28c1..e2c40d823d 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -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;
}
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 488e23a917..256184aac9 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -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) {
diff --git a/src/gallium/drivers/r300/r300_transfer.c b/src/gallium/drivers/r300/r300_transfer.c
index 4f37fabb28..d41f258836 100644
--- a/src/gallium/drivers/r300/r300_transfer.c
+++ b/src/gallium/drivers/r300/r300_transfer.c
@@ -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*