Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
57 pj 1
/* $Id: ac_import.c,v 1.1 2003-02-28 11:49:40 pj 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 "macros.h"
32
#include "imports.h"
33
#include "mmath.h"
34
#include "mtypes.h"
35
 
36
#include "math/m_translate.h"
37
#include "array_cache/ac_context.h"
38
#include "math/m_translate.h"
39
 
40
#define STRIDE_ARRAY( array, offset )           \
41
do {                                            \
42
   char *tmp = (char *) (array).Ptr;            \
43
   tmp += (offset) * (array).StrideB;           \
44
   (array).Ptr = tmp;                           \
45
} while (0)
46
 
47
/* Set the array pointer back to its source when the cached data is
48
 * invalidated:
49
 */
50
 
51
static void reset_texcoord( GLcontext *ctx, GLuint unit )
52
{
53
   ACcontext *ac = AC_CONTEXT(ctx);
54
 
55
   if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) {
56
      ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
57
      STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
58
   }
59
   else {
60
      ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
61
 
62
      if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0)
63
         ac->Raw.TexCoord[unit].Size = 4;
64
      else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0)
65
         ac->Raw.TexCoord[unit].Size = 3;
66
      else
67
         ac->Raw.TexCoord[unit].Size = 2;
68
   }
69
 
70
   ac->IsCached.TexCoord[unit] = GL_FALSE;
71
   ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
72
}
73
 
74
static void reset_vertex( GLcontext *ctx )
75
{
76
   ACcontext *ac = AC_CONTEXT(ctx);
77
   ASSERT(ctx->Array.Vertex.Enabled
78
          || (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled));
79
   ac->Raw.Vertex = ctx->Array.Vertex;
80
   STRIDE_ARRAY(ac->Raw.Vertex, ac->start);
81
   ac->IsCached.Vertex = GL_FALSE;
82
   ac->NewArrayState &= ~_NEW_ARRAY_VERTEX;
83
}
84
 
85
 
86
static void reset_normal( GLcontext *ctx )
87
{
88
   ACcontext *ac = AC_CONTEXT(ctx);
89
 
90
   if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) {
91
      ac->Raw.Normal = ctx->Array.Normal;
92
      STRIDE_ARRAY(ac->Raw.Normal, ac->start);
93
   }
94
   else {
95
      ac->Raw.Normal = ac->Fallback.Normal;
96
   }
97
 
98
   ac->IsCached.Normal = GL_FALSE;
99
   ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
100
}
101
 
102
 
103
static void reset_color( GLcontext *ctx )
104
{
105
   ACcontext *ac = AC_CONTEXT(ctx);
106
 
107
 
108
   if (ctx->Array._Enabled & _NEW_ARRAY_COLOR0) {
109
      ac->Raw.Color = ctx->Array.Color;
110
      STRIDE_ARRAY(ac->Raw.Color, ac->start);
111
   }
112
   else
113
      ac->Raw.Color = ac->Fallback.Color;
114
 
115
   ac->IsCached.Color = GL_FALSE;
116
   ac->NewArrayState &= ~_NEW_ARRAY_COLOR0;
117
}
118
 
119
 
120
static void reset_secondarycolor( GLcontext *ctx )
121
{
122
   ACcontext *ac = AC_CONTEXT(ctx);
123
 
124
   if (ctx->Array._Enabled & _NEW_ARRAY_COLOR1) {
125
      ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
126
      STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
127
   }
128
   else
129
      ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
130
 
131
   ac->IsCached.SecondaryColor = GL_FALSE;
132
   ac->NewArrayState &= ~_NEW_ARRAY_COLOR1;
133
}
134
 
135
 
136
static void reset_index( GLcontext *ctx )
137
{
138
   ACcontext *ac = AC_CONTEXT(ctx);
139
 
140
   if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) {
141
      ac->Raw.Index = ctx->Array.Index;
142
      STRIDE_ARRAY(ac->Raw.Index, ac->start);
143
   }
144
   else
145
      ac->Raw.Index = ac->Fallback.Index;
146
 
147
   ac->IsCached.Index = GL_FALSE;
148
   ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
149
}
150
 
151
 
152
static void reset_fogcoord( GLcontext *ctx )
153
{
154
   ACcontext *ac = AC_CONTEXT(ctx);
155
 
156
   if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) {
157
      ac->Raw.FogCoord = ctx->Array.FogCoord;
158
      STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
159
   }
