[Mesa-dev] [PATCH] i965/blorp: Implement destination clipping and scissoring

Paul Berry stereotype441 at gmail.com
Wed May 23 11:47:40 PDT 2012


On 22 May 2012 11:08, Ian Romanick <idr at freedesktop.org> wrote:

> On 05/14/2012 03:47 PM, Paul Berry wrote:
>
>> This patch implements clipping and scissoring of the destination rect
>> for blits that use the blorp engine (e.g. MSAA blits).
>> ---
>>  src/mesa/drivers/dri/i965/brw_**blorp_blit.cpp |   72
>> ++++++++++++++++++++++++--
>>  1 files changed, 67 insertions(+), 5 deletions(-)
>>
>> diff --git a/src/mesa/drivers/dri/i965/**brw_blorp_blit.cpp
>> b/src/mesa/drivers/dri/i965/**brw_blorp_blit.cpp
>> index ee65cd6..223d8c1 100644
>> --- a/src/mesa/drivers/dri/i965/**brw_blorp_blit.cpp
>> +++ b/src/mesa/drivers/dri/i965/**brw_blorp_blit.cpp
>> @@ -50,6 +50,63 @@ fixup_mirroring(bool&mirror, GLint&coord0,
>> GLint&coord1)
>>  }
>>
>>
>> +/**
>> + * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of
>> + * destination coordinates.
>> + *
>> + * Return true if there is still blitting to do, false if all pixels got
>> + * rejected by the clip and/or scissor.
>> + *
>> + * For clarity, the nomenclature of this function assumes we are
>> clipping and
>> + * scissoring the X coordinate; the exact same logic applies for Y
>> + * coordinates.
>> + */
>> +static inline bool
>> +clip_or_scissor(bool mirror, GLint&src_x0, GLint&src_x1, GLint&dst_x0,
>> +                GLint&dst_x1, GLint fb_xmin, GLint fb_xmax)
>>
>
> Are fb_xmin and fb_xmax the dimensions of the framebuffer, or are they the
> scissor rectangle?


They're the _Xmin and _Xmax values from struct gl_framebuffer, which are
the intersection of the framebuffer bounds and the scissor rectangle (see
mtypes.h line 2626).  I'll add a comment to clarify this.


>
>
>  +{
>> +   /* If we are going to scissor everything away, stop. */
>> +   if (!(fb_xmin<  fb_xmax&&
>> +         dst_x0<  fb_xmax&&
>> +         fb_xmin<  dst_x1&&
>> +         dst_x0<  dst_x1)) {
>> +      return false;
>> +   }
>>
>
> Isn't this handled by core Mesa before execution gets into the driver?


Not that I can find.  The only checks that happen in core mesa are in
_mesa_BlitFramebufferEXT (fbobject.c), and they're all error checks (e.g.
make sure the framebuffers are complete, make sure color types are
compatible, etc.)


>
>
>  +
>> +   /* Clip the destination rectangle, and keep track of how many pixels
>> we
>> +    * clipped off of the left and right sides of it.
>> +    */
>> +   GLint pixels_clipped_left = 0;
>> +   GLint pixels_clipped_right = 0;
>> +   if (dst_x0<  fb_xmin) {
>> +      pixels_clipped_left = fb_xmin - dst_x0;
>> +      dst_x0 = fb_xmin;
>> +   }
>> +   if (fb_xmax<  dst_x1) {
>> +      pixels_clipped_right = dst_x1 - fb_xmax;
>> +      dst_x1 = fb_xmax;
>> +   }
>> +
>> +   /* If we are mirrored, then before applying
>> pixels_clipped_{left,right} to
>> +    * the source coordinates, we need to flip them to account for the
>> +    * mirroring.
>> +    */
>> +   if (mirror) {
>> +      GLint tmp = pixels_clipped_left;
>> +      pixels_clipped_left = pixels_clipped_right;
>> +      pixels_clipped_right = tmp;
>> +   }
>> +
>> +   /* Adjust the source rectangle to remove the pixels corresponding to
>> those
>> +    * that were clipped/scissored out of the destination rectangle.
>> +    */
>> +   src_x0 += pixels_clipped_left;
>> +   src_x1 -= pixels_clipped_right;
>>
>
> Is this going to cause coordinate rounding errors with linear sampling?


It would for scaling blits, but currently brw_blorp_blit.cpp only supports
1:1 blits (because that's all that is required for MSAA).


>
>
>  +
>> +   return true;
>> +}
>> +
>> +
>>  static bool
>>  try_blorp_blit(struct intel_context *intel,
>>                 GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
>> @@ -154,14 +211,19 @@ try_blorp_blit(struct intel_context *intel,
>>     if (width != dstX1 - dstX0) return false;
>>     if (height != dstY1 - dstY0) return false;
>>
>> -   /* Make sure width and height don't need to be clipped or scissored.
>> -    * TODO: support clipping and scissoring.
>> +   /* If the destination rectangle needs to be clipped or scissored, do
>> so.
>>      */
>> +   if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1,
>> +                         draw_fb->_Xmin, draw_fb->_Xmax)&&
>> +         clip_or_scissor(mirror_y, srcY0, srcY1, dstY0, dstY1,
>> +                         draw_fb->_Ymin, draw_fb->_Ymax))) {
>> +      /* Everything got clipped/scissored away, so the blit was
>> successful. */
>> +      return true;
>> +   }
>> +
>> +   /* TODO: Clipping the source rectangle is not yet implemented. */
>>     if (srcX0<  0 || (GLuint) srcX1>  read_fb->Width) return false;
>>     if (srcY0<  0 || (GLuint) srcY1>  read_fb->Height) return false;
>> -   if (dstX0<  0 || (GLuint) dstX1>  draw_fb->Width) return false;
>> -   if (dstY0<  0 || (GLuint) dstY1>  draw_fb->Height) return false;
>> -   if (ctx->Scissor.Enabled) return false;
>>
>>     /* Get ready to blit.  This includes depth resolving the src and dst
>>      * buffers if necessary.
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20120523/bc02af88/attachment.htm>


More information about the mesa-dev mailing list