2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 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"
40 #include "t_imm_debug.h"
43 static void _tnl_import_vertex( GLcontext
*ctx
,
47 struct gl_client_array
*tmp
;
48 GLboolean is_writeable
= 0;
49 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
52 tmp
= _ac_import_vertex(ctx
,
54 stride
? 4*sizeof(GLfloat
) : 0,
60 /* guess we really don't need to add pointers here - BP */
61 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
65 inputs
->Obj
.data
= (GLfloat (*)[4]) data
;
66 inputs
->Obj
.start
= (GLfloat
*) data
;
67 inputs
->Obj
.stride
= tmp
->StrideB
;
68 inputs
->Obj
.size
= tmp
->Size
;
69 inputs
->Obj
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
70 if (inputs
->Obj
.stride
!= 4*sizeof(GLfloat
))
71 inputs
->Obj
.flags
|= VEC_BAD_STRIDE
;
73 inputs
->Obj
.flags
|= VEC_NOT_WRITEABLE
;
76 static void _tnl_import_normal( GLcontext
*ctx
,
80 struct gl_client_array
*tmp
;
81 GLboolean is_writeable
= 0;
82 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
85 tmp
= _ac_import_normal(ctx
, GL_FLOAT
,
86 stride
? 3*sizeof(GLfloat
) : 0, writeable
,
90 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
94 inputs
->Normal
.data
= (GLfloat (*)[4]) data
;
95 inputs
->Normal
.start
= (GLfloat
*) data
;
96 inputs
->Normal
.stride
= tmp
->StrideB
;
97 inputs
->Normal
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
98 if (inputs
->Normal
.stride
!= 3*sizeof(GLfloat
))
99 inputs
->Normal
.flags
|= VEC_BAD_STRIDE
;
101 inputs
->Normal
.flags
|= VEC_NOT_WRITEABLE
;
105 static void _tnl_import_color( GLcontext
*ctx
,
110 struct gl_client_array
*tmp
;
111 GLboolean is_writeable
= 0;
112 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
114 tmp
= _ac_import_color(ctx
,
116 stride
? 4*sizeof(GLfloat
) : 0,
121 inputs
->Color
= *tmp
;
125 static void _tnl_import_secondarycolor( GLcontext
*ctx
,
130 struct gl_client_array
*tmp
;
131 GLboolean is_writeable
= 0;
132 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
134 tmp
= _ac_import_secondarycolor(ctx
,
136 stride
? 4*sizeof(GLfloat
) : 0,
141 inputs
->SecondaryColor
= *tmp
;
144 static void _tnl_import_fogcoord( GLcontext
*ctx
,
148 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
149 struct gl_client_array
*tmp
;
150 GLboolean is_writeable
= 0;
153 tmp
= _ac_import_fogcoord(ctx
, GL_FLOAT
,
154 stride
? sizeof(GLfloat
) : 0, writeable
,
158 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
162 inputs
->FogCoord
.data
= (GLfloat (*)[4]) data
;
163 inputs
->FogCoord
.start
= (GLfloat
*) data
;
164 inputs
->FogCoord
.stride
= tmp
->StrideB
;
165 inputs
->FogCoord
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
166 if (inputs
->FogCoord
.stride
!= sizeof(GLfloat
))
167 inputs
->FogCoord
.flags
|= VEC_BAD_STRIDE
;
169 inputs
->FogCoord
.flags
|= VEC_NOT_WRITEABLE
;
172 static void _tnl_import_index( GLcontext
*ctx
,
176 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
177 struct gl_client_array
*tmp
;
178 GLboolean is_writeable
= 0;
181 tmp
= _ac_import_index(ctx
, GL_UNSIGNED_INT
,
182 stride
? sizeof(GLuint
) : 0, writeable
,
186 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
190 inputs
->Index
.data
= (GLuint
*) data
;
191 inputs
->Index
.start
= (GLuint
*) data
;
192 inputs
->Index
.stride
= tmp
->StrideB
;
193 inputs
->Index
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
194 if (inputs
->Index
.stride
!= sizeof(GLuint
))
195 inputs
->Index
.flags
|= VEC_BAD_STRIDE
;
197 inputs
->Index
.flags
|= VEC_NOT_WRITEABLE
;
201 static void _tnl_import_texcoord( GLcontext
*ctx
,
206 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
207 struct gl_client_array
*tmp
;
208 GLboolean is_writeable
= 0;
211 tmp
= _ac_import_texcoord(ctx
, unit
, GL_FLOAT
,
212 stride
? 4 * sizeof(GLfloat
) : 0,
218 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
222 inputs
->TexCoord
[unit
].data
= (GLfloat (*)[4]) data
;
223 inputs
->TexCoord
[unit
].start
= (GLfloat
*) data
;
224 inputs
->TexCoord
[unit
].stride
= tmp
->StrideB
;
225 inputs
->TexCoord
[unit
].size
= tmp
->Size
;
226 inputs
->TexCoord
[unit
].flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
227 if (inputs
->TexCoord
[unit
].stride
!= 4*sizeof(GLfloat
))
228 inputs
->TexCoord
[unit
].flags
|= VEC_BAD_STRIDE
;
230 inputs
->TexCoord
[unit
].flags
|= VEC_NOT_WRITEABLE
;
234 static void _tnl_import_edgeflag( GLcontext
*ctx
,
238 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
239 struct gl_client_array
*tmp
;
240 GLboolean is_writeable
= 0;
243 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
244 stride
? sizeof(GLubyte
) : 0,
249 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
253 inputs
->EdgeFlag
.data
= (GLubyte
*) data
;
254 inputs
->EdgeFlag
.start
= (GLubyte
*) data
;
255 inputs
->EdgeFlag
.stride
= tmp
->StrideB
;
256 inputs
->EdgeFlag
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
257 if (inputs
->EdgeFlag
.stride
!= sizeof(GLubyte
))
258 inputs
->EdgeFlag
.flags
|= VEC_BAD_STRIDE
;
260 inputs
->EdgeFlag
.flags
|= VEC_NOT_WRITEABLE
;
265 static void _tnl_import_attrib( GLcontext
*ctx
,
270 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
271 struct gl_client_array
*tmp
;
272 GLboolean is_writeable
= 0;
275 tmp
= _ac_import_attrib(ctx
, index
, GL_FLOAT
,
276 stride
? 4 * sizeof(GLfloat
) : 0,
277 4, /* want GLfloat[4] */
282 data
= ADD_POINTERS(tmp
->Ptr
, tmp
->BufferObj
->Data
);
286 inputs
->Attribs
[index
].data
= (GLfloat (*)[4]) data
;
287 inputs
->Attribs
[index
].start
= (GLfloat
*) data
;
288 inputs
->Attribs
[index
].stride
= tmp
->StrideB
;
289 inputs
->Attribs
[index
].size
= tmp
->Size
;
290 inputs
->Attribs
[index
].flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
291 if (inputs
->Attribs
[index
].stride
!= 4 * sizeof(GLfloat
))
292 inputs
->Attribs
[index
].flags
|= VEC_BAD_STRIDE
;
294 inputs
->Attribs
[index
].flags
|= VEC_NOT_WRITEABLE
;
300 * Callback for VB stages that need to improve the quality of arrays
301 * bound to the VB. This is only necessary for client arrays which
302 * have not been transformed at any point in the pipeline.
303 * \param required - bitmask of VERT_*_BIT flags
304 * \param flags - bitmask of VEC_* flags (ex: VEC_NOT_WRITABLE)
306 static void _tnl_upgrade_client_data( GLcontext
*ctx
,
311 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
312 GLboolean writeable
= (flags
& VEC_NOT_WRITEABLE
) != 0;
313 GLboolean stride
= (flags
& VEC_BAD_STRIDE
) != 0;
314 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
318 if (writeable
|| stride
) ca_flags
|= CA_CLIENT_DATA
;
320 if ((required
& VERT_BIT_CLIP
) && VB
->ClipPtr
== VB
->ObjPtr
)
321 required
|= VERT_BIT_POS
;
323 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
325 if ((required
& VERT_BIT_POS
) && (VB
->ObjPtr
->flags
& flags
)) {
326 ASSERT(VB
->ObjPtr
== &inputs
->Obj
);
327 _tnl_import_vertex( ctx
, writeable
, stride
);
328 VB
->importable_data
&= ~(VERT_BIT_POS
|VERT_BIT_CLIP
);
331 if ((required
& VERT_BIT_NORMAL
) && (VB
->NormalPtr
->flags
& flags
)) {
332 ASSERT(VB
->NormalPtr
== &inputs
->Normal
);
333 _tnl_import_normal( ctx
, writeable
, stride
);
334 VB
->importable_data
&= ~VERT_BIT_NORMAL
;
337 if ((required
& VERT_BIT_COLOR0
) && (VB
->ColorPtr
[0]->Flags
& ca_flags
)) {
338 ASSERT(VB
->ColorPtr
[0] == &inputs
->Color
);
339 _tnl_import_color( ctx
, GL_FLOAT
, writeable
, stride
);
340 VB
->importable_data
&= ~VERT_BIT_COLOR0
;
343 if ((required
& VERT_BIT_COLOR1
) &&
344 (VB
->SecondaryColorPtr
[0]->Flags
& ca_flags
)) {
345 ASSERT(VB
->SecondaryColorPtr
[0] == &inputs
->SecondaryColor
);
346 _tnl_import_secondarycolor( ctx
, GL_FLOAT
, writeable
, stride
);
347 VB
->importable_data
&= ~VERT_BIT_COLOR1
;
350 if ((required
& VERT_BIT_FOG
)
351 && (VB
->FogCoordPtr
->flags
& flags
)) {
352 ASSERT(VB
->FogCoordPtr
== &inputs
->FogCoord
);
353 _tnl_import_fogcoord( ctx
, writeable
, stride
);
354 VB
->importable_data
&= ~VERT_BIT_FOG
;
357 if ((required
& VERT_BIT_INDEX
) && (VB
->IndexPtr
[0]->flags
& flags
)) {
358 ASSERT(VB
->IndexPtr
[0] == &inputs
->Index
);
359 _tnl_import_index( ctx
, writeable
, stride
);
360 VB
->importable_data
&= ~VERT_BIT_INDEX
;
363 if (required
& VERT_BITS_TEX_ANY
)
364 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
365 if ((required
& VERT_BIT_TEX(i
)) && (VB
->TexCoordPtr
[i
]->flags
& flags
)) {
366 ASSERT(VB
->TexCoordPtr
[i
] == &inputs
->TexCoord
[i
]);
367 _tnl_import_texcoord( ctx
, i
, writeable
, stride
);
368 VB
->importable_data
&= ~VERT_BIT_TEX(i
);
371 /* XXX not sure what to do here for vertex program arrays */
376 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLsizei count
)
378 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
379 struct vertex_buffer
*VB
= &tnl
->vb
;
380 GLuint inputs
= tnl
->pipeline
.inputs
;
381 struct vertex_arrays
*tmp
= &tnl
->array_inputs
;
383 /* _mesa_debug(ctx, "%s %d..%d // %d..%d\n", __FUNCTION__, */
384 /* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */
385 /* _tnl_print_vert_flags(" inputs", inputs); */
386 /* _tnl_print_vert_flags(" _Enabled", ctx->Array._Enabled); */
387 /* _tnl_print_vert_flags(" importable", inputs & VERT_BITS_FIXUP); */
389 VB
->Count
= count
- start
;
390 VB
->FirstClipped
= VB
->Count
;
392 VB
->MaterialMask
= NULL
;
395 VB
->Primitive
= tnl
->tmp_primitive
;
396 VB
->PrimitiveLength
= tnl
->tmp_primitive_length
;
397 VB
->import_data
= _tnl_upgrade_client_data
;
398 VB
->importable_data
= inputs
& VERT_BITS_FIXUP
;
400 if (ctx
->Array
.LockCount
) {
401 ASSERT(start
== (GLint
) ctx
->Array
.LockFirst
);
402 ASSERT(count
== (GLint
) ctx
->Array
.LockCount
);
405 _ac_import_range( ctx
, start
, count
);
407 /* When vertex program mode is enabled, the generic vertex program
408 * attribute arrays have priority over the conventional attributes.
409 * Try to use them now.
411 if (ctx
->VertexProgram
.Enabled
) {
413 for (index
= 0; index
< VERT_ATTRIB_MAX
; index
++) {
414 /* XXX check program->InputsRead to reduce work here */
415 _tnl_import_attrib( ctx
, index
, GL_FALSE
, GL_TRUE
);
416 VB
->AttribPtr
[index
] = &tmp
->Attribs
[index
];
421 * Conventional attributes
423 if (inputs
& VERT_BIT_POS
) {
424 _tnl_import_vertex( ctx
, 0, 0 );
425 tmp
->Obj
.count
= VB
->Count
;
426 VB
->ObjPtr
= &tmp
->Obj
;
429 if (inputs
& VERT_BIT_NORMAL
) {
430 _tnl_import_normal( ctx
, 0, 0 );
431 tmp
->Normal
.count
= VB
->Count
;
432 VB
->NormalPtr
= &tmp
->Normal
;
435 if (inputs
& VERT_BIT_COLOR0
) {
436 _tnl_import_color( ctx
, 0, 0, 0 );
437 VB
->ColorPtr
[0] = &tmp
->Color
;
441 if (inputs
& VERT_BITS_TEX_ANY
) {
443 for (unit
= 0; unit
< ctx
->Const
.MaxTextureUnits
; unit
++) {
444 if (inputs
& VERT_BIT_TEX(unit
)) {
445 _tnl_import_texcoord( ctx
, unit
, GL_FALSE
, GL_FALSE
);
446 tmp
->TexCoord
[unit
].count
= VB
->Count
;
447 VB
->TexCoordPtr
[unit
] = &tmp
->TexCoord
[unit
];
452 if (inputs
& (VERT_BIT_INDEX
| VERT_BIT_FOG
|
453 VERT_BIT_EDGEFLAG
| VERT_BIT_COLOR1
)) {
454 if (inputs
& VERT_BIT_INDEX
) {
455 _tnl_import_index( ctx
, 0, 0 );
456 tmp
->Index
.count
= VB
->Count
;
457 VB
->IndexPtr
[0] = &tmp
->Index
;
461 if (inputs
& VERT_BIT_FOG
) {
462 _tnl_import_fogcoord( ctx
, 0, 0 );
463 tmp
->FogCoord
.count
= VB
->Count
;
464 VB
->FogCoordPtr
= &tmp
->FogCoord
;
467 if (inputs
& VERT_BIT_EDGEFLAG
) {
468 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
469 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
.data
;
472 if (inputs
& VERT_BIT_COLOR1
) {
473 _tnl_import_secondarycolor( ctx
, 0, 0, 0 );
474 VB
->SecondaryColorPtr
[0] = &tmp
->SecondaryColor
;
475 VB
->SecondaryColorPtr
[1] = 0;