VirtualBox

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

最後變更 在這個檔案從80272是 79679,由 vboxsync 提交於 6 年 前

GuestHost/OpenGL: Enforce upper limit program size and free copy on error case

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

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