summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/r300/r300_render.c33
-rw-r--r--src/gallium/drivers/r300/r300_state.c4
2 files changed, 31 insertions, 6 deletions
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index a0d67e76181..11c7ce859db 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -75,13 +75,40 @@ static boolean r300_nothing_to_draw(struct r300_context *r300)
r300->scissor_state->scissor.empty_area;
}
+static uint32_t r300_provoking_vertex_fixes(struct r300_context *r300,
+ unsigned mode)
+{
+ uint32_t color_control = r300->rs_state->color_control;
+
+ /* By default (see r300_state.c:r300_create_rs_state) color_control is
+ * initialized to provoking the first vertex.
+ *
+ * If we are provoking the first vertex, then there's a quirk in the
+ * specification for ARB_provoking_vertex that essentially makes the
+ * second vertex the correct one to provoke for triangle fans.
+ * (http://www.opengl.org/registry/specs/ARB/provoking_vertex.txt)
+ * Otherwise, force the last vertex, as GL standard. */
+
+ if (r300->rs_state->rs.flatshade_first) {
+ if (mode == PIPE_PRIM_TRIANGLE_FAN) {
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_SECOND;
+ }
+ } else {
+ color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+ }
+
+ return color_control;
+}
+
static void r300_emit_draw_arrays(struct r300_context *r300,
unsigned mode,
unsigned count)
{
CS_LOCALS(r300);
- BEGIN_CS(6);
+ BEGIN_CS(8);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, 0);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
@@ -108,7 +135,9 @@ static void r300_emit_draw_elements(struct r300_context *r300,
assert((start * indexSize) % 4 == 0);
assert(offset_dwords == 0);
- BEGIN_CS(12);
+ BEGIN_CS(14);
+ OUT_CS_REG(R300_GA_COLOR_CONTROL,
+ r300_provoking_vertex_fixes(r300, mode));
OUT_CS_REG(R300_VAP_VF_MIN_VTX_INDX, minIndex);
OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, maxIndex);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 91cf972edee..5f332b2e0c2 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -510,10 +510,6 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
rs->color_control = R300_SHADE_MODEL_SMOOTH;
}
- if (!state->flatshade_first) {
- rs->color_control |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
- }
-
return (void*)rs;
}