Subversion Repositories shark

Rev

Rev 135 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
135 giacomo 1
/* $Id: t_import_array.c,v 1.1 2003-04-24 14:24:01 giacomo Exp $ */
2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  4.1
6
 *
7
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
8
 *
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:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
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.
25
 *
26
 * Authors:
27
 *    Keith Whitwell <keith@tungstengraphics.com>
28
 */
29
 
30
#include "glheader.h"
31
#include "context.h"
32
#include "macros.h"
33
#include "imports.h"
34
#include "mmath.h"
35
#include "state.h"
36
#include "mtypes.h"
37
 
38
#include "array_cache/acache.h"
39
#include "math/m_translate.h"
40
 
41
#include "t_import_array.h"
42
#include "t_context.h"
43
#include "t_imm_debug.h"
44
 
45
 
46
static void _tnl_import_vertex( GLcontext *ctx,
47
                                GLboolean writeable,
48
                                GLboolean stride )
49
{
50
   struct gl_client_array *tmp;
51
   GLboolean is_writeable = 0;
52
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
53
 
54
   tmp = _ac_import_vertex(ctx,
55
                           GL_FLOAT,
56
                           stride ? 4*sizeof(GLfloat) : 0,
57
                           0,
58
                           writeable,
59
                           &is_writeable);
60
 
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;
68
   if (!is_writeable)
69
      inputs->Obj.flags |= VEC_NOT_WRITEABLE;
70
}
71
 
72
static void _tnl_import_normal( GLcontext *ctx,
73
                                GLboolean writeable,
74
                                GLboolean stride )
75
{
76
   struct gl_client_array *tmp;
77
   GLboolean is_writeable = 0;
78
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
79
 
80
   tmp = _ac_import_normal(ctx, GL_FLOAT,
81
                           stride ? 3*sizeof(GLfloat) : 0, writeable,
82
                           &is_writeable);
83
 
84
   inputs->Normal.data = (GLfloat (*)[4]) 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;
90
   if (!is_writeable)
91
      inputs->Normal.flags |= VEC_NOT_WRITEABLE;
92
}
93
 
94
 
95
static void _tnl_import_color( GLcontext *ctx,
96
                               GLenum type,
97
                               GLboolean writeable,
98
                               GLboolean stride )
99
{
100
   struct gl_client_array *tmp;
101
   GLboolean is_writeable = 0;
102
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
103
 
104
   tmp = _ac_import_color(ctx,
105
                          type,
106
                          stride ? 4*sizeof(GLfloat) : 0,
107
                          4,
108
                          writeable,
109
                          &is_writeable);
110
 
111
   inputs->Color = *tmp;
112
}
113
 
114
 
115
static void _tnl_import_secondarycolor( GLcontext *ctx,
116
                                        GLenum type,
117
                                        GLboolean writeable,
118
                                        GLboolean stride )
119
{
120
   struct gl_client_array *tmp;
121
   GLboolean is_writeable = 0;
122
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
123
 
124
   tmp = _ac_import_secondarycolor(ctx,
125
                                   type,
126
                                   stride ? 4*sizeof(GLfloat) : 0,
127
                                   4,
128
                                   writeable,
129
                                   &is_writeable);
130
 
131
   inputs->SecondaryColor = *tmp;
132
}
133
 
134
static void _tnl_import_fogcoord( GLcontext *ctx,
135
                                  GLboolean writeable,
136
                                  GLboolean stride )
137
{
138
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
139
    struct gl_client_array *tmp;
140
   GLboolean is_writeable = 0;
141
 
142
   tmp = _ac_import_fogcoord(ctx, GL_FLOAT,
143
                             stride ? sizeof(GLfloat) : 0, writeable,
144
                             &is_writeable);
145
 
146
   inputs->FogCoord.data = (GLfloat (*)[4]) 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;
152
   if (!is_writeable)
153
      inputs->FogCoord.flags |= VEC_NOT_WRITEABLE;
154
}
155
 
156
static void _tnl_import_index( GLcontext *ctx,
157
                               GLboolean writeable,
158
                               GLboolean stride )
