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;
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;
}
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;
}
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) {
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
+ rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF;
+
return (void*)rs;
}
{
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);
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. */
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,