2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 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>
35 #include "array_cache/acache.h"
36 #include "math/m_translate.h"
38 #include "t_array_import.h"
39 #include "t_context.h"
42 static void _tnl_import_vertex( GLcontext
*ctx
,
46 struct gl_client_array
*tmp
;
47 GLboolean is_writeable
= 0;
48 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
51 tmp
= _ac_import_vertex(ctx
,
53 stride
? 4*sizeof(GLfloat
) : 0,
59 inputs
->Obj
.data
= (GLfloat (*)[4]) data
;
60 inputs
->Obj
.start
= (GLfloat
*) data
;
61 inputs
->Obj
.stride
= tmp
->StrideB
;
62 inputs
->Obj
.size
= tmp
->Size
;
65 static void _tnl_import_normal( GLcontext
*ctx
,
69 struct gl_client_array
*tmp
;
70 GLboolean is_writeable
= 0;
71 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
74 tmp
= _ac_import_normal(ctx
, GL_FLOAT
,
75 stride
? 3*sizeof(GLfloat
) : 0, writeable
,
79 inputs
->Normal
.data
= (GLfloat (*)[4]) data
;
80 inputs
->Normal
.start
= (GLfloat
*) data
;
81 inputs
->Normal
.stride
= tmp
->StrideB
;
82 inputs
->Normal
.size
= 3;
86 static void _tnl_import_color( GLcontext
*ctx
,
90 struct gl_client_array
*tmp
;
91 GLboolean is_writeable
= 0;
92 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
95 tmp
= _ac_import_color(ctx
,
97 stride
? 4*sizeof(GLfloat
) : 0,
103 inputs
->Color
.data
= (GLfloat (*)[4]) data
;
104 inputs
->Color
.start
= (GLfloat
*) data
;
105 inputs
->Color
.stride
= tmp
->StrideB
;
106 inputs
->Color
.size
= tmp
->Size
;
110 static void _tnl_import_secondarycolor( GLcontext
*ctx
,
114 struct gl_client_array
*tmp
;
115 GLboolean is_writeable
= 0;
116 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
119 tmp
= _ac_import_secondarycolor(ctx
,
121 stride
? 4*sizeof(GLfloat
) : 0,
127 inputs
->SecondaryColor
.data
= (GLfloat (*)[4]) data
;
128 inputs
->SecondaryColor
.start
= (GLfloat
*) data
;
129 inputs
->SecondaryColor
.stride
= tmp
->StrideB
;
130 inputs
->SecondaryColor
.size
= tmp
->Size
;
133 static void _tnl_import_fogcoord( GLcontext
*ctx
,
137 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
138 struct gl_client_array
*tmp
;
139 GLboolean is_writeable
= 0;
142 tmp
= _ac_import_fogcoord(ctx
, GL_FLOAT
,
143 stride
? sizeof(GLfloat
) : 0, writeable
,
147 inputs
->FogCoord
.data
= (GLfloat (*)[4]) data
;
148 inputs
->FogCoord
.start
= (GLfloat
*) data
;
149 inputs
->FogCoord
.stride
= tmp
->StrideB
;
152 static void _tnl_import_index( GLcontext
*ctx
,
156 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
157 struct gl_client_array
*tmp
;
158 GLboolean is_writeable
= 0;
161 tmp
= _ac_import_index(ctx
, GL_FLOAT
,
162 stride
? sizeof(GLfloat
) : 0, writeable
,
166 inputs
->Index
.data
= (GLfloat (*)[4]) data
;
167 inputs
->Index
.start
= (GLfloat
*) data
;
168 inputs
->Index
.stride
= tmp
->StrideB
;
172 static void _tnl_import_texcoord( GLcontext
*ctx
,
177 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
178 struct gl_client_array
*tmp
;
179 GLboolean is_writeable
= 0;
182 tmp
= _ac_import_texcoord(ctx
, unit
, GL_FLOAT
,
183 stride
? 4 * sizeof(GLfloat
) : 0,
189 inputs
->TexCoord
[unit
].data
= (GLfloat (*)[4]) data
;
190 inputs
->TexCoord
[unit
].start
= (GLfloat
*) data
;
191 inputs
->TexCoord
[unit
].stride
= tmp
->StrideB
;
192 inputs
->TexCoord
[unit
].size
= tmp
->Size
;
196 static void _tnl_import_edgeflag( GLcontext
*ctx
,
200 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
201 struct gl_client_array
*tmp
;
202 GLboolean is_writeable
= 0;
204 (void) writeable
; (void) stride
;
206 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
212 inputs
->EdgeFlag
= (GLubyte
*) data
;
217 static void _tnl_import_attrib( GLcontext
*ctx
,
222 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
223 struct gl_client_array
*tmp
;
224 GLboolean is_writeable
= 0;
227 tmp
= _ac_import_attrib(ctx
, index
, GL_FLOAT
,
228 stride
? 4 * sizeof(GLfloat
) : 0,
229 4, /* want GLfloat[4] */
234 inputs
->Attribs
[index
].data
= (GLfloat (*)[4]) data
;
235 inputs
->Attribs
[index
].start
= (GLfloat
*) data
;
236 inputs
->Attribs
[index
].stride
= tmp
->StrideB
;
237 inputs
->Attribs
[index
].size
= tmp
->Size
;
243 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLint end
)
245 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
246 struct vertex_buffer
*VB
= &tnl
->vb
;
247 GLuint inputs
= tnl
->pipeline
.inputs
;
248 struct tnl_vertex_arrays
*tmp
= &tnl
->array_inputs
;
251 VB
->Count
= end
- start
;
254 _ac_import_range( ctx
, start
, end
);
256 /* When vertex program mode is enabled, the generic vertex program
257 * attribute arrays have priority over the conventional attributes.
258 * Try to use them now.
260 for (index
= 0; index
< VERT_ATTRIB_MAX
; index
++) {
261 /* When vertex program mode is enabled, the generic vertex attribute
262 * arrays have priority over the conventional vertex arrays.
264 if (ctx
->VertexProgram
._Enabled
265 && ctx
->Array
.VertexAttrib
[index
].Enabled
) {
266 /* Use generic attribute array */
267 _tnl_import_attrib( ctx
, index
, GL_FALSE
, GL_TRUE
);
268 VB
->AttribPtr
[index
] = &tmp
->Attribs
[index
];
270 /* use conventional arrays... */
271 else if (index
== VERT_ATTRIB_POS
) {
272 if (inputs
& _TNL_BIT_POS
) {
273 _tnl_import_vertex( ctx
, 0, 0 );
274 tmp
->Obj
.count
= VB
->Count
;
275 VB
->AttribPtr
[_TNL_ATTRIB_POS
] = &tmp
->Obj
;
278 else if (index
== VERT_ATTRIB_NORMAL
) {
279 if (inputs
& _TNL_BIT_NORMAL
) {
280 _tnl_import_normal( ctx
, 0, 0 );
281 tmp
->Normal
.count
= VB
->Count
;
282 VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
] = &tmp
->Normal
;
285 else if (index
== VERT_ATTRIB_COLOR0
) {
286 if (inputs
& _TNL_BIT_COLOR0
) {
287 _tnl_import_color( ctx
, 0, 0 );
288 tmp
->Color
.count
= VB
->Count
;
289 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
] = &tmp
->Color
;
292 else if (index
== VERT_ATTRIB_COLOR1
) {
293 if (inputs
& _TNL_BIT_COLOR1
) {
294 _tnl_import_secondarycolor( ctx
, 0, 0 );
295 tmp
->SecondaryColor
.count
= VB
->Count
;
296 VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
] = &tmp
->SecondaryColor
;
299 else if (index
== VERT_ATTRIB_FOG
) {
300 if (inputs
& _TNL_BIT_FOG
) {
301 _tnl_import_fogcoord( ctx
, 0, 0 );
302 tmp
->FogCoord
.count
= VB
->Count
;
303 VB
->AttribPtr
[_TNL_ATTRIB_FOG
] = &tmp
->FogCoord
;
306 else if (index
>= VERT_ATTRIB_TEX0
&& index
<= VERT_ATTRIB_TEX7
) {
307 if (inputs
& _TNL_BITS_TEX_ANY
) {
308 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
309 if (inputs
& _TNL_BIT_TEX(i
)) {
310 _tnl_import_texcoord( ctx
, i
, GL_FALSE
, GL_FALSE
);
311 tmp
->TexCoord
[i
].count
= VB
->Count
;
312 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
] = &tmp
->TexCoord
[i
];
319 /* odd-ball vertex attributes */
320 if (inputs
& _TNL_BIT_INDEX
) {
321 _tnl_import_index( ctx
, 0, 0 );
322 tmp
->Index
.count
= VB
->Count
;
323 VB
->AttribPtr
[_TNL_ATTRIB_INDEX
] = &tmp
->Index
;
326 if (inputs
& _TNL_BIT_EDGEFLAG
) {
327 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
328 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
;
331 /* These are constant & can be precalculated:
333 if (inputs
& _TNL_BITS_MAT_ANY
) {
334 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
; i
< _TNL_ATTRIB_INDEX
; i
++) {
335 tmp
->Attribs
[i
].count
= VB
->Count
;
336 tmp
->Attribs
[i
].data
= (GLfloat (*)[4]) tnl
->vtx
.current
[i
];
337 tmp
->Attribs
[i
].start
= tnl
->vtx
.current
[i
];
338 tmp
->Attribs
[i
].size
= 4;
339 tmp
->Attribs
[i
].stride
= 0;
340 VB
->AttribPtr
[i
] = &tmp
->Attribs
[i
];
345 /* Legacy pointers -- remove one day.
347 VB
->ObjPtr
= VB
->AttribPtr
[_TNL_ATTRIB_POS
];
348 VB
->NormalPtr
= VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
];
349 VB
->ColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
];
351 VB
->IndexPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_INDEX
];
353 VB
->SecondaryColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
];
354 VB
->SecondaryColorPtr
[1] = 0;
355 VB
->FogCoordPtr
= VB
->AttribPtr
[_TNL_ATTRIB_FOG
];
357 for (i
= 0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++) {
358 VB
->TexCoordPtr
[i
] = VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
];