159
{
160
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
161
   struct gl_client_array *tmp;
162
   GLboolean is_writeable = 0;
163
 
164
   tmp = _ac_import_index(ctx, GL_UNSIGNED_INT,
165
                          stride ? sizeof(GLuint) : 0, writeable,
166
                          &is_writeable);
167
 
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;
174
   if (!is_writeable)
175
      inputs->Index.flags |= VEC_NOT_WRITEABLE;
176
}
177
 
178
 
179
static void _tnl_import_texcoord( GLcontext *ctx,
180
                                  GLuint unit,
181
                                  GLboolean writeable,
182
                                  GLboolean stride )
183
{
184
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
185
   struct gl_client_array *tmp;
186
   GLboolean is_writeable = 0;
187
 
188
   tmp = _ac_import_texcoord(ctx, unit, GL_FLOAT,
189
                             stride ? 4 * sizeof(GLfloat) : 0,
190
                             0,
191
                             writeable,
192
                             &is_writeable);
193
 
194
   inputs->TexCoord[unit].data = (GLfloat (*)[4]) tmp->Ptr;
195
   inputs->TexCoord[unit].start = (GLfloat *) tmp->Ptr;
196
   inputs->TexCoord[unit].stride = tmp->StrideB;
197
   inputs->TexCoord[unit].size = tmp->Size;
198
   inputs->TexCoord[unit].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
199
   if (inputs->TexCoord[unit].stride != 4*sizeof(GLfloat))
200
      inputs->TexCoord[unit].flags |= VEC_BAD_STRIDE;
201
   if (!is_writeable)
202
      inputs->TexCoord[unit].flags |= VEC_NOT_WRITEABLE;
203
}
204
 
205
 
206
static void _tnl_import_edgeflag( GLcontext *ctx,
207
                                  GLboolean writeable,
208
                                  GLboolean stride )
209
{
210
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
211
   struct gl_client_array *tmp;
212
   GLboolean is_writeable = 0;
213
 
214
   tmp = _ac_import_edgeflag(ctx, GL_UNSIGNED_BYTE,
215
                             stride ? sizeof(GLubyte) : 0,
216
                             0,
217
                             &is_writeable);
218
 
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;
225
   if (!is_writeable)
226
      inputs->EdgeFlag.flags |= VEC_NOT_WRITEABLE;
227
}
228
 
229
 
230
 
231
static void _tnl_import_attrib( GLcontext *ctx,
232
                                GLuint index,
233
                                GLboolean writeable,
234
                                GLboolean stride )
235
{
236
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
237
   struct gl_client_array *tmp;
238
   GLboolean is_writeable = 0;
239
 
240
   tmp = _ac_import_attrib(ctx, index, GL_FLOAT,
241
                           stride ? 4 * sizeof(GLfloat) : 0,
242
                           4,  /* want GLfloat[4] */
243
                           writeable,
244
                           &is_writeable);
245
 
246
   inputs->Attribs[index].data = (GLfloat (*)[4]) tmp->Ptr;
247
   inputs->Attribs[index].start = (GLfloat *) tmp->Ptr;
248
   inputs->Attribs[index].stride = tmp->StrideB;
249
   inputs->Attribs[index].size = tmp->Size;
250
   inputs->Attribs[index].flags &= ~(VEC_BAD_STRIDE|VEC_NOT_WRITEABLE);
251
   if (inputs->Attribs[index].stride != 4 * sizeof(GLfloat))
252
      inputs->Attribs[index].flags |= VEC_BAD_STRIDE;
253
   if (!is_writeable)
254
      inputs->Attribs[index].flags |= VEC_NOT_WRITEABLE;
255
}
256
 
257
 
258
 
259
/**
260
 * Callback for VB stages that need to improve the quality of arrays
261
 * bound to the VB.  This is only necessary for client arrays which
262
 * have not been transformed at any point in the pipeline.
263
 * \param required - bitmask of VERT_*_BIT flags
264
 * \param flags - bitmask of VEC_* flags (ex: VEC_NOT_WRITABLE)
265
 */
