From b77243b9c245fd5957aa6d615a3d83d061f51cc1 Mon Sep 17 00:00:00 2001 From: Anuj Phogat Date: Tue, 11 Dec 2012 19:36:05 -0800 Subject: [PATCH] intel: Support blitting to multiple color draw buffers This patch enables blitting to multiple color attachments of a framebuffer. It also fixes a case when blitting to a framebuffer with renderbuffer/texture attached to non-zero attachment point i.e. GL_COLOR_ATTACHMENT{1, 2, ...}. Earlier we were incorrectly blitting to GL_COLOR_ATTACHMENT0 by default. V2: Use intel_copy_texsubimage() for blitting only if all the color attachments can blit using it. Signed-off-by: Anuj Phogat Reviewed-by: Kenneth Graunke Reviewed-by: Ian Romanick --- src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 5 +- src/mesa/drivers/dri/intel/intel_fbo.c | 92 +++++++++++++------- 2 files changed, 63 insertions(+), 34 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp index 69dab75d2c6..bc7916a1bd4 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -263,8 +263,9 @@ try_blorp_blit(struct intel_context *intel, } for (unsigned i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; ++i) { dst_irb = intel_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[i]); - do_blorp_blit(intel, buffer_bit, src_irb, dst_irb, srcX0, srcY0, - dstX0, dstY0, dstX1, dstY1, mirror_x, mirror_y); + if (dst_irb) + do_blorp_blit(intel, buffer_bit, src_irb, dst_irb, srcX0, srcY0, + dstX0, dstY0, dstX1, dstY1, mirror_x, mirror_y); } break; case GL_DEPTH_BUFFER_BIT: diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 034fa8a96d5..481080944dd 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -793,44 +793,72 @@ intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx, GLbitfield mask, GLenum filter) { if (mask & GL_COLOR_BUFFER_BIT) { + GLint i; 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 *drawAtt; struct intel_renderbuffer *srcRb = intel_renderbuffer(readFb->_ColorReadBuffer); - /* 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 (srcRb && 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; - - struct gl_texture_image *texImage = - _mesa_select_tex_image(ctx, texObj, target, dstLevel); - - if (intel_copy_texsubimage(intel_context(ctx), - intel_texture_image(texImage), - dstX0, dstY0, - srcRb, - srcX0, srcY0, - srcX1 - srcX0, /* width */ - srcY1 - srcY0)) - mask &= ~GL_COLOR_BUFFER_BIT; + /* 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. + */ + const GLboolean use_intel_copy_texsubimage = + 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; + + /* Verify that all the draw buffers can be blitted using + * intel_copy_texsubimage(). + */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + if (idx == -1) + continue; + drawAtt = &drawFb->Attachment[idx]; + + if (srcRb && drawAtt && drawAtt->Texture && + use_intel_copy_texsubimage) + continue; + else + return mask; } + + /* Blit to all active draw buffers */ + for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) { + int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i]; + if (idx == -1) + continue; + drawAtt = &drawFb->Attachment[idx]; + + { + const struct gl_texture_object *texObj = drawAtt->Texture; + const GLuint dstLevel = drawAtt->TextureLevel; + const GLenum target = texObj->Target; + + struct gl_texture_image *texImage = + _mesa_select_tex_image(ctx, texObj, target, dstLevel); + + if (!intel_copy_texsubimage(intel_context(ctx), + intel_texture_image(texImage), + dstX0, dstY0, + srcRb, + srcX0, srcY0, + srcX1 - srcX0, /* width */ + srcY1 - srcY0)) + return mask; + } + } + + mask &= ~GL_COLOR_BUFFER_BIT; } return mask; -- 2.30.2