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 radeon_print(RADEON_SWRENDER
, RADEON_VERBOSE
, "%s\n", __FUNCTION__
);
59 coord
= (GLuint (*)[4])VB
->ObjPtr
->data
;
60 coord_stride
= VB
->ObjPtr
->stride
;
63 if (VB
->TexCoordPtr
[2]) {
64 const GLuint t2
= GET_TEXSOURCE(2);
65 tc2
= (GLuint (*)[4])VB
->TexCoordPtr
[t2
]->data
;
66 tc2_stride
= VB
->TexCoordPtr
[t2
]->stride
;
67 if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 3) {
70 else if (DO_PTEX
&& VB
->TexCoordPtr
[t2
]->size
< 4) {
71 rqcoordsnoswap
|= (1<<2);
74 tc2
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX2
];
80 if (VB
->TexCoordPtr
[1]) {
81 const GLuint t1
= GET_TEXSOURCE(1);
82 tc1
= (GLuint (*)[4])VB
->TexCoordPtr
[t1
]->data
;
83 tc1_stride
= VB
->TexCoordPtr
[t1
]->stride
;
84 if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 3) {
87 else if (DO_PTEX
&& VB
->TexCoordPtr
[t1
]->size
< 4) {
88 rqcoordsnoswap
|= (1<<1);
91 tc1
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX1
];
97 if (VB
->TexCoordPtr
[0]) {
98 const GLuint t0
= GET_TEXSOURCE(0);
99 tc0_stride
= VB
->TexCoordPtr
[t0
]->stride
;
100 tc0
= (GLuint (*)[4])VB
->TexCoordPtr
[t0
]->data
;
101 if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 3) {
104 else if (DO_PTEX
&& VB
->TexCoordPtr
[t0
]->size
< 4) {
105 rqcoordsnoswap
|= (1<<0);
108 tc0
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
];
116 norm_stride
= VB
->NormalPtr
->stride
;
117 norm
= (GLuint (*)[4])VB
->NormalPtr
->data
;
120 norm
= (GLuint (*)[4])&ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
];
125 if (VB
->ColorPtr
[0]) {
126 col
= VB
->ColorPtr
[0]->data
;
127 col_stride
= VB
->ColorPtr
[0]->stride
;
129 col
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
];
134 if (DO_SPEC_OR_FOG
) {
135 if (VB
->SecondaryColorPtr
[0]) {
136 spec
= VB
->SecondaryColorPtr
[0]->data
;
137 spec_stride
= VB
->SecondaryColorPtr
[0]->stride
;
139 spec
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
];
144 if (DO_SPEC_OR_FOG
) {
145 if (VB
->FogCoordPtr
) {
146 fog
= VB
->FogCoordPtr
->data
;
147 fog_stride
= VB
->FogCoordPtr
->stride
;
149 fog
= (GLfloat (*)[4])ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
];
156 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ start
* coord_stride
);
158 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ start
* tc0_stride
);
160 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ start
* tc1_stride
);
162 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ start
* tc2_stride
);
164 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ start
* norm_stride
);
166 STRIDE_4F(col
, start
* col_stride
);
168 STRIDE_4F(spec
, start
* spec_stride
);
170 STRIDE_4F(fog
, start
* fog_stride
);
175 for (i
=start
; i
< end
; i
++) {
177 v
[0].ui
= coord
[0][0];
178 v
[1].ui
= coord
[0][1];
179 v
[2].ui
= coord
[0][2];
181 v
[3].ui
= coord
[0][3];
186 coord
= (GLuint (*)[4])((GLubyte
*)coord
+ coord_stride
);
189 v
[0].ui
= norm
[0][0];
190 v
[1].ui
= norm
[0][1];
191 v
[2].ui
= norm
[0][2];
193 norm
= (GLuint (*)[4])((GLubyte
*)norm
+ norm_stride
);
196 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, col
[0][0]);
197 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, col
[0][1]);
198 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, col
[0][2]);
199 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, col
[0][3]);
200 STRIDE_4F(col
, col_stride
);
203 if (DO_SPEC_OR_FOG
) {
205 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.red
, spec
[0][0]);
206 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.green
, spec
[0][1]);
207 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.blue
, spec
[0][2]);
208 STRIDE_4F(spec
, spec_stride
);
211 UNCLAMPED_FLOAT_TO_UBYTE(v
[0].rgba
.alpha
, radeonComputeFogBlendFactor(ctx
, fog
[0][0]));
212 STRIDE_4F(fog
, fog_stride
);
214 if (TCL_DEBUG
) fprintf(stderr
, "%x ", v
[0].ui
);
220 if (TCL_DEBUG
) fprintf(stderr
, "t0: %.2f %.2f ", v
[0].f
, v
[1].f
);
222 if (fill_tex
& (1<<0))
224 else if (rqcoordsnoswap
& (1<<0))
228 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
233 tc0
= (GLuint (*)[4])((GLubyte
*)tc0
+ tc0_stride
);
238 if (TCL_DEBUG
) fprintf(stderr
, "t1: %.2f %.2f ", v
[0].f
, v
[1].f
);
240 if (fill_tex
& (1<<1))
242 else if (rqcoordsnoswap
& (1<<1))
246 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
251 tc1
= (GLuint (*)[4])((GLubyte
*)tc1
+ tc1_stride
);
256 if (TCL_DEBUG
) fprintf(stderr
, "t2: %.2f %.2f ", v
[0].f
, v
[1].f
);
258 if (fill_tex
& (1<<2))
260 else if (rqcoordsnoswap
& (1<<2))
264 if (TCL_DEBUG
) fprintf(stderr
, "%.2f ", v
[2].f
);
269 tc2
= (GLuint (*)[4])((GLubyte
*)tc2
+ tc2_stride
);
271 if (TCL_DEBUG
) fprintf(stderr
, "\n");
278 static void TAG(init
)( void )
282 if (DO_NORM
) sz
+= 3;
284 if (DO_SPEC_OR_FOG
) sz
++;
285 if (DO_TEX0
) sz
+= 2;
286 if (DO_TEX0
&& DO_PTEX
) sz
++;
287 if (DO_TEX1
) sz
+= 2;
288 if (DO_TEX1
&& DO_PTEX
) sz
++;
289 if (DO_TEX2
) sz
+= 2;
290 if (DO_TEX2
&& DO_PTEX
) sz
++;
292 setup_tab
[IDX
].emit
= TAG(emit
);
293 setup_tab
[IDX
].vertex_format
= IND
;
294 setup_tab
[IDX
].vertex_size
= sz
;