Updates required for building the SciTech SNAP version of Mesa. This includes:
[mesa.git] / src / mesa / tnl / t_array_import.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "macros.h"
31 #include "imports.h"
32 #include "state.h"
33 #include "mtypes.h"
34
35 #include "array_cache/acache.h"
36 #include "math/m_translate.h"
37
38 #include "t_array_import.h"
39 #include "t_context.h"
40 #include "t_imm_debug.h"
41
42
43 static void _tnl_import_vertex( GLcontext *ctx,
44 GLboolean writeable,
45 GLboolean stride )
46 {
47 struct gl_client_array *tmp;
48 GLboolean is_writeable = 0;
49 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
50 GLubyte *data;
51
52 tmp = _ac_import_vertex(ctx,
53 GL_FLOAT,
54 stride ? 4*sizeof(GLfloat) : 0,
55 0,
56 writeable,
57 &is_writeable);
58
59 #if 0
60 /* guess we really don't need to add pointers here - BP */
61 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
62 #else
63 data = tmp->Ptr;
64 #endif
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;
72 if (!is_writeable)
73 inputs->Obj.flags |= VEC_NOT_WRITEABLE;
74 }
75
76 static void _tnl_import_normal( GLcontext *ctx,
77 GLboolean writeable,
78 GLboolean stride )
79 {
80 struct gl_client_array *tmp;
81 GLboolean is_writeable = 0;
82 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
83 GLubyte *data;
84
85 tmp = _ac_import_normal(ctx, GL_FLOAT,
86 stride ? 3*sizeof(GLfloat) : 0, writeable,
87 &is_writeable);
88
89 #if 0
90 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
91 #else
92 data = tmp->Ptr;
93 #endif
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;
100 if (!is_writeable)
101 inputs->Normal.flags |= VEC_NOT_WRITEABLE;
102 }
103
104
105 static void _tnl_import_color( GLcontext *ctx,
106 GLenum type,
107 GLboolean writeable,
108 GLboolean stride )
109 {
110 struct gl_client_array *tmp;
111 GLboolean is_writeable = 0;
112 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
113
114 tmp = _ac_import_color(ctx,
115 type,
116 stride ? 4*sizeof(GLfloat) : 0,
117 4,
118 writeable,
119 &is_writeable);
120
121 inputs->Color = *tmp;
122 }
123
124
125 static void _tnl_import_secondarycolor( GLcontext *ctx,
126 GLenum type,
127 GLboolean writeable,
128 GLboolean stride )
129 {
130 struct gl_client_array *tmp;
131 GLboolean is_writeable = 0;
132 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
133
134 tmp = _ac_import_secondarycolor(ctx,
135 type,
136 stride ? 4*sizeof(GLfloat) : 0,
137 4,
138 writeable,
139 &is_writeable);
140
141 inputs->SecondaryColor = *tmp;
142 }
143
144 static void _tnl_import_fogcoord( GLcontext *ctx,
145 GLboolean writeable,
146 GLboolean stride )
147 {
148 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
149 struct gl_client_array *tmp;
150 GLboolean is_writeable = 0;
151 GLubyte *data;
152
153 tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
154 stride ? sizeof(GLfloat) : 0, writeable,
155 &is_writeable);
156
157 #if 0
158 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
159 #else
160 data = tmp->Ptr;
161 #endif
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;
168 if (!is_writeable)
169 inputs->FogCoord.flags |= VEC_NOT_WRITEABLE;
170 }
171
172 static void _tnl_import_index( GLcontext *ctx,
173 GLboolean writeable,
174 GLboolean stride )
175 {
176 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
177 struct gl_client_array *tmp;
178 GLboolean is_writeable = 0;
179 GLubyte *data;
180
181 tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
182 stride ? sizeof(GLuint) : 0, writeable,
183 &is_writeable);
184
185 #if 0
186 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
187 #else
188 data = tmp->Ptr;
189 #endif
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;
196 if (!is_writeable)
197 inputs->Index.flags |= VEC_NOT_WRITEABLE;
198 }
199
200
201 static void _tnl_import_texcoord( GLcontext *ctx,
202 GLuint unit,
203 GLboolean writeable,
204 GLboolean stride )
205 {
206 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
207 struct gl_client_array *tmp;
208 GLboolean is_writeable = 0;
209 GLubyte *data;
210
211 tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
212 stride ? 4 * sizeof(GLfloat) : 0,
213 0,
214 writeable,
215 &is_writeable);
216
217 #if 0
218 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
219 #else
220 data = tmp->Ptr;
221 #endif
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;
229 if (!is_writeable)
230 inputs->TexCoord[unit].flags |= VEC_NOT_WRITEABLE;
231 }
232
233
234 static void _tnl_import_edgeflag( GLcontext *ctx,
235 GLboolean writeable,
236 GLboolean stride )
237 {
238 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
239 struct gl_client_array *tmp;
240 GLboolean is_writeable = 0;
241 GLubyte *data;
242
243 tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
244 stride ? sizeof(GLubyte) : 0,
245 0,
246 &is_writeable);
247
248 #if 0
249 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
250 #else
251 data = tmp->Ptr;
252 #endif
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;
259 if (!is_writeable)
260 inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE;
261 }
262
263
264
265 static void _tnl_import_attrib( GLcontext *ctx,
266 GLuint index,
267 GLboolean writeable,
268 GLboolean stride )
269 {
270 struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
271 struct gl_client_array *tmp;
272 GLboolean is_writeable = 0;
273 GLubyte *data;
274
275 tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
276 stride ? 4 * sizeof(GLfloat) : 0,
277 4, /* want GLfloat[4] */
278 writeable,
279 &is_writeable);
280
281 #if 0
282 data = ADD_POINTERS(tmp->Ptr, tmp->BufferObj->Data);
283 #else
284 data = tmp->Ptr;
285 #endif
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;
293 if (!is_writeable)
294 inputs->Attribs[index].flags |= VEC_NOT_WRITEABLE;
295 }
296
297
298
299 /**
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)
305 */
306 static void _tnl_upgrade_client_data( GLcontext *ctx,
307 GLuint required,
308 GLuint flags )
309 {
310 GLuint i;
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;
315 GLuint ca_flags = 0;
316 (void) inputs;
317
318 if (writeable || stride) ca_flags |= CA_CLIENT_DATA;
319
320 if ((required & VERT_BIT_CLIP) && VB->ClipPtr == VB->ObjPtr)
321 required |= VERT_BIT_POS;
322
323 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
324
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);
329 }
330
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;
335 }
336
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;
341 }
342
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;
348 }
349
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;
355 }
356
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;
361 }
362
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);
369 }
370
371 /* XXX not sure what to do here for vertex program arrays */
372 }
373
374
375
376 void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
377 {
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;
382
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); */
388
389 VB->Count = count - start;
390 VB->FirstClipped = VB->Count;
391 VB->Elts = NULL;
392 VB->MaterialMask = NULL;
393 VB->Material = NULL;
394 VB->Flag = 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;
399
400 if (ctx->Array.LockCount) {
401 ASSERT(start == (GLint) ctx->Array.LockFirst);
402 ASSERT(count == (GLint) ctx->Array.LockCount);
403 }
404
405 _ac_import_range( ctx, start, count );
406
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.
410 */
411 if (ctx->VertexProgram.Enabled) {
412 GLuint index;
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];
417 }
418 }
419
420 /*
421 * Conventional attributes
422 */
423 if (inputs & VERT_BIT_POS) {
424 _tnl_import_vertex( ctx, 0, 0 );
425 tmp->Obj.count = VB->Count;
426 VB->ObjPtr = &tmp->Obj;
427 }
428
429 if (inputs & VERT_BIT_NORMAL) {
430 _tnl_import_normal( ctx, 0, 0 );
431 tmp->Normal.count = VB->Count;
432 VB->NormalPtr = &tmp->Normal;
433 }
434
435 if (inputs & VERT_BIT_COLOR0) {
436 _tnl_import_color( ctx, 0, 0, 0 );
437 VB->ColorPtr[0] = &tmp->Color;
438 VB->ColorPtr[1] = 0;
439 }
440
441 if (inputs & VERT_BITS_TEX_ANY) {
442 GLuint unit;
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];
448 }
449 }
450 }
451
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;
458 VB->IndexPtr[1] = 0;
459 }
460
461 if (inputs & VERT_BIT_FOG) {
462 _tnl_import_fogcoord( ctx, 0, 0 );
463 tmp->FogCoord.count = VB->Count;
464 VB->FogCoordPtr = &tmp->FogCoord;
465 }
466
467 if (inputs & VERT_BIT_EDGEFLAG) {
468 _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
469 VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
470 }
471
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;
476 }
477 }
478 }