45166644d21298455ea0da6535075b87b29e954c
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
->TexCoordPtr
[tmu0_source
]->data
;
66 tc0_stride
= VB
->TexCoordPtr
[tmu0_source
]->stride
;
67 u0scale
= fxMesa
->s0scale
;
68 v0scale
= fxMesa
->t0scale
;
70 tc0_size
= VB
->TexCoordPtr
[tmu0_source
]->size
;
73 if (IND
& SETUP_TMU1
) {
74 tc1
= VB
->TexCoordPtr
[tmu1_source
]->data
;
75 tc1_stride
= VB
->TexCoordPtr
[tmu1_source
]->stride
;
76 u1scale
= fxMesa
->s1scale
; /* wrong if tmu1_source == 0, possible? */
77 v1scale
= fxMesa
->t1scale
;
79 tc1_size
= VB
->TexCoordPtr
[tmu1_source
]->size
;
82 if (IND
& SETUP_RGBA
) {
83 col
= VB
->ColorPtr
[0]->data
;
84 col_stride
= VB
->ColorPtr
[0]->stride
;
85 col_size
= VB
->ColorPtr
[0]->size
;
88 if (IND
& SETUP_SPEC
) {
89 spec
= VB
->SecondaryColorPtr
[0]->data
;
90 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
93 if (IND
& SETUP_FOGC
) {
94 fog
= VB
->FogCoordPtr
->data
;
95 fog_stride
= VB
->FogCoordPtr
->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]);
132 if (IND
& SETUP_SNAP
) {
133 #if defined(USE_IEEE)
134 const float snapper
= (3L << 18);
140 v
->x
= ((int) (v
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
141 v
->y
= ((int) (v
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
145 proj
= (GLfloat (*)[4])((GLubyte
*)proj
+ proj_stride
);
147 if (IND
& SETUP_RGBA
) {
148 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[2], col
[0][0]);
149 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[1], col
[0][1]);
150 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[0], col
[0][2]);
152 UNCLAMPED_FLOAT_TO_UBYTE(v
->pargb
[3], col
[0][3]);
156 STRIDE_4F(col
, col_stride
);
158 if (IND
& SETUP_SPEC
) {
159 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[2], spec
[0][0]);
160 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[1], spec
[0][1]);
161 UNCLAMPED_FLOAT_TO_UBYTE(v
->pspec
[0], spec
[0][2]);
162 STRIDE_4F(spec
, spec_stride
);
164 if (IND
& SETUP_FOGC
) {
165 v
->fog
= CLAMP(fog
[0][0], 0.0f
, 1.0f
);
166 fog
= (GLfloat (*)[4])((GLubyte
*)fog
+ fog_stride
);
168 if (IND
& SETUP_TMU0
) {
170 v
->tmuvtx
[0].sow
= tc0
[0][0] * u0scale
* w
;
171 v
->tmuvtx
[0].tow
= tc0
[0][1] * v0scale
* w
;
172 if (IND
& SETUP_PTEX
) {
173 v
->tmuvtx
[0].oow
= w
;
175 v
->tmuvtx
[0].oow
*= tc0
[0][3];
177 tc0
= (GLfloat (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
179 if (IND
& SETUP_TMU1
) {
181 v
->tmuvtx
[1].sow
= tc1
[0][0] * u1scale
* w
;
182 v
->tmuvtx
[1].tow
= tc1
[0][1] * v1scale
* w
;
183 if (IND
& SETUP_PTEX
) {
184 v
->tmuvtx
[1].oow
= w
;
186 v
->tmuvtx
[1].oow
*= tc1
[0][3];
188 tc1
= (GLfloat (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
193 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
195 static GLboolean
TAG(check_tex_sizes
)( GLcontext
*ctx
)
197 /* fprintf(stderr, "%s\n", __FUNCTION__); */
199 if (IND
& SETUP_PTEX
)
202 if (IND
& SETUP_TMU0
) {
203 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
205 if (IND
& SETUP_TMU1
) {
206 if (VB
->TexCoordPtr
[0] == 0)
207 VB
->TexCoordPtr
[0] = VB
->TexCoordPtr
[1];
209 if (VB
->TexCoordPtr
[1]->size
== 4)
213 if (VB
->TexCoordPtr
[0] && VB
->TexCoordPtr
[0]->size
== 4)
220 static void TAG(interp
)( GLcontext
*ctx
,
222 GLuint edst
, GLuint eout
, GLuint ein
,
223 GLboolean force_boundary
)
225 fxMesaContext fxMesa
= FX_CONTEXT( ctx
);
226 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
227 const GLfloat
*dstclip
= VB
->ClipPtr
->data
[edst
];
228 const GLfloat oow
= (dstclip
[3] == 0.0F
) ? 1.0F
: (1.0F
/ dstclip
[3]);
229 const GLfloat
*const s
= ctx
->Viewport
._WindowMap
.m
;
230 GrVertex
*fxverts
= fxMesa
->verts
;
231 GrVertex
*dst
= (GrVertex
*) (fxverts
+ edst
);
232 const GrVertex
*out
= (const GrVertex
*) (fxverts
+ eout
);
233 const GrVertex
*in
= (const GrVertex
*) (fxverts
+ ein
);
234 const GLfloat wout
= oow
/ out
->oow
;
235 const GLfloat win
= oow
/ in
->oow
;
237 VIEWPORT_X(dst
->x
, dstclip
[0] * oow
);
238 VIEWPORT_Y(dst
->y
, dstclip
[1] * oow
);
239 VIEWPORT_Z(dst
->ooz
, dstclip
[2] * oow
);
242 if (IND
& SETUP_SNAP
) {
243 #if defined(USE_IEEE)
244 const float snapper
= (3L << 18);
250 dst
->x
= ((int) (dst
->x
* 16.0f
)) * (1.0f
/ 16.0f
);
251 dst
->y
= ((int) (dst
->y
* 16.0f
)) * (1.0f
/ 16.0f
);
256 INTERP_UB( t
, dst
->pargb
[0], out
->pargb
[0], in
->pargb
[0] );
257 INTERP_UB( t
, dst
->pargb
[1], out
->pargb
[1], in
->pargb
[1] );
258 INTERP_UB( t
, dst
->pargb
[2], out
->pargb
[2], in
->pargb
[2] );
259 INTERP_UB( t
, dst
->pargb
[3], out
->pargb
[3], in
->pargb
[3] );
261 if (IND
& SETUP_SPEC
) {
262 INTERP_UB( t
, dst
->pspec
[0], out
->pspec
[0], in
->pspec
[0] );
263 INTERP_UB( t
, dst
->pspec
[1], out
->pspec
[1], in
->pspec
[1] );
264 INTERP_UB( t
, dst
->pspec
[2], out
->pspec
[2], in
->pspec
[2] );
267 if (IND
& SETUP_FOGC
) {
268 INTERP_F( t
, dst
->fog
, out
->fog
, in
->fog
);
271 if (IND
& SETUP_TMU0
) {
274 out
->tmuvtx
[0].sow
* wout
,
275 in
->tmuvtx
[0].sow
* win
);
278 out
->tmuvtx
[0].tow
* wout
,
279 in
->tmuvtx
[0].tow
* win
);
280 if (IND
& SETUP_PTEX
) {
283 out
->tmuvtx
[0].oow
* wout
,
284 in
->tmuvtx
[0].oow
* win
);
288 if (IND
& SETUP_TMU1
) {
291 out
->tmuvtx
[1].sow
* wout
,
292 in
->tmuvtx
[1].sow
* win
);
295 out
->tmuvtx
[1].tow
* wout
,
296 in
->tmuvtx
[1].tow
* win
);
297 if (IND
& SETUP_PTEX
) {
300 out
->tmuvtx
[1].oow
* wout
,
301 in
->tmuvtx
[1].oow
* win
);
308 static void TAG(init
)( void )
310 setup_tab
[IND
].emit
= TAG(emit
);
312 if (IND
& SETUP_SPEC
) {
313 setup_tab
[IND
].copy_pv
= copy_pv2
;
315 setup_tab
[IND
].copy_pv
= copy_pv
;
318 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
319 setup_tab
[IND
].check_tex_sizes
= TAG(check_tex_sizes
);
320 setup_tab
[IND
].interp
= TAG(interp
);
322 if (IND
& SETUP_PTEX
) {
323 setup_tab
[IND
].vertex_format
= (GR_STWHINT_W_DIFF_TMU0
|
324 GR_STWHINT_W_DIFF_TMU1
);
327 setup_tab
[IND
].vertex_format
= 0;
330 #if (IND & SETUP_TMU1)
331 setup_tab
[IND
].vertex_format
|= GR_STWHINT_ST_DIFF_TMU1
;