[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:21:14 PST 2012


On 12/18/2012 11:20 AM, Ian Romanick wrote:
> 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>

Also... if this patch doesn't depend on previous patches in the series, 
it should be marked as a candidate for the 9.0 branch.

>> ---
>>   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