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;
205 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
211 inputs
->EdgeFlag
= (GLubyte
*) data
;
216 static void _tnl_import_attrib( GLcontext
*ctx
,
221 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
222 struct gl_client_array
*tmp
;
223 GLboolean is_writeable
= 0;
226 tmp
= _ac_import_attrib(ctx
, index
, GL_FLOAT
,
227 stride
? 4 * sizeof(GLfloat
) : 0,
228 4, /* want GLfloat[4] */
233 inputs
->Attribs
[index
].data
= (GLfloat (*)[4]) data
;
234 inputs
->Attribs
[index
].start
= (GLfloat
*) data
;
235 inputs
->Attribs
[index
].stride
= tmp
->StrideB
;
236 inputs
->Attribs
[index
].size
= tmp
->Size
;
242 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLint end
)
244 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
245 struct vertex_buffer
*VB
= &tnl
->vb
;
246 GLuint inputs
= tnl
->pipeline
.inputs
;
247 struct tnl_vertex_arrays
*tmp
= &tnl
->array_inputs
;
250 VB
->Count
= end
- start
;
253 _ac_import_range( ctx
, start
, end
);
255 /* When vertex program mode is enabled, the generic vertex program
256 * attribute arrays have priority over the conventional attributes.
257 * Try to use them now.
259 for (index
= 0; index
< VERT_ATTRIB_MAX
; index
++) {
260 /* When vertex program mode is enabled, the generic vertex attribute
261 * arrays have priority over the conventional vertex arrays.
263 if (ctx
->VertexProgram
.Enabled
264 && ctx
->Array
.VertexAttrib
[index
].Enabled
) {
265 /* Use generic attribute array */
266 _tnl_import_attrib( ctx
, index
, GL_FALSE
, GL_TRUE
);
267 VB
->AttribPtr
[index
] = &tmp
->Attribs
[index
];
269 /* use conventional arrays... */
270 else if (index
== VERT_ATTRIB_POS
) {
271 if (inputs
& _TNL_BIT_POS
) {
272 _tnl_import_vertex( ctx
, 0, 0 );
273 tmp
->Obj
.count
= VB
->Count
;
274 VB
->AttribPtr
[_TNL_ATTRIB_POS
] = &tmp
->Obj
;
277 else if (index
== VERT_ATTRIB_NORMAL
) {
278 if (inputs
& _TNL_BIT_NORMAL
) {
279 _tnl_import_normal( ctx
, 0, 0 );
280 tmp
->Normal
.count
= VB
->Count
;
281 VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
] = &tmp
->Normal
;
284 else if (index
== VERT_ATTRIB_COLOR0
) {
285 if (inputs
& _TNL_BIT_COLOR0
) {
286 _tnl_import_color( ctx
, 0, 0 );
287 tmp
->Color
.count
= VB
->Count
;
288 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
] = &tmp
->Color
;
291 else if (index
== VERT_ATTRIB_COLOR1
) {
292 if (inputs
& _TNL_BIT_COLOR1
) {
293 _tnl_import_secondarycolor( ctx
, 0, 0 );
294 tmp
->SecondaryColor
.count
= VB
->Count
;
295 VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
] = &tmp
->SecondaryColor
;
298 else if (index
== VERT_ATTRIB_FOG
) {
299 if (inputs
& _TNL_BIT_FOG
) {
300 _tnl_import_fogcoord( ctx
, 0, 0 );
301 tmp
->FogCoord
.count
= VB
->Count
;
302 VB
->AttribPtr
[_TNL_ATTRIB_FOG
] = &tmp
->FogCoord
;
305 else if (index
>= VERT_ATTRIB_TEX0
&& index
<= VERT_ATTRIB_TEX7
) {
306 if (inputs
& _TNL_BITS_TEX_ANY
) {
307 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
308 if (inputs
& _TNL_BIT_TEX(i
)) {
309 _tnl_import_texcoord( ctx
, i
, GL_FALSE
, GL_FALSE
);
310 tmp
->TexCoord
[i
].count
= VB
->Count
;
311 VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
] = &tmp
->TexCoord
[i
];
318 /* odd-ball vertex attributes */
319 if (inputs
& _TNL_BIT_INDEX
) {
320 _tnl_import_index( ctx
, 0, 0 );
321 tmp
->Index
.count
= VB
->Count
;
322 VB
->AttribPtr
[_TNL_ATTRIB_INDEX
] = &tmp
->Index
;
325 if (inputs
& _TNL_BIT_EDGEFLAG
) {
326 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
327 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
;
330 /* These are constant & can be precalculated:
332 if (inputs
& _TNL_BITS_MAT_ANY
) {
333 for (i
= _TNL_ATTRIB_MAT_FRONT_AMBIENT
; i
< _TNL_ATTRIB_INDEX
; i
++) {
334 tmp
->Attribs
[i
].count
= VB
->Count
;
335 tmp
->Attribs
[i
].data
= (GLfloat (*)[4]) tnl
->vtx
.current
[i
];
336 tmp
->Attribs
[i
].start
= tnl
->vtx
.current
[i
];
337 tmp
->Attribs
[i
].size
= 4;
338 tmp
->Attribs
[i
].stride
= 0;
339 VB
->AttribPtr
[i
] = &tmp
->Attribs
[i
];
344 /* Legacy pointers -- remove one day.
346 VB
->ObjPtr
= VB
->AttribPtr
[_TNL_ATTRIB_POS
];
347 VB
->NormalPtr
= VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
];
348 VB
->ColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
];
350 VB
->IndexPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_INDEX
];
352 VB
->SecondaryColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
];
353 VB
->SecondaryColorPtr
[1] = 0;
354 VB
->FogCoordPtr
= VB
->AttribPtr
[_TNL_ATTRIB_FOG
];
356 for (i
= 0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++) {
357 VB
->TexCoordPtr
[i
] = VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
];