Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/auxiliary/draw/draw_decompose_tmp.h
4565 views
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 <[email protected]>
27
* Chia-I Wu <[email protected]>
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
174
flags = DRAW_PIPE_RESET_STIPPLE |
175
DRAW_PIPE_EDGE_FLAG_0 |
176
DRAW_PIPE_EDGE_FLAG_2;
177
/* always emit idx[3] last */
178
TRIANGLE(flags, idx[0], idx[1], idx[3]);
179
180
flags = DRAW_PIPE_EDGE_FLAG_0 |
181
DRAW_PIPE_EDGE_FLAG_1;
182
TRIANGLE(flags, idx[1], idx[2], idx[3]);
183
}
184
}
185
else {
186
for (i = 0; i + 3 < count; i += 4) {
187
idx[0] = GET_ELT(i);
188
idx[1] = GET_ELT(i + 1);
189
idx[2] = GET_ELT(i + 2);
190
idx[3] = GET_ELT(i + 3);
191
192
flags = DRAW_PIPE_RESET_STIPPLE |
193
DRAW_PIPE_EDGE_FLAG_0 |
194
DRAW_PIPE_EDGE_FLAG_1;
195
/* always emit idx[3] / idx[0] first */
196
if (quads_flatshade_last)
197
TRIANGLE(flags, idx[3], idx[0], idx[1]);
198
else
199
TRIANGLE(flags, idx[0], idx[1], idx[2]);
200
201
flags = DRAW_PIPE_EDGE_FLAG_1 |
202
DRAW_PIPE_EDGE_FLAG_2;
203
if (quads_flatshade_last)
204
TRIANGLE(flags, idx[3], idx[1], idx[2]);
205
else
206
TRIANGLE(flags, idx[0], idx[2], idx[3]);
207
}
208
}
209
break;
210
211
case PIPE_PRIM_QUAD_STRIP:
212
if (count >= 4) {
213
idx[2] = GET_ELT(0);
214
idx[3] = GET_ELT(1);
215
216
if (last_vertex_last) {
217
for (i = 0; i + 3 < count; i += 2) {
218
idx[0] = idx[2];
219
idx[1] = idx[3];
220
idx[2] = GET_ELT(i + 2);
221
idx[3] = GET_ELT(i + 3);
222
223
/* always emit idx[3] last */
224
flags = DRAW_PIPE_RESET_STIPPLE |
225
DRAW_PIPE_EDGE_FLAG_0 |
226
DRAW_PIPE_EDGE_FLAG_2;
227
TRIANGLE(flags, idx[2], idx[0], idx[3]);
228
229
flags = DRAW_PIPE_EDGE_FLAG_0 |
230
DRAW_PIPE_EDGE_FLAG_1;
231
TRIANGLE(flags, idx[0], idx[1], idx[3]);
232
}
233
}
234
else {
235
for (i = 0; i + 3 < count; i += 2) {
236
idx[0] = idx[2];
237
idx[1] = idx[3];
238
idx[2] = GET_ELT(i + 2);
239
idx[3] = GET_ELT(i + 3);
240
241
flags = DRAW_PIPE_RESET_STIPPLE |
242
DRAW_PIPE_EDGE_FLAG_0 |
243
DRAW_PIPE_EDGE_FLAG_1;
244
/* always emit idx[3] / idx[0 first */
245
if (quads_flatshade_last)
246
TRIANGLE(flags, idx[3], idx[2], idx[0]);
247
else
248
TRIANGLE(flags, idx[0], idx[3], idx[2]);
249
250
flags = DRAW_PIPE_EDGE_FLAG_1 |
251
DRAW_PIPE_EDGE_FLAG_2;
252
if (quads_flatshade_last)
253
TRIANGLE(flags, idx[3], idx[0], idx[1]);
254
else
255
TRIANGLE(flags, idx[0], idx[1], idx[3]);
256
}
257
}
258
}
259
break;
260
261
case PIPE_PRIM_POLYGON:
262
if (count >= 3) {
263
ushort edge_next, edge_finish;
264
265
if (last_vertex_last) {
266
flags = (DRAW_PIPE_RESET_STIPPLE |
267
DRAW_PIPE_EDGE_FLAG_0);
268
if (!(prim_flags & DRAW_SPLIT_BEFORE))
269
flags |= DRAW_PIPE_EDGE_FLAG_2;
270
271
edge_next = DRAW_PIPE_EDGE_FLAG_0;
272
edge_finish =
273
(prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_1;
274
}
275
else {
276
flags = (DRAW_PIPE_RESET_STIPPLE |
277
DRAW_PIPE_EDGE_FLAG_1);
278
if (!(prim_flags & DRAW_SPLIT_BEFORE))
279
flags |= DRAW_PIPE_EDGE_FLAG_0;
280
281
edge_next = DRAW_PIPE_EDGE_FLAG_1;
282
edge_finish =
283
(prim_flags & DRAW_SPLIT_AFTER) ? 0 : DRAW_PIPE_EDGE_FLAG_2;
284
}
285
286
idx[0] = GET_ELT(0);
287
idx[2] = GET_ELT(1);
288
289
for (i = 0; i + 2 < count; i++, flags = edge_next) {
290
idx[1] = idx[2];
291
idx[2] = GET_ELT(i + 2);
292
293
if (i + 3 == count)
294
flags |= edge_finish;
295
296
/* idx[0] is both the first and the last vertex */
297
if (last_vertex_last)
298
TRIANGLE(flags, idx[1], idx[2], idx[0]);
299
else
300
TRIANGLE(flags, idx[0], idx[1], idx[2]);
301
}
302
}
303
break;
304
305
case PIPE_PRIM_LINES_ADJACENCY:
306
flags = DRAW_PIPE_RESET_STIPPLE;
307
for (i = 0; i + 3 < count; i += 4) {
308
idx[0] = GET_ELT(i);
309
idx[1] = GET_ELT(i + 1);
310
idx[2] = GET_ELT(i + 2);
311
idx[3] = GET_ELT(i + 3);
312
LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
313
}
314
break;
315
316
case PIPE_PRIM_LINE_STRIP_ADJACENCY:
317
if (count >= 4) {
318
flags = (prim_flags & DRAW_SPLIT_BEFORE) ? 0 : DRAW_PIPE_RESET_STIPPLE;
319
idx[1] = GET_ELT(0);
320
idx[2] = GET_ELT(1);
321
idx[3] = GET_ELT(2);
322
323
for (i = 1; i + 2 < count; i++, flags = 0) {
324
idx[0] = idx[1];
325
idx[1] = idx[2];
326
idx[2] = idx[3];
327
idx[3] = GET_ELT(i + 2);
328
LINE_ADJ(flags, idx[0], idx[1], idx[2], idx[3]);
329
}
330
}
331
break;
332
333
case PIPE_PRIM_TRIANGLES_ADJACENCY:
334
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
335
for (i = 0; i + 5 < count; i += 6) {
336
idx[0] = GET_ELT(i);
337
idx[1] = GET_ELT(i + 1);
338
idx[2] = GET_ELT(i + 2);
339
idx[3] = GET_ELT(i + 3);
340
idx[4] = GET_ELT(i + 4);
341
idx[5] = GET_ELT(i + 5);
342
TRIANGLE_ADJ(flags, idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
343
}
344
break;
345
346
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY:
347
if (count >= 6) {
348
flags = DRAW_PIPE_RESET_STIPPLE | DRAW_PIPE_EDGE_FLAG_ALL;
349
idx[0] = GET_ELT(1);
350
idx[2] = GET_ELT(0);
351
idx[4] = GET_ELT(2);
352
idx[3] = GET_ELT(4);
353
354
/*
355
* The vertices of the i-th triangle are stored in
356
* idx[0,2,4] = { 2*i, 2*i+2, 2*i+4 };
357
*
358
* The adjacent vertices are stored in
359
* idx[1,3,5] = { 2*i-2, 2*i+6, 2*i+3 }.
360
*
361
* However, there are two exceptions:
362
*
363
* For the first triangle, idx[1] = 1;
364
* For the last triangle, idx[3] = 2*i+5.
365
*/
366
if (last_vertex_last) {
367
for (i = 0; i + 5 < count; i += 2) {
368
idx[1] = idx[0];
369
370
idx[0] = idx[2];
371
idx[2] = idx[4];
372
idx[4] = idx[3];
373
374
idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
375
idx[5] = GET_ELT(i + 3);
376
377
/*
378
* alternate the first two vertices (idx[0] and idx[2]) and the
379
* corresponding adjacent vertices (idx[3] and idx[5]) to have
380
* the correct orientation
381
*/
382
if (i & 2) {
383
TRIANGLE_ADJ(flags,
384
idx[2], idx[1], idx[0], idx[5], idx[4], idx[3]);
385
}
386
else {
387
TRIANGLE_ADJ(flags,
388
idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
389
}
390
}
391
}
392
else {
393
for (i = 0; i + 5 < count; i += 2) {
394
idx[1] = idx[0];
395
396
idx[0] = idx[2];
397
idx[2] = idx[4];
398
idx[4] = idx[3];
399
400
idx[3] = GET_ELT(i + ((i + 7 < count) ? 6 : 5));
401
idx[5] = GET_ELT(i + 3);
402
403
/*
404
* alternate the last two vertices (idx[2] and idx[4]) and the
405
* corresponding adjacent vertices (idx[1] and idx[5]) to have
406
* the correct orientation
407
*/
408
if (i & 2) {
409
TRIANGLE_ADJ(flags,
410
idx[0], idx[5], idx[4], idx[3], idx[2], idx[1]);
411
}
412
else {
413
TRIANGLE_ADJ(flags,
414
idx[0], idx[1], idx[2], idx[3], idx[4], idx[5]);
415
}
416
}
417
}
418
}
419
break;
420
421
default:
422
assert(0);
423
break;
424
}
425
426
FUNC_EXIT;
427
}
428
429
#undef LOCAL_VARS
430
#undef FUNC_ENTER
431
#undef FUNC_EXIT
432
#undef LINE_ADJ
433
#undef TRIANGLE_ADJ
434
435
#undef FUNC
436
#undef FUNC_VARS
437
#undef GET_ELT
438
#undef POINT
439
#undef LINE
440
#undef TRIANGLE
441
442