160
   else
161
      ac->Raw.FogCoord = ac->Fallback.FogCoord;
162
 
163
   ac->IsCached.FogCoord = GL_FALSE;
164
   ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
165
}
166
 
167
 
168
static void reset_edgeflag( GLcontext *ctx )
169
{
170
   ACcontext *ac = AC_CONTEXT(ctx);
171
 
172
   if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) {
173
      ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
174
      STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
175
   }
176
   else
177
      ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
178
 
179
   ac->IsCached.EdgeFlag = GL_FALSE;
180
   ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
181
}
182
 
183
 
184
static void reset_attrib( GLcontext *ctx, GLuint index )
185
{
186
   ACcontext *ac = AC_CONTEXT(ctx);
187
   GLboolean fallback = GL_FALSE;
188
 
189
   /*
190
    * The 16 NV vertex attribute arrays have top priority.  If one of those
191
    * is not enabled, look if a corresponding conventional array is enabled.
192
    * If nothing else, use the fallback (ctx->Current.Attrib) values.
193
    */
194
   if (ctx->Array._Enabled & _NEW_ARRAY_ATTRIB(index)) {
195
      ac->Raw.Attrib[index] = ctx->Array.VertexAttrib[index];
196
      STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
197
   }
198
   else if (ctx->Array._Enabled & (1 << index)) {
199
      /* use conventional vertex array if possible */
200
      if (index == VERT_ATTRIB_POS) {
201
         ac->Raw.Attrib[index] = ctx->Array.Vertex;
202
      }
203
      else if (index == VERT_ATTRIB_NORMAL) {
204
         ac->Raw.Attrib[index] = ctx->Array.Normal;
205
      }
206
      else if (index == VERT_ATTRIB_COLOR0) {
207
         ac->Raw.Attrib[index] = ctx->Array.Color;
208
      }
209
      else if (index == VERT_ATTRIB_COLOR1) {
210
         ac->Raw.Attrib[index] = ctx->Array.SecondaryColor;
211
      }
212
      else if (index == VERT_ATTRIB_FOG) {
213
         ac->Raw.Attrib[index] = ctx->Array.FogCoord;
214
      }
215
      else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
216
         GLuint unit = index - VERT_ATTRIB_TEX0;
217
         ASSERT(unit < MAX_TEXTURE_UNITS);
218
         ac->Raw.Attrib[index] = ctx->Array.TexCoord[unit];
219
      }
220
      else {
221
         /* missing conventional array (vertex weight, for example) */
222
         fallback = GL_TRUE;
223
      }
224
      if (!fallback)
225
         STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
226
   }
227
   else {
228
      fallback = GL_TRUE;
229
   }
230
 
231
   if (fallback) {
232
      /* fallback to ctx->Current.Attrib values */
233
      ac->Raw.Attrib[index] = ac->Fallback.Attrib[index];
234
 
235
      if (ctx->Current.Attrib[index][3] != 1.0)
236
         ac->Raw.Attrib[index].Size = 4;
237
      else if (ctx->Current.Attrib[index][2] != 0.0)
238
         ac->Raw.Attrib[index].Size = 3;
239
      else
240
         ac->Raw.Attrib[index].Size = 2;
241
   }
242
 
243
   ac->IsCached.Attrib[index] = GL_FALSE;
244
   ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index);
245
}
246
 
247
 
248
/*
249
 * Generic import function for color data
250
 */
251
static void import( GLcontext *ctx,
252
                    GLenum type,
253
                    struct gl_client_array *to,
254
                    struct gl_client_array *from )
255
{
256
   ACcontext *ac = AC_CONTEXT(ctx);
257
 
258
   if (type == 0)
259
      type = from->Type;
260
 
261
   switch (type) {
262
   case GL_FLOAT:
263
      _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
264
                      from->Ptr,
265
                      from->StrideB,
266
                      from->Type,
267
                      from->Size,
268
                      0,
269
                      ac->count - ac->start);
270
 
271
      to->StrideB = 4 * sizeof(GLfloat);
272
      to->Type = GL_FLOAT;
273
      break;
274
 
275
   case GL_UNSIGNED_BYTE:
276
      _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
277
                       from->Ptr,
278
                       from->StrideB,
279
                       from->Type,
280
                       from->Size,
281
                       0,
282
                       ac->count - ac->start);
