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

Author: Rob Clark <[email protected]>
Date:   Sat Jun  1 14:16:30 2013 -0400

freedreno: better scissor fix

Actually respect rasterizer state.

Signed-off-by: Rob Clark <[email protected]>

---

 src/gallium/drivers/freedreno/a2xx/fd2_emit.c     |   20 +++++++++++---------
 src/gallium/drivers/freedreno/a3xx/fd3_emit.c     |   20 +++++++++++---------
 src/gallium/drivers/freedreno/freedreno_context.h |   14 ++++++++++++++
 src/gallium/drivers/freedreno/freedreno_draw.c    |    5 +++--
 src/gallium/drivers/freedreno/freedreno_state.c   |   12 ++++--------
 5 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c 
b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
index 8a40f9a..b03390e 100644
--- a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
+++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c
@@ -238,17 +238,19 @@ fd2_emit_state(struct fd_context *ctx, uint32_t dirty)
        }
 
        if (dirty & FD_DIRTY_SCISSOR) {
+               struct pipe_scissor_state *scissor = 
fd_context_get_scissor(ctx);
+
                OUT_PKT3(ring, CP_SET_CONSTANT, 3);
                OUT_RING(ring, CP_REG(REG_A2XX_PA_SC_WINDOW_SCISSOR_TL));
-               OUT_RING(ring, xy2d(ctx->scissor.minx,   /* 
PA_SC_WINDOW_SCISSOR_TL */
-                               ctx->scissor.miny));
-               OUT_RING(ring, xy2d(ctx->scissor.maxx,   /* 
PA_SC_WINDOW_SCISSOR_BR */
-                               ctx->scissor.maxy));
-
-               ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, 
ctx->scissor.minx);
-               ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, 
ctx->scissor.miny);
-               ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, 
ctx->scissor.maxx);
-               ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, 
ctx->scissor.maxy);
+               OUT_RING(ring, xy2d(scissor->minx,       /* 
PA_SC_WINDOW_SCISSOR_TL */
+                               scissor->miny));
+               OUT_RING(ring, xy2d(scissor->maxx,       /* 
PA_SC_WINDOW_SCISSOR_BR */
+                               scissor->maxy));
+
+               ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, 
scissor->minx);
+               ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, 
scissor->miny);
+               ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, 
scissor->maxx);
+               ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, 
scissor->maxy);
        }
 
        if (dirty & FD_DIRTY_VIEWPORT) {
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c 
b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 1d048b0..a7a4bf7 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -401,16 +401,18 @@ fd3_emit_state(struct fd_context *ctx, uint32_t dirty)
        }
 
        if (dirty & FD_DIRTY_SCISSOR) {
+               struct pipe_scissor_state *scissor = 
fd_context_get_scissor(ctx);
+
                OUT_PKT0(ring, REG_A3XX_GRAS_SC_WINDOW_SCISSOR_TL, 2);
-               OUT_RING(ring, 
A3XX_GRAS_SC_WINDOW_SCISSOR_TL_X(ctx->scissor.minx) |
-                               
A3XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(ctx->scissor.miny));
-               OUT_RING(ring, 
A3XX_GRAS_SC_WINDOW_SCISSOR_BR_X(ctx->scissor.maxx - 1) |
-                               
A3XX_GRAS_SC_WINDOW_SCISSOR_BR_Y(ctx->scissor.maxy - 1));
-
-               ctx->max_scissor.minx = MIN2(ctx->max_scissor.minx, 
ctx->scissor.minx);
-               ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, 
ctx->scissor.miny);
-               ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, 
ctx->scissor.maxx);
-               ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, 
ctx->scissor.maxy);
+               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->max_scissor.minx = MIN2(ctx->max_scissor.minx, 
scissor->minx);
+               ctx->max_scissor.miny = MIN2(ctx->max_scissor.miny, 
scissor->miny);
+               ctx->max_scissor.maxx = MAX2(ctx->max_scissor.maxx, 
scissor->maxx);
+               ctx->max_scissor.maxy = MAX2(ctx->max_scissor.maxy, 
scissor->maxy);
        }
 
        if (dirty & FD_DIRTY_VIEWPORT) {
diff --git a/src/gallium/drivers/freedreno/freedreno_context.h 
b/src/gallium/drivers/freedreno/freedreno_context.h
index 5475931..3d18260 100644
--- a/src/gallium/drivers/freedreno/freedreno_context.h
+++ b/src/gallium/drivers/freedreno/freedreno_context.h
@@ -139,6 +139,12 @@ struct fd_context {
 
        struct pipe_scissor_state scissor;
 
+       /* we don't have a disable/enable bit for scissor, so instead we keep
+        * a disabled-scissor state which matches the entire bound framebuffer
+        * and use that when scissor is not enabled.
+        */
+       struct pipe_scissor_state disabled_scissor;
+
        /* Track the maximal bounds of the scissor of all the draws within a
         * batch.  Used at the tile rendering step (fd_gmem_render_tiles(),
         * mem2gmem/gmem2mem) to avoid needlessly moving data in/out of gmem.
@@ -218,6 +224,14 @@ fd_context(struct pipe_context *pctx)
        return (struct fd_context *)pctx;
 }
 
+static INLINE struct pipe_scissor_state *
+fd_context_get_scissor(struct fd_context *ctx)
+{
+       if (ctx->rasterizer && ctx->rasterizer->scissor)
+               return &ctx->scissor;
+       return &ctx->disabled_scissor;
+}
+
 struct pipe_context * fd_context_init(struct fd_context *ctx,
                struct pipe_screen *pscreen, void *priv);
 
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c 
b/src/gallium/drivers/freedreno/freedreno_draw.c
index dbdf573..b02b8b9 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -114,11 +114,12 @@ fd_draw_vbo(struct pipe_context *pctx, const struct 
pipe_draw_info *info)
 {
        struct fd_context *ctx = fd_context(pctx);
        struct pipe_framebuffer_state *pfb = &ctx->framebuffer;
+       struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
        unsigned i, buffers = 0;
 
        /* if we supported transform feedback, we'd have to disable this: */
-       if (((ctx->scissor.maxx - ctx->scissor.minx) *
-                       (ctx->scissor.maxy - ctx->scissor.miny)) == 0) {
+       if (((scissor->maxx - scissor->minx) *
+                       (scissor->maxy - scissor->miny)) == 0) {
                return;
        }
 
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c 
b/src/gallium/drivers/freedreno/freedreno_state.c
index 1003197..2f5d52c 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -137,14 +137,10 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
 
        ctx->dirty |= FD_DIRTY_FRAMEBUFFER;
 
-       /* also need to reset the scissor.. mesa/gl state tracker
-        * does this for us, but u_blitter doesn't and other
-        * state trackers might not..
-        */
-       ctx->scissor.minx = 0;
-       ctx->scissor.miny = 0;
-       ctx->scissor.maxx = cso->width;
-       ctx->scissor.maxy = cso->height;
+       ctx->disabled_scissor.minx = 0;
+       ctx->disabled_scissor.miny = 0;
+       ctx->disabled_scissor.maxx = cso->width;
+       ctx->disabled_scissor.maxy = cso->height;
 
        ctx->dirty |= FD_DIRTY_SCISSOR;
 }

_______________________________________________
mesa-commit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to