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.
25 * Keith Whitwell <keith@tungstengraphics.com>
37 static void TAG(emit
)( GLcontext
*ctx
,
38 GLuint start
, GLuint end
,
42 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
43 GLuint (*tc0
)[4], (*tc1
)[4], (*tc2
)[4];
44 GLfloat (*col
)[4], (*spec
)[4];
47 GLuint tc0_stride
, tc1_stride
, col_stride
, spec_stride
, fog_stride
;
48 GLuint tc2_stride
, norm_stride
;
50 GLuint rqcoordsnoswap
= 0;
52 GLuint coord_stride
; /* object coordinates */
55 union emit_union
*v
= (union emit_union
*)dest
;
57 if (RADEON_DEBUG
& DEBUG_VERTS
)
58 fprintf(stderr
, "%s\n", __FUNCTION__
);
60 coord
= (GLuint (*)[4])VB
->ObjPtr
->data
;
61 coord_stride
= VB
->ObjPtr
->stride
;
64 if (VB
->TexCoordPtr
[2]) {
65 const GLuint t2
= GET_TEXSOURCE(2);
66 tc2
= (GLuint (*)[4])VB
->TexCoordPtr
[t2
]->data
;
67 tc2_stride
= VB
->TexCoordPtr
[t2
]->stride
;
68 if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 3) {
71 else if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 4) {
72 rqcoordsnoswap
|= (1<<2);
75 tc2
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
81 if (VB
->TexCoordPtr
[1]) {
82 const GLuint t1
= GET_TEXSOURCE(1);
83 tc1
= (GLuint (*)[4])VB
->TexCoordPtr
[t1
]->data
;
84 tc1_stride
= VB
->TexCoordPtr
[t1
]->stride
;
85 if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 3) {
88 else if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 4) {
89 rqcoordsnoswap
|= (1<<1);
92 tc1
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
98 if (VB
->TexCoordPtr
[0]) {
99 const GLuint t0
= GET_TEXSOURCE(0);
100 tc0_stride
= VB
->TexCoordPtr
[t0
]->stride
;
101 tc0
= (GLuint (*)[4])VB
->TexCoordPtr
[t0
]->data
;
102 if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 3) {
105 else if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 4) {
106 rqcoordsnoswap
|= (1<<0);
109 tc0
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
117 norm_stride
= VB
->NormalPtr
->stride
;
118 norm
= (GLuint (*)[4])VB
->NormalPtr
->data
;
121 norm
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
126 if (VB
->ColorPtr
[0]) {
127 col
= VB
->ColorPtr
[0]->data
;
128 col_stride
= VB
->ColorPtr
[0]->stride
;
130 col
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
135 if (DO_SPEC_OR_FOG
) {
136 if (VB
->SecondaryColorPtr
[0]) {
137 spec
= VB
->SecondaryColorPtr
[0]->data
;
138 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
140 spec
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
145 if (DO_SPEC_OR_FOG
) {
146 if (VB
->FogCoordPtr
) {
147 fog
= VB
->FogCoordPtr
->data
;
148 fog_stride
= VB
->FogCoordPtr
->stride
;
150 fog
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
];
157 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ start
* coord_stride
);
159 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
161 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
163 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ start
* tc2_stride
);
165 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ start
* norm_stride
);
167 STRIDE_4F(col
, start
* col_stride
);
169 STRIDE_4F(spec
, start
* spec_stride
);
171 STRIDE_4F(fog
, start
* fog_stride
);
176 for (i
=start
; i
< end
; i
++) {
178 v
[0].ui
= coord
[0][0];
179 v
[1].ui
= coord
[0][1];
180 v
[2].ui
= coord
[0][2];
182 v
[3].ui
= coord
[0][3];
187 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ coord_stride
);
190 v
[0].ui
= norm
[0][0];
191 v
[1].ui
= norm
[0][1];
192 v
[2].ui
= norm
[0][2];
194 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ norm_stride
);
197 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, col
[0][0]);
198 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, col
[0][1]);
199 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, col
[0][2]);
200 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, col
[0][3]);
201 STRIDE_4F(col
, col_stride
);
204 if (DO_SPEC_OR_FOG
) {
206 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, spec
[0][0]);
207 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, spec
[0][1]);
208 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, spec
[0][2]);
209 STRIDE_4F(spec
, spec_stride
);
212 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, radeonComputeFogBlendFactor(ctx
, fog
[0][0]));
213 STRIDE_4F(fog
, fog_stride
);
215 if (TCL_DEBUG
) fprintf(stderr
, "%x ", v
[0].ui
);
221 if (TCL_DEBUG
) fprintf(stderr
, "t0: %.2f %.2f ", v
[0].f
, v
[1].f
);
223 if (fill_tex
& (1<<0))
225 else if (rqcoordsnoswap
& (1<<0))
229 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
234 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
239 if (TCL_DEBUG
) fprintf(stderr
, "t1: %.2f %.2f ", v
[0].f
, v
[1].f
);
241 if (fill_tex
& (1<<1))
243 else if (rqcoordsnoswap
& (1<<1))
247 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
252 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
257 if (TCL_DEBUG
) fprintf(stderr
, "t2: %.2f %.2f ", v
[0].f
, v
[1].f
);
259 if (fill_tex
& (1<<2))
261 else if (rqcoordsnoswap
& (1<<2))
265 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
270 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ tc2_stride
);
272 if (TCL_DEBUG
) fprintf(stderr
, "\n");
279 static void TAG(init
)( void )
283 if (DO_NORM
) sz
+= 3;
285 if (DO_SPEC_OR_FOG
) sz
++;
286 if (DO_TEX0
) sz
+= 2;
287 if (DO_TEX0
&& DO_PTEX
) sz
++;
288 if (DO_TEX1
) sz
+= 2;
289 if (DO_TEX1
&& DO_PTEX
) sz
++;
290 if (DO_TEX2
) sz
+= 2;
291 if (DO_TEX2
&& DO_PTEX
) sz
++;
293 setup_tab
[IDX
].emit
= TAG(emit
);
294 setup_tab
[IDX
].vertex_format
= IND
;
295 setup_tab
[IDX
].vertex_size
= sz
;