283
 
284
      to->StrideB = 4 * sizeof(GLubyte);
285
      to->Type = GL_UNSIGNED_BYTE;
286
      break;
287
 
288
   case GL_UNSIGNED_SHORT:
289
      _math_trans_4us( (GLushort (*)[4]) to->Ptr,
290
                       from->Ptr,
291
                       from->StrideB,
292
                       from->Type,
293
                       from->Size,
294
                       0,
295
                       ac->count - ac->start);
296
 
297
      to->StrideB = 4 * sizeof(GLushort);
298
      to->Type = GL_UNSIGNED_SHORT;
299
      break;
300
 
301
   default:
302
      ASSERT(0);
303
      break;
304
   }
305
}
306
 
307
 
308
 
309
/*
310
 * Functions to import array ranges with specified types and strides.
311
 * For example, if the vertex data is GLshort[2] and we want GLfloat[3]
312
 * we'll use an import function to do the data conversion.
313
 */
314
 
315
static void import_texcoord( GLcontext *ctx, GLuint unit,
316
                             GLenum type, GLuint stride )
317
{
318
   ACcontext *ac = AC_CONTEXT(ctx);
319
   struct gl_client_array *from = &ac->Raw.TexCoord[unit];
320
   struct gl_client_array *to = &ac->Cache.TexCoord[unit];
321
 
322
   ASSERT(unit < ctx->Const.MaxTextureUnits);
323
 
324
   /* Limited choices at this stage:
325
    */
326
   ASSERT(type == GL_FLOAT);
327
   ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
328
   ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
329
 
330
   _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
331
                   from->Ptr,
332
                   from->StrideB,
333
                   from->Type,
334
                   from->Size,
335
                   0,
336
                   ac->count - ac->start);
337
 
338
   to->Size = from->Size;
339
   to->StrideB = 4 * sizeof(GLfloat);
340
   to->Type = GL_FLOAT;
341
   ac->IsCached.TexCoord[unit] = GL_TRUE;
342
}
343
 
344
static void import_vertex( GLcontext *ctx,
345
                           GLenum type, GLuint stride )
346
{
347
   ACcontext *ac = AC_CONTEXT(ctx);
348
   struct gl_client_array *from = &ac->Raw.Vertex;
349
   struct gl_client_array *to = &ac->Cache.Vertex;
350
 
351
   /* Limited choices at this stage:
352
    */
353
   ASSERT(type == GL_FLOAT);
354
   ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
355
 
356
   _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
357
                   from->Ptr,
358
                   from->StrideB,
359
                   from->Type,
360
                   from->Size,
361
                   0,
362
                   ac->count - ac->start);
363
 
364
   to->Size = from->Size;
365
   to->StrideB = 4 * sizeof(GLfloat);
366
   to->Type = GL_FLOAT;
367
   ac->IsCached.Vertex = GL_TRUE;
368
}
369
 
370
static void import_normal( GLcontext *ctx,
371
                           GLenum type, GLuint stride )
372
{
373
   ACcontext *ac = AC_CONTEXT(ctx);
374
   struct gl_client_array *from = &ac->Raw.Normal;
375
   struct gl_client_array *to = &ac->Cache.Normal;
376
 
377
   /* Limited choices at this stage:
378
    */
379
   ASSERT(type == GL_FLOAT);
380
   ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
381
 
382
   _math_trans_3f( (GLfloat (*)[3]) to->Ptr,
383
                   from->Ptr,
384
                   from->StrideB,
385
                   from->Type,
386
                   0,
387
                   ac->count - ac->start);
388
 
389
   to->StrideB = 3 * sizeof(GLfloat);
390
   to->Type = GL_FLOAT;
391
   ac->IsCached.Normal = GL_TRUE;
392
}
393
 
394
static void import_color( GLcontext *ctx,
395
                          GLenum type, GLuint stride )
396
{
397
   ACcontext *ac = AC_CONTEXT(ctx);
398
   struct gl_client_array *from = &ac->Raw.Color;
399
   struct gl_client_array *to = &ac->Cache.Color;
400
 
401
   import( ctx, type, to, from );
402
 
403
   ac->IsCached.Color = GL_TRUE;
404
}
405
 
406
static void import_index( GLcontext *ctx,
407
                          GLenum type, GLuint stride )
