Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / unichrome / via_vb_rendertmp.h
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #ifndef POSTFIX
27 #define POSTFIX
28 #endif
29
30 #ifndef INIT
31 #define INIT(x)
32 #endif
33
34 #ifndef NEED_EDGEFLAG_SETUP
35 #define NEED_EDGEFLAG_SETUP 0
36 #define EDGEFLAG_GET(a) 0
37 #define EDGEFLAG_SET(a,b) (void)b
38 #endif
39
40 #ifndef RESET_STIPPLE
41 #define RESET_STIPPLE
42 #endif
43
44 #ifndef RESET_OCCLUSION
45 #define RESET_OCCLUSION
46 #endif
47
48 #ifndef TEST_PRIM_END
49 #define TEST_PRIM_END(flags) (flags & PRIM_END)
50 #define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
51 #define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
52 #endif
53
54 #ifndef ELT
55 #define ELT(x) x
56 #endif
57
58 #ifndef RENDER_TAB_QUALIFIER
59 #define RENDER_TAB_QUALIFIER static
60 #endif
61
62 static void TAG(render_points)(GLcontext *ctx,
63 GLuint start,
64 GLuint count,
65 GLuint flags)
66 {
67 LOCAL_VARS;
68 (void)flags;
69 #ifdef PERFORMANCE_MEASURE
70 if (VIA_PERFORMANCE) P_M;
71 #endif
72
73 RESET_OCCLUSION;
74 INIT(GL_POINTS);
75 RENDER_POINTS(start, count);
76 POSTFIX;
77 }
78
79 static void TAG(render_lines)(GLcontext *ctx,
80 GLuint start,
81 GLuint count,
82 GLuint flags)
83 {
84 GLuint j;
85 LOCAL_VARS;
86 (void)flags;
87
88 #ifdef PERFORMANCE_MEASURE
89 if (VIA_PERFORMANCE) P_M;
90 #endif
91 RESET_OCCLUSION;
92 INIT(GL_LINES);
93 for (j = start + 1; j < count; j += 2) {
94 RESET_STIPPLE;
95 RENDER_LINE(ELT(j - 1), ELT(j));
96 }
97 POSTFIX;
98 }
99
100 static void TAG(render_line_strip)(GLcontext *ctx,
101 GLuint start,
102 GLuint count,
103 GLuint flags)
104 {
105 GLuint j;
106 LOCAL_VARS;
107 (void)flags;
108 #ifdef DEBUG
109 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
110 #endif
111 #ifdef PERFORMANCE_MEASURE
112 if (VIA_PERFORMANCE) P_M;
113 #endif
114 RESET_OCCLUSION;
115 INIT(GL_LINES);
116
117 if (TEST_PRIM_BEGIN(flags)) {
118 RESET_STIPPLE;
119 }
120
121 for (j = start + 1; j < count; j++)
122 RENDER_LINE(ELT(j - 1), ELT(j));
123
124 POSTFIX;
125 #ifdef DEBUG
126 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
127 #endif
128 }
129
130 static void TAG(render_line_loop)(GLcontext *ctx,
131 GLuint start,
132 GLuint count,
133 GLuint flags)
134 {
135 GLuint i;
136 LOCAL_VARS;
137 (void)flags;
138 #ifdef DEBUG
139 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
140 #endif
141 #ifdef PERFORMANCE_MEASURE
142 if (VIA_PERFORMANCE) P_M;
143 #endif
144 RESET_OCCLUSION;
145 INIT(GL_LINES);
146
147 if (start + 1 < count) {
148 if (TEST_PRIM_BEGIN(flags)) {
149 RESET_STIPPLE;
150 RENDER_LINE(ELT(start), ELT(start + 1));
151 }
152
153 for (i = start + 2 ; i < count ; i++) {
154 RENDER_LINE(ELT(i - 1), ELT(i));
155 }
156
157 if (TEST_PRIM_END(flags)) {
158 RENDER_LINE(ELT(count - 1), ELT(start));
159 }
160 }
161
162 POSTFIX;
163 #ifdef DEBUG
164 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
165 #endif
166 }
167
168 static void TAG(render_triangles)(GLcontext *ctx,
169 GLuint start,
170 GLuint count,
171 GLuint flags)
172 {
173 GLuint j;
174 LOCAL_VARS;
175 (void)flags;
176 #ifdef DEBUG
177 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
178 #endif
179 #ifdef PERFORMANCE_MEASURE
180 if (VIA_PERFORMANCE) P_M;
181 #endif
182 INIT(GL_TRIANGLES);
183 if (NEED_EDGEFLAG_SETUP) {
184 for (j = start + 2; j < count; j += 3) {
185 /* Leave the edgeflags as supplied by the user.
186 */
187 RESET_STIPPLE;
188 RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
189 }
190 }
191 else {
192 for (j = start + 2; j < count; j += 3) {
193 RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
194 }
195 }
196 POSTFIX;
197 #ifdef DEBUG
198 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
199 #endif
200 }
201
202 static void TAG(render_tri_strip)(GLcontext *ctx,
203 GLuint start,
204 GLuint count,
205 GLuint flags)
206 {
207 GLuint j;
208 GLuint parity = 0;
209 LOCAL_VARS;
210 #ifdef DEBUG
211 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
212 #endif
213 #ifdef PERFORMANCE_MEASURE
214 if (VIA_PERFORMANCE) P_M;
215 #endif
216 INIT(GL_TRIANGLES);
217
218 if (NEED_EDGEFLAG_SETUP) {
219 for (j = start + 2; j < count; j++, parity ^= 1) {
220 GLuint ej2 = ELT(j - 2 + parity);
221 GLuint ej1 = ELT(j - 1 - parity);
222 GLuint ej = ELT(j);
223 GLboolean ef2 = EDGEFLAG_GET(ej2);
224 GLboolean ef1 = EDGEFLAG_GET(ej1);
225 GLboolean ef = EDGEFLAG_GET(ej);
226 if (TEST_PRIM_BEGIN(flags)) {
227 RESET_STIPPLE;
228 }
229 EDGEFLAG_SET(ej2, GL_TRUE);
230 EDGEFLAG_SET(ej1, GL_TRUE);
231 EDGEFLAG_SET(ej, GL_TRUE);
232 RENDER_TRI(ej2, ej1, ej);
233 EDGEFLAG_SET(ej2, ef2);
234 EDGEFLAG_SET(ej1, ef1);
235 EDGEFLAG_SET(ej, ef);
236 }
237 }
238 else {
239 for (j = start + 2; j < count; j++, parity ^= 1) {
240 RENDER_TRI(ELT(j - 2 + parity), ELT(j - 1 - parity), ELT(j));
241 }
242 }
243 POSTFIX;
244 #ifdef DEBUG
245 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
246 #endif
247 }
248
249 static void TAG(render_tri_fan)(GLcontext *ctx,
250 GLuint start,
251 GLuint count,
252 GLuint flags)
253 {
254 GLuint j;
255 LOCAL_VARS;
256 (void)flags;
257 #ifdef DEBUG
258 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
259 #endif
260 #ifdef PERFORMANCE_MEASURE
261 if (VIA_PERFORMANCE) P_M;
262 #endif
263 INIT(GL_TRIANGLES);
264 if (NEED_EDGEFLAG_SETUP) {
265 for (j = start + 2; j < count; j++) {
266 /* For trifans, all edges are boundary.
267 */
268 GLuint ejs = ELT(start);
269 GLuint ej1 = ELT(j - 1);
270 GLuint ej = ELT(j);
271 GLboolean efs = EDGEFLAG_GET(ejs);
272 GLboolean ef1 = EDGEFLAG_GET(ej1);
273 GLboolean ef = EDGEFLAG_GET(ej);
274 if (TEST_PRIM_BEGIN(flags)) {
275 RESET_STIPPLE;
276 }
277 EDGEFLAG_SET(ejs, GL_TRUE);
278 EDGEFLAG_SET(ej1, GL_TRUE);
279 EDGEFLAG_SET(ej, GL_TRUE);
280 RENDER_TRI(ejs, ej1, ej);
281 EDGEFLAG_SET(ejs, efs);
282 EDGEFLAG_SET(ej1, ef1);
283 EDGEFLAG_SET(ej, ef);
284 }
285 }
286 else {
287 for (j = start + 2; j < count; j++) {
288 RENDER_TRI(ELT(start), ELT(j - 1), ELT(j));
289 }
290 }
291
292 POSTFIX;
293 #ifdef DEBUG
294 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
295 #endif
296 }
297
298 static void TAG(render_poly)(GLcontext *ctx,
299 GLuint start,
300 GLuint count,
301 GLuint flags)
302 {
303 GLuint j = start + 2;
304 LOCAL_VARS;
305 (void)flags;
306 #ifdef DEBUG
307 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
308 #endif
309 #ifdef PERFORMANCE_MEASURE
310 if (VIA_PERFORMANCE) P_M;
311 #endif
312 INIT(GL_TRIANGLES);
313
314 if (NEED_EDGEFLAG_SETUP) {
315 GLboolean efstart = EDGEFLAG_GET(ELT(start));
316 GLboolean efcount = EDGEFLAG_GET(ELT(count - 1));
317
318 /* If the primitive does not begin here, the first edge
319 * is non-boundary.
320 */
321 if (!TEST_PRIM_BEGIN(flags)) {
322 EDGEFLAG_SET(ELT(start), GL_FALSE);
323 }
324 else {
325 RESET_STIPPLE;
326 }
327
328 /* If the primitive does not end here, the final edge is
329 * non-boundary.
330 */
331 if (!TEST_PRIM_END(flags)) {
332 EDGEFLAG_SET(ELT(count - 1), GL_FALSE);
333 }
334
335 /* Draw the first triangles (possibly zero)
336 */
337 if (j+1<count) {
338 GLboolean ef = EDGEFLAG_GET(ELT(j));
339 EDGEFLAG_SET(ELT(j), GL_FALSE);
340 RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
341 EDGEFLAG_SET(ELT(j), ef);
342 j++;
343
344 /* Don't render the first edge again:
345 */
346 EDGEFLAG_SET(ELT(start), GL_FALSE);
347
348 for (;j+1<count;j++) {
349 GLboolean efj = EDGEFLAG_GET(ELT(j));
350 EDGEFLAG_SET(ELT(j), GL_FALSE);
351 RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
352 EDGEFLAG_SET(ELT(j), efj);
353 }
354 }
355
356 /* Draw the last or only triangle
357 */
358 if (j < count) {
359 RENDER_TRI(ELT(j-1), ELT(j), ELT(start));
360 }
361
362 /* Restore the first and last edgeflags:
363 */
364 EDGEFLAG_SET(ELT(count - 1), efcount);
365 EDGEFLAG_SET(ELT(start), efstart);
366 }
367 else {
368 for (j = start + 2; j < count; j++) {
369 RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
370 }
371 }
372 POSTFIX;
373 #ifdef DEBUG
374 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
375 #endif
376 }
377
378 static void TAG(render_quads)(GLcontext *ctx,
379 GLuint start,
380 GLuint count,
381 GLuint flags)
382 {
383 GLuint j;
384 LOCAL_VARS;
385 (void)flags;
386 #ifdef DEBUG
387 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
388 #endif
389 #ifdef PERFORMANCE_MEASURE
390 if (VIA_PERFORMANCE) P_M;
391 #endif
392 INIT(GL_TRIANGLES);
393 if (NEED_EDGEFLAG_SETUP) {
394 for (j = start + 3; j < count; j += 4) {
395 /* Use user-specified edgeflags for quads.
396 */
397 RESET_STIPPLE;
398 RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
399 }
400 }
401 else {
402 for (j = start + 3; j < count; j += 4) {
403 RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
404 }
405 }
406 POSTFIX;
407 #ifdef DEBUG
408 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
409 #endif
410 }
411
412 static void TAG(render_quad_strip)(GLcontext *ctx,
413 GLuint start,
414 GLuint count,
415 GLuint flags)
416 {
417 GLuint j;
418 LOCAL_VARS;
419 (void)flags;
420 #ifdef DEBUG
421 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
422 #endif
423 #ifdef PERFORMANCE_MEASURE
424 if (VIA_PERFORMANCE) P_M;
425 #endif
426 INIT(GL_TRIANGLES);
427 if (NEED_EDGEFLAG_SETUP) {
428 for (j = start + 3; j < count; j += 2) {
429 /* All edges are boundary. Set edgeflags to 1, draw the
430 * quad, and restore them to the original values.
431 */
432 GLboolean ef3 = EDGEFLAG_GET(ELT(j - 3));
433 GLboolean ef2 = EDGEFLAG_GET(ELT(j - 2));
434 GLboolean ef1 = EDGEFLAG_GET(ELT(j - 1));
435 GLboolean ef = EDGEFLAG_GET(ELT(j));
436 if (TEST_PRIM_BEGIN(flags)) {
437 RESET_STIPPLE;
438 }
439 EDGEFLAG_SET(ELT(j - 3), GL_TRUE);
440 EDGEFLAG_SET(ELT(j - 2), GL_TRUE);
441 EDGEFLAG_SET(ELT(j - 1), GL_TRUE);
442 EDGEFLAG_SET(ELT(j), GL_TRUE);
443 RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
444 EDGEFLAG_SET(ELT(j - 3), ef3);
445 EDGEFLAG_SET(ELT(j - 2), ef2);
446 EDGEFLAG_SET(ELT(j - 1), ef1);
447 EDGEFLAG_SET(ELT(j), ef);
448 }
449 }
450 else {
451 for (j = start + 3; j < count; j += 2) {
452 RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
453 }
454 }
455 POSTFIX;
456 #ifdef DEBUG
457 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
458 #endif
459 }
460
461 static void TAG(render_noop)(GLcontext *ctx,
462 GLuint start,
463 GLuint count,
464 GLuint flags)
465 {
466 (void)(ctx && start && count && flags);
467 }
468
469 RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON + 2])(GLcontext *,
470 GLuint,
471 GLuint,
472 GLuint) =
473 {
474 TAG(render_points),
475 TAG(render_lines),
476 TAG(render_line_loop),
477 TAG(render_line_strip),
478 TAG(render_triangles),
479 TAG(render_tri_strip),
480 TAG(render_tri_fan),
481 TAG(render_quads),
482 TAG(render_quad_strip),
483 TAG(render_poly),
484 TAG(render_noop),
485 };
486
487 #ifndef PRESERVE_VB_DEFS
488 #undef RENDER_TRI
489 #undef RENDER_QUAD
490 #undef RENDER_LINE
491 #undef RENDER_POINTS
492 #undef LOCAL_VARS
493 #undef INIT
494 #undef POSTFIX
495 #undef RESET_STIPPLE
496 #undef DBG
497 #undef ELT
498 #undef RENDER_TAB_QUALIFIER
499 #endif
500
501 #ifndef PRESERVE_TAG
502 #undef TAG
503 #endif
504
505 #undef PRESERVE_VB_DEFS
506 #undef PRESERVE_TAG