266
static void _tnl_upgrade_client_data( GLcontext *ctx,
267
                                      GLuint required,
268
                                      GLuint flags )
269
{
270
   GLuint i;
271
   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
272
   GLboolean writeable = (flags & VEC_NOT_WRITEABLE) != 0;
273
   GLboolean stride = (flags & VEC_BAD_STRIDE) != 0;
274
   struct vertex_arrays *inputs = &TNL_CONTEXT(ctx)->array_inputs;
275
   GLuint ca_flags = 0;
276
   (void) inputs;
277
 
278
   if (writeable || stride) ca_flags |= CA_CLIENT_DATA;
279
 
280
   if ((required & VERT_BIT_CLIP) && VB->ClipPtr == VB->ObjPtr)
281
      required |= VERT_BIT_POS;
282
 
283
/*     _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
284
 
285
   if ((required & VERT_BIT_POS) && (VB->ObjPtr->flags & flags)) {
286
      ASSERT(VB->ObjPtr == &inputs->Obj);
287
      _tnl_import_vertex( ctx, writeable, stride );
288
      VB->importable_data &= ~(VERT_BIT_POS|VERT_BIT_CLIP);
289
   }
290
 
291
   if ((required & VERT_BIT_NORMAL) && (VB->NormalPtr->flags & flags)) {
292
      ASSERT(VB->NormalPtr == &inputs->Normal);
293
      _tnl_import_normal( ctx, writeable, stride );
294
      VB->importable_data &= ~VERT_BIT_NORMAL;
295
   }
296
 
297
   if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & ca_flags)) {
298
      ASSERT(VB->ColorPtr[0] == &inputs->Color);
299
      _tnl_import_color( ctx, GL_FLOAT, writeable, stride );
300
      VB->importable_data &= ~VERT_BIT_COLOR0;
301
   }
302
 
303
   if ((required & VERT_BIT_COLOR1) &&
304
       (VB->SecondaryColorPtr[0]->Flags & ca_flags)) {
305
      ASSERT(VB->SecondaryColorPtr[0] == &inputs->SecondaryColor);
306
      _tnl_import_secondarycolor( ctx, GL_FLOAT, writeable, stride );
307
      VB->importable_data &= ~VERT_BIT_COLOR1;
308
   }
309
 
310
   if ((required & VERT_BIT_FOG)
311
       && (VB->FogCoordPtr->flags & flags)) {
312
      ASSERT(VB->FogCoordPtr == &inputs->FogCoord);
313
      _tnl_import_fogcoord( ctx, writeable, stride );
314
      VB->importable_data &= ~VERT_BIT_FOG;
315
   }
316
 
317
   if ((required & VERT_BIT_INDEX) && (VB->IndexPtr[0]->flags & flags)) {
318
      ASSERT(VB->IndexPtr[0] == &inputs->Index);
319
      _tnl_import_index( ctx, writeable, stride );
320
      VB->importable_data &= ~VERT_BIT_INDEX;
321
   }
322
 
323
   if (required & VERT_BITS_TEX_ANY)
324
      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
325
         if ((required & VERT_BIT_TEX(i)) && (VB->TexCoordPtr[i]->flags & flags)) {
326
            ASSERT(VB->TexCoordPtr[i] == &inputs->TexCoord[i]);
327
            _tnl_import_texcoord( ctx, i, writeable, stride );
328
            VB->importable_data &= ~VERT_BIT_TEX(i);
329
         }
330
 
331
   /* XXX not sure what to do here for vertex program arrays */
332
}
333
 
334
 
335
 
