alias ARB/NV program functions where possible
[mesa.git] / src / mesa / main / arbprogram.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file arbprogram.c
27 * \brief ARB_vertex/fragment_program state management functions.
28 * \author Brian Paul
29 */
30
31
32 #include "glheader.h"
33 #include "arbprogram.h"
34 #include "context.h"
35 #include "hash.h"
36 #include "imports.h"
37 #include "macros.h"
38 #include "mtypes.h"
39 #include "nvprogram.h"
40 #include "nvfragprog.h"
41 #include "nvvertprog.h"
42
43
44 /* XXX temporary */
45 static void
46 _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
47 const GLubyte *string, GLsizei len,
48 struct vertex_program *prog)
49 {
50 }
51
52
53 static void
54 _mesa_parse_arb_fragment_program(GLcontext *ctx, GLenum target,
55 const GLubyte *string, GLsizei len,
56 struct fragment_program *prog)
57 {
58 }
59
60
61
62 void
63 _mesa_VertexAttrib1sARB(GLuint index, GLshort x)
64 {
65 }
66
67 void
68 _mesa_VertexAttrib1fARB(GLuint index, GLfloat x)
69 {
70 }
71
72 void
73 _mesa_VertexAttrib1dARB(GLuint index, GLdouble x)
74 {
75 }
76
77 void
78 _mesa_VertexAttrib2sARB(GLuint index, GLshort x, GLshort y)
79 {
80 }
81
82 void
83 _mesa_VertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y)
84 {
85 }
86
87 void
88 _mesa_VertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y)
89 {
90 }
91
92 void
93 _mesa_VertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z)
94 {
95 }
96
97 void
98 _mesa_VertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z)
99 {
100 }
101
102 void
103 _mesa_VertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z)
104 {
105 }
106
107 void
108 _mesa_VertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w)
109 {
110 }
111
112 void
113 _mesa_VertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
114 {
115 }
116
117 void
118 _mesa_VertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
119 {
120 }
121
122 void
123 _mesa_VertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w)
124 {
125 }
126
127 void
128 _mesa_VertexAttrib1svARB(GLuint index, const GLshort *v)
129 {
130 }
131
132 void
133 _mesa_VertexAttrib1fvARB(GLuint index, const GLfloat *v)
134 {
135 }
136
137 void
138 _mesa_VertexAttrib1dvARB(GLuint index, const GLdouble *v)
139 {
140 }
141
142 void
143 _mesa_VertexAttrib2svARB(GLuint index, const GLshort *v)
144 {
145 }
146
147 void
148 _mesa_VertexAttrib2fvARB(GLuint index, const GLfloat *v)
149 {
150 }
151
152 void
153 _mesa_VertexAttrib2dvARB(GLuint index, const GLdouble *v)
154 {
155 }
156
157 void
158 _mesa_VertexAttrib3svARB(GLuint index, const GLshort *v)
159 {
160 }
161
162 void
163 _mesa_VertexAttrib3fvARB(GLuint index, const GLfloat *v)
164 {
165 }
166
167 void
168 _mesa_VertexAttrib3dvARB(GLuint index, const GLdouble *v)
169 {
170 }
171
172 void
173 _mesa_VertexAttrib4bvARB(GLuint index, const GLbyte *v)
174 {
175 }
176
177 void
178 _mesa_VertexAttrib4svARB(GLuint index, const GLshort *v)
179 {
180 }
181
182 void
183 _mesa_VertexAttrib4ivARB(GLuint index, const GLint *v)
184 {
185 }
186
187 void
188 _mesa_VertexAttrib4ubvARB(GLuint index, const GLubyte *v)
189 {
190 }
191
192 void
193 _mesa_VertexAttrib4usvARB(GLuint index, const GLushort *v)
194 {
195 }
196
197 void
198 _mesa_VertexAttrib4uivARB(GLuint index, const GLuint *v)
199 {
200 }
201
202 void
203 _mesa_VertexAttrib4fvARB(GLuint index, const GLfloat *v)
204 {
205 }
206
207 void
208 _mesa_VertexAttrib4dvARB(GLuint index, const GLdouble *v)
209 {
210 }
211
212 void
213 _mesa_VertexAttrib4NbvARB(GLuint index, const GLbyte *v)
214 {
215 }
216
217 void
218 _mesa_VertexAttrib4NsvARB(GLuint index, const GLshort *v)
219 {
220 }
221
222 void
223 _mesa_VertexAttrib4NivARB(GLuint index, const GLint *v)
224 {
225 }
226
227 void
228 _mesa_VertexAttrib4NubvARB(GLuint index, const GLubyte *v)
229 {
230 }
231
232 void
233 _mesa_VertexAttrib4NusvARB(GLuint index, const GLushort *v)
234 {
235 }
236
237 void
238 _mesa_VertexAttrib4NuivARB(GLuint index, const GLuint *v)
239 {
240 }
241
242
243 void
244 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
245 GLboolean normalized, GLsizei stride,
246 const GLvoid *pointer)
247 {
248 }
249
250
251 void
252 _mesa_EnableVertexAttribArrayARB(GLuint index)
253 {
254 GET_CURRENT_CONTEXT(ctx);
255 ASSERT_OUTSIDE_BEGIN_END(ctx);
256
257 if (index >= ctx->Const.MaxVertexProgramAttribs) {
258 _mesa_error(ctx, GL_INVALID_VALUE,
259 "glEnableVertexAttribArrayARB(index)");
260 return;
261 }
262
263 ctx->Array.VertexAttrib[index].Enabled = GL_TRUE;
264 ctx->Array._Enabled |= _NEW_ARRAY_ATTRIB(index);
265 ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
266 }
267
268
269 void
270 _mesa_DisableVertexAttribArrayARB(GLuint index)
271 {
272 GET_CURRENT_CONTEXT(ctx);
273 ASSERT_OUTSIDE_BEGIN_END(ctx);
274
275 if (index >= ctx->Const.MaxVertexProgramAttribs) {
276 _mesa_error(ctx, GL_INVALID_VALUE,
277 "glEnableVertexAttribArrayARB(index)");
278 return;
279 }
280
281 ctx->Array.VertexAttrib[index].Enabled = GL_FALSE;
282 ctx->Array._Enabled &= ~_NEW_ARRAY_ATTRIB(index);
283 ctx->Array.NewState &= ~_NEW_ARRAY_ATTRIB(index);
284 }
285
286
287 void
288 _mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
289 {
290 GLfloat fparams[4];
291 GET_CURRENT_CONTEXT(ctx);
292 ASSERT_OUTSIDE_BEGIN_END(ctx);
293
294 _mesa_GetVertexAttribfvARB(index, pname, fparams);
295 if (ctx->ErrorValue == GL_NO_ERROR) {
296 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
297 COPY_4V(params, fparams);
298 }
299 else {
300 params[0] = fparams[0];
301 }
302 }
303 }
304
305
306 void
307 _mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
308 {
309 GET_CURRENT_CONTEXT(ctx);
310 ASSERT_OUTSIDE_BEGIN_END(ctx);
311
312 if (index == 0 || index >= VERT_ATTRIB_MAX) {
313 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribfvARB(index)");
314 return;
315 }
316
317 switch (pname) {
318 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
319 params[0] = ctx->Array.VertexAttrib[index].Enabled;
320 break;
321 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
322 params[0] = ctx->Array.VertexAttrib[index].Size;
323 break;
324 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
325 params[0] = ctx->Array.VertexAttrib[index].Stride;
326 break;
327 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
328 params[0] = ctx->Array.VertexAttrib[index].Type;
329 break;
330 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
331 params[0] = ctx->Array.VertexAttrib[index].Normalized;
332 break;
333 case GL_CURRENT_VERTEX_ATTRIB_ARB:
334 COPY_4V(params, ctx->Current.Attrib[index]);
335 break;
336 default:
337 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribfvARB(pname)");
338 return;
339 }
340 }
341
342
343 void
344 _mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
345 {
346 GLfloat fparams[4];
347 GET_CURRENT_CONTEXT(ctx);
348 ASSERT_OUTSIDE_BEGIN_END(ctx);
349
350 _mesa_GetVertexAttribfvARB(index, pname, fparams);
351 if (ctx->ErrorValue == GL_NO_ERROR) {
352 if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
353 COPY_4V(params, fparams); /* float to int */
354 }
355 else {
356 params[0] = fparams[0];
357 }
358 }
359 }
360
361
362 void
363 _mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
364 {
365 GET_CURRENT_CONTEXT(ctx);
366 ASSERT_OUTSIDE_BEGIN_END(ctx);
367
368 if (index >= ctx->Const.MaxVertexProgramAttribs) {
369 _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
370 return;
371 }
372
373 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
374 _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
375 return;
376 }
377
378 *pointer = ctx->Array.VertexAttrib[index].Ptr;;
379 }
380
381
382 void
383 _mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
384 const GLvoid *string)
385 {
386 GET_CURRENT_CONTEXT(ctx);
387 ASSERT_OUTSIDE_BEGIN_END(ctx);
388
389 if (target == GL_VERTEX_PROGRAM_ARB
390 && ctx->Extensions.ARB_vertex_program) {
391 struct vertex_program *prog = ctx->VertexProgram.Current;
392 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
393 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
394 return;
395 }
396 _mesa_parse_arb_vertex_program(ctx, target, string, len, prog);
397 }
398 else if (target == GL_FRAGMENT_PROGRAM_ARB
399 && ctx->Extensions.ARB_fragment_program) {
400 struct fragment_program *prog = ctx->FragmentProgram.Current;
401 if (format != GL_PROGRAM_FORMAT_ASCII_ARB) {
402 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(format)");
403 return;
404 }
405 _mesa_parse_arb_fragment_program(ctx, target, string, len, prog);
406 }
407 else {
408 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramStringARB(target)");
409 }
410 }
411
412
413 void
414 _mesa_BindProgramARB(GLenum target, GLuint program)
415 {
416 struct program *prog;
417 GET_CURRENT_CONTEXT(ctx);
418 ASSERT_OUTSIDE_BEGIN_END(ctx);
419
420 if (target == GL_VERTEX_PROGRAM_ARB
421 && ctx->Extensions.ARB_vertex_program) {
422 if (ctx->VertexProgram.Current &&
423 ctx->VertexProgram.Current->Base.Id == program)
424 return;
425 /* decrement refcount on previously bound vertex program */
426 if (ctx->VertexProgram.Current) {
427 ctx->VertexProgram.Current->Base.RefCount--;
428 /* and delete if refcount goes below one */
429 if (ctx->VertexProgram.Current->Base.RefCount <= 0) {
430 _mesa_delete_program(ctx, &(ctx->VertexProgram.Current->Base));
431 _mesa_HashRemove(ctx->Shared->Programs, program);
432 }
433 }
434 }
435 else if (target == GL_FRAGMENT_PROGRAM_ARB
436 && ctx->Extensions.ARB_fragment_program) {
437 if (ctx->FragmentProgram.Current &&
438 ctx->FragmentProgram.Current->Base.Id == program)
439 return;
440 /* decrement refcount on previously bound fragment program */
441 if (ctx->FragmentProgram.Current) {
442 ctx->FragmentProgram.Current->Base.RefCount--;
443 /* and delete if refcount goes below one */
444 if (ctx->FragmentProgram.Current->Base.RefCount <= 0) {
445 _mesa_delete_program(ctx, &(ctx->FragmentProgram.Current->Base));
446 _mesa_HashRemove(ctx->Shared->Programs, program);
447 }
448 }
449 }
450 else {
451 _mesa_error(ctx, GL_INVALID_ENUM, "glBindProgramARB(target)");
452 return;
453 }
454
455 /* NOTE: binding to a non-existant program is not an error.
456 * That's supposed to be caught in glBegin.
457 * NOTE: program number 0 is legal here.
458 */
459 if (program == 0) {
460 /* default program */
461 if (target == GL_VERTEX_PROGRAM_ARB)
462 prog = ctx->Shared->DefaultVertexProgram;
463 else
464 prog = ctx->Shared->DefaultFragmentProgram;
465 }
466 else {
467 prog = (struct program *) _mesa_HashLookup(ctx->Shared->Programs, program);
468 if (prog) {
469 if (prog->Target == 0) {
470 /* prog was allocated with glGenProgramsARB */
471 prog->Target = target;
472 }
473 else if (prog->Target != target) {
474 _mesa_error(ctx, GL_INVALID_OPERATION,
475 "glBindProgramARB(target mismatch)");
476 return;
477 }
478 }
479 else {
480 /* allocate a new program now */
481 prog = _mesa_alloc_program(ctx, target, program);
482 if (!prog) {
483 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindProgramARB");
484 return;
485 }
486 prog->Id = program;
487 prog->Target = target;
488 prog->Resident = GL_TRUE;
489 prog->RefCount = 1;
490 _mesa_HashInsert(ctx->Shared->Programs, program, prog);
491 }
492 }
493
494 /* bind now */
495 if (target == GL_VERTEX_PROGRAM_ARB) {
496 ctx->VertexProgram.Current = (struct vertex_program *) prog;
497 }
498 else {
499 ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
500 ctx->FragmentProgram.Current = (struct fragment_program *) prog;
501 }
502
503 if (prog)
504 prog->RefCount++;
505 }
506
507
508 void
509 _mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index,
510 GLdouble x, GLdouble y, GLdouble z, GLdouble w)
511 {
512 _mesa_ProgramEnvParameter4fARB(target, index, x, y, z, w);
513 }
514
515
516 void
517 _mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index,
518 const GLdouble *params)
519 {
520 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
521 params[2], params[3]);
522 }
523
524
525 void
526 _mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index,
527 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
528 {
529 GET_CURRENT_CONTEXT(ctx);
530 ASSERT_OUTSIDE_BEGIN_END(ctx);
531
532 if (target == GL_FRAGMENT_PROGRAM_ARB
533 && ctx->Extensions.ARB_fragment_program) {
534 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
535 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
536 return;
537 }
538 index += FP_PROG_REG_START;
539 ASSIGN_4V(ctx->FragmentProgram.Machine.Registers[index], x, y, z, w);
540 }
541 if (target == GL_VERTEX_PROGRAM_ARB
542 && ctx->Extensions.ARB_vertex_program) {
543 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
544 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramEnvParameter(index)");
545 return;
546 }
547 index += VP_PROG_REG_START;
548 ASSIGN_4V(ctx->VertexProgram.Machine.Registers[index], x, y, z, w);
549 }
550 else {
551 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramEnvParameter(target)");
552 return;
553 }
554 }
555
556
557 void
558 _mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index,
559 const GLfloat *params)
560 {
561 _mesa_ProgramEnvParameter4fARB(target, index, params[0], params[1],
562 params[2], params[3]);
563 }
564
565
566 void
567 _mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index,
568 GLdouble *params)
569 {
570 GET_CURRENT_CONTEXT(ctx);
571 GLfloat fparams[4];
572
573 _mesa_GetProgramEnvParameterfvARB(target, index, fparams);
574 if (ctx->ErrorValue == GL_NO_ERROR) {
575 params[0] = fparams[0];
576 params[1] = fparams[1];
577 params[2] = fparams[2];
578 params[3] = fparams[3];
579 }
580 }
581
582
583 void
584 _mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index,
585 GLfloat *params)
586 {
587 GET_CURRENT_CONTEXT(ctx);
588 ASSERT_OUTSIDE_BEGIN_END(ctx);
589
590 if (target == GL_FRAGMENT_PROGRAM_ARB
591 && ctx->Extensions.ARB_fragment_program) {
592 if (index >= ctx->Const.MaxFragmentProgramEnvParams) {
593 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
594 return;
595 }
596 index += FP_PROG_REG_START;
597 COPY_4V(params, ctx->FragmentProgram.Machine.Registers[index]);
598 }
599 if (target == GL_VERTEX_PROGRAM_ARB
600 && ctx->Extensions.ARB_vertex_program) {
601 if (index >= ctx->Const.MaxVertexProgramEnvParams) {
602 _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramEnvParameter(index)");
603 return;
604 }
605 index += VP_PROG_REG_START;
606 COPY_4V(params, ctx->VertexProgram.Machine.Registers[index]);
607 }
608 else {
609 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramEnvParameter(target)");
610 return;
611 }
612 }
613
614
615 /**
616 * Note, this function is also used by the GL_NV_fragment_program extension.
617 */
618 void
619 _mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index,
620 GLfloat x, GLfloat y, GLfloat z, GLfloat w)
621 {
622 GET_CURRENT_CONTEXT(ctx);
623 struct program *prog;
624 ASSERT_OUTSIDE_BEGIN_END(ctx);
625
626 if ((target == GL_FRAGMENT_PROGRAM_NV
627 && ctx->Extensions.NV_fragment_program) ||
628 (target == GL_FRAGMENT_PROGRAM_ARB
629 && ctx->Extensions.ARB_fragment_program)) {
630 if (index >= ctx->Const.MaxFragmentProgramLocalParams) {
631 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
632 return;
633 }
634 prog = &(ctx->FragmentProgram.Current->Base);
635 }
636 else if (target == GL_VERTEX_PROGRAM_ARB
637 && ctx->Extensions.ARB_vertex_program) {
638 if (index >= ctx->Const.MaxVertexProgramLocalParams) {
639 _mesa_error(ctx, GL_INVALID_VALUE, "glProgramLocalParameterARB");
640 return;
641 }
642 prog = &(ctx->VertexProgram.Current->Base);
643 }
644 else {
645 _mesa_error(ctx, GL_INVALID_ENUM, "glProgramLocalParameterARB");
646 return;
647 }
648
649 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
650 prog->LocalParams[index][0] = x;
651 prog->LocalParams[index][1] = y;
652 prog->LocalParams[index][2] = z;
653 prog->LocalParams[index][3] = w;
654 }
655
656
657 /**
658 * Note, this function is also used by the GL_NV_fragment_program extension.
659 */
660 void
661 _mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index,
662 const GLfloat *params)
663 {
664 _mesa_ProgramLocalParameter4fARB(target, index, params[0], params[1],
665 params[2], params[3]);
666 }
667
668
669 /**
670 * Note, this function is also used by the GL_NV_fragment_program extension.
671 */
672 void
673 _mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index,
674 GLdouble x, GLdouble y,
675 GLdouble z, GLdouble w)
676 {
677 _mesa_ProgramLocalParameter4fARB(target, index, (GLfloat) x, (GLfloat) y,
678 (GLfloat) z, (GLfloat) w);
679 }
680
681
682 /**
683 * Note, this function is also used by the GL_NV_fragment_program extension.
684 */
685 void
686 _mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index,
687 const GLdouble *params)
688 {
689 _mesa_ProgramLocalParameter4fARB(target, index,
690 (GLfloat) params[0], (GLfloat) params[1],
691 (GLfloat) params[2], (GLfloat) params[3]);
692 }
693
694
695 /**
696 * Note, this function is also used by the GL_NV_fragment_program extension.
697 */
698 void
699 _mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index,
700 GLfloat *params)
701 {
702 const struct program *prog;
703 GLuint maxParams;
704 GET_CURRENT_CONTEXT(ctx);
705 ASSERT_OUTSIDE_BEGIN_END(ctx);
706
707 if (target == GL_VERTEX_PROGRAM_ARB
708 && ctx->Extensions.ARB_vertex_program) {
709 prog = &(ctx->VertexProgram.Current->Base);
710 maxParams = ctx->Const.MaxVertexProgramLocalParams;
711 }
712 else if (target == GL_FRAGMENT_PROGRAM_ARB
713 && ctx->Extensions.ARB_fragment_program) {
714 prog = &(ctx->FragmentProgram.Current->Base);
715 maxParams = ctx->Const.MaxFragmentProgramLocalParams;
716 }
717 else if (target == GL_FRAGMENT_PROGRAM_NV
718 && ctx->Extensions.NV_fragment_program) {
719 prog = &(ctx->FragmentProgram.Current->Base);
720 maxParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
721 }
722 else {
723 _mesa_error(ctx, GL_INVALID_ENUM,
724 "glGetProgramLocalParameterARB(target)");
725 return;
726 }
727
728 if (index >= maxParams) {
729 _mesa_error(ctx, GL_INVALID_VALUE,
730 "glGetProgramLocalParameterARB(index)");
731 return;
732 }
733
734 ASSERT(prog);
735 ASSERT(index < MAX_PROGRAM_LOCAL_PARAMS);
736 COPY_4V(params, prog->LocalParams[index]);
737 }
738
739
740 /**
741 * Note, this function is also used by the GL_NV_fragment_program extension.
742 */
743 void
744 _mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index,
745 GLdouble *params)
746 {
747 GET_CURRENT_CONTEXT(ctx);
748 GLfloat floatParams[4];
749 _mesa_GetProgramLocalParameterfvARB(target, index, floatParams);
750 if (ctx->ErrorValue == GL_NO_ERROR) {
751 COPY_4V(params, floatParams);
752 }
753 }
754
755
756 void
757 _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
758 {
759 struct program *prog;
760 GET_CURRENT_CONTEXT(ctx);
761 ASSERT_OUTSIDE_BEGIN_END(ctx);
762
763 if (target == GL_VERTEX_PROGRAM_ARB
764 && ctx->Extensions.ARB_vertex_program) {
765 prog = &(ctx->VertexProgram.Current->Base);
766 }
767 else if (target == GL_FRAGMENT_PROGRAM_ARB
768 && ctx->Extensions.ARB_vertex_program) {
769 prog = &(ctx->FragmentProgram.Current->Base);
770 }
771 else {
772 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
773 return;
774 }
775
776 ASSERT(prog);
777
778 switch (pname) {
779 case GL_PROGRAM_LENGTH_ARB:
780 *params = prog->String ? _mesa_strlen((char *) prog->String) : 0;
781 break;
782 case GL_PROGRAM_FORMAT_ARB:
783 *params = prog->Format;
784 break;
785 case GL_PROGRAM_BINDING_ARB:
786 *params = prog->Id;
787 break;
788 case GL_PROGRAM_INSTRUCTIONS_ARB:
789 *params = prog->NumInstructions;
790 break;
791 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB:
792 if (target == GL_VERTEX_PROGRAM_ARB)
793 *params = ctx->Const.MaxVertexProgramInstructions;
794 else
795 *params = ctx->Const.MaxFragmentProgramInstructions;
796 break;
797 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
798 *params = prog->NumInstructions;
799 break;
800 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB:
801 if (target == GL_VERTEX_PROGRAM_ARB)
802 *params = ctx->Const.MaxVertexProgramInstructions;
803 else
804 *params = ctx->Const.MaxFragmentProgramInstructions;
805 break;
806 case GL_PROGRAM_TEMPORARIES_ARB:
807 *params = prog->NumTemporaries;
808 break;
809 case GL_MAX_PROGRAM_TEMPORARIES_ARB:
810 if (target == GL_VERTEX_PROGRAM_ARB)
811 *params = ctx->Const.MaxVertexProgramTemps;
812 else
813 *params = ctx->Const.MaxFragmentProgramTemps;
814 break;
815 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB:
816 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
817 *params = prog->NumTemporaries;
818 break;
819 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB:
820 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
821 if (target == GL_VERTEX_PROGRAM_ARB)
822 *params = ctx->Const.MaxVertexProgramTemps;
823 else
824 *params = ctx->Const.MaxFragmentProgramTemps;
825 break;
826 case GL_PROGRAM_PARAMETERS_ARB:
827 *params = prog->NumParameters;
828 break;
829 case GL_MAX_PROGRAM_PARAMETERS_ARB:
830 if (target == GL_VERTEX_PROGRAM_ARB)
831 *params = ctx->Const.MaxVertexProgramLocalParams;
832 else
833 *params = ctx->Const.MaxFragmentProgramLocalParams;
834 break;
835 case GL_PROGRAM_NATIVE_PARAMETERS_ARB:
836 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
837 *params = prog->NumParameters;
838 break;
839 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB:
840 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
841 if (target == GL_VERTEX_PROGRAM_ARB)
842 *params = ctx->Const.MaxVertexProgramLocalParams;
843 else
844 *params = ctx->Const.MaxFragmentProgramLocalParams;
845 break;
846 case GL_PROGRAM_ATTRIBS_ARB:
847 *params = prog->NumAttributes;
848 break;
849 case GL_MAX_PROGRAM_ATTRIBS_ARB:
850 if (target == GL_VERTEX_PROGRAM_ARB)
851 *params = ctx->Const.MaxVertexProgramAttribs;
852 else
853 *params = ctx->Const.MaxFragmentProgramAttribs;
854 break;
855 case GL_PROGRAM_NATIVE_ATTRIBS_ARB:
856 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
857 *params = prog->NumAttributes;
858 break;
859 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB:
860 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
861 if (target == GL_VERTEX_PROGRAM_ARB)
862 *params = ctx->Const.MaxVertexProgramAttribs;
863 else
864 *params = ctx->Const.MaxFragmentProgramAttribs;
865 break;
866 case GL_PROGRAM_ADDRESS_REGISTERS_ARB:
867 *params = prog->NumAddressRegs;
868 break;
869 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB:
870 if (target == GL_VERTEX_PROGRAM_ARB)
871 *params = ctx->Const.MaxVertexProgramAddressRegs;
872 else
873 *params = ctx->Const.MaxFragmentProgramAddressRegs;
874 break;
875 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
876 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
877 *params = prog->NumAddressRegs;
878 break;
879 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB:
880 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
881 if (target == GL_VERTEX_PROGRAM_ARB)
882 *params = ctx->Const.MaxVertexProgramAddressRegs;
883 else
884 *params = ctx->Const.MaxFragmentProgramAddressRegs;
885 break;
886 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB:
887 if (target == GL_VERTEX_PROGRAM_ARB)
888 *params = ctx->Const.MaxVertexProgramLocalParams;
889 else
890 *params = ctx->Const.MaxFragmentProgramLocalParams;
891 break;
892 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB:
893 if (target == GL_VERTEX_PROGRAM_ARB)
894 *params = ctx->Const.MaxVertexProgramEnvParams;
895 else
896 *params = ctx->Const.MaxFragmentProgramEnvParams;
897 break;
898 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB:
899 /* XXX ok? */
900 *params = GL_TRUE;
901 break;
902
903 /*
904 * The following apply to fragment programs only.
905 */
906 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB:
907 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
908 if (target != GL_FRAGMENT_PROGRAM_ARB) {
909 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
910 return;
911 }
912 *params = ctx->FragmentProgram.Current->NumAluInstructions;
913 break;
914 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB:
915 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
916 if (target != GL_FRAGMENT_PROGRAM_ARB) {
917 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
918 return;
919 }
920 *params = ctx->FragmentProgram.Current->NumTexInstructions;
921 break;
922 case GL_PROGRAM_TEX_INDIRECTIONS_ARB:
923 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
924 if (target != GL_FRAGMENT_PROGRAM_ARB) {
925 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
926 return;
927 }
928 *params = ctx->FragmentProgram.Current->NumTexIndirections;
929 break;
930 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB:
931 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB:
932 if (target != GL_FRAGMENT_PROGRAM_ARB) {
933 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
934 return;
935 }
936 *params = ctx->Const.MaxFragmentProgramAluInstructions;
937 break;
938 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB:
939 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB:
940 if (target != GL_FRAGMENT_PROGRAM_ARB) {
941 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
942 return;
943 }
944 *params = ctx->Const.MaxFragmentProgramTexInstructions;
945 break;
946 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB:
947 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB:
948 if (target != GL_FRAGMENT_PROGRAM_ARB) {
949 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(target)");
950 return;
951 }
952 *params = ctx->Const.MaxFragmentProgramTexIndirections;
953 break;
954 default:
955 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
956 return;
957 }
958 }
959
960
961 void
962 _mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string)
963 {
964 struct program *prog;
965 GET_CURRENT_CONTEXT(ctx);
966 ASSERT_OUTSIDE_BEGIN_END(ctx);
967
968 if (target == GL_VERTEX_PROGRAM_ARB) {
969 prog = &(ctx->VertexProgram.Current->Base);
970 }
971 else if (target == GL_FRAGMENT_PROGRAM_ARB) {
972 prog = &(ctx->FragmentProgram.Current->Base);
973 }
974 else {
975 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(target)");
976 return;
977 }
978
979 ASSERT(prog);
980
981 if (pname != GL_PROGRAM_STRING_ARB) {
982 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramStringARB(pname)");
983 return;
984 }
985
986 MEMCPY(string, prog->String, _mesa_strlen((char *) prog->String));
987 }