summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2013-06-01 14:16:30 -0400
committerRob Clark <[email protected]>2013-06-08 13:15:51 -0400
commite9edbf0a688c68ef0896e5d4278f411f6b6f8398 (patch)
treebd6ce7e7ae737c5fdefac62aa3c10b3be3029125
parent4af1dcbb7d5431ae75cc39568c99d7a20231f081 (diff)
freedreno: better scissor fix
Actually respect rasterizer state. Signed-off-by: Rob Clark <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/a2xx/fd2_emit.c20
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c20
-rw-r--r--src/gallium/drivers/freedreno/freedreno_context.h14
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.c5
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.c12
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 8a40f9ab7ab..b03390ec436 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 1d048b08c83..a7a4bf78d62 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 54759314e26..3d18260445f 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 dbdf5732658..b02b8b9f9f9 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 10031977e61..2f5d52c017c 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;
}