408
{
409
   ACcontext *ac = AC_CONTEXT(ctx);
410
   struct gl_client_array *from = &ac->Raw.Index;
411
   struct gl_client_array *to = &ac->Cache.Index;
412
 
413
   /* Limited choices at this stage:
414
    */
415
   ASSERT(type == GL_UNSIGNED_INT);
416
   ASSERT(stride == sizeof(GLuint) || stride == 0);
417
 
418
   _math_trans_1ui( (GLuint *) to->Ptr,
419
                    from->Ptr,
420
                    from->StrideB,
421
                    from->Type,
422
                    0,
423
                    ac->count - ac->start);
424
 
425
   to->StrideB = sizeof(GLuint);
426
   to->Type = GL_UNSIGNED_INT;
427
   ac->IsCached.Index = GL_TRUE;
428
}
429
 
430
static void import_secondarycolor( GLcontext *ctx,
431
                                   GLenum type, GLuint stride )
432
{
433
   ACcontext *ac = AC_CONTEXT(ctx);
434
   struct gl_client_array *from = &ac->Raw.SecondaryColor;
435
   struct gl_client_array *to = &ac->Cache.SecondaryColor;
436
 
437
   import( ctx, type, to, from );
438
 
439
   ac->IsCached.SecondaryColor = GL_TRUE;
440
}
441
 
442
static void import_fogcoord( GLcontext *ctx,
443
                             GLenum type, GLuint stride )
444
{
445
   ACcontext *ac = AC_CONTEXT(ctx);
446
   struct gl_client_array *from = &ac->Raw.FogCoord;
447
   struct gl_client_array *to = &ac->Cache.FogCoord;
448
 
449
   /* Limited choices at this stage:
450
    */
451
   ASSERT(type == GL_FLOAT);
452
   ASSERT(stride == sizeof(GLfloat) || stride == 0);
453
 
454
   _math_trans_1f( (GLfloat *) to->Ptr,
455
                   from->Ptr,
456
                   from->StrideB,
457
                   from->Type,
458
                   0,
459
                   ac->count - ac->start);
460
 
461
   to->StrideB = sizeof(GLfloat);
462
   to->Type = GL_FLOAT;
463
   ac->IsCached.FogCoord = GL_TRUE;
464
}
465
 
466
static void import_edgeflag( GLcontext *ctx,
467
                             GLenum type, GLuint stride )
468
{
469
   ACcontext *ac = AC_CONTEXT(ctx);
470
   struct gl_client_array *from = &ac->Raw.EdgeFlag;
471
   struct gl_client_array *to = &ac->Cache.EdgeFlag;
472
 
473
   /* Limited choices at this stage:
474
    */
475
   ASSERT(type == GL_UNSIGNED_BYTE);
476
   ASSERT(stride == sizeof(GLubyte) || stride == 0);
477
 
478
   _math_trans_1ub( (GLubyte *) to->Ptr,
479
                    from->Ptr,
480
                    from->StrideB,
481
                    from->Type,
482
                    0,
483
                    ac->count - ac->start);
484
 
485
   to->StrideB = sizeof(GLubyte);
486
   to->Type = GL_UNSIGNED_BYTE;
487
   ac->IsCached.EdgeFlag = GL_TRUE;
488
}
489
 
490
static void import_attrib( GLcontext *ctx, GLuint index,
491
                           GLenum type, GLuint stride )
492
{
493
   ACcontext *ac = AC_CONTEXT(ctx);
494
   struct gl_client_array *from = &ac->Raw.Attrib[index];
495
   struct gl_client_array *to = &ac->Cache.Attrib[index];
496
 
497
   ASSERT(index < VERT_ATTRIB_MAX);
498
 
499
   /* Limited choices at this stage:
500
    */
501
   ASSERT(type == GL_FLOAT);
502
   ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
503
   ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
504
 
505
   _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
506
                   from->Ptr,
507
                   from->StrideB,
508
                   from->Type,
509
                   from->Size,
510
                   0,
511
                   ac->count - ac->start);
512
 
513
   to->Size = from->Size;
514
   to->StrideB = 4 * sizeof(GLfloat);
515
   to->Type = GL_FLOAT;
516
   ac->IsCached.Attrib[index] = GL_TRUE;
517
}
518
 
519
 
520
 
521
/*
522
 * Externals to request arrays with specific properties:
523
 */
524
 
525
 
