1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keithw@vmware.com>
26 */
27
28 #ifndef LOCALVARS
29 #define LOCALVARS
30 #endif
31
32 #undef TCL_DEBUG
33 #ifndef TCL_DEBUG
34 #define TCL_DEBUG 0
35 #endif
36
TAG(emit)37 static void TAG(emit)( struct gl_context *ctx,
38 GLuint start, GLuint end,
39 void *dest )
40 {
41 LOCALVARS
42 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
43 GLuint (*tc0)[4], (*tc1)[4], (*tc2)[4];
44 GLfloat (*col)[4], (*spec)[4];
45 GLfloat (*fog)[4];
46 GLuint (*norm)[4];
47 GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
48 GLuint tc2_stride, norm_stride;
49 GLuint fill_tex = 0;
50 GLuint rqcoordsnoswap = 0;
51 GLuint (*coord)[4];
52 GLuint coord_stride; /* object coordinates */
53 int i;
54
55 union emit_union *v = (union emit_union *)dest;
56
57 radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
58
59 coord = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_POS]->data;
60 coord_stride = VB->AttribPtr[_TNL_ATTRIB_POS]->stride;
61
62 if (DO_TEX2) {
63 if (VB->AttribPtr[_TNL_ATTRIB_TEX2]) {
64 const GLuint t2 = GET_TEXSOURCE(2);
65 tc2 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->data;
66 tc2_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->stride;
67 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 3) {
68 fill_tex |= (1<<2);
69 }
70 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t2]->size < 4) {
71 rqcoordsnoswap |= (1<<2);
72 }
73 } else {
74 tc2 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX2];
75 tc2_stride = 0;
76 }
77 }
78
79 if (DO_TEX1) {
80 if (VB->AttribPtr[_TNL_ATTRIB_TEX1]) {
81 const GLuint t1 = GET_TEXSOURCE(1);
82 tc1 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->data;
83 tc1_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->stride;
84 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 3) {
85 fill_tex |= (1<<1);
86 }
87 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t1]->size < 4) {
88 rqcoordsnoswap |= (1<<1);
89 }
90 } else {
91 tc1 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX1];
92 tc1_stride = 0;
93 }
94 }
95
96 if (DO_TEX0) {
97 if (VB->AttribPtr[_TNL_ATTRIB_TEX0]) {
98 const GLuint t0 = GET_TEXSOURCE(0);
99 tc0_stride = VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->stride;
100 tc0 = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->data;
101 if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 3) {
102 fill_tex |= (1<<0);
103 }
104 else if (DO_PTEX && VB->AttribPtr[_TNL_ATTRIB_TEX0 + t0]->size < 4) {
105 rqcoordsnoswap |= (1<<0);
106 }
107 } else {
108 tc0 = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_TEX0];
109 tc0_stride = 0;
110 }
111
112 }
113
114 if (DO_NORM) {
115 if (VB->AttribPtr[_TNL_ATTRIB_NORMAL]) {
116 norm_stride = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->stride;
117 norm = (GLuint (*)[4])VB->AttribPtr[_TNL_ATTRIB_NORMAL]->data;
118 } else {
119 norm_stride = 0;
120 norm = (GLuint (*)[4])&ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
121 }
122 }
123
124 if (DO_RGBA) {
125 if (VB->AttribPtr[_TNL_ATTRIB_COLOR0]) {
126 col = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->data;
127 col_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->stride;
128 } else {
129 col = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
130 col_stride = 0;
131 }
132 }
133
134 if (DO_SPEC_OR_FOG) {
135 if (VB->AttribPtr[_TNL_ATTRIB_COLOR1]) {
136 spec = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->data;
137 spec_stride = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->stride;
138 } else {
139 spec = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
140 spec_stride = 0;
141 }
142 }
143
144 if (DO_SPEC_OR_FOG) {
145 if (VB->AttribPtr[_TNL_ATTRIB_FOG]) {
146 fog = VB->AttribPtr[_TNL_ATTRIB_FOG]->data;
147 fog_stride = VB->AttribPtr[_TNL_ATTRIB_FOG]->stride;
148 } else {
149 fog = (GLfloat (*)[4])ctx->Current.Attrib[VERT_ATTRIB_FOG];
150 fog_stride = 0;
151 }
152 }
153
154
155 if (start) {
156 coord = (GLuint (*)[4])((GLubyte *)coord + start * coord_stride);
157 if (DO_TEX0)
158 tc0 = (GLuint (*)[4])((GLubyte *)tc0 + start * tc0_stride);
159 if (DO_TEX1)
160 tc1 = (GLuint (*)[4])((GLubyte *)tc1 + start * tc1_stride);
161 if (DO_TEX2)
162 tc2 = (GLuint (*)[4])((GLubyte *)tc2 + start * tc2_stride);
163 if (DO_NORM)
164 norm = (GLuint (*)[4])((GLubyte *)norm + start * norm_stride);
165 if (DO_RGBA)
166 STRIDE_4F(col, start * col_stride);
167 if (DO_SPEC)
168 STRIDE_4F(spec, start * spec_stride);
169 if (DO_FOG)
170 STRIDE_4F(fog, start * fog_stride);
171 }
172
173
174 {
175 for (i=start; i < end; i++) {
176
177 v[0].ui = coord[0][0];
178 v[1].ui = coord[0][1];
179 v[2].ui = coord[0][2];
180 if (DO_W) {
181 v[3].ui = coord[0][3];
182 v += 4;
183 }
184 else
185 v += 3;
186 coord = (GLuint (*)[4])((GLubyte *)coord + coord_stride);
187
188 if (DO_NORM) {
189 v[0].ui = norm[0][0];
190 v[1].ui = norm[0][1];
191 v[2].ui = norm[0][2];
192 v += 3;
193 norm = (GLuint (*)[4])((GLubyte *)norm + norm_stride);
194 }
195 if (DO_RGBA) {
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);
201 v++;
202 }
203 if (DO_SPEC_OR_FOG) {
204 if (DO_SPEC) {
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);
209 }
210 if (DO_FOG) {
211 UNCLAMPED_FLOAT_TO_UBYTE(v[0].rgba.alpha, radeonComputeFogBlendFactor(ctx, fog[0][0]));
212 STRIDE_4F(fog, fog_stride);
213 }
214 if (TCL_DEBUG) fprintf(stderr, "%x ", v[0].ui);
215 v++;
216 }
217 if (DO_TEX0) {
218 v[0].ui = tc0[0][0];
219 v[1].ui = tc0[0][1];
220 if (TCL_DEBUG) fprintf(stderr, "t0: %.2f %.2f ", v[0].f, v[1].f);
221 if (DO_PTEX) {
222 if (fill_tex & (1<<0))
223 v[2].f = 1.0;
224 else if (rqcoordsnoswap & (1<<0))
225 v[2].ui = tc0[0][2];
226 else
227 v[2].ui = tc0[0][3];
228 if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
229 v += 3;
230 }
231 else
232 v += 2;
233 tc0 = (GLuint (*)[4])((GLubyte *)tc0 + tc0_stride);
234 }
235 if (DO_TEX1) {
236 v[0].ui = tc1[0][0];
237 v[1].ui = tc1[0][1];
238 if (TCL_DEBUG) fprintf(stderr, "t1: %.2f %.2f ", v[0].f, v[1].f);
239 if (DO_PTEX) {
240 if (fill_tex & (1<<1))
241 v[2].f = 1.0;
242 else if (rqcoordsnoswap & (1<<1))
243 v[2].ui = tc1[0][2];
244 else
245 v[2].ui = tc1[0][3];
246 if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
247 v += 3;
248 }
249 else
250 v += 2;
251 tc1 = (GLuint (*)[4])((GLubyte *)tc1 + tc1_stride);
252 }
253 if (DO_TEX2) {
254 v[0].ui = tc2[0][0];
255 v[1].ui = tc2[0][1];
256 if (TCL_DEBUG) fprintf(stderr, "t2: %.2f %.2f ", v[0].f, v[1].f);
257 if (DO_PTEX) {
258 if (fill_tex & (1<<2))
259 v[2].f = 1.0;
260 else if (rqcoordsnoswap & (1<<2))
261 v[2].ui = tc2[0][2];
262 else
263 v[2].ui = tc2[0][3];
264 if (TCL_DEBUG) fprintf(stderr, "%.2f ", v[2].f);
265 v += 3;
266 }
267 else
268 v += 2;
269 tc2 = (GLuint (*)[4])((GLubyte *)tc2 + tc2_stride);
270 }
271 if (TCL_DEBUG) fprintf(stderr, "\n");
272 }
273 }
274 }
275
276
277
TAG(init)278 static void TAG(init)( void )
279 {
280 int sz = 3;
281 if (DO_W) sz++;
282 if (DO_NORM) sz += 3;
283 if (DO_RGBA) sz++;
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++;
291
292 setup_tab[IDX].emit = TAG(emit);
293 setup_tab[IDX].vertex_format = IND;
294 setup_tab[IDX].vertex_size = sz;
295 }
296
297
298 #undef IND
299 #undef TAG
300 #undef IDX
301