VirtualBox

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

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

Additions/common/crOpengl,GuestHost/OpenGL,HostServices/SharedOpenGL: Eliminate all global variables from the state tracker library (state_tracker) in preparation of the SPU DLL merging, bugref:9435

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

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