From 08afcaa56e187cdd137a5c6581c265c1a0fc8d18 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sun, 11 Apr 2010 08:27:33 +0200 Subject: [PATCH] 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 ++---- .../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 fc186df640e..e3dd6de5c72 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 771aaf8d224..60ec164dde9 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 f549b453ee5..95ce1a9600d 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 4685ec47614..a8cd2f5b315 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; } -- 2.30.2