526
struct gl_client_array *_ac_import_texcoord( GLcontext *ctx,
527
                                             GLuint unit,
528
                                             GLenum type,
529
                                             GLuint reqstride,
530
                                             GLuint reqsize,
531
                                             GLboolean reqwriteable,
532
                                             GLboolean *writeable )
533
{
534
   ACcontext *ac = AC_CONTEXT(ctx);
535
 
536
   ASSERT(unit < ctx->Const.MaxTextureUnits);
537
 
538
   /* Can we keep the existing version?
539
    */
540
   if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
541
      reset_texcoord( ctx, unit );
542
 
543
   /* Is the request impossible?
544
    */
545
   if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize)
546
      return 0;
547
 
548
   /* Do we need to pull in a copy of the client data:
549
    */
550
   if (ac->Raw.TexCoord[unit].Type != type ||
551
       (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) ||
552
       reqwriteable)
553
   {
554
      if (!ac->IsCached.TexCoord[unit])
555
         import_texcoord(ctx, unit, type, reqstride );
556
      *writeable = GL_TRUE;
557
      return &ac->Cache.TexCoord[unit];
558
   }
559
   else {
560
      *writeable = GL_FALSE;
561
      return &ac->Raw.TexCoord[unit];
562
   }
563
}
564
 
565
struct gl_client_array *_ac_import_vertex( GLcontext *ctx,
566
                                           GLenum type,
567
                                           GLuint reqstride,
568
                                           GLuint reqsize,
569
                                           GLboolean reqwriteable,
570
                                           GLboolean *writeable )
571
{
572
   ACcontext *ac = AC_CONTEXT(ctx);
573
 
574
   /* Can we keep the existing version?
575
    */
576
   if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
577
      reset_vertex( ctx );
578
 
579
   /* Is the request impossible?
580
    */
581
   if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize)
582
      return 0;
583
 
584
   /* Do we need to pull in a copy of the client data:
585
    */
586
   if (ac->Raw.Vertex.Type != type ||
587
       (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) ||
588
       reqwriteable)
589
   {
590
      if (!ac->IsCached.Vertex)
591
         import_vertex(ctx, type, reqstride );
592
      *writeable = GL_TRUE;
593
      return &ac->Cache.Vertex;
594
   }
595
   else {
596
      *writeable = GL_FALSE;
597
      return &ac->Raw.Vertex;
598
   }
599
}
600
 
601
struct gl_client_array *_ac_import_normal( GLcontext *ctx,
602
                                           GLenum type,
603
                                           GLuint reqstride,
604
                                           GLboolean reqwriteable,
605
                                           GLboolean *writeable )
606
{
607
   ACcontext *ac = AC_CONTEXT(ctx);
608
 
609
   /* Can we keep the existing version?
610
    */
611
   if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
612
      reset_normal( ctx );
613
 
614
   /* Do we need to pull in a copy of the client data:
615
    */
616
   if (ac->Raw.Normal.Type != type ||
617
       (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) ||
618
       reqwriteable)
619
   {
620
      if (!ac->IsCached.Normal)
621
         import_normal(ctx, type, reqstride );
622
      *writeable = GL_TRUE;
623
      return &ac->Cache.Normal;
624
   }
625
   else {
626
      *writeable = GL_FALSE;
627
      return &ac->Raw.Normal;
628
   }
629
}
630
 
631
struct gl_client_array *_ac_import_color( GLcontext *ctx,
632
                                          GLenum type,
633
                                          GLuint reqstride,
634
                                          GLuint reqsize,
635
                                          GLboolean reqwriteable,
636
                                          GLboolean *writeable )
637
{
638
   ACcontext *ac = AC_CONTEXT(ctx);
639
 
640
   /* Can we keep the existing version?
641
    */
642
   if (ac->NewArrayState & _NEW_ARRAY_COLOR0)
643
      reset_color( ctx );
644
 
645
   /* Is the request impossible?
646
    */
647
   if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) {
648
      return 0;
649
   }
650
 
651
   /* Do we need to pull in a copy of the client data:
652
    */
653
   if ((type != 0 && ac->Raw.Color.Type != type) ||
654
       (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) ||
655
       reqwriteable)
656
   {
657
      if (!ac->IsCached.Color)
658
         import_color(ctx, type, reqstride );
659
      *writeable = GL_TRUE;
660
      return &ac->Cache.Color;
661
   }
