~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to src/gallium/auxiliary/draw/draw_decompose_tmp.h

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

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