On 22 May 2012 11:08, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="HOEnZb"><div class="h5">On 05/14/2012 03:47 PM, Paul Berry wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This patch implements clipping and scissoring of the destination rect<br>
for blits that use the blorp engine (e.g. MSAA blits).<br>
---<br>
src/mesa/drivers/dri/i965/brw_<u></u>blorp_blit.cpp | 72 ++++++++++++++++++++++++--<br>
1 files changed, 67 insertions(+), 5 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
index ee65cd6..223d8c1 100644<br>
--- a/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
+++ b/src/mesa/drivers/dri/i965/<u></u>brw_blorp_blit.cpp<br>
@@ -50,6 +50,63 @@ fixup_mirroring(bool&mirror, GLint&coord0, GLint&coord1)<br>
}<br>
<br>
<br>
+/**<br>
+ * Adjust {src,dst}_x{0,1} to account for clipping and scissoring of<br>
+ * destination coordinates.<br>
+ *<br>
+ * Return true if there is still blitting to do, false if all pixels got<br>
+ * rejected by the clip and/or scissor.<br>
+ *<br>
+ * For clarity, the nomenclature of this function assumes we are clipping and<br>
+ * scissoring the X coordinate; the exact same logic applies for Y<br>
+ * coordinates.<br>
+ */<br>
+static inline bool<br>
+clip_or_scissor(bool mirror, GLint&src_x0, GLint&src_x1, GLint&dst_x0,<br>
+ GLint&dst_x1, GLint fb_xmin, GLint fb_xmax)<br>
</blockquote>
<br></div></div>
Are fb_xmin and fb_xmax the dimensions of the framebuffer, or are they the scissor rectangle?</blockquote><div><br>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.<br>
</div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+{<br>
+ /* If we are going to scissor everything away, stop. */<br>
+ if (!(fb_xmin< fb_xmax&&<br>
+ dst_x0< fb_xmax&&<br>
+ fb_xmin< dst_x1&&<br>
+ dst_x0< dst_x1)) {<br>
+ return false;<br>
+ }<br>
</blockquote>
<br></div>
Isn't this handled by core Mesa before execution gets into the driver?</blockquote><div><br>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.)<br>
</div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ /* Clip the destination rectangle, and keep track of how many pixels we<br>
+ * clipped off of the left and right sides of it.<br>
+ */<br>
+ GLint pixels_clipped_left = 0;<br>
+ GLint pixels_clipped_right = 0;<br>
+ if (dst_x0< fb_xmin) {<br>
+ pixels_clipped_left = fb_xmin - dst_x0;<br>
+ dst_x0 = fb_xmin;<br>
+ }<br>
+ if (fb_xmax< dst_x1) {<br>
+ pixels_clipped_right = dst_x1 - fb_xmax;<br>
+ dst_x1 = fb_xmax;<br>
+ }<br>
+<br>
+ /* If we are mirrored, then before applying pixels_clipped_{left,right} to<br>
+ * the source coordinates, we need to flip them to account for the<br>
+ * mirroring.<br>
+ */<br>
+ if (mirror) {<br>
+ GLint tmp = pixels_clipped_left;<br>
+ pixels_clipped_left = pixels_clipped_right;<br>
+ pixels_clipped_right = tmp;<br>
+ }<br>
+<br>
+ /* Adjust the source rectangle to remove the pixels corresponding to those<br>
+ * that were clipped/scissored out of the destination rectangle.<br>
+ */<br>
+ src_x0 += pixels_clipped_left;<br>
+ src_x1 -= pixels_clipped_right;<br>
</blockquote>
<br></div></div>
Is this going to cause coordinate rounding errors with linear sampling?</blockquote><div><br>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).<br>
</div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ return true;<br>
+}<br>
+<br>
+<br>
static bool<br>
try_blorp_blit(struct intel_context *intel,<br>
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,<br>
@@ -154,14 +211,19 @@ try_blorp_blit(struct intel_context *intel,<br>
if (width != dstX1 - dstX0) return false;<br>
if (height != dstY1 - dstY0) return false;<br>
<br>
- /* Make sure width and height don't need to be clipped or scissored.<br>
- * TODO: support clipping and scissoring.<br>
+ /* If the destination rectangle needs to be clipped or scissored, do so.<br>
*/<br>
+ if (!(clip_or_scissor(mirror_x, srcX0, srcX1, dstX0, dstX1,<br>
+ draw_fb->_Xmin, draw_fb->_Xmax)&&<br>
+ clip_or_scissor(mirror_y, srcY0, srcY1, dstY0, dstY1,<br>
+ draw_fb->_Ymin, draw_fb->_Ymax))) {<br>
+ /* Everything got clipped/scissored away, so the blit was successful. */<br>
+ return true;<br>
+ }<br>
+<br>
+ /* TODO: Clipping the source rectangle is not yet implemented. */<br>
if (srcX0< 0 || (GLuint) srcX1> read_fb->Width) return false;<br>
if (srcY0< 0 || (GLuint) srcY1> read_fb->Height) return false;<br>
- if (dstX0< 0 || (GLuint) dstX1> draw_fb->Width) return false;<br>
- if (dstY0< 0 || (GLuint) dstY1> draw_fb->Height) return false;<br>
- if (ctx->Scissor.Enabled) return false;<br>
<br>
/* Get ready to blit. This includes depth resolving the src and dst<br>
* buffers if necessary.<br>
</blockquote>
<br>
</div></div></blockquote></div><br>