[Mesa-dev] [PATCH 4/6] intel: Fix framebuffer blitting to GL_COLOR_ATTACHMENTi when i!=0

Ian Romanick idr at freedesktop.org
Tue Dec 18 11:20:35 PST 2012


On 12/12/2012 03:25 PM, Anuj Phogat wrote:
> This patch fixes a case when blitting to a framebuffer with
> renderbuffers/textures attached to GL_COLOR_ATTACHMENT{1, 2, ...}.
> Earlier we were incorrectly blitting to GL_COLOR_ATTACHMENT0 by default.
>
> Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
> ---
>   src/mesa/drivers/dri/i965/brw_blorp_blit.cpp |    5 +-
>   src/mesa/drivers/dri/intel/intel_fbo.c       |   85 ++++++++++++++++----------
>   2 files changed, 56 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 e8604e7..41a8734 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 6a66521..d0e9fe2 100644
> --- a/src/mesa/drivers/dri/intel/intel_fbo.c
> +++ b/src/mesa/drivers/dri/intel/intel_fbo.c
> @@ -793,44 +793,65 @@ intel_blit_framebuffer_copy_tex_sub_image(struct gl_context *ctx,
>                                             GLbitfield mask, GLenum filter)
>   {
>      if (mask & GL_COLOR_BUFFER_BIT) {
> +      GLboolean result = false;

Use bool.

>         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;
> +      /* Blit to all active draw buffers */
> +      for (int i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
> +           int idx = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
> +           if (idx != -1) {
> +              drawAtt = &drawFb->Attachment[idx];
> +           }
> +           else
> +              continue;

    if (idx == -1)
       continue;

    drawAtt = &drawFb->Attachment[idx];
    ...

> +
> +         /* 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);
> +
> +            result = intel_copy_texsubimage(intel_context(ctx),
> +                                            intel_texture_image(texImage),
> +                                            dstX0, dstY0,
> +                                            srcRb,
> +                                            srcX0, srcY0,
> +                                            srcX1 - srcX0, /* width */
> +                                            srcY1 - srcY0);
> +           if (!result)
> +	      break;
> +         }
> +	 /* This handles a case where not all the draw buffer attachments
> +	  * are textures.
> +	  */
> +	 else if (srcRb && drawAtt) {
> +	    result = false;
> +	    break;
> +	 }
>         }
> +
> +      if (result)
> +         mask &= ~GL_COLOR_BUFFER_BIT;
>      }
>
>      return mask;
>



More information about the mesa-dev mailing list