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];
44 GLfloat (*col
)[4], (*spec
)[4];
45 GLuint tc0_stride
, tc1_stride
, col_stride
, spec_stride
;
46 GLuint tc0_size
, tc1_size
, col_size
;
47 GLfloat (*proj
)[4] = VB
->NdcPtr
->data
;
48 GLuint proj_stride
= VB
->NdcPtr
->stride
;
53 GrVertex
*v
= (GrVertex
*)dest
;
54 GLfloat u0scale
,v0scale
,u1scale
,v1scale
;
55 const GLubyte
*mask
= VB
->ClipMask
;
56 const GLfloat
*const s
= ctx
->Viewport
._WindowMap
.m
;
59 if (IND
& SETUP_PSIZ
) {
60 psize
= VB
->PointSizePtr
->data
;
61 psize_stride
= VB
->PointSizePtr
->stride
;
64 if (IND
& SETUP_TMU0
) {
65 tc0
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu0_source
]->data
;
66 tc0_stride
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu0_source
]->stride
;
67 u0scale
= fxMesa
->s0scale
;
68 v0scale
= fxMesa
->t0scale
;
70 tc0_size
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu0_source
]->size
;
73 if (IND
& SETUP_TMU1
) {
74 tc1
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu1_source
]->data
;
75 tc1_stride
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu1_source
]->stride
;
76 u1scale
= fxMesa
->s1scale
; /* wrong if tmu1_source == 0, possible? */
77 v1scale
= fxMesa
->t1scale
;
79 tc1_size
= VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ tmu1_source
]->size
;
82 if (IND
& SETUP_RGBA
) {
83 col
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->data
;
84 col_stride
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->stride
;
85 col_size
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
]->size
;
88 if (IND
& SETUP_SPEC
) {
89 spec
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->data
;
90 spec_stride
= VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
]->stride
;
93 if (IND
& SETUP_FOGC
) {
94 fog
= VB
->AttribPtr
[_TNL_ATTRIB_FOG
]->data
;
95 fog_stride
= VB
->AttribPtr
[_TNL_ATTRIB_FOG
]->stride
;
99 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ start
* proj_stride
);
100 if (IND
& SETUP_PSIZ
)
101 psize
= (GLfloat (*)[4])((GLubyte
*)psize
+ start
* psize_stride
);
102 if (IND
& SETUP_TMU0
)
103 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
104 if (IND
& SETUP_TMU1
)
105 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
106 if (IND
& SETUP_RGBA
)
107 STRIDE_4F(col
, start
* col_stride
);
108 if (IND
& SETUP_SPEC
)
109 STRIDE_4F(spec
, start
* spec_stride
);
110 if (IND
& SETUP_FOGC
)
111 fog
= (GLfloat (*)[4])((GLubyte
*)fog
+ start
* fog_stride
);
114 for (i
=start
; i
< end
; i
++, v
++) {
115 if (IND
& SETUP_PSIZ
) {
116 v
->psize
= psize
[0][0];
117 psize
= (GLfloat (*)[4])((GLubyte
*)psize
+ psize_stride
);
120 if (IND
& SETUP_XYZW
) {
123 VIEWPORT_X(v
->x
, proj
[0][0]);
124 VIEWPORT_Y(v
->y
, proj
[0][1]);
125 VIEWPORT_Z(v
->ooz
, proj
[0][2]);
128 if (IND
& SETUP_SNAP
) {
129 #if defined(USE_IEEE)
130 const float snapper
= (3L << 18);
136 v
->x
= ((int) (v
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
137 v
->y
= ((int) (v
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
145 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ proj_stride
);
147 if (IND
& SETUP_RGBA
) {
149 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[2], col
[0][0]);
150 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[1], col
[0][1]);
151 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[0], col
[0][2]);
153 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[3], col
[0][3]);
157 #else /* !FX_PACKEDCOLOR */
158 CNORM(v
->r
, col
[0][0]);
159 CNORM(v
->g
, col
[0][1]);
160 CNORM(v
->b
, col
[0][2]);
162 CNORM(v
->a
, col
[0][3]);
166 #endif /* !FX_PACKEDCOLOR */
167 STRIDE_4F(col
, col_stride
);
169 if (IND
& SETUP_SPEC
) {
171 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[2], spec
[0][0]);
172 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[1], spec
[0][1]);
173 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[0], spec
[0][2]);
174 #else /* !FX_PACKEDCOLOR */
175 CNORM(v
->r1
, spec
[0][0]);
176 CNORM(v
->g1
, spec
[0][1]);
177 CNORM(v
->b1
, spec
[0][2]);
178 #endif /* !FX_PACKEDCOLOR */
179 STRIDE_4F(spec
, spec_stride
);
181 if (IND
& SETUP_FOGC
) {
182 v
->fog
= CLAMP(fog
[0][0], 0.0f
, 1.0f
);
183 fog
= (GLfloat (*)[4])((GLubyte
*)fog
+ fog_stride
);
185 if (IND
& SETUP_TMU0
) {
187 v
->tmuvtx
[0].sow
= tc0
[0][0] * u0scale
* w
;
188 v
->tmuvtx
[0].tow
= tc0
[0][1] * v0scale
* w
;
189 if (IND
& SETUP_PTEX
) {
190 v
->tmuvtx
[0].oow
= w
;
192 v
->tmuvtx
[0].oow
*= tc0
[0][3];
194 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
196 if (IND
& SETUP_TMU1
) {
198 v
->tmuvtx
[1].sow
= tc1
[0][0] * u1scale
* w
;
199 v
->tmuvtx
[1].tow
= tc1
[0][1] * v1scale
* w
;
200 if (IND
& SETUP_PTEX
) {
201 v
->tmuvtx
[1].oow
= w
;
203 v
->tmuvtx
[1].oow
*= tc1
[0][3];
205 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
210 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
212 static GLboolean
TAG(check_tex_sizes
)( GLcontext
*ctx
)
214 /* fprintf(stderr, "%s\n", __FUNCTION__); */
216 if (IND
& SETUP_PTEX
)
219 if (IND
& SETUP_TMU0
) {
220 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
222 if (IND
& SETUP_TMU1
) {
223 if (VB
->AttribPtr
[_TNL_ATTRIB_TEX0
] == 0)
224 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
] = VB
->AttribPtr
[_TNL_ATTRIB_TEX1
];
226 if (VB
->AttribPtr
[_TNL_ATTRIB_TEX1
]->size
== 4)
230 if (VB
->AttribPtr
[_TNL_ATTRIB_TEX0
] &&
231 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
]->size
== 4)
238 static void TAG(interp
)( GLcontext
*ctx
,
240 GLuint edst
, GLuint eout
, GLuint ein
,
241 GLboolean force_boundary
)
243 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
244 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
245 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
246 const GLfloat oow
= (dstclip
[3] == 0.0F
) ? 1.0F
: (1.0F
/ dstclip
[3]);
247 const GLfloat
*const s
= ctx
->Viewport
._WindowMap
.m
;
248 GrVertex
*fxverts
= fxMesa
->verts
;
249 GrVertex
*dst
= (GrVertex
*) (fxverts
+ edst
);
250 const GrVertex
*out
= (const GrVertex
*) (fxverts
+ eout
);
251 const GrVertex
*in
= (const GrVertex
*) (fxverts
+ ein
);
252 const GLfloat wout
= oow
/ out
->oow
;
253 const GLfloat win
= oow
/ in
->oow
;
255 VIEWPORT_X(dst
->x
, dstclip
[0] * oow
);
256 VIEWPORT_Y(dst
->y
, dstclip
[1] * oow
);
257 VIEWPORT_Z(dst
->ooz
, dstclip
[2] * oow
);
260 if (IND
& SETUP_SNAP
) {
261 #if defined(USE_IEEE)
262 const float snapper
= (3L << 18);
268 dst
->x
= ((int) (dst
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
269 dst
->y
= ((int) (dst
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
275 INTERP_UB( t
, dst
->pargb
[0], out
->pargb
[0], in
->pargb
[0] );
276 INTERP_UB( t
, dst
->pargb
[1], out
->pargb
[1], in
->pargb
[1] );
277 INTERP_UB( t
, dst
->pargb
[2], out
->pargb
[2], in
->pargb
[2] );
278 INTERP_UB( t
, dst
->pargb
[3], out
->pargb
[3], in
->pargb
[3] );
279 #else /* !FX_PACKEDCOLOR */
280 INTERP_F( t
, dst
->r
, out
->r
, in
->r
);
281 INTERP_F( t
, dst
->g
, out
->g
, in
->g
);
282 INTERP_F( t
, dst
->b
, out
->b
, in
->b
);
283 INTERP_F( t
, dst
->a
, out
->a
, in
->a
);
284 #endif /* !FX_PACKEDCOLOR */
286 if (IND
& SETUP_SPEC
) {
288 INTERP_UB( t
, dst
->pspec
[0], out
->pspec
[0], in
->pspec
[0] );
289 INTERP_UB( t
, dst
->pspec
[1], out
->pspec
[1], in
->pspec
[1] );
290 INTERP_UB( t
, dst
->pspec
[2], out
->pspec
[2], in
->pspec
[2] );
291 #else /* !FX_PACKEDCOLOR */
292 INTERP_F( t
, dst
->r1
, out
->r1
, in
->r1
);
293 INTERP_F( t
, dst
->g1
, out
->g1
, in
->g1
);
294 INTERP_F( t
, dst
->b1
, out
->b1
, in
->b1
);
295 #endif /* !FX_PACKEDCOLOR */
298 if (IND
& SETUP_FOGC
) {
299 INTERP_F( t
, dst
->fog
, out
->fog
, in
->fog
);
302 if (IND
& SETUP_TMU0
) {
305 out
->tmuvtx
[0].sow
* wout
,
306 in
->tmuvtx
[0].sow
* win
);
309 out
->tmuvtx
[0].tow
* wout
,
310 in
->tmuvtx
[0].tow
* win
);
311 if (IND
& SETUP_PTEX
) {
314 out
->tmuvtx
[0].oow
* wout
,
315 in
->tmuvtx
[0].oow
* win
);
319 if (IND
& SETUP_TMU1
) {
322 out
->tmuvtx
[1].sow
* wout
,
323 in
->tmuvtx
[1].sow
* win
);
326 out
->tmuvtx
[1].tow
* wout
,
327 in
->tmuvtx
[1].tow
* win
);
328 if (IND
& SETUP_PTEX
) {
331 out
->tmuvtx
[1].oow
* wout
,
332 in
->tmuvtx
[1].oow
* win
);
339 static void TAG(init
)( void )
341 setup_tab
[IND
].emit
= TAG(emit
);
343 if (IND
& SETUP_SPEC
) {
344 setup_tab
[IND
].copy_pv
= copy_pv2
;
346 setup_tab
[IND
].copy_pv
= copy_pv
;
349 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
350 setup_tab
[IND
].check_tex_sizes
= TAG(check_tex_sizes
);
351 setup_tab
[IND
].interp
= TAG(interp
);
353 setup_tab
[IND
].vertex_format
= 0;
354 if (IND
& SETUP_PTEX
) {
355 setup_tab
[IND
].vertex_format
|= GR_STWHINT_W_DIFF_TMU0
;
358 #if (IND & SETUP_TMU1)
359 setup_tab
[IND
].vertex_format
|= GR_STWHINT_ST_DIFF_TMU1
;
360 if (IND
& SETUP_PTEX
) {
361 setup_tab
[IND
].vertex_format
|= GR_STWHINT_W_DIFF_TMU1
;