VirtualBox

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

Last change on this file since 16970 was 15532, checked in by vboxsync, 16 years ago

crOpenGL: export to OSE

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