2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell <keith@tungstengraphics.com>
27 * Daniel Borca <dborca@users.sourceforge.net>
31 #define VIEWPORT_X(dst,x) dst = s[0] * x + s[12]
32 #define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13]
33 #define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14]
36 static void TAG(emit
)( GLcontext
*ctx
,
37 GLuint start
, GLuint end
,
40 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
41 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
42 GLuint tmu0_source
= fxMesa
->tmu_source
[0];
43 GLuint tmu1_source
= fxMesa
->tmu_source
[1];
44 GLfloat (*tc0
)[4], (*tc1
)[4];
46 GLuint tc0_stride
, tc1_stride
, col_stride
;
47 GLuint tc0_size
, tc1_size
, col_size
;
48 GLfloat (*proj
)[4] = VB
->NdcPtr
->data
;
49 GLuint proj_stride
= VB
->NdcPtr
->stride
;
52 tdfxVertex
*v
= (tdfxVertex
*)dest
;
53 GLfloat u0scale
,v0scale
,u1scale
,v1scale
;
54 const GLubyte
*mask
= VB
->ClipMask
;
55 const GLfloat
*s
= fxMesa
->hw_viewport
;
58 /* fprintf(stderr, "%s\n", __FUNCTION__); */
60 if (IND
& TDFX_TEX0_BIT
) {
61 tc0_stride
= VB
->TexCoordPtr
[tmu0_source
]->stride
;
62 tc0
= VB
->TexCoordPtr
[tmu0_source
]->data
;
63 u0scale
= fxMesa
->sScale0
;
64 v0scale
= fxMesa
->tScale0
;
65 if (IND
& TDFX_PTEX_BIT
)
66 tc0_size
= VB
->TexCoordPtr
[tmu0_source
]->size
;
69 if (IND
& TDFX_TEX1_BIT
) {
70 tc1
= VB
->TexCoordPtr
[tmu1_source
]->data
;
71 tc1_stride
= VB
->TexCoordPtr
[tmu1_source
]->stride
;
72 u1scale
= fxMesa
->sScale1
;
73 v1scale
= fxMesa
->tScale1
;
74 if (IND
& TDFX_PTEX_BIT
)
75 tc1_size
= VB
->TexCoordPtr
[tmu1_source
]->size
;
78 if (IND
& TDFX_RGBA_BIT
) {
79 col
= VB
->ColorPtr
[0]->data
;
80 col_stride
= VB
->ColorPtr
[0]->stride
;
81 col_size
= VB
->ColorPtr
[0]->size
;
84 if (IND
& TDFX_FOGC_BIT
) {
85 fog
= VB
->FogCoordPtr
->data
;
86 fog_stride
= VB
->FogCoordPtr
->stride
;
90 /* May have nonstandard strides:
93 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ start
* proj_stride
);
94 if (IND
& TDFX_TEX0_BIT
)
95 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
96 if (IND
& TDFX_TEX1_BIT
)
97 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
98 if (IND
& TDFX_RGBA_BIT
)
99 STRIDE_4F(col
, start
* col_stride
);
100 if (IND
& TDFX_FOGC_BIT
)
101 STRIDE_4F(fog
, start
* fog_stride
);
104 for (i
=start
; i
< end
; i
++, v
++) {
105 if (IND
& TDFX_XYZ_BIT
) {
108 VIEWPORT_X(v
->x
, proj
[0][0]);
109 VIEWPORT_Y(v
->y
, proj
[0][1]);
110 VIEWPORT_Z(v
->z
, proj
[0][2]);
116 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ proj_stride
);
118 if (IND
& TDFX_RGBA_BIT
) {
119 UNCLAMPED_FLOAT_TO_UBYTE(v
->color
[0], col
[0][2]);
120 UNCLAMPED_FLOAT_TO_UBYTE(v
->color
[1], col
[0][1]);
121 UNCLAMPED_FLOAT_TO_UBYTE(v
->color
[2], col
[0][0]);
123 UNCLAMPED_FLOAT_TO_UBYTE(v
->color
[3], col
[0][3]);
127 STRIDE_4F(col
, col_stride
);
129 if (IND
& TDFX_FOGC_BIT
) {
130 v
->fog
= CLAMP(fog
[0][0], 0.0f
, 1.0f
);
131 STRIDE_4F(fog
, fog_stride
);
133 if (IND
& TDFX_TEX0_BIT
) {
135 v
->tu0
= tc0
[0][0] * u0scale
* w
;
136 v
->tv0
= tc0
[0][1] * v0scale
* w
;
137 if (IND
& TDFX_PTEX_BIT
) {
140 v
->tq0
= tc0
[0][3] * w
;
142 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
144 if (IND
& TDFX_TEX1_BIT
) {
146 v
->tu1
= tc1
[0][0] * u1scale
* w
;
147 v
->tv1
= tc1
[0][1] * v1scale
* w
;
148 if (IND
& TDFX_PTEX_BIT
) {
151 v
->tq1
= tc1
[0][3] * w
;
153 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
160 static GLboolean
TAG(check_tex_sizes
)( GLcontext
*ctx
)
162 /* fprintf(stderr, "%s\n", __FUNCTION__); */
164 if (IND
& TDFX_PTEX_BIT
)
167 if (IND
& TDFX_TEX0_BIT
) {
168 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
170 if (IND
& TDFX_TEX1_BIT
) {
171 if (VB
->TexCoordPtr
[0] == 0)
172 VB
->TexCoordPtr
[0] = VB
->TexCoordPtr
[1];
174 if (VB
->TexCoordPtr
[1]->size
== 4)
178 if (VB
->TexCoordPtr
[0]->size
== 4)
186 static void TAG(interp
)( GLcontext
*ctx
,
188 GLuint edst
, GLuint eout
, GLuint ein
,
189 GLboolean force_boundary
)
191 tdfxContextPtr fxMesa
= TDFX_CONTEXT( ctx
);
192 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
193 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
194 const GLfloat oow
= (dstclip
[3] == 0.0F
) ? 1.0F
: (1.0F
/ dstclip
[3]);
195 const GLfloat
*s
= fxMesa
->hw_viewport
;
196 tdfxVertex
*dst
= fxMesa
->verts
+ edst
;
197 const tdfxVertex
*out
= fxMesa
->verts
+ eout
;
198 const tdfxVertex
*in
= fxMesa
->verts
+ ein
;
199 const GLfloat wout
= oow
/ out
->rhw
;
200 const GLfloat win
= oow
/ in
->rhw
;
202 VIEWPORT_X(dst
->x
, dstclip
[0] * oow
);
203 VIEWPORT_Y(dst
->y
, dstclip
[1] * oow
);
204 VIEWPORT_Z(dst
->z
, dstclip
[2] * oow
);
207 INTERP_UB( t
, dst
->color
[0], out
->color
[0], in
->color
[0] );
208 INTERP_UB( t
, dst
->color
[1], out
->color
[1], in
->color
[1] );
209 INTERP_UB( t
, dst
->color
[2], out
->color
[2], in
->color
[2] );
210 INTERP_UB( t
, dst
->color
[3], out
->color
[3], in
->color
[3] );
212 if (IND
& TDFX_FOGC_BIT
) {
213 INTERP_F( t
, dst
->fog
, out
->fog
, in
->fog
);
216 if (IND
& TDFX_TEX0_BIT
) {
217 INTERP_F( t
, dst
->tu0
, out
->tu0
* wout
, in
->tu0
* win
);
218 INTERP_F( t
, dst
->tv0
, out
->tv0
* wout
, in
->tv0
* win
);
219 if (IND
& TDFX_PTEX_BIT
) {
220 INTERP_F( t
, dst
->tq0
, out
->tq0
* wout
, in
->tq0
* win
);
223 if (IND
& TDFX_TEX1_BIT
) {
224 INTERP_F( t
, dst
->tu1
, out
->tu1
* wout
, in
->tu1
* win
);
225 INTERP_F( t
, dst
->tv1
, out
->tv1
* wout
, in
->tv1
* win
);
226 if (IND
& TDFX_PTEX_BIT
) {
227 INTERP_F( t
, dst
->tq1
, out
->tq1
* wout
, in
->tq1
* win
);
233 static void TAG(init
)( void )
235 /* fprintf(stderr, "%s\n", __FUNCTION__); */
237 setup_tab
[IND
].emit
= TAG(emit
);
238 setup_tab
[IND
].check_tex_sizes
= TAG(check_tex_sizes
);
239 setup_tab
[IND
].interp
= TAG(interp
);
240 setup_tab
[IND
].copy_pv
= copy_pv
;
242 if (IND
& TDFX_TEX1_BIT
) {
243 if (IND
& TDFX_PTEX_BIT
) {
244 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_PROJ2
;
247 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_MULTI
;
250 else if (IND
& TDFX_TEX0_BIT
) {
251 if (IND
& TDFX_PTEX_BIT
) {
252 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_PROJ1
;
254 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_SINGLE
;
257 else if (IND
& TDFX_W_BIT
) {
258 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_NOTEX
;
260 setup_tab
[IND
].vertex_format
= TDFX_LAYOUT_TINY
;