radeon: fix frontbuffer read/drawpixels

Bug 25699

The main problem was the optimising flush wasn't doing the front
rendering checks properly.
This commit is contained in:
Dave Airlie 2009-12-18 14:35:03 +10:00
parent 5f59e79f3a
commit 112908c279
5 changed files with 58 additions and 16 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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");
}

View file

@ -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 (ctx->DrawBuffer->_StencilBuffer)
map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
if (fb->_StencilBuffer)
map_unmap_rb(fb->_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)