VirtualBox

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

Last change on this file since 36300 was 33548, checked in by vboxsync, 14 years ago

crOpenGL: fix vertex attribs tracking

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 83.4 KB
Line 
1/* Copyright (c) 2001, Stanford University
2 * All rights reserved
3 *
4 * See the file LICENSE.txt for information on redistributing this software.
5 */
6
7#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 CRStateBits *sb = GetCurrentBits();
1593 CRClientBits *cb = &(sb->client);
1594
1595 if (index >= g->limits.maxVertexProgramAttribs) {
1596 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1597 "glEnableVertexAttribArrayARB(index)");
1598 return;
1599 }
1600 c->array.a[index].enabled = GL_FALSE;
1601 DIRTY(cb->dirty, g->neg_bitid);
1602 DIRTY(cb->enableClientState, g->neg_bitid);
1603}
1604
1605
1606void STATE_APIENTRY crStateEnableVertexAttribArrayARB(GLuint index)
1607{
1608 CRContext *g = GetCurrentContext();
1609 CRClientState *c = &(g->client);
1610 CRStateBits *sb = GetCurrentBits();
1611 CRClientBits *cb = &(sb->client);
1612
1613 if (index >= g->limits.maxVertexProgramAttribs) {
1614 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1615 "glEnableVertexAttribArrayARB(index)");
1616 return;
1617 }
1618 c->array.a[index].enabled = GL_TRUE;
1619 DIRTY(cb->dirty, g->neg_bitid);
1620 DIRTY(cb->enableClientState, g->neg_bitid);
1621}
1622
1623
1624void STATE_APIENTRY crStateGetProgramEnvParameterdvARB(GLenum target, GLuint index, GLdouble *params)
1625{
1626 GLfloat fparams[4];
1627 crStateGetProgramEnvParameterfvARB(target, index, fparams);
1628 params[0] = fparams[0];
1629 params[1] = fparams[1];
1630 params[2] = fparams[2];
1631 params[3] = fparams[3];
1632}
1633
1634void STATE_APIENTRY crStateGetProgramEnvParameterfvARB(GLenum target, GLuint index, GLfloat *params)
1635{
1636 CRContext *g = GetCurrentContext();
1637 CRProgramState *p = &(g->program);
1638
1639 if (g->current.inBeginEnd) {
1640 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1641 "glGetProgramEnvParameterARB called in Begin/End");
1642 return;
1643 }
1644
1645 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1646 if (index >= g->limits.maxFragmentProgramEnvParams) {
1647 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1648 "glGetProgramEnvParameterARB(index)");
1649 return;
1650 }
1651 params[0] = p->fragmentParameters[index][0];
1652 params[1] = p->fragmentParameters[index][1];
1653 params[2] = p->fragmentParameters[index][2];
1654 params[3] = p->fragmentParameters[index][3];
1655 }
1656 else if (target == GL_VERTEX_PROGRAM_ARB || target == GL_VERTEX_PROGRAM_NV) {
1657 if (index >= g->limits.maxVertexProgramEnvParams) {
1658 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1659 "glGetProgramEnvParameterARB(index)");
1660 return;
1661 }
1662 params[0] = p->vertexParameters[index][0];
1663 params[1] = p->vertexParameters[index][1];
1664 params[2] = p->vertexParameters[index][2];
1665 params[3] = p->vertexParameters[index][3];
1666 }
1667 else {
1668 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1669 "glGetProgramEnvParameterARB(target)");
1670 return;
1671 }
1672}
1673
1674
1675void STATE_APIENTRY crStateProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
1676{
1677 crStateProgramEnvParameter4fARB(target, index, (GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w);
1678}
1679
1680void STATE_APIENTRY crStateProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble *params)
1681{
1682 crStateProgramEnvParameter4fARB(target, index, (GLfloat) params[0], (GLfloat) params[1], (GLfloat) params[2], (GLfloat) params[3]);
1683}
1684
1685void STATE_APIENTRY crStateProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
1686{
1687 CRContext *g = GetCurrentContext();
1688 CRProgramState *p = &(g->program);
1689 CRStateBits *sb = GetCurrentBits();
1690 CRProgramBits *pb = &(sb->program);
1691
1692 if (g->current.inBeginEnd) {
1693 crStateError(__LINE__, __FILE__, GL_INVALID_OPERATION,
1694 "glProgramEnvParameterARB called in Begin/End");
1695 return;
1696 }
1697
1698 if (target == GL_FRAGMENT_PROGRAM_ARB || target == GL_FRAGMENT_PROGRAM_NV) {
1699 if (index >= g->limits.maxFragmentProgramEnvParams) {
1700 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1701 "glProgramEnvParameterARB(index)");
1702 return;
1703 }
1704 p->fragmentParameters[index][0] = x;
1705 p->fragmentParameters[index][1] = y;
1706 p->fragmentParameters[index][2] = z;
1707 p->fragmentParameters[index][3] = w;
1708 DIRTY(pb->fragmentEnvParameter[index], g->neg_bitid);
1709 DIRTY(pb->fragmentEnvParameters, g->neg_bitid);
1710 }
1711 else if (target == GL_VERTEX_PROGRAM_ARB || target == GL_VERTEX_PROGRAM_NV) {
1712 if (index >= g->limits.maxVertexProgramEnvParams) {
1713 crStateError(__LINE__, __FILE__, GL_INVALID_VALUE,
1714 "glProgramEnvParameterARB(index)");
1715 return;
1716 }
1717 p->vertexParameters[index][0] = x;
1718 p->vertexParameters[index][1] = y;
1719 p->vertexParameters[index][2] = z;
1720 p->vertexParameters[index][3] = w;
1721 DIRTY(pb->vertexEnvParameter[index], g->neg_bitid);
1722 DIRTY(pb->vertexEnvParameters, g->neg_bitid);
1723 }
1724 else {
1725 crStateError(__LINE__, __FILE__, GL_INVALID_ENUM,
1726 "glProgramEnvParameterARB(target)");
1727 return;
1728 }
1729
1730 DIRTY(pb->dirty, g->neg_bitid);
1731}
1732
1733void STATE_APIENTRY crStateProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params)
1734{
1735 crStateProgramEnvParameter4fARB(target, index, params[0], params[1], params[2], params[3]);
1736}
1737
1738
1739/**********************************************************************/
1740
1741
1742void crStateProgramInit( CRContext *ctx )
1743{
1744 CRProgramState *p = &(ctx->program);
1745 CRStateBits *sb = GetCurrentBits();
1746 CRProgramBits *pb = &(sb->program);
1747 GLuint i;
1748
1749 CRASSERT(CR_MAX_PROGRAM_ENV_PARAMS >= CR_MAX_VERTEX_PROGRAM_ENV_PARAMS);
1750 CRASSERT(CR_MAX_PROGRAM_ENV_PARAMS >= CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS);
1751
1752 CRASSERT(CR_MAX_PROGRAM_LOCAL_PARAMS >= CR_MAX_VERTEX_PROGRAM_LOCAL_PARAMS);
1753 CRASSERT(CR_MAX_PROGRAM_LOCAL_PARAMS >= CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS);
1754
1755 p->programHash = crAllocHashtable();
1756
1757 /* ARB_vertex/fragment_program define default program objects */
1758 p->defaultVertexProgram = GetProgram(p, GL_VERTEX_PROGRAM_ARB, 0);
1759 p->defaultFragmentProgram = GetProgram(p, GL_FRAGMENT_PROGRAM_ARB, 0);
1760
1761 p->currentVertexProgram = p->defaultVertexProgram;
1762 p->currentFragmentProgram = p->defaultFragmentProgram;
1763 p->errorPos = -1;
1764 p->errorString = NULL;
1765
1766 for (i = 0; i < ctx->limits.maxVertexProgramEnvParams / 4; i++) {
1767 p->TrackMatrix[i] = GL_NONE;
1768 p->TrackMatrixTransform[i] = GL_IDENTITY_NV;
1769 }
1770 for (i = 0; i < ctx->limits.maxVertexProgramEnvParams; i++) {
1771 p->vertexParameters[i][0] = 0.0;
1772 p->vertexParameters[i][1] = 0.0;
1773 p->vertexParameters[i][2] = 0.0;
1774 p->vertexParameters[i][3] = 0.0;
1775 }
1776 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_ENV_PARAMS; i++) {
1777 p->fragmentParameters[i][0] = 0.0;
1778 p->fragmentParameters[i][1] = 0.0;
1779 p->fragmentParameters[i][2] = 0.0;
1780 p->fragmentParameters[i][3] = 0.0;
1781 }
1782
1783 p->vpEnabled = GL_FALSE;
1784 p->fpEnabled = GL_FALSE;
1785 p->fpEnabledARB = GL_FALSE;
1786 p->vpPointSize = GL_FALSE;
1787 p->vpTwoSide = GL_FALSE;
1788 RESET(pb->dirty, ctx->bitid);
1789}
1790
1791
1792static void DeleteProgramCallback( void *data )
1793{
1794 CRProgram *prog = (CRProgram *) data;
1795 DeleteProgram(prog);
1796}
1797
1798void crStateProgramDestroy(CRContext *ctx)
1799{
1800 CRProgramState *p = &(ctx->program);
1801 crFreeHashtable(p->programHash, DeleteProgramCallback);
1802 DeleteProgram(p->defaultVertexProgram);
1803 DeleteProgram(p->defaultFragmentProgram);
1804}
1805
1806
1807/* XXX it would be nice to autogenerate this, but we can't for now.
1808 */
1809void
1810crStateProgramDiff(CRProgramBits *b, CRbitvalue *bitID,
1811 CRContext *fromCtx, CRContext *toCtx)
1812{
1813 CRProgramState *from = &(fromCtx->program);
1814 CRProgramState *to = &(toCtx->program);
1815 unsigned int i, j;
1816 CRbitvalue nbitID[CR_MAX_BITARRAY];
1817
1818 CRASSERT(from->currentVertexProgram);
1819 CRASSERT(to->currentVertexProgram);
1820 CRASSERT(from->currentFragmentProgram);
1821 CRASSERT(to->currentFragmentProgram);
1822
1823 for (j=0;j<CR_MAX_BITARRAY;j++)
1824 nbitID[j] = ~bitID[j];
1825
1826 /* vertex program enable */
1827 if (CHECKDIRTY(b->vpEnable, bitID)) {
1828 glAble able[2];
1829 CRProgram *toProg = to->currentVertexProgram;
1830
1831 able[0] = diff_api.Disable;
1832 able[1] = diff_api.Enable;
1833 if (from->vpEnabled != to->vpEnabled) {
1834 if (toProg->isARBprogram)
1835 able[to->vpEnabled](GL_VERTEX_PROGRAM_ARB);
1836 else
1837 able[to->vpEnabled](GL_VERTEX_PROGRAM_NV);
1838 from->vpEnabled = to->vpEnabled;
1839 }
1840 if (from->vpTwoSide != to->vpTwoSide) {
1841 able[to->vpTwoSide](GL_VERTEX_PROGRAM_TWO_SIDE_NV);
1842 from->vpTwoSide = to->vpTwoSide;
1843 }
1844 if (from->vpPointSize != to->vpPointSize) {
1845 able[to->vpPointSize](GL_VERTEX_PROGRAM_POINT_SIZE_NV);
1846 from->vpPointSize = to->vpPointSize;
1847 }
1848 CLEARDIRTY(b->vpEnable, nbitID);
1849 }
1850
1851 /* fragment program enable */
1852 if (CHECKDIRTY(b->fpEnable, bitID)) {
1853 glAble able[2];
1854 able[0] = diff_api.Disable;
1855 able[1] = diff_api.Enable;
1856 if (from->fpEnabled != to->fpEnabled) {
1857 able[to->fpEnabled](GL_FRAGMENT_PROGRAM_NV);
1858 from->fpEnabled = to->fpEnabled;
1859 }
1860 if (from->fpEnabledARB != to->fpEnabledARB) {
1861 able[to->fpEnabledARB](GL_FRAGMENT_PROGRAM_ARB);
1862 from->fpEnabledARB = to->fpEnabledARB;
1863 }
1864 CLEARDIRTY(b->fpEnable, nbitID);
1865 }
1866
1867 /* program/track matrices */
1868 if (to->vpEnabled) {
1869 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams / 4; i++) {
1870 if (CHECKDIRTY(b->trackMatrix[i], bitID)) {
1871 if (from->TrackMatrix[i] != to->TrackMatrix[i] ||
1872 from->TrackMatrixTransform[i] != to->TrackMatrixTransform[i]) {
1873 diff_api.TrackMatrixNV(GL_VERTEX_PROGRAM_NV, i * 4,
1874 to->TrackMatrix[i],
1875 to->TrackMatrixTransform[i]);
1876 from->TrackMatrix[i] = to->TrackMatrix[i];
1877 from->TrackMatrixTransform[i] = to->TrackMatrixTransform[i];
1878 }
1879 CLEARDIRTY(b->trackMatrix[i], nbitID);
1880 }
1881 }
1882 }
1883
1884 if (to->vpEnabled) {
1885 /* vertex program binding */
1886 CRProgram *fromProg = from->currentVertexProgram;
1887 CRProgram *toProg = to->currentVertexProgram;
1888
1889 if (CHECKDIRTY(b->vpBinding, bitID)) {
1890 if (fromProg->id != toProg->id) {
1891 if (toProg->isARBprogram)
1892 diff_api.BindProgramARB(GL_VERTEX_PROGRAM_ARB, toProg->id);
1893 else
1894 diff_api.BindProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id);
1895 from->currentVertexProgram = toProg;
1896 }
1897 CLEARDIRTY(b->vpBinding, nbitID);
1898 }
1899
1900 if (toProg) {
1901 /* vertex program text */
1902 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
1903 if (toProg->isARBprogram) {
1904 diff_api.ProgramStringARB( GL_VERTEX_PROGRAM_ARB, toProg->format, toProg->length, toProg->string );
1905 }
1906 else {
1907 diff_api.LoadProgramNV( GL_VERTEX_PROGRAM_NV, toProg->id, toProg->length, toProg->string );
1908 }
1909 CLEARDIRTY(toProg->dirtyProgram, nbitID);
1910 }
1911
1912 /* vertex program global/env parameters */
1913 if (CHECKDIRTY(b->vertexEnvParameters, bitID)) {
1914 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams; i++) {
1915 if (CHECKDIRTY(b->vertexEnvParameter[i], bitID)) {
1916 if (toProg->isARBprogram)
1917 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i,
1918 to->vertexParameters[i]);
1919 else
1920 diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i,
1921 to->vertexParameters[i]);
1922 if (fromProg) {
1923 COPY_4V(from->vertexParameters[i],
1924 to->vertexParameters[i]);
1925 }
1926 CLEARDIRTY(b->vertexEnvParameter[i], nbitID);
1927 }
1928 }
1929 CLEARDIRTY(b->vertexEnvParameters, nbitID);
1930 }
1931
1932 /* vertex program local parameters */
1933 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
1934 for (i = 0; i < toCtx->limits.maxVertexProgramLocalParams; i++) {
1935 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
1936 if (toProg->isARBprogram)
1937 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, toProg->parameters[i]);
1938 else
1939 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_NV, i, toProg->parameters[i]);
1940 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
1941 }
1942 }
1943 CLEARDIRTY(toProg->dirtyParams, nbitID);
1944 }
1945 }
1946 }
1947
1948 /*
1949 * Separate paths for NV vs ARB fragment program
1950 */
1951 if (to->fpEnabled) {
1952 /* NV fragment program binding */
1953 CRProgram *fromProg = from->currentFragmentProgram;
1954 CRProgram *toProg = to->currentFragmentProgram;
1955 if (CHECKDIRTY(b->fpBinding, bitID)) {
1956 if (fromProg->id != toProg->id) {
1957 diff_api.BindProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id);
1958 from->currentFragmentProgram = toProg;
1959 }
1960 CLEARDIRTY(b->fpBinding, nbitID);
1961 }
1962
1963 if (toProg) {
1964 /* fragment program text */
1965 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
1966 diff_api.LoadProgramNV( GL_FRAGMENT_PROGRAM_NV, toProg->id,
1967 toProg->length, toProg->string );
1968 CLEARDIRTY(toProg->dirtyProgram, nbitID);
1969 }
1970
1971 /* fragment program global/env parameters */
1972 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
1973 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
1974 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
1975 diff_api.ProgramParameter4fvNV(GL_FRAGMENT_PROGRAM_NV, i,
1976 to->fragmentParameters[i]);
1977 if (fromProg) {
1978 COPY_4V(from->fragmentParameters[i],
1979 to->fragmentParameters[i]);
1980 }
1981 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
1982 }
1983 }
1984 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
1985 }
1986
1987 /* named local parameters */
1988 if (CHECKDIRTY(toProg->dirtyNamedParams, bitID)) {
1989 CRProgramSymbol *symbol;
1990 for (symbol = toProg->symbolTable; symbol; symbol = symbol->next) {
1991 if (CHECKDIRTY(symbol->dirty, bitID)) {
1992 GLint len = crStrlen(symbol->name);
1993 diff_api.ProgramNamedParameter4fvNV(toProg->id, len,
1994 (const GLubyte *) symbol->name,
1995 symbol->value);
1996 if (fromProg) {
1997 SetProgramSymbol(fromProg, symbol->name, len,
1998 symbol->value[0], symbol->value[1],
1999 symbol->value[2], symbol->value[3]);
2000 }
2001 CLEARDIRTY(symbol->dirty, nbitID);
2002 }
2003 }
2004 CLEARDIRTY(toProg->dirtyNamedParams, nbitID);
2005 }
2006
2007 /* numbered local parameters */
2008 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2009 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2010 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2011 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i,
2012 toProg->parameters[i]);
2013 if (fromProg) {
2014 COPY_4V(fromProg->parameters[i], toProg->parameters[i]);
2015 }
2016 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
2017 }
2018 }
2019 CLEARDIRTY(toProg->dirtyParams, nbitID);
2020 }
2021 }
2022 }
2023 else if (to->fpEnabledARB) {
2024 /* ARB fragment program binding */
2025 CRProgram *fromProg = from->currentFragmentProgram;
2026 CRProgram *toProg = to->currentFragmentProgram;
2027 if (CHECKDIRTY(b->fpBinding, bitID)) {
2028 if (fromProg->id != toProg->id) {
2029 diff_api.BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, toProg->id);
2030 from->currentFragmentProgram = toProg;
2031 }
2032 CLEARDIRTY(b->fpBinding, nbitID);
2033 }
2034
2035 if (toProg) {
2036 /* fragment program text */
2037 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2038 diff_api.ProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, toProg->format,
2039 toProg->length, toProg->string );
2040 CLEARDIRTY(toProg->dirtyProgram, nbitID);
2041 }
2042
2043 /* fragment program global/env parameters */
2044 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2045 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2046 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2047 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2048 to->fragmentParameters[i]);
2049 if (fromProg) {
2050 COPY_4V(from->fragmentParameters[i],
2051 to->fragmentParameters[i]);
2052 }
2053 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
2054 }
2055 }
2056 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
2057 }
2058
2059 /* numbered local parameters */
2060 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2061 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2062 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2063 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2064 toProg->parameters[i]);
2065 if (fromProg) {
2066 COPY_4V(fromProg->parameters[i], toProg->parameters[i]);
2067 }
2068 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
2069 }
2070 }
2071 CLEARDIRTY(toProg->dirtyParams, nbitID);
2072 }
2073 }
2074 }
2075
2076 CLEARDIRTY(b->dirty, nbitID);
2077}
2078
2079
2080void
2081crStateProgramSwitch(CRProgramBits *b, CRbitvalue *bitID,
2082 CRContext *fromCtx, CRContext *toCtx)
2083{
2084 CRProgramState *from = &(fromCtx->program);
2085 CRProgramState *to = &(toCtx->program);
2086 unsigned int i, j;
2087 CRbitvalue nbitID[CR_MAX_BITARRAY];
2088 GLenum whichVert = fromCtx->extensions.ARB_vertex_program && toCtx->extensions.ARB_vertex_program ? GL_VERTEX_PROGRAM_ARB : GL_VERTEX_PROGRAM_NV;
2089
2090
2091 for (j=0;j<CR_MAX_BITARRAY;j++)
2092 nbitID[j] = ~bitID[j];
2093
2094 /* vertex program enable */
2095 if (CHECKDIRTY(b->vpEnable, bitID)) {
2096 glAble able[2];
2097 able[0] = diff_api.Disable;
2098 able[1] = diff_api.Enable;
2099 if (from->vpEnabled != to->vpEnabled) {
2100 able[to->vpEnabled](whichVert);
2101 }
2102 if (from->vpTwoSide != to->vpTwoSide) {
2103 able[to->vpTwoSide](GL_VERTEX_PROGRAM_TWO_SIDE_NV);
2104 }
2105 if (from->vpPointSize != to->vpPointSize) {
2106 able[to->vpPointSize](GL_VERTEX_PROGRAM_POINT_SIZE_NV);
2107 }
2108
2109 CLEARDIRTY(b->vpEnable, nbitID);
2110 }
2111
2112 /* fragment program enable */
2113 if (CHECKDIRTY(b->fpEnable, bitID)) {
2114 glAble able[2];
2115 able[0] = diff_api.Disable;
2116 able[1] = diff_api.Enable;
2117 if (from->fpEnabled != to->fpEnabled) {
2118 able[to->fpEnabled](GL_FRAGMENT_PROGRAM_NV);
2119 }
2120 if (from->fpEnabledARB != to->fpEnabledARB) {
2121 able[to->fpEnabledARB](GL_FRAGMENT_PROGRAM_ARB);
2122 }
2123 CLEARDIRTY(b->fpEnable, nbitID);
2124 }
2125
2126 /* program/track matrices */
2127 if (to->vpEnabled) {
2128 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams / 4; i++) {
2129 if (CHECKDIRTY(b->trackMatrix[i], bitID)) {
2130 if (from->TrackMatrix[i] != to->TrackMatrix[i]) {
2131 diff_api.TrackMatrixNV(GL_VERTEX_PROGRAM_NV, i * 4,
2132 to->TrackMatrix[i],
2133 to->TrackMatrixTransform[i]);
2134 }
2135 CLEARDIRTY(b->trackMatrix[i], nbitID);
2136 }
2137 }
2138 }
2139
2140 if (to->vpEnabled) {
2141 /* vertex program binding */
2142 CRProgram *fromProg = from->currentVertexProgram;
2143 CRProgram *toProg = to->currentVertexProgram;
2144 if (CHECKDIRTY(b->vpBinding, bitID)) {
2145 if (fromProg->id != toProg->id) {
2146 if (toProg->isARBprogram)
2147 diff_api.BindProgramARB(GL_VERTEX_PROGRAM_ARB, toProg->id);
2148 else
2149 diff_api.BindProgramNV(GL_VERTEX_PROGRAM_NV, toProg->id);
2150 }
2151 CLEARDIRTY(b->vpBinding, nbitID);
2152 }
2153
2154 if (toProg) {
2155 /* vertex program text */
2156 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2157 if (toProg->isARBprogram)
2158 diff_api.ProgramStringARB( GL_VERTEX_PROGRAM_ARB,
2159 toProg->format,
2160 toProg->length,
2161 toProg->string );
2162 else
2163 diff_api.LoadProgramNV( GL_VERTEX_PROGRAM_NV,
2164 toProg->id,
2165 toProg->length,
2166 toProg->string );
2167 CLEARDIRTY(toProg->dirtyProgram, nbitID);
2168 }
2169
2170 /* vertex program global/env parameters */
2171 if (CHECKDIRTY(b->vertexEnvParameters, bitID)) {
2172 for (i = 0; i < toCtx->limits.maxVertexProgramEnvParams; i++) {
2173 if (CHECKDIRTY(b->vertexEnvParameter[i], bitID)) {
2174 if (toProg->isARBprogram)
2175 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i,
2176 to->vertexParameters[i]);
2177 else
2178 diff_api.ProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, i,
2179 to->vertexParameters[i]);
2180 CLEARDIRTY(b->vertexEnvParameter[i], nbitID);
2181 }
2182 }
2183 CLEARDIRTY(b->vertexEnvParameters, nbitID);
2184 }
2185
2186 /* vertex program local parameters */
2187 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2188 for (i = 0; i < toCtx->limits.maxVertexProgramLocalParams; i++) {
2189 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2190
2191
2192 if (toProg->isARBprogram)
2193 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, toProg->parameters[i]);
2194 else
2195 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_NV, i, toProg->parameters[i]);
2196 }
2197 }
2198 CLEARDIRTY(toProg->dirtyParams, nbitID);
2199 }
2200 }
2201 }
2202
2203 /*
2204 * Separate paths for NV vs ARB fragment program
2205 */
2206 if (to->fpEnabled) {
2207 /* NV fragment program binding */
2208 CRProgram *fromProg = from->currentFragmentProgram;
2209 CRProgram *toProg = to->currentFragmentProgram;
2210 if (CHECKDIRTY(b->fpBinding, bitID)) {
2211 if (fromProg->id != toProg->id) {
2212 diff_api.BindProgramNV(GL_FRAGMENT_PROGRAM_NV, toProg->id);
2213 }
2214 CLEARDIRTY(b->fpBinding, nbitID);
2215 }
2216
2217 if (toProg) {
2218 /* fragment program text */
2219 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2220 diff_api.LoadProgramNV( GL_FRAGMENT_PROGRAM_NV, toProg->id,
2221 toProg->length, toProg->string );
2222 CLEARDIRTY(toProg->dirtyProgram, nbitID);
2223 }
2224
2225 /* fragment program global/env parameters */
2226 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2227 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2228 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2229 diff_api.ProgramParameter4fvNV(GL_FRAGMENT_PROGRAM_NV, i,
2230 to->fragmentParameters[i]);
2231 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
2232 }
2233 }
2234 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
2235 }
2236
2237 /* named local parameters */
2238 if (CHECKDIRTY(toProg->dirtyNamedParams, bitID)) {
2239 CRProgramSymbol *symbol;
2240 for (symbol = toProg->symbolTable; symbol; symbol = symbol->next) {
2241 if (CHECKDIRTY(symbol->dirty, bitID)) {
2242 GLint len = crStrlen(symbol->name);
2243 diff_api.ProgramNamedParameter4fvNV(toProg->id, len,
2244 (const GLubyte *) symbol->name,
2245 symbol->value);
2246 CLEARDIRTY(symbol->dirty, nbitID);
2247 }
2248 }
2249 CLEARDIRTY(toProg->dirtyNamedParams, nbitID);
2250 }
2251
2252 /* numbered local parameters */
2253 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2254 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2255 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2256 if (toProg->isARBprogram)
2257 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2258 toProg->parameters[i]);
2259 else
2260 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_NV, i,
2261 toProg->parameters[i]);
2262 }
2263 }
2264 CLEARDIRTY(toProg->dirtyParams, nbitID);
2265 }
2266 }
2267 }
2268 else if (to->fpEnabledARB) {
2269 /* ARB fragment program binding */
2270 CRProgram *fromProg = from->currentFragmentProgram;
2271 CRProgram *toProg = to->currentFragmentProgram;
2272 if (CHECKDIRTY(b->fpBinding, bitID)) {
2273 if (fromProg->id != toProg->id) {
2274 diff_api.BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, toProg->id);
2275 }
2276 CLEARDIRTY(b->fpBinding, nbitID);
2277 }
2278
2279 if (toProg) {
2280 /* fragment program text */
2281 if (CHECKDIRTY(toProg->dirtyProgram, bitID)) {
2282 diff_api.ProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, toProg->format,
2283 toProg->length, toProg->string );
2284 CLEARDIRTY(toProg->dirtyProgram, nbitID);
2285 }
2286
2287 /* fragment program global/env parameters */
2288 if (CHECKDIRTY(b->fragmentEnvParameters, bitID)) {
2289 for (i = 0; i < toCtx->limits.maxFragmentProgramEnvParams; i++) {
2290 if (CHECKDIRTY(b->fragmentEnvParameter[i], bitID)) {
2291 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2292 to->fragmentParameters[i]);
2293 CLEARDIRTY(b->fragmentEnvParameter[i], nbitID);
2294 }
2295 }
2296 CLEARDIRTY(b->fragmentEnvParameters, nbitID);
2297 }
2298
2299 /* numbered local parameters */
2300 if (CHECKDIRTY(toProg->dirtyParams, bitID)) {
2301 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++) {
2302 if (CHECKDIRTY(toProg->dirtyParam[i], bitID)) {
2303 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i,
2304 toProg->parameters[i]);
2305 CLEARDIRTY(toProg->dirtyParam[i], nbitID);
2306 }
2307 }
2308 CLEARDIRTY(toProg->dirtyParams, nbitID);
2309 }
2310 }
2311 }
2312
2313 CLEARDIRTY(b->dirty, nbitID);
2314
2315 /* Resend program data */
2316 if (toCtx->program.bResyncNeeded)
2317 {
2318 toCtx->program.bResyncNeeded = GL_FALSE;
2319
2320 crStateDiffAllPrograms(toCtx, bitID, GL_TRUE);
2321 }
2322}
2323
2324/*@todo support NVprograms and add some data validity checks*/
2325static void
2326DiffProgramCallback(unsigned long key, void *pProg, void *pCtx)
2327{
2328 CRContext *pContext = (CRContext *) pCtx;
2329 CRProgram *pProgram = (CRProgram *) pProg;
2330 uint32_t i;
2331
2332 if (pProgram->isARBprogram)
2333 {
2334 diff_api.BindProgramARB(pProgram->target, pProgram->id);
2335 diff_api.ProgramStringARB(pProgram->target, pProgram->format, pProgram->length, pProgram->string);
2336
2337 if (GL_VERTEX_PROGRAM_ARB == pProgram->target)
2338 {
2339 /* vertex program global/env parameters */
2340 for (i = 0; i < pContext->limits.maxVertexProgramEnvParams; i++)
2341 {
2342 diff_api.ProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, pContext->program.vertexParameters[i]);
2343 }
2344 /* vertex program local parameters */
2345 for (i = 0; i < pContext->limits.maxVertexProgramLocalParams; i++)
2346 {
2347 diff_api.ProgramLocalParameter4fvARB(GL_VERTEX_PROGRAM_ARB, i, pProgram->parameters[i]);
2348 }
2349 }
2350 else if (GL_FRAGMENT_PROGRAM_ARB == pProgram->target)
2351 {
2352 /* vertex program global/env parameters */
2353 for (i = 0; i < pContext->limits.maxFragmentProgramEnvParams; i++)
2354 {
2355 diff_api.ProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, pContext->program.fragmentParameters[i]);
2356 }
2357 /* vertex program local parameters */
2358 for (i = 0; i < CR_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMS; i++)
2359 {
2360 diff_api.ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, i, pProgram->parameters[i]);
2361 }
2362 }
2363 else
2364 {
2365 crError("Unexpected program target");
2366 }
2367 }
2368 else
2369 {
2370 diff_api.BindProgramNV(pProgram->target, pProgram->id);
2371 }
2372}
2373
2374void crStateDiffAllPrograms(CRContext *g, CRbitvalue *bitID, GLboolean bForceUpdate)
2375{
2376 CRProgram *pOrigVP, *pOrigFP;
2377
2378 (void) bForceUpdate;
2379
2380 /* save original bindings */
2381 pOrigVP = g->program.currentVertexProgram;
2382 pOrigFP = g->program.currentFragmentProgram;
2383
2384 crHashtableWalk(g->program.programHash, DiffProgramCallback, g);
2385
2386 /* restore original bindings */
2387 if (pOrigVP->isARBprogram)
2388 diff_api.BindProgramARB(pOrigVP->target, pOrigVP->id);
2389 else
2390 diff_api.BindProgramNV(pOrigVP->target, pOrigVP->id);
2391
2392 if (pOrigFP->isARBprogram)
2393 diff_api.BindProgramARB(pOrigFP->target, pOrigFP->id);
2394 else
2395 diff_api.BindProgramNV(pOrigFP->target, pOrigFP->id);
2396}
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