Mesa (master): a3xx: use window scissor to simulate viewport xy clip

Ilia Mirkin imirkin at kemper.freedesktop.org
Sun Sep 4 00:06:09 UTC 2016


Module: Mesa
Branch: master
Commit: ca313e00b6eda27e4308c29fd7244f43c77d4f97
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ca313e00b6eda27e4308c29fd7244f43c77d4f97

Author: Ilia Mirkin <imirkin at alum.mit.edu>
Date:   Tue Aug 30 22:42:24 2016 -0400

a3xx: use window scissor to simulate viewport xy clip

Unfortunately a3xx does not have a separate disable for depth clipping,
so when depth clamp is enabled, we disable the whole 3d clipper logic.
This in turn also gets rid of the xy clip that it would normally do.
When we detect this would happen, instead we integrate the viewport into
the window scissor. This may have slightly different behavior around
wide points, but it's unlikely that anything depends on this.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=97231
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
Cc: mesa-stable at lists.freedesktop.org

---

 src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 36 +++++++++++++++++++--------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 7945184..6d223c0 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -629,19 +629,35 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
 		OUT_RING(ring, val);
 	}
 
-	if (dirty & FD_DIRTY_SCISSOR) {
+	if (dirty & (FD_DIRTY_SCISSOR | FD_DIRTY_RASTERIZER | FD_DIRTY_VIEWPORT)) {
 		struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
+		int minx = scissor->minx;
+		int miny = scissor->miny;
+		int maxx = scissor->maxx;
+		int maxy = scissor->maxy;
+
+		/* Unfortunately there is no separate depth clip disable, only an all
+		 * or nothing deal. So when we disable clipping, we must handle the
+		 * viewport clip via scissors.
+		 */
+		if (!ctx->rasterizer->depth_clip) {
+			struct pipe_viewport_state *vp = &ctx->viewport;
+			minx = MAX2(minx, (int)floorf(vp->translate[0] - fabsf(vp->scale[0])));
+			miny = MAX2(miny, (int)floorf(vp->translate[1] - fabsf(vp->scale[1])));
+			maxx = MIN2(maxx, (int)ceilf(vp->translate[0] + fabsf(vp->scale[0])));
+			maxy = MIN2(maxy, (int)ceilf(vp->translate[1] + fabsf(vp->scale[1])));
+		}
 
 		OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
-		OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(scissor->minx) |
-				A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(scissor->miny));
-		OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(scissor->maxx - 1) |
-				A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(scissor->maxy - 1));
-
-		ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, scissor->minx);
-		ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, scissor->miny);
-		ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, scissor->maxx);
-		ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, scissor->maxy);
+		OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(minx) |
+				A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(miny));
+		OUT_RING(ring, A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(maxx - 1) |
+				A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(maxy - 1));
+
+		ctx->batch->max_scissor.minx = MIN2(ctx->batch->max_scissor.minx, minx);
+		ctx->batch->max_scissor.miny = MIN2(ctx->batch->max_scissor.miny, miny);
+		ctx->batch->max_scissor.maxx = MAX2(ctx->batch->max_scissor.maxx, maxx);
+		ctx->batch->max_scissor.maxy = MAX2(ctx->batch->max_scissor.maxy, maxy);
 	}
 
 	if (dirty & FD_DIRTY_VIEWPORT) {




More information about the mesa-commit mailing list