1 /* $Id: t_array_import.c,v 1.19 2001/12/14 02:51:42 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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"
43 #include "t_imm_debug.h"
46 static void _tnl_import_vertex( GLcontext
*ctx
,
50 struct gl_client_array
*tmp
;
51 GLboolean is_writeable
= 0;
52 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
54 tmp
= _ac_import_vertex(ctx
,
56 stride
? 4*sizeof(GLfloat
) : 0,
61 inputs
->Obj
.data
= (GLfloat (*)[4]) tmp
->Ptr
;
62 inputs
->Obj
.start
= (GLfloat
*) tmp
->Ptr
;
63 inputs
->Obj
.stride
= tmp
->StrideB
;
64 inputs
->Obj
.size
= tmp
->Size
;
65 inputs
->Obj
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
66 if (inputs
->Obj
.stride
!= 4*sizeof(GLfloat
))
67 inputs
->Obj
.flags
|= VEC_BAD_STRIDE
;
69 inputs
->Obj
.flags
|= VEC_NOT_WRITEABLE
;
72 static void _tnl_import_normal( GLcontext
*ctx
,
76 struct gl_client_array
*tmp
;
77 GLboolean is_writeable
= 0;
78 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
80 tmp
= _ac_import_normal(ctx
, GL_FLOAT
,
81 stride
? 3*sizeof(GLfloat
) : 0, writeable
,
84 inputs
->Normal
.data
= (GLfloat (*)[3]) tmp
->Ptr
;
85 inputs
->Normal
.start
= (GLfloat
*) tmp
->Ptr
;
86 inputs
->Normal
.stride
= tmp
->StrideB
;
87 inputs
->Normal
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
88 if (inputs
->Normal
.stride
!= 3*sizeof(GLfloat
))
89 inputs
->Normal
.flags
|= VEC_BAD_STRIDE
;
91 inputs
->Normal
.flags
|= VEC_NOT_WRITEABLE
;
95 static void _tnl_import_color( GLcontext
*ctx
,
100 struct gl_client_array
*tmp
;
101 GLboolean is_writeable
= 0;
102 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
104 tmp
= _ac_import_color(ctx
,
106 stride
? 4*sizeof(GLfloat
) : 0,
111 inputs
->Color
= *tmp
;
115 static void _tnl_import_secondarycolor( GLcontext
*ctx
,
120 struct gl_client_array
*tmp
;
121 GLboolean is_writeable
= 0;
122 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
124 tmp
= _ac_import_secondarycolor(ctx
,
126 stride
? 4*sizeof(GLfloat
) : 0,
131 inputs
->SecondaryColor
= *tmp
;
134 static void _tnl_import_fogcoord( GLcontext
*ctx
,
138 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
139 struct gl_client_array
*tmp
;
140 GLboolean is_writeable
= 0;
142 tmp
= _ac_import_fogcoord(ctx
, GL_FLOAT
,
143 stride
? sizeof(GLfloat
) : 0, writeable
,
146 inputs
->FogCoord
.data
= (GLfloat
*) tmp
->Ptr
;
147 inputs
->FogCoord
.start
= (GLfloat
*) tmp
->Ptr
;
148 inputs
->FogCoord
.stride
= tmp
->StrideB
;
149 inputs
->FogCoord
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
150 if (inputs
->FogCoord
.stride
!= sizeof(GLfloat
))
151 inputs
->FogCoord
.flags
|= VEC_BAD_STRIDE
;
153 inputs
->FogCoord
.flags
|= VEC_NOT_WRITEABLE
;
156 static void _tnl_import_index( GLcontext
*ctx
,
160 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
161 struct gl_client_array
*tmp
;
162 GLboolean is_writeable
= 0;
164 tmp
= _ac_import_index(ctx
, GL_UNSIGNED_INT
,
165 stride
? sizeof(GLuint
) : 0, writeable
,
168 inputs
->Index
.data
= (GLuint
*) tmp
->Ptr
;
169 inputs
->Index
.start
= (GLuint
*) tmp
->Ptr
;
170 inputs
->Index
.stride
= tmp
->StrideB
;
171 inputs
->Index
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
172 if (inputs
->Index
.stride
!= sizeof(GLuint
))
173 inputs
->Index
.flags
|= VEC_BAD_STRIDE
;
175 inputs
->Index
.flags
|= VEC_NOT_WRITEABLE
;
179 static void _tnl_import_texcoord( GLcontext
*ctx
,
184 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
185 struct gl_client_array
*tmp
;
186 GLboolean is_writeable
= 0;
188 tmp
= _ac_import_texcoord(ctx
, i
, GL_FLOAT
,
189 stride
? 4*sizeof(GLfloat
) : 0,
194 inputs
->TexCoord
[i
].data
= (GLfloat (*)[4]) tmp
->Ptr
;
195 inputs
->TexCoord
[i
].start
= (GLfloat
*) tmp
->Ptr
;
196 inputs
->TexCoord
[i
].stride
= tmp
->StrideB
;
197 inputs
->TexCoord
[i
].size
= tmp
->Size
;
198 inputs
->TexCoord
[i
].flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
199 if (inputs
->TexCoord
[i
].stride
!= 4*sizeof(GLfloat
))
200 inputs
->TexCoord
[i
].flags
|= VEC_BAD_STRIDE
;
202 inputs
->TexCoord
[i
].flags
|= VEC_NOT_WRITEABLE
;
206 static void _tnl_import_edgeflag( GLcontext
*ctx
,
210 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
211 struct gl_client_array
*tmp
;
212 GLboolean is_writeable
= 0;
214 tmp
= _ac_import_edgeflag(ctx
, GL_UNSIGNED_BYTE
,
215 stride
? sizeof(GLubyte
) : 0,
219 inputs
->EdgeFlag
.data
= (GLubyte
*) tmp
->Ptr
;
220 inputs
->EdgeFlag
.start
= (GLubyte
*) tmp
->Ptr
;
221 inputs
->EdgeFlag
.stride
= tmp
->StrideB
;
222 inputs
->EdgeFlag
.flags
&= ~(VEC_BAD_STRIDE
|VEC_NOT_WRITEABLE
);
223 if (inputs
->EdgeFlag
.stride
!= sizeof(GLubyte
))
224 inputs
->EdgeFlag
.flags
|= VEC_BAD_STRIDE
;
226 inputs
->EdgeFlag
.flags
|= VEC_NOT_WRITEABLE
;
231 /* Callback for VB stages that need to improve the quality of arrays
232 * bound to the VB. This is only necessary for client arrays which
233 * have not been transformed at any point in the pipeline.
235 static void _tnl_upgrade_client_data( GLcontext
*ctx
,
240 struct vertex_buffer
*VB
= &TNL_CONTEXT(ctx
)->vb
;
241 GLboolean writeable
= (flags
& VEC_NOT_WRITEABLE
) != 0;
242 GLboolean stride
= (flags
& VEC_BAD_STRIDE
) != 0;
243 struct vertex_arrays
*inputs
= &TNL_CONTEXT(ctx
)->array_inputs
;
247 if (writeable
|| stride
) ca_flags
|= CA_CLIENT_DATA
;
249 if ((required
& VERT_CLIP
) && VB
->ClipPtr
== VB
->ObjPtr
)
250 required
|= VERT_OBJ_BIT
;
252 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
254 if ((required
& VERT_OBJ_BIT
) && (VB
->ObjPtr
->flags
& flags
)) {
255 ASSERT(VB
->ObjPtr
== &inputs
->Obj
);
256 _tnl_import_vertex( ctx
, writeable
, stride
);
257 VB
->importable_data
&= ~(VERT_OBJ_BIT
|VERT_CLIP
);
260 if ((required
& VERT_NORMAL_BIT
) && (VB
->NormalPtr
->flags
& flags
)) {
261 ASSERT(VB
->NormalPtr
== &inputs
->Normal
);
262 _tnl_import_normal( ctx
, writeable
, stride
);
263 VB
->importable_data
&= ~VERT_NORMAL_BIT
;
266 if ((required
& VERT_COLOR0_BIT
) && (VB
->ColorPtr
[0]->Flags
& ca_flags
)) {
267 ASSERT(VB
->ColorPtr
[0] == &inputs
->Color
);
268 _tnl_import_color( ctx
, GL_FLOAT
, writeable
, stride
);
269 VB
->importable_data
&= ~VERT_COLOR0_BIT
;
272 if ((required
& VERT_COLOR1_BIT
) &&
273 (VB
->SecondaryColorPtr
[0]->Flags
& ca_flags
)) {
274 ASSERT(VB
->SecondaryColorPtr
[0] == &inputs
->SecondaryColor
);
275 _tnl_import_secondarycolor( ctx
, GL_FLOAT
, writeable
, stride
);
276 VB
->importable_data
&= ~VERT_COLOR1_BIT
;
279 if ((required
& VERT_FOG_BIT
) && (VB
->FogCoordPtr
->flags
& flags
)) {
280 ASSERT(VB
->FogCoordPtr
== &inputs
->FogCoord
);
281 _tnl_import_fogcoord( ctx
, writeable
, stride
);
282 VB
->importable_data
&= ~VERT_FOG_BIT
;
285 if ((required
& VERT_INDEX_BIT
) && (VB
->IndexPtr
[0]->flags
& flags
)) {
286 ASSERT(VB
->IndexPtr
[0] == &inputs
->Index
);
287 _tnl_import_index( ctx
, writeable
, stride
);
288 VB
->importable_data
&= ~VERT_INDEX_BIT
;
291 if (required
& VERT_TEX_ANY
)
292 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++)
293 if ((required
& VERT_TEX(i
)) && (VB
->TexCoordPtr
[i
]->flags
& flags
)) {
294 ASSERT(VB
->TexCoordPtr
[i
] == &inputs
->TexCoord
[i
]);
295 _tnl_import_texcoord( ctx
, i
, writeable
, stride
);
296 VB
->importable_data
&= ~VERT_TEX(i
);
303 void _tnl_vb_bind_arrays( GLcontext
*ctx
, GLint start
, GLsizei count
)
305 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
306 struct vertex_buffer
*VB
= &tnl
->vb
;
307 GLuint inputs
= tnl
->pipeline
.inputs
;
308 struct vertex_arrays
*tmp
= &tnl
->array_inputs
;
311 /* fprintf(stderr, "%s %d..%d // %d..%d\n", __FUNCTION__, */
312 /* start, count, ctx->Array.LockFirst, ctx->Array.LockCount); */
313 /* _tnl_print_vert_flags(" inputs", inputs); */
314 /* _tnl_print_vert_flags(" _Enabled", ctx->Array._Enabled); */
315 /* _tnl_print_vert_flags(" importable", inputs & VERT_FIXUP); */
317 VB
->Count
= count
- start
;
318 VB
->FirstClipped
= VB
->Count
;
320 VB
->MaterialMask
= 0;
323 VB
->Primitive
= tnl
->tmp_primitive
;
324 VB
->PrimitiveLength
= tnl
->tmp_primitive_length
;
325 VB
->import_data
= _tnl_upgrade_client_data
;
326 VB
->importable_data
= inputs
& VERT_FIXUP
;
328 if (ctx
->Array
.LockCount
) {
329 ASSERT(start
== (GLint
) ctx
->Array
.LockFirst
);
330 ASSERT(count
== (GLint
) ctx
->Array
.LockCount
);
333 _ac_import_range( ctx
, start
, count
);
335 if (inputs
& VERT_OBJ_BIT
) {
336 _tnl_import_vertex( ctx
, 0, 0 );
337 tmp
->Obj
.count
= VB
->Count
;
338 VB
->ObjPtr
= &tmp
->Obj
;
341 if (inputs
& VERT_NORMAL_BIT
) {
342 _tnl_import_normal( ctx
, 0, 0 );
343 tmp
->Normal
.count
= VB
->Count
;
344 VB
->NormalPtr
= &tmp
->Normal
;
347 if (inputs
& VERT_COLOR0_BIT
) {
348 _tnl_import_color( ctx
, 0, 0, 0 );
349 VB
->ColorPtr
[0] = &tmp
->Color
;
353 if (inputs
& VERT_TEX_ANY
) {
354 for (i
= 0; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
355 if (inputs
& VERT_TEX(i
)) {
356 _tnl_import_texcoord( ctx
, i
, 0, 0 );
357 tmp
->TexCoord
[i
].count
= VB
->Count
;
358 VB
->TexCoordPtr
[i
] = &tmp
->TexCoord
[i
];
363 if (inputs
& (VERT_INDEX_BIT
|VERT_FOG_BIT
|VERT_EDGEFLAG_BIT
|VERT_COLOR1_BIT
)) {
364 if (inputs
& VERT_INDEX_BIT
) {
365 _tnl_import_index( ctx
, 0, 0 );
366 tmp
->Index
.count
= VB
->Count
;
367 VB
->IndexPtr
[0] = &tmp
->Index
;
371 if (inputs
& VERT_FOG_BIT
) {
372 _tnl_import_fogcoord( ctx
, 0, 0 );
373 tmp
->FogCoord
.count
= VB
->Count
;
374 VB
->FogCoordPtr
= &tmp
->FogCoord
;
377 if (inputs
& VERT_EDGEFLAG_BIT
) {
378 _tnl_import_edgeflag( ctx
, GL_TRUE
, sizeof(GLboolean
) );
379 VB
->EdgeFlag
= (GLboolean
*) tmp
->EdgeFlag
.data
;
382 if (inputs
& VERT_COLOR1_BIT
) {
383 _tnl_import_secondarycolor( ctx
, 0, 0, 0 );
384 VB
->SecondaryColorPtr
[0] = &tmp
->SecondaryColor
;
385 VB
->SecondaryColorPtr
[1] = 0;