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 * ARB_vertex/fragment_program state management functions.
33 #include "arbprogram.h"
34 #include "arbfragparse.h"
35 #include "arbvertparse.h"
40 #include "nvprogram.h"
41 #include "nvfragparse.h"
42 #include "nvfragprog.h"
43 #include "nvvertparse.h"
44 #include "nvvertprog.h"
48 _mesa_EnableVertexAttribArrayARB(GLuint index
)
50 GET_CURRENT_CONTEXT(ctx
);
51 ASSERT_OUTSIDE_BEGIN_END(ctx
);
53 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
54 _mesa_error(ctx
, GL_INVALID_VALUE
,
55 "glEnableVertexAttribArrayARB(index)");
59 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
60 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_TRUE
;
61 ctx
->Array
._Enabled
|= _NEW_ARRAY_ATTRIB(index
);
62 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
67 _mesa_DisableVertexAttribArrayARB(GLuint index
)
69 GET_CURRENT_CONTEXT(ctx
);
70 ASSERT_OUTSIDE_BEGIN_END(ctx
);
72 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
73 _mesa_error(ctx
, GL_INVALID_VALUE
,
74 "glEnableVertexAttribArrayARB(index)");
78 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
79 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_FALSE
;
80 ctx
->Array
._Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
81 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
86 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
89 GET_CURRENT_CONTEXT(ctx
);
90 ASSERT_OUTSIDE_BEGIN_END(ctx
);
92 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
93 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
94 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
95 COPY_4V(params
, fparams
);
98 params
[0] = fparams
[0];
105 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
107 GET_CURRENT_CONTEXT(ctx
);
108 ASSERT_OUTSIDE_BEGIN_END(ctx
);
110 if (index
== 0 || index
>= MAX_VERTEX_PROGRAM_ATTRIBS
) {
111 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribfvARB(index)");
116 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
117 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Enabled
;
119 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
120 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Size
;
122 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
123 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Stride
;
125 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
126 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Type
;
128 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
129 params
[0] = ctx
->Array
.VertexAttrib
[index
].Normalized
;
131 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
132 FLUSH_CURRENT(ctx
, 0);
134 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
136 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
138 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
139 if (!ctx
->Extensions
.ARB_vertex_buffer_object
) {
140 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
143 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].BufferObj
->Name
;
145 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
152 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
155 GET_CURRENT_CONTEXT(ctx
);
156 ASSERT_OUTSIDE_BEGIN_END(ctx
);
158 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
159 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
160 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
161 COPY_4V_CAST(params
, fparams
, GLint
); /* float to int */
164 params
[0] = (GLint
) fparams
[0];
171 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
173 GET_CURRENT_CONTEXT(ctx
);
174 ASSERT_OUTSIDE_BEGIN_END(ctx
);
176 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
177 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
181 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
182 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
186 *pointer
= (GLvoid
*) ctx
->Array
.VertexAttrib
[index
].Ptr
;;
191 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
192 const GLvoid
*string
)
194 GET_CURRENT_CONTEXT(ctx
);
195 ASSERT_OUTSIDE_BEGIN_END(ctx
);
197 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
199 if (target
== GL_VERTEX_PROGRAM_ARB
200 && ctx
->Extensions
.ARB_vertex_program
) {
201 struct vertex_program
*prog
= ctx
->VertexProgram
.Current
;
202 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
203 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
206 _mesa_parse_arb_vertex_program(ctx
, target
, (const GLubyte
*) string
,
209 if (ctx
->Driver
.ProgramStringNotify
)
210 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
212 else if (target
== GL_FRAGMENT_PROGRAM_ARB
213 && ctx
->Extensions
.ARB_fragment_program
) {
214 struct fragment_program
*prog
= ctx
->FragmentProgram
.Current
;
215 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
216 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
219 _mesa_parse_arb_fragment_program(ctx
, target
, (const GLubyte
*) string
,
222 if (ctx
->Driver
.ProgramStringNotify
)
223 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
226 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
233 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
234 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
236 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
237 (GLfloat
) z
, (GLfloat
) w
);
242 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
243 const GLdouble
*params
)
245 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
246 (GLfloat
) params
[1], (GLfloat
) params
[2],
247 (GLfloat
) params
[3]);
252 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
253 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
255 GET_CURRENT_CONTEXT(ctx
);
256 ASSERT_OUTSIDE_BEGIN_END(ctx
);
258 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
260 if (target
== GL_FRAGMENT_PROGRAM_ARB
261 && ctx
->Extensions
.ARB_fragment_program
) {
262 if (index
>= ctx
->Const
.MaxFragmentProgramEnvParams
) {
263 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
266 ASSIGN_4V(ctx
->FragmentProgram
.Parameters
[index
], x
, y
, z
, w
);
268 if (target
== GL_VERTEX_PROGRAM_ARB
269 && ctx
->Extensions
.ARB_vertex_program
) {
270 if (index
>= ctx
->Const
.MaxVertexProgramEnvParams
) {
271 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
274 ASSIGN_4V(ctx
->VertexProgram
.Parameters
[index
], x
, y
, z
, w
);
277 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
284 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
285 const GLfloat
*params
)
287 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
288 params
[2], params
[3]);
293 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
296 GET_CURRENT_CONTEXT(ctx
);
299 _mesa_GetProgramEnvParameterfvARB(target
, index
, fparams
);
300 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
301 params
[0] = fparams
[0];
302 params
[1] = fparams
[1];
303 params
[2] = fparams
[2];
304 params
[3] = fparams
[3];
310 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
313 GET_CURRENT_CONTEXT(ctx
);
315 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
317 if (!ctx
->_CurrentProgram
)
318 ASSERT_OUTSIDE_BEGIN_END(ctx
);
320 if (target
== GL_FRAGMENT_PROGRAM_ARB
321 && ctx
->Extensions
.ARB_fragment_program
) {
322 if (index
>= ctx
->Const
.MaxFragmentProgramEnvParams
) {
323 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
326 COPY_4V(params
, ctx
->FragmentProgram
.Parameters
[index
]);
328 if (target
== GL_VERTEX_PROGRAM_ARB
329 && ctx
->Extensions
.ARB_vertex_program
) {
330 if (index
>= ctx
->Const
.MaxVertexProgramEnvParams
) {
331 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
334 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
337 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
344 * Note, this function is also used by the GL_NV_fragment_program extension.
347 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
348 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
350 GET_CURRENT_CONTEXT(ctx
);
351 struct program
*prog
;
352 ASSERT_OUTSIDE_BEGIN_END(ctx
);
354 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
356 if ((target
== GL_FRAGMENT_PROGRAM_NV
357 && ctx
->Extensions
.NV_fragment_program
) ||
358 (target
== GL_FRAGMENT_PROGRAM_ARB
359 && ctx
->Extensions
.ARB_fragment_program
)) {
360 if (index
>= ctx
->Const
.MaxFragmentProgramLocalParams
) {
361 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
364 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
366 else if (target
== GL_VERTEX_PROGRAM_ARB
367 && ctx
->Extensions
.ARB_vertex_program
) {
368 if (index
>= ctx
->Const
.MaxVertexProgramLocalParams
) {
369 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
372 prog
= &(ctx
->VertexProgram
.Current
->Base
);
375 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
379 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
380 prog
->LocalParams
[index
][0] = x
;
381 prog
->LocalParams
[index
][1] = y
;
382 prog
->LocalParams
[index
][2] = z
;
383 prog
->LocalParams
[index
][3] = w
;
388 * Note, this function is also used by the GL_NV_fragment_program extension.
391 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
392 const GLfloat
*params
)
394 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
395 params
[2], params
[3]);
400 * Note, this function is also used by the GL_NV_fragment_program extension.
403 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
404 GLdouble x
, GLdouble y
,
405 GLdouble z
, GLdouble w
)
407 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
408 (GLfloat
) z
, (GLfloat
) w
);
413 * Note, this function is also used by the GL_NV_fragment_program extension.
416 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
417 const GLdouble
*params
)
419 _mesa_ProgramLocalParameter4fARB(target
, index
,
420 (GLfloat
) params
[0], (GLfloat
) params
[1],
421 (GLfloat
) params
[2], (GLfloat
) params
[3]);
426 * Note, this function is also used by the GL_NV_fragment_program extension.
429 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
432 const struct program
*prog
;
434 GET_CURRENT_CONTEXT(ctx
);
435 ASSERT_OUTSIDE_BEGIN_END(ctx
);
437 if (target
== GL_VERTEX_PROGRAM_ARB
438 && ctx
->Extensions
.ARB_vertex_program
) {
439 prog
= &(ctx
->VertexProgram
.Current
->Base
);
440 maxParams
= ctx
->Const
.MaxVertexProgramLocalParams
;
442 else if (target
== GL_FRAGMENT_PROGRAM_ARB
443 && ctx
->Extensions
.ARB_fragment_program
) {
444 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
445 maxParams
= ctx
->Const
.MaxFragmentProgramLocalParams
;
447 else if (target
== GL_FRAGMENT_PROGRAM_NV
448 && ctx
->Extensions
.NV_fragment_program
) {
449 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
450 maxParams
= MAX_NV_FRAGMENT_PROGRAM_PARAMS
;
453 _mesa_error(ctx
, GL_INVALID_ENUM
,
454 "glGetProgramLocalParameterARB(target)");
458 if (index
>= maxParams
) {
459 _mesa_error(ctx
, GL_INVALID_VALUE
,
460 "glGetProgramLocalParameterARB(index)");
465 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
466 COPY_4V(params
, prog
->LocalParams
[index
]);
471 * Note, this function is also used by the GL_NV_fragment_program extension.
474 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
477 GET_CURRENT_CONTEXT(ctx
);
478 GLfloat floatParams
[4];
479 _mesa_GetProgramLocalParameterfvARB(target
, index
, floatParams
);
480 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
481 COPY_4V(params
, floatParams
);
487 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
489 struct program
*prog
;
490 GET_CURRENT_CONTEXT(ctx
);
492 if (!ctx
->_CurrentProgram
)
493 ASSERT_OUTSIDE_BEGIN_END(ctx
);
495 if (target
== GL_VERTEX_PROGRAM_ARB
496 && ctx
->Extensions
.ARB_vertex_program
) {
497 prog
= &(ctx
->VertexProgram
.Current
->Base
);
499 else if (target
== GL_FRAGMENT_PROGRAM_ARB
500 && ctx
->Extensions
.ARB_fragment_program
) {
501 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
504 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
511 case GL_PROGRAM_LENGTH_ARB
:
512 *params
= prog
->String
? _mesa_strlen((char *) prog
->String
) : 0;
514 case GL_PROGRAM_FORMAT_ARB
:
515 *params
= prog
->Format
;
517 case GL_PROGRAM_BINDING_ARB
:
520 case GL_PROGRAM_INSTRUCTIONS_ARB
:
521 *params
= prog
->NumInstructions
;
523 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
524 if (target
== GL_VERTEX_PROGRAM_ARB
)
525 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
527 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
529 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
530 *params
= prog
->NumInstructions
;
532 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
533 if (target
== GL_VERTEX_PROGRAM_ARB
)
534 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
536 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
538 case GL_PROGRAM_TEMPORARIES_ARB
:
539 *params
= prog
->NumTemporaries
;
541 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
542 if (target
== GL_VERTEX_PROGRAM_ARB
)
543 *params
= ctx
->Const
.MaxVertexProgramTemps
;
545 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
547 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
548 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
549 *params
= prog
->NumTemporaries
;
551 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
552 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
553 if (target
== GL_VERTEX_PROGRAM_ARB
)
554 *params
= ctx
->Const
.MaxVertexProgramTemps
;
556 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
558 case GL_PROGRAM_PARAMETERS_ARB
:
559 *params
= prog
->NumParameters
;
561 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
562 if (target
== GL_VERTEX_PROGRAM_ARB
)
563 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
565 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
567 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
568 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
569 *params
= prog
->NumParameters
;
571 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
572 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
573 if (target
== GL_VERTEX_PROGRAM_ARB
)
574 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
576 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
578 case GL_PROGRAM_ATTRIBS_ARB
:
579 *params
= prog
->NumAttributes
;
581 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
582 if (target
== GL_VERTEX_PROGRAM_ARB
)
583 *params
= ctx
->Const
.MaxVertexProgramAttribs
;
585 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
587 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
588 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
589 *params
= prog
->NumAttributes
;
591 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
592 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
593 if (target
== GL_VERTEX_PROGRAM_ARB
)
594 *params
= ctx
->Const
.MaxVertexProgramAttribs
;
596 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
598 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
599 *params
= prog
->NumAddressRegs
;
601 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
602 if (target
== GL_VERTEX_PROGRAM_ARB
)
603 *params
= ctx
->Const
.MaxVertexProgramAddressRegs
;
605 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
607 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
608 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
609 *params
= prog
->NumAddressRegs
;
611 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
612 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
613 if (target
== GL_VERTEX_PROGRAM_ARB
)
614 *params
= ctx
->Const
.MaxVertexProgramAddressRegs
;
616 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
618 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
619 if (target
== GL_VERTEX_PROGRAM_ARB
)
620 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
622 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
624 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
625 if (target
== GL_VERTEX_PROGRAM_ARB
)
626 *params
= ctx
->Const
.MaxVertexProgramEnvParams
;
628 *params
= ctx
->Const
.MaxFragmentProgramEnvParams
;
630 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
631 if (ctx
->Driver
.IsProgramNative
)
632 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
638 * The following apply to fragment programs only.
640 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
641 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
642 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
643 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
646 *params
= ctx
->FragmentProgram
.Current
->NumAluInstructions
;
648 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
649 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
650 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
651 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
654 *params
= ctx
->FragmentProgram
.Current
->NumTexInstructions
;
656 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
657 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
658 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
659 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
662 *params
= ctx
->FragmentProgram
.Current
->NumTexIndirections
;
664 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
665 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
666 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
667 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
670 *params
= ctx
->Const
.MaxFragmentProgramAluInstructions
;
672 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
673 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
674 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
675 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
678 *params
= ctx
->Const
.MaxFragmentProgramTexInstructions
;
680 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
681 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
682 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
683 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
686 *params
= ctx
->Const
.MaxFragmentProgramTexIndirections
;
689 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
696 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
698 struct program
*prog
;
699 GET_CURRENT_CONTEXT(ctx
);
701 if (!ctx
->_CurrentProgram
)
702 ASSERT_OUTSIDE_BEGIN_END(ctx
);
704 if (target
== GL_VERTEX_PROGRAM_ARB
) {
705 prog
= &(ctx
->VertexProgram
.Current
->Base
);
707 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
708 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
711 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
717 if (pname
!= GL_PROGRAM_STRING_ARB
) {
718 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
722 MEMCPY(string
, prog
->String
, _mesa_strlen((char *) prog
->String
));