summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Olšák <maraeo@gmail.com>2010-05-08 22:50:49 +0200
committerMarek Olšák <maraeo@gmail.com>2010-05-08 23:19:33 +0200
commitd044ecbe7625af1118655bcc9dba7ed00342534f (patch)
tree00f52655b66333a9e03f09f3a14465dc1a6fd6dc
parent084580fa43320b1a0878b572c6804aa5a40b2f9d (diff)
r300g: follow pipe_rasterizer_state::light_twoside
-rw-r--r--src/gallium/drivers/r300/r300_context.h2
-rw-r--r--src/gallium/drivers/r300/r300_state.c6
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c24
3 files changed, 27 insertions, 5 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index dd16565c56..4b401a7040 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -442,6 +442,8 @@ struct r300_context {
boolean stencil_ref_bf_fallback;
/* Point sprites texcoord index, 1 bit per texcoord */
int sprite_coord_enable;
+ /* Whether two-sided color selection is enabled (AKA light_twoside). */
+ boolean two_sided_color;
/* upload managers */
struct u_upload_mgr *upload_vb;
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 1344415861..399099785c 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -870,6 +870,7 @@ 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;
int last_sprite_coord_enable = r300->sprite_coord_enable;
+ boolean last_two_sided_color = r300->two_sided_color;
if (r300->draw) {
draw_flush(r300->draw);
@@ -879,15 +880,18 @@ 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->sprite_coord_enable = rs->rs.sprite_coord_enable;
+ r300->two_sided_color = rs->rs.light_twoside;
} else {
r300->polygon_offset_enabled = FALSE;
r300->sprite_coord_enable = 0;
+ r300->two_sided_color = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
r300->rs_state.size = 27 + (r300->polygon_offset_enabled ? 5 : 0);
- if (last_sprite_coord_enable != r300->sprite_coord_enable) {
+ if (last_sprite_coord_enable != r300->sprite_coord_enable ||
+ last_two_sided_color != r300->two_sided_color) {
r300->rs_block_state.dirty = TRUE;
}
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 193a60c034..c738899827 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -355,10 +355,26 @@ static void r300_update_rs_block(struct r300_context *r300)
/* Set up back-face colors. The rasterizer will do the color selection
* automatically. */
if (any_bcolor_used) {
- for (i = 0; i < ATTR_COLOR_COUNT; i++) {
- rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
- rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
- stream_loc_notcl[loc++] = 4 + i;
+ if (r300->two_sided_color) {
+ /* Rasterize as back-face colors. */
+ for (i = 0; i < ATTR_COLOR_COUNT; i++) {
+ rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
+ rs.vap_out_vtx_fmt[0] |= R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << (2+i);
+ stream_loc_notcl[loc++] = 4 + i;
+ }
+ } else {
+ /* Rasterize two fake texcoords to prevent from the two-sided color
+ * selection. */
+ /* XXX Consider recompiling the vertex shader to save 2 RS units. */
+ for (i = 0; i < 2; i++) {
+ rs.vap_vsm_vtx_assm |= (R300_INPUT_CNTL_TC0 << tex_count);
+ rs.vap_out_vtx_fmt[1] |= (4 << (3 * tex_count));
+ stream_loc_notcl[loc++] = 6 + tex_count;
+
+ /* Rasterize it. */
+ rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW);
+ tex_count++;
+ }
}
}