2 * Author: Max Lingua <sunmax@libero.it>
5 /**** MACROS start ****/
7 /* point/line macros */
9 #define LINE_VERT_VARS \
12 int x[3], y[3], z[3]; \
19 int i, tmp, tmp2, tmp3; \
20 GLfloat ydiff, fy[3]; \
21 (void) v; (void) vvv; (void) x; (void) y; (void) z; (void) idx; \
22 (void) dx01; (void) dy01; (void) delt02; (void) deltzy; \
23 (void) zstart; (void) start02; (void) ystart; (void) y01y12; \
24 (void) i; (void) tmp; (void) tmp2; (void) tmp3; (void) ydiff; (void) fy
26 #define LINE_FLAT_VARS \
27 int arstart, gbstart; \
28 int deltarx, deltgbx, deltary, deltgby; \
30 (void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
31 (void) deltary; (void) deltgby; (void) col
33 #define LINE_GOURAUD_VARS \
34 int arstart, gbstart; \
35 int deltary, deltgby; \
36 int ctmp, ctmp2, ctmp3, ctmp4; \
38 (void) arstart; (void) gbstart; (void) deltary; (void) deltgby; \
39 (void) ctmp; (void) ctmp2; (void) ctmp3; (void) ctmp4; (void) col
41 #define SORT_LINE_VERT() \
43 if(v[0].win[1] <= v[1].win[1]) { \
48 } else if (v[0].win[1] > v[1].win[1]) { \
56 #define SET_LINE_VERT() \
58 x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
59 y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
60 z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
62 x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
63 y[1] = dPriv->h - v[idx[1]].win[1]; \
64 z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
67 #define SET_LINE_XY() \
69 tmp = v[idx[0]].win[0]; \
70 tmp2 = v[idx[1]].win[0]; \
75 ydiff = fy[0] - (float)y[0]; \
80 #define SET_LINE_DIR() \
83 y01y12 |= 0x80000000; \
89 end01 = ((tmp << 16) | tmp2); \
92 delt02 = -(dx01/dy01); \
96 if (dy01 > tmp3) { /* Y MAJ */ \
97 /* NOTE: tmp3 always >=0 */ \
99 } else if (delt02 >= 0){ /* X MAJ - positive delta */ \
100 start02 = x[0] + delt02/2; \
101 dy01 = tmp3; /* could be 0 */ \
102 } else { /* X MAJ - negative delta */ \
103 start02 = x[0] + delt02/2 + ((1 << 20) - 1); \
104 dy01 = tmp3; /* could be 0 */ \
108 #define SET_LINE_Z() \
113 deltzy = (z[1] - z[0])/dy01; \
115 deltzy = 0; /* dy01 = tmp3 = 0 (it's a point)*/ \
119 #define SET_LINE_FLAT_COL() \
121 col[0] = &(v[idx[0]].color[0]); \
122 deltarx = deltary = deltgbx = deltgby = 0; \
123 gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
124 arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
127 #define SET_LINE_GOURAUD_COL() \
129 col[0] = &(v[idx[0]].color[0]); \
130 col[1] = &(v[idx[1]].color[0]); \
135 for (i=0; i<2; i++) { \
136 /* FIXME: swapped ! */ \
137 col[i][0] = vvv[!idx[i]]->v.color.red; \
138 col[i][1] = vvv[!idx[i]]->v.color.green; \
139 col[i][2] = vvv[!idx[i]]->v.color.blue; \
140 col[i][3] = vvv[!idx[i]]->v.color.alpha; \
145 ctmp = ((col[0][1] - col[1][1]) << 7) / dy01; \
146 ctmp2 = ((col[0][2] - col[1][2]) << 7) / dy01; \
147 deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
149 ctmp3 = ((col[0][3] - col[1][3]) << 7) / dy01; \
150 ctmp4 = ((col[0][0] - col[1][0]) << 7) / dy01; \
151 deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
153 ctmp = ((col[1][1] - col[0][1]) << 7); \
154 ctmp2 = ((col[1][2] - col[0][2]) << 7); \
155 deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
157 ctmp3 = ((col[1][3] - col[0][3]) << 7); \
158 ctmp4 = ((col[1][0] - col[0][0]) << 7); \
159 deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
160 deltgby = deltary = 0; \
163 idx[0] = 1; /* FIXME: swapped */ \
166 (((int)((ydiff * ctmp) + (col[idx[0]][1] << 7)) << 16) & 0x7FFF0000) \
167 | ((int)((ydiff * ctmp2) + (col[idx[0]][2] << 7)) & 0x7FFF); \
169 (((int)((ydiff * ctmp3) + (col[idx[0]][3] << 7)) << 16) & 0x7FFF0000) \
170 | ((int)((ydiff * ctmp4) + (col[idx[0]][0] << 7)) & 0x7FFF); \
173 #define SEND_LINE_COL() \
181 #define SEND_LINE_VERT() \
196 /* tri macros (mostly stolen from utah-glx...) */
200 int x[3], y[3], z[3]; \
205 int delt01, delt02, delt12; \
206 int deltzx, deltzy, zstart; \
207 int start02, end01, end12; \
208 int ystart, y01y12; \
210 GLfloat ydiff, fy[3]; \
211 (void) v; (void) x; (void) y; (void) z; (void) idx; (void) dx01; \
212 (void) dy01; (void) dx02; (void) dy02; (void) dx12; (void) dy12; \
213 (void) delt01; (void) delt02; (void) delt12; (void) deltzx; \
214 (void) deltzy; (void) zstart; (void) start02; (void) end01; \
215 (void) end12; (void) ystart; (void) y01y12; (void) i; (void) tmp; \
216 (void) lr; (void) ydiff; (void) fy
218 #define GOURAUD_VARS \
219 int arstart, gbstart; \
220 int deltarx, deltgbx, deltary, deltgby; \
221 int ctmp, ctmp2, ctmp3, ctmp4; \
223 (void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
224 (void) deltary; (void) deltgby; (void) ctmp; (void) ctmp2; \
225 (void) ctmp3; (void) ctmp4; (void) col
228 int arstart, gbstart; \
229 int deltarx, deltgbx, deltary, deltgby; \
231 (void) arstart; (void) gbstart; (void) deltarx; (void) deltgbx; \
232 (void) deltary; (void) deltgby; (void) col
236 GLfloat ru0, ru1, ru2; \
238 GLfloat rv0, rv1, rv2; \
239 GLfloat w0, w1, w2; \
240 GLfloat rw0, rw1, rw2; \
243 int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
244 int deltwx, deltwy; \
245 int rbaseu, rbasev; \
246 int dstart, ustart, wstart, vstart; \
247 static int stmp = 0; \
248 s3vTextureObjectPtr t; \
249 (void) u0; (void) u1; (void) u2; (void) ru0; (void) ru1; (void) ru2; \
250 (void) v0; (void) v1; (void) v2; (void) rv0; (void) rv1; (void) rv2; \
251 (void) w0; (void) w1; (void) w2; (void) rw0; (void) rw1; (void) rw2; \
252 (void) baseu; (void) basev; (void) d0; (void) d1; (void) d2; \
253 (void) deltdx; (void) deltvx; (void) deltux; (void) deltdy; \
254 (void) deltuy; (void) deltwx; (void) deltwy; (void) rbaseu; \
255 (void) rbasev; (void) dstart; (void) ustart; (void) wstart; \
256 (void) vstart; (void) stmp; (void) t
258 #define SORT_VERT() \
260 for (i=0; i<3; i++) \
261 fy[i] = v[i].win[1]; \
263 if (fy[1] > fy[0]) { /* (fy[1] > fy[0]) */ \
265 if (fy[2] > fy[0]) { \
267 if (fy[1] > fy[2]) { \
279 } else { /* (fy[1] < y[0]) */ \
280 if (fy[2] > fy[0]) { \
286 if (fy[2] > fy[1]) { \
299 for (i=0; i<3; i++) \
301 x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/ 1024.0 * 1024.0); \
302 y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
303 z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
306 ydiff = fy[0] - (float)y[0]; \
310 dx12 = x[2] - x[1]; \
311 dy12 = y[1] - y[2]; \
312 dx01 = x[1] - x[0]; \
313 dy01 = y[0] - y[1]; \
314 dx02 = x[2] - x[0]; \
315 dy02 = y[0] - y[2]; \
317 delt01 = delt02 = delt12 = 0; \
323 if (dy01) delt01 = dx01 / dy01; \
324 if (dy12) delt12 = dx12 / dy12; \
325 delt02 = dx02 / dy02; \
327 start02 = x[0] + (ydiff * delt02); \
328 end01 = x[0] + (ydiff * delt01); \
329 end12 = x[1] + ((fy[1] - (GLfloat)y[1]) * delt12); \
334 tmp = x[1] - (dy01 * delt02 + x[0]); \
343 y01y12 = ((((y[0] - y[1]) & 0x7FF) << 16) \
344 | ((y[1] - y[2]) & 0x7FF) | lr); \
349 deltzy = (z[2] - z[0]) / dy02; \
351 deltzx = (z[1] - (dy01 * deltzy + z[0])) / tmp; \
355 zstart = (deltzy * ydiff) + z[0]; \
358 #define SET_FLAT_COL() \
360 col[0] = &(v[0].color[0]); \
361 deltarx = deltary = deltgbx = deltgby = 0; \
362 gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
363 arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
366 #define SET_GOURAUD_COL() \
368 col[0] = &(v[idx[0]].color[0]); \
369 col[1] = &(v[idx[1]].color[0]); \
370 col[2] = &(v[idx[2]].color[0]); \
372 ctmp = ((col[2][3] - col[0][3]) << 7) / dy02; \
373 ctmp2 = ((col[2][0] - col[0][0]) << 7) / dy02; \
374 deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
375 ctmp3 = ((col[2][1] - col[0][1]) << 7) / dy02; \
376 ctmp4 = ((col[2][2] - col[0][2]) << 7) / dy02; \
377 deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
379 (((int)((ydiff * ctmp3) + (col[0][1] << 7)) << 16) & 0x7FFF0000) \
380 | ((int)((ydiff * ctmp4) + (col[0][2] << 7)) & 0x7FFF); \
382 (((int)((ydiff * ctmp) + (col[0][3] << 7)) << 16) & 0x7FFF0000) \
383 | ((int)((ydiff * ctmp2) + (col[0][0] << 7)) & 0x7FFF); \
385 int ax, rx, gx, bx; \
386 ax = ((col[1][3] << 7) - (dy01 * ctmp + (col[0][3] << 7))) / tmp; \
387 rx = ((col[1][0] << 7) - (dy01 * ctmp2 + (col[0][0] << 7))) / tmp; \
388 gx = ((col[1][1] << 7) - (dy01 * ctmp3 + (col[0][1] << 7))) / tmp; \
389 bx = ((col[1][2] << 7) - (dy01 * ctmp4 + (col[0][2] << 7))) / tmp; \
390 deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
391 deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
393 deltgbx = deltarx = 0; \
397 #define SET_TEX_VERT() \
399 t = ((s3vTextureObjectPtr) \
400 ctx->Texture.Unit[0]._Current->DriverData); \
401 deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
403 u0 = (v[idx[0]].texcoord[0][0] \
404 * (GLfloat)(t->image[0].image->Width) * 256.0); \
405 u1 = (v[idx[1]].texcoord[0][0] \
406 * (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
407 u2 = (v[idx[2]].texcoord[0][0] \
408 * (GLfloat)(t->globj->Image[0][0]->Width) * 256.0); \
409 v0 = (v[idx[0]].texcoord[0][1] \
410 * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
411 v1 = (v[idx[1]].texcoord[0][1] \
412 * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
413 v2 = (v[idx[2]].texcoord[0][1] \
414 * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \
416 w0 = (v[idx[0]].win[3]); \
417 w1 = (v[idx[1]].win[3]); \
418 w2 = (v[idx[2]].win[3]); \
421 #define SET_BASEUV() \
471 rw0 = (512.0 * w0); \
472 rw1 = (512.0 * w1); \
473 rw2 = (512.0 * w2); \
481 suv = (v[idx[0]].texcoord[0][0] - \
482 v[idx[2]].texcoord[0][0]) * \
483 (v[idx[1]].texcoord[0][1] - \
484 v[idx[2]].texcoord[0][1]) - \
485 (v[idx[1]].texcoord[0][0] - \
486 v[idx[2]].texcoord[0][0]) * \
487 (v[idx[0]].texcoord[0][1] - \
488 v[idx[2]].texcoord[0][2]); \
490 sxy = (v[idx[0]].texcoord[0][0] - \
491 v[idx[2]].texcoord[0][0]) * \
492 (v[idx[1]].texcoord[0][1] - \
493 v[idx[2]].texcoord[0][1]) - \
494 (v[idx[1]].texcoord[0][0] - \
495 v[idx[2]].texcoord[0][0]) * \
496 (v[idx[0]].texcoord[0][1] - \
497 v[idx[2]].texcoord[0][2]); \
499 if (sxy < 0) sxy *= -1.0; \
500 if (suv < 0) suv *= -1.0; \
502 lev = *(int*)&suv - *(int *)&sxy; \
507 dstart = (lev << 27); \
515 ru0 = (((u0 - baseu) * rw0)); \
516 ru1 = (((u1 - baseu) * rw1)); \
517 ru2 = (((u2 - baseu) * rw2)); \
518 rv0 = (((v0 - basev) * rw0)); \
519 rv1 = (((v1 - basev) * rw1)); \
520 rv2 = (((v2 - basev) * rw2)); \
522 while (baseu < 0) { baseu += (t->globj->Image[0][0]->Width << 8); } \
523 while (basev < 0) { basev += (t->globj->Image[0][0]->Height << 8); } \
525 if (!(baseu & 0xFF)) \
526 { baseu = (baseu >> 8); } \
528 { baseu = (baseu >> 8) + 1; } \
530 if ((basev & 0x80) || !(basev & 0xFF)) \
531 { basev = (basev >> 8); } \
533 { basev = (basev >> 8) - 1; } \
535 rbaseu = (baseu) << (16 - t->globj->Image[0][0]->WidthLog2); \
536 rbasev = (basev) << (16 - t->globj->Image[0][0]->WidthLog2); \
537 deltuy = (((ru2 - ru0) / dy02)); \
538 deltvy = (((rv2 - rv0) / dy02)); \
539 rw0 *= (1024.0 * 512.0); \
540 rw1 *= (1024.0 * 512.0); \
541 rw2 *= (1024.0 * 512.0); \
542 deltwy = ((rw2 - rw0) / dy02); \
544 deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
545 deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
546 deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
547 } else { deltux = deltvx = deltwx = 0; } \
548 ustart = (deltuy * ydiff) + (ru0); \
549 vstart = (deltvy * ydiff) + (rv0); \
550 wstart = (deltwy * ydiff) + (rw0); \
553 #define SEND_UVWD() \
555 DMAOUT((rbasev & 0xFFFF)); \
556 DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
571 #define SEND_VERT() \
596 /**** MACROS end ****/
601 static void TAG(s3v_point
)( s3vContextPtr vmesa
,
602 const s3vVertex
*_v0
)
606 static void TAG(s3v_line
)( s3vContextPtr vmesa
,
607 const s3vVertex
*_v0
,
608 const s3vVertex
*_v1
)
610 GLcontext
*ctx
= vmesa
->glCtx
;
611 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
614 #if (IND & S3V_RAST_FLAT_BIT)
619 #if (IND & S3V_RAST_CULL_BIT)
624 DEBUG(("*** s3v_line: "));
625 #if (IND & S3V_RAST_CULL_BIT)
628 #if (IND & S3V_RAST_FLAT_BIT)
635 s3v_print_vertex(ctx
, _v0
);
636 s3v_print_vertex(ctx
, _v1
);
639 s3v_translate_vertex( ctx
, _v0
, &v
[0] );
640 s3v_translate_vertex( ctx
, _v1
, &v
[1] );
642 #if (IND & S3V_RAST_CULL_BIT)
643 /* FIXME: should we cull lines too? */
645 (void)v
; /* v[0]; v[1]; */
654 #if (IND & S3V_RAST_FLAT_BIT)
657 SET_LINE_GOURAUD_COL();
660 DMAOUT_CHECK(3DLINE_GBD
, 15);
667 static void TAG(s3v_triangle
)( s3vContextPtr vmesa
,
668 const s3vVertex
*_v0
,
669 const s3vVertex
*_v1
,
670 const s3vVertex
*_v2
)
672 GLcontext
*ctx
= vmesa
->glCtx
;
673 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
676 #if (IND & S3v_RAST_FLAT_BIT)
681 #if (IND & S3V_RAST_TEX_BIT)
684 #if (IND & S3V_RAST_CULL_BIT)
688 DEBUG(("*** s3v_triangle: "));
689 #if (IND & S3V_RAST_CULL_BIT)
692 #if (IND & S3V_RAST_FLAT_BIT)
695 #if (IND & S3V_RAST_TEX_BIT)
702 s3v_print_vertex(ctx
, _v0
);
703 s3v_print_vertex(ctx
, _v1
);
704 s3v_print_vertex(ctx
, _v2
);
707 s3v_translate_vertex( ctx
, _v0
, &v
[0] );
708 s3v_translate_vertex( ctx
, _v1
, &v
[1] );
709 s3v_translate_vertex( ctx
, _v2
, &v
[2] );
711 #if (IND & S3V_RAST_CULL_BIT)
712 cull
= vmesa
->backface_sign
*
713 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
714 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
716 if (cull
< vmesa
->cull_zero
/* -0.02f */) return;
719 (void)v
; /* v[0]; v[1]; v[2]; */
724 if (dy02
== 0) return;
730 #if (IND & S3V_RAST_TEX_BIT)
735 #if (IND & S3V_RAST_FLAT_BIT)
741 #if (IND & S3V_RAST_TEX_BIT)
742 DMAOUT_CHECK(3DTRI_BASEV
, 31);
748 DMAOUT_CHECK(3DTRI_GBX
, 17);
755 static void TAG(s3v_quad
)( s3vContextPtr vmesa
,
756 const s3vVertex
*_v0
,
757 const s3vVertex
*_v1
,
758 const s3vVertex
*_v2
,
759 const s3vVertex
*_v3
)
761 GLcontext
*ctx
= vmesa
->glCtx
;
762 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
766 #if (IND & S3v_RAST_FLAT_BIT)
771 #if (IND & S3V_RAST_TEX_BIT)
774 #if (IND & S3V_RAST_CULL_BIT)
778 DEBUG(("*** s3v_quad: "));
779 #if (IND & S3V_RAST_CULL_BIT)
781 /* printf(""); */ /* speed trick */
783 #if (IND & S3V_RAST_FLAT_BIT)
786 #if (IND & S3V_RAST_TEX_BIT)
793 s3v_print_vertex(ctx
, _v0
);
794 s3v_print_vertex(ctx
, _v1
);
795 s3v_print_vertex(ctx
, _v2
);
796 s3v_print_vertex(ctx
, _v3
);
798 s3v_translate_vertex( ctx
, _v0
, &temp_v
[0] );
799 s3v_translate_vertex( ctx
, _v1
, &temp_v
[1] );
800 s3v_translate_vertex( ctx
, _v2
, &temp_v
[2] );
801 s3v_translate_vertex( ctx
, _v3
, &temp_v
[3] );
803 /* FIRST TRI (0,1,2) */
806 /* printf(""); */ /* speed trick (a) [turn on if (a) is return]*/
812 #if (IND & S3V_RAST_CULL_BIT)
813 cull
= vmesa
->backface_sign
*
814 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
815 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
817 if (cull
< vmesa
->cull_zero
/* -0.02f */) goto second
; /* return; */ /* (a) */
830 if (dy02
== 0) goto second
;
836 #if (IND & S3V_RAST_TEX_BIT)
841 #if (IND & S3V_RAST_FLAT_BIT)
847 #if (IND & S3V_RAST_TEX_BIT)
848 DMAOUT_CHECK(3DTRI_BASEV
, 31);
854 DMAOUT_CHECK(3DTRI_GBX
, 17);
860 /* SECOND TRI (0,2,3) */
867 #if (IND & S3V_RAST_CULL_BIT)
868 cull
= vmesa
->backface_sign
*
869 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
870 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
872 if (cull
< /* -0.02f */ vmesa
->cull_zero
) return;
878 /* printf(""); */ /* speed trick */
887 if (dy02
== 0) return;
893 #if (IND & S3V_RAST_TEX_BIT)
898 #if (IND & S3V_RAST_FLAT_BIT)
904 #if (IND & S3V_RAST_TEX_BIT)
905 DMAOUT_CHECK(3DTRI_BASEV
, 31);
911 DMAOUT_CHECK(3DTRI_GBX
, 17);
918 static void TAG(s3v_init
)(void)
920 s3v_point_tab
[IND
] = TAG(s3v_point
);
921 s3v_line_tab
[IND
] = TAG(s3v_line
);
922 s3v_tri_tab
[IND
] = TAG(s3v_triangle
);
923 s3v_quad_tab
[IND
] = TAG(s3v_quad
);