freedreno/a6xx: set guardband clip
authorRob Clark <robdclark@gmail.com>
Mon, 19 Nov 2018 15:24:40 +0000 (10:24 -0500)
committerRob Clark <robdclark@gmail.com>
Tue, 27 Nov 2018 20:44:02 +0000 (15:44 -0500)
On older gens, the CLIP_ADJ bitfields were actually 3.6 fixed point.
Which might make more sense.  Although this formula comes up with values
pretty close to what blob does for various viewport sizes (for at least
a5xx and a6xx), and seems to work.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_state.c
src/gallium/drivers/freedreno/freedreno_util.h

index 4697b2f6b9a62a2230b218cc1adb938bdf86a5d8..70b93340e7729996fdeed81cad045eba1abd31a9 100644 (file)
@@ -677,12 +677,6 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
                OUT_RING(ring, A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_X(scissor->maxx - 1) |
                                A6XX_GRAS_SC_SCREEN_SCISSOR_TL_0_Y(scissor->maxy - 1));
 
-               OUT_PKT4(ring, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2);
-               OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->minx) |
-                               A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->miny));
-               OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->maxx - 1) |
-                               A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_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);
@@ -690,7 +684,8 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
        }
 
        if (dirty & FD_DIRTY_VIEWPORT) {
-               fd_wfi(ctx->batch, ring);
+               struct pipe_scissor_state *scissor = &ctx->viewport_scissor;
+
                OUT_PKT4(ring, REG_A6XX_GRAS_CL_VPORT_XOFFSET_0, 6);
                OUT_RING(ring, A6XX_GRAS_CL_VPORT_XOFFSET_0(ctx->viewport.translate[0]));
                OUT_RING(ring, A6XX_GRAS_CL_VPORT_XSCALE_0(ctx->viewport.scale[0]));
@@ -698,6 +693,19 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
                OUT_RING(ring, A6XX_GRAS_CL_VPORT_YSCALE_0(ctx->viewport.scale[1]));
                OUT_RING(ring, A6XX_GRAS_CL_VPORT_ZOFFSET_0(ctx->viewport.translate[2]));
                OUT_RING(ring, A6XX_GRAS_CL_VPORT_ZSCALE_0(ctx->viewport.scale[2]));
+
+               OUT_PKT4(ring, REG_A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0, 2);
+               OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->minx) |
+                               A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->miny));
+               OUT_RING(ring, A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_X(scissor->maxx - 1) |
+                               A6XX_GRAS_SC_VIEWPORT_SCISSOR_TL_0_Y(scissor->maxy - 1));
+
+               unsigned guardband_x = fd_calc_guardband(scissor->maxx - scissor->minx);
+               unsigned guardband_y = fd_calc_guardband(scissor->maxy - scissor->miny);
+
+               OUT_PKT4(ring, REG_A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ, 1);
+               OUT_RING(ring, A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_HORZ(guardband_x) |
+                               A6XX_GRAS_CL_GUARDBAND_CLIP_ADJ_VERT(guardband_y));
        }
 
        if (dirty & FD_DIRTY_PROG) {
index 8914489d8be9f10f753c1cf2e75525b61132eb64..3a03845b4aba14a54bed3eada330e4064f414532 100644 (file)
@@ -289,6 +289,7 @@ struct fd_context {
        struct pipe_framebuffer_state framebuffer;
        struct pipe_poly_stipple stipple;
        struct pipe_viewport_state viewport;
+       struct pipe_scissor_state viewport_scissor;
        struct fd_constbuf_stateobj constbuf[PIPE_SHADER_TYPES];
        struct fd_shaderbuf_stateobj shaderbuf[PIPE_SHADER_TYPES];
        struct fd_shaderimg_stateobj shaderimg[PIPE_SHADER_TYPES];
index 76b54a56044022dedaaf58c66e2a7a4b1cffe416..1b67cc35f14fa44610888b81750fc31e24128149 100644 (file)
@@ -288,7 +288,36 @@ fd_set_viewport_states(struct pipe_context *pctx,
                const struct pipe_viewport_state *viewport)
 {
        struct fd_context *ctx = fd_context(pctx);
+       struct pipe_scissor_state *scissor = &ctx->viewport_scissor;
+       float minx, miny, maxx, maxy;
+
        ctx->viewport = *viewport;
+
+       /* see si_get_scissor_from_viewport(): */
+
+       /* Convert (-1, -1) and (1, 1) from clip space into window space. */
+       minx = -viewport->scale[0] + viewport->translate[0];
+       miny = -viewport->scale[1] + viewport->translate[1];
+       maxx = viewport->scale[0] + viewport->translate[0];
+       maxy = viewport->scale[1] + viewport->translate[1];
+
+       /* Handle inverted viewports. */
+       if (minx > maxx) {
+               swap(minx, maxx);
+       }
+       if (miny > maxy) {
+               swap(miny, maxy);
+       }
+
+       debug_assert(miny >= 0);
+       debug_assert(maxy >= 0);
+
+       /* Convert to integer and round up the max bounds. */
+       scissor->minx = minx;
+       scissor->miny = miny;
+       scissor->maxx = ceilf(maxx);
+       scissor->maxy = ceilf(maxy);
+
        ctx->dirty |= FD_DIRTY_VIEWPORT;
 }
 
index e03f37dd627e38f2414b589f5b3b9a49715590bd..125ad83523cf3b186ebb64047183081c44524542 100644 (file)
@@ -194,6 +194,18 @@ fd_half_precision(struct pipe_framebuffer_state *pfb)
        return true;
 }
 
+/* Note sure if this is same on all gens, but seems to be same on the later
+ * gen's
+ */
+static inline unsigned
+fd_calc_guardband(unsigned x)
+{
+       float l = log2(x);
+       if (l <= 8)
+               return 511;
+       return 511 - ((l - 8) * 65);
+}
+
 #define LOG_DWORDS 0
 
 static inline void emit_marker(struct fd_ringbuffer *ring, int scratch_idx);