2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 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"
37 #include "t_array_import.h"
38 #include "t_context.h"
42 * XXX writable and stride are always false in these functions...
44 static void _tnl_import_vertex( GLcontext
*ctx
,
48 struct gl_client_array
*tmp
;
49 GLboolean is_writable
= 0;
50 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
53 tmp
= _ac_import_vertex(ctx
,
55 stride
? 4*sizeof(GLfloat
) : 0,
61 inputs
->Obj
.data
= (GLfloat (*)[4]) data
;
62 inputs
->Obj
.start
= (GLfloat
*) data
;
63 inputs
->Obj
.stride
= tmp
->StrideB
;
64 inputs
->Obj
.size
= tmp
->Size
;
67 static void _tnl_import_normal( GLcontext
*ctx
,
71 struct gl_client_array
*tmp
;
72 GLboolean is_writable
= 0;
73 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
76 tmp
= _ac_import_normal(ctx
, GL_FLOAT
,
77 stride
? 3*sizeof(GLfloat
) : 0, writable
,
81 inputs
->Normal
.data
= (GLfloat (*)[4]) data
;
82 inputs
->Normal
.start
= (GLfloat
*) data
;
83 inputs
->Normal
.stride
= tmp
->StrideB
;
84 inputs
->Normal
.size
= 3;
88 static void _tnl_import_color( GLcontext
*ctx
,
92 struct gl_client_array
*tmp
;
93 GLboolean is_writable
= 0;
94 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
97 tmp
= _ac_import_color(ctx
,
99 stride
? 4*sizeof(GLfloat
) : 0,
105 inputs
->Color
.data
= (GLfloat (*)[4]) data
;
106 inputs
->Color
.start
= (GLfloat
*) data
;
107 inputs
->Color
.stride
= tmp
->StrideB
;
108 inputs
->Color
.size
= tmp
->Size
;
112 static void _tnl_import_secondarycolor( GLcontext
*ctx
,
116 struct gl_client_array
*tmp
;
117 GLboolean is_writable
= 0;
118 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
121 tmp
= _ac_import_secondarycolor(ctx
,
123 stride
? 4*sizeof(GLfloat
) : 0,
129 inputs
->SecondaryColor
.data
= (GLfloat (*)[4]) data
;
130 inputs
->SecondaryColor
.start
= (GLfloat
*) data
;
131 inputs
->SecondaryColor
.stride
= tmp
->StrideB
;
132 inputs
->SecondaryColor
.size
= tmp
->Size
;
135 static void _tnl_import_fogcoord( GLcontext
*ctx
,
139 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
140 struct gl_client_array
*tmp
;
141 GLboolean is_writable
= 0;
144 tmp
= _ac_import_fogcoord(ctx
, GL_FLOAT
,
145 stride
? sizeof(GLfloat
) : 0, writable
,
149 inputs
->FogCoord
.data
= (GLfloat (*)[4]) data
;
150 inputs
->FogCoord
.start
= (GLfloat
*) data
;
151 inputs
->FogCoord
.stride
= tmp
->StrideB
;
154 static void _tnl_import_index( GLcontext
*ctx
,
158 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
159 struct gl_client_array
*tmp
;
160 GLboolean is_writable
= 0;
163 tmp
= _ac_import_index(ctx
, GL_FLOAT
,
164 stride
? sizeof(GLfloat
) : 0, writable
,
168 inputs
->Index
.data
= (GLfloat (*)[4]) data
;
169 inputs
->Index
.start
= (GLfloat
*) data
;
170 inputs
->Index
.stride
= tmp
->StrideB
;
174 static void _tnl_import_texcoord( GLcontext
*ctx
,
179 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
180 struct gl_client_array
*tmp
;
181 GLboolean is_writable
= 0;
184 tmp
= _ac_import_texcoord(ctx
, unit
, GL_FLOAT
,
185 stride
? 4 * sizeof(GLfloat
) : 0,
191 inputs
->TexCoord
[unit
].data
= (GLfloat (*)[4]) data
;
192 inputs
->TexCoord
[unit
].start
= (GLfloat
*) data
;
193 inputs
->TexCoord
[unit
].stride
= tmp
->StrideB
;
194 inputs
->TexCoord
[unit
].size
= tmp
->Size
;
198 static void _tnl_import_edgeflag( GLcontext
*ctx
,
202 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
203 struct gl_client_array
*tmp
;
204 GLboolean is_writable
= 0;
206 (void) writable
; (void) stride
;
208 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
214 inputs
->EdgeFlag
= (GLubyte
*) data
;
219 static void _tnl_import_attrib( GLcontext
*ctx
,
224 struct tnl_vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
225 struct gl_client_array
*tmp
;
226 GLboolean is_writable
= 0;
229 ASSERT(index
< MAX_VERTEX_PROGRAM_ATTRIBS
);
231 tmp
= _ac_import_attrib(ctx
, index
, GL_FLOAT
,
232 stride
? 4 * sizeof(GLfloat
) : 0,
233 4, /* want GLfloat[4] */
238 inputs
->Attribs
[index
].data
= (GLfloat (*)[4]) data
;
239 inputs
->Attribs
[index
].start
= (GLfloat
*) data
;
240 inputs
->Attribs
[index
].stride
= tmp
->StrideB
;
241 inputs
->Attribs
[index
].size
= tmp
->Size
;
245 static void _tnl_constant_attrib( TNLcontext
*tnl
,
246 struct tnl_vertex_arrays
*tmp
,
249 tmp
->Attribs
[i
].count
= 1;
250 tmp
->Attribs
[i
].data
= (GLfloat (*)[4]) tnl
->vtx
.current
[i
];
251 tmp
->Attribs
[i
].start
= tnl
->vtx
.current
[i
];
252 tmp
->Attribs
[i
].size
= 4;
253 tmp
->Attribs
[i
].stride
= 0;
254 tnl
->vb
.AttribPtr
[i
] = &tmp
->Attribs
[i
];
259 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLint end
)
261 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
262 struct vertex_buffer
*VB
= &tnl
->vb
;
263 struct tnl_vertex_arrays
*tmp
= &tnl
->array_inputs
;
264 const struct gl_vertex_program
*program
265 = ctx
->VertexProgram
._Enabled
? ctx
->VertexProgram
.Current
: NULL
;
268 VB
->Count
= end
- start
;
271 _ac_import_range( ctx
, start
, end
);
273 /* Note that the generic attribute arrays are treated differently
274 * depending on whether an NV or ARB vertex program is enabled
275 * (corresponding to aliasing vs. non-aliasing behaviour).
276 * Generic array 0 always aliases vertex position.
278 for (index
= 0; index
< VERT_ATTRIB_MAX
; index
++) {
279 if (ctx
->VertexProgram
._Enabled
280 && (program
->IsNVProgram
|| index
== 0)
281 && ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
) {
282 /* Use generic attribute array. If an NV vertex program is active,
283 * the generic arrays override the conventional attributes.
284 * Otherwise, if an ARB vertex program is active, we'll import the
285 * generic attributes without aliasing over conventional attribs
288 _tnl_import_attrib( ctx
, index
, GL_FALSE
, GL_TRUE
);
289 VB
->AttribPtr
[index
] = &tmp
->Attribs
[index
];
291 /* use conventional arrays... */
292 else if (index
== VERT_ATTRIB_POS
) {
293 _tnl_import_vertex( ctx
, GL_FALSE
, GL_FALSE
);
294 tmp
->Obj
.count
= VB
->Count
;
295 VB
->AttribPtr
[_TNL_ATTRIB_POS
] = &tmp
->Obj
;
297 else if (index
== VERT_ATTRIB_NORMAL
) {
298 _tnl_import_normal( ctx
, GL_FALSE
, GL_FALSE
);
299 tmp
->Normal
.count
= VB
->Count
;
300 VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
] = &tmp
->Normal
;
302 else if (index
== VERT_ATTRIB_COLOR0
) {
303 _tnl_import_color( ctx
, GL_FALSE
, GL_FALSE
);
304 tmp
->Color
.count
= VB
->Count
;
305 VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
] = &tmp
->Color
;
307 else if (index
== VERT_ATTRIB_COLOR1
) {
308 _tnl_import_secondarycolor( ctx
, GL_FALSE
, GL_FALSE
);
309 tmp
->SecondaryColor
.count
= VB
->Count
;
310 VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
] = &tmp
->SecondaryColor
;
312 else if (index
== VERT_ATTRIB_FOG
) {
313 _tnl_import_fogcoord( ctx
, GL_FALSE
, GL_FALSE
);
314 tmp
->FogCoord
.count
= VB
->Count
;
315 VB
->AttribPtr
[_TNL_ATTRIB_FOG
] = &tmp
->FogCoord
;
317 else if (index
== VERT_ATTRIB_COLOR_INDEX
) {
318 _tnl_import_index( ctx
, GL_FALSE
, GL_FALSE
);
319 tmp
->Index
.count
= VB
->Count
;
320 VB
->AttribPtr
[_TNL_ATTRIB_COLOR_INDEX
] = &tmp
->Index
;
322 else if (index
>= VERT_ATTRIB_TEX0
&& index
<= VERT_ATTRIB_TEX7
) {
323 i
= index
- VERT_ATTRIB_TEX0
;
324 _tnl_import_texcoord( ctx
, i
, GL_FALSE
, GL_FALSE
);
325 tmp
->TexCoord
[i
].count
= VB
->Count
;
326 VB
->AttribPtr
[index
] = &tmp
->TexCoord
[i
];
328 else if (index
>= VERT_ATTRIB_GENERIC1
&&
329 index
<= VERT_ATTRIB_GENERIC15
) {
330 const GLuint arrayIndex
= index
- VERT_ATTRIB_GENERIC0
;
331 if (program
&& !program
->IsNVProgram
&&
332 ctx
->Array
.ArrayObj
->VertexAttrib
[arrayIndex
].Enabled
) {
333 /* GL_ARB_vertex_program: bind a generic attribute array */
334 _tnl_import_attrib(ctx
, arrayIndex
, GL_FALSE
, GL_TRUE
);
335 VB
->AttribPtr
[index
] = &tmp
->Attribs
[arrayIndex
];
338 _tnl_constant_attrib(tnl
, tmp
, index
);
342 _tnl_constant_attrib(tnl
, tmp
, index
);
344 assert(VB
->AttribPtr
[index
]);
345 assert(VB
->AttribPtr
[index
]->size
);
348 /* odd-ball vertex attributes */
350 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
351 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
;
354 /* These are constant & could be precalculated:
356 for (i
= _TNL_FIRST_MAT
; i
<= _TNL_LAST_MAT
; i
++) {
357 _tnl_constant_attrib(tnl
, tmp
, i
);
361 /* Legacy pointers -- remove one day.
363 VB
->ObjPtr
= VB
->AttribPtr
[_TNL_ATTRIB_POS
];
364 VB
->NormalPtr
= VB
->AttribPtr
[_TNL_ATTRIB_NORMAL
];
365 VB
->ColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR0
];
366 VB
->ColorPtr
[1] = NULL
;
367 VB
->IndexPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR_INDEX
];
368 VB
->IndexPtr
[1] = NULL
;
369 VB
->SecondaryColorPtr
[0] = VB
->AttribPtr
[_TNL_ATTRIB_COLOR1
];
370 VB
->SecondaryColorPtr
[1] = NULL
;
371 VB
->FogCoordPtr
= VB
->AttribPtr
[_TNL_ATTRIB_FOG
];
373 for (i
= 0; i
< ctx
->Const
.MaxTextureCoordUnits
; i
++) {
374 VB
->TexCoordPtr
[i
] = VB
->AttribPtr
[_TNL_ATTRIB_TEX0
+ i
];