2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
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
44 #ifndef RESET_OCCLUSION
45 #define RESET_OCCLUSION
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)
58 #ifndef RENDER_TAB_QUALIFIER
59 #define RENDER_TAB_QUALIFIER static
62 static void TAG(render_points
)(GLcontext
*ctx
,
69 #ifdef PERFORMANCE_MEASURE
70 if (VIA_PERFORMANCE
) P_M
;
75 RENDER_POINTS(start
, count
);
79 static void TAG(render_lines
)(GLcontext
*ctx
,
88 #ifdef PERFORMANCE_MEASURE
89 if (VIA_PERFORMANCE
) P_M
;
93 for (j
= start
+ 1; j
< count
; j
+= 2) {
95 RENDER_LINE(ELT(j
- 1), ELT(j
));
100 static void TAG(render_line_strip
)(GLcontext
*ctx
,
109 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
111 #ifdef PERFORMANCE_MEASURE
112 if (VIA_PERFORMANCE
) P_M
;
117 if (TEST_PRIM_BEGIN(flags
)) {
121 for (j
= start
+ 1; j
< count
; j
++)
122 RENDER_LINE(ELT(j
- 1), ELT(j
));
126 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
130 static void TAG(render_line_loop
)(GLcontext
*ctx
,
139 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
141 #ifdef PERFORMANCE_MEASURE
142 if (VIA_PERFORMANCE
) P_M
;
147 if (start
+ 1 < count
) {
148 if (TEST_PRIM_BEGIN(flags
)) {
150 RENDER_LINE(ELT(start
), ELT(start
+ 1));
153 for (i
= start
+ 2 ; i
< count
; i
++) {
154 RENDER_LINE(ELT(i
- 1), ELT(i
));
157 if (TEST_PRIM_END(flags
)) {
158 RENDER_LINE(ELT(count
- 1), ELT(start
));
164 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
168 static void TAG(render_triangles
)(GLcontext
*ctx
,
177 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
179 #ifdef PERFORMANCE_MEASURE
180 if (VIA_PERFORMANCE
) P_M
;
183 if (NEED_EDGEFLAG_SETUP
) {
184 for (j
= start
+ 2; j
< count
; j
+= 3) {
185 /* Leave the edgeflags as supplied by the user.
188 RENDER_TRI(ELT(j
- 2), ELT(j
- 1), ELT(j
));
192 for (j
= start
+ 2; j
< count
; j
+= 3) {
193 RENDER_TRI(ELT(j
- 2), ELT(j
- 1), ELT(j
));
198 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
202 static void TAG(render_tri_strip
)(GLcontext
*ctx
,
211 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
213 #ifdef PERFORMANCE_MEASURE
214 if (VIA_PERFORMANCE
) P_M
;
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
);
223 GLboolean ef2
= EDGEFLAG_GET(ej2
);
224 GLboolean ef1
= EDGEFLAG_GET(ej1
);
225 GLboolean ef
= EDGEFLAG_GET(ej
);
226 if (TEST_PRIM_BEGIN(flags
)) {
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
);
239 for (j
= start
+ 2; j
< count
; j
++, parity
^= 1) {
240 RENDER_TRI(ELT(j
- 2 + parity
), ELT(j
- 1 - parity
), ELT(j
));
245 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
249 static void TAG(render_tri_fan
)(GLcontext
*ctx
,
258 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
260 #ifdef PERFORMANCE_MEASURE
261 if (VIA_PERFORMANCE
) P_M
;
264 if (NEED_EDGEFLAG_SETUP
) {
265 for (j
= start
+ 2; j
< count
; j
++) {
266 /* For trifans, all edges are boundary.
268 GLuint ejs
= ELT(start
);
269 GLuint ej1
= ELT(j
- 1);
271 GLboolean efs
= EDGEFLAG_GET(ejs
);
272 GLboolean ef1
= EDGEFLAG_GET(ej1
);
273 GLboolean ef
= EDGEFLAG_GET(ej
);
274 if (TEST_PRIM_BEGIN(flags
)) {
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
);
287 for (j
= start
+ 2; j
< count
; j
++) {
288 RENDER_TRI(ELT(start
), ELT(j
- 1), ELT(j
));
294 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
298 static void TAG(render_poly
)(GLcontext
*ctx
,
303 GLuint j
= start
+ 2;
307 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
309 #ifdef PERFORMANCE_MEASURE
310 if (VIA_PERFORMANCE
) P_M
;
314 if (NEED_EDGEFLAG_SETUP
) {
315 GLboolean efstart
= EDGEFLAG_GET(ELT(start
));
316 GLboolean efcount
= EDGEFLAG_GET(ELT(count
- 1));
318 /* If the primitive does not begin here, the first edge
321 if (!TEST_PRIM_BEGIN(flags
)) {
322 EDGEFLAG_SET(ELT(start
), GL_FALSE
);
328 /* If the primitive does not end here, the final edge is
331 if (!TEST_PRIM_END(flags
)) {
332 EDGEFLAG_SET(ELT(count
- 1), GL_FALSE
);
335 /* Draw the first triangles (possibly zero)
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
);
344 /* Don't render the first edge again:
346 EDGEFLAG_SET(ELT(start
), GL_FALSE
);
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
);
356 /* Draw the last or only triangle
359 RENDER_TRI(ELT(j
-1), ELT(j
), ELT(start
));
362 /* Restore the first and last edgeflags:
364 EDGEFLAG_SET(ELT(count
- 1), efcount
);
365 EDGEFLAG_SET(ELT(start
), efstart
);
368 for (j
= start
+ 2; j
< count
; j
++) {
369 RENDER_TRI(ELT(j
- 1), ELT(j
), ELT(start
));
374 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
378 static void TAG(render_quads
)(GLcontext
*ctx
,
387 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
389 #ifdef PERFORMANCE_MEASURE
390 if (VIA_PERFORMANCE
) P_M
;
393 if (NEED_EDGEFLAG_SETUP
) {
394 for (j
= start
+ 3; j
< count
; j
+= 4) {
395 /* Use user-specified edgeflags for quads.
398 RENDER_QUAD(ELT(j
- 3), ELT(j
- 2), ELT(j
- 1), ELT(j
));
402 for (j
= start
+ 3; j
< count
; j
+= 4) {
403 RENDER_QUAD(ELT(j
- 3), ELT(j
- 2), ELT(j
- 1), ELT(j
));
408 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
412 static void TAG(render_quad_strip
)(GLcontext
*ctx
,
421 if (VIA_DEBUG
) fprintf(stderr
, "%s - in\n", __FUNCTION__
);
423 #ifdef PERFORMANCE_MEASURE
424 if (VIA_PERFORMANCE
) P_M
;
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.
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
)) {
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
);
451 for (j
= start
+ 3; j
< count
; j
+= 2) {
452 RENDER_QUAD(ELT(j
- 1), ELT(j
- 3), ELT(j
- 2), ELT(j
));
457 if (VIA_DEBUG
) fprintf(stderr
, "%s - out\n", __FUNCTION__
);
461 static void TAG(render_noop
)(GLcontext
*ctx
,
466 (void)(ctx
&& start
&& count
&& flags
);
469 RENDER_TAB_QUALIFIER
void (*TAG(render_tab
)[GL_POLYGON
+ 2])(GLcontext
*,
476 TAG(render_line_loop
),
477 TAG(render_line_strip
),
478 TAG(render_triangles
),
479 TAG(render_tri_strip
),
482 TAG(render_quad_strip
),
487 #ifndef PRESERVE_VB_DEFS
498 #undef RENDER_TAB_QUALIFIER
505 #undef PRESERVE_VB_DEFS