summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-08-30 22:42:24 -0400
committerIlia Mirkin <[email protected]>2016-09-03 19:58:42 -0400
commitca313e00b6eda27e4308c29fd7244f43c77d4f97 (patch)
treed4df2692f56786ac669a56591b946e1e46bc6c96
parent83d7230fd5ab69e7e111e3a02e604e65922fb171 (diff)
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 <[email protected]> Cc: [email protected]
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c36
1 files 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 7945184d8f0..6d223c05c10 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) {