summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuj Phogat <[email protected]>2012-12-11 19:36:05 -0800
committerIan Romanick <[email protected]>2013-01-15 15:08:55 -0800
commitb77243b9c245fd5957aa6d615a3d83d061f51cc1 (patch)
treede3641a49b29210573ed52a9f93084d2082bfc13
parent0c535ae7fc703e10c1df7a108e8704263d7b75d3 (diff)
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 <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Reviewed-by: Ian Romanick <[email protected]>
-rw-r--r--src/mesa/drivers/dri/i965/brw_blorp_blit.cpp5
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c92
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;