2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
27 * \brief ARB_vertex/fragment_program state management functions.
33 #include "arbprogram.h"
39 #include "nvprogram.h"
40 #include "nvfragprog.h"
41 #include "nvvertprog.h"
46 _mesa_parse_arb_vertex_program(GLcontext
*ctx
, GLenum target
,
47 const GLubyte
*string
, GLsizei len
,
48 struct vertex_program
*prog
)
54 _mesa_parse_arb_fragment_program(GLcontext
*ctx
, GLenum target
,
55 const GLubyte
*string
, GLsizei len
,
56 struct fragment_program
*prog
)
63 _mesa_VertexAttrib1sARB(GLuint index
, GLshort x
)
68 _mesa_VertexAttrib1fARB(GLuint index
, GLfloat x
)
73 _mesa_VertexAttrib1dARB(GLuint index
, GLdouble x
)
78 _mesa_VertexAttrib2sARB(GLuint index
, GLshort x
, GLshort y
)
83 _mesa_VertexAttrib2fARB(GLuint index
, GLfloat x
, GLfloat y
)
88 _mesa_VertexAttrib2dARB(GLuint index
, GLdouble x
, GLdouble y
)
93 _mesa_VertexAttrib3sARB(GLuint index
, GLshort x
, GLshort y
, GLshort z
)
98 _mesa_VertexAttrib3fARB(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
)
103 _mesa_VertexAttrib3dARB(GLuint index
, GLdouble x
, GLdouble y
, GLdouble z
)
108 _mesa_VertexAttrib4sARB(GLuint index
, GLshort x
, GLshort y
, GLshort z
, GLshort w
)
113 _mesa_VertexAttrib4fARB(GLuint index
, GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
118 _mesa_VertexAttrib4dARB(GLuint index
, GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
123 _mesa_VertexAttrib4NubARB(GLuint index
, GLubyte x
, GLubyte y
, GLubyte z
, GLubyte w
)
128 _mesa_VertexAttrib1svARB(GLuint index
, const GLshort
*v
)
133 _mesa_VertexAttrib1fvARB(GLuint index
, const GLfloat
*v
)
138 _mesa_VertexAttrib1dvARB(GLuint index
, const GLdouble
*v
)
143 _mesa_VertexAttrib2svARB(GLuint index
, const GLshort
*v
)
148 _mesa_VertexAttrib2fvARB(GLuint index
, const GLfloat
*v
)
153 _mesa_VertexAttrib2dvARB(GLuint index
, const GLdouble
*v
)
158 _mesa_VertexAttrib3svARB(GLuint index
, const GLshort
*v
)
163 _mesa_VertexAttrib3fvARB(GLuint index
, const GLfloat
*v
)
168 _mesa_VertexAttrib3dvARB(GLuint index
, const GLdouble
*v
)
173 _mesa_VertexAttrib4bvARB(GLuint index
, const GLbyte
*v
)
178 _mesa_VertexAttrib4svARB(GLuint index
, const GLshort
*v
)
183 _mesa_VertexAttrib4ivARB(GLuint index
, const GLint
*v
)
188 _mesa_VertexAttrib4ubvARB(GLuint index
, const GLubyte
*v
)
193 _mesa_VertexAttrib4usvARB(GLuint index
, const GLushort
*v
)
198 _mesa_VertexAttrib4uivARB(GLuint index
, const GLuint
*v
)
203 _mesa_VertexAttrib4fvARB(GLuint index
, const GLfloat
*v
)
208 _mesa_VertexAttrib4dvARB(GLuint index
, const GLdouble
*v
)
213 _mesa_VertexAttrib4NbvARB(GLuint index
, const GLbyte
*v
)
218 _mesa_VertexAttrib4NsvARB(GLuint index
, const GLshort
*v
)
223 _mesa_VertexAttrib4NivARB(GLuint index
, const GLint
*v
)
228 _mesa_VertexAttrib4NubvARB(GLuint index
, const GLubyte
*v
)
233 _mesa_VertexAttrib4NusvARB(GLuint index
, const GLushort
*v
)
238 _mesa_VertexAttrib4NuivARB(GLuint index
, const GLuint
*v
)
244 _mesa_VertexAttribPointerARB(GLuint index
, GLint size
, GLenum type
,
245 GLboolean normalized
, GLsizei stride
,
246 const GLvoid
*pointer
)
252 _mesa_EnableVertexAttribArrayARB(GLuint index
)
254 GET_CURRENT_CONTEXT(ctx
);
255 ASSERT_OUTSIDE_BEGIN_END(ctx
);
257 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
258 _mesa_error(ctx
, GL_INVALID_VALUE
,
259 "glEnableVertexAttribArrayARB(index)");
263 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_TRUE
;
264 ctx
->Array
._Enabled
|= _NEW_ARRAY_ATTRIB(index
);
265 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
270 _mesa_DisableVertexAttribArrayARB(GLuint index
)
272 GET_CURRENT_CONTEXT(ctx
);
273 ASSERT_OUTSIDE_BEGIN_END(ctx
);
275 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
276 _mesa_error(ctx
, GL_INVALID_VALUE
,
277 "glEnableVertexAttribArrayARB(index)");
281 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_FALSE
;
282 ctx
->Array
._Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
283 ctx
->Array
.NewState
&= ~_NEW_ARRAY_ATTRIB(index
);
288 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
291 GET_CURRENT_CONTEXT(ctx
);
292 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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
);
300 params
[0] = fparams
[0];
307 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
309 GET_CURRENT_CONTEXT(ctx
);
310 ASSERT_OUTSIDE_BEGIN_END(ctx
);
312 if (index
== 0 || index
>= VERT_ATTRIB_MAX
) {
313 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribfvARB(index)");
318 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
319 params
[0] = ctx
->Array
.VertexAttrib
[index
].Enabled
;
321 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
322 params
[0] = ctx
->Array
.VertexAttrib
[index
].Size
;
324 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
325 params
[0] = ctx
->Array
.VertexAttrib
[index
].Stride
;
327 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
328 params
[0] = ctx
->Array
.VertexAttrib
[index
].Type
;
330 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
331 params
[0] = ctx
->Array
.VertexAttrib
[index
].Normalized
;
333 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
334 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
337 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
344 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
347 GET_CURRENT_CONTEXT(ctx
);
348 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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 */
356 params
[0] = fparams
[0];
363 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
365 GET_CURRENT_CONTEXT(ctx
);
366 ASSERT_OUTSIDE_BEGIN_END(ctx
);
368 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
369 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
373 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
374 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
378 *pointer
= ctx
->Array
.VertexAttrib
[index
].Ptr
;;
383 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
384 const GLvoid
*string
)
386 GET_CURRENT_CONTEXT(ctx
);
387 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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)");
396 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
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)");
405 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
408 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
414 _mesa_BindProgramARB(GLenum target
, GLuint program
)
416 struct program
*prog
;
417 GET_CURRENT_CONTEXT(ctx
);
418 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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
)
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
);
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
)
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
);
451 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBindProgramARB(target)");
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.
460 /* default program */
461 if (target
== GL_VERTEX_PROGRAM_ARB
)
462 prog
= ctx
->Shared
->DefaultVertexProgram
;
464 prog
= ctx
->Shared
->DefaultFragmentProgram
;
467 prog
= (struct program
*) _mesa_HashLookup(ctx
->Shared
->Programs
, program
);
469 if (prog
->Target
== 0) {
470 /* prog was allocated with glGenProgramsARB */
471 prog
->Target
= target
;
473 else if (prog
->Target
!= target
) {
474 _mesa_error(ctx
, GL_INVALID_OPERATION
,
475 "glBindProgramARB(target mismatch)");
480 /* allocate a new program now */
481 prog
= _mesa_alloc_program(ctx
, target
, program
);
483 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glBindProgramARB");
487 prog
->Target
= target
;
488 prog
->Resident
= GL_TRUE
;
490 _mesa_HashInsert(ctx
->Shared
->Programs
, program
, prog
);
495 if (target
== GL_VERTEX_PROGRAM_ARB
) {
496 ctx
->VertexProgram
.Current
= (struct vertex_program
*) prog
;
499 ASSERT(target
== GL_FRAGMENT_PROGRAM_ARB
);
500 ctx
->FragmentProgram
.Current
= (struct fragment_program
*) prog
;
509 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
510 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
512 _mesa_ProgramEnvParameter4fARB(target
, index
, x
, y
, z
, w
);
517 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
518 const GLdouble
*params
)
520 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
521 params
[2], params
[3]);
526 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
527 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
529 GET_CURRENT_CONTEXT(ctx
);
530 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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)");
538 index
+= FP_PROG_REG_START
;
539 ASSIGN_4V(ctx
->FragmentProgram
.Machine
.Registers
[index
], x
, y
, z
, w
);
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)");
547 index
+= VP_PROG_REG_START
;
548 ASSIGN_4V(ctx
->VertexProgram
.Machine
.Registers
[index
], x
, y
, z
, w
);
551 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
558 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
559 const GLfloat
*params
)
561 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
562 params
[2], params
[3]);
567 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
570 GET_CURRENT_CONTEXT(ctx
);
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];
584 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
587 GET_CURRENT_CONTEXT(ctx
);
588 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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)");
596 index
+= FP_PROG_REG_START
;
597 COPY_4V(params
, ctx
->FragmentProgram
.Machine
.Registers
[index
]);
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)");
605 index
+= VP_PROG_REG_START
;
606 COPY_4V(params
, ctx
->VertexProgram
.Machine
.Registers
[index
]);
609 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
616 * Note, this function is also used by the GL_NV_fragment_program extension.
619 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
620 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
622 GET_CURRENT_CONTEXT(ctx
);
623 struct program
*prog
;
624 ASSERT_OUTSIDE_BEGIN_END(ctx
);
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");
634 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
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");
642 prog
= &(ctx
->VertexProgram
.Current
->Base
);
645 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
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
;
658 * Note, this function is also used by the GL_NV_fragment_program extension.
661 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
662 const GLfloat
*params
)
664 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
665 params
[2], params
[3]);
670 * Note, this function is also used by the GL_NV_fragment_program extension.
673 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
674 GLdouble x
, GLdouble y
,
675 GLdouble z
, GLdouble w
)
677 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
678 (GLfloat
) z
, (GLfloat
) w
);
683 * Note, this function is also used by the GL_NV_fragment_program extension.
686 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
687 const GLdouble
*params
)
689 _mesa_ProgramLocalParameter4fARB(target
, index
,
690 (GLfloat
) params
[0], (GLfloat
) params
[1],
691 (GLfloat
) params
[2], (GLfloat
) params
[3]);
696 * Note, this function is also used by the GL_NV_fragment_program extension.
699 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
702 const struct program
*prog
;
704 GET_CURRENT_CONTEXT(ctx
);
705 ASSERT_OUTSIDE_BEGIN_END(ctx
);
707 if (target
== GL_VERTEX_PROGRAM_ARB
708 && ctx
->Extensions
.ARB_vertex_program
) {
709 prog
= &(ctx
->VertexProgram
.Current
->Base
);
710 maxParams
= ctx
->Const
.MaxVertexProgramLocalParams
;
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
;
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
;
723 _mesa_error(ctx
, GL_INVALID_ENUM
,
724 "glGetProgramLocalParameterARB(target)");
728 if (index
>= maxParams
) {
729 _mesa_error(ctx
, GL_INVALID_VALUE
,
730 "glGetProgramLocalParameterARB(index)");
735 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
736 COPY_4V(params
, prog
->LocalParams
[index
]);
741 * Note, this function is also used by the GL_NV_fragment_program extension.
744 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
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
);
757 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
759 struct program
*prog
;
760 GET_CURRENT_CONTEXT(ctx
);
761 ASSERT_OUTSIDE_BEGIN_END(ctx
);
763 if (target
== GL_VERTEX_PROGRAM_ARB
764 && ctx
->Extensions
.ARB_vertex_program
) {
765 prog
= &(ctx
->VertexProgram
.Current
->Base
);
767 else if (target
== GL_FRAGMENT_PROGRAM_ARB
768 && ctx
->Extensions
.ARB_vertex_program
) {
769 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
772 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
779 case GL_PROGRAM_LENGTH_ARB
:
780 *params
= prog
->String
? _mesa_strlen((char *) prog
->String
) : 0;
782 case GL_PROGRAM_FORMAT_ARB
:
783 *params
= prog
->Format
;
785 case GL_PROGRAM_BINDING_ARB
:
788 case GL_PROGRAM_INSTRUCTIONS_ARB
:
789 *params
= prog
->NumInstructions
;
791 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
792 if (target
== GL_VERTEX_PROGRAM_ARB
)
793 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
795 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
797 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
798 *params
= prog
->NumInstructions
;
800 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
801 if (target
== GL_VERTEX_PROGRAM_ARB
)
802 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
804 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
806 case GL_PROGRAM_TEMPORARIES_ARB
:
807 *params
= prog
->NumTemporaries
;
809 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
810 if (target
== GL_VERTEX_PROGRAM_ARB
)
811 *params
= ctx
->Const
.MaxVertexProgramTemps
;
813 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
815 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
816 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
817 *params
= prog
->NumTemporaries
;
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
;
824 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
826 case GL_PROGRAM_PARAMETERS_ARB
:
827 *params
= prog
->NumParameters
;
829 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
830 if (target
== GL_VERTEX_PROGRAM_ARB
)
831 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
833 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
835 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
836 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
837 *params
= prog
->NumParameters
;
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
;
844 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
846 case GL_PROGRAM_ATTRIBS_ARB
:
847 *params
= prog
->NumAttributes
;
849 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
850 if (target
== GL_VERTEX_PROGRAM_ARB
)
851 *params
= ctx
->Const
.MaxVertexProgramAttribs
;
853 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
855 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
856 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
857 *params
= prog
->NumAttributes
;
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
;
864 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
866 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
867 *params
= prog
->NumAddressRegs
;
869 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
870 if (target
== GL_VERTEX_PROGRAM_ARB
)
871 *params
= ctx
->Const
.MaxVertexProgramAddressRegs
;
873 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
875 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
876 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
877 *params
= prog
->NumAddressRegs
;
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
;
884 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
886 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
887 if (target
== GL_VERTEX_PROGRAM_ARB
)
888 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
890 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
892 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
893 if (target
== GL_VERTEX_PROGRAM_ARB
)
894 *params
= ctx
->Const
.MaxVertexProgramEnvParams
;
896 *params
= ctx
->Const
.MaxFragmentProgramEnvParams
;
898 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
904 * The following apply to fragment programs only.
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)");
912 *params
= ctx
->FragmentProgram
.Current
->NumAluInstructions
;
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)");
920 *params
= ctx
->FragmentProgram
.Current
->NumTexInstructions
;
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)");
928 *params
= ctx
->FragmentProgram
.Current
->NumTexIndirections
;
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)");
936 *params
= ctx
->Const
.MaxFragmentProgramAluInstructions
;
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)");
944 *params
= ctx
->Const
.MaxFragmentProgramTexInstructions
;
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)");
952 *params
= ctx
->Const
.MaxFragmentProgramTexIndirections
;
955 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
962 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
964 struct program
*prog
;
965 GET_CURRENT_CONTEXT(ctx
);
966 ASSERT_OUTSIDE_BEGIN_END(ctx
);
968 if (target
== GL_VERTEX_PROGRAM_ARB
) {
969 prog
= &(ctx
->VertexProgram
.Current
->Base
);
971 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
972 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
975 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
981 if (pname
!= GL_PROGRAM_STRING_ARB
) {
982 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
986 MEMCPY(string
, prog
->String
, _mesa_strlen((char *) prog
->String
));