diff options
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 36 |
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) { |