Mesa (master): llvmpipe: update driver's provoking vertex code

Brian Paul brianp at kemper.freedesktop.org
Thu May 6 00:26:26 UTC 2010


Module: Mesa
Branch: master
Commit: 246d39059e21bdc840128d448bcd79a957bbd1d1
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=246d39059e21bdc840128d448bcd79a957bbd1d1

Author: Brian Paul <brianp at vmware.com>
Date:   Wed May  5 13:52:05 2010 -0600

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 f8a5816..53b9169 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 5d3122e..4d77573 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;
 




More information about the mesa-commit mailing list