From f13a904c34cf7ac5aae3d50a1421259895fc9a08 Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Fri, 18 Dec 2009 19:42:02 -0800 Subject: [PATCH] r300g: Respect provoking vertex for trifans. Fixes part of piglit's clipFlat test; next up is to get quads right. --- src/gallium/drivers/r300/r300_render.c | 33 ++++++++++++++++++++++++-- src/gallium/drivers/r300/r300_state.c | 4 ---- 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; } -- 2.30.2