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; \
22 #define LINE_FLAT_VARS \
23 int arstart, gbstart; \
24 int deltarx, deltgbx, deltary, deltgby; \
27 #define LINE_GOURAUD_VARS \
28 int arstart, gbstart; \
29 int deltary, deltgby; \
30 int ctmp, ctmp2, ctmp3, ctmp4; \
33 #define SORT_LINE_VERT() \
35 if(v[0].win[1] <= v[1].win[1]) { \
40 } else if (v[0].win[1] > v[1].win[1]) { \
48 #define SET_LINE_VERT() \
50 x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
51 y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \
52 z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \
54 x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \
55 y[1] = dPriv->h - v[idx[1]].win[1]; \
56 z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \
59 #define SET_LINE_XY() \
61 tmp = v[idx[0]].win[0]; \
62 tmp2 = v[idx[1]].win[0]; \
67 ydiff = fy[0] - (float)y[0]; \
72 #define SET_LINE_DIR() \
75 y01y12 |= 0x80000000; \
81 end01 = ((tmp << 16) | tmp2); \
84 delt02 = -(dx01/dy01); \
88 if (dy01 > tmp3) { /* Y MAJ */ \
89 /* NOTE: tmp3 always >=0 */ \
91 } else if (delt02 >= 0){ /* X MAJ - positive delta */ \
92 start02 = x[0] + delt02/2; \
93 dy01 = tmp3; /* could be 0 */ \
94 } else { /* X MAJ - negative delta */ \
95 start02 = x[0] + delt02/2 + ((1 << 20) - 1); \
96 dy01 = tmp3; /* could be 0 */ \
100 #define SET_LINE_Z() \
105 deltzy = (z[1] - z[0])/dy01; \
107 deltzy = 0; /* dy01 = tmp3 = 0 (it's a point)*/ \
111 #define SET_LINE_FLAT_COL() \
113 col[0] = &(v[idx[0]].color[0]); \
114 deltarx = deltary = deltgbx = deltgby = 0; \
115 gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
116 arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
119 #define SET_LINE_GOURAUD_COL() \
121 col[0] = &(v[idx[0]].color[0]); \
122 col[1] = &(v[idx[1]].color[0]); \
127 for (i=0; i<2; i++) { \
128 /* FIXME: swapped ! */ \
129 col[i][0] = vvv[!idx[i]]->v.color.red; \
130 col[i][1] = vvv[!idx[i]]->v.color.green; \
131 col[i][2] = vvv[!idx[i]]->v.color.blue; \
132 col[i][3] = vvv[!idx[i]]->v.color.alpha; \
137 ctmp = ((col[0][1] - col[1][1]) << 7) / dy01; \
138 ctmp2 = ((col[0][2] - col[1][2]) << 7) / dy01; \
139 deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
141 ctmp3 = ((col[0][3] - col[1][3]) << 7) / dy01; \
142 ctmp4 = ((col[0][0] - col[1][0]) << 7) / dy01; \
143 deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
145 ctmp = ((col[1][1] - col[0][1]) << 7); \
146 ctmp2 = ((col[1][2] - col[0][2]) << 7); \
147 deltgby = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
149 ctmp3 = ((col[1][3] - col[0][3]) << 7); \
150 ctmp4 = ((col[1][0] - col[0][0]) << 7); \
151 deltary = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
152 deltgby = deltary = 0; \
155 idx[0] = 1; /* FIXME: swapped */ \
158 (((int)((ydiff * ctmp) + (col[idx[0]][1] << 7)) << 16) & 0x7FFF0000) \
159 | ((int)((ydiff * ctmp2) + (col[idx[0]][2] << 7)) & 0x7FFF); \
161 (((int)((ydiff * ctmp3) + (col[idx[0]][3] << 7)) << 16) & 0x7FFF0000) \
162 | ((int)((ydiff * ctmp4) + (col[idx[0]][0] << 7)) & 0x7FFF); \
165 #define SEND_LINE_COL() \
173 #define SEND_LINE_VERT() \
188 /* tri macros (mostly stolen from utah-glx...) */
192 int x[3], y[3], z[3]; \
197 int delt01, delt02, delt12; \
198 int deltzx, deltzy, zstart; \
199 int start02, end01, end12; \
200 int ystart, y01y12; \
204 #define GOURAUD_VARS \
205 int arstart, gbstart; \
206 int deltarx, deltgbx, deltary, deltgby; \
207 int ctmp, ctmp2, ctmp3, ctmp4; \
211 int arstart, gbstart; \
212 int deltarx, deltgbx, deltary, deltgby; \
217 GLfloat ru0, ru1, ru2; \
219 GLfloat rv0, rv1, rv2; \
220 GLfloat w0, w1, w2; \
221 GLfloat rw0, rw1, rw2; \
224 int deltdx, deltvx, deltux, deltdy, deltvy, deltuy; \
225 int deltwx, deltwy; \
226 int rbaseu, rbasev; \
227 int dstart, ustart, wstart, vstart; \
228 static int stmp = 0; \
229 s3vTextureObjectPtr t
231 #define SORT_VERT() \
233 for (i=0; i<3; i++) \
234 fy[i] = v[i].win[1]; \
236 if (fy[1] > fy[0]) { /* (fy[1] > fy[0]) */ \
238 if (fy[2] > fy[0]) { \
240 if (fy[1] > fy[2]) { \
252 } else { /* (fy[1] < y[0]) */ \
253 if (fy[2] > fy[0]) { \
259 if (fy[2] > fy[1]) { \
272 for (i=0; i<3; i++) \
274 x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/ 1024.0 * 1024.0); \
275 y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \
276 z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \
279 ydiff = fy[0] - (float)y[0]; \
283 dx12 = x[2] - x[1]; \
284 dy12 = y[1] - y[2]; \
285 dx01 = x[1] - x[0]; \
286 dy01 = y[0] - y[1]; \
287 dx02 = x[2] - x[0]; \
288 dy02 = y[0] - y[2]; \
290 delt01 = delt02 = delt12 = 0; \
296 if (dy01) delt01 = dx01 / dy01; \
297 if (dy12) delt12 = dx12 / dy12; \
298 delt02 = dx02 / dy02; \
300 start02 = x[0] + (ydiff * delt02); \
301 end01 = x[0] + (ydiff * delt01); \
302 end12 = x[1] + ((fy[1] - (GLfloat)y[1]) * delt12); \
307 tmp = x[1] - (dy01 * delt02 + x[0]); \
316 y01y12 = ((((y[0] - y[1]) & 0x7FF) << 16) \
317 | ((y[1] - y[2]) & 0x7FF) | lr); \
322 deltzy = (z[2] - z[0]) / dy02; \
324 deltzx = (z[1] - (dy01 * deltzy + z[0])) / tmp; \
328 zstart = (deltzy * ydiff) + z[0]; \
331 #define SET_FLAT_COL() \
333 col[0] = &(v[0].color[0]); \
334 deltarx = deltary = deltgbx = deltgby = 0; \
335 gbstart = (((col[0][1]) << 23) | ((col[0][2]) << 7)); \
336 arstart = (((col[0][3]) << 23) | ((col[0][0]) << 7)); \
339 #define SET_GOURAUD_COL() \
341 col[0] = &(v[idx[0]].color[0]); \
342 col[1] = &(v[idx[1]].color[0]); \
343 col[2] = &(v[idx[2]].color[0]); \
345 ctmp = ((col[2][3] - col[0][3]) << 7) / dy02; \
346 ctmp2 = ((col[2][0] - col[0][0]) << 7) / dy02; \
347 deltary = ((ctmp << 16) & 0xFFFF0000) | (ctmp2 & 0xFFFF); \
348 ctmp3 = ((col[2][1] - col[0][1]) << 7) / dy02; \
349 ctmp4 = ((col[2][2] - col[0][2]) << 7) / dy02; \
350 deltgby = ((ctmp3 << 16) & 0xFFFF0000) | (ctmp4 & 0xFFFF); \
352 (((int)((ydiff * ctmp3) + (col[0][1] << 7)) << 16) & 0x7FFF0000) \
353 | ((int)((ydiff * ctmp4) + (col[0][2] << 7)) & 0x7FFF); \
355 (((int)((ydiff * ctmp) + (col[0][3] << 7)) << 16) & 0x7FFF0000) \
356 | ((int)((ydiff * ctmp2) + (col[0][0] << 7)) & 0x7FFF); \
358 int ax, rx, gx, bx; \
359 ax = ((col[1][3] << 7) - (dy01 * ctmp + (col[0][3] << 7))) / tmp; \
360 rx = ((col[1][0] << 7) - (dy01 * ctmp2 + (col[0][0] << 7))) / tmp; \
361 gx = ((col[1][1] << 7) - (dy01 * ctmp3 + (col[0][1] << 7))) / tmp; \
362 bx = ((col[1][2] << 7) - (dy01 * ctmp4 + (col[0][2] << 7))) / tmp; \
363 deltarx = ((ax << 16) & 0xFFFF0000) | (rx & 0xFFFF); \
364 deltgbx = ((gx << 16) & 0xFFFF0000) | (bx & 0xFFFF); \
366 deltgbx = deltarx = 0; \
370 #define SET_TEX_VERT() \
372 t = ((s3vTextureObjectPtr) \
373 ctx->Texture.Unit[0]._Current->DriverData); \
374 deltwx = deltwy = wstart = deltdx = deltdy = dstart = 0; \
376 u0 = (v[idx[0]].texcoord[0][0] \
377 * (GLfloat)(t->image[0].image->Width) * 256.0); \
378 u1 = (v[idx[1]].texcoord[0][0] \
379 * (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
380 u2 = (v[idx[2]].texcoord[0][0] \
381 * (GLfloat)(t->globj->Image[0]->Width) * 256.0); \
382 v0 = (v[idx[0]].texcoord[0][1] \
383 * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
384 v1 = (v[idx[1]].texcoord[0][1] \
385 * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
386 v2 = (v[idx[2]].texcoord[0][1] \
387 * (GLfloat)(t->globj->Image[0]->Height) * 256.0); \
389 w0 = (v[idx[0]].win[3]); \
390 w1 = (v[idx[1]].win[3]); \
391 w2 = (v[idx[2]].win[3]); \
394 #define SET_BASEUV() \
444 rw0 = (512.0 * w0); \
445 rw1 = (512.0 * w1); \
446 rw2 = (512.0 * w2); \
454 suv = (v[idx[0]].texcoord[0][0] - \
455 v[idx[2]].texcoord[0][0]) * \
456 (v[idx[1]].texcoord[0][1] - \
457 v[idx[2]].texcoord[0][1]) - \
458 (v[idx[1]].texcoord[0][0] - \
459 v[idx[2]].texcoord[0][0]) * \
460 (v[idx[0]].texcoord[0][1] - \
461 v[idx[2]].texcoord[0][2]); \
463 sxy = (v[idx[0]].texcoord[0][0] - \
464 v[idx[2]].texcoord[0][0]) * \
465 (v[idx[1]].texcoord[0][1] - \
466 v[idx[2]].texcoord[0][1]) - \
467 (v[idx[1]].texcoord[0][0] - \
468 v[idx[2]].texcoord[0][0]) * \
469 (v[idx[0]].texcoord[0][1] - \
470 v[idx[2]].texcoord[0][2]); \
472 if (sxy < 0) sxy *= -1.0; \
473 if (suv < 0) suv *= -1.0; \
475 lev = *(int*)&suv - *(int *)&sxy; \
480 dstart = (lev << 27); \
488 ru0 = (((u0 - baseu) * rw0)); \
489 ru1 = (((u1 - baseu) * rw1)); \
490 ru2 = (((u2 - baseu) * rw2)); \
491 rv0 = (((v0 - basev) * rw0)); \
492 rv1 = (((v1 - basev) * rw1)); \
493 rv2 = (((v2 - basev) * rw2)); \
495 while (baseu < 0) { baseu += (t->globj->Image[0]->Width << 8); } \
496 while (basev < 0) { basev += (t->globj->Image[0]->Height << 8); } \
498 if (!(baseu & 0xFF)) \
499 { baseu = (baseu >> 8); } \
501 { baseu = (baseu >> 8) + 1; } \
503 if ((basev & 0x80) || !(basev & 0xFF)) \
504 { basev = (basev >> 8); } \
506 { basev = (basev >> 8) - 1; } \
508 rbaseu = (baseu) << (16 - t->globj->Image[0]->WidthLog2); \
509 rbasev = (basev) << (16 - t->globj->Image[0]->WidthLog2); \
510 deltuy = (((ru2 - ru0) / dy02)); \
511 deltvy = (((rv2 - rv0) / dy02)); \
512 rw0 *= (1024.0 * 512.0); \
513 rw1 *= (1024.0 * 512.0); \
514 rw2 *= (1024.0 * 512.0); \
515 deltwy = ((rw2 - rw0) / dy02); \
517 deltux = ((ru1 - (dy01 * deltuy + ru0)) / tmp); \
518 deltvx = ((rv1 - (dy01 * deltvy + rv0)) / tmp); \
519 deltwx = ((rw1 - (dy01 * deltwy + rw0)) / tmp); \
520 } else { deltux = deltvx = deltwx = 0; } \
521 ustart = (deltuy * ydiff) + (ru0); \
522 vstart = (deltvy * ydiff) + (rv0); \
523 wstart = (deltwy * ydiff) + (rw0); \
526 #define SEND_UVWD() \
528 DMAOUT((rbasev & 0xFFFF)); \
529 DMAOUT((0xa0000000 | (rbaseu & 0xFFFF))); \
544 #define SEND_VERT() \
569 /**** MACROS end ****/
574 static void TAG(s3v_point
)( s3vContextPtr vmesa
,
575 const s3vVertex
*_v0
)
579 static void TAG(s3v_line
)( s3vContextPtr vmesa
,
580 const s3vVertex
*_v0
,
581 const s3vVertex
*_v1
)
583 GLcontext
*ctx
= vmesa
->glCtx
;
584 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
587 #if (IND & S3V_RAST_FLAT_BIT)
592 #if (IND & S3V_RAST_CULL_BIT)
596 DEBUG(("*** s3v_line: "));
597 #if (IND & S3V_RAST_CULL_BIT)
600 #if (IND & S3V_RAST_FLAT_BIT)
607 s3v_print_vertex(ctx
, _v0
);
608 s3v_print_vertex(ctx
, _v1
);
611 s3v_translate_vertex( ctx
, _v0
, &v
[0] );
612 s3v_translate_vertex( ctx
, _v1
, &v
[1] );
614 #if (IND & S3V_RAST_CULL_BIT)
615 /* FIXME: should we cull lines too? */
617 (void)v
; /* v[0]; v[1]; */
626 #if (IND & S3V_RAST_FLAT_BIT)
629 SET_LINE_GOURAUD_COL();
632 DMAOUT_CHECK(3DLINE_GBD
, 15);
639 static void TAG(s3v_triangle
)( s3vContextPtr vmesa
,
640 const s3vVertex
*_v0
,
641 const s3vVertex
*_v1
,
642 const s3vVertex
*_v2
)
644 GLcontext
*ctx
= vmesa
->glCtx
;
645 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
648 #if (IND & S3v_RAST_FLAT_BIT)
653 #if (IND & S3V_RAST_TEX_BIT)
656 #if (IND & S3V_RAST_CULL_BIT)
660 DEBUG(("*** s3v_triangle: "));
661 #if (IND & S3V_RAST_CULL_BIT)
664 #if (IND & S3V_RAST_FLAT_BIT)
667 #if (IND & S3V_RAST_TEX_BIT)
674 s3v_print_vertex(ctx
, _v0
);
675 s3v_print_vertex(ctx
, _v1
);
676 s3v_print_vertex(ctx
, _v2
);
679 s3v_translate_vertex( ctx
, _v0
, &v
[0] );
680 s3v_translate_vertex( ctx
, _v1
, &v
[1] );
681 s3v_translate_vertex( ctx
, _v2
, &v
[2] );
683 #if (IND & S3V_RAST_CULL_BIT)
684 cull
= vmesa
->backface_sign
*
685 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
686 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
688 if (cull
< vmesa
->cull_zero
/* -0.02f */) return;
691 (void)v
; /* v[0]; v[1]; v[2]; */
696 if (dy02
== 0) return;
702 #if (IND & S3V_RAST_TEX_BIT)
707 #if (IND & S3V_RAST_FLAT_BIT)
713 #if (IND & S3V_RAST_TEX_BIT)
714 DMAOUT_CHECK(3DTRI_BASEV
, 31);
720 DMAOUT_CHECK(3DTRI_GBX
, 17);
727 static void TAG(s3v_quad
)( s3vContextPtr vmesa
,
728 const s3vVertex
*_v0
,
729 const s3vVertex
*_v1
,
730 const s3vVertex
*_v2
,
731 const s3vVertex
*_v3
)
733 GLcontext
*ctx
= vmesa
->glCtx
;
734 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
738 #if (IND & S3v_RAST_FLAT_BIT)
743 #if (IND & S3V_RAST_TEX_BIT)
746 #if (IND & S3V_RAST_CULL_BIT)
750 DEBUG(("*** s3v_quad: "));
751 #if (IND & S3V_RAST_CULL_BIT)
753 /* printf(""); */ /* speed trick */
755 #if (IND & S3V_RAST_FLAT_BIT)
758 #if (IND & S3V_RAST_TEX_BIT)
765 s3v_print_vertex(ctx
, _v0
);
766 s3v_print_vertex(ctx
, _v1
);
767 s3v_print_vertex(ctx
, _v2
);
768 s3v_print_vertex(ctx
, _v3
);
770 s3v_translate_vertex( ctx
, _v0
, &temp_v
[0] );
771 s3v_translate_vertex( ctx
, _v1
, &temp_v
[1] );
772 s3v_translate_vertex( ctx
, _v2
, &temp_v
[2] );
773 s3v_translate_vertex( ctx
, _v3
, &temp_v
[3] );
775 /* FIRST TRI (0,1,2) */
778 /* printf(""); */ /* speed trick (a) [turn on if (a) is return]*/
784 #if (IND & S3V_RAST_CULL_BIT)
785 cull
= vmesa
->backface_sign
*
786 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
787 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
789 if (cull
< vmesa
->cull_zero
/* -0.02f */) goto second
; /* return; */ /* (a) */
802 if (dy02
== 0) goto second
;
808 #if (IND & S3V_RAST_TEX_BIT)
813 #if (IND & S3V_RAST_FLAT_BIT)
819 #if (IND & S3V_RAST_TEX_BIT)
820 DMAOUT_CHECK(3DTRI_BASEV
, 31);
826 DMAOUT_CHECK(3DTRI_GBX
, 17);
832 /* SECOND TRI (0,2,3) */
839 #if (IND & S3V_RAST_CULL_BIT)
840 cull
= vmesa
->backface_sign
*
841 ((v
[1].win
[0] - v
[0].win
[0]) * (v
[0].win
[1] - v
[2].win
[1]) +
842 (v
[1].win
[1] - v
[0].win
[1]) * (v
[2].win
[0] - v
[0].win
[0]));
844 if (cull
< /* -0.02f */ vmesa
->cull_zero
) return;
850 /* printf(""); */ /* speed trick */
859 if (dy02
== 0) return;
865 #if (IND & S3V_RAST_TEX_BIT)
870 #if (IND & S3V_RAST_FLAT_BIT)
876 #if (IND & S3V_RAST_TEX_BIT)
877 DMAOUT_CHECK(3DTRI_BASEV
, 31);
883 DMAOUT_CHECK(3DTRI_GBX
, 17);
890 static void TAG(s3v_init
)(void)
892 s3v_point_tab
[IND
] = TAG(s3v_point
);
893 s3v_line_tab
[IND
] = TAG(s3v_line
);
894 s3v_tri_tab
[IND
] = TAG(s3v_triangle
);
895 s3v_quad_tab
[IND
] = TAG(s3v_quad
);