r300g: Respect provoking vertex for trifans.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 19 Dec 2009 03:42:02 +0000 (19:42 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Sat, 19 Dec 2009 03:49:14 +0000 (19:49 -0800)
Fixes part of piglit's clipFlat test; next up is to get quads right.

src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_state.c

index a0d67e76181e893f3019f3e513f5a0ce5929e4f6..11c7ce859db7c1ad94d7f3e76fcbcfb24a7d1172 100644 (file)
@@ -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);
index 91cf972edee4fa46d026f3b09b645d62c6444c3b..5f332b2e0c24683bcd8d7ee4b897fcfa756cbd34 100644 (file)
@@ -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;
 }