new files
[mesa.git] / src / mesa / tnl / t_vtx_generic.c
1 /**************************************************************************
2
3 Copyright 2004 Tungsten Graphics Inc., Cedar Park, Texas.
4
5 All Rights Reserved.
6
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 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29 * Authors:
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33 #include "glheader.h"
34 #include "context.h"
35 #include "macros.h"
36 #include "vtxfmt.h"
37 #include "dlist.h"
38 #include "state.h"
39 #include "light.h"
40 #include "api_arrayelt.h"
41 #include "api_noop.h"
42 #include "t_vtx_api.h"
43
44
45 /* Versions of all the entrypoints for situations where codegen isn't
46 * available.
47 *
48 * Note: Only one size for each attribute may be active at once.
49 * Eg. if Color3f is installed/active, then Color4f may not be, even
50 * if the vertex actually contains 4 color coordinates. This is
51 * because the 3f version won't otherwise set color[3] to 1.0 -- this
52 * is the job of the chooser function when switching between Color4f
53 * and Color3f.
54 */
55 #define ATTRFV( ATTR, N ) \
56 static void attrib_##ATTR##_##N( const GLfloat *v ) \
57 { \
58 GET_CURRENT_CONTEXT( ctx ); \
59 TNLcontext *tnl = TNL_CONTEXT(ctx); \
60 \
61 if ((ATTR) == 0) { \
62 GLuint i; \
63 \
64 if (N>0) tnl->vtx.vbptr[0] = v[0]; \
65 if (N>1) tnl->vtx.vbptr[1] = v[1]; \
66 if (N>2) tnl->vtx.vbptr[2] = v[2]; \
67 if (N>3) tnl->vtx.vbptr[3] = v[3]; \
68 \
69 for (i = N; i < tnl->vtx.vertex_size; i++) \
70 tnl->vtx.vbptr[i] = tnl->vtx.vertex[i]; \
71 \
72 tnl->vtx.vbptr += tnl->vtx.vertex_size; \
73 \
74 if (--tnl->vtx.counter == 0) \
75 _tnl_wrap_filled_vertex( ctx ); \
76 } \
77 else { \
78 GLfloat *dest = tnl->vtx.attrptr[ATTR]; \
79 if (N>0) dest[0] = v[0]; \
80 if (N>1) dest[1] = v[1]; \
81 if (N>2) dest[2] = v[2]; \
82 if (N>3) dest[3] = v[3]; \
83 } \
84 }
85
86 #define INIT(TAB, ATTR) \
87 TAB[ATTR][0] = attrib_##ATTR##_1; \
88 TAB[ATTR][1] = attrib_##ATTR##_2; \
89 TAB[ATTR][2] = attrib_##ATTR##_3; \
90 TAB[ATTR][3] = attrib_##ATTR##_4;
91
92
93 #define ATTRS( ATTRIB ) \
94 ATTRFV( ATTRIB, 1 ) \
95 ATTRFV( ATTRIB, 2 ) \
96 ATTRFV( ATTRIB, 3 ) \
97 ATTRFV( ATTRIB, 4 )
98
99 ATTRS( 0 )
100 ATTRS( 1 )
101 ATTRS( 2 )
102 ATTRS( 3 )
103 ATTRS( 4 )
104 ATTRS( 5 )
105 ATTRS( 6 )
106 ATTRS( 7 )
107 ATTRS( 8 )
108 ATTRS( 9 )
109 ATTRS( 10 )
110 ATTRS( 11 )
111 ATTRS( 12 )
112 ATTRS( 13 )
113 ATTRS( 14 )
114 ATTRS( 15 )
115
116 void _tnl_generic_attr_table_init( attrfv_func (*tab)[4] )
117 {
118 INIT( tab, 0 );
119 INIT( tab, 1 );
120 INIT( tab, 2 );
121 INIT( tab, 3 );
122 INIT( tab, 4 );
123 INIT( tab, 5 );
124 INIT( tab, 6 );
125 INIT( tab, 7 );
126 INIT( tab, 8 );
127 INIT( tab, 9 );
128 INIT( tab, 10 );
129 INIT( tab, 11 );
130 INIT( tab, 12 );
131 INIT( tab, 13 );
132 INIT( tab, 14 );
133 INIT( tab, 15 );
134 }
135
136 /* These can be made efficient with codegen. Further, by adding more
137 * logic to do_choose(), the double-dispatch for legacy entrypoints
138 * like glVertex3f() can be removed.
139 */
140 #define DISPATCH_ATTRFV( ATTR, COUNT, P ) \
141 do { \
142 GET_CURRENT_CONTEXT( ctx ); \
143 TNLcontext *tnl = TNL_CONTEXT(ctx); \
144 tnl->vtx.tabfv[ATTR][COUNT-1]( P ); \
145 } while (0)
146
147 #define DISPATCH_ATTR1FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 1, V )
148 #define DISPATCH_ATTR2FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 2, V )
149 #define DISPATCH_ATTR3FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 3, V )
150 #define DISPATCH_ATTR4FV( ATTR, V ) DISPATCH_ATTRFV( ATTR, 4, V )
151
152 #define DISPATCH_ATTR1F( ATTR, S ) DISPATCH_ATTRFV( ATTR, 1, &(S) )
153
154 #define DISPATCH_ATTR2F( ATTR, S,T ) \
155 do { \
156 GLfloat v[2]; \
157 v[0] = S; v[1] = T; \
158 DISPATCH_ATTR2FV( ATTR, v ); \
159 } while (0)
160 #define DISPATCH_ATTR3F( ATTR, S,T,R ) \
161 do { \
162 GLfloat v[3]; \
163 v[0] = S; v[1] = T; v[2] = R; \
164 DISPATCH_ATTR3FV( ATTR, v ); \
165 } while (0)
166 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
167 do { \
168 GLfloat v[4]; \
169 v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
170 DISPATCH_ATTR4FV( ATTR, v ); \
171 } while (0)
172
173
174 static void GLAPIENTRY _tnl_Vertex2f( GLfloat x, GLfloat y )
175 {
176 DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );
177 }
178
179 static void GLAPIENTRY _tnl_Vertex2fv( const GLfloat *v )
180 {
181 DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );
182 }
183
184 static void GLAPIENTRY _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
185 {
186 DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );
187 }
188
189 static void GLAPIENTRY _tnl_Vertex3fv( const GLfloat *v )
190 {
191 DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );
192 }
193
194 static void GLAPIENTRY _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z,
195 GLfloat w )
196 {
197 DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );
198 }
199
200 static void GLAPIENTRY _tnl_Vertex4fv( const GLfloat *v )
201 {
202 DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );
203 }
204
205 static void GLAPIENTRY _tnl_TexCoord1f( GLfloat x )
206 {
207 DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );
208 }
209
210 static void GLAPIENTRY _tnl_TexCoord1fv( const GLfloat *v )
211 {
212 DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );
213 }
214
215 static void GLAPIENTRY _tnl_TexCoord2f( GLfloat x, GLfloat y )
216 {
217 DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );
218 }
219
220 static void GLAPIENTRY _tnl_TexCoord2fv( const GLfloat *v )
221 {
222 DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );
223 }
224
225 static void GLAPIENTRY _tnl_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
226 {
227 DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );
228 }
229
230 static void GLAPIENTRY _tnl_TexCoord3fv( const GLfloat *v )
231 {
232 DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );
233 }
234
235 static void GLAPIENTRY _tnl_TexCoord4f( GLfloat x, GLfloat y, GLfloat z,
236 GLfloat w )
237 {
238 DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );
239 }
240
241 static void GLAPIENTRY _tnl_TexCoord4fv( const GLfloat *v )
242 {
243 DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );
244 }
245
246 static void GLAPIENTRY _tnl_Normal3f( GLfloat x, GLfloat y, GLfloat z )
247 {
248 DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );
249 }
250
251 static void GLAPIENTRY _tnl_Normal3fv( const GLfloat *v )
252 {
253 DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );
254 }
255
256 static void GLAPIENTRY _tnl_FogCoordfEXT( GLfloat x )
257 {
258 DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );
259 }
260
261 static void GLAPIENTRY _tnl_FogCoordfvEXT( const GLfloat *v )
262 {
263 DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );
264 }
265
266 static void GLAPIENTRY _tnl_Color3f( GLfloat x, GLfloat y, GLfloat z )
267 {
268 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );
269 }
270
271 static void GLAPIENTRY _tnl_Color3fv( const GLfloat *v )
272 {
273 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
274 }
275
276 static void GLAPIENTRY _tnl_Color4f( GLfloat x, GLfloat y, GLfloat z,
277 GLfloat w )
278 {
279 DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w );
280 }
281
282 static void GLAPIENTRY _tnl_Color4fv( const GLfloat *v )
283 {
284 DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v );
285 }
286
287 static void GLAPIENTRY _tnl_SecondaryColor3fEXT( GLfloat x, GLfloat y,
288 GLfloat z )
289 {
290 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z );
291 }
292
293 static void GLAPIENTRY _tnl_SecondaryColor3fvEXT( const GLfloat *v )
294 {
295 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v );
296 }
297
298 static void GLAPIENTRY _tnl_MultiTexCoord1f( GLenum target, GLfloat x )
299 {
300 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
301 DISPATCH_ATTR1F( attr, x );
302 }
303
304 static void GLAPIENTRY _tnl_MultiTexCoord1fv( GLenum target,
305 const GLfloat *v )
306 {
307 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
308 DISPATCH_ATTR1FV( attr, v );
309 }
310
311 static void GLAPIENTRY _tnl_MultiTexCoord2f( GLenum target, GLfloat x,
312 GLfloat y )
313 {
314 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
315 DISPATCH_ATTR2F( attr, x, y );
316 }
317
318 static void GLAPIENTRY _tnl_MultiTexCoord2fv( GLenum target,
319 const GLfloat *v )
320 {
321 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
322 DISPATCH_ATTR2FV( attr, v );
323 }
324
325 static void GLAPIENTRY _tnl_MultiTexCoord3f( GLenum target, GLfloat x,
326 GLfloat y, GLfloat z)
327 {
328 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
329 DISPATCH_ATTR3F( attr, x, y, z );
330 }
331
332 static void GLAPIENTRY _tnl_MultiTexCoord3fv( GLenum target,
333 const GLfloat *v )
334 {
335 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
336 DISPATCH_ATTR3FV( attr, v );
337 }
338
339 static void GLAPIENTRY _tnl_MultiTexCoord4f( GLenum target, GLfloat x,
340 GLfloat y, GLfloat z,
341 GLfloat w )
342 {
343 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
344 DISPATCH_ATTR4F( attr, x, y, z, w );
345 }
346
347 static void GLAPIENTRY _tnl_MultiTexCoord4fv( GLenum target,
348 const GLfloat *v )
349 {
350 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
351 DISPATCH_ATTR4FV( attr, v );
352 }
353
354 static void GLAPIENTRY _tnl_VertexAttrib1fNV( GLuint index, GLfloat x )
355 {
356 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
357 DISPATCH_ATTR1F( index, x );
358 }
359
360 static void GLAPIENTRY _tnl_VertexAttrib1fvNV( GLuint index,
361 const GLfloat *v )
362 {
363 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
364 DISPATCH_ATTR1FV( index, v );
365 }
366
367 static void GLAPIENTRY _tnl_VertexAttrib2fNV( GLuint index, GLfloat x,
368 GLfloat y )
369 {
370 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
371 DISPATCH_ATTR2F( index, x, y );
372 }
373
374 static void GLAPIENTRY _tnl_VertexAttrib2fvNV( GLuint index,
375 const GLfloat *v )
376 {
377 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
378 DISPATCH_ATTR2FV( index, v );
379 }
380
381 static void GLAPIENTRY _tnl_VertexAttrib3fNV( GLuint index, GLfloat x,
382 GLfloat y, GLfloat z )
383 {
384 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
385 DISPATCH_ATTR3F( index, x, y, z );
386 }
387
388 static void GLAPIENTRY _tnl_VertexAttrib3fvNV( GLuint index,
389 const GLfloat *v )
390 {
391 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
392 DISPATCH_ATTR3FV( index, v );
393 }
394
395 static void GLAPIENTRY _tnl_VertexAttrib4fNV( GLuint index, GLfloat x,
396 GLfloat y, GLfloat z,
397 GLfloat w )
398 {
399 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
400 DISPATCH_ATTR4F( index, x, y, z, w );
401 }
402
403 static void GLAPIENTRY _tnl_VertexAttrib4fvNV( GLuint index,
404 const GLfloat *v )
405 {
406 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
407 DISPATCH_ATTR4FV( index, v );
408 }
409
410
411 /* Install the generic versions of the 2nd level dispatch functions.
412 * There's currently no codegen alternative to these, though one is in
413 * the works.
414 */
415 void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx )
416 {
417 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
418
419 vfmt->Color3f = _tnl_Color3f;
420 vfmt->Color3fv = _tnl_Color3fv;
421 vfmt->Color4f = _tnl_Color4f;
422 vfmt->Color4fv = _tnl_Color4fv;
423 vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
424 vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
425 vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1f;
426 vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv;
427 vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2f;
428 vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv;
429 vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3f;
430 vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv;
431 vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4f;
432 vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv;
433 vfmt->Normal3f = _tnl_Normal3f;
434 vfmt->Normal3fv = _tnl_Normal3fv;
435 vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
436 vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
437 vfmt->TexCoord1f = _tnl_TexCoord1f;
438 vfmt->TexCoord1fv = _tnl_TexCoord1fv;
439 vfmt->TexCoord2f = _tnl_TexCoord2f;
440 vfmt->TexCoord2fv = _tnl_TexCoord2fv;
441 vfmt->TexCoord3f = _tnl_TexCoord3f;
442 vfmt->TexCoord3fv = _tnl_TexCoord3fv;
443 vfmt->TexCoord4f = _tnl_TexCoord4f;
444 vfmt->TexCoord4fv = _tnl_TexCoord4fv;
445 vfmt->Vertex2f = _tnl_Vertex2f;
446 vfmt->Vertex2fv = _tnl_Vertex2fv;
447 vfmt->Vertex3f = _tnl_Vertex3f;
448 vfmt->Vertex3fv = _tnl_Vertex3fv;
449 vfmt->Vertex4f = _tnl_Vertex4f;
450 vfmt->Vertex4fv = _tnl_Vertex4fv;
451 vfmt->VertexAttrib1fNV = _tnl_VertexAttrib1fNV;
452 vfmt->VertexAttrib1fvNV = _tnl_VertexAttrib1fvNV;
453 vfmt->VertexAttrib2fNV = _tnl_VertexAttrib2fNV;
454 vfmt->VertexAttrib2fvNV = _tnl_VertexAttrib2fvNV;
455 vfmt->VertexAttrib3fNV = _tnl_VertexAttrib3fNV;
456 vfmt->VertexAttrib3fvNV = _tnl_VertexAttrib3fvNV;
457 vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
458 vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
459 }