1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Interface between 'draw' module's output and the softpipe rasterizer/setup
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * code.  When the 'draw' module has finished filling a vertex buffer, the
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * draw_arrays() functions below will be called.  Loop over the vertices and
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * call the point/line/tri setup functions.
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Authors
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *  Brian Paul
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_context.h"
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_setup.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_state.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "sp_prim_vbuf.h"
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw/draw_context.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "draw/draw_vbuf.h"
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_prim.h"
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SP_MAX_VBUF_INDEXES 1024
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define SP_MAX_VBUF_SIZE    4096
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtypedef const float (*cptrf4)[4];
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Subclass of vbuf_render.
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct softpipe_vbuf_render
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vbuf_render base;
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_context *softpipe;
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct setup_context *setup;
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint prim;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint vertex_size;
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint nr_vertices;
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint vertex_buffer_size;
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   void *vertex_buffer;
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** cast wrapper */
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct softpipe_vbuf_render *
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsoftpipe_vbuf_render(struct vbuf_render *vbr)
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (struct softpipe_vbuf_render *) vbr;
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** This tells the draw module about our desired vertex layout */
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const struct vertex_info *
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_get_vertex_info(struct vbuf_render *vbr)
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return softpipe_get_vbuf_vertex_info(cvbr->softpipe);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic boolean
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_allocate_vertices(struct vbuf_render *vbr,
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          ushort vertex_size, ushort nr_vertices)
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned size = vertex_size * nr_vertices;
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cvbr->vertex_buffer_size < size) {
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      align_free(cvbr->vertex_buffer);
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cvbr->vertex_buffer = align_malloc(size, 16);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      cvbr->vertex_buffer_size = size;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->vertex_size = vertex_size;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->nr_vertices = nr_vertices;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cvbr->vertex_buffer != NULL;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_release_vertices(struct vbuf_render *vbr)
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* keep the old allocation for next time */
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void *
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_map_vertices(struct vbuf_render *vbr)
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return cvbr->vertex_buffer;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_unmap_vertices(struct vbuf_render *vbr,
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       ushort min_index,
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       ushort max_index )
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (void) cvbr;
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* do nothing */
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct setup_context *setup_ctx = cvbr->setup;
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sp_setup_prepare( setup_ctx );
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->softpipe->reduced_prim = u_reduced_prim(prim);
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->prim = prim;
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE cptrf4 get_vert( const void *vertex_buffer,
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               int index,
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                               int stride )
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return (cptrf4)((char *)vertex_buffer + index * stride);
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * draw elements / indexed primitives
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_draw_elements(struct vbuf_render *vbr, const ushort *indices, uint nr)
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_context *softpipe = cvbr->softpipe;
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const void *vertex_buffer = cvbr->vertex_buffer;
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct setup_context *setup = cvbr->setup;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (cvbr->prim) {
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_POINTS:
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < nr; i++) {
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_point( setup,
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         get_vert(vertex_buffer, indices[i-0], stride) );
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINES:
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i += 2) {
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-1], stride),
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-0], stride) );
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINE_STRIP:
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i ++) {
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-1], stride),
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-0], stride) );
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINE_LOOP:
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i ++) {
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-1], stride),
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[i-0], stride) );
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (nr) {
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[nr-1], stride),
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, indices[0], stride) );
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLES:
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 2; i < nr; i += 3) {
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_tri( setup,
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, indices[i-2], stride),
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, indices[i-1], stride),
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, indices[i-0], stride) );
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLE_STRIP:
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit first triangle vertex as first triangle vertex */
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride),
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-(i&1)], stride) );
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit last triangle vertex as last triangle vertex */
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLE_FAN:
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit first non-spoke vertex as first vertex */
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[0], stride) );
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit last non-spoke vertex as last vertex */
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[0], stride),
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_QUADS:
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GL quads don't follow provoking vertex convention */
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as first triangle vertex */
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 4) {
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride),
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride) );
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride),
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride) );
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as last triangle vertex */
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 4) {
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride),
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride),
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride),
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_QUAD_STRIP:
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GL quad strips don't follow provoking vertex convention */
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as first triangle vertex */
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 2) {
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride),
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride) );
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride) );
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as last triangle vertex */
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 2) {
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride),
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-2], stride),
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-3], stride),
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_POLYGON:
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Almost same as tri fan but the _first_ vertex specifies the flat
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * shading color.
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit first polygon  vertex as first triangle vertex */
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[0], stride),
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride) );
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit first polygon  vertex as last triangle vertex */
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-1], stride),
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[i-0], stride),
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, indices[0], stride) );
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This function is hit when the draw module is working in pass-through mode.
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * It's up to us to convert the vertex array into point/line/tri prims.
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_context *softpipe = cvbr->softpipe;
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct setup_context *setup = cvbr->setup;
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const void *vertex_buffer =
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (void *) get_vert(cvbr->vertex_buffer, start, stride);
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const boolean flatshade_first = softpipe->rasterizer->flatshade_first;
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (cvbr->prim) {
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_POINTS:
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < nr; i++) {
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_point( setup,
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         get_vert(vertex_buffer, i-0, stride) );
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINES:
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i += 2) {
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, i-1, stride),
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, i-0, stride) );
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINE_STRIP:
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i ++) {
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     get_vert(vertex_buffer, i-1, stride),
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                     get_vert(vertex_buffer, i-0, stride) );
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_LINE_LOOP:
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 1; i < nr; i ++) {
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, i-1, stride),
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, i-0, stride) );
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (nr) {
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_line( setup,
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, nr-1, stride),
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        get_vert(vertex_buffer, 0, stride) );
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLES:
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 2; i < nr; i += 3) {
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         sp_setup_tri( setup,
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, i-2, stride),
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, i-1, stride),
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       get_vert(vertex_buffer, i-0, stride) );
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLE_STRIP:
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i++) {
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit first triangle vertex as first triangle vertex */
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride),
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i+(i&1)-1, stride),
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-(i&1), stride) );
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i++) {
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit last triangle vertex as last triangle vertex */
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i+(i&1)-2, stride),
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-(i&1)-1, stride),
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_TRIANGLE_FAN:
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit first non-spoke vertex as first vertex */
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, 0, stride)  );
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            /* emit last non-spoke vertex as last vertex */
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, 0, stride),
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_QUADS:
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GL quads don't follow provoking vertex convention */
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as first triangle vertex */
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 4) {
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride),
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride) );
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride),
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride) );
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as last triangle vertex */
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 4) {
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride),
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride),
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride),
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_QUAD_STRIP:
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* GL quad strips don't follow provoking vertex convention */
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as first triangle vertex */
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 2) {
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride),
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride) );
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride) );
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit last quad vertex as last triangle vertex */
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 3; i < nr; i += 2) {
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride),
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-2, stride),
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-3, stride),
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   case PIPE_PRIM_POLYGON:
516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* Almost same as tri fan but the _first_ vertex specifies the flat
517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       * shading color.
518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org       */
519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (flatshade_first) {
520f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit first polygon  vertex as first triangle vertex */
521f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
522f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
523f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, 0, stride),
524f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
525f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride) );
526f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
527f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
528f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      else {
529f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         /* emit first polygon  vertex as last triangle vertex */
530f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (i = 2; i < nr; i += 1) {
531f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            sp_setup_tri( setup,
532f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-1, stride),
533f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, i-0, stride),
534f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          get_vert(vertex_buffer, 0, stride) );
535f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
536f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
537f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      break;
538f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
539f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   default:
540f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
541f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
542f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
543f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
544f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
545f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_so_info(struct vbuf_render *vbr, uint primitives, uint vertices,
546f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                uint prim_generated)
547f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
548f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
549f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_context *softpipe = cvbr->softpipe;
550f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
551f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   softpipe->so_stats.num_primitives_written += primitives;
552f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   softpipe->so_stats.primitives_storage_needed =
553f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vertices * 4 /*sizeof(float|int32)*/ * 4 /*x,y,z,w*/;
554f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   softpipe->num_primitives_generated += prim_generated;
555f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
556f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
557f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
558f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
559f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_vbuf_destroy(struct vbuf_render *vbr)
560f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
561f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
562f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (cvbr->vertex_buffer)
563f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      align_free(cvbr->vertex_buffer);
564f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   sp_setup_destroy_context(cvbr->setup);
565f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(cvbr);
566f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
567f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
568f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
569f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**
570f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Create the post-transform vertex handler for the given context.
571f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */
572f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct vbuf_render *
573f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgsp_create_vbuf_backend(struct softpipe_context *sp)
574f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
575f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render);
576f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
577f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(sp->draw);
578f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
579f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
580f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
581f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
582f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info;
583f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices;
584f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.map_vertices = sp_vbuf_map_vertices;
585f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
586f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.set_primitive = sp_vbuf_set_primitive;
587f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.draw_elements = sp_vbuf_draw_elements;
588f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
589f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.release_vertices = sp_vbuf_release_vertices;
590f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.set_stream_output_info = sp_vbuf_so_info;
591f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->base.destroy = sp_vbuf_destroy;
592f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
593f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->softpipe = sp;
594f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
595f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   cvbr->setup = sp_setup_create_context(cvbr->softpipe);
596f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
597f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &cvbr->base;
598f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
599