i965: Disable the GB clip test when a limited viewport is set.
authorEric Anholt <eric@anholt.net>
Thu, 15 Nov 2012 20:00:33 +0000 (12:00 -0800)
committerEric Anholt <eric@anholt.net>
Tue, 20 Nov 2012 06:33:44 +0000 (22:33 -0800)
The theory of the guardband is that you extend the clip volume to avoid
expensive clipping computation, and just let fragments outside the viewport
get clipped by the drawable's bounds.  But if a smaller-than-window-size
viewport is set, and we don't also happen to have a scissor set, then
rendering could incorrectly extend outside of the viewport when it should have
been clipped to the viewport.

Fixes the new piglit triangle-guardband-viewport test.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
NOTE: This is a candidate for the 9.0 branch.

src/mesa/drivers/dri/i965/gen6_clip_state.c
src/mesa/drivers/dri/i965/gen7_clip_state.c

index 63c58656416f905b4b21af6ecb208dcb8b7cffec..51ffbae279f10671f53423d76e546036e6a5891b 100644 (file)
@@ -30,6 +30,7 @@
 #include "brw_defines.h"
 #include "brw_util.h"
 #include "intel_batchbuffer.h"
+#include "main/fbobject.h"
 
 static void
 upload_clip_state(struct brw_context *brw)
@@ -38,6 +39,9 @@ upload_clip_state(struct brw_context *brw)
    struct gl_context *ctx = &intel->ctx;
    uint32_t dw2 = 0;
 
+   /* _NEW_BUFFERS */
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+
    /* CACHE_NEW_WM_PROG */
    if (brw->wm.prog_data->barycentric_interp_modes &
        BRW_WM_NONPERSPECTIVE_BARYCENTRIC_BITS) {
@@ -64,6 +68,13 @@ upload_clip_state(struct brw_context *brw)
    dw2 |= (ctx->Transform.ClipPlanesEnabled <<
            GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT);
 
+   if (ctx->Viewport.X == 0 &&
+       ctx->Viewport.Y == 0 &&
+       ctx->Viewport.Width == fb->Width &&
+       ctx->Viewport.Height == fb->Height) {
+      dw2 |= GEN6_CLIP_GB_TEST;
+   }
+
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2));
    OUT_BATCH(GEN6_CLIP_STATISTICS_ENABLE);
@@ -71,7 +82,6 @@ upload_clip_state(struct brw_context *brw)
             GEN6_CLIP_API_OGL |
             GEN6_CLIP_MODE_NORMAL |
             GEN6_CLIP_XY_TEST |
-            GEN6_CLIP_GB_TEST |
             dw2);
    OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
              U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |
@@ -81,7 +91,7 @@ upload_clip_state(struct brw_context *brw)
 
 const struct brw_tracked_state gen6_clip_state = {
    .dirty = {
-      .mesa  = _NEW_TRANSFORM | _NEW_LIGHT,
+      .mesa  = _NEW_TRANSFORM | _NEW_LIGHT | _NEW_BUFFERS,
       .brw   = (BRW_NEW_CONTEXT),
       .cache = CACHE_NEW_WM_PROG
    },
index e82a3390208b92b5619858a8e442f636e597de24..29a5ed571725d2d3b3e6a40f0141142f0a68efb5 100644 (file)
@@ -91,6 +91,13 @@ upload_clip_state(struct brw_context *brw)
    dw2 |= (ctx->Transform.ClipPlanesEnabled <<
            GEN6_USER_CLIP_CLIP_DISTANCES_SHIFT);
 
+   if (ctx->Viewport.X == 0 &&
+       ctx->Viewport.Y == 0 &&
+       ctx->Viewport.Width == fb->Width &&
+       ctx->Viewport.Height == fb->Height) {
+      dw2 |= GEN6_CLIP_GB_TEST;
+   }
+
    BEGIN_BATCH(4);
    OUT_BATCH(_3DSTATE_CLIP << 16 | (4 - 2));
    OUT_BATCH(dw1);
@@ -98,7 +105,6 @@ upload_clip_state(struct brw_context *brw)
             GEN6_CLIP_API_OGL |
             GEN6_CLIP_MODE_NORMAL |
             GEN6_CLIP_XY_TEST |
-            GEN6_CLIP_GB_TEST |
              dw2);
    OUT_BATCH(U_FIXED(0.125, 3) << GEN6_CLIP_MIN_POINT_WIDTH_SHIFT |
              U_FIXED(255.875, 3) << GEN6_CLIP_MAX_POINT_WIDTH_SHIFT |