summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2009-12-18 14:35:03 +1000
committerDave Airlie <[email protected]>2009-12-18 14:35:03 +1000
commit112908c279b0a768eca95a505856a087e479674b (patch)
tree223dbf732b663853f6e94bdf5d15adf4a352be38 /src/mesa/drivers
parent5f59e79f3a9f273c683304117802bb216171c257 (diff)
radeon: fix frontbuffer read/drawpixels
Bug 25699 The main problem was the optimising flush wasn't doing the front rendering checks properly.
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r--src/mesa/drivers/dri/r600/r700_clear.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c24
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c40
5 files changed, 58 insertions, 16 deletions
diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c
index c6546ab00c2..526d3843d16 100644
--- a/src/mesa/drivers/dri/r600/r700_clear.c
+++ b/src/mesa/drivers/dri/r600/r700_clear.c
@@ -57,6 +57,10 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x\n", __func__, mask);
+ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+ context->radeon.front_buffer_dirty = GL_TRUE;
+ }
+
if( GL_TRUE == r700ClearFast(context, mask) )
{
return;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index 51fa6189377..2a2b16a54bd 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -641,6 +641,27 @@ void radeonCopySubBuffer(__DRIdrawablePrivate * dPriv,
}
}
+/**
+ * Check if we're about to draw into the front color buffer.
+ * If so, set the intel->front_buffer_dirty field to true.
+ */
+void
+radeon_check_front_buffer_rendering(GLcontext *ctx)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ const struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+ if (fb->Name == 0) {
+ /* drawing to window system buffer */
+ if (fb->_NumColorDrawBuffers > 0) {
+ if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
+ radeon->front_buffer_dirty = GL_TRUE;
+ }
+ }
+ }
+}
+
+
void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
@@ -1095,7 +1116,7 @@ void radeonFlush(GLcontext *ctx)
then no point flushing anything at all.
*/
if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
- return;
+ goto flush_front;
if (radeon->dma.flush)
radeon->dma.flush( ctx );
@@ -1103,6 +1124,7 @@ void radeonFlush(GLcontext *ctx)
if (radeon->cmdbuf.cs->cdw)
rcommonFlushCmdBuf(radeon, __FUNCTION__);
+flush_front:
if ((ctx->DrawBuffer->Name == 0) && radeon->front_buffer_dirty) {
__DRIscreen *const screen = radeon->radeonScreen->driScreen;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index 0608fe2418c..faad145cc49 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -43,6 +43,8 @@ radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
struct radeon_bo *bo);
struct radeon_renderbuffer *
radeon_create_renderbuffer(gl_format format, __DRIdrawablePrivate *driDrawPriv);
+
+void radeon_check_front_buffer_rendering(GLcontext *ctx);
static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
{
struct radeon_renderbuffer *rrb = (struct radeon_renderbuffer *)rb;
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index a0106d00fa2..13fd6f99719 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -575,6 +575,10 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
GLuint color_mask = 0;
GLuint orig_mask = mask;
+ if (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_FRONT_RIGHT)) {
+ rmesa->radeon.front_buffer_dirty = GL_TRUE;
+ }
+
if ( RADEON_DEBUG & RADEON_IOCTL ) {
fprintf( stderr, "radeonClear\n");
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index 37904dc8dc9..cffe8406628 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -828,18 +828,21 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
}
static void
-radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
+radeon_map_unmap_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb,
+ GLboolean map)
{
GLuint i, j;
/* color draw buffers */
for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
- map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map);
+ map_unmap_rb(fb->_ColorDrawBuffers[j], map);
+
+ map_unmap_rb(fb->_ColorReadBuffer, map);
/* check for render to textures */
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att =
- ctx->DrawBuffer->Attachment + i;
+ fb->Attachment + i;
struct gl_texture_object *tex = att->Texture;
if (tex) {
/* Render to texture. Note that a mipmapped texture need not
@@ -855,15 +858,15 @@ radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
radeon_teximage_unmap(image);
}
}
-
- map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
-
+
/* depth buffer (Note wrapper!) */
- if (ctx->DrawBuffer->_DepthBuffer)
- map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
+ if (fb->_DepthBuffer)
+ map_unmap_rb(fb->_DepthBuffer->Wrapped, map);
+
+ if (fb->_StencilBuffer)
+ map_unmap_rb(fb->_StencilBuffer->Wrapped, map);
- if (ctx->DrawBuffer->_StencilBuffer)
- map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
+ radeon_check_front_buffer_rendering(ctx);
}
static void radeonSpanRenderStart(GLcontext * ctx)
@@ -888,23 +891,30 @@ static void radeonSpanRenderStart(GLcontext * ctx)
ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
}
- radeon_map_unmap_buffers(ctx, 1);
+ radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE);
}
static void radeonSpanRenderFinish(GLcontext * ctx)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
int i;
+
_swrast_flush(ctx);
- if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
- UNLOCK_HARDWARE(rmesa);
- }
+
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Texture.Unit[i]._ReallyEnabled)
ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
}
- radeon_map_unmap_buffers(ctx, 0);
+ radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE);
+
+ if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
+ UNLOCK_HARDWARE(rmesa);
+ }
}
void radeonInitSpanFuncs(GLcontext * ctx)