From b5e32cfa43b71b44b3845124f5e5c1c72716a087 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Sat, 5 Feb 2011 10:21:11 +0000 Subject: [PATCH] meta: Try using glCopyTexSubImage2D in _mesa_meta_BlitFramebuffer In the case where glBlitFramebuffer is being used to copy to a texture without scaling it is faster if we can use the hardware to do a blit rather than having to do a texture render. In most of the drivers glCopyTexSubImage2D will use a blit so this patch makes it check for when glBlitFramebuffer is doing a simple copy and then divert to glCopyTexSubImage2D. https://bugs.freedesktop.org/show_bug.cgi?id=33934 --- src/mesa/drivers/common/meta.c | 88 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 88 insertions(+), 0 deletions(-) diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index fd12e4d..c01e0f4 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -1099,6 +1099,87 @@ init_blit_depth_pixels(struct gl_context *ctx) /** + * Try to do a glBlitFramebuffer using glCopyTexSubImage2D + * We can do this when the dst renderbuffer is actually a texture and + * there is no scaling, mirroring or scissoring. + * + * \return new buffer mask indicating the buffers left to blit using the + * normal path. + */ +static GLbitfield +blitframebuffer_copy_tex_sub_image(struct gl_context *ctx, + GLint srcX0, GLint srcY0, + GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + if (mask & GL_COLOR_BUFFER_BIT) { + const struct gl_framebuffer *drawFb = ctx->DrawBuffer; + const struct gl_framebuffer *readFb = ctx->ReadBuffer; + const struct gl_renderbuffer_attachment *drawAtt = + &drawFb->Attachment[drawFb->_ColorDrawBufferIndexes[0]]; + const struct gl_renderbuffer_attachment *readAtt = + &readFb->Attachment[readFb->_ColorReadBufferIndex]; + + /* If the source and destination are the same size with no + mirroring, the rectangles are within the size of the + texture and there is no scissor then we can use + glCopyTexSubimage2D to implement the blit. This will end + up as a fast hardware blit on some drivers */ + if (drawAtt && drawAtt->Texture && + srcX0 - srcX1 == dstX0 - dstX1 && + srcY0 - srcY1 == dstY0 - dstY1 && + srcX1 >= srcX0 && + srcY1 >= srcY0 && + srcX0 >= 0 && srcX1 <= readFb->Width && + srcY0 >= 0 && srcY1 <= readFb->Height && + dstX0 >= 0 && dstX1 <= drawFb->Width && + dstY0 >= 0 && dstY1 <= drawFb->Height && + !ctx->Scissor.Enabled) { + const struct gl_texture_object *texObj = drawAtt->Texture; + const GLuint dstLevel = drawAtt->TextureLevel; + const GLenum target = texObj->Target; + + if (drawAtt->Texture == readAtt->Texture) { + /* Can't use same texture as both the source and dest. We need + * to handle overlapping blits and besides, some hw may not + * support this. + */ + return mask; + } + + if (target != GL_TEXTURE_2D && + target != GL_TEXTURE_RECTANGLE_ARB) { + /* Can't handle other texture types at this time */ + return mask; + } + + /* The pixel ops affect the operation of CopyTexSubImage2D so + we need to temporarily restore them to the defaults. We're + also going to override the bound texture */ + _mesa_meta_begin (ctx, META_PIXEL_TRANSFER | META_TEXTURE); + + _mesa_BindTexture (GL_TEXTURE_2D, texObj->Name); + + _mesa_CopyTexSubImage2D (target, + dstLevel, + dstX0, dstY0, + srcX0, srcY0, + srcX1 - srcX0, /* width */ + srcY1 - srcY0); + + _mesa_meta_end (ctx); + + /* Done with color buffer */ + mask &= ~GL_COLOR_BUFFER_BIT; + } + } + + return mask; +} + +/** * Try to do a glBlitFramebuffer using no-copy texturing. * We can do this when the src renderbuffer is actually a texture. * But if the src buffer == dst buffer we cannot do this. @@ -1263,6 +1344,13 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx, return; } + /* Try faster, glCopyTexSubImage2D approach first */ + mask = blitframebuffer_copy_tex_sub_image(ctx, srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); + if (mask == 0x0) + return; + if (srcFlipX) { GLint tmp = dstX0; dstX0 = dstX1; -- 1.7.3.16.g9464b