VirtualBox

source: vbox/trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_program.c@ 68474

Last change on this file since 68474 was 63459, checked in by vboxsync, 8 years ago

gcc 6 compile fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 82.1 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#include "state.h"
8#include "state_internals.h"
9#include "cr_mem.h"
10#include "cr_string.h"
11
12
13/*
14 * General notes:
15 *
16 * Vertex programs can change vertices so bounding boxes may not be
17 * practical for tilesort. Tilesort may have to broadcast geometry
18 * when vertex programs are in effect. We could semi-parse vertex
19 * programs to determine if they write to the o[HPOS] register.
20 */
21
22
23/*
24 * Lookup the named program and return a pointer to it.
25 * If the program doesn't exist, create it and reserve its Id and put
26 * it into the hash table.
27 */
28static CRProgram *
29GetProgram(CRProgramState *p, GLenum target, GLuint id)
30{
31 CRProgram *prog;
32
33 prog = crHashtableSearch(p->programHash, id);
34 if (!prog) {
35 prog = (CRProgram *) crCalloc(sizeof(CRProgram));
36 if (!prog)
37 return NULL;
38 prog->target = target;
39 prog->id = id;
40 prog->format = GL_PROGRAM_FORMAT_ASCII_ARB;
41 prog->resident = GL_TRUE;
42 prog->symbolTable = NULL;
43
44 if (id > 0)
45 crHashtableAdd(p->programHash, id, (void *) prog);
46 }
47 return prog;
48}
49
50
51/*
52 * Delete a CRProgram object and all attached data.
53 */
54static void
55DeleteProgram(CRProgram *prog)
56{
57 CRProgramSymbol *symbol, *next;
58
59 if (prog->string)
60 crFree((void *) prog->string);
61
62 for (symbol = prog->symbolTable; symbol; symbol = next) {
63 next = symbol->next;
64 crFree((void *) symbol->name);
65 crFree(symbol);
66 }
67 crFree(prog);
68}
69
70
71/*
72 * Set the named symbol to the value (x, y, z, w).
73 * NOTE: Symbols should only really be added during parsing of the program.
74 * However, the state tracker does not parse the programs (yet). So, when
75 * someone calls glProgramNamedParameter4fNV() we always enter the symbol
76 * since we don't know if it's really valid or not.
77 */
78static void
79SetProgramSymbol(CRProgram *prog, const char *name, GLsizei len,
80 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
81{
82 CRProgramSymbol *symbol;
83
84 for (symbol = prog->symbolTable; symbol; symbol = symbol->next) {
85 /* NOTE: <name> may not be null-terminated! */
86 if (crStrncmp(symbol->name, name, len) == 0 && symbol->name[len] == 0) {
87 /* found it */
88 symbol->value[0] = x;
89 symbol->value[1] = y;
90 symbol->value[2] = z;
91 symbol->value[3] = w;
92 FILLDIRTY(symbol->dirty);
93 return;
94 }
95 }
96 /* add new symbol table entry */
97 symbol = (CRProgramSymbol *) crAlloc(sizeof(CRProgramSymbol));
98 if (symbol) {
99 symbol->name = crStrndup(name, len);
100 symbol->cbName = len;
101 symbol->value[0] = x;
102 symbol->value[1] = y;
103 symbol->value[2] = z;
104 symbol->value[3] = w;
105 symbol->next = prog->symbolTable;
106 prog->symbolTable = symbol;
107 FILLDIRTY(symbol->dirty);
108 }
109}
110
111
112/*
113 * Return a pointer to the values for the given symbol. Return NULL if
114 * the name doesn't exist in the symbol table.
115 */
116static const GLfloat *
117GetProgramSymbol(const CRProgram *prog, const char *name, GLsizei len)
118{
119 CRProgramSymbol *symbol = prog->symbolTable;
120 for (symbol = prog->symbolTable; symbol; symbol = symbol->next) {
121 /* NOTE: <name> may not be null-terminated! */
122 if (crStrncmp(symbol->name, name, len) == 0 && symbol->name[len] == 0) {
123 return symbol->value;
124 }
125 }
126 return NULL;
127}
128
129
130/*
131 * Used by both glBindProgramNV and glBindProgramARB
132 */
133static CRProgram *
134BindProgram(GLenum target, GLuint id,
135 GLenum vertexTarget, GLenum fragmentTarget)
136{
137 CRContext *g = GetCurrentContext();
138 CRProgramState *p = &(g->program);
139 CRStateBits *sb = GetCurrentBits();
140 CRProgramBits *pb = &(sb->program);
141 CRProgram *prog;
142
143 if (g->current.inBeginEnd) {
144 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
145 "glBindProgram called in Begin/End");
146 return NULL;
147 }
148
149 if (id == 0) {
150 if (target == vertexTarget) {
151 prog = p->defaultVertexProgram;
152 }
153 else if (target == fragmentTarget) {
154 prog = p->defaultFragmentProgram;
155 }
156 else {
157 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
158 "glBindProgram(bad target)");
159 return NULL;
160 }
161 }
162 else {
163 prog = GetProgram(p, target, id );
164 }
165
166 if (!prog) {
167 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glBindProgram");
168 return NULL;
169 }
170 else if (prog->target != target) {
171 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
172 "glBindProgram target mismatch");
173 return NULL;
174 }
175
176 if (target == vertexTarget) {
177 p->currentVertexProgram = prog;
178 p->vpProgramBinding = id;
179 DIRTY(pb->dirty, g->neg_bitid);
180 DIRTY(pb->vpBinding, g->neg_bitid);
181 }
182 else if (target == fragmentTarget) {
183 p->currentFragmentProgram = prog;
184 p->fpProgramBinding = id;
185 DIRTY(pb->dirty, g->neg_bitid);
186 DIRTY(pb->fpBinding, g->neg_bitid);
187 }
188 return prog;
189}
190
191
192void STATE_APIENTRY crStateBindProgramNV(GLenum target, GLuint id)
193{
194 CRProgram *prog = BindProgram(target, id, GL_VERTEX_PROGRAM_NV,
195 GL_FRAGMENT_PROGRAM_NV);
196 if (prog) {
197 prog->isARBprogram = GL_FALSE;
198 }
199}
200
201
202void STATE_APIENTRY crStateBindProgramARB(GLenum target, GLuint id)
203{
204 CRProgram *prog = BindProgram(target, id, GL_VERTEX_PROGRAM_ARB,
205 GL_FRAGMENT_PROGRAM_ARB);
206 if (prog) {
207 prog->isARBprogram = GL_TRUE;
208 }
209}
210
211
212void STATE_APIENTRY crStateDeleteProgramsARB(GLsizei n, const GLuint *ids)
213{
214 CRContext *g = GetCurrentContext();
215 CRProgramState *p = &(g->program);
216 CRStateBits *sb = GetCurrentBits();
217 CRProgramBits *pb = &(sb->program);
218 GLint i;
219
220 if (g->current.inBeginEnd) {
221 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
222 "glDeleteProgramsNV called in Begin/End");
223 return;
224 }
225
226 if (n < 0)
227 {
228 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glDeleteProgramsNV(n)");
229 return;
230 }
231
232 for (i = 0; i < n; i++) {
233 CRProgram *prog;
234 if (ids[i] > 0) {
235 prog = (CRProgram *) crHashtableSearch(p->programHash, ids[i]);
236 if (prog == p->currentVertexProgram) {
237 p->currentVertexProgram = p->defaultVertexProgram;
238 DIRTY(pb->dirty, g->neg_bitid);
239 DIRTY(pb->vpBinding, g->neg_bitid);
240 }
241 else if (prog == p->currentFragmentProgram) {
242 p->currentFragmentProgram = p->defaultFragmentProgram;
243 DIRTY(pb->dirty, g->neg_bitid);
244 DIRTY(pb->fpBinding, g->neg_bitid);
245 }
246 if (prog) {
247 DeleteProgram(prog);
248 }
249 crHashtableDelete(p->programHash, ids[i], GL_FALSE);
250 }
251 }
252}
253
254
255void STATE_APIENTRY crStateExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params)
256{
257 /* Hmmm, this is really hard to do if we don't actually execute
258 * the program in a software simulation.
259 */
260 (void)params;
261 (void)target;
262 (void)id;
263}
264
265
266void STATE_APIENTRY crStateGenProgramsNV(GLsizei n, GLuint *ids)
267{
268 CRContext *g = GetCurrentContext();
269 CRProgramState *p = &(g->program);
270
271 crStateGenNames(g, p->programHash, n, ids);
272}
273
274void STATE_APIENTRY crStateGenProgramsARB(GLsizei n, GLuint *ids)
275{
276 crStateGenProgramsNV(n, ids);
277}
278
279
280GLboolean STATE_APIENTRY crStateIsProgramARB(GLuint id)
281{
282 CRContext *g = GetCurrentContext();
283 CRProgramState *p = &(g->program);
284 CRProgram *prog;
285
286 if (g->current.inBeginEnd) {
287 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
288 "glIsProgram called in Begin/End");
289 return GL_FALSE;
290 }
291
292 if (id == 0) {
293 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
294 "glIsProgram(id==0)");
295 return GL_FALSE;
296 }
297
298 prog = (CRProgram *) crHashtableSearch(p->programHash, id);
299 if (prog)
300 return GL_TRUE;
301 else
302 return GL_FALSE;
303}
304
305
306GLboolean STATE_APIENTRY crStateAreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences)
307{
308 CRContext *g = GetCurrentContext();
309 CRProgramState *p = &(g->program);
310 int i;
311 GLboolean retVal = GL_TRUE;
312
313 if (n < 0) {
314 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
315 "glAreProgramsResidentNV(n)");
316 return GL_FALSE;
317 }
318
319 for (i = 0; i < n; i++) {
320 CRProgram *prog;
321
322 if (ids[i] == 0) {
323 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
324 "glAreProgramsResidentNV(id)");
325 return GL_FALSE;
326 }
327
328 prog = (CRProgram *) crHashtableSearch(p->programHash, ids[i]);
329 if (!prog) {
330 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
331 "glAreProgramsResidentNV(id)");
332 return GL_FALSE;
333 }
334
335 if (!prog->resident) {
336 retVal = GL_FALSE;
337 break;
338 }
339 }
340
341 if (retVal == GL_FALSE) {
342 for (i = 0; i < n; i++) {
343 CRProgram *prog = (CRProgram *)
344 crHashtableSearch(p->programHash, ids[i]);
345 residences[i] = prog->resident;
346 }
347 }
348
349 return retVal;
350}
351
352
353void STATE_APIENTRY crStateRequestResidentProgramsNV(GLsizei n, const GLuint *ids)
354{
355 CRContext *g = GetCurrentContext();
356 CRProgramState *p = &(g->program);
357 GLint i;
358
359 if (g->current.inBeginEnd) {
360 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
361 "glRequestResidentProgramsNV called in Begin/End");
362 return;
363 }
364
365 if (n < 0) {
366 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
367 "glRequestResidentProgramsNV(n<0)");
368 return;
369 }
370
371 for (i = 0; i < n ; i++) {
372 CRProgram *prog = (CRProgram *) crHashtableSearch(p->programHash, ids[i]);
373 if (prog)
374 prog->resident = GL_TRUE;
375 }
376}
377
378
379void STATE_APIENTRY crStateLoadProgramNV(GLenum target, GLuint id, GLsizei len,
380 const GLubyte *program)
381{
382 CRContext *g = GetCurrentContext();
383 CRProgramState *p = &(g->program);
384 CRStateBits *sb = GetCurrentBits();
385 CRProgramBits *pb = &(sb->program);
386 CRProgram *prog;
387 GLubyte *progCopy;
388
389 if (g->current.inBeginEnd) {
390 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
391 "glLoadProgramNV called in Begin/End");
392 return;
393 }
394
395 if (id == 0) {
396 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
397 "glLoadProgramNV(id==0)");
398 return;
399 }
400
401 prog = GetProgram(p, target, id);
402
403 if (!prog) {
404 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glLoadProgramNV");
405 return;
406 }
407 else if (prog && prog->target != target) {
408 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
409 "glLoadProgramNV(target)");
410 return;
411 }
412
413 progCopy = crAlloc(len);
414 if (!progCopy) {
415 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glLoadProgramNV");
416 return;
417 }
418 if (crStrncmp((const char *) program,"!!FP1.0", 7) != 0
419 && crStrncmp((const char *) program,"!!FCP1.0", 8) != 0
420 && crStrncmp((const char *) program,"!!VP1.0", 7) != 0
421 && crStrncmp((const char *) program,"!!VP1.1", 7) != 0
422 && crStrncmp((const char *) program,"!!VP2.0", 7) != 0
423 && crStrncmp((const char *) program,"!!VSP1.0", 8) != 0) {
424 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glLoadProgramNV");
425 crDebug("program = (%s)\n",program);
426 return;
427 }
428 crMemcpy(progCopy, program, len);
429 if (prog->string)
430 crFree((void *) prog->string);
431
432 prog->string = progCopy;
433 prog->length = len;
434 prog->isARBprogram = GL_FALSE;
435
436 DIRTY(prog->dirtyProgram, g->neg_bitid);
437 DIRTY(pb->dirty, g->neg_bitid);
438}
439
440
441void STATE_APIENTRY crStateProgramStringARB(GLenum target, GLenum format,
442 GLsizei len, const GLvoid *string)
443{
444 CRContext *g = GetCurrentContext();
445 CRProgramState *p = &(g->program);
446 CRStateBits *sb = GetCurrentBits();
447 CRProgramBits *pb = &(sb->program);
448 CRProgram *prog;
449 GLubyte *progCopy;
450
451 if (g->current.inBeginEnd) {
452 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
453 "glProgramStringARB called in Begin/End");
454 return;
455 }
456
457 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
458 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
459 "glProgramStringARB(format)");
460 return;
461 }
462
463 if (target == GL_FRAGMENT_PROGRAM_ARB
464 && g->extensions.ARB_fragment_program) {
465 prog = p->currentFragmentProgram;
466 }
467 else if (target == GL_VERTEX_PROGRAM_ARB
468 && g->extensions.ARB_vertex_program) {
469 prog = p->currentVertexProgram;
470 }
471 else {
472 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
473 "glProgramStringARB(target)");
474 return;
475 }
476
477 CRASSERT(prog);
478
479
480 progCopy = crAlloc(len);
481 if (!progCopy) {
482 crStateError(__LINE__, __FILE__, GL_OUT_OF_MEMORY, "glProgramStringARB");
483 return;
484 }
485 if (crStrncmp(string,"!!ARBvp1.0", 10) != 0
486 && crStrncmp(string,"!!ARBfp1.0", 10) != 0) {
487 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE, "glProgramStringARB");
488 return;
489 }
490 crMemcpy(progCopy, string, len);
491 if (prog->string)
492 crFree((void *) prog->string);
493
494 prog->string = progCopy;
495 prog->length = len;
496 prog->format = format;
497 prog->isARBprogram = GL_TRUE;
498
499 DIRTY(prog->dirtyProgram, g->neg_bitid);
500 DIRTY(pb->dirty, g->neg_bitid);
501}
502
503
504void STATE_APIENTRY crStateGetProgramivNV(GLuint id, GLenum pname, GLint *params)
505{
506 CRContext *g = GetCurrentContext();
507 CRProgramState *p = &(g->program);
508 CRProgram *prog;
509
510 if (g->current.inBeginEnd) {
511 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
512 "glGetProgramivNV called in Begin/End");
513 return;
514 }
515
516 if (id == 0) {
517 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
518 "glGetProgramivNV(bad id)");
519 return;
520 }
521
522 prog = (CRProgram *) crHashtableSearch(p->programHash, id);
523 if (!prog) {
524 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
525 "glGetProgramivNV(bad id)");
526 return;
527 }
528
529 switch (pname) {
530 case GL_PROGRAM_TARGET_NV:
531 *params = prog->target;
532 return;
533 case GL_PROGRAM_LENGTH_NV:
534 *params = prog->length;
535 return;
536 case GL_PROGRAM_RESIDENT_NV:
537 *params = prog->resident;
538 return;
539 default:
540 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
541 "glGetProgramivNV(pname)");
542 return;
543 }
544}
545
546
547void STATE_APIENTRY crStateGetProgramStringNV(GLuint id, GLenum pname, GLubyte *program)
548{
549 CRContext *g = GetCurrentContext();
550 CRProgramState *p = &(g->program);
551 CRProgram *prog;
552
553 if (pname != GL_PROGRAM_STRING_NV) {
554 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
555 "glGetProgramStringNV(pname)");
556 return;
557 }
558
559 if (g->current.inBeginEnd) {
560 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
561 "glGetProgramStringNV called in Begin/End");
562 return;
563 }
564
565 if (id == 0) {
566 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
567 "glGetProgramStringNV(bad id)");
568 return;
569 }
570
571 prog = (CRProgram *) crHashtableSearch(p->programHash, id);
572 if (!prog) {
573 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
574 "glGetProgramStringNV(bad id)");
575 return;
576 }
577
578 crMemcpy(program, prog->string, prog->length);
579}
580
581
582void STATE_APIENTRY crStateGetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
583{
584 CRContext *g = GetCurrentContext();
585 CRProgramState *p = &(g->program);
586 CRProgram *prog;
587
588 if (target == GL_VERTEX_PROGRAM_ARB) {
589 prog = p->currentVertexProgram;
590 }
591 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
592 prog = p->currentFragmentProgram;
593 }
594 else {
595 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
596 "glGetProgramStringNV(target)");
597 return;
598 }
599
600 if (pname != GL_PROGRAM_STRING_NV) {
601 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
602 "glGetProgramStringNV(pname)");
603 return;
604 }
605
606 if (g->current.inBeginEnd) {
607 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
608 "glGetProgramStringNV called in Begin/End");
609 return;
610 }
611
612 crMemcpy(string, prog->string, prog->length);
613}
614
615
616void STATE_APIENTRY crStateProgramParameter4dNV(GLenum target, GLuint index,
617 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
618{
619 crStateProgramParameter4fNV(target, index, (GLfloat) x, (GLfloat) y,
620 (GLfloat) z, (GLfloat) w);
621}
622
623
624void STATE_APIENTRY crStateProgramParameter4dvNV(GLenum target, GLuint index,
625 const GLdouble *params)
626{
627 crStateProgramParameter4fNV(target, index,
628 (GLfloat) params[0], (GLfloat) params[1],
629 (GLfloat) params[2], (GLfloat) params[3]);
630}
631
632
633void STATE_APIENTRY crStateProgramParameter4fNV(GLenum target, GLuint index,
634 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
635{
636 CRContext *g = GetCurrentContext();
637 CRProgramState *p = &(g->program);
638 CRStateBits *sb = GetCurrentBits();
639 CRProgramBits *pb = &(sb->program);
640
641 if (g->current.inBeginEnd) {
642 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
643 "glProgramParameterNV called in Begin/End");
644 return;
645 }
646
647 if (target == GL_VERTEX_PROGRAM_NV) {
648 if (index < g->limits.maxVertexProgramEnvParams) {
649 p->vertexParameters[index][0] = x;
650 p->vertexParameters[index][1] = y;
651 p->vertexParameters[index][2] = z;
652 p->vertexParameters[index][3] = w;
653 DIRTY(pb->dirty, g->neg_bitid);
654 DIRTY(pb->vertexEnvParameter[index], g->neg_bitid);
655 DIRTY(pb->vertexEnvParameters, g->neg_bitid);
656 }
657 else {
658 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
659 "glProgramParameterNV(index=%d)", index);
660 return;
661 }
662 }
663 else {
664 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
665 "glProgramParameterNV(target)");
666 return;
667 }
668}
669
670
671void STATE_APIENTRY crStateProgramParameter4fvNV(GLenum target, GLuint index,
672 const GLfloat *params)
673{
674 crStateProgramParameter4fNV(target, index,
675 params[0], params[1], params[2], params[3]);
676}
677
678
679void STATE_APIENTRY crStateProgramParameters4dvNV(GLenum target, GLuint index,
680 GLuint num, const GLdouble *params)
681{
682 CRContext *g = GetCurrentContext();
683 CRProgramState *p = &(g->program);
684 CRStateBits *sb = GetCurrentBits();
685 CRProgramBits *pb = &(sb->program);
686
687 if (g->current.inBeginEnd) {
688 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
689 "glProgramParameters4dvNV called in Begin/End");
690 return;
691 }
692
693 if (target == GL_VERTEX_PROGRAM_NV) {
694 if (index + num < g->limits.maxVertexProgramEnvParams) {
695 GLuint i;
696 for (i = 0; i < num; i++) {
697 p->vertexParameters[index+i][0] = (GLfloat) params[i*4+0];
698 p->vertexParameters[index+i][1] = (GLfloat) params[i*4+1];
699 p->vertexParameters[index+i][2] = (GLfloat) params[i*4+2];
700 p->vertexParameters[index+i][3] = (GLfloat) params[i*4+3];
701 }
702 DIRTY(pb->dirty, g->neg_bitid);
703 DIRTY(pb->vertexEnvParameters, g->neg_bitid);
704 }
705 else {
706 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
707 "glProgramParameters4dvNV(index+num)");
708 return;
709 }
710 }
711 else {
712 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
713 "glProgramParameterNV(target)");
714 return;
715 }
716}
717
718
719void STATE_APIENTRY crStateProgramParameters4fvNV(GLenum target, GLuint index,
720 GLuint num, const GLfloat *params)
721{
722 CRContext *g = GetCurrentContext();
723 CRProgramState *p = &(g->program);
724 CRStateBits *sb = GetCurrentBits();
725 CRProgramBits *pb = &(sb->program);
726
727 if (g->current.inBeginEnd) {
728 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
729 "glProgramParameters4dvNV called in Begin/End");
730 return;
731 }
732
733 if (target == GL_VERTEX_PROGRAM_NV) {
734 if (index + num < g->limits.maxVertexProgramEnvParams) {
735 GLuint i;
736 for (i = 0; i < num; i++) {
737 p->vertexParameters[index+i][0] = params[i*4+0];
738 p->vertexParameters[index+i][1] = params[i*4+1];
739 p->vertexParameters[index+i][2] = params[i*4+2];
740 p->vertexParameters[index+i][3] = params[i*4+3];
741 }
742 DIRTY(pb->dirty, g->neg_bitid);
743 DIRTY(pb->vertexEnvParameters, g->neg_bitid);
744 }
745 else {
746 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
747 "glProgramParameters4dvNV(index+num)");
748 return;
749 }
750 }
751 else {
752 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
753 "glProgramParameterNV(target)");
754 return;
755 }
756}
757
758
759void STATE_APIENTRY crStateGetProgramParameterfvNV(GLenum target, GLuint index,
760 GLenum pname, GLfloat *params)
761{
762 CRContext *g = GetCurrentContext();
763 CRProgramState *p = &(g->program);
764
765 if (g->current.inBeginEnd) {
766 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
767 "glGetProgramParameterfvNV called in Begin/End");
768 return;
769 }
770
771 if (target == GL_VERTEX_PROGRAM_NV) {
772 if (pname == GL_PROGRAM_PARAMETER_NV) {
773 if (index < g->limits.maxVertexProgramEnvParams) {
774 params[0] = p->vertexParameters[index][0];
775 params[1] = p->vertexParameters[index][1];
776 params[2] = p->vertexParameters[index][2];
777 params[3] = p->vertexParameters[index][3];
778 }
779 else {
780 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
781 "glGetProgramParameterfvNV(index)");
782 return;
783 }
784 }
785 else {
786 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
787 "glGetProgramParameterfvNV(pname)");
788 return;
789 }
790 }
791 else {
792 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
793 "glGetProgramParameterfvNV(target)");
794 return;
795 }
796}
797
798
799void STATE_APIENTRY crStateGetProgramParameterdvNV(GLenum target, GLuint index,
800 GLenum pname, GLdouble *params)
801{
802 CRContext *g = GetCurrentContext();
803 CRProgramState *p = &(g->program);
804
805 if (g->current.inBeginEnd) {
806 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
807 "glGetProgramParameterdvNV called in Begin/End");
808 return;
809 }
810
811 if (target == GL_VERTEX_PROGRAM_NV) {
812 if (pname == GL_PROGRAM_PARAMETER_NV) {
813 if (index < g->limits.maxVertexProgramEnvParams) {
814 params[0] = p->vertexParameters[index][0];
815 params[1] = p->vertexParameters[index][1];
816 params[2] = p->vertexParameters[index][2];
817 params[3] = p->vertexParameters[index][3];
818 }
819 else {
820 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
821 "glGetProgramParameterdvNV(index)");
822 return;
823 }
824 }
825 else {
826 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
827 "glGetProgramParameterdvNV(pname)");
828 return;
829 }
830 }
831 else {
832 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
833 "glGetProgramParameterdvNV(target)");
834 return;
835 }
836}
837
838
839void STATE_APIENTRY crStateTrackMatrixNV(GLenum target, GLuint address,
840 GLenum matrix, GLenum transform)
841{
842 CRContext *g = GetCurrentContext();
843 CRProgramState *p = &(g->program);
844 CRStateBits *sb = GetCurrentBits();
845 CRProgramBits *pb = &(sb->program);
846
847 if (g->current.inBeginEnd) {
848 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
849 "glGetTrackMatrixivNV called in Begin/End");
850 return;
851 }
852
853 if (target == GL_VERTEX_PROGRAM_NV) {
854 if (address & 0x3) {
855 /* addr must be multiple of four */
856 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
857 "glTrackMatrixNV(address)");
858 return;
859 }
860
861 switch (matrix) {
862 case GL_NONE:
863 case GL_MODELVIEW:
864 case GL_PROJECTION:
865 case GL_TEXTURE:
866 case GL_COLOR:
867 case GL_MODELVIEW_PROJECTION_NV:
868 case GL_MATRIX0_NV:
869 case GL_MATRIX1_NV:
870 case GL_MATRIX2_NV:
871 case GL_MATRIX3_NV:
872 case GL_MATRIX4_NV:
873 case GL_MATRIX5_NV:
874 case GL_MATRIX6_NV:
875 case GL_MATRIX7_NV:
876 case GL_TEXTURE0_ARB:
877 case GL_TEXTURE1_ARB:
878 case GL_TEXTURE2_ARB:
879 case GL_TEXTURE3_ARB:
880 case GL_TEXTURE4_ARB:
881 case GL_TEXTURE5_ARB:
882 case GL_TEXTURE6_ARB:
883 case GL_TEXTURE7_ARB:
884 /* OK, fallthrough */
885 break;
886 default:
887 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
888 "glTrackMatrixNV(matrix = %x)",matrix);
889 return;
890 }
891
892 switch (transform) {
893 case GL_IDENTITY_NV:
894 case GL_INVERSE_NV:
895 case GL_TRANSPOSE_NV:
896 case GL_INVERSE_TRANSPOSE_NV:
897 /* OK, fallthrough */
898 break;
899 default:
900 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
901 "glTrackMatrixNV(transform = %x)",transform);
902 return;
903 }
904
905 p->TrackMatrix[address / 4] = matrix;
906 p->TrackMatrixTransform[address / 4] = transform;
907 DIRTY(pb->trackMatrix[address/4], g->neg_bitid);
908 DIRTY(pb->dirty, g->neg_bitid);
909 }
910 else {
911 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
912 "glTrackMatrixNV(target = %x)",target);
913 }
914}
915
916
917void STATE_APIENTRY crStateGetTrackMatrixivNV(GLenum target, GLuint address,
918 GLenum pname, GLint *params)
919{
920 CRContext *g = GetCurrentContext();
921 CRProgramState *p = &(g->program);
922
923 if (g->current.inBeginEnd) {
924 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
925 "glGetTrackMatrixivNV called in Begin/End");
926 return;
927 }
928
929 if (target == GL_VERTEX_PROGRAM_NV) {
930 if ((address & 0x3) || address >= g->limits.maxVertexProgramEnvParams) {
931 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
932 "glGetTrackMatrixivNV(address)");
933 return;
934 }
935 if (pname == GL_TRACK_MATRIX_NV) {
936 params[0] = (GLint) p->TrackMatrix[address / 4];
937 }
938 else if (pname == GL_TRACK_MATRIX_TRANSFORM_NV) {
939 params[0] = (GLint) p->TrackMatrixTransform[address / 4];
940 }
941 else {
942 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
943 "glGetTrackMatrixivNV(pname)");
944 return;
945 }
946 }
947 else {
948 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
949 "glGetTrackMatrixivNV(target)");
950 return;
951 }
952}
953
954
955void STATE_APIENTRY crStateGetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params)
956{
957 /* init vars to prevent compiler warnings/errors */
958 GLfloat floatParams[4] = { 0.0, 0.0, 0.0, 0.0 };
959 crStateGetVertexAttribfvNV(index, pname, floatParams);
960 params[0] = floatParams[0];
961 if (pname == GL_CURRENT_ATTRIB_NV) {
962 params[1] = floatParams[1];
963 params[2] = floatParams[2];
964 params[3] = floatParams[3];
965 }
966}
967
968
969void STATE_APIENTRY crStateGetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params)
970{
971 CRContext *g = GetCurrentContext();
972
973 if (g->current.inBeginEnd) {
974 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
975 "glGetVertexAttribfvNV called in Begin/End");
976 return;
977 }
978
979 if (index >= CR_MAX_VERTEX_ATTRIBS) {
980 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
981 "glGetVertexAttribfvNV(index)");
982 return;
983 }
984
985 switch (pname) {
986 case GL_ATTRIB_ARRAY_SIZE_NV:
987 params[0] = (GLfloat) g->client.array.a[index].size;
988 break;
989 case GL_ATTRIB_ARRAY_STRIDE_NV:
990 params[0] = (GLfloat) g->client.array.a[index].stride;
991 break;
992 case GL_ATTRIB_ARRAY_TYPE_NV:
993 params[0] = (GLfloat) g->client.array.a[index].type;
994 break;
995 case GL_CURRENT_ATTRIB_NV:
996 crStateCurrentRecover();
997 COPY_4V(params , g->current.vertexAttrib[index]);
998 break;
999 default:
1000 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetVertexAttribfvNV");
1001 return;
1002 }
1003}
1004
1005
1006void STATE_APIENTRY crStateGetVertexAttribivNV(GLuint index, GLenum pname, GLint *params)
1007{
1008 /* init vars to prevent compiler warnings/errors */
1009 GLfloat floatParams[4] = { 0.0, 0.0, 0.0, 0.0 };
1010 crStateGetVertexAttribfvNV(index, pname, floatParams);
1011 params[0] = (GLint) floatParams[0];
1012 if (pname == GL_CURRENT_ATTRIB_NV) {
1013 params[1] = (GLint) floatParams[1];
1014 params[2] = (GLint) floatParams[2];
1015 params[3] = (GLint) floatParams[3];
1016 }
1017}
1018
1019
1020
1021void STATE_APIENTRY crStateGetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
1022{
1023 CRContext *g = GetCurrentContext();
1024
1025 if (g->current.inBeginEnd) {
1026 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1027 "glGetVertexAttribfvARB called in Begin/End");
1028 return;
1029 }
1030
1031 if (index >= CR_MAX_VERTEX_ATTRIBS) {
1032 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1033 "glGetVertexAttribfvARB(index)");
1034 return;
1035 }
1036
1037 switch (pname) {
1038 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
1039 params[0] = (GLfloat) g->client.array.a[index].enabled;
1040 break;
1041 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
1042 params[0] = (GLfloat) g->client.array.a[index].size;
1043 break;
1044 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
1045 params[0] = (GLfloat) g->client.array.a[index].stride;
1046 break;
1047 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
1048 params[0] = (GLfloat) g->client.array.a[index].type;
1049 break;
1050 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
1051 params[0] = (GLfloat) g->client.array.a[index].normalized;
1052 break;
1053 case GL_CURRENT_VERTEX_ATTRIB_ARB:
1054 crStateCurrentRecover();
1055 COPY_4V(params , g->current.vertexAttrib[index]);
1056 break;
1057 default:
1058 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM, "glGetVertexAttribfvARB");
1059 return;
1060 }
1061}
1062
1063
1064void STATE_APIENTRY crStateGetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
1065{
1066 /* init vars to prevent compiler warnings/errors */
1067 GLfloat floatParams[4] = { 0.0, 0.0, 0.0, 0.0 };
1068 crStateGetVertexAttribfvARB(index, pname, floatParams);
1069 params[0] = (GLint) floatParams[0];
1070 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1071 params[1] = (GLint) floatParams[1];
1072 params[2] = (GLint) floatParams[2];
1073 params[3] = (GLint) floatParams[3];
1074 }
1075}
1076
1077
1078void STATE_APIENTRY crStateGetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
1079{
1080 /* init vars to prevent compiler warnings/errors */
1081 GLfloat floatParams[4] = { 0.0, 0.0, 0.0, 0.0 };
1082 crStateGetVertexAttribfvARB(index, pname, floatParams);
1083 params[0] = floatParams[0];
1084 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
1085 params[1] = floatParams[1];
1086 params[2] = floatParams[2];
1087 params[3] = floatParams[3];
1088 }
1089}
1090
1091
1092/**********************************************************************/
1093
1094/*
1095 * Added by GL_NV_fragment_program
1096 */
1097
1098void STATE_APIENTRY crStateProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1099{
1100 CRContext *g = GetCurrentContext();
1101 CRProgramState *p = &(g->program);
1102 CRProgram *prog;
1103 CRStateBits *sb = GetCurrentBits();
1104 CRProgramBits *pb = &(sb->program);
1105
1106 if (g->current.inBeginEnd) {
1107 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1108 "glProgramNamedParameterfNV called in Begin/End");
1109 return;
1110 }
1111
1112 prog = (CRProgram *) crHashtableSearch(p->programHash, id);
1113 if (!prog) {
1114 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1115 "glProgramNamedParameterNV(bad id %d)", id);
1116 return;
1117 }
1118
1119 if (prog->target != GL_FRAGMENT_PROGRAM_NV) {
1120 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1121 "glProgramNamedParameterNV(target)");
1122 return;
1123 }
1124
1125 SetProgramSymbol(prog, (const char *)name, len, x, y, z, w);
1126 DIRTY(prog->dirtyNamedParams, g->neg_bitid);
1127 DIRTY(pb->dirty, g->neg_bitid);
1128}
1129
1130
1131void STATE_APIENTRY crStateProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
1132{
1133 crStateProgramNamedParameter4fNV(id, len, name, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
1134}
1135
1136
1137void STATE_APIENTRY crStateProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name, const GLfloat v[])
1138{
1139 crStateProgramNamedParameter4fNV(id, len, name, v[0], v[1], v[2], v[3]);
1140}
1141
1142
1143void STATE_APIENTRY crStateProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name, const GLdouble v[])
1144{
1145 crStateProgramNamedParameter4fNV(id, len, name, (GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]);
1146}
1147
1148
1149void STATE_APIENTRY crStateGetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name, GLfloat *params)
1150{
1151 CRContext *g = GetCurrentContext();
1152 CRProgramState *p = &(g->program);
1153 const CRProgram *prog;
1154 const GLfloat *value;
1155
1156 if (g->current.inBeginEnd) {
1157 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1158 "glGetProgramNamedParameterfNV called in Begin/End");
1159 return;
1160 }
1161
1162 prog = (const CRProgram *) crHashtableSearch(p->programHash, id);
1163 if (!prog) {
1164 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1165 "glGetProgramNamedParameterNV(bad id)");
1166 return;
1167 }
1168
1169 if (prog->target != GL_FRAGMENT_PROGRAM_NV) {
1170 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1171 "glGetProgramNamedParameterNV(target)");
1172 return;
1173 }
1174
1175 value = GetProgramSymbol(prog, (const char *)name, len);
1176 if (!value) {
1177 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1178 "glGetProgramNamedParameterNV(name)");
1179 return;
1180 }
1181
1182 params[0] = value[0];
1183 params[1] = value[1];
1184 params[2] = value[2];
1185 params[3] = value[3];
1186}
1187
1188
1189void STATE_APIENTRY crStateGetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name, GLdouble *params)
1190{
1191 GLfloat floatParams[4];
1192 crStateGetProgramNamedParameterfvNV(id, len, name, floatParams);
1193 params[0] = floatParams[0];
1194 params[1] = floatParams[1];
1195 params[2] = floatParams[2];
1196 params[3] = floatParams[3];
1197}
1198
1199
1200void STATE_APIENTRY crStateProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
1201{
1202 crStateProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
1203}
1204
1205
1206void STATE_APIENTRY crStateProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble *params)
1207{
1208 crStateProgramLocalParameter4fARB(target, index, (GLfloat) params[0], (GLfloat) params[1],
1209 (GLfloat) params[2], (GLfloat) params[3]);
1210}
1211
1212
1213void STATE_APIENTRY crStateProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1214{
1215 CRContext *g = GetCurrentContext();
1216 CRProgramState *p = &(g->program);
1217 CRProgram *prog;
1218 CRStateBits *sb = GetCurrentBits();
1219 CRProgramBits *pb = &(sb->program);
1220
1221 if (g->current.inBeginEnd) {
1222 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1223 "glProgramLocalParameterARB called in Begin/End");
1224 return;
1225 }
1226
1227 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1228 if (index >= CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS) {
1229 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1230 "glProgramLocalParameterARB(index)");
1231 return;
1232 }
1233 prog = p->currentFragmentProgram;
1234 }
1235 else if (target == GL_VERTEX_PROGRAM_ARB) {
1236 if (index >= CR_MAX_VERTEX_PROGRAM_LOCAL_PARAMS) {
1237 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1238 "glProgramLocalParameterARB(index)");
1239 return;
1240 }
1241 prog = p->currentVertexProgram;
1242 }
1243 else {
1244 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1245 "glProgramLocalParameterARB(target)");
1246 return;
1247 }
1248
1249 CRASSERT(prog);
1250
1251 prog->parameters[index][0] = x;
1252 prog->parameters[index][1] = y;
1253 prog->parameters[index][2] = z;
1254 prog->parameters[index][3] = w;
1255 DIRTY(prog->dirtyParam[index], g->neg_bitid);
1256 DIRTY(prog->dirtyParams, g->neg_bitid);
1257 DIRTY(pb->dirty, g->neg_bitid);
1258}
1259
1260
1261void STATE_APIENTRY crStateProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat *params)
1262{
1263 crStateProgramLocalParameter4fARB(target, index, params[0], params[1], params[2], params[3]);
1264}
1265
1266
1267void STATE_APIENTRY crStateGetProgramLocalParameterfvARB(GLenum target, GLuint index, GLfloat *params)
1268{
1269 CRContext *g = GetCurrentContext();
1270 CRProgramState *p = &(g->program);
1271 const CRProgram *prog = NULL;
1272
1273 if (g->current.inBeginEnd) {
1274 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1275 "glGetProgramLocalParameterARB called in Begin/End");
1276 return;
1277 }
1278
1279 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1280 prog = p->currentFragmentProgram;
1281 if (index >= g->limits.maxFragmentProgramLocalParams) {
1282 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1283 "glGetProgramLocalParameterARB(index)");
1284 return;
1285 }
1286 }
1287 else if ( target == GL_VERTEX_PROGRAM_ARB
1288#if GL_VERTEX_PROGRAM_ARB != GL_VERTEX_PROGRAM_NV
1289 || target == GL_VERTEX_PROGRAM_NV
1290#endif
1291 ) {
1292 prog = p->currentVertexProgram;
1293 if (index >= g->limits.maxVertexProgramLocalParams) {
1294 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1295 "glGetProgramLocalParameterARB(index)");
1296 return;
1297 }
1298 }
1299 else {
1300 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1301 "glGetProgramLocalParameterARB(target)");
1302 return;
1303 }
1304 if (!prog) {
1305 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1306 "glGetProgramLocalParameterARB(no program)");
1307 return;
1308 }
1309
1310 if (!prog) {
1311 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1312 "glGetProgramLocalParameterARB(no program)");
1313 return;
1314 }
1315
1316 CRASSERT(prog);
1317 CRASSERT(index < CR_MAX_PROGRAM_LOCAL_PARAMS);
1318 params[0] = prog->parameters[index][0];
1319 params[1] = prog->parameters[index][1];
1320 params[2] = prog->parameters[index][2];
1321 params[3] = prog->parameters[index][3];
1322}
1323
1324
1325void STATE_APIENTRY crStateGetProgramLocalParameterdvARB(GLenum target, GLuint index, GLdouble *params)
1326{
1327 GLfloat floatParams[4];
1328 crStateGetProgramLocalParameterfvARB(target, index, floatParams);
1329 params[0] = floatParams[0];
1330 params[1] = floatParams[1];
1331 params[2] = floatParams[2];
1332 params[3] = floatParams[3];
1333}
1334
1335
1336
1337void STATE_APIENTRY crStateGetProgramivARB(GLenum target, GLenum pname, GLint *params)
1338{
1339 CRProgram *prog;
1340 CRContext *g = GetCurrentContext();
1341 CRProgramState *p = &(g->program);
1342
1343 if (g->current.inBeginEnd) {
1344 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1345 "glGetProgramivARB called in Begin/End");
1346 return;
1347 }
1348
1349 if (target == GL_VERTEX_PROGRAM_ARB) {
1350 prog = p->currentVertexProgram;
1351 }
1352 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
1353 prog = p->currentFragmentProgram;
1354 }
1355 else {
1356 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1357 "glGetProgramivARB(target)");
1358 return;
1359 }
1360
1361 CRASSERT(prog);
1362
1363 switch (pname) {
1364 case GL_PROGRAM_LENGTH_ARB:
1365 *params = prog->length;
1366 break;
1367 case GL_PROGRAM_FORMAT_ARB:
1368 *params = prog->format;
1369 break;
1370 case GL_PROGRAM_BINDING_ARB:
1371 *params = prog->id;
1372 break;
1373 case GL_PROGRAM_INSTRUCTIONS_ARB:
1374 *params = prog->numInstructions;
1375 break;
1376 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
1377 if (target == GL_VERTEX_PROGRAM_ARB)
1378 *params = g->limits.maxVertexProgramInstructions;
1379 else
1380 *params = g->limits.maxFragmentProgramInstructions;
1381 break;
1382 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
1383 *params = prog->numInstructions;
1384 break;
1385 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
1386 if (target == GL_VERTEX_PROGRAM_ARB)
1387 *params = g->limits.maxVertexProgramInstructions;
1388 else
1389 *params = g->limits.maxFragmentProgramInstructions;
1390 break;
1391 case GL_PROGRAM_TEMPORARIES_ARB:
1392 *params = prog->numTemporaries;
1393 break;
1394 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
1395 if (target == GL_VERTEX_PROGRAM_ARB)
1396 *params = g->limits.maxVertexProgramTemps;
1397 else
1398 *params = g->limits.maxFragmentProgramTemps;
1399 break;
1400 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
1401 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
1402 *params = prog->numTemporaries;
1403 break;
1404 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
1405 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
1406 if (target == GL_VERTEX_PROGRAM_ARB)
1407 *params = g->limits.maxVertexProgramTemps;
1408 else
1409 *params = g->limits.maxFragmentProgramTemps;
1410 break;
1411 case GL_PROGRAM_PARAMETERS_ARB:
1412 *params = prog->numParameters;
1413 break;
1414 case GL_MAX_PROGRAM_PARAMETERS_ARB:
1415 if (target == GL_VERTEX_PROGRAM_ARB)
1416 *params = g->limits.maxVertexProgramLocalParams;
1417 else
1418 *params = g->limits.maxFragmentProgramLocalParams;
1419 break;
1420 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
1421 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
1422 *params = prog->numParameters;
1423 break;
1424 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
1425 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
1426 if (target == GL_VERTEX_PROGRAM_ARB)
1427 *params = g->limits.maxVertexProgramLocalParams;
1428 else
1429 *params = g->limits.maxFragmentProgramLocalParams;
1430 break;
1431 case GL_PROGRAM_ATTRIBS_ARB:
1432 *params = prog->numAttributes;
1433 break;
1434 case GL_MAX_PROGRAM_ATTRIBS_ARB:
1435 if (target == GL_VERTEX_PROGRAM_ARB)
1436 *params = g->limits.maxVertexProgramAttribs;
1437 else
1438 *params = g->limits.maxFragmentProgramAttribs;
1439 break;
1440 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
1441 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
1442 *params = prog->numAttributes;
1443 break;
1444 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
1445 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
1446 if (target == GL_VERTEX_PROGRAM_ARB)
1447 *params = g->limits.maxVertexProgramAttribs;
1448 else
1449 *params = g->limits.maxFragmentProgramAttribs;
1450 break;
1451 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
1452 *params = prog->numAddressRegs;
1453 break;
1454 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
1455 if (target == GL_VERTEX_PROGRAM_ARB)
1456 *params = g->limits.maxVertexProgramAddressRegs;
1457 else
1458 *params = g->limits.maxFragmentProgramAddressRegs;
1459 break;
1460 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
1461 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
1462 *params = prog->numAddressRegs;
1463 break;
1464 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
1465 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
1466 if (target == GL_VERTEX_PROGRAM_ARB)
1467 *params = g->limits.maxVertexProgramAddressRegs;
1468 else
1469 *params = g->limits.maxFragmentProgramAddressRegs;
1470 break;
1471 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
1472 if (target == GL_VERTEX_PROGRAM_ARB)
1473 *params = g->limits.maxVertexProgramLocalParams;
1474 else
1475 *params = g->limits.maxFragmentProgramLocalParams;
1476 break;
1477 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
1478 if (target == GL_VERTEX_PROGRAM_ARB)
1479 *params = g->limits.maxVertexProgramEnvParams;
1480 else
1481 *params = g->limits.maxFragmentProgramEnvParams;
1482 break;
1483 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
1484 /* XXX ok? */
1485 *params = GL_TRUE;
1486 break;
1487
1488 /*
1489 * These are for fragment programs only
1490 */
1491 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
1492 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1493 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1494 "crStateGetProgramivARB(target or pname)");
1495 return;
1496 }
1497 *params = prog->numAluInstructions;
1498 break;
1499 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
1500 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1501 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1502 "crStateGetProgramivARB(target or pname)");
1503 return;
1504 }
1505 *params = prog->numTexInstructions;
1506 break;
1507 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
1508 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1509 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1510 "crStateGetProgramivARB(target or pname)");
1511 return;
1512 }
1513 *params = prog->numTexIndirections;
1514 break;
1515 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
1516 /* XXX same as GL_PROGRAM_ALU_INSTRUCTIONS_ARB? */
1517 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1518 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1519 "crStateGetProgramivARB(target or pname)");
1520 return;
1521 }
1522 *params = prog->numAluInstructions;
1523 break;
1524 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
1525 /* XXX same as GL_PROGRAM_ALU_INSTRUCTIONS_ARB? */
1526 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1527 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1528 "crStateGetProgramivARB(target or pname)");
1529 return;
1530 }
1531 *params = prog->numTexInstructions;
1532 break;
1533 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
1534 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1535 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1536 "crStateGetProgramivARB(target or pname)");
1537 return;
1538 }
1539 *params = prog->numTexIndirections;
1540 break;
1541 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
1542 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
1543 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1544 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1545 "crStateGetProgramivARB(target or pname)");
1546 return;
1547 }
1548 *params = g->limits.maxFragmentProgramAluInstructions;
1549 break;
1550 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
1551 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
1552 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1553 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1554 "crStateGetProgramivARB(target or pname)");
1555 return;
1556 }
1557 *params = g->limits.maxFragmentProgramTexInstructions;
1558 break;
1559 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
1560 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
1561 if (target != GL_FRAGMENT_PROGRAM_ARB || !g->extensions.ARB_fragment_program) {
1562 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1563 "crStateGetProgramivARB(target or pname)");
1564 return;
1565 }
1566 *params = g->limits.maxFragmentProgramTexIndirections;
1567 break;
1568 default:
1569 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1570 "crStateGetProgramivARB(pname)");
1571 return;
1572 }
1573}
1574
1575
1576/* XXX maybe move these two functions into state_client.c? */
1577void STATE_APIENTRY crStateDisableVertexAttribArrayARB(GLuint index)
1578{
1579 CRContext *g = GetCurrentContext();
1580 CRClientState *c = &(g->client);
1581 CRStateBits *sb = GetCurrentBits();
1582 CRClientBits *cb = &(sb->client);
1583
1584 if (index >= g->limits.maxVertexProgramAttribs) {
1585 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1586 "glDisableVertexAttribArrayARB(index)");
1587 return;
1588 }
1589 c->array.a[index].enabled = GL_FALSE;
1590 DIRTY(cb->dirty, g->neg_bitid);
1591 DIRTY(cb->enableClientState, g->neg_bitid);
1592}
1593
1594
1595void STATE_APIENTRY crStateEnableVertexAttribArrayARB(GLuint index)
1596{
1597 CRContext *g = GetCurrentContext();
1598 CRClientState *c = &(g->client);
1599 CRStateBits *sb = GetCurrentBits();
1600 CRClientBits *cb = &(sb->client);
1601
1602 if (index >= g->limits.maxVertexProgramAttribs) {
1603 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1604 "glEnableVertexAttribArrayARB(index)");
1605 return;
1606 }
1607 c->array.a[index].enabled = GL_TRUE;
1608 DIRTY(cb->dirty, g->neg_bitid);
1609 DIRTY(cb->enableClientState, g->neg_bitid);
1610}
1611
1612
1613void STATE_APIENTRY crStateGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble *params)
1614{
1615 GLfloat fparams[4];
1616 crStateGetProgramEnvParameterfvARB(target, index, fparams);
1617 params[0] = fparams[0];
1618 params[1] = fparams[1];
1619 params[2] = fparams[2];
1620 params[3] = fparams[3];
1621}
1622
1623void STATE_APIENTRY crStateGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat *params)
1624{
1625 CRContext *g = GetCurrentContext();
1626 CRProgramState *p = &(g->program);
1627
1628 if (g->current.inBeginEnd) {
1629 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1630 "glGetProgramEnvParameterARB called in Begin/End");
1631 return;
1632 }
1633
1634 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1635 if (index >= g->limits.maxFragmentProgramEnvParams) {
1636 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1637 "glGetProgramEnvParameterARB(index)");
1638 return;
1639 }
1640 params[0] = p->fragmentParameters[index][0];
1641 params[1] = p->fragmentParameters[index][1];
1642 params[2] = p->fragmentParameters[index][2];
1643 params[3] = p->fragmentParameters[index][3];
1644 }
1645 else if ( target == GL_VERTEX_PROGRAM_ARB
1646#if GL_VERTEX_PROGRAM_ARB != GL_VERTEX_PROGRAM_NV
1647 || target == GL_VERTEX_PROGRAM_NV
1648#endif
1649 ) {
1650 if (index >= g->limits.maxVertexProgramEnvParams) {
1651 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1652 "glGetProgramEnvParameterARB(index)");
1653 return;
1654 }
1655 params[0] = p->vertexParameters[index][0];
1656 params[1] = p->vertexParameters[index][1];
1657 params[2] = p->vertexParameters[index][2];
1658 params[3] = p->vertexParameters[index][3];
1659 }
1660 else {
1661 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1662 "glGetProgramEnvParameterARB(target)");
1663 return;
1664 }
1665}
1666
1667
1668void STATE_APIENTRY crStateProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
1669{
1670 crStateProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
1671}
1672
1673void STATE_APIENTRY crStateProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble *params)
1674{
1675 crStateProgramEnvParameter4fARB(target, index, (GLfloat) params[0], (GLfloat) params[1], (GLfloat) params[2], (GLfloat) params[3]);
1676}
1677
1678void STATE_APIENTRY crStateProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1679{
1680 CRContext *g = GetCurrentContext();
1681 CRProgramState *p = &(g->program);
1682 CRStateBits *sb = GetCurrentBits();
1683 CRProgramBits *pb = &(sb->program);
1684
1685 if (g->current.inBeginEnd) {
1686 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1687 "glProgramEnvParameterARB called in Begin/End");
1688 return;
1689 }
1690
1691 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1692 if (index >= g->limits.maxFragmentProgramEnvParams) {
1693 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1694 "glProgramEnvParameterARB(index)");
1695 return;
1696 }
1697 p->fragmentParameters[index][0] = x;
1698 p->fragmentParameters[index][1] = y;
1699 p->fragmentParameters[index][2] = z;
1700 p->fragmentParameters[index][3] = w;
1701 DIRTY(pb->fragmentEnvParameter[index], g->neg_bitid);
1702 DIRTY(pb->fragmentEnvParameters, g->neg_bitid);
1703 }
1704 else if ( target == GL_VERTEX_PROGRAM_ARB
1705#if GL_VERTEX_PROGRAM_ARB != GL_VERTEX_PROGRAM_NV
1706 || target == GL_VERTEX_PROGRAM_NV
1707#endif
1708 ) {
1709 if (index >= g->limits.maxVertexProgramEnvParams) {
1710 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1711 "glProgramEnvParameterARB(index)");
1712 return;
1713 }
1714 p->vertexParameters[index][0] = x;
1715 p->vertexParameters[index][1] = y;
1716 p->vertexParameters[index][2] = z;
1717 p->vertexParameters[index][3] = w;
1718 DIRTY(pb->vertexEnvParameter[index], g->neg_bitid);
1719 DIRTY(pb->vertexEnvParameters, g->neg_bitid);
1720 }
1721 else {
1722 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1723 "glProgramEnvParameterARB(target)");
1724 return;
1725 }
1726
1727 DIRTY(pb->dirty, g->neg_bitid);
1728}
1729
1730void STATE_APIENTRY crStateProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params)
1731{
1732 crStateProgramEnvParameter4fARB(target, index, params[0], params[1], params[2], params[3]);
1733}
1734
1735
1736/**********************************************************************/
1737
1738
1739void crStateProgramInit( CRContext *ctx )
1740{
1741 CRProgramState *p = &(ctx->program);
1742 CRStateBits *sb = GetCurrentBits();
1743 CRProgramBits *pb = &(sb->program);
1744 GLuint i;
1745
1746 CRASSERT(CR_MAX_PROGRAM_ENV_PARAMS >= CR_MAX_VERTEX_PROGRAM_ENV_PARAMS);
1747 CRASSERT(CR_MAX_PROGRAM_ENV_PARAMS >= CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS);
1748
1749 CRASSERT(CR_MAX_PROGRAM_LOCAL_PARAMS >= CR_MAX_VERTEX_PROGRAM_LOCAL_PARAMS);
1750 CRASSERT(CR_MAX_PROGRAM_LOCAL_PARAMS >= CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS);
1751
1752 p->programHash = crAllocHashtable();
1753
1754 /* ARB_vertex/fragment_program define default program objects */
1755 p->defaultVertexProgram = GetProgram(p, GL_VERTEX_PROGRAM_ARB, 0);
1756 p->defaultFragmentProgram = GetProgram(p, GL_FRAGMENT_PROGRAM_ARB, 0);
1757
1758 p->currentVertexProgram = p->defaultVertexProgram;
1759 p->currentFragmentProgram = p->defaultFragmentProgram;
1760 p->errorPos = -1;
1761 p->errorString = NULL;
1762
1763 for (i = 0; i < ctx->limits.maxVertexProgramEnvParams / 4; i++) {
1764 p->TrackMatrix[i] = GL_NONE;
1765 p->TrackMatrixTransform[i] = GL_IDENTITY_NV;
1766 }
1767 for (i = 0; i < ctx->limits.maxVertexProgramEnvParams; i++) {
1768 p->vertexParameters[i][0] = 0.0;
1769 p->vertexParameters[i][1] = 0.0;
1770 p->vertexParameters[i][2] = 0.0;
1771 p->vertexParameters[i][3] = 0.0;
1772 }
1773 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS; i++) {
1774 p->fragmentParameters[i][0] = 0.0;
1775 p->fragmentParameters[i][1] = 0.0;
1776 p->fragmentParameters[i][2] = 0.0;
1777 p->fragmentParameters[i][3] = 0.0;
1778 }
1779
1780 p->vpEnabled = GL_FALSE;
1781 p->fpEnabled = GL_FALSE;
1782 p->fpEnabledARB = GL_FALSE;
1783 p->vpPointSize = GL_FALSE;
1784 p->vpTwoSide = GL_FALSE;
1785 RESET(pb->dirty, ctx->bitid);
1786}
1787
1788
1789static void DeleteProgramCallback( void *data )
1790{
1791 CRProgram *prog = (CRProgram *) data;
1792 DeleteProgram(prog);
1793}
1794
1795void crStateProgramDestroy(CRContext *ctx)
1796{
1797 CRProgramState *p = &(ctx->program);
1798 crFreeHashtable(p->programHash, DeleteProgramCallback);
1799 DeleteProgram(p->defaultVertexProgram);
1800 DeleteProgram(p->defaultFragmentProgram);
1801}
1802
1803
1804/* XXX it would be nice to autogenerate this, but we can't for now.
1805 */
1806void
1807crStateProgramDiff(CRProgramBits *b, CRbitvalue *bitID,
1808 CRContext *fromCtx, CRContext *toCtx)
1809{
1810 CRProgramState *from = &(fromCtx->program);
1811 CRProgramState *to = &(toCtx->program);
1812 unsigned int i, j;
1813 CRbitvalue nbitID[CR_MAX_BITARRAY];
1814
1815 CRASSERT(from->currentVertexProgram);
1816 CRASSERT(to->currentVertexProgram);
1817 CRASSERT(from->currentFragmentProgram);
1818 CRASSERT(to->currentFragmentProgram);
1819
1820 for (j=0;j<CR_MAX_BITARRAY;j++)
1821 nbitID[j] = ~bitID[j];
1822
1823 /* vertex program enable */
1824 if (CHECKDIRTY(b->vpEnable, bitID)) {
1825 glAble able[2];
1826 CRProgram *toProg = to->currentVertexProgram;
1827
1828 able[0] = diff_api.Disable;
1829 able[1] = diff_api.Enable;
1830 if (from->vpEnabled != to->vpEnabled) {
1831 if (toProg->isARBprogram)
1832 able[to->vpEnabled](GL_VERTEX_PROGRAM_ARB);
1833 else
1834 able[to->vpEnabled](GL_VERTEX_PROGRAM_NV);
1835 from->vpEnabled = to->vpEnabled;
1836 }
1837 if (from->vpTwoSide != to->vpTwoSide) {
1838 able[to->vpTwoSide](GL_VERTEX_PROGRAM_TWO_SIDE_NV);
1839 from->vpTwoSide = to->vpTwoSide;
1840 }
1841 if (from->vpPointSize != to->vpPointSize) {
1842 able[to->vpPointSize](GL_VERTEX_PROGRAM_POINT_SIZE_NV);
1843 from->vpPointSize = to->vpPointSize;
1844 }
1845 CLEARDIRTY(b->vpEnable, nbitID);
1846 }
1847
1848 /* fragment program enable */
1849 if (CHECKDIRTY(b->fpEnable, bitID)) {
1850 glAble able[2];
1851 able[0] = diff_api.Disable;
1852 able[1] = diff_api.Enable;
1853 if (from->fpEnabled != to->fpEnabled) {
1854 able[to->fpEnabled](GL_FRAGMENT_PROGRAM_NV);
1855 from->fpEnabled = to->fpEnabled;
1856 }
1857 if (from->fpEnabledARB != to->fpEnabledARB) {
1858 able[to->fpEnabledARB](GL_FRAGMENT_PROGRAM_ARB);
1859 from->fpEnabledARB = to->fpEnabledARB;
1860 }
1861 CLEARDIRTY(b->fpEnable, nbitID);
1862 }
1863
1864 /* program/track matrices */
1865 if (to->vpEnabled) {
1866 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams / 4; i++) {
1867 if (CHECKDIRTY(b->trackMatrix[i], bitID)) {
1868 if (from->TrackMatrix[i] != to->TrackMatrix[i] ||
1869 from->TrackMatrixTransform[i] != to->TrackMatrixTransform[i]) {
1870 diff_api.TrackMatrixNV(GL_VERTEX_PROGRAM_NV, i * 4,
1871 to->TrackMatrix[i],
1872 to->TrackMatrixTransform[i]);
1873 from->TrackMatrix[i] = to->TrackMatrix[i];
1874 from->TrackMatrixTransform[i] = to->TrackMatrixTransform[i];
1875 }
1876 CLEARDIRTY(b->trackMatrix[i], nbitID);
1877 }
1878 }
1879 }
1880
1881 if (to->vpEnabled) {
1882 /* vertex program binding */
1883 CRProgram *fromProg = from->currentVertexProgram;
1884 CRProgram *toProg = to->currentVertexProgram;
1885
1886 if (CHECKDIRTY(b->vpBinding, bitID)) {
1887 if (fromProg->id != toProg->id) {
1888 if (toProg->isARBprogram)
1889 diff_api.BindProgramARB(GL_VERTEX_PROGRAM_ARB, toProg->id);
1890 else
1891 diff_api.BindProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id);
1892 from->currentVertexProgram = toProg;
1893 }
1894 CLEARDIRTY(b->vpBinding, nbitID);
1895 }
1896
1897 if (toProg) {
1898 /* vertex program text */
1899 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
1900 if (toProg->isARBprogram) {
1901 diff_api.ProgramStringARB( GL_VERTEX_PROGRAM_ARB, toProg->format, toProg->length, toProg->string );
1902 }
1903 else {
1904 diff_api.LoadProgramNV( GL_VERTEX_PROGRAM_NV, toProg->id, toProg->length, toProg->string );
1905 }
1906 CLEARDIRTY(toProg->dirtyProgram, nbitID);
1907 }
1908
1909 /* vertex program global/env parameters */
1910 if (CHECKDIRTY(b->vertexEnvParameters, bitID)) {
1911 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams; i++) {
1912 if (CHECKDIRTY(b->vertexEnvParameter[i], bitID)) {
1913 if (toProg->isARBprogram)
1914 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i,
1915 to->vertexParameters[i]);
1916 else
1917 diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i,
1918 to->vertexParameters[i]);
1919 if (fromProg) {
1920 COPY_4V(from->vertexParameters[i],
1921 to->vertexParameters[i]);
1922 }
1923 CLEARDIRTY(b->vertexEnvParameter[i], nbitID);
1924 }
1925 }
1926 CLEARDIRTY(b->vertexEnvParameters, nbitID);
1927 }
1928
1929 /* vertex program local parameters */
1930 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
1931 for (i = 0; i < toCtx->limits.maxVertexProgramLocalParams; i++) {
1932 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
1933 if (toProg->isARBprogram)
1934 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, toProg->parameters[i]);
1935 else
1936 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_NV, i, toProg->parameters[i]);
1937 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
1938 }
1939 }
1940 CLEARDIRTY(toProg->dirtyParams, nbitID);
1941 }
1942 }
1943 }
1944
1945 /*
1946 * Separate paths for NV vs ARB fragment program
1947 */
1948 if (to->fpEnabled) {
1949 /* NV fragment program binding */
1950 CRProgram *fromProg = from->currentFragmentProgram;
1951 CRProgram *toProg = to->currentFragmentProgram;
1952 if (CHECKDIRTY(b->fpBinding, bitID)) {
1953 if (fromProg->id != toProg->id) {
1954 diff_api.BindProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id);
1955 from->currentFragmentProgram = toProg;
1956 }
1957 CLEARDIRTY(b->fpBinding, nbitID);
1958 }
1959
1960 if (toProg) {
1961 /* fragment program text */
1962 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
1963 diff_api.LoadProgramNV( GL_FRAGMENT_PROGRAM_NV, toProg->id,
1964 toProg->length, toProg->string );
1965 CLEARDIRTY(toProg->dirtyProgram, nbitID);
1966 }
1967
1968 /* fragment program global/env parameters */
1969 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
1970 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
1971 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
1972 diff_api.ProgramParameter4fvNV(GL_FRAGMENT_PROGRAM_NV, i,
1973 to->fragmentParameters[i]);
1974 if (fromProg) {
1975 COPY_4V(from->fragmentParameters[i],
1976 to->fragmentParameters[i]);
1977 }
1978 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
1979 }
1980 }
1981 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
1982 }
1983
1984 /* named local parameters */
1985 if (CHECKDIRTY(toProg->dirtyNamedParams, bitID)) {
1986 CRProgramSymbol *symbol;
1987 for (symbol = toProg->symbolTable; symbol; symbol = symbol->next) {
1988 if (CHECKDIRTY(symbol->dirty, bitID)) {
1989 GLint len = crStrlen(symbol->name);
1990 diff_api.ProgramNamedParameter4fvNV(toProg->id, len,
1991 (const GLubyte *) symbol->name,
1992 symbol->value);
1993 if (fromProg) {
1994 SetProgramSymbol(fromProg, symbol->name, len,
1995 symbol->value[0], symbol->value[1],
1996 symbol->value[2], symbol->value[3]);
1997 }
1998 CLEARDIRTY(symbol->dirty, nbitID);
1999 }
2000 }
2001 CLEARDIRTY(toProg->dirtyNamedParams, nbitID);
2002 }
2003
2004 /* numbered local parameters */
2005 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2006 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2007 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2008 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i,
2009 toProg->parameters[i]);
2010 if (fromProg) {
2011 COPY_4V(fromProg->parameters[i], toProg->parameters[i]);
2012 }
2013 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
2014 }
2015 }
2016 CLEARDIRTY(toProg->dirtyParams, nbitID);
2017 }
2018 }
2019 }
2020 else if (to->fpEnabledARB) {
2021 /* ARB fragment program binding */
2022 CRProgram *fromProg = from->currentFragmentProgram;
2023 CRProgram *toProg = to->currentFragmentProgram;
2024 if (CHECKDIRTY(b->fpBinding, bitID)) {
2025 if (fromProg->id != toProg->id) {
2026 diff_api.BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, toProg->id);
2027 from->currentFragmentProgram = toProg;
2028 }
2029 CLEARDIRTY(b->fpBinding, nbitID);
2030 }
2031
2032 if (toProg) {
2033 /* fragment program text */
2034 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2035 diff_api.ProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, toProg->format,
2036 toProg->length, toProg->string );
2037 CLEARDIRTY(toProg->dirtyProgram, nbitID);
2038 }
2039
2040 /* fragment program global/env parameters */
2041 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2042 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2043 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2044 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2045 to->fragmentParameters[i]);
2046 if (fromProg) {
2047 COPY_4V(from->fragmentParameters[i],
2048 to->fragmentParameters[i]);
2049 }
2050 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
2051 }
2052 }
2053 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
2054 }
2055
2056 /* numbered local parameters */
2057 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2058 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2059 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2060 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2061 toProg->parameters[i]);
2062 if (fromProg) {
2063 COPY_4V(fromProg->parameters[i], toProg->parameters[i]);
2064 }
2065 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
2066 }
2067 }
2068 CLEARDIRTY(toProg->dirtyParams, nbitID);
2069 }
2070 }
2071 }
2072
2073 CLEARDIRTY(b->dirty, nbitID);
2074}
2075
2076
2077void
2078crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
2079 CRContext *fromCtx, CRContext *toCtx)
2080{
2081 CRProgramState *from = &(fromCtx->program);
2082 CRProgramState *to = &(toCtx->program);
2083 unsigned int i, j;
2084 CRbitvalue nbitID[CR_MAX_BITARRAY];
2085 GLenum whichVert = fromCtx->extensions.ARB_vertex_program && toCtx->extensions.ARB_vertex_program ? GL_VERTEX_PROGRAM_ARB : GL_VERTEX_PROGRAM_NV;
2086
2087
2088 for (j=0;j<CR_MAX_BITARRAY;j++)
2089 nbitID[j] = ~bitID[j];
2090
2091 /* vertex program enable */
2092 if (CHECKDIRTY(b->vpEnable, bitID)) {
2093 glAble able[2];
2094 able[0] = diff_api.Disable;
2095 able[1] = diff_api.Enable;
2096 if (from->vpEnabled != to->vpEnabled) {
2097 able[to->vpEnabled](whichVert);
2098 }
2099 if (from->vpTwoSide != to->vpTwoSide) {
2100 able[to->vpTwoSide](GL_VERTEX_PROGRAM_TWO_SIDE_NV);
2101 }
2102 if (from->vpPointSize != to->vpPointSize) {
2103 able[to->vpPointSize](GL_VERTEX_PROGRAM_POINT_SIZE_NV);
2104 }
2105 DIRTY(b->vpEnable, nbitID);
2106 }
2107
2108 /* fragment program enable */
2109 if (CHECKDIRTY(b->fpEnable, bitID)) {
2110 glAble able[2];
2111 able[0] = diff_api.Disable;
2112 able[1] = diff_api.Enable;
2113 if (from->fpEnabled != to->fpEnabled) {
2114 able[to->fpEnabled](GL_FRAGMENT_PROGRAM_NV);
2115 }
2116 if (from->fpEnabledARB != to->fpEnabledARB) {
2117 able[to->fpEnabledARB](GL_FRAGMENT_PROGRAM_ARB);
2118 }
2119 DIRTY(b->fpEnable, nbitID);
2120 }
2121
2122 /* program/track matrices */
2123 if (to->vpEnabled) {
2124 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams / 4; i++) {
2125 if (CHECKDIRTY(b->trackMatrix[i], bitID)) {
2126 if (from->TrackMatrix[i] != to->TrackMatrix[i]) {
2127 diff_api.TrackMatrixNV(GL_VERTEX_PROGRAM_NV, i * 4,
2128 to->TrackMatrix[i],
2129 to->TrackMatrixTransform[i]);
2130 }
2131 DIRTY(b->trackMatrix[i], nbitID);
2132 }
2133 }
2134 }
2135
2136 if (to->vpEnabled) {
2137 /* vertex program binding */
2138 CRProgram *fromProg = from->currentVertexProgram;
2139 CRProgram *toProg = to->currentVertexProgram;
2140 if (CHECKDIRTY(b->vpBinding, bitID)) {
2141 if (fromProg->id != toProg->id) {
2142 if (toProg->isARBprogram)
2143 diff_api.BindProgramARB(GL_VERTEX_PROGRAM_ARB, toProg->id);
2144 else
2145 diff_api.BindProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id);
2146 }
2147 DIRTY(b->vpBinding, nbitID);
2148 }
2149
2150 if (toProg) {
2151 /* vertex program text */
2152 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2153 if (toProg->isARBprogram)
2154 diff_api.ProgramStringARB(GL_VERTEX_PROGRAM_ARB, toProg->format, toProg->length, toProg->string);
2155 else
2156 diff_api.LoadProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id, toProg->length, toProg->string);
2157
2158 DIRTY(toProg->dirtyProgram, nbitID);
2159 }
2160
2161 /* vertex program global/env parameters */
2162 if (CHECKDIRTY(b->vertexEnvParameters, bitID)) {
2163 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams; i++) {
2164 if (CHECKDIRTY(b->vertexEnvParameter[i], bitID)) {
2165 if (toProg->isARBprogram)
2166 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, to->vertexParameters[i]);
2167 else
2168 diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i, to->vertexParameters[i]);
2169
2170 DIRTY(b->vertexEnvParameter[i], nbitID);
2171 }
2172 }
2173 DIRTY(b->vertexEnvParameters, nbitID);
2174 }
2175
2176 /* vertex program local parameters */
2177 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2178 for (i = 0; i < toCtx->limits.maxVertexProgramLocalParams; i++) {
2179 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2180
2181
2182 if (toProg->isARBprogram)
2183 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, toProg->parameters[i]);
2184 else
2185 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_NV, i, toProg->parameters[i]);
2186 }
2187 }
2188 DIRTY(toProg->dirtyParams, nbitID);
2189 }
2190 }
2191 }
2192
2193 /*
2194 * Separate paths for NV vs ARB fragment program
2195 */
2196 if (to->fpEnabled) {
2197 /* NV fragment program binding */
2198 CRProgram *fromProg = from->currentFragmentProgram;
2199 CRProgram *toProg = to->currentFragmentProgram;
2200 if (CHECKDIRTY(b->fpBinding, bitID)) {
2201 if (fromProg->id != toProg->id) {
2202 diff_api.BindProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id);
2203 }
2204 DIRTY(b->fpBinding, nbitID);
2205 }
2206
2207 if (toProg) {
2208 /* fragment program text */
2209 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2210 diff_api.LoadProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id, toProg->length, toProg->string);
2211 DIRTY(toProg->dirtyProgram, nbitID);
2212 }
2213
2214 /* fragment program global/env parameters */
2215 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2216 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2217 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2218 diff_api.ProgramParameter4fvNV(GL_FRAGMENT_PROGRAM_NV, i,
2219 to->fragmentParameters[i]);
2220 DIRTY(b->fragmentEnvParameter[i], nbitID);
2221 }
2222 }
2223 DIRTY(b->fragmentEnvParameters, nbitID);
2224 }
2225
2226 /* named local parameters */
2227 if (CHECKDIRTY(toProg->dirtyNamedParams, bitID)) {
2228 CRProgramSymbol *symbol;
2229 for (symbol = toProg->symbolTable; symbol; symbol = symbol->next) {
2230 if (CHECKDIRTY(symbol->dirty, bitID)) {
2231 GLint len = crStrlen(symbol->name);
2232 diff_api.ProgramNamedParameter4fvNV(toProg->id, len,
2233 (const GLubyte *) symbol->name,
2234 symbol->value);
2235 DIRTY(symbol->dirty, nbitID);
2236 }
2237 }
2238 DIRTY(toProg->dirtyNamedParams, nbitID);
2239 }
2240
2241 /* numbered local parameters */
2242 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2243 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2244 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2245 if (toProg->isARBprogram)
2246 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, toProg->parameters[i]);
2247 else
2248 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i, toProg->parameters[i]);
2249 }
2250 }
2251 DIRTY(toProg->dirtyParams, nbitID);
2252 }
2253 }
2254 }
2255 else if (to->fpEnabledARB) {
2256 /* ARB fragment program binding */
2257 CRProgram *fromProg = from->currentFragmentProgram;
2258 CRProgram *toProg = to->currentFragmentProgram;
2259 if (CHECKDIRTY(b->fpBinding, bitID)) {
2260 if (fromProg->id != toProg->id) {
2261 diff_api.BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, toProg->id);
2262 }
2263 DIRTY(b->fpBinding, nbitID);
2264 }
2265
2266 if (toProg) {
2267 /* fragment program text */
2268 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2269 diff_api.ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, toProg->format, toProg->length, toProg->string);
2270 DIRTY(toProg->dirtyProgram, nbitID);
2271 }
2272
2273 /* fragment program global/env parameters */
2274 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2275 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2276 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2277 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, to->fragmentParameters[i]);
2278 DIRTY(b->fragmentEnvParameter[i], nbitID);
2279 }
2280 }
2281 DIRTY(b->fragmentEnvParameters, nbitID);
2282 }
2283
2284 /* numbered local parameters */
2285 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2286 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2287 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2288 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, toProg->parameters[i]);
2289 DIRTY(toProg->dirtyParam[i], nbitID);
2290 }
2291 }
2292 DIRTY(toProg->dirtyParams, nbitID);
2293 }
2294 }
2295 }
2296
2297 DIRTY(b->dirty, nbitID);
2298
2299 /* Resend program data */
2300 if (toCtx->program.bResyncNeeded)
2301 {
2302 toCtx->program.bResyncNeeded = GL_FALSE;
2303
2304 crStateDiffAllPrograms(toCtx, bitID, GL_TRUE);
2305 }
2306}
2307
2308/*@todo support NVprograms and add some data validity checks*/
2309static void
2310DiffProgramCallback(unsigned long key, void *pProg, void *pCtx)
2311{
2312 CRContext *pContext = (CRContext *) pCtx;
2313 CRProgram *pProgram = (CRProgram *) pProg;
2314 uint32_t i;
2315 (void)key;
2316
2317 if (pProgram->isARBprogram)
2318 {
2319 diff_api.BindProgramARB(pProgram->target, pProgram->id);
2320 diff_api.ProgramStringARB(pProgram->target, pProgram->format, pProgram->length, pProgram->string);
2321
2322 if (GL_VERTEX_PROGRAM_ARB == pProgram->target)
2323 {
2324 /* vertex program global/env parameters */
2325 for (i = 0; i < pContext->limits.maxVertexProgramEnvParams; i++)
2326 {
2327 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, pContext->program.vertexParameters[i]);
2328 }
2329 /* vertex program local parameters */
2330 for (i = 0; i < pContext->limits.maxVertexProgramLocalParams; i++)
2331 {
2332 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, pProgram->parameters[i]);
2333 }
2334 }
2335 else if (GL_FRAGMENT_PROGRAM_ARB == pProgram->target)
2336 {
2337 /* vertex program global/env parameters */
2338 for (i = 0; i < pContext->limits.maxFragmentProgramEnvParams; i++)
2339 {
2340 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, pContext->program.fragmentParameters[i]);
2341 }
2342 /* vertex program local parameters */
2343 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++)
2344 {
2345 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, pProgram->parameters[i]);
2346 }
2347 }
2348 else
2349 {
2350 crError("Unexpected program target");
2351 }
2352 }
2353 else
2354 {
2355 diff_api.BindProgramNV(pProgram->target, pProgram->id);
2356 }
2357}
2358
2359void crStateDiffAllPrograms(CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate)
2360{
2361 CRProgram *pOrigVP, *pOrigFP;
2362
2363 (void) bForceUpdate; (void)bitID;
2364
2365 /* save original bindings */
2366 pOrigVP = g->program.currentVertexProgram;
2367 pOrigFP = g->program.currentFragmentProgram;
2368
2369 crHashtableWalk(g->program.programHash, DiffProgramCallback, g);
2370
2371 /* restore original bindings */
2372 if (pOrigVP->isARBprogram)
2373 diff_api.BindProgramARB(pOrigVP->target, pOrigVP->id);
2374 else
2375 diff_api.BindProgramNV(pOrigVP->target, pOrigVP->id);
2376
2377 if (pOrigFP->isARBprogram)
2378 diff_api.BindProgramARB(pOrigFP->target, pOrigFP->id);
2379 else
2380 diff_api.BindProgramNV(pOrigFP->target, pOrigFP->id);
2381}
Note: See TracBrowser for help on using the repository browser.

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