2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 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 "arbprogparse.h"
43 _mesa_EnableVertexAttribArrayARB(GLuint index
)
45 GET_CURRENT_CONTEXT(ctx
);
46 ASSERT_OUTSIDE_BEGIN_END(ctx
);
48 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
49 _mesa_error(ctx
, GL_INVALID_VALUE
,
50 "glEnableVertexAttribArrayARB(index)");
54 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
55 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_TRUE
;
56 ctx
->Array
.ArrayObj
->_Enabled
|= _NEW_ARRAY_ATTRIB(index
);
57 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
62 _mesa_DisableVertexAttribArrayARB(GLuint index
)
64 GET_CURRENT_CONTEXT(ctx
);
65 ASSERT_OUTSIDE_BEGIN_END(ctx
);
67 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
68 _mesa_error(ctx
, GL_INVALID_VALUE
,
69 "glEnableVertexAttribArrayARB(index)");
73 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
74 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_FALSE
;
75 ctx
->Array
.ArrayObj
->_Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
76 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
81 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
84 GET_CURRENT_CONTEXT(ctx
);
85 ASSERT_OUTSIDE_BEGIN_END(ctx
);
87 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
88 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
89 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
90 COPY_4V(params
, fparams
);
93 params
[0] = fparams
[0];
100 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
102 GET_CURRENT_CONTEXT(ctx
);
103 ASSERT_OUTSIDE_BEGIN_END(ctx
);
105 if (index
>= MAX_VERTEX_PROGRAM_ATTRIBS
) {
106 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribfvARB(index)");
111 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
112 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
;
114 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
115 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Size
;
117 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
118 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Stride
;
120 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
121 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Type
;
123 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
124 params
[0] = ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Normalized
;
126 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
128 _mesa_error(ctx
, GL_INVALID_OPERATION
,
129 "glGetVertexAttribfvARB(index==0)");
132 FLUSH_CURRENT(ctx
, 0);
133 COPY_4V(params
, ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
]);
135 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
136 if (!ctx
->Extensions
.ARB_vertex_buffer_object
) {
137 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
140 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].BufferObj
->Name
;
143 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
150 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
153 GET_CURRENT_CONTEXT(ctx
);
154 ASSERT_OUTSIDE_BEGIN_END(ctx
);
156 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
157 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
158 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
159 COPY_4V_CAST(params
, fparams
, GLint
); /* float to int */
162 params
[0] = (GLint
) fparams
[0];
169 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
171 GET_CURRENT_CONTEXT(ctx
);
172 ASSERT_OUTSIDE_BEGIN_END(ctx
);
174 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
175 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
179 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
180 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
184 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Ptr
;
189 * Determine if id names a vertex or fragment program.
190 * \note Not compiled into display lists.
191 * \note Called from both glIsProgramNV and glIsProgramARB.
192 * \param id is the program identifier
193 * \return GL_TRUE if id is a program, else GL_FALSE.
196 _mesa_IsProgramARB(GLuint id
)
198 struct gl_program
*prog
= NULL
;
199 GET_CURRENT_CONTEXT(ctx
);
200 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
205 prog
= _mesa_lookup_program(ctx
, id
);
206 if (prog
&& (prog
!= &_mesa_DummyProgram
))
214 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
215 const GLvoid
*string
)
217 GET_CURRENT_CONTEXT(ctx
);
218 ASSERT_OUTSIDE_BEGIN_END(ctx
);
220 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
222 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
223 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
227 if (target
== GL_VERTEX_PROGRAM_ARB
228 && ctx
->Extensions
.ARB_vertex_program
) {
229 struct gl_vertex_program
*prog
= ctx
->VertexProgram
.Current
;
230 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
232 if (ctx
->Program
.ErrorPos
== -1 && ctx
->Driver
.ProgramStringNotify
)
233 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
235 else if (target
== GL_FRAGMENT_PROGRAM_ARB
236 && ctx
->Extensions
.ARB_fragment_program
) {
237 struct gl_fragment_program
*prog
= ctx
->FragmentProgram
.Current
;
238 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
240 if (ctx
->Program
.ErrorPos
== -1 && ctx
->Driver
.ProgramStringNotify
)
241 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
244 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
251 * Set a program env parameter register.
252 * \note Called from the GL API dispatcher.
253 * Note, this function is also used by the GL_NV_vertex_program extension
254 * (alias to ProgramParameterdNV)
257 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
258 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
260 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
261 (GLfloat
) z
, (GLfloat
) w
);
266 * Set a program env parameter register.
267 * \note Called from the GL API dispatcher.
268 * Note, this function is also used by the GL_NV_vertex_program extension
269 * (alias to ProgramParameterdvNV)
272 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
273 const GLdouble
*params
)
275 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
276 (GLfloat
) params
[1], (GLfloat
) params
[2],
277 (GLfloat
) params
[3]);
282 * Set a program env parameter register.
283 * \note Called from the GL API dispatcher.
284 * Note, this function is also used by the GL_NV_vertex_program extension
285 * (alias to ProgramParameterfNV)
288 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
289 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
291 GET_CURRENT_CONTEXT(ctx
);
292 ASSERT_OUTSIDE_BEGIN_END(ctx
);
294 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
296 if (target
== GL_FRAGMENT_PROGRAM_ARB
297 && ctx
->Extensions
.ARB_fragment_program
) {
298 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
299 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
302 ASSIGN_4V(ctx
->FragmentProgram
.Parameters
[index
], x
, y
, z
, w
);
304 else if (target
== GL_VERTEX_PROGRAM_ARB
/* == GL_VERTEX_PROGRAM_NV */
305 && (ctx
->Extensions
.ARB_vertex_program
|| ctx
->Extensions
.NV_vertex_program
)) {
306 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
307 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
310 ASSIGN_4V(ctx
->VertexProgram
.Parameters
[index
], x
, y
, z
, w
);
313 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
319 * Set a program env parameter register.
320 * \note Called from the GL API dispatcher.
321 * Note, this function is also used by the GL_NV_vertex_program extension
322 * (alias to ProgramParameterfvNV)
325 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
326 const GLfloat
*params
)
328 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
329 params
[2], params
[3]);
334 _mesa_ProgramEnvParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
335 const GLfloat
*params
)
337 GET_CURRENT_CONTEXT(ctx
);
340 ASSERT_OUTSIDE_BEGIN_END(ctx
);
342 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
345 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(count)");
348 if (target
== GL_FRAGMENT_PROGRAM_ARB
349 && ctx
->Extensions
.ARB_fragment_program
) {
350 if ((index
+ count
) > ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
351 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
354 dest
= ctx
->FragmentProgram
.Parameters
[index
];
356 else if (target
== GL_VERTEX_PROGRAM_ARB
357 && ctx
->Extensions
.ARB_vertex_program
) {
358 if ((index
+ count
) > ctx
->Const
.VertexProgram
.MaxEnvParams
) {
359 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
362 dest
= ctx
->VertexProgram
.Parameters
[index
];
365 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameters4fv(target)");
369 for ( i
= 0 ; i
< count
; i
++ ) {
370 COPY_4V(dest
, params
);
378 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
381 GET_CURRENT_CONTEXT(ctx
);
384 _mesa_GetProgramEnvParameterfvARB(target
, index
, fparams
);
385 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
386 params
[0] = fparams
[0];
387 params
[1] = fparams
[1];
388 params
[2] = fparams
[2];
389 params
[3] = fparams
[3];
395 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
398 GET_CURRENT_CONTEXT(ctx
);
400 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
402 if (!ctx
->_CurrentProgram
)
403 ASSERT_OUTSIDE_BEGIN_END(ctx
);
405 if (target
== GL_FRAGMENT_PROGRAM_ARB
406 && ctx
->Extensions
.ARB_fragment_program
) {
407 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
408 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
411 COPY_4V(params
, ctx
->FragmentProgram
.Parameters
[index
]);
413 else if (target
== GL_VERTEX_PROGRAM_ARB
414 && ctx
->Extensions
.ARB_vertex_program
) {
415 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
416 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
419 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
422 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
429 * Note, this function is also used by the GL_NV_fragment_program extension.
432 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
433 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
435 GET_CURRENT_CONTEXT(ctx
);
436 struct gl_program
*prog
;
437 ASSERT_OUTSIDE_BEGIN_END(ctx
);
439 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
441 if ((target
== GL_FRAGMENT_PROGRAM_NV
442 && ctx
->Extensions
.NV_fragment_program
) ||
443 (target
== GL_FRAGMENT_PROGRAM_ARB
444 && ctx
->Extensions
.ARB_fragment_program
)) {
445 if (index
>= ctx
->Const
.FragmentProgram
.MaxLocalParams
) {
446 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
449 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
451 else if (target
== GL_VERTEX_PROGRAM_ARB
452 && ctx
->Extensions
.ARB_vertex_program
) {
453 if (index
>= ctx
->Const
.VertexProgram
.MaxLocalParams
) {
454 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
457 prog
= &(ctx
->VertexProgram
.Current
->Base
);
460 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
464 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
465 prog
->LocalParams
[index
][0] = x
;
466 prog
->LocalParams
[index
][1] = y
;
467 prog
->LocalParams
[index
][2] = z
;
468 prog
->LocalParams
[index
][3] = w
;
473 * Note, this function is also used by the GL_NV_fragment_program extension.
476 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
477 const GLfloat
*params
)
479 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
480 params
[2], params
[3]);
485 _mesa_ProgramLocalParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
486 const GLfloat
*params
)
488 GET_CURRENT_CONTEXT(ctx
);
489 struct gl_program
*prog
;
491 ASSERT_OUTSIDE_BEGIN_END(ctx
);
493 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
496 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fv(count)");
499 if (target
== GL_FRAGMENT_PROGRAM_ARB
500 && ctx
->Extensions
.ARB_fragment_program
) {
501 if ((index
+ count
) > ctx
->Const
.FragmentProgram
.MaxLocalParams
) {
502 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fvEXT(index + count)");
505 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
507 else if (target
== GL_VERTEX_PROGRAM_ARB
508 && ctx
->Extensions
.ARB_vertex_program
) {
509 if ((index
+ count
) > ctx
->Const
.VertexProgram
.MaxLocalParams
) {
510 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fvEXT(index + count)");
513 prog
= &(ctx
->VertexProgram
.Current
->Base
);
516 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameters4fvEXT(target)");
520 for (i
= 0; i
< count
; i
++) {
521 ASSERT((index
+ i
) < MAX_PROGRAM_LOCAL_PARAMS
);
522 COPY_4V(prog
->LocalParams
[index
+ i
], params
);
529 * Note, this function is also used by the GL_NV_fragment_program extension.
532 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
533 GLdouble x
, GLdouble y
,
534 GLdouble z
, GLdouble w
)
536 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
537 (GLfloat
) z
, (GLfloat
) w
);
542 * Note, this function is also used by the GL_NV_fragment_program extension.
545 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
546 const GLdouble
*params
)
548 _mesa_ProgramLocalParameter4fARB(target
, index
,
549 (GLfloat
) params
[0], (GLfloat
) params
[1],
550 (GLfloat
) params
[2], (GLfloat
) params
[3]);
555 * Note, this function is also used by the GL_NV_fragment_program extension.
558 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
561 const struct gl_program
*prog
;
563 GET_CURRENT_CONTEXT(ctx
);
564 ASSERT_OUTSIDE_BEGIN_END(ctx
);
566 if (target
== GL_VERTEX_PROGRAM_ARB
567 && ctx
->Extensions
.ARB_vertex_program
) {
568 prog
= &(ctx
->VertexProgram
.Current
->Base
);
569 maxParams
= ctx
->Const
.VertexProgram
.MaxLocalParams
;
571 else if (target
== GL_FRAGMENT_PROGRAM_ARB
572 && ctx
->Extensions
.ARB_fragment_program
) {
573 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
574 maxParams
= ctx
->Const
.FragmentProgram
.MaxLocalParams
;
576 else if (target
== GL_FRAGMENT_PROGRAM_NV
577 && ctx
->Extensions
.NV_fragment_program
) {
578 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
579 maxParams
= MAX_NV_FRAGMENT_PROGRAM_PARAMS
;
582 _mesa_error(ctx
, GL_INVALID_ENUM
,
583 "glGetProgramLocalParameterARB(target)");
587 if (index
>= maxParams
) {
588 _mesa_error(ctx
, GL_INVALID_VALUE
,
589 "glGetProgramLocalParameterARB(index)");
594 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
595 COPY_4V(params
, prog
->LocalParams
[index
]);
600 * Note, this function is also used by the GL_NV_fragment_program extension.
603 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
606 GET_CURRENT_CONTEXT(ctx
);
607 GLfloat floatParams
[4];
608 _mesa_GetProgramLocalParameterfvARB(target
, index
, floatParams
);
609 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
610 COPY_4V(params
, floatParams
);
616 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
618 const struct gl_program_constants
*limits
;
619 struct gl_program
*prog
;
620 GET_CURRENT_CONTEXT(ctx
);
622 if (!ctx
->_CurrentProgram
)
623 ASSERT_OUTSIDE_BEGIN_END(ctx
);
625 if (target
== GL_VERTEX_PROGRAM_ARB
626 && ctx
->Extensions
.ARB_vertex_program
) {
627 prog
= &(ctx
->VertexProgram
.Current
->Base
);
628 limits
= &ctx
->Const
.VertexProgram
;
630 else if (target
== GL_FRAGMENT_PROGRAM_ARB
631 && ctx
->Extensions
.ARB_fragment_program
) {
632 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
633 limits
= &ctx
->Const
.FragmentProgram
;
636 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
643 /* Queries supported for both vertex and fragment programs */
645 case GL_PROGRAM_LENGTH_ARB
:
647 = prog
->String
? (GLint
) _mesa_strlen((char *) prog
->String
) : 0;
649 case GL_PROGRAM_FORMAT_ARB
:
650 *params
= prog
->Format
;
652 case GL_PROGRAM_BINDING_ARB
:
655 case GL_PROGRAM_INSTRUCTIONS_ARB
:
656 *params
= prog
->NumInstructions
;
658 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
659 *params
= limits
->MaxInstructions
;
661 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
662 *params
= prog
->NumNativeInstructions
;
664 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
665 *params
= limits
->MaxNativeInstructions
;
667 case GL_PROGRAM_TEMPORARIES_ARB
:
668 *params
= prog
->NumTemporaries
;
670 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
671 *params
= limits
->MaxTemps
;
673 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
674 *params
= prog
->NumNativeTemporaries
;
676 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
677 *params
= limits
->MaxNativeTemps
;
679 case GL_PROGRAM_PARAMETERS_ARB
:
680 *params
= prog
->NumParameters
;
682 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
683 *params
= limits
->MaxParameters
;
685 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
686 *params
= prog
->NumNativeParameters
;
688 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
689 *params
= limits
->MaxNativeParameters
;
691 case GL_PROGRAM_ATTRIBS_ARB
:
692 *params
= prog
->NumAttributes
;
694 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
695 *params
= limits
->MaxAttribs
;
697 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
698 *params
= prog
->NumNativeAttributes
;
700 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
701 *params
= limits
->MaxNativeAttribs
;
703 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
704 *params
= prog
->NumAddressRegs
;
706 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
707 *params
= limits
->MaxAddressRegs
;
709 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
710 *params
= prog
->NumNativeAddressRegs
;
712 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
713 *params
= limits
->MaxNativeAddressRegs
;
715 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
716 *params
= limits
->MaxLocalParams
;
718 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
719 *params
= limits
->MaxEnvParams
;
721 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
723 * XXX we may not really need a driver callback here.
724 * If the number of native instructions, registers, etc. used
725 * are all below the maximums, we could return true.
726 * The spec says that even if this query returns true, there's
727 * no guarantee that the program will run in hardware.
730 /* default/null program */
733 else if (ctx
->Driver
.IsProgramNative
) {
735 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
738 /* probably running in software */
743 /* continue with fragment-program only queries below */
748 * The following apply to fragment programs only (at this time)
750 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
751 const struct gl_fragment_program
*fp
= ctx
->FragmentProgram
.Current
;
753 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
754 *params
= fp
->Base
.NumNativeAluInstructions
;
756 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
757 *params
= fp
->Base
.NumAluInstructions
;
759 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
760 *params
= fp
->Base
.NumTexInstructions
;
762 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
763 *params
= fp
->Base
.NumNativeTexInstructions
;
765 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
766 *params
= fp
->Base
.NumTexIndirections
;
768 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
769 *params
= fp
->Base
.NumNativeTexIndirections
;
771 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
772 *params
= limits
->MaxAluInstructions
;
774 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
775 *params
= limits
->MaxNativeAluInstructions
;
777 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
778 *params
= limits
->MaxTexInstructions
;
780 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
781 *params
= limits
->MaxNativeTexInstructions
;
783 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
784 *params
= limits
->MaxTexIndirections
;
786 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
787 *params
= limits
->MaxNativeTexIndirections
;
790 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
798 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
800 const struct gl_program
*prog
;
801 char *dst
= (char *) string
;
802 GET_CURRENT_CONTEXT(ctx
);
804 if (!ctx
->_CurrentProgram
)
805 ASSERT_OUTSIDE_BEGIN_END(ctx
);
807 if (target
== GL_VERTEX_PROGRAM_ARB
) {
808 prog
= &(ctx
->VertexProgram
.Current
->Base
);
810 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
811 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
814 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
820 if (pname
!= GL_PROGRAM_STRING_ARB
) {
821 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
826 _mesa_memcpy(dst
, prog
->String
, _mesa_strlen((char *) prog
->String
));