VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_client.c@ 44059

Last change on this file since 44059 was 44052, checked in by vboxsync, 12 years ago

crOpenGL: fix buffer object refferencing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 80.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7/*
8 * This file manages all the client-side state including:
9 * Pixel pack/unpack parameters
10 * Vertex arrays
11 */
12
13
14#include "cr_mem.h"
15#include "state.h"
16#include "state/cr_statetypes.h"
17#include "state/cr_statefuncs.h"
18#include "state_internals.h"
19
20const CRPixelPackState crStateNativePixelPacking = {
21 0, /* rowLength */
22 0, /* skipRows */
23 0, /* skipPixels */
24 1, /* alignment */
25 0, /* imageHeight */
26 0, /* skipImages */
27 GL_FALSE, /* swapBytes */
28 GL_FALSE, /* psLSBFirst */
29};
30
31
32void crStateClientInitBits (CRClientBits *c)
33{
34 int i;
35
36 /* XXX why GLCLIENT_BIT_ALLOC? */
37 c->v = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
38 c->n = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
39 c->c = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
40 c->s = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
41 c->i = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
42 for ( i = 0; i < CR_MAX_TEXTURE_UNITS; i++ )
43 c->t[i] = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
44 c->e = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
45 c->f = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
46
47#ifdef CR_NV_vertex_program
48 for ( i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++ )
49 c->a[i] = (CRbitvalue *) crCalloc(GLCLIENT_BIT_ALLOC*sizeof(CRbitvalue));
50#endif
51}
52
53void crStateClientDestroyBits (CRClientBits *c)
54{
55 int i;
56
57 crFree(c->v);
58 crFree(c->n);
59 crFree(c->c);
60 crFree(c->s);
61 crFree(c->i);
62
63 for ( i = 0; i < CR_MAX_TEXTURE_UNITS; i++ )
64 crFree(c->t[i]);
65
66 crFree(c->e);
67 crFree(c->f);
68
69#ifdef CR_NV_vertex_program
70 for ( i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++ )
71 crFree(c->a[i]);
72#endif
73}
74
75static void crStateUnlockClientPointer(CRClientPointer* cp)
76{
77 if (cp->locked)
78 {
79#ifndef IN_GUEST
80 if (cp->p) crFree(cp->p);
81#endif
82 cp->locked = GL_FALSE;
83 }
84}
85
86void crStateClientDestroy(CRClientState *c)
87{
88#ifdef CR_EXT_compiled_vertex_array
89 if (c->array.locked)
90 {
91 unsigned int i;
92
93 crStateUnlockClientPointer(&c->array.v);
94 crStateUnlockClientPointer(&c->array.c);
95 crStateUnlockClientPointer(&c->array.f);
96 crStateUnlockClientPointer(&c->array.s);
97 crStateUnlockClientPointer(&c->array.e);
98 crStateUnlockClientPointer(&c->array.i);
99 crStateUnlockClientPointer(&c->array.n);
100 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
101 {
102 crStateUnlockClientPointer(&c->array.t[i]);
103 }
104 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++)
105 {
106 crStateUnlockClientPointer(&c->array.a[i]);
107 }
108 }
109#endif
110}
111
112void crStateClientInit(CRClientState *c)
113{
114 CRContext *g = GetCurrentContext();
115 unsigned int i;
116
117 /* pixel pack/unpack */
118 c->unpack.rowLength = 0;
119 c->unpack.skipRows = 0;
120 c->unpack.skipPixels = 0;
121 c->unpack.skipImages = 0;
122 c->unpack.alignment = 4;
123 c->unpack.imageHeight = 0;
124 c->unpack.swapBytes = GL_FALSE;
125 c->unpack.psLSBFirst = GL_FALSE;
126 c->pack.rowLength = 0;
127 c->pack.skipRows = 0;
128 c->pack.skipPixels = 0;
129 c->pack.skipImages = 0;
130 c->pack.alignment = 4;
131 c->pack.imageHeight = 0;
132 c->pack.swapBytes = GL_FALSE;
133 c->pack.psLSBFirst = GL_FALSE;
134
135 /* ARB multitexture */
136 c->curClientTextureUnit = 0;
137
138#ifdef CR_EXT_compiled_vertex_array
139 c->array.lockFirst = 0;
140 c->array.lockCount = 0;
141 c->array.locked = GL_FALSE;
142# ifdef IN_GUEST
143 c->array.synced = GL_FALSE;
144# endif
145#endif
146
147 /* vertex array */
148 c->array.v.p = NULL;
149 c->array.v.size = 4;
150 c->array.v.type = GL_FLOAT;
151 c->array.v.stride = 0;
152 c->array.v.enabled = 0;
153#ifdef CR_ARB_vertex_buffer_object
154 c->array.v.buffer = g ? g->bufferobject.arrayBuffer : NULL;
155 if (c->array.v.buffer)
156 ++c->array.v.buffer->refCount;
157#endif
158#ifdef CR_EXT_compiled_vertex_array
159 c->array.v.locked = GL_FALSE;
160 c->array.v.prevPtr = NULL;
161 c->array.v.prevStride = 0;
162#endif
163
164 /* color array */
165 c->array.c.p = NULL;
166 c->array.c.size = 4;
167 c->array.c.type = GL_FLOAT;
168 c->array.c.stride = 0;
169 c->array.c.enabled = 0;
170#ifdef CR_ARB_vertex_buffer_object
171 c->array.c.buffer = g ? g->bufferobject.arrayBuffer : NULL;
172 if (c->array.c.buffer)
173 ++c->array.c.buffer->refCount;
174#endif
175#ifdef CR_EXT_compiled_vertex_array
176 c->array.c.locked = GL_FALSE;
177 c->array.c.prevPtr = NULL;
178 c->array.c.prevStride = 0;
179#endif
180
181 /* fog array */
182 c->array.f.p = NULL;
183 c->array.f.size = 0;
184 c->array.f.type = GL_FLOAT;
185 c->array.f.stride = 0;
186 c->array.f.enabled = 0;
187#ifdef CR_ARB_vertex_buffer_object
188 c->array.f.buffer = g ? g->bufferobject.arrayBuffer : NULL;
189 if (c->array.f.buffer)
190 ++c->array.f.buffer->refCount;
191#endif
192#ifdef CR_EXT_compiled_vertex_array
193 c->array.f.locked = GL_FALSE;
194 c->array.f.prevPtr = NULL;
195 c->array.f.prevStride = 0;
196#endif
197
198 /* secondary color array */
199 c->array.s.p = NULL;
200 c->array.s.size = 3;
201 c->array.s.type = GL_FLOAT;
202 c->array.s.stride = 0;
203 c->array.s.enabled = 0;
204#ifdef CR_ARB_vertex_buffer_object
205 c->array.s.buffer = g ? g->bufferobject.arrayBuffer : NULL;
206 if (c->array.s.buffer)
207 ++c->array.s.buffer->refCount;
208#endif
209#ifdef CR_EXT_compiled_vertex_array
210 c->array.s.locked = GL_FALSE;
211 c->array.s.prevPtr = NULL;
212 c->array.s.prevStride = 0;
213#endif
214
215 /* edge flag array */
216 c->array.e.p = NULL;
217 c->array.e.size = 0;
218 c->array.e.type = GL_FLOAT;
219 c->array.e.stride = 0;
220 c->array.e.enabled = 0;
221#ifdef CR_ARB_vertex_buffer_object
222 c->array.e.buffer = g ? g->bufferobject.arrayBuffer : NULL;
223 if (c->array.e.buffer)
224 ++c->array.e.buffer->refCount;
225#endif
226#ifdef CR_EXT_compiled_vertex_array
227 c->array.e.locked = GL_FALSE;
228 c->array.e.prevPtr = NULL;
229 c->array.e.prevStride = 0;
230#endif
231
232 /* color index array */
233 c->array.i.p = NULL;
234 c->array.i.size = 0;
235 c->array.i.type = GL_FLOAT;
236 c->array.i.stride = 0;
237 c->array.i.enabled = 0;
238#ifdef CR_ARB_vertex_buffer_object
239 c->array.i.buffer = g ? g->bufferobject.arrayBuffer : NULL;
240 if (c->array.i.buffer)
241 ++c->array.i.buffer->refCount;
242#endif
243#ifdef CR_EXT_compiled_vertex_array
244 c->array.i.locked = GL_FALSE;
245 c->array.i.prevPtr = NULL;
246 c->array.i.prevStride = 0;
247#endif
248
249 /* normal array */
250 c->array.n.p = NULL;
251 c->array.n.size = 4;
252 c->array.n.type = GL_FLOAT;
253 c->array.n.stride = 0;
254 c->array.n.enabled = 0;
255#ifdef CR_ARB_vertex_buffer_object
256 c->array.n.buffer = g ? g->bufferobject.arrayBuffer : NULL;
257 if (c->array.n.buffer)
258 ++c->array.n.buffer->refCount;
259#endif
260#ifdef CR_EXT_compiled_vertex_array
261 c->array.n.locked = GL_FALSE;
262 c->array.n.prevPtr = NULL;
263 c->array.n.prevStride = 0;
264#endif
265
266 /* texcoord arrays */
267 for (i = 0 ; i < CR_MAX_TEXTURE_UNITS ; i++)
268 {
269 c->array.t[i].p = NULL;
270 c->array.t[i].size = 4;
271 c->array.t[i].type = GL_FLOAT;
272 c->array.t[i].stride = 0;
273 c->array.t[i].enabled = 0;
274#ifdef CR_ARB_vertex_buffer_object
275 c->array.t[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
276 if (c->array.t[i].buffer)
277 ++c->array.t[i].buffer->refCount;
278#endif
279#ifdef CR_EXT_compiled_vertex_array
280 c->array.t[i].locked = GL_FALSE;
281 c->array.t[i].prevPtr = NULL;
282 c->array.t[i].prevStride = 0;
283#endif
284 }
285
286 /* generic vertex attributes */
287#ifdef CR_NV_vertex_program
288 for (i = 0; i < CR_MAX_VERTEX_ATTRIBS; i++) {
289 c->array.a[i].enabled = GL_FALSE;
290 c->array.a[i].type = GL_FLOAT;
291 c->array.a[i].size = 4;
292 c->array.a[i].stride = 0;
293#ifdef CR_ARB_vertex_buffer_object
294 c->array.a[i].buffer = g ? g->bufferobject.arrayBuffer : NULL;
295 if (c->array.a[i].buffer)
296 ++c->array.a[i].buffer->refCount;
297#endif
298#ifdef CR_EXT_compiled_vertex_array
299 c->array.a[i].locked = GL_FALSE;
300 c->array.a[i].prevPtr = NULL;
301 c->array.a[i].prevStride = 0;
302#endif
303 }
304#endif
305}
306
307
308/*
309 * PixelStore functions are here, not in state_pixel.c because this
310 * is client-side state, like vertex arrays.
311 */
312
313void STATE_APIENTRY crStatePixelStoref (GLenum pname, GLfloat param)
314{
315
316 /* The GL SPEC says I can do this on page 76. */
317 switch( pname )
318 {
319 case GL_PACK_SWAP_BYTES:
320 case GL_PACK_LSB_FIRST:
321 case GL_UNPACK_SWAP_BYTES:
322 case GL_UNPACK_LSB_FIRST:
323 crStatePixelStorei( pname, param == 0.0f ? 0: 1 );
324 break;
325 default:
326 crStatePixelStorei( pname, (GLint) param );
327 break;
328 }
329}
330
331void STATE_APIENTRY crStatePixelStorei (GLenum pname, GLint param)
332{
333 CRContext *g = GetCurrentContext();
334 CRClientState *c = &(g->client);
335 CRStateBits *sb = GetCurrentBits();
336 CRClientBits *cb = &(sb->client);
337
338 if (g->current.inBeginEnd)
339 {
340 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "PixelStore{if} called in Begin/End");
341 return;
342 }
343
344 FLUSH();
345
346 switch(pname) {
347 case GL_PACK_SWAP_BYTES:
348 c->pack.swapBytes = (GLboolean) param;
349 DIRTY(cb->pack, g->neg_bitid);
350 break;
351 case GL_PACK_LSB_FIRST:
352 c->pack.psLSBFirst = (GLboolean) param;
353 DIRTY(cb->pack, g->neg_bitid);
354 break;
355 case GL_PACK_ROW_LENGTH:
356 if (param < 0.0f)
357 {
358 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Length: %f", param);
359 return;
360 }
361 c->pack.rowLength = param;
362 DIRTY(cb->pack, g->neg_bitid);
363 break;
364#ifdef CR_OPENGL_VERSION_1_2
365 case GL_PACK_IMAGE_HEIGHT:
366 if (param < 0.0f)
367 {
368 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Image Height: %f", param);
369 return;
370 }
371 c->pack.imageHeight = param;
372 DIRTY(cb->pack, g->neg_bitid);
373 break;
374#endif
375 case GL_PACK_SKIP_IMAGES:
376 if (param < 0.0f)
377 {
378 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Images: %f", param);
379 return;
380 }
381 c->pack.skipImages = param;
382 DIRTY(cb->pack, g->neg_bitid);
383 break;
384 case GL_PACK_SKIP_PIXELS:
385 if (param < 0.0f)
386 {
387 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Pixels: %f", param);
388 return;
389 }
390 c->pack.skipPixels = param;
391 DIRTY(cb->pack, g->neg_bitid);
392 break;
393 case GL_PACK_SKIP_ROWS:
394 if (param < 0.0f)
395 {
396 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Skip: %f", param);
397 return;
398 }
399 c->pack.skipRows = param;
400 DIRTY(cb->pack, g->neg_bitid);
401 break;
402 case GL_PACK_ALIGNMENT:
403 if (((GLint) param) != 1 &&
404 ((GLint) param) != 2 &&
405 ((GLint) param) != 4 &&
406 ((GLint) param) != 8)
407 {
408 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Invalid Alignment: %f", param);
409 return;
410 }
411 c->pack.alignment = param;
412 DIRTY(cb->pack, g->neg_bitid);
413 break;
414
415 case GL_UNPACK_SWAP_BYTES:
416 c->unpack.swapBytes = (GLboolean) param;
417 DIRTY(cb->unpack, g->neg_bitid);
418 break;
419 case GL_UNPACK_LSB_FIRST:
420 c->unpack.psLSBFirst = (GLboolean) param;
421 DIRTY(cb->unpack, g->neg_bitid);
422 break;
423 case GL_UNPACK_ROW_LENGTH:
424 if (param < 0.0f)
425 {
426 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Length: %f", param);
427 return;
428 }
429 c->unpack.rowLength = param;
430 DIRTY(cb->unpack, g->neg_bitid);
431 break;
432#ifdef CR_OPENGL_VERSION_1_2
433 case GL_UNPACK_IMAGE_HEIGHT:
434 if (param < 0.0f)
435 {
436 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Image Height: %f", param);
437 return;
438 }
439 c->unpack.imageHeight = param;
440 DIRTY(cb->unpack, g->neg_bitid);
441 break;
442#endif
443 case GL_UNPACK_SKIP_IMAGES:
444 if (param < 0.0f)
445 {
446 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Images: %f", param);
447 return;
448 }
449 c->unpack.skipImages = param;
450 DIRTY(cb->unpack, g->neg_bitid);
451 break;
452 case GL_UNPACK_SKIP_PIXELS:
453 if (param < 0.0f)
454 {
455 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Skip Pixels: %f", param);
456 return;
457 }
458 c->unpack.skipPixels = param;
459 DIRTY(cb->unpack, g->neg_bitid);
460 break;
461 case GL_UNPACK_SKIP_ROWS:
462 if (param < 0.0f)
463 {
464 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Negative Row Skip: %f", param);
465 return;
466 }
467 c->unpack.skipRows = param;
468 DIRTY(cb->unpack, g->neg_bitid);
469 break;
470 case GL_UNPACK_ALIGNMENT:
471 if (((GLint) param) != 1 &&
472 ((GLint) param) != 2 &&
473 ((GLint) param) != 4 &&
474 ((GLint) param) != 8)
475 {
476 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Invalid Alignment: %f", param);
477 return;
478 }
479 c->unpack.alignment = param;
480 DIRTY(cb->unpack, g->neg_bitid);
481 break;
482 default:
483 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "Unknown glPixelStore Pname: %d", pname);
484 return;
485 }
486 DIRTY(cb->dirty, g->neg_bitid);
487}
488
489
490static void setClientState(CRClientState *c, CRClientBits *cb,
491 CRbitvalue *neg_bitid, GLenum array, GLboolean state)
492{
493 CRContext *g = GetCurrentContext();
494
495 switch (array)
496 {
497#ifdef CR_NV_vertex_program
498 case GL_VERTEX_ATTRIB_ARRAY0_NV:
499 case GL_VERTEX_ATTRIB_ARRAY1_NV:
500 case GL_VERTEX_ATTRIB_ARRAY2_NV:
501 case GL_VERTEX_ATTRIB_ARRAY3_NV:
502 case GL_VERTEX_ATTRIB_ARRAY4_NV:
503 case GL_VERTEX_ATTRIB_ARRAY5_NV:
504 case GL_VERTEX_ATTRIB_ARRAY6_NV:
505 case GL_VERTEX_ATTRIB_ARRAY7_NV:
506 case GL_VERTEX_ATTRIB_ARRAY8_NV:
507 case GL_VERTEX_ATTRIB_ARRAY9_NV:
508 case GL_VERTEX_ATTRIB_ARRAY10_NV:
509 case GL_VERTEX_ATTRIB_ARRAY11_NV:
510 case GL_VERTEX_ATTRIB_ARRAY12_NV:
511 case GL_VERTEX_ATTRIB_ARRAY13_NV:
512 case GL_VERTEX_ATTRIB_ARRAY14_NV:
513 case GL_VERTEX_ATTRIB_ARRAY15_NV:
514 {
515 const GLuint i = array - GL_VERTEX_ATTRIB_ARRAY0_NV;
516 c->array.a[i].enabled = state;
517 }
518 break;
519#endif
520 case GL_VERTEX_ARRAY:
521 c->array.v.enabled = state;
522 break;
523 case GL_COLOR_ARRAY:
524 c->array.c.enabled = state;
525 break;
526 case GL_NORMAL_ARRAY:
527 c->array.n.enabled = state;
528 break;
529 case GL_INDEX_ARRAY:
530 c->array.i.enabled = state;
531 break;
532 case GL_TEXTURE_COORD_ARRAY:
533 c->array.t[c->curClientTextureUnit].enabled = state;
534 break;
535 case GL_EDGE_FLAG_ARRAY:
536 c->array.e.enabled = state;
537 break;
538#ifdef CR_EXT_fog_coord
539 case GL_FOG_COORDINATE_ARRAY_EXT:
540 c->array.f.enabled = state;
541 break;
542#endif
543#ifdef CR_EXT_secondary_color
544 case GL_SECONDARY_COLOR_ARRAY_EXT:
545 if( g->extensions.EXT_secondary_color ){
546 c->array.s.enabled = state;
547 }
548 else {
549 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to Enable/Disable Client State: SECONDARY_COLOR_ARRAY_EXT - EXT_secondary_color is not enabled." );
550 return;
551 }
552 break;
553#endif
554 default:
555 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to Enable/Disable Client State: 0x%x", array );
556 return;
557 }
558 DIRTY(cb->dirty, neg_bitid);
559 DIRTY(cb->enableClientState, neg_bitid);
560}
561
562void STATE_APIENTRY crStateEnableClientState (GLenum array)
563{
564 CRContext *g = GetCurrentContext();
565 CRClientState *c = &(g->client);
566 CRStateBits *sb = GetCurrentBits();
567 CRClientBits *cb = &(sb->client);
568
569 FLUSH();
570
571 setClientState(c, cb, g->neg_bitid, array, GL_TRUE);
572}
573
574void STATE_APIENTRY crStateDisableClientState (GLenum array)
575{
576 CRContext *g = GetCurrentContext();
577 CRClientState *c = &(g->client);
578 CRStateBits *sb = GetCurrentBits();
579 CRClientBits *cb = &(sb->client);
580
581 FLUSH();
582
583 setClientState(c, cb, g->neg_bitid, array, GL_FALSE);
584}
585
586static void
587crStateClientSetPointer(CRClientPointer *cp, GLint size,
588 GLenum type, GLboolean normalized,
589 GLsizei stride, const GLvoid *pointer)
590{
591 CRContext *g = GetCurrentContext();
592
593#ifdef CR_EXT_compiled_vertex_array
594 crStateUnlockClientPointer(cp);
595 cp->prevPtr = cp->p;
596 cp->prevStride = cp->stride;
597#endif
598
599 cp->p = (unsigned char *) pointer;
600 cp->size = size;
601 cp->type = type;
602 cp->normalized = normalized;
603
604 /* Calculate the bytes per index for address calculation */
605 cp->bytesPerIndex = size;
606 switch (type)
607 {
608 case GL_BYTE:
609 case GL_UNSIGNED_BYTE:
610 break;
611 case GL_SHORT:
612 case GL_UNSIGNED_SHORT:
613 cp->bytesPerIndex *= sizeof(GLshort);
614 break;
615 case GL_INT:
616 case GL_UNSIGNED_INT:
617 cp->bytesPerIndex *= sizeof(GLint);
618 break;
619 case GL_FLOAT:
620 cp->bytesPerIndex *= sizeof(GLfloat);
621 break;
622 case GL_DOUBLE:
623 cp->bytesPerIndex *= sizeof(GLdouble);
624 break;
625 default:
626 crStateError( __LINE__, __FILE__, GL_INVALID_VALUE,
627 "Unknown type of vertex array: %d", type );
628 return;
629 }
630
631 /*
632 ** Note: If stride==0 then we set the
633 ** stride equal address offset
634 ** therefore stride can never equal
635 ** zero.
636 */
637 if (stride)
638 cp->stride = stride;
639 else
640 cp->stride = cp->bytesPerIndex;
641
642#ifdef CR_ARB_vertex_buffer_object
643 if (cp->buffer)
644 {
645 --cp->buffer->refCount;
646 CRASSERT(cp->buffer->refCount && cp->buffer->refCount < UINT32_MAX/2);
647 }
648 cp->buffer = g->bufferobject.arrayBuffer;
649 if (cp->buffer)
650 ++cp->buffer->refCount;
651#endif
652}
653
654void STATE_APIENTRY crStateVertexPointer(GLint size, GLenum type,
655 GLsizei stride, const GLvoid *p)
656{
657 CRContext *g = GetCurrentContext();
658 CRClientState *c = &(g->client);
659 CRStateBits *sb = GetCurrentBits();
660 CRClientBits *cb = &(sb->client);
661
662 FLUSH();
663
664 if (size != 2 && size != 3 && size != 4)
665 {
666 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexPointer: invalid size: %d", size);
667 return;
668 }
669 if (type != GL_SHORT && type != GL_INT &&
670 type != GL_FLOAT && type != GL_DOUBLE)
671 {
672 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glVertexPointer: invalid type: 0x%x", type);
673 return;
674 }
675 if (stride < 0)
676 {
677 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexPointer: stride was negative: %d", stride);
678 return;
679 }
680
681 crStateClientSetPointer(&(c->array.v), size, type, GL_FALSE, stride, p);
682 DIRTY(cb->dirty, g->neg_bitid);
683 DIRTY(cb->clientPointer, g->neg_bitid);
684 DIRTY(cb->v, g->neg_bitid);
685}
686
687void STATE_APIENTRY crStateColorPointer(GLint size, GLenum type,
688 GLsizei stride, const GLvoid *p)
689{
690 CRContext *g = GetCurrentContext();
691 CRClientState *c = &(g->client);
692 CRStateBits *sb = GetCurrentBits();
693 CRClientBits *cb = &(sb->client);
694
695 FLUSH();
696
697 if (size != 3 && size != 4)
698 {
699 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glColorPointer: invalid size: %d", size);
700 return;
701 }
702 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
703 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
704 type != GL_INT && type != GL_UNSIGNED_INT &&
705 type != GL_FLOAT && type != GL_DOUBLE)
706 {
707 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glColorPointer: invalid type: 0x%x", type);
708 return;
709 }
710 if (stride < 0)
711 {
712 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glColorPointer: stride was negative: %d", stride);
713 return;
714 }
715
716 crStateClientSetPointer(&(c->array.c), size, type, GL_TRUE, stride, p);
717 DIRTY(cb->dirty, g->neg_bitid);
718 DIRTY(cb->clientPointer, g->neg_bitid);
719 DIRTY(cb->c, g->neg_bitid);
720}
721
722void STATE_APIENTRY crStateSecondaryColorPointerEXT(GLint size,
723 GLenum type, GLsizei stride, const GLvoid *p)
724{
725 CRContext *g = GetCurrentContext();
726 CRClientState *c = &(g->client);
727 CRStateBits *sb = GetCurrentBits();
728 CRClientBits *cb = &(sb->client);
729
730 FLUSH();
731
732 if ( !g->extensions.EXT_secondary_color )
733 {
734 crError( "glSecondaryColorPointerEXT called but EXT_secondary_color is disabled." );
735 return;
736 }
737
738 /*Note: According to opengl spec, only size==3 should be accepted here.
739 *But it turns out that most drivers accept size==4 here as well, and 4th value
740 *could even be accessed in shaders code.
741 *Having a strict check here, leads to difference between guest and host gpu states, which
742 *in turn could lead to crashes when using server side VBOs.
743 *@todo: add error reporting to state's VBO related functions and abort dispatching to
744 *real gpu on any failure to prevent other possible issues.
745 */
746
747 if ((size != 3) && (size != 4))
748 {
749 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glSecondaryColorPointerEXT: invalid size: %d", size);
750 return;
751 }
752 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
753 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
754 type != GL_INT && type != GL_UNSIGNED_INT &&
755 type != GL_FLOAT && type != GL_DOUBLE)
756 {
757 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glSecondaryColorPointerEXT: invalid type: 0x%x", type);
758 return;
759 }
760 if (stride < 0)
761 {
762 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glSecondaryColorPointerEXT: stride was negative: %d", stride);
763 return;
764 }
765
766 crStateClientSetPointer(&(c->array.s), size, type, GL_TRUE, stride, p);
767 DIRTY(cb->dirty, g->neg_bitid);
768 DIRTY(cb->clientPointer, g->neg_bitid);
769 DIRTY(cb->s, g->neg_bitid);
770}
771
772void STATE_APIENTRY crStateIndexPointer(GLenum type, GLsizei stride,
773 const GLvoid *p)
774{
775 CRContext *g = GetCurrentContext();
776 CRClientState *c = &(g->client);
777 CRStateBits *sb = GetCurrentBits();
778 CRClientBits *cb = &(sb->client);
779
780 FLUSH();
781
782 if (type != GL_SHORT && type != GL_INT && type != GL_UNSIGNED_BYTE &&
783 type != GL_FLOAT && type != GL_DOUBLE)
784 {
785 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glIndexPointer: invalid type: 0x%x", type);
786 return;
787 }
788 if (stride < 0)
789 {
790 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glIndexPointer: stride was negative: %d", stride);
791 return;
792 }
793
794 crStateClientSetPointer(&(c->array.i), 1, type, GL_TRUE, stride, p);
795 DIRTY(cb->dirty, g->neg_bitid);
796 DIRTY(cb->clientPointer, g->neg_bitid);
797 DIRTY(cb->i, g->neg_bitid);
798}
799
800void STATE_APIENTRY crStateNormalPointer(GLenum type, GLsizei stride,
801 const GLvoid *p)
802{
803 CRContext *g = GetCurrentContext();
804 CRClientState *c = &(g->client);
805 CRStateBits *sb = GetCurrentBits();
806 CRClientBits *cb = &(sb->client);
807
808 FLUSH();
809
810 if (type != GL_BYTE && type != GL_SHORT &&
811 type != GL_INT && type != GL_FLOAT &&
812 type != GL_DOUBLE)
813 {
814 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glNormalPointer: invalid type: 0x%x", type);
815 return;
816 }
817 if (stride < 0)
818 {
819 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glNormalPointer: stride was negative: %d", stride);
820 return;
821 }
822
823 crStateClientSetPointer(&(c->array.n), 3, type, GL_TRUE, stride, p);
824 DIRTY(cb->dirty, g->neg_bitid);
825 DIRTY(cb->clientPointer, g->neg_bitid);
826 DIRTY(cb->n, g->neg_bitid);
827}
828
829void STATE_APIENTRY crStateTexCoordPointer(GLint size, GLenum type,
830 GLsizei stride, const GLvoid *p)
831{
832 CRContext *g = GetCurrentContext();
833 CRClientState *c = &(g->client);
834 CRStateBits *sb = GetCurrentBits();
835 CRClientBits *cb = &(sb->client);
836
837 FLUSH();
838
839 if (size != 1 && size != 2 && size != 3 && size != 4)
840 {
841 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: invalid size: %d", size);
842 return;
843 }
844 if (type != GL_SHORT && type != GL_INT &&
845 type != GL_FLOAT && type != GL_DOUBLE)
846 {
847 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glTexCoordPointer: invalid type: 0x%x", type);
848 return;
849 }
850 if (stride < 0)
851 {
852 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: stride was negative: %d", stride);
853 return;
854 }
855
856 crStateClientSetPointer(&(c->array.t[c->curClientTextureUnit]), size, type, GL_FALSE, stride, p);
857 DIRTY(cb->dirty, g->neg_bitid);
858 DIRTY(cb->clientPointer, g->neg_bitid);
859 DIRTY(cb->t[c->curClientTextureUnit], g->neg_bitid);
860}
861
862void STATE_APIENTRY crStateEdgeFlagPointer(GLsizei stride, const GLvoid *p)
863{
864 CRContext *g = GetCurrentContext();
865 CRClientState *c = &(g->client);
866 CRStateBits *sb = GetCurrentBits();
867 CRClientBits *cb = &(sb->client);
868
869 FLUSH();
870
871 if (stride < 0)
872 {
873 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glTexCoordPointer: stride was negative: %d", stride);
874 return;
875 }
876
877 crStateClientSetPointer(&(c->array.e), 1, GL_UNSIGNED_BYTE, GL_FALSE, stride, p);
878 DIRTY(cb->dirty, g->neg_bitid);
879 DIRTY(cb->clientPointer, g->neg_bitid);
880 DIRTY(cb->e, g->neg_bitid);
881}
882
883void STATE_APIENTRY crStateFogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *p)
884{
885 CRContext *g = GetCurrentContext();
886 CRClientState *c = &(g->client);
887 CRStateBits *sb = GetCurrentBits();
888 CRClientBits *cb = &(sb->client);
889
890 FLUSH();
891
892 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
893 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
894 type != GL_INT && type != GL_UNSIGNED_INT &&
895 type != GL_FLOAT && type != GL_DOUBLE)
896 {
897 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glFogCoordPointerEXT: invalid type: 0x%x", type);
898 return;
899 }
900 if (stride < 0)
901 {
902 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glFogCoordPointerEXT: stride was negative: %d", stride);
903 return;
904 }
905
906 crStateClientSetPointer(&(c->array.f), 1, type, GL_FALSE, stride, p);
907 DIRTY(cb->dirty, g->neg_bitid);
908 DIRTY(cb->clientPointer, g->neg_bitid);
909 DIRTY(cb->f, g->neg_bitid);
910}
911
912
913void STATE_APIENTRY crStateVertexAttribPointerNV(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *p)
914{
915 GLboolean normalized = GL_FALSE;
916 /* Extra error checking for NV arrays */
917 if (type != GL_UNSIGNED_BYTE && type != GL_SHORT &&
918 type != GL_FLOAT && type != GL_DOUBLE) {
919 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
920 "glVertexAttribPointerNV: invalid type: 0x%x", type);
921 return;
922 }
923 crStateVertexAttribPointerARB(index, size, type, normalized, stride, p);
924}
925
926
927void STATE_APIENTRY crStateVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *p)
928{
929 CRContext *g = GetCurrentContext();
930 CRClientState *c = &(g->client);
931 CRStateBits *sb = GetCurrentBits();
932 CRClientBits *cb = &(sb->client);
933
934 FLUSH();
935
936 if (index >= CR_MAX_VERTEX_ATTRIBS)
937 {
938 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: invalid index: %d", (int) index);
939 return;
940 }
941 if (size != 1 && size != 2 && size != 3 && size != 4)
942 {
943 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: invalid size: %d", size);
944 return;
945 }
946 if (type != GL_BYTE && type != GL_UNSIGNED_BYTE &&
947 type != GL_SHORT && type != GL_UNSIGNED_SHORT &&
948 type != GL_INT && type != GL_UNSIGNED_INT &&
949 type != GL_FLOAT && type != GL_DOUBLE)
950 {
951 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glVertexAttribPointerARB: invalid type: 0x%x", type);
952 return;
953 }
954 if (stride < 0)
955 {
956 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glVertexAttribPointerARB: stride was negative: %d", stride);
957 return;
958 }
959
960 crStateClientSetPointer(&(c->array.a[index]), size, type, normalized, stride, p);
961 DIRTY(cb->dirty, g->neg_bitid);
962 DIRTY(cb->clientPointer, g->neg_bitid);
963 DIRTY(cb->a[index], g->neg_bitid);
964}
965
966
967void STATE_APIENTRY crStateGetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
968{
969 CRContext *g = GetCurrentContext();
970
971 if (g->current.inBeginEnd) {
972 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
973 "glGetVertexAttribPointervNV called in Begin/End");
974 return;
975 }
976
977 if (index >= CR_MAX_VERTEX_ATTRIBS) {
978 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
979 "glGetVertexAttribPointervNV(index)");
980 return;
981 }
982
983 if (pname != GL_ATTRIB_ARRAY_POINTER_NV) {
984 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
985 "glGetVertexAttribPointervNV(pname)");
986 return;
987 }
988
989 *pointer = g->client.array.a[index].p;
990}
991
992
993void STATE_APIENTRY crStateGetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
994{
995 crStateGetVertexAttribPointervNV(index, pname, pointer);
996}
997
998
999
1000/*
1001** Currently I treat Interleaved Arrays as if the
1002** user uses them as separate arrays.
1003** Certainly not the most efficient method but it
1004** lets me use the same glDrawArrays method.
1005*/
1006void STATE_APIENTRY crStateInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *p)
1007{
1008 CRContext *g = GetCurrentContext();
1009 CRClientState *c = &(g->client);
1010 CRStateBits *sb = GetCurrentBits();
1011 CRClientBits *cb = &(sb->client);
1012 CRClientPointer *cp;
1013 unsigned char *base = (unsigned char *) p;
1014
1015 if (g->current.inBeginEnd)
1016 {
1017 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glInterleavedArrays called in begin/end");
1018 return;
1019 }
1020
1021 FLUSH();
1022
1023 if (stride < 0)
1024 {
1025 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION, "glInterleavedArrays: stride < 0: %d", stride);
1026 return;
1027 }
1028
1029 switch (format)
1030 {
1031 case GL_T4F_C4F_N3F_V4F:
1032 case GL_T2F_C4F_N3F_V3F:
1033 case GL_C4F_N3F_V3F:
1034 case GL_T4F_V4F:
1035 case GL_T2F_C3F_V3F:
1036 case GL_T2F_N3F_V3F:
1037 case GL_C3F_V3F:
1038 case GL_N3F_V3F:
1039 case GL_T2F_C4UB_V3F:
1040 case GL_T2F_V3F:
1041 case GL_C4UB_V3F:
1042 case GL_V3F:
1043 case GL_C4UB_V2F:
1044 case GL_V2F:
1045 break;
1046 default:
1047 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1048 return;
1049 }
1050
1051 DIRTY(cb->dirty, g->neg_bitid);
1052 DIRTY(cb->clientPointer, g->neg_bitid);
1053
1054/* p, size, type, stride, enabled, bytesPerIndex */
1055/*
1056** VertexPointer
1057*/
1058
1059 cp = &(c->array.v);
1060 cp->type = GL_FLOAT;
1061 cp->enabled = GL_TRUE;
1062
1063#ifdef CR_EXT_compiled_vertex_array
1064 crStateUnlockClientPointer(cp);
1065#endif
1066
1067 switch (format)
1068 {
1069 case GL_T4F_C4F_N3F_V4F:
1070 cp->p = base+4*sizeof(GLfloat)+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1071 cp->size = 4;
1072 break;
1073 case GL_T2F_C4F_N3F_V3F:
1074 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1075 cp->size = 3;
1076 break;
1077 case GL_C4F_N3F_V3F:
1078 cp->p = base+4*sizeof(GLfloat)+3*sizeof(GLfloat);
1079 cp->size = 3;
1080 break;
1081 case GL_T4F_V4F:
1082 cp->p = base+4*sizeof(GLfloat);
1083 cp->size = 4;
1084 break;
1085 case GL_T2F_C3F_V3F:
1086 cp->p = base+2*sizeof(GLfloat)+3*sizeof(GLfloat);
1087 cp->size = 3;
1088 break;
1089 case GL_T2F_N3F_V3F:
1090 cp->p = base+2*sizeof(GLfloat)+3*sizeof(GLfloat);
1091 cp->size = 3;
1092 break;
1093 case GL_C3F_V3F:
1094 cp->p = base+3*sizeof(GLfloat);
1095 cp->size = 3;
1096 break;
1097 case GL_N3F_V3F:
1098 cp->p = base+3*sizeof(GLfloat);
1099 cp->size = 3;
1100 break;
1101 case GL_T2F_C4UB_V3F:
1102 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLubyte);
1103 cp->size = 3;
1104 break;
1105 case GL_T2F_V3F:
1106 cp->p = base+2*sizeof(GLfloat);
1107 cp->size = 3;
1108 break;
1109 case GL_C4UB_V3F:
1110 cp->p = base+4*sizeof(GLubyte);
1111 cp->size = 3;
1112 break;
1113 case GL_V3F:
1114 cp->p = base;
1115 cp->size = 3;
1116 break;
1117 case GL_C4UB_V2F:
1118 cp->p = base+4*sizeof(GLubyte);
1119 cp->size = 2;
1120 break;
1121 case GL_V2F:
1122 cp->p = base;
1123 cp->size = 2;
1124 break;
1125 default:
1126 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1127 return;
1128 }
1129
1130 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1131
1132 if (stride==0)
1133 stride = cp->bytesPerIndex + (cp->p - base);
1134 cp->stride = stride;
1135
1136/*
1137** NormalPointer
1138*/
1139
1140 cp = &(c->array.n);
1141 cp->enabled = GL_TRUE;
1142 cp->stride = stride;
1143#ifdef CR_EXT_compiled_vertex_array
1144 crStateUnlockClientPointer(cp);
1145#endif
1146
1147 switch (format)
1148 {
1149 case GL_T4F_C4F_N3F_V4F:
1150 cp->p = base+4*sizeof(GLfloat)+4*sizeof(GLfloat);
1151 break;
1152 case GL_T2F_C4F_N3F_V3F:
1153 cp->p = base+2*sizeof(GLfloat)+4*sizeof(GLfloat);
1154 break;
1155 case GL_C4F_N3F_V3F:
1156 cp->p = base+4*sizeof(GLfloat);
1157 break;
1158 case GL_T2F_N3F_V3F:
1159 cp->p = base+2*sizeof(GLfloat);
1160 break;
1161 case GL_N3F_V3F:
1162 cp->p = base;
1163 break;
1164 case GL_T4F_V4F:
1165 case GL_T2F_C3F_V3F:
1166 case GL_C3F_V3F:
1167 case GL_T2F_C4UB_V3F:
1168 case GL_T2F_V3F:
1169 case GL_C4UB_V3F:
1170 case GL_V3F:
1171 case GL_C4UB_V2F:
1172 case GL_V2F:
1173 cp->enabled = GL_FALSE;
1174 break;
1175 default:
1176 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1177 return;
1178 }
1179
1180 if (cp->enabled)
1181 {
1182 cp->type = GL_FLOAT;
1183 cp->size = 3;
1184 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1185 }
1186
1187/*
1188** ColorPointer
1189*/
1190
1191 cp = &(c->array.c);
1192 cp->enabled = GL_TRUE;
1193 cp->stride = stride;
1194#ifdef CR_EXT_compiled_vertex_array
1195 crStateUnlockClientPointer(cp);
1196#endif
1197
1198 switch (format)
1199 {
1200 case GL_T4F_C4F_N3F_V4F:
1201 cp->size = 4;
1202 cp->type = GL_FLOAT;
1203 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1204 cp->p = base+4*sizeof(GLfloat);
1205 break;
1206 case GL_T2F_C4F_N3F_V3F:
1207 cp->size = 4;
1208 cp->type = GL_FLOAT;
1209 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1210 cp->p = base+2*sizeof(GLfloat);
1211 break;
1212 case GL_C4F_N3F_V3F:
1213 cp->size = 4;
1214 cp->type = GL_FLOAT;
1215 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1216 cp->p = base;
1217 break;
1218 case GL_T2F_C3F_V3F:
1219 cp->size = 3;
1220 cp->type = GL_FLOAT;
1221 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1222 cp->p = base+2*sizeof(GLfloat);
1223 break;
1224 case GL_C3F_V3F:
1225 cp->size = 3;
1226 cp->type = GL_FLOAT;
1227 cp->bytesPerIndex = cp->size * sizeof(GLfloat);
1228 cp->p = base;
1229 break;
1230 case GL_T2F_C4UB_V3F:
1231 cp->size = 4;
1232 cp->type = GL_UNSIGNED_BYTE;
1233 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1234 cp->p = base+2*sizeof(GLfloat);
1235 break;
1236 case GL_C4UB_V3F:
1237 cp->size = 4;
1238 cp->type = GL_UNSIGNED_BYTE;
1239 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1240 cp->p = base;
1241 break;
1242 case GL_C4UB_V2F:
1243 cp->size = 4;
1244 cp->type = GL_UNSIGNED_BYTE;
1245 cp->bytesPerIndex = cp->size * sizeof(GLubyte);
1246 cp->p = base;
1247 break;
1248 case GL_T2F_N3F_V3F:
1249 case GL_N3F_V3F:
1250 case GL_T4F_V4F:
1251 case GL_T2F_V3F:
1252 case GL_V3F:
1253 case GL_V2F:
1254 cp->enabled = GL_FALSE;
1255 break;
1256 default:
1257 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1258 return;
1259 }
1260
1261/*
1262** TexturePointer
1263*/
1264
1265 cp = &(c->array.t[c->curClientTextureUnit]);
1266 cp->enabled = GL_TRUE;
1267 cp->stride = stride;
1268#ifdef CR_EXT_compiled_vertex_array
1269 crStateUnlockClientPointer(cp);
1270#endif
1271
1272 switch (format)
1273 {
1274 case GL_T4F_C4F_N3F_V4F:
1275 cp->size = 4;
1276 cp->p = base;
1277 break;
1278 case GL_T2F_C4F_N3F_V3F:
1279 cp->size = 3;
1280 cp->p = base;
1281 break;
1282 case GL_T2F_C3F_V3F:
1283 case GL_T2F_N3F_V3F:
1284 cp->size = 3;
1285 cp->p = base;
1286 break;
1287 case GL_T2F_C4UB_V3F:
1288 cp->size = 3;
1289 cp->p = base;
1290 break;
1291 case GL_T4F_V4F:
1292 cp->size = 4;
1293 cp->p = base;
1294 break;
1295 case GL_T2F_V3F:
1296 cp->size = 3;
1297 cp->p = base;
1298 break;
1299 case GL_C4UB_V3F:
1300 case GL_C4UB_V2F:
1301 case GL_C3F_V3F:
1302 case GL_C4F_N3F_V3F:
1303 case GL_N3F_V3F:
1304 case GL_V3F:
1305 case GL_V2F:
1306 cp->enabled = GL_FALSE;
1307 break;
1308 default:
1309 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glInterleavedArrays: Unrecognized format: %d", format);
1310 return;
1311 }
1312
1313 if (cp->enabled)
1314 {
1315 cp->type = GL_FLOAT;
1316 cp->bytesPerIndex = cp->size * sizeof (GLfloat);
1317 }
1318}
1319
1320void STATE_APIENTRY crStateGetPointerv(GLenum pname, GLvoid * * params)
1321{
1322 CRContext *g = GetCurrentContext();
1323 CRClientState *c = &(g->client);
1324
1325 if (g->current.inBeginEnd)
1326 {
1327 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1328 "GetPointerv called in begin/end");
1329 return;
1330 }
1331
1332 switch (pname)
1333 {
1334 case GL_VERTEX_ARRAY_POINTER:
1335 *params = (GLvoid *) c->array.v.p;
1336 break;
1337 case GL_COLOR_ARRAY_POINTER:
1338 *params = (GLvoid *) c->array.c.p;
1339 break;
1340 case GL_NORMAL_ARRAY_POINTER:
1341 *params = (GLvoid *) c->array.n.p;
1342 break;
1343 case GL_INDEX_ARRAY_POINTER:
1344 *params = (GLvoid *) c->array.i.p;
1345 break;
1346 case GL_TEXTURE_COORD_ARRAY_POINTER:
1347 *params = (GLvoid *) c->array.t[c->curClientTextureUnit].p;
1348 break;
1349 case GL_EDGE_FLAG_ARRAY_POINTER:
1350 *params = (GLvoid *) c->array.e.p;
1351 break;
1352#ifdef CR_EXT_fog_coord
1353 case GL_FOG_COORDINATE_ARRAY_POINTER_EXT:
1354 *params = (GLvoid *) c->array.f.p;
1355 break;
1356#endif
1357#ifdef CR_EXT_secondary_color
1358 case GL_SECONDARY_COLOR_ARRAY_POINTER_EXT:
1359 if( g->extensions.EXT_secondary_color ){
1360 *params = (GLvoid *) c->array.s.p;
1361 }
1362 else {
1363 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "Invalid Enum passed to glGetPointerv: SECONDARY_COLOR_ARRAY_EXT - EXT_secondary_color is not enabled." );
1364 return;
1365 }
1366 break;
1367#endif
1368 case GL_FEEDBACK_BUFFER_POINTER:
1369 case GL_SELECTION_BUFFER_POINTER:
1370 /* do nothing - API switching should pick this up */
1371 break;
1372 default:
1373 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1374 "glGetPointerv: invalid pname: %d", pname);
1375 return;
1376 }
1377}
1378
1379
1380void STATE_APIENTRY crStatePushClientAttrib( GLbitfield mask )
1381{
1382 CRContext *g = GetCurrentContext();
1383 CRClientState *c = &(g->client);
1384
1385 if (g->current.inBeginEnd) {
1386 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1387 "glPushClientAttrib called in Begin/End");
1388 return;
1389 }
1390
1391 if (c->attribStackDepth == CR_MAX_CLIENT_ATTRIB_STACK_DEPTH - 1) {
1392 crStateError(__LINE__, __FILE__, GL_STACK_OVERFLOW,
1393 "glPushClientAttrib called with a full stack!" );
1394 return;
1395 }
1396
1397 FLUSH();
1398
1399 c->pushMaskStack[c->attribStackDepth++] = mask;
1400
1401 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1402 c->pixelPackStoreStack[c->pixelStoreStackDepth] = c->pack;
1403 c->pixelUnpackStoreStack[c->pixelStoreStackDepth] = c->unpack;
1404 c->pixelStoreStackDepth++;
1405 }
1406 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1407 c->vertexArrayStack[c->vertexArrayStackDepth] = c->array;
1408 c->vertexArrayStackDepth++;
1409 }
1410
1411 /* dirty? - no, because we haven't really changed any state */
1412}
1413
1414
1415void STATE_APIENTRY crStatePopClientAttrib( void )
1416{
1417 CRContext *g = GetCurrentContext();
1418 CRClientState *c = &(g->client);
1419 CRStateBits *sb = GetCurrentBits();
1420 CRClientBits *cb = &(sb->client);
1421 CRbitvalue mask;
1422
1423 if (g->current.inBeginEnd) {
1424 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1425 "glPopClientAttrib called in Begin/End");
1426 return;
1427 }
1428
1429 if (c->attribStackDepth == 0) {
1430 crStateError(__LINE__, __FILE__, GL_STACK_UNDERFLOW,
1431 "glPopClientAttrib called with an empty stack!" );
1432 return;
1433 }
1434
1435 FLUSH();
1436
1437 mask = c->pushMaskStack[--c->attribStackDepth];
1438
1439 if (mask & GL_CLIENT_PIXEL_STORE_BIT) {
1440 if (c->pixelStoreStackDepth == 0) {
1441 crError("bug in glPopClientAttrib (pixel store) ");
1442 return;
1443 }
1444 c->pixelStoreStackDepth--;
1445 c->pack = c->pixelPackStoreStack[c->pixelStoreStackDepth];
1446 c->unpack = c->pixelUnpackStoreStack[c->pixelStoreStackDepth];
1447 DIRTY(cb->pack, g->neg_bitid);
1448 }
1449
1450 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
1451 if (c->vertexArrayStackDepth == 0) {
1452 crError("bug in glPopClientAttrib (vertex array) ");
1453 return;
1454 }
1455 c->vertexArrayStackDepth--;
1456 c->array = c->vertexArrayStack[c->vertexArrayStackDepth];
1457 DIRTY(cb->clientPointer, g->neg_bitid);
1458 }
1459
1460 DIRTY(cb->dirty, g->neg_bitid);
1461}
1462
1463static void crStateLockClientPointer(CRClientPointer* cp)
1464{
1465 crStateUnlockClientPointer(cp);
1466 if (cp->enabled)
1467 {
1468 cp->locked = GL_TRUE;
1469 }
1470}
1471
1472static GLboolean crStateCanLockClientPointer(CRClientPointer* cp)
1473{
1474 return !(cp->enabled && cp->buffer && cp->buffer->id);
1475}
1476
1477void STATE_APIENTRY crStateLockArraysEXT(GLint first, GLint count)
1478{
1479 CRContext *g = GetCurrentContext();
1480 CRClientState *c = &(g->client);
1481 int i;
1482
1483 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1484 {
1485 if (!crStateCanLockClientPointer(crStateGetClientPointerByIndex(i, &c->array)))
1486 {
1487 break;
1488 }
1489 }
1490 if (i<CRSTATECLIENT_MAX_VERTEXARRAYS)
1491 {
1492 crDebug("crStateLockArraysEXT ignored because array %i have a bound VBO", i);
1493 return;
1494 }
1495
1496 c->array.locked = GL_TRUE;
1497 c->array.lockFirst = first;
1498 c->array.lockCount = count;
1499#ifdef IN_GUEST
1500 c->array.synced = GL_FALSE;
1501#endif
1502
1503 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1504 {
1505 crStateLockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
1506 }
1507}
1508
1509void STATE_APIENTRY crStateUnlockArraysEXT()
1510{
1511 CRContext *g = GetCurrentContext();
1512 CRClientState *c = &(g->client);
1513 int i;
1514
1515 if (!c->array.locked)
1516 {
1517 crDebug("crStateUnlockArraysEXT ignored because arrays aren't locked");
1518 return;
1519 }
1520
1521 c->array.locked = GL_FALSE;
1522#ifdef IN_GUEST
1523 c->array.synced = GL_FALSE;
1524#endif
1525
1526 for (i=0; i<CRSTATECLIENT_MAX_VERTEXARRAYS; ++i)
1527 {
1528 crStateUnlockClientPointer(crStateGetClientPointerByIndex(i, &c->array));
1529 }
1530}
1531
1532void STATE_APIENTRY crStateVertexArrayRangeNV(GLsizei length, const GLvoid *pointer)
1533{
1534 /* XXX todo */
1535 crWarning("crStateVertexArrayRangeNV not implemented");
1536}
1537
1538
1539void STATE_APIENTRY crStateFlushVertexArrayRangeNV(void)
1540{
1541 /* XXX todo */
1542 crWarning("crStateFlushVertexArrayRangeNV not implemented");
1543}
1544
1545/*Returns if the given clientpointer could be used on server side directly*/
1546#define CRSTATE_IS_SERVER_CP(cp) (!(cp).enabled || !(cp).p || ((cp).buffer && (cp).buffer->id) || ((cp).locked))
1547
1548static void crStateDumpClientPointer(CRClientPointer *cp, const char *name, int i)
1549{
1550 if (i<0 && cp->enabled)
1551 {
1552 crDebug("CP(%s): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1553 name, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1554 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1555 }
1556 else if (0==i || cp->enabled)
1557 {
1558 crDebug("CP(%s%i): enabled:%d ptr:%p buffer:%p buffer.name:%i locked: %i %s",
1559 name, i, cp->enabled, cp->p, cp->buffer, cp->buffer? cp->buffer->id:-1, (int)cp->locked,
1560 CRSTATE_IS_SERVER_CP(*cp) ? "":"!FAIL!");
1561 }
1562}
1563
1564/*
1565 * Determine if the enabled arrays all live on the server
1566 * (via GL_ARB_vertex_buffer_object).
1567 */
1568GLboolean crStateUseServerArrays(void)
1569{
1570#ifdef CR_ARB_vertex_buffer_object
1571 CRContext *g = GetCurrentContext();
1572 CRClientState *c = &(g->client);
1573 int i;
1574 GLboolean res;
1575
1576 res = CRSTATE_IS_SERVER_CP(c->array.v)
1577 && CRSTATE_IS_SERVER_CP(c->array.n)
1578 && CRSTATE_IS_SERVER_CP(c->array.c)
1579 && CRSTATE_IS_SERVER_CP(c->array.i)
1580 && CRSTATE_IS_SERVER_CP(c->array.e)
1581 && CRSTATE_IS_SERVER_CP(c->array.s)
1582 && CRSTATE_IS_SERVER_CP(c->array.f);
1583
1584 if (res)
1585 {
1586 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1587 if (!CRSTATE_IS_SERVER_CP(c->array.t[i]))
1588 {
1589 res = GL_FALSE;
1590 break;
1591 }
1592 }
1593
1594 if (res)
1595 {
1596 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1597 if (!CRSTATE_IS_SERVER_CP(c->array.a[i]))
1598 {
1599 res = GL_FALSE;
1600 break;
1601 }
1602 }
1603
1604#if defined(DEBUG) && 0
1605 if (!res)
1606 {
1607 crStateDumpClientPointer(&c->array.v, "v", -1);
1608 crStateDumpClientPointer(&c->array.n, "n", -1);
1609 crStateDumpClientPointer(&c->array.c, "c", -1);
1610 crStateDumpClientPointer(&c->array.i, "i", -1);
1611 crStateDumpClientPointer(&c->array.e, "e", -1);
1612 crStateDumpClientPointer(&c->array.s, "s", -1);
1613 crStateDumpClientPointer(&c->array.f, "f", -1);
1614 for (i = 0; (unsigned int)i < g->limits.maxTextureUnits; i++)
1615 crStateDumpClientPointer(&c->array.t[i], "tex", i);
1616 for (i = 0; (unsigned int)i < g->limits.maxVertexProgramAttribs; i++)
1617 crStateDumpClientPointer(&c->array.a[i], "attrib", i);
1618 crDebug("crStateUseServerArrays->%d", res);
1619 }
1620#endif
1621
1622 return res;
1623#else
1624 return GL_FALSE;
1625#endif
1626}
1627
1628
1629/**
1630 * Determine if there's a server-side array element buffer.
1631 * Called by glDrawElements() in packing SPUs to determine if glDrawElements
1632 * should be evaluated (unrolled) locally or if glDrawElements should be
1633 * packed and sent to the server.
1634 */
1635GLboolean
1636crStateUseServerArrayElements(void)
1637{
1638#ifdef CR_ARB_vertex_buffer_object
1639 CRContext *g = GetCurrentContext();
1640 if (g->bufferobject.elementsBuffer &&
1641 g->bufferobject.elementsBuffer->id > 0)
1642 return GL_TRUE;
1643 else
1644 return GL_FALSE;
1645#else
1646 return GL_FALSE;
1647#endif
1648}
1649
1650#define CR_BUFFER_HWID(_p) ((_p) ? (_p)->hwid : 0)
1651
1652void
1653crStateClientDiff(CRClientBits *cb, CRbitvalue *bitID,
1654 CRContext *fromCtx, CRContext *toCtx)
1655{
1656 CRClientState *from = &(fromCtx->client);
1657 const CRClientState *to = &(toCtx->client);
1658 GLint curClientTextureUnit = from->curClientTextureUnit;
1659 int i;
1660 GLint idHwArrayBuffer = CR_BUFFER_HWID(toCtx->bufferobject.arrayBuffer);
1661 const GLint idHwInitialBuffer = idHwArrayBuffer;
1662
1663#ifdef DEBUG_misha
1664 {
1665 GLint tstHwBuffer = -1;
1666 diff_api.GetIntegerv(GL_ARRAY_BUFFER_BINDING, &tstHwBuffer);
1667 CRASSERT(idHwInitialBuffer == tstHwBuffer);
1668 }
1669#endif
1670
1671
1672 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1673 /* one or more vertex pointers is dirty */
1674 if (CHECKDIRTY(cb->v, bitID)) {
1675 if (from->array.v.size != to->array.v.size ||
1676 from->array.v.type != to->array.v.type ||
1677 from->array.v.stride != to->array.v.stride ||
1678 from->array.v.p != to->array.v.p ||
1679 from->array.v.buffer != to->array.v.buffer) {
1680 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.v.buffer);
1681 if (idHwArrayBufferUsed != idHwArrayBuffer)
1682 {
1683 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1684 idHwArrayBuffer = idHwArrayBufferUsed;
1685 }
1686 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1687 to->array.v.stride, to->array.v.p);
1688 from->array.v.size = to->array.v.size;
1689 from->array.v.type = to->array.v.type;
1690 from->array.v.stride = to->array.v.stride;
1691 from->array.v.p = to->array.v.p;
1692 from->array.v.buffer = to->array.v.buffer;
1693 }
1694 CLEARDIRTY2(cb->v, bitID);
1695 }
1696 /* normal */
1697 if (CHECKDIRTY(cb->n, bitID)) {
1698 if (from->array.n.type != to->array.n.type ||
1699 from->array.n.stride != to->array.n.stride ||
1700 from->array.n.p != to->array.n.p ||
1701 from->array.n.buffer != to->array.n.buffer) {
1702 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.n.buffer);
1703 if (idHwArrayBufferUsed != idHwArrayBuffer)
1704 {
1705 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1706 idHwArrayBuffer = idHwArrayBufferUsed;
1707 }
1708 diff_api.NormalPointer(to->array.n.type,
1709 to->array.n.stride, to->array.n.p);
1710 from->array.n.type = to->array.n.type;
1711 from->array.n.stride = to->array.n.stride;
1712 from->array.n.p = to->array.n.p;
1713 from->array.n.buffer = to->array.n.buffer;
1714 }
1715 CLEARDIRTY2(cb->n, bitID);
1716 }
1717 /* color */
1718 if (CHECKDIRTY(cb->c, bitID)) {
1719 if (from->array.c.size != to->array.c.size ||
1720 from->array.c.type != to->array.c.type ||
1721 from->array.c.stride != to->array.c.stride ||
1722 from->array.c.p != to->array.c.p ||
1723 from->array.c.buffer != to->array.c.buffer) {
1724 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.c.buffer);
1725 if (idHwArrayBufferUsed != idHwArrayBuffer)
1726 {
1727 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1728 idHwArrayBuffer = idHwArrayBufferUsed;
1729 }
1730 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
1731 to->array.c.stride, to->array.c.p);
1732 from->array.c.size = to->array.c.size;
1733 from->array.c.type = to->array.c.type;
1734 from->array.c.stride = to->array.c.stride;
1735 from->array.c.p = to->array.c.p;
1736 from->array.c.buffer = to->array.c.buffer;
1737 }
1738 CLEARDIRTY2(cb->c, bitID);
1739 }
1740 /* index */
1741 if (CHECKDIRTY(cb->i, bitID)) {
1742 if (from->array.i.type != to->array.i.type ||
1743 from->array.i.stride != to->array.i.stride ||
1744 from->array.i.p != to->array.i.p ||
1745 from->array.i.buffer != to->array.i.buffer) {
1746 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.i.buffer);
1747 if (idHwArrayBufferUsed != idHwArrayBuffer)
1748 {
1749 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1750 idHwArrayBuffer = idHwArrayBufferUsed;
1751 }
1752 diff_api.IndexPointer(to->array.i.type,
1753 to->array.i.stride, to->array.i.p);
1754 from->array.i.type = to->array.i.type;
1755 from->array.i.stride = to->array.i.stride;
1756 from->array.i.p = to->array.i.p;
1757 from->array.i.buffer = to->array.i.buffer;
1758 }
1759 CLEARDIRTY2(cb->i, bitID);
1760 }
1761 /* texcoords */
1762 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1763 if (CHECKDIRTY(cb->t[i], bitID)) {
1764 if (from->array.t[i].size != to->array.t[i].size ||
1765 from->array.t[i].type != to->array.t[i].type ||
1766 from->array.t[i].stride != to->array.t[i].stride ||
1767 from->array.t[i].p != to->array.t[i].p ||
1768 from->array.t[i].buffer != to->array.t[i].buffer) {
1769 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.t[i].buffer);
1770 if (idHwArrayBufferUsed != idHwArrayBuffer)
1771 {
1772 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1773 idHwArrayBuffer = idHwArrayBufferUsed;
1774 }
1775 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1776 curClientTextureUnit = i;
1777 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
1778 to->array.t[i].stride, to->array.t[i].p);
1779 from->array.t[i].size = to->array.t[i].size;
1780 from->array.t[i].type = to->array.t[i].type;
1781 from->array.t[i].stride = to->array.t[i].stride;
1782 from->array.t[i].p = to->array.t[i].p;
1783 from->array.t[i].buffer = to->array.t[i].buffer;
1784 }
1785 CLEARDIRTY2(cb->t[i], bitID);
1786 }
1787 }
1788 /* edge flag */
1789 if (CHECKDIRTY(cb->e, bitID)) {
1790 if (from->array.e.stride != to->array.e.stride ||
1791 from->array.e.p != to->array.e.p ||
1792 from->array.e.buffer != to->array.e.buffer) {
1793 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.e.buffer);
1794 if (idHwArrayBufferUsed != idHwArrayBuffer)
1795 {
1796 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1797 idHwArrayBuffer = idHwArrayBufferUsed;
1798 }
1799 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
1800 from->array.e.stride = to->array.e.stride;
1801 from->array.e.p = to->array.e.p;
1802 from->array.e.buffer = to->array.e.buffer;
1803 }
1804 CLEARDIRTY2(cb->e, bitID);
1805 }
1806 /* secondary color */
1807 if (CHECKDIRTY(cb->s, bitID)) {
1808 if (from->array.s.size != to->array.s.size ||
1809 from->array.s.type != to->array.s.type ||
1810 from->array.s.stride != to->array.s.stride ||
1811 from->array.s.p != to->array.s.p ||
1812 from->array.s.buffer != to->array.s.buffer) {
1813 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.s.buffer);
1814 if (idHwArrayBufferUsed != idHwArrayBuffer)
1815 {
1816 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1817 idHwArrayBuffer = idHwArrayBufferUsed;
1818 }
1819 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
1820 to->array.s.stride, to->array.s.p);
1821 from->array.s.size = to->array.s.size;
1822 from->array.s.type = to->array.s.type;
1823 from->array.s.stride = to->array.s.stride;
1824 from->array.s.p = to->array.s.p;
1825 from->array.s.buffer = to->array.s.buffer;
1826 }
1827 CLEARDIRTY2(cb->s, bitID);
1828 }
1829 /* fog coord */
1830 if (CHECKDIRTY(cb->f, bitID)) {
1831 if (from->array.f.type != to->array.f.type ||
1832 from->array.f.stride != to->array.f.stride ||
1833 from->array.f.p != to->array.f.p ||
1834 from->array.f.buffer != to->array.f.buffer) {
1835 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.f.buffer);
1836 if (idHwArrayBufferUsed != idHwArrayBuffer)
1837 {
1838 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1839 idHwArrayBuffer = idHwArrayBufferUsed;
1840 }
1841 diff_api.FogCoordPointerEXT(to->array.f.type,
1842 to->array.f.stride, to->array.f.p);
1843 from->array.f.type = to->array.f.type;
1844 from->array.f.stride = to->array.f.stride;
1845 from->array.f.p = to->array.f.p;
1846 from->array.f.buffer = to->array.f.buffer;
1847 }
1848 CLEARDIRTY2(cb->f, bitID);
1849 }
1850#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
1851 /* vertex attributes */
1852 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1853 if (CHECKDIRTY(cb->a[i], bitID)) {
1854 if (from->array.a[i].size != to->array.a[i].size ||
1855 from->array.a[i].type != to->array.a[i].type ||
1856 from->array.a[i].stride != to->array.a[i].stride ||
1857 from->array.a[i].normalized != to->array.a[i].normalized ||
1858 from->array.a[i].p != to->array.a[i].p ||
1859 from->array.a[i].buffer != to->array.a[i].buffer) {
1860 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.a[i].buffer);
1861 if (idHwArrayBufferUsed != idHwArrayBuffer)
1862 {
1863 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1864 idHwArrayBuffer = idHwArrayBufferUsed;
1865 }
1866 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
1867 to->array.a[i].type,
1868 to->array.a[i].normalized,
1869 to->array.a[i].stride,
1870 to->array.a[i].p);
1871 from->array.a[i].size = to->array.a[i].size;
1872 from->array.a[i].type = to->array.a[i].type;
1873 from->array.a[i].stride = to->array.a[i].stride;
1874 from->array.a[i].normalized = to->array.a[i].normalized;
1875 from->array.a[i].p = to->array.a[i].p;
1876 from->array.a[i].buffer = to->array.a[i].buffer;
1877 }
1878 CLEARDIRTY2(cb->a[i], bitID);
1879 }
1880 }
1881#endif
1882 }
1883
1884 if (idHwArrayBuffer != idHwInitialBuffer)
1885 {
1886 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwInitialBuffer);
1887 }
1888
1889 if (CHECKDIRTY(cb->enableClientState, bitID)) {
1890 /* update vertex array enable/disable flags */
1891 glAble able[2];
1892 able[0] = diff_api.Disable;
1893 able[1] = diff_api.Enable;
1894 if (from->array.v.enabled != to->array.v.enabled) {
1895 able[to->array.v.enabled](GL_VERTEX_ARRAY);
1896 from->array.v.enabled = to->array.v.enabled;
1897 }
1898 if (from->array.n.enabled != to->array.n.enabled) {
1899 able[to->array.n.enabled](GL_NORMAL_ARRAY);
1900 from->array.n.enabled = to->array.n.enabled;
1901 }
1902 if (from->array.c.enabled != to->array.c.enabled) {
1903 able[to->array.c.enabled](GL_COLOR_ARRAY);
1904 from->array.c.enabled = to->array.c.enabled;
1905 }
1906 if (from->array.i.enabled != to->array.i.enabled) {
1907 able[to->array.i.enabled](GL_INDEX_ARRAY);
1908 from->array.i.enabled = to->array.i.enabled;
1909 }
1910 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
1911 if (from->array.t[i].enabled != to->array.t[i].enabled) {
1912 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
1913 curClientTextureUnit = i;
1914 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
1915 from->array.t[i].enabled = to->array.t[i].enabled;
1916 }
1917 }
1918 if (from->array.e.enabled != to->array.e.enabled) {
1919 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
1920 from->array.e.enabled = to->array.e.enabled;
1921 }
1922 if (from->array.s.enabled != to->array.s.enabled) {
1923 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
1924 from->array.s.enabled = to->array.s.enabled;
1925 }
1926 if (from->array.f.enabled != to->array.f.enabled) {
1927 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
1928 from->array.f.enabled = to->array.f.enabled;
1929 }
1930 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
1931 if (from->array.a[i].enabled != to->array.a[i].enabled) {
1932 if (to->array.a[i].enabled)
1933 diff_api.EnableVertexAttribArrayARB(i);
1934 else
1935 diff_api.DisableVertexAttribArrayARB(i);
1936 from->array.a[i].enabled = to->array.a[i].enabled;
1937 }
1938 }
1939 CLEARDIRTY2(cb->enableClientState, bitID);
1940 }
1941
1942 if (to->curClientTextureUnit != curClientTextureUnit)
1943 {
1944 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
1945 }
1946}
1947
1948
1949void
1950crStateClientSwitch(CRClientBits *cb, CRbitvalue *bitID,
1951 CRContext *fromCtx, CRContext *toCtx)
1952{
1953 const CRClientState *from = &(fromCtx->client);
1954 const CRClientState *to = &(toCtx->client);
1955 GLint curClientTextureUnit = from->curClientTextureUnit;
1956 int i;
1957 GLint idHwArrayBuffer = CR_BUFFER_HWID(toCtx->bufferobject.arrayBuffer);
1958 const GLint idHwInitialBuffer = idHwArrayBuffer;
1959
1960#ifdef DEBUG_misha
1961 {
1962 GLint tstHwBuffer = -1;
1963 diff_api.GetIntegerv(GL_ARRAY_BUFFER_BINDING, &tstHwBuffer);
1964 CRASSERT(idHwInitialBuffer == tstHwBuffer);
1965 }
1966#endif
1967
1968 if (CHECKDIRTY(cb->clientPointer, bitID)) {
1969 /* one or more vertex pointers is dirty */
1970 if (CHECKDIRTY(cb->v, bitID)) {
1971 if (from->array.v.size != to->array.v.size ||
1972 from->array.v.type != to->array.v.type ||
1973 from->array.v.stride != to->array.v.stride ||
1974 from->array.v.p != to->array.v.p ||
1975 from->array.v.buffer != to->array.v.buffer) {
1976 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.v.buffer);
1977 if (idHwArrayBufferUsed != idHwArrayBuffer)
1978 {
1979 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
1980 idHwArrayBuffer = idHwArrayBufferUsed;
1981 }
1982 diff_api.VertexPointer(to->array.v.size, to->array.v.type,
1983 to->array.v.stride, to->array.v.p);
1984 FILLDIRTY(cb->v);
1985 FILLDIRTY(cb->clientPointer);
1986 FILLDIRTY(cb->dirty);
1987 }
1988 CLEARDIRTY2(cb->v, bitID);
1989 }
1990 /* normal */
1991 if (CHECKDIRTY(cb->n, bitID)) {
1992 if (from->array.n.type != to->array.n.type ||
1993 from->array.n.stride != to->array.n.stride ||
1994 from->array.n.p != to->array.n.p ||
1995 from->array.n.buffer != to->array.n.buffer) {
1996 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.n.buffer);
1997 if (idHwArrayBufferUsed != idHwArrayBuffer)
1998 {
1999 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2000 idHwArrayBuffer = idHwArrayBufferUsed;
2001 }
2002 diff_api.NormalPointer(to->array.n.type,
2003 to->array.n.stride, to->array.n.p);
2004 FILLDIRTY(cb->n);
2005 FILLDIRTY(cb->clientPointer);
2006 FILLDIRTY(cb->dirty);
2007 }
2008 CLEARDIRTY2(cb->n, bitID);
2009 }
2010 /* color */
2011 if (CHECKDIRTY(cb->c, bitID)) {
2012 if (from->array.c.size != to->array.c.size ||
2013 from->array.c.type != to->array.c.type ||
2014 from->array.c.stride != to->array.c.stride ||
2015 from->array.c.p != to->array.c.p ||
2016 from->array.c.buffer != to->array.c.buffer) {
2017 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.c.buffer);
2018 if (idHwArrayBufferUsed != idHwArrayBuffer)
2019 {
2020 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2021 idHwArrayBuffer = idHwArrayBufferUsed;
2022 }
2023 diff_api.ColorPointer(to->array.c.size, to->array.c.type,
2024 to->array.c.stride, to->array.c.p);
2025 FILLDIRTY(cb->c);
2026 FILLDIRTY(cb->clientPointer);
2027 FILLDIRTY(cb->dirty);
2028 }
2029 CLEARDIRTY2(cb->c, bitID);
2030 }
2031 /* index */
2032 if (CHECKDIRTY(cb->i, bitID)) {
2033 if (from->array.i.type != to->array.i.type ||
2034 from->array.i.stride != to->array.i.stride ||
2035 from->array.i.p != to->array.i.p ||
2036 from->array.i.buffer != to->array.i.buffer) {
2037 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.i.buffer);
2038 if (idHwArrayBufferUsed != idHwArrayBuffer)
2039 {
2040 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2041 idHwArrayBuffer = idHwArrayBufferUsed;
2042 }
2043 diff_api.IndexPointer(to->array.i.type,
2044 to->array.i.stride, to->array.i.p);
2045 FILLDIRTY(cb->i);
2046 FILLDIRTY(cb->dirty);
2047 FILLDIRTY(cb->clientPointer);
2048 }
2049 CLEARDIRTY2(cb->i, bitID);
2050 }
2051 /* texcoords */
2052 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
2053 if (CHECKDIRTY(cb->t[i], bitID)) {
2054 if (from->array.t[i].size != to->array.t[i].size ||
2055 from->array.t[i].type != to->array.t[i].type ||
2056 from->array.t[i].stride != to->array.t[i].stride ||
2057 from->array.t[i].p != to->array.t[i].p ||
2058 from->array.t[i].buffer != to->array.t[i].buffer) {
2059 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.t[i].buffer);
2060 if (idHwArrayBufferUsed != idHwArrayBuffer)
2061 {
2062 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2063 idHwArrayBuffer = idHwArrayBufferUsed;
2064 }
2065 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
2066 curClientTextureUnit = i;
2067 diff_api.TexCoordPointer(to->array.t[i].size, to->array.t[i].type,
2068 to->array.t[i].stride, to->array.t[i].p);
2069 FILLDIRTY(cb->t[i]);
2070 FILLDIRTY(cb->clientPointer);
2071 FILLDIRTY(cb->dirty);
2072 }
2073 CLEARDIRTY2(cb->t[i], bitID);
2074 }
2075 }
2076 /* edge flag */
2077 if (CHECKDIRTY(cb->e, bitID)) {
2078 if (from->array.e.stride != to->array.e.stride ||
2079 from->array.e.p != to->array.e.p ||
2080 from->array.e.buffer != to->array.e.buffer) {
2081 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.e.buffer);
2082 if (idHwArrayBufferUsed != idHwArrayBuffer)
2083 {
2084 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2085 idHwArrayBuffer = idHwArrayBufferUsed;
2086 }
2087 diff_api.EdgeFlagPointer(to->array.e.stride, to->array.e.p);
2088 FILLDIRTY(cb->e);
2089 FILLDIRTY(cb->clientPointer);
2090 FILLDIRTY(cb->dirty);
2091 }
2092 CLEARDIRTY2(cb->e, bitID);
2093 }
2094 /* secondary color */
2095 if (CHECKDIRTY(cb->s, bitID)) {
2096 if (from->array.s.size != to->array.s.size ||
2097 from->array.s.type != to->array.s.type ||
2098 from->array.s.stride != to->array.s.stride ||
2099 from->array.s.p != to->array.s.p ||
2100 from->array.s.buffer != to->array.s.buffer) {
2101 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.s.buffer);
2102 if (idHwArrayBufferUsed != idHwArrayBuffer)
2103 {
2104 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2105 idHwArrayBuffer = idHwArrayBufferUsed;
2106 }
2107 diff_api.SecondaryColorPointerEXT(to->array.s.size, to->array.s.type,
2108 to->array.s.stride, to->array.s.p);
2109 FILLDIRTY(cb->s);
2110 FILLDIRTY(cb->clientPointer);
2111 FILLDIRTY(cb->dirty);
2112 }
2113 CLEARDIRTY2(cb->s, bitID);
2114 }
2115 /* fog coord */
2116 if (CHECKDIRTY(cb->f, bitID)) {
2117 if (from->array.f.type != to->array.f.type ||
2118 from->array.f.stride != to->array.f.stride ||
2119 from->array.f.p != to->array.f.p ||
2120 from->array.f.buffer != to->array.f.buffer) {
2121 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.f.buffer);
2122 if (idHwArrayBufferUsed != idHwArrayBuffer)
2123 {
2124 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2125 idHwArrayBuffer = idHwArrayBufferUsed;
2126 }
2127 diff_api.FogCoordPointerEXT(to->array.f.type,
2128 to->array.f.stride, to->array.f.p);
2129 FILLDIRTY(cb->f);
2130 FILLDIRTY(cb->clientPointer);
2131 FILLDIRTY(cb->dirty);
2132 }
2133 CLEARDIRTY2(cb->f, bitID);
2134 }
2135#if defined(CR_NV_vertex_program) || defined(CR_ARB_vertex_program)
2136 /* vertex attributes */
2137 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
2138 if (CHECKDIRTY(cb->a[i], bitID)) {
2139 if (from->array.a[i].size != to->array.a[i].size ||
2140 from->array.a[i].type != to->array.a[i].type ||
2141 from->array.a[i].stride != to->array.a[i].stride ||
2142 from->array.a[i].normalized != to->array.a[i].normalized ||
2143 from->array.a[i].p != to->array.a[i].p ||
2144 from->array.a[i].buffer != to->array.a[i].buffer) {
2145 GLint idHwArrayBufferUsed = CR_BUFFER_HWID(to->array.a[i].buffer);
2146 if (idHwArrayBufferUsed != idHwArrayBuffer)
2147 {
2148 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwArrayBufferUsed);
2149 idHwArrayBuffer = idHwArrayBufferUsed;
2150 }
2151 diff_api.VertexAttribPointerARB(i, to->array.a[i].size,
2152 to->array.a[i].type,
2153 to->array.a[i].normalized,
2154 to->array.a[i].stride,
2155 to->array.a[i].p);
2156 FILLDIRTY(cb->a[i]);
2157 FILLDIRTY(cb->clientPointer);
2158 FILLDIRTY(cb->dirty);
2159 }
2160 CLEARDIRTY2(cb->a[i], bitID);
2161 }
2162 }
2163#endif
2164 }
2165
2166 if (idHwArrayBuffer != idHwInitialBuffer)
2167 {
2168 diff_api.BindBufferARB(GL_ARRAY_BUFFER_ARB, idHwInitialBuffer);
2169 }
2170
2171 if (CHECKDIRTY(cb->enableClientState, bitID)) {
2172 /* update vertex array enable/disable flags */
2173 glAble able[2];
2174 able[0] = diff_api.Disable;
2175 able[1] = diff_api.Enable;
2176 if (from->array.v.enabled != to->array.v.enabled) {
2177 able[to->array.v.enabled](GL_VERTEX_ARRAY);
2178 FILLDIRTY(cb->enableClientState);
2179 FILLDIRTY(cb->dirty);
2180 }
2181 if (from->array.n.enabled != to->array.n.enabled) {
2182 able[to->array.n.enabled](GL_NORMAL_ARRAY);
2183 FILLDIRTY(cb->enableClientState);
2184 FILLDIRTY(cb->dirty);
2185 }
2186 if (from->array.c.enabled != to->array.c.enabled) {
2187 able[to->array.c.enabled](GL_COLOR_ARRAY);
2188 FILLDIRTY(cb->enableClientState);
2189 FILLDIRTY(cb->dirty);
2190 }
2191 if (from->array.i.enabled != to->array.i.enabled) {
2192 able[to->array.i.enabled](GL_INDEX_ARRAY);
2193 FILLDIRTY(cb->enableClientState);
2194 FILLDIRTY(cb->dirty);
2195 }
2196 for (i = 0; (unsigned int)i < toCtx->limits.maxTextureUnits; i++) {
2197 if (from->array.t[i].enabled != to->array.t[i].enabled) {
2198 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + i);
2199 curClientTextureUnit = i;
2200 able[to->array.t[i].enabled](GL_TEXTURE_COORD_ARRAY);
2201 FILLDIRTY(cb->enableClientState);
2202 FILLDIRTY(cb->dirty);
2203 }
2204 }
2205 if (from->array.e.enabled != to->array.e.enabled) {
2206 able[to->array.e.enabled](GL_EDGE_FLAG_ARRAY);
2207 FILLDIRTY(cb->enableClientState);
2208 FILLDIRTY(cb->dirty);
2209 }
2210 if (from->array.s.enabled != to->array.s.enabled) {
2211 able[to->array.s.enabled](GL_SECONDARY_COLOR_ARRAY_EXT);
2212 FILLDIRTY(cb->enableClientState);
2213 FILLDIRTY(cb->dirty);
2214 }
2215 if (from->array.f.enabled != to->array.f.enabled) {
2216 able[to->array.f.enabled](GL_FOG_COORDINATE_ARRAY_EXT);
2217 FILLDIRTY(cb->enableClientState);
2218 FILLDIRTY(cb->dirty);
2219 }
2220 for (i = 0; (unsigned int)i < toCtx->limits.maxVertexProgramAttribs; i++) {
2221 if (from->array.a[i].enabled != to->array.a[i].enabled) {
2222 if (to->array.a[i].enabled)
2223 diff_api.EnableVertexAttribArrayARB(i);
2224 else
2225 diff_api.DisableVertexAttribArrayARB(i);
2226 FILLDIRTY(cb->enableClientState);
2227 FILLDIRTY(cb->dirty);
2228 }
2229 }
2230 CLEARDIRTY2(cb->enableClientState, bitID);
2231 }
2232
2233 if (to->curClientTextureUnit != curClientTextureUnit)
2234 {
2235 diff_api.ClientActiveTextureARB(GL_TEXTURE0_ARB + to->curClientTextureUnit);
2236 }
2237
2238 if (CHECKDIRTY(cb->unpack, bitID))
2239 {
2240 if (from->unpack.rowLength != to->unpack.rowLength)
2241 {
2242 diff_api.PixelStorei(GL_UNPACK_ROW_LENGTH, to->unpack.rowLength);
2243 FILLDIRTY(cb->unpack);
2244 FILLDIRTY(cb->dirty);
2245 }
2246 if (from->unpack.skipRows != to->unpack.skipRows)
2247 {
2248 diff_api.PixelStorei(GL_UNPACK_SKIP_ROWS, to->unpack.skipRows);
2249 FILLDIRTY(cb->unpack);
2250 FILLDIRTY(cb->dirty);
2251 }
2252 if (from->unpack.skipPixels != to->unpack.skipPixels)
2253 {
2254 diff_api.PixelStorei(GL_UNPACK_SKIP_PIXELS, to->unpack.skipPixels);
2255 FILLDIRTY(cb->unpack);
2256 FILLDIRTY(cb->dirty);
2257 }
2258 if (from->unpack.alignment != to->unpack.alignment)
2259 {
2260 diff_api.PixelStorei(GL_UNPACK_ALIGNMENT, to->unpack.alignment);
2261 FILLDIRTY(cb->unpack);
2262 FILLDIRTY(cb->dirty);
2263 }
2264 if (from->unpack.imageHeight != to->unpack.imageHeight)
2265 {
2266 diff_api.PixelStorei(GL_UNPACK_IMAGE_HEIGHT, to->unpack.imageHeight);
2267 FILLDIRTY(cb->unpack);
2268 FILLDIRTY(cb->dirty);
2269 }
2270 if (from->unpack.skipImages != to->unpack.skipImages)
2271 {
2272 diff_api.PixelStorei(GL_UNPACK_SKIP_IMAGES, to->unpack.skipImages);
2273 FILLDIRTY(cb->unpack);
2274 FILLDIRTY(cb->dirty);
2275 }
2276 if (from->unpack.swapBytes != to->unpack.swapBytes)
2277 {
2278 diff_api.PixelStorei(GL_UNPACK_SWAP_BYTES, to->unpack.swapBytes);
2279 FILLDIRTY(cb->unpack);
2280 FILLDIRTY(cb->dirty);
2281 }
2282 if (from->unpack.psLSBFirst != to->unpack.psLSBFirst)
2283 {
2284 diff_api.PixelStorei(GL_UNPACK_LSB_FIRST, to->unpack.psLSBFirst);
2285 FILLDIRTY(cb->unpack);
2286 FILLDIRTY(cb->dirty);
2287 }
2288 CLEARDIRTY2(cb->unpack, bitID);
2289 }
2290
2291 if (CHECKDIRTY(cb->pack, bitID))
2292 {
2293 if (from->pack.rowLength != to->pack.rowLength)
2294 {
2295 diff_api.PixelStorei(GL_PACK_ROW_LENGTH, to->pack.rowLength);
2296 FILLDIRTY(cb->pack);
2297 FILLDIRTY(cb->dirty);
2298 }
2299 if (from->pack.skipRows != to->pack.skipRows)
2300 {
2301 diff_api.PixelStorei(GL_PACK_SKIP_ROWS, to->pack.skipRows);
2302 FILLDIRTY(cb->pack);
2303 FILLDIRTY(cb->dirty);
2304 }
2305 if (from->pack.skipPixels != to->pack.skipPixels)
2306 {
2307 diff_api.PixelStorei(GL_PACK_SKIP_PIXELS, to->pack.skipPixels);
2308 FILLDIRTY(cb->pack);
2309 FILLDIRTY(cb->dirty);
2310 }
2311 if (from->pack.alignment != to->pack.alignment)
2312 {
2313 diff_api.PixelStorei(GL_PACK_ALIGNMENT, to->pack.alignment);
2314 FILLDIRTY(cb->pack);
2315 FILLDIRTY(cb->dirty);
2316 }
2317 if (from->pack.imageHeight != to->pack.imageHeight)
2318 {
2319 diff_api.PixelStorei(GL_PACK_IMAGE_HEIGHT, to->pack.imageHeight);
2320 FILLDIRTY(cb->pack);
2321 FILLDIRTY(cb->dirty);
2322 }
2323 if (from->pack.skipImages != to->pack.skipImages)
2324 {
2325 diff_api.PixelStorei(GL_PACK_SKIP_IMAGES, to->pack.skipImages);
2326 FILLDIRTY(cb->pack);
2327 FILLDIRTY(cb->dirty);
2328 }
2329 if (from->pack.swapBytes != to->pack.swapBytes)
2330 {
2331 diff_api.PixelStorei(GL_PACK_SWAP_BYTES, to->pack.swapBytes);
2332 FILLDIRTY(cb->pack);
2333 FILLDIRTY(cb->dirty);
2334 }
2335 if (from->pack.psLSBFirst != to->pack.psLSBFirst)
2336 {
2337 diff_api.PixelStorei(GL_PACK_LSB_FIRST, to->pack.psLSBFirst);
2338 FILLDIRTY(cb->pack);
2339 FILLDIRTY(cb->dirty);
2340 }
2341 CLEARDIRTY2(cb->pack, bitID);
2342 }
2343
2344 CLEARDIRTY2(cb->dirty, bitID);
2345}
2346
2347CRClientPointer* crStateGetClientPointerByIndex(int index, CRVertexArrays *array)
2348{
2349 CRASSERT(array && index>=0 && index<CRSTATECLIENT_MAX_VERTEXARRAYS);
2350
2351 if (index<7)
2352 {
2353 switch (index)
2354 {
2355 case 0: return &array->v;
2356 case 1: return &array->c;
2357 case 2: return &array->f;
2358 case 3: return &array->s;
2359 case 4: return &array->e;
2360 case 5: return &array->i;
2361 case 6: return &array->n;
2362 }
2363 }
2364 else if (index<(7+CR_MAX_TEXTURE_UNITS))
2365 {
2366 return &array->t[index-7];
2367 }
2368 else
2369 {
2370 return &array->a[index-7-CR_MAX_TEXTURE_UNITS];
2371 }
2372
2373 /*silence the compiler warning*/
2374 CRASSERT(false);
2375 return NULL;
2376}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette