summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/r300_context.h11
-rw-r--r--src/gallium/drivers/r300/r300_emit.c19
-rw-r--r--src/gallium/drivers/r300/r300_state.c73
3 files changed, 57 insertions, 46 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 11cd9f855f3..23ea32c57ed 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -98,11 +98,14 @@ struct r300_sampler_state {
unsigned min_lod, max_lod;
};
+struct r300_scissor_regs {
+ uint32_t top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */
+ uint32_t bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+};
+
struct r300_scissor_state {
- uint32_t scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */
- uint32_t scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
- uint32_t no_scissor_top_left; /* R300_SC_SCISSORS_TL: 0x43e0 */
- uint32_t no_scissor_bottom_right; /* R300_SC_SCISSORS_BR: 0x43e4 */
+ struct r300_scissor_regs framebuffer;
+ struct r300_scissor_regs scissor;
};
struct r300_texture_state {
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 04dca292167..dbf316a9b57 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -563,21 +563,26 @@ void r300_emit_rs_block_state(struct r300_context* r300,
END_CS;
}
-void r300_emit_scissor_state(struct r300_context* r300,
- struct r300_scissor_state* scissor)
+static void r300_emit_scissor_regs(struct r300_context* r300,
+ struct r300_scissor_regs* scissor)
{
CS_LOCALS(r300);
BEGIN_CS(3);
OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
+ OUT_CS(scissor->top_left);
+ OUT_CS(scissor->bottom_right);
+ END_CS;
+}
+
+void r300_emit_scissor_state(struct r300_context* r300,
+ struct r300_scissor_state* scissor)
+{
if (r300->rs_state->rs.scissor) {
- OUT_CS(scissor->scissor_top_left);
- OUT_CS(scissor->scissor_bottom_right);
+ r300_emit_scissor_regs(r300, &scissor->scissor);
} else {
- OUT_CS(scissor->no_scissor_top_left);
- OUT_CS(scissor->no_scissor_bottom_right);
+ r300_emit_scissor_regs(r300, &scissor->framebuffer);
}
- END_CS;
}
void r300_emit_texture(struct r300_context* r300,
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 2bc2b79c021..d3233557cea 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -289,11 +289,34 @@ static void r300_set_edgeflags(struct pipe_context* pipe,
/* XXX and even worse, I have no idea WTF the bitfield is */
}
+static void r300_set_scissor_regs(const struct pipe_scissor_state* state,
+ struct r300_scissor_regs *scissor,
+ boolean is_r500)
+{
+ if (is_r500) {
+ scissor->top_left =
+ (state->minx << R300_SCISSORS_X_SHIFT) |
+ (state->miny << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
+ ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
+ } else {
+ /* Offset of 1440 in non-R500 chipsets. */
+ scissor->top_left =
+ ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
+ ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
+ scissor->bottom_right =
+ (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+ }
+}
+
static void
r300_set_framebuffer_state(struct pipe_context* pipe,
const struct pipe_framebuffer_state* state)
{
struct r300_context* r300 = r300_context(pipe);
+ struct pipe_scissor_state scissor;
if (r300->draw) {
draw_flush(r300->draw);
@@ -301,26 +324,17 @@ static void
r300->framebuffer_state = *state;
- r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
+ scissor.minx = scissor.miny = 0;
+ scissor.maxx = state->width;
+ scissor.maxy = state->height;
+ r300_set_scissor_regs(&scissor, &r300->scissor_state->framebuffer,
+ r300_screen(r300->context.screen)->caps->is_r500);
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- r300->scissor_state->no_scissor_top_left =
- (0 << R300_SCISSORS_X_SHIFT) |
- (0 << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->no_scissor_bottom_right =
- ((state->width - 1) << R300_SCISSORS_X_SHIFT) |
- ((state->height - 1) << R300_SCISSORS_Y_SHIFT);
- } else {
- /* Offset of 1440 in non-R500 chipsets. */
- r300->scissor_state->no_scissor_top_left =
- ((0 + 1440) << R300_SCISSORS_X_SHIFT) |
- ((0 + 1440) << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->no_scissor_bottom_right =
- (((state->width - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
- (((state->height - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || !r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
}
-
- r300->dirty_state |= R300_NEW_SCISSOR;
+ r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
}
/* Create fragment shader state. */
@@ -642,24 +656,13 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- r300->scissor_state->scissor_top_left =
- (state->minx << R300_SCISSORS_X_SHIFT) |
- (state->miny << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
- ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
- } else {
- /* Offset of 1440 in non-R500 chipsets. */
- r300->scissor_state->scissor_top_left =
- ((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
- ((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
- r300->scissor_state->scissor_bottom_right =
- (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
- (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
- }
+ r300_set_scissor_regs(state, &r300->scissor_state->scissor,
+ r300_screen(r300->context.screen)->caps->is_r500);
- r300->dirty_state |= R300_NEW_SCISSOR;
+ /* Don't rely on the order of states being set for the first time. */
+ if (!r300->rs_state || r300->rs_state->rs.scissor) {
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ }
}
static void r300_set_viewport_state(struct pipe_context* pipe,