662
   else {
663
      *writeable = GL_FALSE;
664
      return &ac->Raw.Color;
665
   }
666
}
667
 
668
struct gl_client_array *_ac_import_index( GLcontext *ctx,
669
                                          GLenum type,
670
                                          GLuint reqstride,
671
                                          GLboolean reqwriteable,
672
                                          GLboolean *writeable )
673
{
674
   ACcontext *ac = AC_CONTEXT(ctx);
675
 
676
   /* Can we keep the existing version?
677
    */
678
   if (ac->NewArrayState & _NEW_ARRAY_INDEX)
679
      reset_index( ctx );
680
 
681
 
682
   /* Do we need to pull in a copy of the client data:
683
    */
684
   if (ac->Raw.Index.Type != type ||
685
       (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) ||
686
       reqwriteable)
687
   {
688
      if (!ac->IsCached.Index)
689
         import_index(ctx, type, reqstride );
690
      *writeable = GL_TRUE;
691
      return &ac->Cache.Index;
692
   }
693
   else {
694
      *writeable = GL_FALSE;
695
      return &ac->Raw.Index;
696
   }
697
}
698
 
699
struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx,
700
                                                   GLenum type,
701
                                                   GLuint reqstride,
702
                                                   GLuint reqsize,
703
                                                   GLboolean reqwriteable,
704
                                                   GLboolean *writeable )
705
{
706
   ACcontext *ac = AC_CONTEXT(ctx);
707
 
708
   /* Can we keep the existing version?
709
    */
710
   if (ac->NewArrayState & _NEW_ARRAY_COLOR1)
711
      reset_secondarycolor( ctx );
712
 
713
   /* Is the request impossible?
714
    */
715
   if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize)
716
      return 0;
717
 
718
   /* Do we need to pull in a copy of the client data:
719
    */
720
   if ((type != 0 && ac->Raw.SecondaryColor.Type != type) ||
721
       (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) ||
722
       reqwriteable)
723
   {
724
      if (!ac->IsCached.SecondaryColor)
725
         import_secondarycolor(ctx, type, reqstride );
726
      *writeable = GL_TRUE;
727
      return &ac->Cache.SecondaryColor;
728
   }
729
   else {
730
      *writeable = GL_FALSE;
731
      return &ac->Raw.SecondaryColor;
732
   }
733
}
734
 
735
struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx,
736
                                             GLenum type,
737
                                             GLuint reqstride,
738
                                             GLboolean reqwriteable,
739
                                             GLboolean *writeable )
740
{
741
   ACcontext *ac = AC_CONTEXT(ctx);
742
 
743
   /* Can we keep the existing version?
744
    */
745
   if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
746
      reset_fogcoord( ctx );
747
 
748
   /* Do we need to pull in a copy of the client data:
749
    */
750
   if (ac->Raw.FogCoord.Type != type ||
751
       (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) ||
752
       reqwriteable)
753
   {
754
      if (!ac->IsCached.FogCoord)
755
         import_fogcoord(ctx, type, reqstride );
756
      *writeable = GL_TRUE;
757
      return &ac->Cache.FogCoord;
758
   }
759
   else {
760
      *writeable = GL_FALSE;
761
      return &ac->Raw.FogCoord;
762
   }
763
}
764
 
765
struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx,
766
                                             GLenum type,
767
                                             GLuint reqstride,
768
                                             GLboolean reqwriteable,
769
                                             GLboolean *writeable )
770
{
771
   ACcontext *ac = AC_CONTEXT(ctx);
772
 
773
   /* Can we keep the existing version?
774
    */
775
   if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
776
      reset_edgeflag( ctx );
777
 
778
   /* Do we need to pull in a copy of the client data:
779
    */
780
   if (ac->Raw.EdgeFlag.Type != type ||
781
       (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) ||
782
       reqwriteable)
783
   {
784
      if (!ac->IsCached.EdgeFlag)
785
         import_edgeflag(ctx, type, reqstride );
786
      *writeable = GL_TRUE;
787
      return &ac->Cache.EdgeFlag;
788
   }
789
   else {
790
      *writeable = GL_FALSE;
791
      return &ac->Raw.EdgeFlag;
792
   }
793
}
794
 
