1a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell/**************************************************************************
2c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
3a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * All Rights Reserved.
5c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
6a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * Permission is hereby granted, free of charge, to any person obtaining a
7a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * copy of this software and associated documentation files (the
8a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * "Software"), to deal in the Software without restriction, including
9a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * without limitation the rights to use, copy, modify, merge, publish,
10a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * distribute, sub license, and/or sell copies of the Software, and to
11a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * permit persons to whom the Software is furnished to do so, subject to
12a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * the following conditions:
13c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
14a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * The above copyright notice and this permission notice (including the
15a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * next paragraph) shall be included in all copies or substantial portions
16a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * of the Software.
17c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
18a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
26a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell **************************************************************************/
27a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
28a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell/**
29d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul * Interface between 'draw' module's output and the softpipe rasterizer/setup
30d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul * code.  When the 'draw' module has finished filling a vertex buffer, the
31d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul * draw_arrays() functions below will be called.  Loop over the vertices and
32d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul * call the point/line/tri setup functions.
33c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell *
342d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian * Authors
352d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian *  Brian Paul
36a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell */
37a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
38a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
39a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell#include "sp_context.h"
404fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell#include "sp_setup.h"
413d81a956b9de709de17a98b93fead4d3307b2b99Brian#include "sp_state.h"
422d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian#include "sp_prim_vbuf.h"
436acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "draw/draw_context.h"
446acd63a4980951727939c0dd545a0324965b3834José Fonseca#include "draw/draw_vbuf.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
46a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell#include "util/u_prim.h"
47a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
48a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
492d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian#define SP_MAX_VBUF_INDEXES 1024
502d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian#define SP_MAX_VBUF_SIZE    4096
51a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
52c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwelltypedef const float (*cptrf4)[4];
53a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
54a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell/**
552d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian * Subclass of vbuf_render.
56a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell */
572d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstruct softpipe_vbuf_render
58a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
592d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct vbuf_render base;
602d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_context *softpipe;
614fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   struct setup_context *setup;
624fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell
632d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   uint prim;
642d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   uint vertex_size;
65a321b8ed6ea583f43f8d5ab5d1b918a96df44f1dKeith Whitwell   uint nr_vertices;
667ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   uint vertex_buffer_size;
672d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   void *vertex_buffer;
682d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian};
69a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
70a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
712d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian/** cast wrapper */
722d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstatic struct softpipe_vbuf_render *
732d37e78e636e5e1e7d5d00230e50a00f7a71e868Briansoftpipe_vbuf_render(struct vbuf_render *vbr)
74a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
752d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   return (struct softpipe_vbuf_render *) vbr;
76a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
77a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
78a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
79826f55218879ff42207f3968fd4a89370c8ae460Brian Paul/** This tells the draw module about our desired vertex layout */
802d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstatic const struct vertex_info *
812d37e78e636e5e1e7d5d00230e50a00f7a71e868Briansp_vbuf_get_vertex_info(struct vbuf_render *vbr)
82a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
832d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
843d81a956b9de709de17a98b93fead4d3307b2b99Brian   return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
85a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
86a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
87a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
887ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellstatic boolean
892d37e78e636e5e1e7d5d00230e50a00f7a71e868Briansp_vbuf_allocate_vertices(struct vbuf_render *vbr,
907ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell                          ushort vertex_size, ushort nr_vertices)
91a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
922d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
937ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   unsigned size = vertex_size * nr_vertices;
947ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell
957ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   if (cvbr->vertex_buffer_size < size) {
969d9a7edfbc7259b532123d7d85f6238f59a9a41aBrian Paul      align_free(cvbr->vertex_buffer);
977ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell      cvbr->vertex_buffer = align_malloc(size, 16);
987ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell      cvbr->vertex_buffer_size = size;
997ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   }
1007ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell
1012d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   cvbr->vertex_size = vertex_size;
102a321b8ed6ea583f43f8d5ab5d1b918a96df44f1dKeith Whitwell   cvbr->nr_vertices = nr_vertices;
103a321b8ed6ea583f43f8d5ab5d1b918a96df44f1dKeith Whitwell
1047ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   return cvbr->vertex_buffer != NULL;
105a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
106a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
107826f55218879ff42207f3968fd4a89370c8ae460Brian Paul
1082d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstatic void
1097ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellsp_vbuf_release_vertices(struct vbuf_render *vbr)
1107ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell{
1117ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   /* keep the old allocation for next time */
1127ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell}
1137ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell
114826f55218879ff42207f3968fd4a89370c8ae460Brian Paul
1157ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellstatic void *
1167ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellsp_vbuf_map_vertices(struct vbuf_render *vbr)
117a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
1182d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
1197ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   return cvbr->vertex_buffer;
1207ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell}
1217ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell
122826f55218879ff42207f3968fd4a89370c8ae460Brian Paul
1237ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellstatic void
1247ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwellsp_vbuf_unmap_vertices(struct vbuf_render *vbr,
1257ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell                       ushort min_index,
1267ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell                       ushort max_index )
1277ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell{
1287ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
1297ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
130180ccffe550698d860e06d3cf5e16e4d9c3e7dddVinson Lee   (void) cvbr;
1317ca78a07b37e4cce0e258f711c6f8bbe1d98a633Keith Whitwell   /* do nothing */
132a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
133a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
134a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
135488dd2c1912132fe7ee5e81b05fb64ba62a46098Brian Paulstatic void
1362d37e78e636e5e1e7d5d00230e50a00f7a71e868Briansp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
137a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
1382d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
1394fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   struct setup_context *setup_ctx = cvbr->setup;
1408b607f42d094e61432c5718b8baa0a68268ec150Keith Whitwell
1419a0ff33ad60cb63d430c4f93f6531f7aa2ec2ba8Brian Paul   sp_setup_prepare( setup_ctx );
1428b607f42d094e61432c5718b8baa0a68268ec150Keith Whitwell
143a1dbd7aa159e266592a1e52504680992327ca9e0Keith Whitwell   cvbr->softpipe->reduced_prim = u_reduced_prim(prim);
144f116a149160d50d43a23b02a3416725d6f895d51Keith Whitwell   cvbr->prim = prim;
145a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
146a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
147a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
14890e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwellstatic INLINE cptrf4 get_vert( const void *vertex_buffer,
14990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell                               int index,
15090e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell                               int stride )
15190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell{
15290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   return (cptrf4)((char *)vertex_buffer + index * stride);
15390e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell}
1542d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian
1552d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian
156d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul/**
157d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul * draw elements / indexed primitives
158d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul */
1592d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstatic void
160740e50c60f03d194aafab93d5251699964800979Brian Paulsp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
1612d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian{
1622d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
1632d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_context *softpipe = cvbr->softpipe;
164d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
16590e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   const void *vertex_buffer = cvbr->vertex_buffer;
166cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   struct setup_context *setup = cvbr->setup;
167cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
168d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul   unsigned i;
1698e7326832a7420154fc0d526ac682494db1be160Keith Whitwell
1702d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   switch (cvbr->prim) {
17190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_POINTS:
17290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 0; i < nr; i++) {
173cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_point( setup,
174826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                         get_vert(vertex_buffer, indices[i-0], stride) );
1752d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      }
1762d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      break;
1772d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian
1782d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   case PIPE_PRIM_LINES:
17990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i += 2) {
180cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
181826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-1], stride),
182826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-0], stride) );
18390e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
18490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
185c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
18690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_LINE_STRIP:
18790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i ++) {
188cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
189826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-1], stride),
190826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-0], stride) );
1912d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      }
1922d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      break;
1932d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian
19490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_LINE_LOOP:
19590e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i ++) {
196cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
197826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-1], stride),
198826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[i-0], stride) );
19990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
20090e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      if (nr) {
201cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
202826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[nr-1], stride),
203826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, indices[0], stride) );
20490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
20590e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
206c95dcc49629b72b95826e87e067d7a48753605fbKeith Whitwell
20790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_TRIANGLES:
208cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      for (i = 2; i < nr; i += 3) {
209cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_tri( setup,
210cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, indices[i-2], stride),
211cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, indices[i-1], stride),
212cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, indices[i-0], stride) );
21390e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
21490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
21590e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
21690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_TRIANGLE_STRIP:
217cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
218d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
219cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit first triangle vertex as first triangle vertex */
220cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
221cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride),
222826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
223cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-(i&1)], stride) );
224cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul
2255aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
226d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      }
227d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      else {
228d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
229cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit last triangle vertex as last triangle vertex */
230cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
231826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
232826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
233826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
2345aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
2352d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      }
2362d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian      break;
23790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
23890e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_TRIANGLE_FAN:
239cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
240d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
241cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit first non-spoke vertex as first vertex */
242cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
243cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
244826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
245cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[0], stride) );
2465aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
247d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      }
248d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      else {
249d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
250cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit last non-spoke vertex as last vertex */
251cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
252826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[0], stride),
253826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
254826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
2555aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
25690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
25790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
258086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul
25990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_QUADS:
260cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      /* GL quads don't follow provoking vertex convention */
261cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
262cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as first triangle vertex */
263cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 4) {
264cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
265cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
266cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride),
267cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride) );
2685aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul
269cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
270cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
271cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride),
272cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride) );
273cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
274cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
275cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
276cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as last triangle vertex */
277cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 4) {
278cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
279cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride),
280cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride),
281cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
282cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul
283cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
284cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride),
285cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
286cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
287cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
28890e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
28990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
290086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul
29190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_QUAD_STRIP:
292cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      /* GL quad strips don't follow provoking vertex convention */
293cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
294cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as first triangle vertex */
295cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 2) {
296cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
297cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
298cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride),
299cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride) );
300cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
301cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
302cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
303cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride) );
304cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
305cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
306cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
307cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as last triangle vertex */
308cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 2) {
309cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
310cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride),
311cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-2], stride),
312cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
313cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
314cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
315cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-3], stride),
316cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
317cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
31890e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
31990e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
320086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul
321086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul   case PIPE_PRIM_POLYGON:
3225aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul      /* Almost same as tri fan but the _first_ vertex specifies the flat
323cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul       * shading color.
3245aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul       */
325cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
326cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit first polygon  vertex as first triangle vertex */
327cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 2; i < nr; i += 1) {
328cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
329cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[0], stride),
330cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
331cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride) );
332cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
333cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
334cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
335cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit first polygon  vertex as last triangle vertex */
336cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 2; i < nr; i += 1) {
337cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
338cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-1], stride),
339cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[i-0], stride),
340cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, indices[0], stride) );
341cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
342086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul      }
343086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul      break;
344086ecea179ed572c89aa77c5f465671a5cef87a7Brian Paul
34590e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   default:
34690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      assert(0);
347a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell   }
348a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
349a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
350a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
3517d5e38a55ae99a4c28873377572f77f383ce0c3eBrian/**
3527d5e38a55ae99a4c28873377572f77f383ce0c3eBrian * This function is hit when the draw module is working in pass-through mode.
3537d5e38a55ae99a4c28873377572f77f383ce0c3eBrian * It's up to us to convert the vertex array into point/line/tri prims.
3547d5e38a55ae99a4c28873377572f77f383ce0c3eBrian */
3557d5e38a55ae99a4c28873377572f77f383ce0c3eBrianstatic void
3567d5e38a55ae99a4c28873377572f77f383ce0c3eBriansp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
3577d5e38a55ae99a4c28873377572f77f383ce0c3eBrian{
3587d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
3597d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   struct softpipe_context *softpipe = cvbr->softpipe;
360cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   struct setup_context *setup = cvbr->setup;
36190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
362d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul   const void *vertex_buffer =
363d7b5243c64b93d4f35d42ce89ae297de09fb76b4Brian Paul      (void *) get_vert(cvbr->vertex_buffer, start, stride);
364cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
365e4cdce43cebe6a2b38f7ea5145474ca2b12c57bbKeith Whitwell   unsigned i;
3667d5e38a55ae99a4c28873377572f77f383ce0c3eBrian
3677d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   switch (cvbr->prim) {
36849a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_POINTS:
36949a687882a659bd03fd09ca7a7d592818914597aBrian      for (i = 0; i < nr; i++) {
370cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_point( setup,
371826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                         get_vert(vertex_buffer, i-0, stride) );
37249a687882a659bd03fd09ca7a7d592818914597aBrian      }
37349a687882a659bd03fd09ca7a7d592818914597aBrian      break;
37490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
37549a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_LINES:
37690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i += 2) {
377cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
378826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, i-1, stride),
379826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, i-0, stride) );
38049a687882a659bd03fd09ca7a7d592818914597aBrian      }
38149a687882a659bd03fd09ca7a7d592818914597aBrian      break;
38290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
38349a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_LINE_STRIP:
38490e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i ++) {
385cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
38690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell                     get_vert(vertex_buffer, i-1, stride),
38790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell                     get_vert(vertex_buffer, i-0, stride) );
38849a687882a659bd03fd09ca7a7d592818914597aBrian      }
38949a687882a659bd03fd09ca7a7d592818914597aBrian      break;
39090e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
39190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell   case PIPE_PRIM_LINE_LOOP:
39290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      for (i = 1; i < nr; i ++) {
393cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
394826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, i-1, stride),
395826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, i-0, stride) );
39690e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
39790e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      if (nr) {
398cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_line( setup,
399826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, nr-1, stride),
400826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                        get_vert(vertex_buffer, 0, stride) );
40190e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      }
40290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell      break;
40390e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
4047d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   case PIPE_PRIM_TRIANGLES:
405cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      for (i = 2; i < nr; i += 3) {
406cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         sp_setup_tri( setup,
407cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, i-2, stride),
408cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, i-1, stride),
409cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                       get_vert(vertex_buffer, i-0, stride) );
4107d5e38a55ae99a4c28873377572f77f383ce0c3eBrian      }
4117d5e38a55ae99a4c28873377572f77f383ce0c3eBrian      break;
41290e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
41349a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_TRIANGLE_STRIP:
414cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
415d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i++) {
416cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit first triangle vertex as first triangle vertex */
417cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
418cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride),
419826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i+(i&1)-1, stride),
420cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-(i&1), stride) );
4215aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
422d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      }
423d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      else {
424d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i++) {
425cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit last triangle vertex as last triangle vertex */
426cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
427826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i+(i&1)-2, stride),
428826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i-(i&1)-1, stride),
429826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
4305aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
43149a687882a659bd03fd09ca7a7d592818914597aBrian      }
43249a687882a659bd03fd09ca7a7d592818914597aBrian      break;
43390e86363de7dbcfda3490b5c31d701350a0fa2efKeith Whitwell
43449a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_TRIANGLE_FAN:
435cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
436d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
437cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit first non-spoke vertex as first vertex */
438cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
439cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
440826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i-0, stride),
441cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, 0, stride)  );
4425aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
443d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      }
444d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell      else {
445d12bae9368e0c44a9943d9b37ab848ea307d70c7Keith Whitwell         for (i = 2; i < nr; i += 1) {
446cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            /* emit last non-spoke vertex as last vertex */
447cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
448826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, 0, stride),
449826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i-1, stride),
450826f55218879ff42207f3968fd4a89370c8ae460Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
4515aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul         }
45249a687882a659bd03fd09ca7a7d592818914597aBrian      }
45349a687882a659bd03fd09ca7a7d592818914597aBrian      break;
454a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul
45549a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_QUADS:
456cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      /* GL quads don't follow provoking vertex convention */
457cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
458cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as first triangle vertex */
459cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 4) {
460cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
461cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride),
462cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride),
463cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride) );
464cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
465cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride),
466cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride),
467cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride) );
468cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
469cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
470cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
471cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as last triangle vertex */
472cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 4) {
473cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
474cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride),
475cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride),
476cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
477cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
478cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride),
479cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
480cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
481cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
48249a687882a659bd03fd09ca7a7d592818914597aBrian      }
48349a687882a659bd03fd09ca7a7d592818914597aBrian      break;
4845aec03aaf45ce83cb203849bb3f13c336b232822Brian Paul
48549a687882a659bd03fd09ca7a7d592818914597aBrian   case PIPE_PRIM_QUAD_STRIP:
486cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      /* GL quad strips don't follow provoking vertex convention */
487cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
488cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as first triangle vertex */
489cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 2) {
490cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
491cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride),
492cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride),
493cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride) );
494cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
495cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride),
496cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
497cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride) );
498cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
499cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
500cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
501cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit last quad vertex as last triangle vertex */
502cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 3; i < nr; i += 2) {
503cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
504cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride),
505cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-2, stride),
506cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
507cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
508cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
509cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-3, stride),
510cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
511cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
5127d5e38a55ae99a4c28873377572f77f383ce0c3eBrian      }
5137d5e38a55ae99a4c28873377572f77f383ce0c3eBrian      break;
514a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul
515a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul   case PIPE_PRIM_POLYGON:
516a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul      /* Almost same as tri fan but the _first_ vertex specifies the flat
517cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul       * shading color.
518a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul       */
519cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      if (flatshade_first) {
520cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit first polygon  vertex as first triangle vertex */
521cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 2; i < nr; i += 1) {
522cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
523cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, 0, stride),
524cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
525cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride) );
526cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
527cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      }
528cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul      else {
529cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         /* emit first polygon  vertex as last triangle vertex */
530cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         for (i = 2; i < nr; i += 1) {
531cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul            sp_setup_tri( setup,
532cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-1, stride),
533cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, i-0, stride),
534cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul                          get_vert(vertex_buffer, 0, stride) );
535cb136a93aba4dc64db7e446b0fbc36c9172e4017Brian Paul         }
536a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul      }
537a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul      break;
538a59575d8fbe8b0ca053cc8366ce7a42bc660158aBrian Paul
5397d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   default:
5407d5e38a55ae99a4c28873377572f77f383ce0c3eBrian      assert(0);
5417d5e38a55ae99a4c28873377572f77f383ce0c3eBrian   }
5427d5e38a55ae99a4c28873377572f77f383ce0c3eBrian}
5437d5e38a55ae99a4c28873377572f77f383ce0c3eBrian
5442c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusinstatic void
545ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airliesp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
546ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie                uint prim_generated)
5472c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin{
5482c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
5492c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin   struct softpipe_context *softpipe = cvbr->softpipe;
550be7d8ddf0c0a293ee94db360a44561beb10e62f9Zack Rusin
551ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie   softpipe->so_stats.num_primitives_written += primitives;
552be7d8ddf0c0a293ee94db360a44561beb10e62f9Zack Rusin   softpipe->so_stats.primitives_storage_needed =
553be7d8ddf0c0a293ee94db360a44561beb10e62f9Zack Rusin      vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
554ec8cbd79ac4065111365a6720c9564de56855cc8Dave Airlie   softpipe->num_primitives_generated += prim_generated;
5552c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin}
5562c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin
5577d5e38a55ae99a4c28873377572f77f383ce0c3eBrian
5582d37e78e636e5e1e7d5d00230e50a00f7a71e868Brianstatic void
5592d37e78e636e5e1e7d5d00230e50a00f7a71e868Briansp_vbuf_destroy(struct vbuf_render *vbr)
560a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
5612d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
562826f55218879ff42207f3968fd4a89370c8ae460Brian Paul   if (cvbr->vertex_buffer)
563e5da7b8548842500e751b133b96b28113fbe0d76José Fonseca      align_free(cvbr->vertex_buffer);
5649a0ff33ad60cb63d430c4f93f6531f7aa2ec2ba8Brian Paul   sp_setup_destroy_context(cvbr->setup);
5652d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian   FREE(cvbr);
566a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
567a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
568a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
5692d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian/**
5704fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell * Create the post-transform vertex handler for the given context.
5712d37e78e636e5e1e7d5d00230e50a00f7a71e868Brian */
5724fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwellstruct vbuf_render *
5734fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwellsp_create_vbuf_backend(struct softpipe_context *sp)
574a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell{
5754fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render);
576a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
5774fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   assert(sp->draw);
578a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
5794fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
5804fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
581d75454840672f462de933724daae24a839aac48eMichal
5824fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info;
5834fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices;
5844fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.map_vertices = sp_vbuf_map_vertices;
5854fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
5864fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.set_primitive = sp_vbuf_set_primitive;
587740e50c60f03d194aafab93d5251699964800979Brian Paul   cvbr->base.draw_elements = sp_vbuf_draw_elements;
5884fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
5894fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.release_vertices = sp_vbuf_release_vertices;
5902c22b8e61dc4adab658c6198feea30c006aa6c58Zack Rusin   cvbr->base.set_stream_output_info = sp_vbuf_so_info;
5914fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->base.destroy = sp_vbuf_destroy;
592d75454840672f462de933724daae24a839aac48eMichal
5934fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   cvbr->softpipe = sp;
594a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell
5959a0ff33ad60cb63d430c4f93f6531f7aa2ec2ba8Brian Paul   cvbr->setup = sp_setup_create_context(cvbr->softpipe);
5967d5e38a55ae99a4c28873377572f77f383ce0c3eBrian
5974fe0fc3eba1f79beda890a5016359d549bab6ad4Keith Whitwell   return &cvbr->base;
598a37e0daeb97bb36ba10038b12a909e22e08b52c4Keith Whitwell}
599