1 /* $Id: t_array_import.c,v 1.7 2001/01/24 00:04:59 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keithw@valinux.com>
38 #include "array_cache/acache.h"
39 #include "math/m_translate.h"
41 #include "t_array_import.h"
42 #include "t_context.h"
45 static void _tnl_import_vertex( GLcontext
*ctx
,
49 struct gl_client_array
*tmp
;
50 GLboolean is_writeable
= 0;
51 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
53 tmp
= _ac_import_vertex(ctx
,
55 stride
? 4*sizeof(GLfloat
) : 0,
60 inputs
->Obj
.data
= tmp
->Ptr
;
61 inputs
->Obj
.start
= (GLfloat
*)tmp
->Ptr
;
62 inputs
->Obj
.stride
= tmp
->StrideB
;
63 inputs
->Obj
.size
= tmp
->Size
;
64 inputs
->Obj
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
65 if (inputs
->Obj
.stride
!= 4*sizeof(GLfloat
))
66 inputs
->Obj
.flags
|= VEC_BAD_STRIDE
;
68 inputs
->Obj
.flags
|= VEC_NOT_WRITEABLE
;
71 static void _tnl_import_normal( GLcontext
*ctx
,
75 struct gl_client_array
*tmp
;
76 GLboolean is_writeable
= 0;
77 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
79 tmp
= _ac_import_normal(ctx
, GL_FLOAT
,
80 stride
? 3*sizeof(GLfloat
) : 0, writeable
,
83 inputs
->Normal
.data
= tmp
->Ptr
;
84 inputs
->Normal
.start
= (GLfloat
*)tmp
->Ptr
;
85 inputs
->Normal
.stride
= tmp
->StrideB
;
86 inputs
->Normal
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
87 if (inputs
->Normal
.stride
!= 3*sizeof(GLfloat
))
88 inputs
->Normal
.flags
|= VEC_BAD_STRIDE
;
90 inputs
->Normal
.flags
|= VEC_NOT_WRITEABLE
;
94 static void _tnl_import_color( GLcontext
*ctx
,
98 struct gl_client_array
*tmp
;
99 GLboolean is_writeable
= 0;
100 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
102 tmp
= _ac_import_color(ctx
,
104 stride
? 4*sizeof(GLubyte
) : 0,
109 inputs
->Color
.data
= tmp
->Ptr
;
110 inputs
->Color
.start
= (GLchan
*)tmp
->Ptr
;
111 inputs
->Color
.stride
= tmp
->StrideB
;
112 inputs
->Color
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
113 if (inputs
->Color
.stride
!= 4*sizeof(GLchan
))
114 inputs
->Color
.flags
|= VEC_BAD_STRIDE
;
116 inputs
->Color
.flags
|= VEC_NOT_WRITEABLE
;
120 static void _tnl_import_secondarycolor( GLcontext
*ctx
,
124 struct gl_client_array
*tmp
;
125 GLboolean is_writeable
= 0;
126 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
128 tmp
= _ac_import_secondarycolor(ctx
, GL_UNSIGNED_BYTE
,
129 stride
? 4*sizeof(GLubyte
) : 0,
134 inputs
->SecondaryColor
.data
= tmp
->Ptr
;
135 inputs
->SecondaryColor
.start
= (GLchan
*)tmp
->Ptr
;
136 inputs
->SecondaryColor
.stride
= tmp
->StrideB
;
137 inputs
->SecondaryColor
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
138 if (inputs
->SecondaryColor
.stride
!= 4*sizeof(GLubyte
))
139 inputs
->SecondaryColor
.flags
|= VEC_BAD_STRIDE
;
141 inputs
->SecondaryColor
.flags
|= VEC_NOT_WRITEABLE
;
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;
152 tmp
= _ac_import_fogcoord(ctx
, GL_FLOAT
,
153 stride
? sizeof(GLfloat
) : 0, writeable
,
156 inputs
->FogCoord
.data
= tmp
->Ptr
;
157 inputs
->FogCoord
.start
= (GLfloat
*)tmp
->Ptr
;
158 inputs
->FogCoord
.stride
= tmp
->StrideB
;
159 inputs
->FogCoord
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
160 if (inputs
->FogCoord
.stride
!= sizeof(GLfloat
))
161 inputs
->FogCoord
.flags
|= VEC_BAD_STRIDE
;
163 inputs
->FogCoord
.flags
|= VEC_NOT_WRITEABLE
;
166 static void _tnl_import_index( GLcontext
*ctx
,
170 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
171 struct gl_client_array
*tmp
;
172 GLboolean is_writeable
= 0;
174 tmp
= _ac_import_index(ctx
, GL_UNSIGNED_INT
,
175 stride
? sizeof(GLuint
) : 0, writeable
,
178 inputs
->Index
.data
= tmp
->Ptr
;
179 inputs
->Index
.start
= (GLuint
*)tmp
->Ptr
;
180 inputs
->Index
.stride
= tmp
->StrideB
;
181 inputs
->Index
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
182 if (inputs
->Index
.stride
!= sizeof(GLuint
))
183 inputs
->Index
.flags
|= VEC_BAD_STRIDE
;
185 inputs
->Index
.flags
|= VEC_NOT_WRITEABLE
;
189 static void _tnl_import_texcoord( GLcontext
*ctx
,
194 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
195 struct gl_client_array
*tmp
;
196 GLboolean is_writeable
= 0;
198 tmp
= _ac_import_texcoord(ctx
, i
, GL_FLOAT
,
199 stride
? 4*sizeof(GLfloat
) : 0,
204 inputs
->TexCoord
[i
].data
= tmp
->Ptr
;
205 inputs
->TexCoord
[i
].start
= (GLfloat
*)tmp
->Ptr
;
206 inputs
->TexCoord
[i
].stride
= tmp
->StrideB
;
207 inputs
->TexCoord
[i
].size
= tmp
->Size
;
208 inputs
->TexCoord
[i
].flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
209 if (inputs
->TexCoord
[i
].stride
!= 4*sizeof(GLfloat
))
210 inputs
->TexCoord
[i
].flags
|= VEC_BAD_STRIDE
;
212 inputs
->TexCoord
[i
].flags
|= VEC_NOT_WRITEABLE
;
216 static void _tnl_import_edgeflag( GLcontext
*ctx
,
220 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
221 struct gl_client_array
*tmp
;
222 GLboolean is_writeable
= 0;
224 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
225 stride
? sizeof(GLubyte
) : 0,
229 inputs
->EdgeFlag
.data
= tmp
->Ptr
;
230 inputs
->EdgeFlag
.start
= (GLubyte
*)tmp
->Ptr
;
231 inputs
->EdgeFlag
.stride
= tmp
->StrideB
;
232 inputs
->EdgeFlag
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
233 if (inputs
->EdgeFlag
.stride
!= sizeof(GLubyte
))
234 inputs
->EdgeFlag
.flags
|= VEC_BAD_STRIDE
;
236 inputs
->EdgeFlag
.flags
|= VEC_NOT_WRITEABLE
;
241 /* Callback for VB stages that need to improve the quality of arrays
242 * bound to the VB. This is only necessary for client arrays which
243 * have not been transformed at any point in the pipeline.
245 static void _tnl_upgrade_client_data( GLcontext
*ctx
,
250 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
251 GLboolean writeable
= (flags
& VEC_NOT_WRITEABLE
) != 0;
252 GLboolean stride
= (flags
& VEC_BAD_STRIDE
) != 0;
253 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
256 if ((required
& VERT_CLIP
) && VB
->ClipPtr
== VB
->ObjPtr
)
257 required
|= VERT_OBJ
;
259 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
261 if ((required
& VERT_OBJ
) && (VB
->ObjPtr
->flags
& flags
)) {
262 ASSERT(VB
->ObjPtr
== &inputs
->Obj
);
263 _tnl_import_vertex( ctx
, writeable
, stride
);
264 VB
->importable_data
&= ~(VERT_OBJ
|VERT_CLIP
);
267 if ((required
& VERT_NORM
) && (VB
->NormalPtr
->flags
& flags
)) {
268 ASSERT(VB
->NormalPtr
== &inputs
->Normal
);
269 _tnl_import_normal( ctx
, writeable
, stride
);
270 VB
->importable_data
&= ~VERT_NORM
;
273 if ((required
& VERT_RGBA
) && (VB
->ColorPtr
[0]->flags
& flags
)) {
274 ASSERT(VB
->ColorPtr
[0] == &inputs
->Color
);
275 _tnl_import_color( ctx
, writeable
, stride
);
276 VB
->importable_data
&= ~VERT_RGBA
;
279 if ((required
& VERT_SPEC_RGB
) && (VB
->SecondaryColorPtr
[0]->flags
&flags
)) {
280 ASSERT(VB
->SecondaryColorPtr
[0] == &inputs
->SecondaryColor
);
281 _tnl_import_secondarycolor( ctx
, writeable
, stride
);
282 VB
->importable_data
&= ~VERT_SPEC_RGB
;
285 if ((required
& VERT_FOG_COORD
) && (VB
->FogCoordPtr
->flags
& flags
)) {
286 ASSERT(VB
->FogCoordPtr
== &inputs
->FogCoord
);
287 _tnl_import_fogcoord( ctx
, writeable
, stride
);
288 VB
->importable_data
&= ~VERT_FOG_COORD
;
291 if ((required
& VERT_INDEX
) && (VB
->IndexPtr
[0]->flags
& flags
)) {
292 ASSERT(VB
->IndexPtr
[0] == &inputs
->Index
);
293 _tnl_import_index( ctx
, writeable
, stride
);
294 VB
->importable_data
&= ~VERT_INDEX
;
297 if (required
& VERT_TEX_ANY
)
298 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
299 if ((required
& VERT_TEX(i
)) && (VB
->TexCoordPtr
[i
]->flags
& flags
)) {
300 ASSERT(VB
->TexCoordPtr
[i
] == &inputs
->TexCoord
[i
]);
301 _tnl_import_texcoord( ctx
, i
, writeable
, stride
);
302 VB
->importable_data
&= ~VERT_TEX(i
);
311 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLsizei count
)
313 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
314 struct vertex_buffer
*VB
= &tnl
->vb
;
315 GLuint inputs
= tnl
->pipeline
.inputs
;
317 struct vertex_arrays
*tmp
= &tnl
->array_inputs
;
319 if (ctx
->Array
.LockCount
) {
320 ASSERT(start
== ctx
->Array
.LockFirst
);
321 ASSERT(count
== ctx
->Array
.LockCount
);
324 imports
= tnl
->pipeline
.inputs
;
326 _ac_import_range( ctx
, start
, count
);
328 VB
->Count
= count
- start
;
329 VB
->FirstClipped
= VB
->Count
;
332 VB
->MaterialMask
= 0;
336 /* _tnl_print_vert_flags("_tnl_vb_bind_arrays: inputs", inputs); */
337 /* _tnl_print_vert_flags("_tnl_vb_bind_arrays: imports", imports); */
338 /* _tnl_print_vert_flags("_tnl_vb_bind_arrays: _Enabled", ctx->Array._Enabled); */
340 if (inputs
& VERT_OBJ
) {
341 if (imports
& VERT_OBJ
) {
342 _tnl_import_vertex( ctx
, 0, 0 );
343 tmp
->Obj
.count
= VB
->Count
;
345 VB
->ObjPtr
= &tmp
->Obj
;
348 if (inputs
& VERT_NORM
) {
349 if (imports
& VERT_NORM
) {
350 _tnl_import_normal( ctx
, 0, 0 );
351 tmp
->Normal
.count
= VB
->Count
;
353 VB
->NormalPtr
= &tmp
->Normal
;
356 if (inputs
& VERT_RGBA
) {
357 if (imports
& VERT_RGBA
) {
358 _tnl_import_color( ctx
, 0, 0 );
359 tmp
->Color
.count
= VB
->Count
;
361 VB
->ColorPtr
[0] = &tmp
->Color
;
365 if (inputs
& VERT_INDEX
) {
366 if (imports
& VERT_INDEX
) {
367 _tnl_import_index( ctx
, 0, 0 );
368 tmp
->Index
.count
= VB
->Count
;
370 VB
->IndexPtr
[0] = &tmp
->Index
;
375 if (inputs
& VERT_FOG_COORD
) {
376 if (imports
& VERT_FOG_COORD
) {
377 _tnl_import_fogcoord( ctx
, 0, 0 );
378 tmp
->FogCoord
.count
= VB
->Count
;
380 VB
->FogCoordPtr
= &tmp
->FogCoord
;
383 if (inputs
& VERT_EDGE
) {
384 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
385 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
.data
;
388 if (inputs
& VERT_SPEC_RGB
) {
389 if (imports
& VERT_SPEC_RGB
) {
390 _tnl_import_secondarycolor( ctx
, 0, 0 );
391 tmp
->SecondaryColor
.count
= VB
->Count
;
393 VB
->SecondaryColorPtr
[0] = &tmp
->SecondaryColor
;
394 VB
->SecondaryColorPtr
[1] = 0;
397 if (inputs
& VERT_TEX_ANY
) {
399 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++)
400 if (inputs
& VERT_TEX(i
)) {
401 if (imports
& VERT_TEX(i
)) {
402 _tnl_import_texcoord( ctx
, i
, 0, 0 );
403 tmp
->TexCoord
[i
].count
= VB
->Count
;
405 VB
->TexCoordPtr
[i
] = &tmp
->TexCoord
[i
];
409 VB
->Primitive
= tnl
->tmp_primitive
;
410 VB
->PrimitiveLength
= tnl
->tmp_primitive_length
;
411 VB
->import_data
= _tnl_upgrade_client_data
;
412 VB
->importable_data
= imports
& VERT_FIXUP
;
413 /* _tnl_print_vert_flags("_tnl_vb_bind_arrays: importable", VB->importable_data); */
420 /* Function to fill an immediate struct with the effects of
421 * consecutive calls to ArrayElement with consecutive indices.
423 void _tnl_fill_immediate_drawarrays( GLcontext
*ctx
, struct immediate
*IM
,
424 GLuint start
, GLuint count
)
426 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
427 GLuint required
= ctx
->Array
._Enabled
;
428 GLuint n
= count
- start
;
431 if (!ctx
->CompileFlag
)
432 required
&= tnl
->pipeline
.inputs
;
434 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
435 fprintf(stderr
, "exec_full_array_elements %d .. %d\n", start
, count
);
437 _math_trans_4f( IM
->Obj
+ IM
->Start
,
438 ctx
->Array
.Vertex
.Ptr
,
439 ctx
->Array
.Vertex
.StrideB
,
440 ctx
->Array
.Vertex
.Type
,
441 ctx
->Array
.Vertex
.Size
,
444 if (ctx
->Array
.Vertex
.Size
== 4)
445 required
|= VERT_OBJ_234
;
446 else if (ctx
->Array
.Vertex
.Size
== 3)
447 required
|= VERT_OBJ_23
;
450 if (required
& VERT_NORM
) {
451 _math_trans_3f( IM
->Normal
+ IM
->Start
,
452 ctx
->Array
.Normal
.Ptr
,
453 ctx
->Array
.Normal
.StrideB
,
454 ctx
->Array
.Normal
.Type
,
458 if (required
& VERT_EDGE
) {
459 _math_trans_1ub( IM
->EdgeFlag
+ IM
->Start
,
460 ctx
->Array
.EdgeFlag
.Ptr
,
461 ctx
->Array
.EdgeFlag
.StrideB
,
462 ctx
->Array
.EdgeFlag
.Type
,
466 if (required
& VERT_RGBA
) {
467 #if CHAN_TYPE == GL_UNSIGNED_BYTE
468 _math_trans_4ub( IM
->Color
+ IM
->Start
,
469 ctx
->Array
.Color
.Ptr
,
470 ctx
->Array
.Color
.StrideB
,
471 ctx
->Array
.Color
.Type
,
472 ctx
->Array
.Color
.Size
,
474 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
475 _math_trans_4us( IM
->Color
+ IM
->Start
,
476 ctx
->Array
.Color
.Ptr
,
477 ctx
->Array
.Color
.StrideB
,
478 ctx
->Array
.Color
.Type
,
479 ctx
->Array
.Color
.Size
,
481 #elif CHAN_TYPE == GL_FLOAT
482 _math_trans_4f( IM
->Color
+ IM
->Start
,
483 ctx
->Array
.Color
.Ptr
,
484 ctx
->Array
.Color
.StrideB
,
485 ctx
->Array
.Color
.Type
,
486 ctx
->Array
.Color
.Size
,
491 if (required
& VERT_SPEC_RGB
) {
492 #if CHAN_TYPE == GL_UNSIGNED_BYTE
493 _math_trans_4ub( IM
->SecondaryColor
+ IM
->Start
,
494 ctx
->Array
.SecondaryColor
.Ptr
,
495 ctx
->Array
.SecondaryColor
.StrideB
,
496 ctx
->Array
.SecondaryColor
.Type
,
497 ctx
->Array
.SecondaryColor
.Size
,
499 #elif CHAN_TYPE == GL_UNSIGNED_SHORT
500 _math_trans_4us( IM
->SecondaryColor
+ IM
->Start
,
501 ctx
->Array
.SecondaryColor
.Ptr
,
502 ctx
->Array
.SecondaryColor
.StrideB
,
503 ctx
->Array
.SecondaryColor
.Type
,
504 ctx
->Array
.SecondaryColor
.Size
,
506 #elif CHAN_TYPE == GL_FLOAT
507 _math_trans_4f( IM
->SecondaryColor
+ IM
->Start
,
508 ctx
->Array
.SecondaryColor
.Ptr
,
509 ctx
->Array
.SecondaryColor
.StrideB
,
510 ctx
->Array
.SecondaryColor
.Type
,
511 ctx
->Array
.SecondaryColor
.Size
,
516 if (required
& VERT_FOG_COORD
) {
517 _math_trans_1f( IM
->FogCoord
+ IM
->Start
,
518 ctx
->Array
.FogCoord
.Ptr
,
519 ctx
->Array
.FogCoord
.StrideB
,
520 ctx
->Array
.FogCoord
.Type
,
524 if (required
& VERT_INDEX
) {
525 _math_trans_1ui( IM
->Index
+ IM
->Start
,
526 ctx
->Array
.Index
.Ptr
,
527 ctx
->Array
.Index
.StrideB
,
528 ctx
->Array
.Index
.Type
,
532 if (required
& VERT_TEX_ANY
) {
533 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
534 if (required
& VERT_TEX(i
)) {
535 _math_trans_4f( IM
->TexCoord
[i
] + IM
->Start
,
536 ctx
->Array
.TexCoord
[i
].Ptr
,
537 ctx
->Array
.TexCoord
[i
].StrideB
,
538 ctx
->Array
.TexCoord
[i
].Size
,
539 ctx
->Array
.TexCoord
[i
].Type
,
542 if (ctx
->Array
.TexCoord
[i
].Size
== 4)
543 IM
->TexSize
|= TEX_SIZE_4(i
);
544 else if (ctx
->Array
.TexCoord
[i
].Size
== 3)
545 IM
->TexSize
|= TEX_SIZE_3(i
);
550 IM
->Count
= IM
->Start
+ n
;
551 IM
->Flag
[IM
->Start
] |= required
;
552 for (i
= IM
->Start
+1 ; i
< IM
->Count
; i
++)
553 IM
->Flag
[i
] = required
;