336
void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLsizei count )
337
{
338
   TNLcontext *tnl = TNL_CONTEXT(ctx);
339
   struct vertex_buffer *VB = &tnl->vb;
340
   GLuint inputs = tnl->pipeline.inputs;
341
   struct vertex_arrays *tmp = &tnl->array_inputs;
342
 
343
/*        _mesa_debug(ctx, "%s %d..%d // %d..%d\n", __FUNCTION__, */
344
/*            start, count, ctx->Array.LockFirst, ctx->Array.LockCount);  */
345
/*        _tnl_print_vert_flags("    inputs", inputs);  */
346
/*        _tnl_print_vert_flags("    _Enabled", ctx->Array._Enabled); */
347
/*        _tnl_print_vert_flags("    importable", inputs & VERT_BITS_FIXUP); */
348
 
349
   VB->Count = count - start;
350
   VB->FirstClipped = VB->Count;
351
   VB->Elts = NULL;
352
   VB->MaterialMask = NULL;
353
   VB->Material = NULL;
354
   VB->Flag = NULL;
355
   VB->Primitive = tnl->tmp_primitive;
356
   VB->PrimitiveLength = tnl->tmp_primitive_length;
357
   VB->import_data = _tnl_upgrade_client_data;
358
   VB->importable_data = inputs & VERT_BITS_FIXUP;
359
 
360
   if (ctx->Array.LockCount) {
361
      ASSERT(start == (GLint) ctx->Array.LockFirst);
362
      ASSERT(count == (GLint) ctx->Array.LockCount);
363
   }
364
 
365
   _ac_import_range( ctx, start, count );
366
 
367
   if (inputs & VERT_BIT_POS) {
368
      _tnl_import_vertex( ctx, 0, 0 );
369
      tmp->Obj.count = VB->Count;
370
      VB->ObjPtr = &tmp->Obj;
371
   }
372
 
373
   if (inputs & VERT_BIT_NORMAL) {
374
      _tnl_import_normal( ctx, 0, 0 );
375
      tmp->Normal.count = VB->Count;
376
      VB->NormalPtr = &tmp->Normal;
377
   }
378
 
379
   if (inputs & VERT_BIT_COLOR0) {
380
      _tnl_import_color( ctx, 0, 0, 0 );
381
      VB->ColorPtr[0] = &tmp->Color;
382
      VB->ColorPtr[1] = 0;
383
   }
384
 
385
   if (inputs & VERT_BITS_TEX_ANY) {
386
      GLuint unit;
387
      for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
388
         if (inputs & VERT_BIT_TEX(unit)) {
389
            _tnl_import_texcoord( ctx, unit, GL_FALSE, GL_FALSE );
390
            tmp->TexCoord[unit].count = VB->Count;
391
            VB->TexCoordPtr[unit] = &tmp->TexCoord[unit];
392
         }
393
      }
394
   }
395
 
396
   if (inputs & (VERT_BIT_INDEX | VERT_BIT_FOG |
397
                 VERT_BIT_EDGEFLAG | VERT_BIT_COLOR1)) {
398
      if (inputs & VERT_BIT_INDEX) {
399
         _tnl_import_index( ctx, 0, 0 );
400
         tmp->Index.count = VB->Count;
401
         VB->IndexPtr[0] = &tmp->Index;
402
         VB->IndexPtr[1] = 0;
403
      }
404
 
405
      if (inputs & VERT_BIT_FOG) {
406
         _tnl_import_fogcoord( ctx, 0, 0 );
407
         tmp->FogCoord.count = VB->Count;
408
         VB->FogCoordPtr = &tmp->FogCoord;
409
      }
410
 
411
      if (inputs & VERT_BIT_EDGEFLAG) {
412
         _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
413
         VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag.data;
414
      }
415
 
416
      if (inputs & VERT_BIT_COLOR1) {
417
         _tnl_import_secondarycolor( ctx, 0, 0, 0 );
418
         VB->SecondaryColorPtr[0] = &tmp->SecondaryColor;
419
         VB->SecondaryColorPtr[1] = 0;
420
      }
421
   }
422
 
423
   /* XXX not 100% sure this is finished.  Keith should probably inspect. */
424
   if (ctx->VertexProgram.Enabled) {
425
      GLuint index;
426
      for (index = 0; index < VERT_ATTRIB_MAX; index++) {
427
         /* XXX check program->InputsRead to reduce work here */
428
         _tnl_import_attrib( ctx, index, GL_FALSE, GL_TRUE );
429
         VB->AttribPtr[index] = &tmp->Attribs[index];
430
      }
431
   }
432
}