[Mesa-dev] [PATCH 02/11] softpipe: Handle adjacency primitives.

Brian Paul brianp at vmware.com
Wed Nov 7 08:07:40 PST 2012


On 11/07/2012 08:26 AM, jfonseca at vmware.com wrote:
> From: José Fonseca<jfonseca at vmware.com>
>
> Not fully tested.
>
> Based on diagrams from
> http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124.aspx#Primitive_Adjacency
> ---
>   src/gallium/drivers/softpipe/sp_prim_vbuf.c |   46 +++++++++++++++++++++++++++
>   1 file changed, 46 insertions(+)
>
> diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
> index a142118..593a4fc 100644
> --- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
> +++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
> @@ -380,6 +380,14 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
>         }
>         break;
>
> +   case PIPE_PRIM_LINES_ADJACENCY:
> +      for (i = 3; i<  nr; i += 4) {
> +         sp_setup_line( setup,
> +                        get_vert(vertex_buffer, i-2, stride),
> +                        get_vert(vertex_buffer, i-1, stride) );
> +      }
> +      break;
> +
>      case PIPE_PRIM_LINE_STRIP:
>         for (i = 1; i<  nr; i ++) {
>            sp_setup_line( setup,
> @@ -388,6 +396,14 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
>         }
>         break;
>
> +   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
> +      for (i = 3; i<  nr; i++) {
> +         sp_setup_line( setup,
> +                     get_vert(vertex_buffer, i-2, stride),
> +                     get_vert(vertex_buffer, i-1, stride) );
> +      }
> +      break;
> +
>      case PIPE_PRIM_LINE_LOOP:
>         for (i = 1; i<  nr; i ++) {
>            sp_setup_line( setup,
> @@ -410,6 +426,15 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
>         }
>         break;
>
> +   case PIPE_PRIM_TRIANGLES_ADJACENCY:
> +      for (i = 5; i<  nr; i += 6) {
> +         sp_setup_tri( setup,
> +                       get_vert(vertex_buffer, i-5, stride),
> +                       get_vert(vertex_buffer, i-3, stride),
> +                       get_vert(vertex_buffer, i-1, stride) );
> +      }
> +      break;
> +
>      case PIPE_PRIM_TRIANGLE_STRIP:
>         if (flatshade_first) {
>            for (i = 2; i<  nr; i++) {
> @@ -431,6 +456,27 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
>         }
>         break;
>
> +   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
> +      if (flatshade_first) {
> +         for (i = 5; i<  nr; i++) {
> +            /* emit first triangle vertex as first triangle vertex */
> +            sp_setup_tri( setup,
> +                          get_vert(vertex_buffer, i-5, stride),
> +                          get_vert(vertex_buffer, i+(i&1)-3, stride),
> +                          get_vert(vertex_buffer, i-(i&1)-1, stride) );
> +         }
> +      }
> +      else {
> +         for (i = 5; i<  nr; i++) {
> +            /* emit last triangle vertex as last triangle vertex */
> +            sp_setup_tri( setup,
> +                          get_vert(vertex_buffer, i+(i&1)-5, stride),
> +                          get_vert(vertex_buffer, i-(i&1)-3, stride),
> +                          get_vert(vertex_buffer, i-1, stride) );
> +         }
> +      }
> +      break;
> +


Shouldn't we increment with i+=2 since we emit need to emit a triangle 
for every other vertex?

I wrote a test program to generate and print the indexes for adjacency 
triangles based on your arithmetic:


#include <stdio.h>

int main(int argc, char *argv[])
{
    int i, nr = 14;
    for (i = 5; i < nr; i++) {
       int a = i-5;
       int b = i+(i&1)-3;
       int c = i-(i&1)-1;
       printf("%d: %d, %d, %d\n", i, a, b, c);
    }
    return 0;
}

The output is:

5: 0, 3, 3
6: 1, 3, 5
7: 2, 5, 5
8: 3, 5, 7
9: 4, 7, 7
10: 5, 7, 9
11: 6, 9, 9
12: 7, 9, 11
13: 8, 11, 11

There's too many triangles and duplicated vertex indexes.

This seems to work:

int main(int argc, char *argv[])
{
    int i, nr = 14;
    for (i = 5; i < nr; i+=2) {
       int a = i-5;
       int b = (i&2) ? i-1 : i-3;
       int c = (i&2) ? i-3 : i-1;
       printf("%d: %d, %d, %d\n", i, a, b, c);
    }
    return 0;
}

-Brian


More information about the mesa-dev mailing list