Mesa (master): r300g: use cliprects for scissoring

Marek Olšák mareko at kemper.freedesktop.org
Sun Apr 11 01:16:56 PDT 2010


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

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Apr 11 08:27:33 2010 +0200

r300g: use cliprects for scissoring

Cliprects can be disabled, scissors can't. It maps nicely to hardware.

---

 src/gallium/drivers/r300/r300_context.h         |    3 +-
 src/gallium/drivers/r300/r300_emit.c            |   71 +++++++----------------
 src/gallium/drivers/r300/r300_state.c           |   20 ++-----
 src/gallium/drivers/r300/r300_state_invariant.c |    6 +--
 4 files changed, 29 insertions(+), 71 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index fc186df..e3dd6de 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -105,6 +105,7 @@ struct r300_rs_state {
     uint32_t line_stipple_value;    /* R300_GA_LINE_STIPPLE_VALUE: 0x4260 */
     uint32_t color_control;         /* R300_GA_COLOR_CONTROL: 0x4278 */
     uint32_t polygon_mode;          /* R300_GA_POLY_MODE: 0x4288 */
+    uint32_t clip_rule;             /* R300_SC_CLIP_RULE: 0x43D0 */
 };
 
 struct r300_rs_block {
@@ -410,8 +411,6 @@ struct r300_context {
     boolean polygon_offset_enabled;
     /* Z buffer bit depth. */
     uint32_t zbuffer_bpp;
-    /* Whether scissor is enabled. */
-    boolean scissor_enabled;
     /* Whether rendering is conditional and should be skipped. */
     boolean skip_rendering;
     /* Whether the two-sided stencil ref value is different for front and
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 771aaf8..60ec164 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -438,6 +438,17 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
                      0, RADEON_GEM_DOMAIN_VRAM, 0);
     }
 
+    OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
+    if (r300->screen->caps.is_r500) {
+        OUT_CS(0);
+        OUT_CS(((fb->width  - 1) << R300_SCISSORS_X_SHIFT) |
+               ((fb->height - 1) << R300_SCISSORS_Y_SHIFT));
+    } else {
+        OUT_CS((1440 << R300_SCISSORS_X_SHIFT) |
+               (1440 << R300_SCISSORS_Y_SHIFT));
+        OUT_CS(((fb->width  + 1440-1) << R300_SCISSORS_X_SHIFT) |
+               ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT));
+    }
     OUT_CS_REG(R300_GA_POINT_MINMAX,
         (MAX2(fb->width, fb->height) * 6) << R300_GA_POINT_MINMAX_MAX_SHIFT);
     END_CS;
@@ -608,6 +619,7 @@ void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)
     OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
     OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value);
     OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode);
+    OUT_CS_REG(R300_SC_CLIP_RULE, rs->clip_rule);
     END_CS;
 }
 
@@ -656,61 +668,22 @@ void r300_emit_rs_block_state(struct r300_context* r300,
 void r300_emit_scissor_state(struct r300_context* r300,
                              unsigned size, void* state)
 {
-    unsigned minx, miny, maxx, maxy;
-    uint32_t top_left, bottom_right;
     struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state;
-    struct pipe_framebuffer_state* fb =
-        (struct pipe_framebuffer_state*)r300->fb_state.state;
     CS_LOCALS(r300);
 
-    minx = miny = 0;
-    maxx = fb->width;
-    maxy = fb->height;
-
-    if (r300->scissor_enabled) {
-        minx = MAX2(minx, scissor->minx);
-        miny = MAX2(miny, scissor->miny);
-        maxx = MIN2(maxx, scissor->maxx);
-        maxy = MIN2(maxy, scissor->maxy);
-    }
-
-    /* Special case for zero-area scissor.
-     *
-     * We can't allow the variables maxx and maxy to be zero because they are
-     * subtracted from later in the code, which would cause emitting ~0 and
-     * making the kernel checker angry.
-     *
-     * Let's consider we change maxx and maxy to 1, which is effectively
-     * a one-pixel area. We must then change minx and miny to a number which is
-     * greater than 1 to get the zero area back. */
-    if (!maxx || !maxy) {
-        minx = 2;
-        miny = 2;
-        maxx = 1;
-        maxy = 1;
-    }
-
+    BEGIN_CS(size);
+    OUT_CS_REG_SEQ(R300_SC_CLIPRECT_TL_0, 2);
     if (r300->screen->caps.is_r500) {
-        top_left =
-            (minx << R300_SCISSORS_X_SHIFT) |
-            (miny << R300_SCISSORS_Y_SHIFT);
-        bottom_right =
-            ((maxx - 1) << R300_SCISSORS_X_SHIFT) |
-            ((maxy - 1) << R300_SCISSORS_Y_SHIFT);
+        OUT_CS((scissor->minx << R300_CLIPRECT_X_SHIFT) |
+               (scissor->miny << R300_CLIPRECT_Y_SHIFT));
+        OUT_CS(((scissor->maxx - 1) << R300_CLIPRECT_X_SHIFT) |
+               ((scissor->maxy - 1) << R300_CLIPRECT_Y_SHIFT));
     } else {
-        /* Offset of 1440 in non-R500 chipsets. */
-        top_left =
-            ((minx + 1440) << R300_SCISSORS_X_SHIFT) |
-            ((miny + 1440) << R300_SCISSORS_Y_SHIFT);
-        bottom_right =
-            (((maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
-            (((maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+        OUT_CS(((scissor->minx + 1440) << R300_CLIPRECT_X_SHIFT) |
+               ((scissor->miny + 1440) << R300_CLIPRECT_Y_SHIFT));
+        OUT_CS(((scissor->maxx + 1440-1) << R300_CLIPRECT_X_SHIFT) |
+               ((scissor->maxy + 1440-1) << R300_CLIPRECT_Y_SHIFT));
     }
-
-    BEGIN_CS(size);
-    OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
-    OUT_CS(top_left);
-    OUT_CS(bottom_right);
     END_CS;
 }
 
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index f549b45..95ce1a9 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -641,16 +641,13 @@ static void
     if (!!old_state->zsbuf != !!state->zsbuf) {
         r300->dsa_state.dirty = TRUE;
     }
-    if (!r300->scissor_enabled) {
-        r300->scissor_state.dirty = TRUE;
-    }
 
     r300_fb_update_tiling_flags(r300, r300->fb_state.state, state);
 
     memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state));
 
     r300->fb_state.size = (10 * state->nr_cbufs) + (2 * (4 - state->nr_cbufs)) +
-                          (state->zsbuf ? 10 : 0) + 8;
+                          (state->zsbuf ? 10 : 0) + 11;
 
     /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {
@@ -836,6 +833,8 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
         rs->color_control = R300_SHADE_MODEL_SMOOTH;
     }
 
+    rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+
     return (void*)rs;
 }
 
@@ -844,7 +843,6 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
 {
     struct r300_context* r300 = r300_context(pipe);
     struct r300_rs_state* rs = (struct r300_rs_state*)state;
-    boolean scissor_was_enabled = r300->scissor_enabled;
 
     if (r300->draw) {
         draw_flush(r300->draw);
@@ -853,18 +851,12 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
 
     if (rs) {
         r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw;
-        r300->scissor_enabled = rs->rs.scissor;
     } else {
         r300->polygon_offset_enabled = FALSE;
-        r300->scissor_enabled = FALSE;
     }
 
     UPDATE_STATE(state, r300->rs_state);
-    r300->rs_state.size = 17 + (r300->polygon_offset_enabled ? 5 : 0);
-
-    if (scissor_was_enabled != r300->scissor_enabled) {
-        r300->scissor_state.dirty = TRUE;
-    }
+    r300->rs_state.size = 19 + (r300->polygon_offset_enabled ? 5 : 0);
 }
 
 /* Free rasterizer state. */
@@ -1070,9 +1062,7 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
     memcpy(r300->scissor_state.state, state,
         sizeof(struct pipe_scissor_state));
 
-    if (r300->scissor_enabled) {
-        r300->scissor_state.dirty = TRUE;
-    }
+    r300->scissor_state.dirty = TRUE;
 }
 
 static void r300_set_viewport_state(struct pipe_context* pipe,
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 4685ec4..a8cd2f5 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -78,7 +78,7 @@ void r300_emit_invariant_state(struct r300_context* r300,
     END_CS;
 
     /* XXX unsorted stuff from surface_fill */
-    BEGIN_CS(44 + (caps->has_tcl ? 7 : 0) +
+    BEGIN_CS(42 + (caps->has_tcl ? 7 : 0) +
              (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0));
 
     if (caps->has_tcl) {
@@ -125,9 +125,5 @@ void r300_emit_invariant_state(struct r300_context* r300,
     OUT_CS_REG(R300_ZB_DEPTHCLEARVALUE, 0x00000000);
     OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0x00000000);
     OUT_CS_REG(R300_ZB_HIZ_PITCH, 0x00000000);
-
-    /* XXX */
-    OUT_CS_REG(R300_SC_CLIP_RULE, 0xFFFF);
-
     END_CS;
 }



More information about the mesa-commit mailing list