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]
35 static void TAG(emit
)( GLcontext
*ctx
,
36 GLuint start
, GLuint end
,
39 fxMesaContext fxMesa
= FX_CONTEXT(ctx
);
40 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
41 GLuint tmu0_source
= fxMesa
->tmu_source
[0];
42 GLuint tmu1_source
= fxMesa
->tmu_source
[1];
43 GLfloat (*tc0
)[4], (*tc1
)[4];
45 GLuint tc0_stride
, tc1_stride
, col_stride
;
46 GLuint tc0_size
, tc1_size
;
47 GLfloat (*proj
)[4] = VB
->NdcPtr
->data
;
48 GLuint proj_stride
= VB
->NdcPtr
->stride
;
51 GrVertex
*v
= (GrVertex
*)dest
;
52 GLfloat u0scale
,v0scale
,u1scale
,v1scale
;
53 const GLubyte
*mask
= VB
->ClipMask
;
54 const GLfloat
*const s
= ctx
->Viewport
._WindowMap
.m
;
57 if (IND
& SETUP_PSIZ
) {
58 psize
= VB
->PointSizePtr
->data
;
59 psize_stride
= VB
->PointSizePtr
->stride
;
62 if (IND
& SETUP_TMU0
) {
63 tc0
= VB
->TexCoordPtr
[tmu0_source
]->data
;
64 tc0_stride
= VB
->TexCoordPtr
[tmu0_source
]->stride
;
65 u0scale
= fxMesa
->s0scale
;
66 v0scale
= fxMesa
->t0scale
;
68 tc0_size
= VB
->TexCoordPtr
[tmu0_source
]->size
;
71 if (IND
& SETUP_TMU1
) {
72 tc1
= VB
->TexCoordPtr
[tmu1_source
]->data
;
73 tc1_stride
= VB
->TexCoordPtr
[tmu1_source
]->stride
;
74 u1scale
= fxMesa
->s1scale
; /* wrong if tmu1_source == 0, possible? */
75 v1scale
= fxMesa
->t1scale
;
77 tc1_size
= VB
->TexCoordPtr
[tmu1_source
]->size
;
80 if (IND
& SETUP_RGBA
) {
81 col
= VB
->ColorPtr
[0]->data
;
82 col_stride
= VB
->ColorPtr
[0]->stride
;
86 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ start
* proj_stride
);
87 if (IND
& SETUP_PSIZ
) {
88 psize
= (GLfloat (*)[4])((GLubyte
*)psize
+ start
* psize_stride
);
91 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
93 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
95 STRIDE_4F(col
, start
* col_stride
);
98 for (i
=start
; i
< end
; i
++, v
++) {
99 if (IND
& SETUP_PSIZ
) {
100 v
->psize
= psize
[0][0];
101 psize
= (GLfloat (*)[4])((GLubyte
*)psize
+ psize_stride
);
104 if (IND
& SETUP_XYZW
) {
107 VIEWPORT_X(v
->x
, proj
[0][0]);
108 VIEWPORT_Y(v
->y
, proj
[0][1]);
109 VIEWPORT_Z(v
->ooz
, proj
[0][2]);
116 if (IND
& SETUP_SNAP
) {
117 #if defined(USE_IEEE)
118 const float snapper
= (3L << 18);
124 v
->x
= ((int) (v
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
125 v
->y
= ((int) (v
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
129 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ proj_stride
);
131 if (IND
& SETUP_RGBA
) {
132 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[2], col
[0][0]);
133 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[1], col
[0][1]);
134 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[0], col
[0][2]);
135 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[3], col
[0][3]);
136 STRIDE_4F(col
, col_stride
);
138 if (IND
& SETUP_TMU0
) {
140 v
->tmuvtx
[0].sow
= tc0
[0][0] * u0scale
* w
;
141 v
->tmuvtx
[0].tow
= tc0
[0][1] * v0scale
* w
;
142 if (IND
& SETUP_PTEX
) {
143 v
->tmuvtx
[0].oow
= w
;
145 v
->tmuvtx
[0].oow
*= tc0
[0][3];
147 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
149 if (IND
& SETUP_TMU1
) {
151 v
->tmuvtx
[1].sow
= tc1
[0][0] * u1scale
* w
;
152 v
->tmuvtx
[1].tow
= tc1
[0][1] * v1scale
* w
;
153 if (IND
& SETUP_PTEX
) {
154 v
->tmuvtx
[1].oow
= w
;
156 v
->tmuvtx
[1].oow
*= tc1
[0][3];
158 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
163 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
165 static GLboolean
TAG(check_tex_sizes
)( GLcontext
*ctx
)
167 /* fprintf(stderr, "%s\n", __FUNCTION__); */
169 if (IND
& SETUP_PTEX
)
172 if (IND
& SETUP_TMU0
) {
173 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
175 if (IND
& SETUP_TMU1
) {
176 if (VB
->TexCoordPtr
[0] == 0)
177 VB
->TexCoordPtr
[0] = VB
->TexCoordPtr
[1];
179 if (VB
->TexCoordPtr
[1]->size
== 4)
183 if (VB
->TexCoordPtr
[0] && VB
->TexCoordPtr
[0]->size
== 4)
190 static void TAG(interp
)( GLcontext
*ctx
,
192 GLuint edst
, GLuint eout
, GLuint ein
,
193 GLboolean force_boundary
)
195 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
196 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
197 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
198 const GLfloat oow
= (dstclip
[3] == 0.0F
) ? 1.0F
: (1.0F
/ dstclip
[3]);
199 const GLfloat
*const s
= ctx
->Viewport
._WindowMap
.m
;
200 GrVertex
*fxverts
= fxMesa
->verts
;
201 GrVertex
*dst
= (GrVertex
*) (fxverts
+ edst
);
202 const GrVertex
*out
= (const GrVertex
*) (fxverts
+ eout
);
203 const GrVertex
*in
= (const GrVertex
*) (fxverts
+ ein
);
204 const GLfloat wout
= 1.0F
/ out
->oow
;
205 const GLfloat win
= 1.0F
/ in
->oow
;
207 VIEWPORT_X(dst
->x
, dstclip
[0] * oow
);
208 VIEWPORT_Y(dst
->y
, dstclip
[1] * oow
);
209 VIEWPORT_Z(dst
->ooz
, dstclip
[2] * oow
);
212 if (IND
& SETUP_SNAP
) {
213 #if defined(USE_IEEE)
214 const float snapper
= (3L << 18);
220 dst
->x
= ((int) (dst
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
221 dst
->y
= ((int) (dst
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
226 INTERP_UB( t
, dst
->pargb
[0], out
->pargb
[0], in
->pargb
[0] );
227 INTERP_UB( t
, dst
->pargb
[1], out
->pargb
[1], in
->pargb
[1] );
228 INTERP_UB( t
, dst
->pargb
[2], out
->pargb
[2], in
->pargb
[2] );
229 INTERP_UB( t
, dst
->pargb
[3], out
->pargb
[3], in
->pargb
[3] );
231 if (IND
& SETUP_TMU0
) {
232 if (IND
& SETUP_PTEX
) {
235 out
->tmuvtx
[0].sow
* wout
,
236 in
->tmuvtx
[0].sow
* win
);
239 out
->tmuvtx
[0].tow
* wout
,
240 in
->tmuvtx
[0].tow
* win
);
243 out
->tmuvtx
[0].oow
* wout
,
244 in
->tmuvtx
[0].oow
* win
);
246 dst
->tmuvtx
[0].sow
*= oow
;
247 dst
->tmuvtx
[0].tow
*= oow
;
248 dst
->tmuvtx
[0].oow
*= oow
;
252 out
->tmuvtx
[0].sow
* wout
,
253 in
->tmuvtx
[0].sow
* win
);
256 out
->tmuvtx
[0].tow
* wout
,
257 in
->tmuvtx
[0].tow
* win
);
259 dst
->tmuvtx
[0].sow
*= oow
;
260 dst
->tmuvtx
[0].tow
*= oow
;
264 if (IND
& SETUP_TMU1
) {
265 if (IND
& SETUP_PTEX
) {
268 out
->tmuvtx
[1].sow
* wout
,
269 in
->tmuvtx
[1].sow
* win
);
272 out
->tmuvtx
[1].tow
* wout
,
273 in
->tmuvtx
[1].tow
* win
);
276 out
->tmuvtx
[1].oow
* wout
,
277 in
->tmuvtx
[1].oow
* win
);
279 dst
->tmuvtx
[1].sow
*= oow
;
280 dst
->tmuvtx
[1].tow
*= oow
;
281 dst
->tmuvtx
[1].oow
*= oow
;
285 out
->tmuvtx
[1].sow
* wout
,
286 in
->tmuvtx
[1].sow
* win
);
289 out
->tmuvtx
[1].tow
* wout
,
290 in
->tmuvtx
[1].tow
* win
);
292 dst
->tmuvtx
[1].sow
*= oow
;
293 dst
->tmuvtx
[1].tow
*= oow
;
300 static void TAG(init
)( void )
302 setup_tab
[IND
].emit
= TAG(emit
);
304 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
305 setup_tab
[IND
].check_tex_sizes
= TAG(check_tex_sizes
);
306 setup_tab
[IND
].interp
= TAG(interp
);
308 if (IND
& SETUP_PTEX
) {
309 setup_tab
[IND
].vertex_format
= (GR_STWHINT_W_DIFF_TMU0
|
310 GR_STWHINT_W_DIFF_TMU1
);
313 setup_tab
[IND
].vertex_format
= 0;
316 #if (IND & SETUP_TMU1)
317 setup_tab
[IND
].vertex_format
|= GR_STWHINT_ST_DIFF_TMU1
;