Rename the various function types in t_context.h to include a tnl_ prefix.
[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( tnl_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 #if defined(USE_X86_ASM) && 0 /* will break register calling convention */
155 /* Naughty cheat:
156 */
157 #define DISPATCH_ATTR2F( ATTR, S,T ) DISPATCH_ATTRFV( ATTR, 2, &(S) )
158 #define DISPATCH_ATTR3F( ATTR, S,T,R ) DISPATCH_ATTRFV( ATTR, 3, &(S) )
159 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) DISPATCH_ATTRFV( ATTR, 4, &(S) )
160 #else
161 /* Safe:
162 */
163 #define DISPATCH_ATTR2F( ATTR, S,T ) \
164 do { \
165 GLfloat v[2]; \
166 v[0] = S; v[1] = T; \
167 DISPATCH_ATTR2FV( ATTR, v ); \
168 } while (0)
169 #define DISPATCH_ATTR3F( ATTR, S,T,R ) \
170 do { \
171 GLfloat v[3]; \
172 v[0] = S; v[1] = T; v[2] = R; \
173 DISPATCH_ATTR3FV( ATTR, v ); \
174 } while (0)
175 #define DISPATCH_ATTR4F( ATTR, S,T,R,Q ) \
176 do { \
177 GLfloat v[4]; \
178 v[0] = S; v[1] = T; v[2] = R; v[3] = Q; \
179 DISPATCH_ATTR4FV( ATTR, v ); \
180 } while (0)
181 #endif
182
183
184 static void GLAPIENTRY _tnl_Vertex2f( GLfloat x, GLfloat y )
185 {
186 DISPATCH_ATTR2F( _TNL_ATTRIB_POS, x, y );
187 }
188
189 static void GLAPIENTRY _tnl_Vertex2fv( const GLfloat *v )
190 {
191 DISPATCH_ATTR2FV( _TNL_ATTRIB_POS, v );
192 }
193
194 static void GLAPIENTRY _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
195 {
196 DISPATCH_ATTR3F( _TNL_ATTRIB_POS, x, y, z );
197 }
198
199 static void GLAPIENTRY _tnl_Vertex3fv( const GLfloat *v )
200 {
201 DISPATCH_ATTR3FV( _TNL_ATTRIB_POS, v );
202 }
203
204 static void GLAPIENTRY _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z,
205 GLfloat w )
206 {
207 DISPATCH_ATTR4F( _TNL_ATTRIB_POS, x, y, z, w );
208 }
209
210 static void GLAPIENTRY _tnl_Vertex4fv( const GLfloat *v )
211 {
212 DISPATCH_ATTR4FV( _TNL_ATTRIB_POS, v );
213 }
214
215 static void GLAPIENTRY _tnl_TexCoord1f( GLfloat x )
216 {
217 DISPATCH_ATTR1F( _TNL_ATTRIB_TEX0, x );
218 }
219
220 static void GLAPIENTRY _tnl_TexCoord1fv( const GLfloat *v )
221 {
222 DISPATCH_ATTR1FV( _TNL_ATTRIB_TEX0, v );
223 }
224
225 static void GLAPIENTRY _tnl_TexCoord2f( GLfloat x, GLfloat y )
226 {
227 DISPATCH_ATTR2F( _TNL_ATTRIB_TEX0, x, y );
228 }
229
230 static void GLAPIENTRY _tnl_TexCoord2fv( const GLfloat *v )
231 {
232 DISPATCH_ATTR2FV( _TNL_ATTRIB_TEX0, v );
233 }
234
235 static void GLAPIENTRY _tnl_TexCoord3f( GLfloat x, GLfloat y, GLfloat z )
236 {
237 DISPATCH_ATTR3F( _TNL_ATTRIB_TEX0, x, y, z );
238 }
239
240 static void GLAPIENTRY _tnl_TexCoord3fv( const GLfloat *v )
241 {
242 DISPATCH_ATTR3FV( _TNL_ATTRIB_TEX0, v );
243 }
244
245 static void GLAPIENTRY _tnl_TexCoord4f( GLfloat x, GLfloat y, GLfloat z,
246 GLfloat w )
247 {
248 DISPATCH_ATTR4F( _TNL_ATTRIB_TEX0, x, y, z, w );
249 }
250
251 static void GLAPIENTRY _tnl_TexCoord4fv( const GLfloat *v )
252 {
253 DISPATCH_ATTR4FV( _TNL_ATTRIB_TEX0, v );
254 }
255
256 static void GLAPIENTRY _tnl_Normal3f( GLfloat x, GLfloat y, GLfloat z )
257 {
258 DISPATCH_ATTR3F( _TNL_ATTRIB_NORMAL, x, y, z );
259 }
260
261 static void GLAPIENTRY _tnl_Normal3fv( const GLfloat *v )
262 {
263 DISPATCH_ATTR3FV( _TNL_ATTRIB_NORMAL, v );
264 }
265
266 static void GLAPIENTRY _tnl_FogCoordfEXT( GLfloat x )
267 {
268 DISPATCH_ATTR1F( _TNL_ATTRIB_FOG, x );
269 }
270
271 static void GLAPIENTRY _tnl_FogCoordfvEXT( const GLfloat *v )
272 {
273 DISPATCH_ATTR1FV( _TNL_ATTRIB_FOG, v );
274 }
275
276 static void GLAPIENTRY _tnl_Color3f( GLfloat x, GLfloat y, GLfloat z )
277 {
278 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR0, x, y, z );
279 }
280
281 static void GLAPIENTRY _tnl_Color3fv( const GLfloat *v )
282 {
283 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR0, v );
284 }
285
286 static void GLAPIENTRY _tnl_Color4f( GLfloat x, GLfloat y, GLfloat z,
287 GLfloat w )
288 {
289 DISPATCH_ATTR4F( _TNL_ATTRIB_COLOR0, x, y, z, w );
290 }
291
292 static void GLAPIENTRY _tnl_Color4fv( const GLfloat *v )
293 {
294 DISPATCH_ATTR4FV( _TNL_ATTRIB_COLOR0, v );
295 }
296
297 static void GLAPIENTRY _tnl_SecondaryColor3fEXT( GLfloat x, GLfloat y,
298 GLfloat z )
299 {
300 DISPATCH_ATTR3F( _TNL_ATTRIB_COLOR1, x, y, z );
301 }
302
303 static void GLAPIENTRY _tnl_SecondaryColor3fvEXT( const GLfloat *v )
304 {
305 DISPATCH_ATTR3FV( _TNL_ATTRIB_COLOR1, v );
306 }
307
308 static void GLAPIENTRY _tnl_MultiTexCoord1f( GLenum target, GLfloat x )
309 {
310 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
311 DISPATCH_ATTR1F( attr, x );
312 }
313
314 static void GLAPIENTRY _tnl_MultiTexCoord1fv( GLenum target,
315 const GLfloat *v )
316 {
317 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
318 DISPATCH_ATTR1FV( attr, v );
319 }
320
321 static void GLAPIENTRY _tnl_MultiTexCoord2f( GLenum target, GLfloat x,
322 GLfloat y )
323 {
324 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
325 DISPATCH_ATTR2F( attr, x, y );
326 }
327
328 static void GLAPIENTRY _tnl_MultiTexCoord2fv( GLenum target,
329 const GLfloat *v )
330 {
331 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
332 DISPATCH_ATTR2FV( attr, v );
333 }
334
335 static void GLAPIENTRY _tnl_MultiTexCoord3f( GLenum target, GLfloat x,
336 GLfloat y, GLfloat z)
337 {
338 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
339 DISPATCH_ATTR3F( attr, x, y, z );
340 }
341
342 static void GLAPIENTRY _tnl_MultiTexCoord3fv( GLenum target,
343 const GLfloat *v )
344 {
345 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
346 DISPATCH_ATTR3FV( attr, v );
347 }
348
349 static void GLAPIENTRY _tnl_MultiTexCoord4f( GLenum target, GLfloat x,
350 GLfloat y, GLfloat z,
351 GLfloat w )
352 {
353 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
354 DISPATCH_ATTR4F( attr, x, y, z, w );
355 }
356
357 static void GLAPIENTRY _tnl_MultiTexCoord4fv( GLenum target,
358 const GLfloat *v )
359 {
360 GLuint attr = (target & 0x7) + _TNL_ATTRIB_TEX0;
361 DISPATCH_ATTR4FV( attr, v );
362 }
363
364 static void GLAPIENTRY _tnl_VertexAttrib1fNV( GLuint index, GLfloat x )
365 {
366 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
367 DISPATCH_ATTR1F( index, x );
368 }
369
370 static void GLAPIENTRY _tnl_VertexAttrib1fvNV( GLuint index,
371 const GLfloat *v )
372 {
373 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
374 DISPATCH_ATTR1FV( index, v );
375 }
376
377 static void GLAPIENTRY _tnl_VertexAttrib2fNV( GLuint index, GLfloat x,
378 GLfloat y )
379 {
380 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
381 DISPATCH_ATTR2F( index, x, y );
382 }
383
384 static void GLAPIENTRY _tnl_VertexAttrib2fvNV( GLuint index,
385 const GLfloat *v )
386 {
387 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
388 DISPATCH_ATTR2FV( index, v );
389 }
390
391 static void GLAPIENTRY _tnl_VertexAttrib3fNV( GLuint index, GLfloat x,
392 GLfloat y, GLfloat z )
393 {
394 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
395 DISPATCH_ATTR3F( index, x, y, z );
396 }
397
398 static void GLAPIENTRY _tnl_VertexAttrib3fvNV( GLuint index,
399 const GLfloat *v )
400 {
401 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
402 DISPATCH_ATTR3FV( index, v );
403 }
404
405 static void GLAPIENTRY _tnl_VertexAttrib4fNV( GLuint index, GLfloat x,
406 GLfloat y, GLfloat z,
407 GLfloat w )
408 {
409 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
410 DISPATCH_ATTR4F( index, x, y, z, w );
411 }
412
413 static void GLAPIENTRY _tnl_VertexAttrib4fvNV( GLuint index,
414 const GLfloat *v )
415 {
416 if (index >= VERT_ATTRIB_MAX) index = ERROR_ATTRIB;
417 DISPATCH_ATTR4FV( index, v );
418 }
419
420
421 /* Install the generic versions of the 2nd level dispatch
422 * functions. Some of these have a codegen alternative.
423 */
424 void _tnl_generic_exec_vtxfmt_init( GLcontext *ctx )
425 {
426 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->exec_vtxfmt);
427
428 vfmt->Color3f = _tnl_Color3f;
429 vfmt->Color3fv = _tnl_Color3fv;
430 vfmt->Color4f = _tnl_Color4f;
431 vfmt->Color4fv = _tnl_Color4fv;
432 vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
433 vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
434 vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1f;
435 vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fv;
436 vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2f;
437 vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fv;
438 vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3f;
439 vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fv;
440 vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4f;
441 vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fv;
442 vfmt->Normal3f = _tnl_Normal3f;
443 vfmt->Normal3fv = _tnl_Normal3fv;
444 vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
445 vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
446 vfmt->TexCoord1f = _tnl_TexCoord1f;
447 vfmt->TexCoord1fv = _tnl_TexCoord1fv;
448 vfmt->TexCoord2f = _tnl_TexCoord2f;
449 vfmt->TexCoord2fv = _tnl_TexCoord2fv;
450 vfmt->TexCoord3f = _tnl_TexCoord3f;
451 vfmt->TexCoord3fv = _tnl_TexCoord3fv;
452 vfmt->TexCoord4f = _tnl_TexCoord4f;
453 vfmt->TexCoord4fv = _tnl_TexCoord4fv;
454 vfmt->Vertex2f = _tnl_Vertex2f;
455 vfmt->Vertex2fv = _tnl_Vertex2fv;
456 vfmt->Vertex3f = _tnl_Vertex3f;
457 vfmt->Vertex3fv = _tnl_Vertex3fv;
458 vfmt->Vertex4f = _tnl_Vertex4f;
459 vfmt->Vertex4fv = _tnl_Vertex4fv;
460 vfmt->VertexAttrib1fNV = _tnl_VertexAttrib1fNV;
461 vfmt->VertexAttrib1fvNV = _tnl_VertexAttrib1fvNV;
462 vfmt->VertexAttrib2fNV = _tnl_VertexAttrib2fNV;
463 vfmt->VertexAttrib2fvNV = _tnl_VertexAttrib2fvNV;
464 vfmt->VertexAttrib3fNV = _tnl_VertexAttrib3fNV;
465 vfmt->VertexAttrib3fvNV = _tnl_VertexAttrib3fvNV;
466 vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
467 vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
468 }