684f2acc890849ac4fba0e0ad05927879bc5b7e0
1 /* -*- mode: c; c-basic-offset: 3 -*- */
3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell <keithw@valinux.com>
28 * Adapted to Mach64 by:
29 * José Fonseca <j_r_fonseca@yahoo.co.uk>
33 /* DO_XYZW: Emit xyz and maybe w coordinates.
34 * DO_RGBA: Emit color.
35 * DO_SPEC: Emit specular color.
36 * DO_FOG: Emit fog coordinate in specular alpha.
37 * DO_TEX0: Emit tex0 u,v coordinates.
38 * DO_TEX1: Emit tex1 u,v coordinates.
39 * DO_PTEX: Emit tex0,1 q coordinates where possible.
41 * Additionally, this template assumes it is emitting *transformed*
42 * vertices; the modifications to emit untransformed vertices (ie. to
43 * t&l hardware) are probably too great to cooexist with the code
44 * already in this file.
47 #define VIEWPORT_X(x) ((GLint) ((s[0] * (x) + s[12]) * 4.0))
48 #define VIEWPORT_Y(y) ((GLint) ((s[5] * (y) + s[13]) * 4.0))
49 #define VIEWPORT_Z(z) (((GLuint) (s[10] * (z) + s[14])) << 15)
55 static void TAG(emit
)( GLcontext
*ctx
,
56 GLuint start
, GLuint end
,
61 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
90 VERTEX
*v
= (VERTEX
*)dest
;
91 const GLfloat
*s
= GET_VIEWPORT_MAT();
92 #if DO_TEX1 || DO_TEX0 || DO_XYZW
93 const GLubyte
*mask
= VB
->ClipMask
;
98 (void) s
; /* Quiet compiler */
100 /* fprintf(stderr, "%s(big) importable %d %d..%d\n", */
101 /* __FUNCTION__, VB->importable_data, start, end); */
105 const GLuint t1
= GET_TEXSOURCE(1);
106 tc1
= VB
->TexCoordPtr
[t1
]->data
;
107 tc1_stride
= VB
->TexCoordPtr
[t1
]->stride
;
109 tc1_size
= VB
->TexCoordPtr
[t1
]->size
;
116 const GLuint t0
= GET_TEXSOURCE(0);
117 tc0
= VB
->TexCoordPtr
[t0
]->data
;
118 tc0_stride
= VB
->TexCoordPtr
[t0
]->stride
;
120 tc0_size
= VB
->TexCoordPtr
[t0
]->size
;
126 if (VB
->SecondaryColorPtr
[0]) {
127 spec
= VB
->SecondaryColorPtr
[0]->data
;
128 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
130 spec
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
136 if (VB
->FogCoordPtr
) {
137 fog
= VB
->FogCoordPtr
->data
;
138 fog_stride
= VB
->FogCoordPtr
->stride
;
140 static GLfloat tmp
[4] = {0, 0, 0, 0};
147 col
= VB
->ColorPtr
[0]->data
;
148 col_stride
= VB
->ColorPtr
[0]->stride
;
151 coord
= VB
->NdcPtr
->data
;
152 coord_stride
= VB
->NdcPtr
->stride
;
156 STRIDE_4F(tc1
, start
* tc1_stride
);
159 STRIDE_4F(tc0
, start
* tc0_stride
);
162 STRIDE_4F(spec
, start
* spec_stride
);
165 STRIDE_4F(fog
, start
* fog_stride
);
168 STRIDE_4F(col
, start
* col_stride
);
170 STRIDE_4F(coord
, start
* coord_stride
);
173 for (i
=start
; i
< end
; i
++, v
= (VERTEX
*)((GLubyte
*)v
+ stride
)) {
174 CARD32
*p
= (CARD32
*)v
;
175 #if DO_TEX1 || DO_TEX0
190 #ifdef MACH64_PREMULT_TEXCOORDS
191 LE32_OUT_FLOAT( p
++, w
*tc1
[0][0] ); /* VERTEX_?_SECONDARY_S */
192 LE32_OUT_FLOAT( p
++, w
*tc1
[0][1] ); /* VERTEX_?_SECONDARY_T */
193 LE32_OUT_FLOAT( p
++, w
*tc1
[0][3] ); /* VERTEX_?_SECONDARY_W */
194 #else /* !MACH64_PREMULT_TEXCOORDS */
195 float rhw
= 1.0 / tc1
[0][3];
196 LE32_OUT_FLOAT( p
++, rhw
*tc1
[0][0] ); /* VERTEX_?_SECONDARY_S */
197 LE32_OUT_FLOAT( p
++, rhw
*tc1
[0][1] ); /* VERTEX_?_SECONDARY_T */
198 LE32_OUT_FLOAT( p
++, w
*tc1
[0][3] ); /* VERTEX_?_SECONDARY_W */
199 #endif /* !MACH64_PREMULT_TEXCOORDS */
202 #ifdef MACH64_PREMULT_TEXCOORDS
203 LE32_OUT_FLOAT( p
++, w
*tc1
[0][0] ); /* VERTEX_?_SECONDARY_S */
204 LE32_OUT_FLOAT( p
++, w
*tc1
[0][1] ); /* VERTEX_?_SECONDARY_T */
205 LE32_OUT_FLOAT( p
++, w
); /* VERTEX_?_SECONDARY_W */
206 #else /* !MACH64_PREMULT_TEXCOORDS */
207 LE32_OUT_FLOAT( p
++, tc1
[0][0] ); /* VERTEX_?_SECONDARY_S */
208 LE32_OUT_FLOAT( p
++, tc1
[0][1] ); /* VERTEX_?_SECONDARY_T */
209 LE32_OUT_FLOAT( p
++, w
); /* VERTEX_?_SECONDARY_W */
210 #endif /* !MACH64_PREMULT_TEXCOORDS */
214 STRIDE_4F(tc1
, tc1_stride
);
217 #endif /* !DO_TEX1 */
222 #ifdef MACH64_PREMULT_TEXCOORDS
223 LE32_OUT_FLOAT( p
++, w
*tc0
[0][0] ); /* VERTEX_?_S */
224 LE32_OUT_FLOAT( p
++, w
*tc0
[0][1] ); /* VERTEX_?_T */
225 LE32_OUT_FLOAT( p
++, w
*tc0
[0][3] ); /* VERTEX_?_W */
226 #else /* !MACH64_PREMULT_TEXCOORDS */
227 float rhw
= 1.0 / tc0
[0][3];
228 LE32_OUT_FLOAT( p
++, rhw
*tc0
[0][0] ); /* VERTEX_?_S */
229 LE32_OUT_FLOAT( p
++, rhw
*tc0
[0][1] ); /* VERTEX_?_T */
230 LE32_OUT_FLOAT( p
++, w
*tc0
[0][3] ); /* VERTEX_?_W */
231 #endif /* !MACH64_PREMULT_TEXCOORDS */
234 #ifdef MACH64_PREMULT_TEXCOORDS
235 LE32_OUT_FLOAT( p
++, w
*tc0
[0][0] ); /* VERTEX_?_S */
236 LE32_OUT_FLOAT( p
++, w
*tc0
[0][1] ); /* VERTEX_?_T */
237 LE32_OUT_FLOAT( p
++, w
); /* VERTEX_?_W */
238 #else /* !MACH64_PREMULT_TEXCOORDS */
239 LE32_OUT_FLOAT( p
++, tc0
[0][0] ); /* VERTEX_?_S */
240 LE32_OUT_FLOAT( p
++, tc0
[0][1] ); /* VERTEX_?_T */
241 LE32_OUT_FLOAT( p
++, w
); /* VERTEX_?_W */
242 #endif /* !MACH64_PREMULT_TEXCOORDS */
246 STRIDE_4F(tc0
, tc0_stride
);
249 #endif /* !DO_TEX0 */
252 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[0], spec
[0][2]); /* VERTEX_?_SPEC_B */
253 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[1], spec
[0][1]); /* VERTEX_?_SPEC_G */
254 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[2], spec
[0][0]); /* VERTEX_?_SPEC_R */
256 STRIDE_4F(spec
, spec_stride
);
259 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[3], fog
[0][0]); /* VERTEX_?_SPEC_A */
260 /* ((GLubyte *)p)[3] = fog[0][0] * 255.0; */
261 STRIDE_4F(fog
, fog_stride
);
268 LE32_OUT( p
++, VIEWPORT_Z( coord
[0][2] ) ); /* VERTEX_?_Z */
277 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[0], col
[0][2]);
278 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[1], col
[0][1]);
279 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[2], col
[0][0]);
280 UNCLAMPED_FLOAT_TO_UBYTE(((GLubyte
*)p
)[3], col
[0][3]);
282 STRIDE_4F(col
, col_stride
);
291 (VIEWPORT_X( coord
[0][0] ) << 16) | /* VERTEX_?_X */
292 (VIEWPORT_Y( coord
[0][1] ) & 0xffff) ); /* VERTEX_?_Y */
294 if (MACH64_DEBUG
& DEBUG_VERBOSE_PRIMS
) {
295 fprintf( stderr
, "%s: vert %d: %.2f %.2f %.2f %x\n",
298 (LE32_IN( p
) >> 16)/4.0,
299 (LE32_IN( p
) & 0xffff)/4.0,
300 LE32_IN( p
- 2 )/65536.0,
301 *(GLuint
*)(p
- 1) );
305 #if DO_TEX1 || DO_TEX0 || DO_XYZW
306 STRIDE_4F(coord
, coord_stride
);
309 assert( p
+ 1 - (CARD32
*)v
== 10 );
313 #if DO_XYZW && DO_RGBA
315 static GLboolean
TAG(check_tex_sizes
)( GLcontext
*ctx
)
318 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
320 /* Force 'missing' texcoords to something valid.
322 if (DO_TEX1
&& VB
->TexCoordPtr
[0] == 0)
323 VB
->TexCoordPtr
[0] = VB
->TexCoordPtr
[1];
328 /* No hardware support for projective texture. Can fake it for
331 if ((DO_TEX1
&& VB
->TexCoordPtr
[GET_TEXSOURCE(1)]->size
== 4)) {
336 if (DO_TEX0
&& VB
->TexCoordPtr
[GET_TEXSOURCE(0)]->size
== 4) {
347 static void TAG(interp
)( GLcontext
*ctx
,
349 GLuint edst
, GLuint eout
, GLuint ein
,
350 GLboolean force_boundary
)
353 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
354 GLubyte
*ddverts
= GET_VERTEX_STORE();
355 GLuint size
= GET_VERTEX_SIZE();
356 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
358 const GLfloat
*s
= GET_VIEWPORT_MAT();
360 CARD32
*dst
= (CARD32
*)(ddverts
+ (edst
* size
));
361 CARD32
*in
= (CARD32
*)(ddverts
+ (ein
* size
));
362 CARD32
*out
= (CARD32
*)(ddverts
+ (eout
* size
));
366 w
= (dstclip
[3] == 0.0F
) ? 1.0 : (1.0 / dstclip
[3]);
372 GLfloat wout
= VB
->NdcPtr
->data
[eout
][3];
373 GLfloat win
= VB
->NdcPtr
->data
[ein
][3];
374 GLfloat qout
= LE32_IN_FLOAT( out
+ 2 ) / wout
;
375 GLfloat qin
= LE32_IN_FLOAT( in
+ 2 ) / win
;
378 INTERP_F( t
, qdst
, qout
, qin
);
381 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
382 LE32_OUT_FLOAT( dst
, temp
*rqdst
); /* VERTEX_?_SECONDARY_S */
385 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
386 LE32_OUT_FLOAT( dst
, temp
*rqdst
); /* VERTEX_?_SECONDARY_T */
389 LE32_OUT_FLOAT( dst
, w
*rqdst
); /* VERTEX_?_SECONDARY_W */
392 #ifdef MACH64_PREMULT_TEXCOORDS
393 GLfloat qout
= w
/ LE32_IN_FLOAT( out
+ 2 );
394 GLfloat qin
= w
/ LE32_IN_FLOAT( in
+ 2 );
396 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
397 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_SECONDARY_S */
400 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
401 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_SECONDARY_T */
403 #else /* !MACH64_PREMULT_TEXCOORDS */
404 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
), LE32_IN_FLOAT( in
) );
405 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_SECONDARY_S */
408 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
), LE32_IN_FLOAT( in
) );
409 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_SECONDARY_T */
411 #endif /* !MACH64_PREMULT_TEXCOORDS */
412 LE32_OUT_FLOAT( dst
, w
); /* VERTEX_?_SECONDARY_W */
414 #endif /* !DO_PTEX */
417 dst
+= 3; out
+= 3; in
+= 3;
418 #endif /* !DO_TEX1 */
424 GLfloat wout
= VB
->NdcPtr
->data
[eout
][3];
425 GLfloat win
= VB
->NdcPtr
->data
[ein
][3];
426 GLfloat qout
= LE32_IN_FLOAT( out
+ 2 ) / wout
;
427 GLfloat qin
= LE32_IN_FLOAT( in
+ 2 ) / win
;
430 INTERP_F( t
, qdst
, qout
, qin
);
433 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
434 LE32_OUT_FLOAT( dst
, temp
*rqdst
); /* VERTEX_?_S */
437 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
438 LE32_OUT_FLOAT( dst
, temp
*rqdst
); /* VERTEX_?_T */
441 LE32_OUT_FLOAT( dst
, w
*rqdst
); /* VERTEX_?_W */
444 #ifdef MACH64_PREMULT_TEXCOORDS
445 GLfloat qout
= w
/ LE32_IN_FLOAT( out
+ 2 );
446 GLfloat qin
= w
/ LE32_IN_FLOAT( in
+ 2 );
448 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
449 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_S */
452 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
) * qout
, LE32_IN_FLOAT( in
) * qin
);
453 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_T */
455 #else /* !MACH64_PREMULT_TEXCOORDS */
456 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
), LE32_IN_FLOAT( in
) );
457 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_S */
460 INTERP_F( t
, temp
, LE32_IN_FLOAT( out
), LE32_IN_FLOAT( in
) );
461 LE32_OUT_FLOAT( dst
, temp
); /* VERTEX_?_T */
463 #endif /* !MACH64_PREMULT_TEXCOORDS */
464 LE32_OUT_FLOAT( dst
, w
); /* VERTEX_?_W */
466 #endif /* !DO_PTEX */
469 dst
+= 3; out
+= 3; in
+= 3;
470 #endif /* !DO_TEX0 */
473 INTERP_UB( t
, ((GLubyte
*)dst
)[0], ((GLubyte
*)out
)[0], ((GLubyte
*)in
)[0] ); /* VERTEX_?_SPEC_B */
474 INTERP_UB( t
, ((GLubyte
*)dst
)[1], ((GLubyte
*)out
)[1], ((GLubyte
*)in
)[1] ); /* VERTEX_?_SPEC_G */
475 INTERP_UB( t
, ((GLubyte
*)dst
)[2], ((GLubyte
*)out
)[2], ((GLubyte
*)in
)[2] ); /* VERTEX_?_SPEC_R */
479 INTERP_UB( t
, ((GLubyte
*)dst
)[3], ((GLubyte
*)out
)[3], ((GLubyte
*)in
)[3] ); /* VERTEX_?_SPEC_A */
484 LE32_OUT( dst
, VIEWPORT_Z( dstclip
[2] * w
) ); /* VERTEX_?_Z */
487 INTERP_UB( t
, ((GLubyte
*)dst
)[0], ((GLubyte
*)out
)[0], ((GLubyte
*)in
)[0] ); /* VERTEX_?_B */
488 INTERP_UB( t
, ((GLubyte
*)dst
)[1], ((GLubyte
*)out
)[1], ((GLubyte
*)in
)[1] ); /* VERTEX_?_G */
489 INTERP_UB( t
, ((GLubyte
*)dst
)[2], ((GLubyte
*)out
)[2], ((GLubyte
*)in
)[2] ); /* VERTEX_?_R */
490 INTERP_UB( t
, ((GLubyte
*)dst
)[3], ((GLubyte
*)out
)[3], ((GLubyte
*)in
)[3] ); /* VERTEX_?_A */
491 dst
++; /*out++; in++;*/
494 (VIEWPORT_X( dstclip
[0] * w
) << 16) | /* VERTEX_?_X */
495 (VIEWPORT_Y( dstclip
[1] * w
) & 0xffff) ); /* VERTEX_?_Y */
497 assert( dst
+ 1 - (CARD32
*)(ddverts
+ (edst
* size
)) == 10 );
498 assert( in
+ 2 - (CARD32
*)(ddverts
+ (ein
* size
)) == 10 );
499 assert( out
+ 2 - (CARD32
*)(ddverts
+ (eout
* size
)) == 10 );
501 if (MACH64_DEBUG
& DEBUG_VERBOSE_PRIMS
) {
502 fprintf( stderr
, "%s: dst vert: %.2f %.2f %.2f %x\n",
504 (GLshort
)(LE32_IN( dst
) >> 16)/4.0,
505 (GLshort
)(LE32_IN( dst
) & 0xffff)/4.0,
506 LE32_IN( dst
- 2 )/65536.0,
507 *(GLuint
*)(dst
- 1) );
511 #endif /* DO_RGBA && DO_XYZW */
514 static void TAG(copy_pv
)( GLcontext
*ctx
, GLuint edst
, GLuint esrc
)
516 #if DO_SPEC || DO_FOG || DO_RGBA
518 GLubyte
*verts
= GET_VERTEX_STORE();
519 GLuint size
= GET_VERTEX_SIZE();
520 GLuint
*dst
= (GLuint
*)(verts
+ (edst
* size
));
521 GLuint
*src
= (GLuint
*)(verts
+ (esrc
* size
));
524 #if DO_SPEC || DO_FOG
525 dst
[6] = src
[6]; /* VERTEX_?_SPEC_ARGB */
529 dst
[8] = src
[8]; /* VERTEX_?_ARGB */
533 static void TAG(init
)( void )
535 setup_tab
[IND
].emit
= TAG(emit
);
537 #if DO_XYZW && DO_RGBA
538 setup_tab
[IND
].check_tex_sizes
= TAG(check_tex_sizes
);
539 setup_tab
[IND
].interp
= TAG(interp
);
542 setup_tab
[IND
].copy_pv
= TAG(copy_pv
);
545 setup_tab
[IND
].vertex_format
= TEX1_VERTEX_FORMAT
;
546 setup_tab
[IND
].vertex_size
= 10;
548 setup_tab
[IND
].vertex_format
= TEX0_VERTEX_FORMAT
;
549 setup_tab
[IND
].vertex_size
= 7;
550 #elif DO_SPEC || DO_FOG
551 setup_tab
[IND
].vertex_format
= NOTEX_VERTEX_FORMAT
;
552 setup_tab
[IND
].vertex_size
= 4;
554 setup_tab
[IND
].vertex_format
= TINY_VERTEX_FORMAT
;
555 setup_tab
[IND
].vertex_size
= 3;