diff options
author | Eric Anholt <[email protected]> | 2013-06-03 20:50:50 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2013-06-17 15:43:23 -0700 |
commit | b0e3c3b852e2e24d55f1ea2073c463de1f963d76 (patch) | |
tree | fbbac785d539e89bdf321127d99ecfb73b1f4cac | |
parent | 815dce92822ebb2ed25f8e3a3f87a62c115cb0d0 (diff) |
intel: Directly implement blit glBlitFramebuffer instead of awkward reuse.
This gets us support for blitting to attachment types other than
textures.
v2: fix up comments from review by Kenneth.
Reviewed-by: Kenneth Graunke <[email protected]>
Acked-by: Paul Berry <[email protected]>
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_fbo.c | 133 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_copy.c | 2 |
3 files changed, 72 insertions, 70 deletions
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c index 9f892a92eb9..5fe3dc79560 100644 --- a/src/mesa/drivers/dri/intel/intel_fbo.c +++ b/src/mesa/drivers/dri/intel/intel_fbo.c @@ -737,76 +737,85 @@ intel_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) * normal path. */ static GLbitfield -intel_blit_framebuffer_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) +intel_blit_framebuffer_with_blitter(struct gl_context *ctx, + GLint srcX0, GLint srcY0, + GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, + GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { + struct intel_context *intel = intel_context(ctx); + 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; - struct intel_renderbuffer *srcRb = - intel_renderbuffer(readFb->_ColorReadBuffer); + struct gl_renderbuffer *src_rb = readFb->_ColorReadBuffer; + struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); + + if (!src_irb) { + perf_debug("glBlitFramebuffer(): missing src renderbuffer. " + "Falling back to software rendering.\n"); + return mask; + } /* 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. + * scissor, then we can probably use the blit engine. */ - 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(). + if (!(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)) { + perf_debug("glBlitFramebuffer(): non-1:1 blit. " + "Falling back to software rendering.\n"); + return mask; + } + + /* Blit to all active draw buffers. We don't do any pre-checking, + * because we assume that copying to MRTs is rare, and failure midway + * through copying is even more rare. Even if it was to occur, it's + * safe to let meta start the copy over from scratch, because + * glBlitFramebuffer completely overwrites the destination pixels, and + * results are undefined if any destination pixels have a dependency on + * source pixels. */ 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 + struct gl_renderbuffer *dst_rb = ctx->DrawBuffer->_ColorDrawBuffers[i]; + struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb); + + if (!dst_irb) { + perf_debug("glBlitFramebuffer(): missing dst renderbuffer. " + "Falling back to software rendering.\n"); 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; + gl_format src_format = _mesa_get_srgb_format_linear(src_rb->Format); + gl_format dst_format = _mesa_get_srgb_format_linear(dst_rb->Format); + if (src_format != dst_format) { + perf_debug("glBlitFramebuffer(): unsupported blit from %s to %s. " + "Falling back to software rendering.\n", + _mesa_get_format_name(src_format), + _mesa_get_format_name(dst_format)); + return mask; + } + + if (!intel_miptree_blit(intel, + src_irb->mt, + src_irb->mt_level, src_irb->mt_layer, + srcX0, srcY0, src_rb->Name == 0, + dst_irb->mt, + dst_irb->mt_level, dst_irb->mt_layer, + dstX0, dstY0, dst_rb->Name == 0, + dstX1 - dstX0, dstY1 - dstY0, GL_COPY)) { + perf_debug("glBlitFramebuffer(): unknown blit failure. " + "Falling back to software rendering.\n"); + return mask; } } @@ -831,11 +840,11 @@ intel_blit_framebuffer(struct gl_context *ctx, return; #endif - /* Try glCopyTexSubImage2D approach which uses the BLT. */ - mask = intel_blit_framebuffer_copy_tex_sub_image(ctx, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); + /* Try using the BLT engine. */ + mask = intel_blit_framebuffer_with_blitter(ctx, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); if (mask == 0x0) return; diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h index e03811546ab..a08fdf4aa71 100644 --- a/src/mesa/drivers/dri/intel/intel_tex.h +++ b/src/mesa/drivers/dri/intel/intel_tex.h @@ -68,13 +68,6 @@ bool intel_tex_image_s8z24_create_renderbuffers(struct intel_context *intel, struct intel_texture_image *image); -bool intel_copy_texsubimage(struct intel_context *intel, - struct intel_texture_image *intelImage, - GLint dstx, GLint dsty, - struct intel_renderbuffer *irb, - GLint x, GLint y, - GLsizei width, GLsizei height); - bool intel_texsubimage_tiled_memcpy(struct gl_context *ctx, GLuint dims, diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c index 4f01c587b6e..f9e03fa9048 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_copy.c +++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c @@ -48,7 +48,7 @@ #define FILE_DEBUG_FLAG DEBUG_TEXTURE -bool +static bool intel_copy_texsubimage(struct intel_context *intel, struct intel_texture_image *intelImage, GLint dstx, GLint dsty, |