diff options
-rw-r--r-- | src/mesa/drivers/dri/i965/gen6_clip_state.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/gen6_clip_state.c b/src/mesa/drivers/dri/i965/gen6_clip_state.c index e8c1b915172..ab0828135be 100644 --- a/src/mesa/drivers/dri/i965/gen6_clip_state.c +++ b/src/mesa/drivers/dri/i965/gen6_clip_state.c @@ -98,6 +98,37 @@ upload_clip_state(struct brw_context *brw) dw2 |= GEN6_CLIP_GB_TEST; + /* We need to disable guardband clipping if the guardband (which we always + * program to the maximum screen-space bounding box of 8K x 8K) will be + * smaller than the viewport. + * + * Closely examining the clip determination formulas in the documentation + * reveals that objects will be discarded entirely if they're outside the + * (small) guardband, even if they're within the (large) viewport: + * + * TR = TR_GB || TR_VPXY || TR_VPZ || TR_UC || TR_NEGW + * TA = !TR && TA_GB && TA_VPZ && TA_NEGW + * MC = !(TA || TR) + * + * (TA is "Trivial Accept", TR is "Trivial Reject", MC is "Must Clip".) + * + * Disabling guardband clipping removes the TR_GB condition, which means + * they'll be considered MC ("Must Clip") unless they're rejected for + * some other reason. + * + * Note that there is no TA_VPXY condition. If there were, objects entirely + * inside a 16384x16384 viewport would be trivially accepted, breaking the + * "objects must have a screenspace bounding box not exceeding 8K in the X + * or Y direction" restriction. Instead, they're clipped. + */ + for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) { + if (ctx->ViewportArray[i].Width > 8192 || + ctx->ViewportArray[i].Height > 8192) { + dw2 &= ~GEN6_CLIP_GB_TEST; + break; + } + } + /* If the viewport dimensions are smaller than the drawable dimensions, * we have to disable guardband clipping prior to Gen8. We always program * the guardband to a fixed size, which is almost always larger than the |