From fa1d267beb4adb542ea90b805306599f602c38d2 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 13 Jul 2012 14:21:27 -0700 Subject: [PATCH] i965/blorp: Rearrange order of blit validation and preparation steps. This patch rearranges the order of steps performed by a blorp blit from this: - Sync up state of window system buffers. - Find buffers. - Find miptrees. - Make sure buffer formats match. - Handle mirroring. - Make sure width and height match. - Handle clipping/scissoring. - Account for window system origin conventions. - Do depth resolves, if applicable. - Do the blit. - Record the need for a future HiZ resolve, if applicable. To this: - Sync up state of window system buffers. - Handle mirroring. - Make sure width and height match. - Handle clipping/scissoring. - Account for window system origin conventions. - Find buffers. - Make sure buffer formats match. - Find miptrees. - Do depth resolves, if applicable. - Do the blit. - Record the need for a future HiZ resolve, if applicable. The steps are the same, but they are now performed in an order that will make it possible to implement correct DrawBuffers support. Note that the last four steps are now in a separate function (do_blorp_blit), since they will need to be executed repeatedly when DrawBuffers support is added. Reviewed-by: Chad Versace --- src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 143 ++++++++++++------- 1 file changed, 88 insertions(+), 55 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp index eb78fe1ece7..0c42e8517bd 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp @@ -110,6 +110,61 @@ clip_or_scissor(bool mirror, GLint &src_x0, GLint &src_x1, GLint &dst_x0, } +static struct intel_mipmap_tree * +find_miptree(GLbitfield buffer_bit, struct gl_renderbuffer *rb) +{ + struct intel_renderbuffer *irb = intel_renderbuffer(rb); + struct intel_mipmap_tree *mt = irb->mt; + if (buffer_bit == GL_STENCIL_BUFFER_BIT && mt->stencil_mt) + mt = mt->stencil_mt; + return mt; +} + + +static void +do_blorp_blit(struct intel_context *intel, GLbitfield buffer_bit, + struct gl_renderbuffer *src_rb, struct gl_renderbuffer *dst_rb, + GLint srcX0, GLint srcY0, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + bool mirror_x, bool mirror_y) +{ + struct gl_context *ctx = &intel->ctx; + + /* Find source/dst miptrees */ + struct intel_mipmap_tree *src_mt = find_miptree(buffer_bit, src_rb); + struct intel_mipmap_tree *dst_mt = find_miptree(buffer_bit, dst_rb); + + /* Get ready to blit. This includes depth resolving the src and dst + * buffers if necessary. + */ + intel_renderbuffer_resolve_depth(intel, intel_renderbuffer(src_rb)); + intel_renderbuffer_resolve_depth(intel, intel_renderbuffer(dst_rb)); + + /* Do the blit */ + brw_blorp_blit_params params(brw_context(ctx), src_mt, dst_mt, + srcX0, srcY0, dstX0, dstY0, dstX1, dstY1, + mirror_x, mirror_y); + brw_blorp_exec(intel, ¶ms); + + /* Mark the dst buffer as needing a HiZ resolve if necessary. */ + intel_renderbuffer_set_needs_hiz_resolve(intel_renderbuffer(dst_rb)); +} + + +static bool +formats_match(GLbitfield buffer_bit, struct gl_renderbuffer *src_rb, + struct gl_renderbuffer *dst_rb) +{ + /* Note: don't just check gl_renderbuffer::Format, because in some cases + * multiple gl_formats resolve to the same native type in the miptree (for + * example MESA_FORMAT_X8_Z24 and MESA_FORMAT_S8_Z24), and we can blit + * between those formats. + */ + return find_miptree(buffer_bit, src_rb)->format == + find_miptree(buffer_bit, dst_rb)->format; +} + + static bool try_blorp_blit(struct intel_context *intel, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, @@ -123,49 +178,8 @@ try_blorp_blit(struct intel_context *intel, */ intel_prepare_render(intel); - /* Find buffers */ const struct gl_framebuffer *read_fb = ctx->ReadBuffer; const struct gl_framebuffer *draw_fb = ctx->DrawBuffer; - struct gl_renderbuffer *src_rb; - struct gl_renderbuffer *dst_rb; - switch (buffer_bit) { - case GL_COLOR_BUFFER_BIT: - src_rb = read_fb->_ColorReadBuffer; - dst_rb = - draw_fb->Attachment[ - draw_fb->_ColorDrawBufferIndexes[0]].Renderbuffer; - break; - case GL_DEPTH_BUFFER_BIT: - src_rb = read_fb->Attachment[BUFFER_DEPTH].Renderbuffer; - dst_rb = draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer; - break; - case GL_STENCIL_BUFFER_BIT: - src_rb = read_fb->Attachment[BUFFER_STENCIL].Renderbuffer; - dst_rb = draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer; - break; - default: - assert(false); - } - - /* Find source miptree */ - struct intel_renderbuffer *src_irb = intel_renderbuffer(src_rb); - struct intel_mipmap_tree *src_mt = src_irb->mt; - if (buffer_bit == GL_STENCIL_BUFFER_BIT && src_mt->stencil_mt) - src_mt = src_mt->stencil_mt; - - /* Find destination miptree */ - struct intel_renderbuffer *dst_irb = intel_renderbuffer(dst_rb); - struct intel_mipmap_tree *dst_mt = dst_irb->mt; - if (buffer_bit == GL_STENCIL_BUFFER_BIT && dst_mt->stencil_mt) - dst_mt = dst_mt->stencil_mt; - - /* Blorp blits can't translate from one format to another. For that we'll - * have to fall back to the meta-op blit. Note: the meta-op blit doesn't - * support multisampled blits, but fortunately this is ok because - * multisampled blits require identical source and destination formats. - */ - if (src_mt->format != dst_mt->format) - return false; /* Detect if the blit needs to be mirrored */ bool mirror_x = false, mirror_y = false; @@ -213,20 +227,39 @@ try_blorp_blit(struct intel_context *intel, mirror_y = !mirror_y; } - /* Get ready to blit. This includes depth resolving the src and dst - * buffers if necessary. - */ - intel_renderbuffer_resolve_depth(intel, src_irb); - intel_renderbuffer_resolve_depth(intel, dst_irb); - - /* Do the blit */ - brw_blorp_blit_params params(brw_context(ctx), src_mt, dst_mt, - srcX0, srcY0, dstX0, dstY0, dstX1, dstY1, - mirror_x, mirror_y); - brw_blorp_exec(intel, ¶ms); - - /* Mark the dst buffer as needing a HiZ resolve if necessary. */ - intel_renderbuffer_set_needs_hiz_resolve(dst_irb); + /* Find buffers */ + struct gl_renderbuffer *src_rb; + struct gl_renderbuffer *dst_rb; + switch (buffer_bit) { + case GL_COLOR_BUFFER_BIT: + src_rb = read_fb->_ColorReadBuffer; + dst_rb = + draw_fb->Attachment[ + draw_fb->_ColorDrawBufferIndexes[0]].Renderbuffer; + if (!formats_match(buffer_bit, src_rb, dst_rb)) + return false; + do_blorp_blit(intel, buffer_bit, src_rb, dst_rb, srcX0, srcY0, + dstX0, dstY0, dstX1, dstY1, mirror_x, mirror_y); + break; + case GL_DEPTH_BUFFER_BIT: + src_rb = read_fb->Attachment[BUFFER_DEPTH].Renderbuffer; + dst_rb = draw_fb->Attachment[BUFFER_DEPTH].Renderbuffer; + if (!formats_match(buffer_bit, src_rb, dst_rb)) + return false; + do_blorp_blit(intel, buffer_bit, src_rb, dst_rb, srcX0, srcY0, + dstX0, dstY0, dstX1, dstY1, mirror_x, mirror_y); + break; + case GL_STENCIL_BUFFER_BIT: + src_rb = read_fb->Attachment[BUFFER_STENCIL].Renderbuffer; + dst_rb = draw_fb->Attachment[BUFFER_STENCIL].Renderbuffer; + if (!formats_match(buffer_bit, src_rb, dst_rb)) + return false; + do_blorp_blit(intel, buffer_bit, src_rb, dst_rb, srcX0, srcY0, + dstX0, dstY0, dstX1, dstY1, mirror_x, mirror_y); + break; + default: + assert(false); + } return true; } -- 2.30.2