From 9b2ebcaf4b94bfc8756f6b216e0e452013616f2c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 19 Jun 2010 19:44:06 +0200 Subject: [PATCH] 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. --- src/gallium/drivers/r300/r300_emit.c | 31 +++++++++++++++++++------------ src/gallium/drivers/r300/r300_state.c | 2 +- src/gallium/drivers/r300/r300_transfer.c | 14 -------------- 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 50372d2..e2c40d8 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 488e23a..256184a 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 4f37fab..d41f258 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* -- 2.7.4