VirtualBox

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

最後變更 在這個檔案從78341是 71903,由 vboxsync 提交於 7 年 前

3D: bugref:9096, Chromium code cleanup

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

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