1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright 2008 VMware, Inc.
5bf215546Sopenharmony_ci * Copyright (C) 2010 LunarG Inc.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci *
25bf215546Sopenharmony_ci * Authors:
26bf215546Sopenharmony_ci  *   Keith Whitwell <keithw@vmware.com>
27bf215546Sopenharmony_ci *    Chia-I Wu <olv@lunarg.com>
28bf215546Sopenharmony_ci */
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci/* these macros are optional */
31bf215546Sopenharmony_ci#ifndef LOCAL_VARS
32bf215546Sopenharmony_ci#define LOCAL_VARS
33bf215546Sopenharmony_ci#endif
34bf215546Sopenharmony_ci#ifndef FUNC_ENTER
35bf215546Sopenharmony_ci#define FUNC_ENTER do {} while (0)
36bf215546Sopenharmony_ci#endif
37bf215546Sopenharmony_ci#ifndef FUNC_EXIT
38bf215546Sopenharmony_ci#define FUNC_EXIT do {} while (0)
39bf215546Sopenharmony_ci#endif
40bf215546Sopenharmony_ci#ifndef LINE_ADJ
41bf215546Sopenharmony_ci#define LINE_ADJ(flags, a0, i0, i1, a1) LINE(flags, i0, i1)
42bf215546Sopenharmony_ci#endif
43bf215546Sopenharmony_ci#ifndef TRIANGLE_ADJ
44bf215546Sopenharmony_ci#define TRIANGLE_ADJ(flags, i0, a0, i1, a1, i2, a2) TRIANGLE(flags, i0, i1, i2)
45bf215546Sopenharmony_ci#endif
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_cistatic void
48bf215546Sopenharmony_ciFUNC(FUNC_VARS)
49bf215546Sopenharmony_ci{
50bf215546Sopenharmony_ci   unsigned idx[6], i;
51bf215546Sopenharmony_ci   ushort flags;
52bf215546Sopenharmony_ci   LOCAL_VARS
53bf215546Sopenharmony_ci
54bf215546Sopenharmony_ci   FUNC_ENTER;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   /* prim, prim_flags, count, and last_vertex_last should have been defined */
57bf215546Sopenharmony_ci   if (0) {
58bf215546Sopenharmony_ci      debug_printf("%s: prim 0x%x, prim_flags 0x%x, count %d, last_vertex_last %d\n",
59bf215546Sopenharmony_ci            __FUNCTION__, prim, prim_flags, count, last_vertex_last);
60bf215546Sopenharmony_ci   }
61bf215546Sopenharmony_ci
62bf215546Sopenharmony_ci   switch (prim) {
63bf215546Sopenharmony_ci   case PIPE_PRIM_POINTS:
64bf215546Sopenharmony_ci      for (i = 0; i < count; i++) {
65bf215546Sopenharmony_ci         idx[0] = GET_ELT(i);
66bf215546Sopenharmony_ci         POINT(idx[0]);
67bf215546Sopenharmony_ci      }
68bf215546Sopenharmony_ci      break;
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci   case PIPE_PRIM_LINES:
71bf215546Sopenharmony_ci      flags = DRAW_PIPE_RESET_STIPPLE;
72bf215546Sopenharmony_ci      for (i = 0; i + 1 < count; i += 2) {
73bf215546Sopenharmony_ci         idx[0] = GET_ELT(i);
74bf215546Sopenharmony_ci         idx[1] = GET_ELT(i + 1);
75bf215546Sopenharmony_ci         LINE(flags, idx[0], idx[1]);
76bf215546Sopenharmony_ci      }
77bf215546Sopenharmony_ci      break;
78bf215546Sopenharmony_ci
79bf215546Sopenharmony_ci   case PIPE_PRIM_LINE_LOOP:
80bf215546Sopenharmony_ci   case PIPE_PRIM_LINE_STRIP:
81bf215546Sopenharmony_ci      if (count >= 2) {
82bf215546Sopenharmony_ci         flags = (prim_flags & DRAW_SPLIT_BEFORE) ? 0 : DRAW_PIPE_RESET_STIPPLE;
83bf215546Sopenharmony_ci         idx[1] = GET_ELT(0);
84bf215546Sopenharmony_ci         idx[2] = idx[1];
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci         for (i = 1; i < count; i++, flags = 0) {
87bf215546Sopenharmony_ci            idx[0] = idx[1];
88bf215546Sopenharmony_ci            idx[1] = GET_ELT(i);
89bf215546Sopenharmony_ci            LINE(flags, idx[0], idx[1]);
90bf215546Sopenharmony_ci         }
91bf215546Sopenharmony_ci         /* close the loop */
92bf215546Sopenharmony_ci         if (prim == PIPE_PRIM_LINE_LOOP && !prim_flags)
93bf215546Sopenharmony_ci            LINE(flags, idx[1], idx[2]);
94bf215546Sopenharmony_ci      }
95bf215546Sopenharmony_ci      break;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLES:
98bf215546Sopenharmony_ci      flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
99bf215546Sopenharmony_ci      for (i = 0; i + 2 < count; i += 3) {
100bf215546Sopenharmony_ci         idx[0] = GET_ELT(i);
101bf215546Sopenharmony_ci         idx[1] = GET_ELT(i + 1);
102bf215546Sopenharmony_ci         idx[2] = GET_ELT(i + 2);
103bf215546Sopenharmony_ci         TRIANGLE(flags, idx[0], idx[1], idx[2]);
104bf215546Sopenharmony_ci      }
105bf215546Sopenharmony_ci      break;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_STRIP:
108bf215546Sopenharmony_ci      if (count >= 3) {
109bf215546Sopenharmony_ci         flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
110bf215546Sopenharmony_ci         idx[1] = GET_ELT(0);
111bf215546Sopenharmony_ci         idx[2] = GET_ELT(1);
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci         if (last_vertex_last) {
114bf215546Sopenharmony_ci            for (i = 0; i + 2 < count; i++) {
115bf215546Sopenharmony_ci               idx[0] = idx[1];
116bf215546Sopenharmony_ci               idx[1] = idx[2];
117bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
118bf215546Sopenharmony_ci               /* always emit idx[2] last */
119bf215546Sopenharmony_ci               if (i & 1)
120bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[1], idx[0], idx[2]);
121bf215546Sopenharmony_ci               else
122bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[0], idx[1], idx[2]);
123bf215546Sopenharmony_ci            }
124bf215546Sopenharmony_ci         }
125bf215546Sopenharmony_ci         else {
126bf215546Sopenharmony_ci            for (i = 0; i + 2 < count; i++) {
127bf215546Sopenharmony_ci               idx[0] = idx[1];
128bf215546Sopenharmony_ci               idx[1] = idx[2];
129bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
130bf215546Sopenharmony_ci               /* always emit idx[0] first */
131bf215546Sopenharmony_ci               if (i & 1)
132bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[0], idx[2], idx[1]);
133bf215546Sopenharmony_ci               else
134bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[0], idx[1], idx[2]);
135bf215546Sopenharmony_ci            }
136bf215546Sopenharmony_ci         }
137bf215546Sopenharmony_ci      }
138bf215546Sopenharmony_ci      break;
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_FAN:
141bf215546Sopenharmony_ci      if (count >= 3) {
142bf215546Sopenharmony_ci         flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
143bf215546Sopenharmony_ci         idx[0] = GET_ELT(0);
144bf215546Sopenharmony_ci         idx[2] = GET_ELT(1);
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci         /* idx[0] is neither the first nor the last vertex */
147bf215546Sopenharmony_ci         if (last_vertex_last) {
148bf215546Sopenharmony_ci            for (i = 0; i + 2 < count; i++) {
149bf215546Sopenharmony_ci               idx[1] = idx[2];
150bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
151bf215546Sopenharmony_ci               /* always emit idx[2] last */
152bf215546Sopenharmony_ci               TRIANGLE(flags, idx[0], idx[1], idx[2]);
153bf215546Sopenharmony_ci            }
154bf215546Sopenharmony_ci         }
155bf215546Sopenharmony_ci         else {
156bf215546Sopenharmony_ci            for (i = 0; i + 2 < count; i++) {
157bf215546Sopenharmony_ci               idx[1] = idx[2];
158bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
159bf215546Sopenharmony_ci               /* always emit idx[1] first */
160bf215546Sopenharmony_ci               TRIANGLE(flags, idx[1], idx[2], idx[0]);
161bf215546Sopenharmony_ci            }
162bf215546Sopenharmony_ci         }
163bf215546Sopenharmony_ci      }
164bf215546Sopenharmony_ci      break;
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_ci   case PIPE_PRIM_QUADS:
167bf215546Sopenharmony_ci      if (last_vertex_last) {
168bf215546Sopenharmony_ci         for (i = 0; i + 3 < count; i += 4) {
169bf215546Sopenharmony_ci            idx[0] = GET_ELT(i);
170bf215546Sopenharmony_ci            idx[1] = GET_ELT(i + 1);
171bf215546Sopenharmony_ci            idx[2] = GET_ELT(i + 2);
172bf215546Sopenharmony_ci            idx[3] = GET_ELT(i + 3);
173bf215546Sopenharmony_ci#ifdef PASS_QUADS
174bf215546Sopenharmony_ci            QUAD(0, idx[0], idx[1],
175bf215546Sopenharmony_ci                  idx[2], idx[3]);
176bf215546Sopenharmony_ci#else
177bf215546Sopenharmony_ci            flags = DRAW_PIPE_RESET_STIPPLE |
178bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_0 |
179bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_2;
180bf215546Sopenharmony_ci            /* always emit idx[3] last */
181bf215546Sopenharmony_ci            TRIANGLE(flags, idx[0], idx[1], idx[3]);
182bf215546Sopenharmony_ci
183bf215546Sopenharmony_ci            flags = DRAW_PIPE_EDGE_FLAG_0 |
184bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_1;
185bf215546Sopenharmony_ci            TRIANGLE(flags, idx[1], idx[2], idx[3]);
186bf215546Sopenharmony_ci#endif
187bf215546Sopenharmony_ci         }
188bf215546Sopenharmony_ci      }
189bf215546Sopenharmony_ci      else {
190bf215546Sopenharmony_ci         for (i = 0; i + 3 < count; i += 4) {
191bf215546Sopenharmony_ci            idx[0] = GET_ELT(i);
192bf215546Sopenharmony_ci            idx[1] = GET_ELT(i + 1);
193bf215546Sopenharmony_ci            idx[2] = GET_ELT(i + 2);
194bf215546Sopenharmony_ci            idx[3] = GET_ELT(i + 3);
195bf215546Sopenharmony_ci#ifdef PASS_QUADS
196bf215546Sopenharmony_ci            QUAD(0, idx[0], idx[1],
197bf215546Sopenharmony_ci                  idx[2], idx[3]);
198bf215546Sopenharmony_ci#else
199bf215546Sopenharmony_ci            flags = DRAW_PIPE_RESET_STIPPLE |
200bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_0 |
201bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_1;
202bf215546Sopenharmony_ci            /* always emit idx[3] / idx[0] first */
203bf215546Sopenharmony_ci            if (quads_flatshade_last)
204bf215546Sopenharmony_ci               TRIANGLE(flags, idx[3], idx[0], idx[1]);
205bf215546Sopenharmony_ci            else
206bf215546Sopenharmony_ci               TRIANGLE(flags, idx[0], idx[1], idx[2]);
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci            flags = DRAW_PIPE_EDGE_FLAG_1 |
209bf215546Sopenharmony_ci                    DRAW_PIPE_EDGE_FLAG_2;
210bf215546Sopenharmony_ci            if (quads_flatshade_last)
211bf215546Sopenharmony_ci               TRIANGLE(flags, idx[3], idx[1], idx[2]);
212bf215546Sopenharmony_ci            else
213bf215546Sopenharmony_ci               TRIANGLE(flags, idx[0], idx[2], idx[3]);
214bf215546Sopenharmony_ci#endif
215bf215546Sopenharmony_ci         }
216bf215546Sopenharmony_ci      }
217bf215546Sopenharmony_ci      break;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   case PIPE_PRIM_QUAD_STRIP:
220bf215546Sopenharmony_ci      if (count >= 4) {
221bf215546Sopenharmony_ci         idx[2] = GET_ELT(0);
222bf215546Sopenharmony_ci         idx[3] = GET_ELT(1);
223bf215546Sopenharmony_ci
224bf215546Sopenharmony_ci         if (last_vertex_last) {
225bf215546Sopenharmony_ci            for (i = 0; i + 3 < count; i += 2) {
226bf215546Sopenharmony_ci               idx[0] = idx[2];
227bf215546Sopenharmony_ci               idx[1] = idx[3];
228bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
229bf215546Sopenharmony_ci               idx[3] = GET_ELT(i + 3);
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci#ifdef PASS_QUADS
232bf215546Sopenharmony_ci               QUAD(0, idx[2], idx[0],
233bf215546Sopenharmony_ci                    idx[1], idx[3]);
234bf215546Sopenharmony_ci#else
235bf215546Sopenharmony_ci               /* always emit idx[3] last */
236bf215546Sopenharmony_ci               flags = DRAW_PIPE_RESET_STIPPLE |
237bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_0 |
238bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_2;
239bf215546Sopenharmony_ci               TRIANGLE(flags, idx[2], idx[0], idx[3]);
240bf215546Sopenharmony_ci
241bf215546Sopenharmony_ci               flags = DRAW_PIPE_EDGE_FLAG_0 |
242bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_1;
243bf215546Sopenharmony_ci               TRIANGLE(flags, idx[0], idx[1], idx[3]);
244bf215546Sopenharmony_ci#endif
245bf215546Sopenharmony_ci            }
246bf215546Sopenharmony_ci         }
247bf215546Sopenharmony_ci         else {
248bf215546Sopenharmony_ci            for (i = 0; i + 3 < count; i += 2) {
249bf215546Sopenharmony_ci               idx[0] = idx[2];
250bf215546Sopenharmony_ci               idx[1] = idx[3];
251bf215546Sopenharmony_ci               idx[2] = GET_ELT(i + 2);
252bf215546Sopenharmony_ci               idx[3] = GET_ELT(i + 3);
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci#ifdef PASS_QUADS
255bf215546Sopenharmony_ci               QUAD(0, idx[3], idx[2],
256bf215546Sopenharmony_ci                    idx[0], idx[1]);
257bf215546Sopenharmony_ci#else
258bf215546Sopenharmony_ci               flags = DRAW_PIPE_RESET_STIPPLE |
259bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_0 |
260bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_1;
261bf215546Sopenharmony_ci               /* always emit idx[3] / idx[0 first */
262bf215546Sopenharmony_ci               if (quads_flatshade_last)
263bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[3], idx[2], idx[0]);
264bf215546Sopenharmony_ci               else
265bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[0], idx[3], idx[2]);
266bf215546Sopenharmony_ci
267bf215546Sopenharmony_ci               flags = DRAW_PIPE_EDGE_FLAG_1 |
268bf215546Sopenharmony_ci                       DRAW_PIPE_EDGE_FLAG_2;
269bf215546Sopenharmony_ci               if (quads_flatshade_last)
270bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[3], idx[0], idx[1]);
271bf215546Sopenharmony_ci               else
272bf215546Sopenharmony_ci                  TRIANGLE(flags, idx[0], idx[1], idx[3]);
273bf215546Sopenharmony_ci#endif
274bf215546Sopenharmony_ci            }
275bf215546Sopenharmony_ci         }
276bf215546Sopenharmony_ci      }
277bf215546Sopenharmony_ci      break;
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci   case PIPE_PRIM_POLYGON:
280bf215546Sopenharmony_ci      if (count >= 3) {
281bf215546Sopenharmony_ci         ushort edge_next, edge_finish;
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci         if (last_vertex_last) {
284bf215546Sopenharmony_ci            flags = (DRAW_PIPE_RESET_STIPPLE |
285bf215546Sopenharmony_ci                     DRAW_PIPE_EDGE_FLAG_0);
286bf215546Sopenharmony_ci            if (!(prim_flags & DRAW_SPLIT_BEFORE))
287bf215546Sopenharmony_ci               flags |= DRAW_PIPE_EDGE_FLAG_2;
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci            edge_next = DRAW_PIPE_EDGE_FLAG_0;
290bf215546Sopenharmony_ci            edge_finish =
291bf215546Sopenharmony_ci               (prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_1;
292bf215546Sopenharmony_ci         }
293bf215546Sopenharmony_ci         else {
294bf215546Sopenharmony_ci            flags = (DRAW_PIPE_RESET_STIPPLE |
295bf215546Sopenharmony_ci                     DRAW_PIPE_EDGE_FLAG_1);
296bf215546Sopenharmony_ci            if (!(prim_flags & DRAW_SPLIT_BEFORE))
297bf215546Sopenharmony_ci               flags |= DRAW_PIPE_EDGE_FLAG_0;
298bf215546Sopenharmony_ci
299bf215546Sopenharmony_ci            edge_next = DRAW_PIPE_EDGE_FLAG_1;
300bf215546Sopenharmony_ci            edge_finish =
301bf215546Sopenharmony_ci               (prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_2;
302bf215546Sopenharmony_ci         }
303bf215546Sopenharmony_ci
304bf215546Sopenharmony_ci         idx[0] = GET_ELT(0);
305bf215546Sopenharmony_ci         idx[2] = GET_ELT(1);
306bf215546Sopenharmony_ci
307bf215546Sopenharmony_ci         for (i = 0; i + 2 < count; i++, flags = edge_next) {
308bf215546Sopenharmony_ci            idx[1] = idx[2];
309bf215546Sopenharmony_ci            idx[2] = GET_ELT(i + 2);
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_ci            if (i + 3 == count)
312bf215546Sopenharmony_ci               flags |= edge_finish;
313bf215546Sopenharmony_ci
314bf215546Sopenharmony_ci            /* idx[0] is both the first and the last vertex */
315bf215546Sopenharmony_ci            if (last_vertex_last)
316bf215546Sopenharmony_ci               TRIANGLE(flags, idx[1], idx[2], idx[0]);
317bf215546Sopenharmony_ci            else
318bf215546Sopenharmony_ci               TRIANGLE(flags, idx[0], idx[1], idx[2]);
319bf215546Sopenharmony_ci         }
320bf215546Sopenharmony_ci      }
321bf215546Sopenharmony_ci      break;
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci   case PIPE_PRIM_LINES_ADJACENCY:
324bf215546Sopenharmony_ci      flags = DRAW_PIPE_RESET_STIPPLE;
325bf215546Sopenharmony_ci      for (i = 0; i + 3 < count; i += 4) {
326bf215546Sopenharmony_ci         idx[0] = GET_ELT(i);
327bf215546Sopenharmony_ci         idx[1] = GET_ELT(i + 1);
328bf215546Sopenharmony_ci         idx[2] = GET_ELT(i + 2);
329bf215546Sopenharmony_ci         idx[3] = GET_ELT(i + 3);
330bf215546Sopenharmony_ci         LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
331bf215546Sopenharmony_ci      }
332bf215546Sopenharmony_ci      break;
333bf215546Sopenharmony_ci
334bf215546Sopenharmony_ci   case PIPE_PRIM_LINE_STRIP_ADJACENCY:
335bf215546Sopenharmony_ci      if (count >= 4) {
336bf215546Sopenharmony_ci         flags = (prim_flags & DRAW_SPLIT_BEFORE) ? 0 : DRAW_PIPE_RESET_STIPPLE;
337bf215546Sopenharmony_ci         idx[1] = GET_ELT(0);
338bf215546Sopenharmony_ci         idx[2] = GET_ELT(1);
339bf215546Sopenharmony_ci         idx[3] = GET_ELT(2);
340bf215546Sopenharmony_ci
341bf215546Sopenharmony_ci         for (i = 1; i + 2 < count; i++, flags = 0) {
342bf215546Sopenharmony_ci            idx[0] = idx[1];
343bf215546Sopenharmony_ci            idx[1] = idx[2];
344bf215546Sopenharmony_ci            idx[2] = idx[3];
345bf215546Sopenharmony_ci            idx[3] = GET_ELT(i + 2);
346bf215546Sopenharmony_ci            LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
347bf215546Sopenharmony_ci         }
348bf215546Sopenharmony_ci      }
349bf215546Sopenharmony_ci      break;
350bf215546Sopenharmony_ci
351bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLES_ADJACENCY:
352bf215546Sopenharmony_ci      flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
353bf215546Sopenharmony_ci      for (i = 0; i + 5 < count; i += 6) {
354bf215546Sopenharmony_ci         idx[0] = GET_ELT(i);
355bf215546Sopenharmony_ci         idx[1] = GET_ELT(i + 1);
356bf215546Sopenharmony_ci         idx[2] = GET_ELT(i + 2);
357bf215546Sopenharmony_ci         idx[3] = GET_ELT(i + 3);
358bf215546Sopenharmony_ci         idx[4] = GET_ELT(i + 4);
359bf215546Sopenharmony_ci         idx[5] = GET_ELT(i + 5);
360bf215546Sopenharmony_ci         TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
361bf215546Sopenharmony_ci      }
362bf215546Sopenharmony_ci      break;
363bf215546Sopenharmony_ci
364bf215546Sopenharmony_ci   case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
365bf215546Sopenharmony_ci      if (count >= 6) {
366bf215546Sopenharmony_ci         flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
367bf215546Sopenharmony_ci         idx[0] = GET_ELT(1);
368bf215546Sopenharmony_ci         idx[2] = GET_ELT(0);
369bf215546Sopenharmony_ci         idx[4] = GET_ELT(2);
370bf215546Sopenharmony_ci         idx[3] = GET_ELT(4);
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci         /*
373bf215546Sopenharmony_ci          * The vertices of the i-th triangle are stored in
374bf215546Sopenharmony_ci          * idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 };
375bf215546Sopenharmony_ci          *
376bf215546Sopenharmony_ci          * The adjacent vertices are stored in
377bf215546Sopenharmony_ci          * idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }.
378bf215546Sopenharmony_ci          *
379bf215546Sopenharmony_ci          * However, there are two exceptions:
380bf215546Sopenharmony_ci          *
381bf215546Sopenharmony_ci          * For the first triangle, idx[1] = 1;
382bf215546Sopenharmony_ci          * For the  last triangle, idx[3] = 2*i+5.
383bf215546Sopenharmony_ci          */
384bf215546Sopenharmony_ci         if (last_vertex_last) {
385bf215546Sopenharmony_ci            for (i = 0; i + 5 < count; i += 2) {
386bf215546Sopenharmony_ci               idx[1] = idx[0];
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci               idx[0] = idx[2];
389bf215546Sopenharmony_ci               idx[2] = idx[4];
390bf215546Sopenharmony_ci               idx[4] = idx[3];
391bf215546Sopenharmony_ci
392bf215546Sopenharmony_ci               idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
393bf215546Sopenharmony_ci               idx[5] = GET_ELT(i + 3);
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci               /*
396bf215546Sopenharmony_ci                * alternate the first two vertices (idx[0] and idx[2]) and the
397bf215546Sopenharmony_ci                * corresponding adjacent vertices (idx[3] and idx[5]) to have
398bf215546Sopenharmony_ci                * the correct orientation
399bf215546Sopenharmony_ci                */
400bf215546Sopenharmony_ci               if (i & 2) {
401bf215546Sopenharmony_ci                  TRIANGLE_ADJ(flags,
402bf215546Sopenharmony_ci                        idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]);
403bf215546Sopenharmony_ci               }
404bf215546Sopenharmony_ci               else {
405bf215546Sopenharmony_ci                  TRIANGLE_ADJ(flags,
406bf215546Sopenharmony_ci                        idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
407bf215546Sopenharmony_ci               }
408bf215546Sopenharmony_ci            }
409bf215546Sopenharmony_ci         }
410bf215546Sopenharmony_ci         else {
411bf215546Sopenharmony_ci            for (i = 0; i + 5 < count; i += 2) {
412bf215546Sopenharmony_ci               idx[1] = idx[0];
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci               idx[0] = idx[2];
415bf215546Sopenharmony_ci               idx[2] = idx[4];
416bf215546Sopenharmony_ci               idx[4] = idx[3];
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_ci               idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
419bf215546Sopenharmony_ci               idx[5] = GET_ELT(i + 3);
420bf215546Sopenharmony_ci
421bf215546Sopenharmony_ci               /*
422bf215546Sopenharmony_ci                * alternate the last two vertices (idx[2] and idx[4]) and the
423bf215546Sopenharmony_ci                * corresponding adjacent vertices (idx[1] and idx[5]) to have
424bf215546Sopenharmony_ci                * the correct orientation
425bf215546Sopenharmony_ci                */
426bf215546Sopenharmony_ci               if (i & 2) {
427bf215546Sopenharmony_ci                  TRIANGLE_ADJ(flags,
428bf215546Sopenharmony_ci                        idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]);
429bf215546Sopenharmony_ci               }
430bf215546Sopenharmony_ci               else {
431bf215546Sopenharmony_ci                  TRIANGLE_ADJ(flags,
432bf215546Sopenharmony_ci                        idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
433bf215546Sopenharmony_ci               }
434bf215546Sopenharmony_ci            }
435bf215546Sopenharmony_ci         }
436bf215546Sopenharmony_ci      }
437bf215546Sopenharmony_ci      break;
438bf215546Sopenharmony_ci
439bf215546Sopenharmony_ci   default:
440bf215546Sopenharmony_ci      assert(0);
441bf215546Sopenharmony_ci      break;
442bf215546Sopenharmony_ci   }
443bf215546Sopenharmony_ci
444bf215546Sopenharmony_ci   FUNC_EXIT;
445bf215546Sopenharmony_ci}
446bf215546Sopenharmony_ci
447bf215546Sopenharmony_ci#undef LOCAL_VARS
448bf215546Sopenharmony_ci#undef FUNC_ENTER
449bf215546Sopenharmony_ci#undef FUNC_EXIT
450bf215546Sopenharmony_ci#undef LINE_ADJ
451bf215546Sopenharmony_ci#undef TRIANGLE_ADJ
452bf215546Sopenharmony_ci
453bf215546Sopenharmony_ci#undef FUNC
454bf215546Sopenharmony_ci#undef FUNC_VARS
455bf215546Sopenharmony_ci#undef GET_ELT
456bf215546Sopenharmony_ci#undef POINT
457bf215546Sopenharmony_ci#undef LINE
458bf215546Sopenharmony_ci#undef TRIANGLE
459