From 246d39059e21bdc840128d448bcd79a957bbd1d1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 5 May 2010 13:52:05 -0600 Subject: [PATCH] llvmpipe: update driver's provoking vertex code Note that the lp_setup_vbuf.c code is very, very similar to the corresponding code in softpipe. It could probably be shared. --- src/gallium/drivers/llvmpipe/lp_setup_tri.c | 10 +- src/gallium/drivers/llvmpipe/lp_setup_vbuf.c | 262 ++++++++++++------- 2 files changed, 179 insertions(+), 93 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/lp_setup_tri.c b/src/gallium/drivers/llvmpipe/lp_setup_tri.c index f8a58165733..53b91690b68 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_tri.c @@ -205,8 +205,14 @@ static void setup_tri_coefficients( struct lp_setup_context *setup, switch (setup->fs.input[slot].interp) { case LP_INTERP_CONSTANT: - for (i = 0; i < NUM_CHANNELS; i++) - constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); + if (setup->flatshade_first) { + for (i = 0; i < NUM_CHANNELS; i++) + constant_coef(setup, tri, slot+1, v1[vert_attr][i], i); + } + else { + for (i = 0; i < NUM_CHANNELS; i++) + constant_coef(setup, tri, slot+1, v3[vert_attr][i], i); + } break; case LP_INTERP_LINEAR: diff --git a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c index 5d3122e8ba2..4d775735421 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c +++ b/src/gallium/drivers/llvmpipe/lp_setup_vbuf.c @@ -136,6 +136,7 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) struct lp_setup_context *setup = lp_setup_context(vbr); const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = setup->vertex_buffer; + const boolean flatshade_first = setup->flatshade_first; unsigned i; lp_setup_update_state(setup); @@ -178,35 +179,28 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLES: - if (setup->flatshade_first) { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - } + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first triangle vertex as first triangle vertex */ setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i+(i&1)-1], stride), - get_vert(vertex_buffer, indices[i-(i&1)], stride), - get_vert(vertex_buffer, indices[i-2], stride) ); + get_vert(vertex_buffer, indices[i-(i&1)], stride) ); + } } else { for (i = 2; i < nr; i += 1) { + /* emit last triangle vertex as last triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, indices[i+(i&1)-2], stride), get_vert(vertex_buffer, indices[i-(i&1)-1], stride), @@ -216,16 +210,18 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first non-spoke vertex as first vertex */ setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[0], stride), - get_vert(vertex_buffer, indices[i-1], stride) ); + get_vert(vertex_buffer, indices[0], stride) ); } } else { for (i = 2; i < nr; i += 1) { + /* emit last non-spoke vertex as last vertex */ setup->triangle( setup, get_vert(vertex_buffer, indices[0], stride), get_vert(vertex_buffer, indices[i-1], stride), @@ -235,43 +231,88 @@ lp_setup_draw(struct vbuf_render *vbr, const ushort *indices, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - setup->triangle( setup, + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, get_vert(vertex_buffer, indices[i-3], stride), get_vert(vertex_buffer, indices[i-2], stride), get_vert(vertex_buffer, indices[i-0], stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-2], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[i-3], stride), - get_vert(vertex_buffer, indices[i-0], stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-2], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-3], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - setup->triangle( setup, - get_vert(vertex_buffer, indices[i-0], stride), - get_vert(vertex_buffer, indices[i-1], stride), - get_vert(vertex_buffer, indices[0], stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[0], stride), + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, indices[i-1], stride), + get_vert(vertex_buffer, indices[i-0], stride), + get_vert(vertex_buffer, indices[0], stride) ); + } } break; @@ -292,6 +333,7 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) const unsigned stride = setup->vertex_info->size * sizeof(float); const void *vertex_buffer = (void *) get_vert(setup->vertex_buffer, start, stride); + const boolean flatshade_first = setup->flatshade_first; unsigned i; lp_setup_update_state(setup); @@ -334,35 +376,27 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLES: - if (setup->flatshade_first) { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, i-2, stride) ); - } - } - else { - for (i = 2; i < nr; i += 3) { - setup->triangle( setup, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); - } + for (i = 2; i < nr; i += 3) { + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); } break; case PIPE_PRIM_TRIANGLE_STRIP: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i++) { + /* emit first triangle vertex as first triangle vertex */ setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), get_vert(vertex_buffer, i+(i&1)-1, stride), - get_vert(vertex_buffer, i-(i&1), stride), - get_vert(vertex_buffer, i-2, stride) ); + get_vert(vertex_buffer, i-(i&1), stride) ); } } else { for (i = 2; i < nr; i++) { + /* emit last triangle vertex as last triangle vertex */ setup->triangle( setup, get_vert(vertex_buffer, i+(i&1)-2, stride), get_vert(vertex_buffer, i-(i&1)-1, stride), @@ -372,16 +406,18 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_TRIANGLE_FAN: - if (setup->flatshade_first) { + if (flatshade_first) { for (i = 2; i < nr; i += 1) { + /* emit first non-spoke vertex as first vertex */ setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride), - get_vert(vertex_buffer, i-1, stride) ); + get_vert(vertex_buffer, 0, stride) ); } } else { for (i = 2; i < nr; i += 1) { + /* emit last non-spoke vertex as last vertex */ setup->triangle( setup, get_vert(vertex_buffer, 0, stride), get_vert(vertex_buffer, i-1, stride), @@ -391,42 +427,86 @@ lp_setup_draw_arrays(struct vbuf_render *vbr, uint start, uint nr) break; case PIPE_PRIM_QUADS: - for (i = 3; i < nr; i += 4) { - setup->triangle( setup, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quads don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 4) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_QUAD_STRIP: - for (i = 3; i < nr; i += 2) { - setup->triangle( setup, - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-2, stride), - get_vert(vertex_buffer, i-0, stride) ); - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-3, stride), - get_vert(vertex_buffer, i-0, stride) ); + /* GL quad strips don't follow provoking vertex convention */ + if (flatshade_first) { + /* emit last quad vertex as first triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride) ); + } + } + else { + /* emit last quad vertex as last triangle vertex */ + for (i = 3; i < nr; i += 2) { + setup->triangle( setup, + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-2, stride), + get_vert(vertex_buffer, i-0, stride) ); + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-3, stride), + get_vert(vertex_buffer, i-0, stride) ); + } } break; case PIPE_PRIM_POLYGON: /* Almost same as tri fan but the _first_ vertex specifies the flat - * shading color. Note that the first polygon vertex is passed as - * the last triangle vertex here. - * flatshade_first state makes no difference. + * shading color. */ - for (i = 2; i < nr; i += 1) { - setup->triangle( setup, - get_vert(vertex_buffer, i-1, stride), - get_vert(vertex_buffer, i-0, stride), - get_vert(vertex_buffer, 0, stride) ); + if (flatshade_first) { + /* emit first polygon vertex as first triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, 0, stride), + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride) ); + } + } + else { + /* emit first polygon vertex as last triangle vertex */ + for (i = 2; i < nr; i += 1) { + setup->triangle( setup, + get_vert(vertex_buffer, i-1, stride), + get_vert(vertex_buffer, i-0, stride), + get_vert(vertex_buffer, 0, stride) ); + } } break; -- 2.30.2