795
/* GL_NV_vertex_program */
796
struct gl_client_array *_ac_import_attrib( GLcontext *ctx,
797
                                           GLuint index,
798
                                           GLenum type,
799
                                           GLuint reqstride,
800
                                           GLuint reqsize,
801
                                           GLboolean reqwriteable,
802
                                           GLboolean *writeable )
803
{
804
   ACcontext *ac = AC_CONTEXT(ctx);
805
 
806
   ASSERT(index < VERT_ATTRIB_MAX);
807
 
808
   /* Can we keep the existing version?
809
    */
810
   if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index)) {
811
      reset_attrib( ctx, index );
812
   }
813
   else if (ac->NewArrayState & (1 << index)) {
814
      /* Also need to check conventional attributes */
815
      reset_attrib( ctx, index );
816
   }
817
 
818
   /* Is the request impossible?
819
    */
820
   if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize)
821
      return NULL;
822
 
823
   /* Do we need to pull in a copy of the client data:
824
    */
825
   if (ac->Raw.Attrib[index].Type != type ||
826
       (reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) ||
827
       reqwriteable)
828
   {
829
      if (!ac->IsCached.Attrib[index])
830
         import_attrib(ctx, index, type, reqstride );
831
      *writeable = GL_TRUE;
832
      return &ac->Cache.Attrib[index];
833
   }
834
   else {
835
      *writeable = GL_FALSE;
836
      return &ac->Raw.Attrib[index];
837
   }
838
}
839
 
840
 
841
/* Clients must call this function to validate state and set bounds
842
 * before importing any data:
843
 */
844
void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
845
{
846
   ACcontext *ac = AC_CONTEXT(ctx);
847
 
848
   if (!ctx->Array.LockCount) {
849
      /* Not locked, discard cached data.  Changes to lock
850
       * status are caught via. _ac_invalidate_state().
851
       */
852
      ac->NewArrayState = _NEW_ARRAY_ALL;
853
      ac->start = start;
854
      ac->count = count;
855
   }
856
   else {
857
      /* Locked, discard data for any disabled arrays.  Require that
858
       * the whole locked range always be dealt with, otherwise hard to
859
       * maintain cached data in the face of clipping.
860
       */
861
      ac->NewArrayState |= ~ctx->Array._Enabled;
862
      ac->start = ctx->Array.LockFirst;
863
      ac->count = ctx->Array.LockCount;
864
      ASSERT(ac->start == start); /* hmm? */
865
      ASSERT(ac->count == count);
866
   }
867
}
868
 
869
 
870
 
871
/* Additional convienence function for importing the element list
872
 * for glDrawElements() and glDrawRangeElements().
873
 */
874
CONST void *
875
_ac_import_elements( GLcontext *ctx,
876
                     GLenum new_type,
877
                     GLuint count,
878
                     GLenum old_type,
879
                     CONST void *indices )
880
{
881
   ACcontext *ac = AC_CONTEXT(ctx);
882
 
883
   if (old_type == new_type)
884
      return indices;
885
 
886
   if (ac->elt_size < count * sizeof(GLuint)) {
887
      if (ac->Elts) FREE(ac->Elts);
888
      while (ac->elt_size < count * sizeof(GLuint))
889
         ac->elt_size *= 2;
890
      ac->Elts = (GLuint *) MALLOC(ac->elt_size);
891
   }
892
 
893
   switch (new_type) {
894
   case GL_UNSIGNED_BYTE:
895
      ASSERT(0);
896
      return 0;
897
   case GL_UNSIGNED_SHORT:
898
      ASSERT(0);
899
      return 0;
900
   case GL_UNSIGNED_INT: {
901
      GLuint *out = (GLuint *)ac->Elts;
902
      GLuint i;
903
 
904
      switch (old_type) {
905
      case GL_UNSIGNED_BYTE: {
906
         CONST GLubyte *in = (CONST GLubyte *)indices;
907
         for (i = 0 ; i < count ; i++)
908
            out[i] = in[i];
909
         break;
910
      }
911
      case GL_UNSIGNED_SHORT: {
912
         CONST GLushort *in = (CONST GLushort *)indices;
913
         for (i = 0 ; i < count ; i++)
914
               out[i] = in[i];
915
         break;
916
      }
917
      default:
918
         ASSERT(0);
919
      }
920
 
921
      return (CONST void *)out;
922
   }
923
   default:
924
      ASSERT(0);
925
      break;
926
   }
927
 
928
   return 0;
929
}