2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2006 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"
42 _mesa_EnableVertexAttribArrayARB(GLuint index
)
44 GET_CURRENT_CONTEXT(ctx
);
45 ASSERT_OUTSIDE_BEGIN_END(ctx
);
47 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
48 _mesa_error(ctx
, GL_INVALID_VALUE
,
49 "glEnableVertexAttribArrayARB(index)");
53 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
54 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_TRUE
;
55 ctx
->Array
.ArrayObj
->_Enabled
|= _NEW_ARRAY_ATTRIB(index
);
56 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
61 _mesa_DisableVertexAttribArrayARB(GLuint index
)
63 GET_CURRENT_CONTEXT(ctx
);
64 ASSERT_OUTSIDE_BEGIN_END(ctx
);
66 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
67 _mesa_error(ctx
, GL_INVALID_VALUE
,
68 "glEnableVertexAttribArrayARB(index)");
72 FLUSH_VERTICES(ctx
, _NEW_ARRAY
);
73 ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
= GL_FALSE
;
74 ctx
->Array
.ArrayObj
->_Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
75 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
80 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
83 GET_CURRENT_CONTEXT(ctx
);
84 ASSERT_OUTSIDE_BEGIN_END(ctx
);
86 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
87 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
88 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
89 COPY_4V(params
, fparams
);
92 params
[0] = fparams
[0];
99 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
101 GET_CURRENT_CONTEXT(ctx
);
102 ASSERT_OUTSIDE_BEGIN_END(ctx
);
104 if (index
== 0 || index
>= MAX_VERTEX_PROGRAM_ATTRIBS
) {
105 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribfvARB(index)");
110 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
111 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Enabled
;
113 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
114 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Size
;
116 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
117 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Stride
;
119 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
120 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Type
;
122 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
123 params
[0] = ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Normalized
;
125 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
126 FLUSH_CURRENT(ctx
, 0);
127 COPY_4V(params
, ctx
->Current
.Attrib
[VERT_ATTRIB_GENERIC0
+ index
]);
129 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
130 if (!ctx
->Extensions
.ARB_vertex_buffer_object
) {
131 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
134 params
[0] = (GLfloat
) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].BufferObj
->Name
;
137 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
144 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
147 GET_CURRENT_CONTEXT(ctx
);
148 ASSERT_OUTSIDE_BEGIN_END(ctx
);
150 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
151 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
152 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
153 COPY_4V_CAST(params
, fparams
, GLint
); /* float to int */
156 params
[0] = (GLint
) fparams
[0];
163 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
165 GET_CURRENT_CONTEXT(ctx
);
166 ASSERT_OUTSIDE_BEGIN_END(ctx
);
168 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
169 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
173 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
174 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
178 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Ptr
;
183 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
184 const GLvoid
*string
)
186 GET_CURRENT_CONTEXT(ctx
);
187 ASSERT_OUTSIDE_BEGIN_END(ctx
);
189 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
191 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
192 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
196 if (target
== GL_VERTEX_PROGRAM_ARB
197 && ctx
->Extensions
.ARB_vertex_program
) {
198 struct gl_vertex_program
*prog
= ctx
->VertexProgram
.Current
;
199 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
201 if (ctx
->Driver
.ProgramStringNotify
)
202 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
204 else if (target
== GL_FRAGMENT_PROGRAM_ARB
205 && ctx
->Extensions
.ARB_fragment_program
) {
206 struct gl_fragment_program
*prog
= ctx
->FragmentProgram
.Current
;
207 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
209 if (ctx
->Driver
.ProgramStringNotify
)
210 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
213 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
220 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
221 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
223 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
224 (GLfloat
) z
, (GLfloat
) w
);
229 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
230 const GLdouble
*params
)
232 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
233 (GLfloat
) params
[1], (GLfloat
) params
[2],
234 (GLfloat
) params
[3]);
239 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
240 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
242 GET_CURRENT_CONTEXT(ctx
);
243 ASSERT_OUTSIDE_BEGIN_END(ctx
);
245 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
247 if (target
== GL_FRAGMENT_PROGRAM_ARB
248 && ctx
->Extensions
.ARB_fragment_program
) {
249 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
250 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
253 ASSIGN_4V(ctx
->FragmentProgram
.Parameters
[index
], x
, y
, z
, w
);
255 else if (target
== GL_VERTEX_PROGRAM_ARB
256 && ctx
->Extensions
.ARB_vertex_program
) {
257 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
258 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
261 ASSIGN_4V(ctx
->VertexProgram
.Parameters
[index
], x
, y
, z
, w
);
264 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
271 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
272 const GLfloat
*params
)
274 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
275 params
[2], params
[3]);
280 _mesa_ProgramEnvParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
281 const GLfloat
*params
)
283 GET_CURRENT_CONTEXT(ctx
);
286 ASSERT_OUTSIDE_BEGIN_END(ctx
);
288 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
291 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(count)");
294 if (target
== GL_FRAGMENT_PROGRAM_ARB
295 && ctx
->Extensions
.ARB_fragment_program
) {
296 if ((index
+ count
) > ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
297 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
300 dest
= ctx
->FragmentProgram
.Parameters
[index
];
302 else if (target
== GL_VERTEX_PROGRAM_ARB
303 && ctx
->Extensions
.ARB_vertex_program
) {
304 if ((index
+ count
) > ctx
->Const
.VertexProgram
.MaxEnvParams
) {
305 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
308 dest
= ctx
->VertexProgram
.Parameters
[index
];
311 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameters4fv(target)");
315 for ( i
= 0 ; i
< count
; i
++ ) {
316 COPY_4V(dest
, params
);
324 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
327 GET_CURRENT_CONTEXT(ctx
);
330 _mesa_GetProgramEnvParameterfvARB(target
, index
, fparams
);
331 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
332 params
[0] = fparams
[0];
333 params
[1] = fparams
[1];
334 params
[2] = fparams
[2];
335 params
[3] = fparams
[3];
341 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
344 GET_CURRENT_CONTEXT(ctx
);
346 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
348 if (!ctx
->_CurrentProgram
)
349 ASSERT_OUTSIDE_BEGIN_END(ctx
);
351 if (target
== GL_FRAGMENT_PROGRAM_ARB
352 && ctx
->Extensions
.ARB_fragment_program
) {
353 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
354 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
357 COPY_4V(params
, ctx
->FragmentProgram
.Parameters
[index
]);
359 else if (target
== GL_VERTEX_PROGRAM_ARB
360 && ctx
->Extensions
.ARB_vertex_program
) {
361 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
362 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
365 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
368 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
375 * Note, this function is also used by the GL_NV_fragment_program extension.
378 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
379 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
381 GET_CURRENT_CONTEXT(ctx
);
382 struct gl_program
*prog
;
383 ASSERT_OUTSIDE_BEGIN_END(ctx
);
385 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
387 if ((target
== GL_FRAGMENT_PROGRAM_NV
388 && ctx
->Extensions
.NV_fragment_program
) ||
389 (target
== GL_FRAGMENT_PROGRAM_ARB
390 && ctx
->Extensions
.ARB_fragment_program
)) {
391 if (index
>= ctx
->Const
.FragmentProgram
.MaxLocalParams
) {
392 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
395 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
397 else if (target
== GL_VERTEX_PROGRAM_ARB
398 && ctx
->Extensions
.ARB_vertex_program
) {
399 if (index
>= ctx
->Const
.VertexProgram
.MaxLocalParams
) {
400 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
403 prog
= &(ctx
->VertexProgram
.Current
->Base
);
406 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
410 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
411 prog
->LocalParams
[index
][0] = x
;
412 prog
->LocalParams
[index
][1] = y
;
413 prog
->LocalParams
[index
][2] = z
;
414 prog
->LocalParams
[index
][3] = w
;
419 * Note, this function is also used by the GL_NV_fragment_program extension.
422 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
423 const GLfloat
*params
)
425 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
426 params
[2], params
[3]);
431 _mesa_ProgramLocalParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
432 const GLfloat
*params
)
434 GET_CURRENT_CONTEXT(ctx
);
435 struct gl_program
*prog
;
437 ASSERT_OUTSIDE_BEGIN_END(ctx
);
439 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
442 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fv(count)");
445 if (target
== GL_FRAGMENT_PROGRAM_ARB
446 && ctx
->Extensions
.ARB_fragment_program
) {
447 if ((index
+ count
) > ctx
->Const
.FragmentProgram
.MaxLocalParams
) {
448 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fvEXT(index + count)");
451 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
453 else if (target
== GL_VERTEX_PROGRAM_ARB
454 && ctx
->Extensions
.ARB_vertex_program
) {
455 if ((index
+ count
) > ctx
->Const
.VertexProgram
.MaxLocalParams
) {
456 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameters4fvEXT(index + count)");
459 prog
= &(ctx
->VertexProgram
.Current
->Base
);
462 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameters4fvEXT(target)");
466 for (i
= 0; i
< count
; i
++) {
467 ASSERT((index
+ i
) < MAX_PROGRAM_LOCAL_PARAMS
);
468 COPY_4V(prog
->LocalParams
[index
+ i
], params
);
475 * Note, this function is also used by the GL_NV_fragment_program extension.
478 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
479 GLdouble x
, GLdouble y
,
480 GLdouble z
, GLdouble w
)
482 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
483 (GLfloat
) z
, (GLfloat
) w
);
488 * Note, this function is also used by the GL_NV_fragment_program extension.
491 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
492 const GLdouble
*params
)
494 _mesa_ProgramLocalParameter4fARB(target
, index
,
495 (GLfloat
) params
[0], (GLfloat
) params
[1],
496 (GLfloat
) params
[2], (GLfloat
) params
[3]);
501 * Note, this function is also used by the GL_NV_fragment_program extension.
504 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
507 const struct gl_program
*prog
;
509 GET_CURRENT_CONTEXT(ctx
);
510 ASSERT_OUTSIDE_BEGIN_END(ctx
);
512 if (target
== GL_VERTEX_PROGRAM_ARB
513 && ctx
->Extensions
.ARB_vertex_program
) {
514 prog
= &(ctx
->VertexProgram
.Current
->Base
);
515 maxParams
= ctx
->Const
.VertexProgram
.MaxLocalParams
;
517 else if (target
== GL_FRAGMENT_PROGRAM_ARB
518 && ctx
->Extensions
.ARB_fragment_program
) {
519 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
520 maxParams
= ctx
->Const
.FragmentProgram
.MaxLocalParams
;
522 else if (target
== GL_FRAGMENT_PROGRAM_NV
523 && ctx
->Extensions
.NV_fragment_program
) {
524 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
525 maxParams
= MAX_NV_FRAGMENT_PROGRAM_PARAMS
;
528 _mesa_error(ctx
, GL_INVALID_ENUM
,
529 "glGetProgramLocalParameterARB(target)");
533 if (index
>= maxParams
) {
534 _mesa_error(ctx
, GL_INVALID_VALUE
,
535 "glGetProgramLocalParameterARB(index)");
540 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
541 COPY_4V(params
, prog
->LocalParams
[index
]);
546 * Note, this function is also used by the GL_NV_fragment_program extension.
549 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
552 GET_CURRENT_CONTEXT(ctx
);
553 GLfloat floatParams
[4];
554 _mesa_GetProgramLocalParameterfvARB(target
, index
, floatParams
);
555 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
556 COPY_4V(params
, floatParams
);
562 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
564 const struct gl_program_constants
*limits
;
565 struct gl_program
*prog
;
566 GET_CURRENT_CONTEXT(ctx
);
568 if (!ctx
->_CurrentProgram
)
569 ASSERT_OUTSIDE_BEGIN_END(ctx
);
571 if (target
== GL_VERTEX_PROGRAM_ARB
572 && ctx
->Extensions
.ARB_vertex_program
) {
573 prog
= &(ctx
->VertexProgram
.Current
->Base
);
574 limits
= &ctx
->Const
.VertexProgram
;
576 else if (target
== GL_FRAGMENT_PROGRAM_ARB
577 && ctx
->Extensions
.ARB_fragment_program
) {
578 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
579 limits
= &ctx
->Const
.FragmentProgram
;
582 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
589 /* Queries supported for both vertex and fragment programs */
591 case GL_PROGRAM_LENGTH_ARB
:
593 = prog
->String
? (GLint
) _mesa_strlen((char *) prog
->String
) : 0;
595 case GL_PROGRAM_FORMAT_ARB
:
596 *params
= prog
->Format
;
598 case GL_PROGRAM_BINDING_ARB
:
601 case GL_PROGRAM_INSTRUCTIONS_ARB
:
602 *params
= prog
->NumInstructions
;
604 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
605 *params
= limits
->MaxInstructions
;
607 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
608 *params
= prog
->NumNativeInstructions
;
610 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
611 *params
= limits
->MaxNativeInstructions
;
613 case GL_PROGRAM_TEMPORARIES_ARB
:
614 *params
= prog
->NumTemporaries
;
616 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
617 *params
= limits
->MaxTemps
;
619 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
620 *params
= prog
->NumNativeTemporaries
;
622 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
623 *params
= limits
->MaxNativeTemps
;
625 case GL_PROGRAM_PARAMETERS_ARB
:
626 *params
= prog
->NumParameters
;
628 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
629 *params
= limits
->MaxParameters
;
631 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
632 *params
= prog
->NumNativeParameters
;
634 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
635 *params
= limits
->MaxNativeParameters
;
637 case GL_PROGRAM_ATTRIBS_ARB
:
638 *params
= prog
->NumAttributes
;
640 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
641 *params
= limits
->MaxAttribs
;
643 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
644 *params
= prog
->NumNativeAttributes
;
646 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
647 *params
= limits
->MaxNativeAttribs
;
649 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
650 *params
= prog
->NumAddressRegs
;
652 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
653 *params
= limits
->MaxAddressRegs
;
655 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
656 *params
= prog
->NumNativeAddressRegs
;
658 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
659 *params
= limits
->MaxNativeAddressRegs
;
661 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
662 *params
= limits
->MaxLocalParams
;
664 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
665 *params
= limits
->MaxEnvParams
;
667 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
669 * XXX we may not really need a driver callback here.
670 * If the number of native instructions, registers, etc. used
671 * are all below the maximums, we could return true.
672 * The spec says that even if this query returns true, there's
673 * no guarantee that the program will run in hardware.
675 if (ctx
->Driver
.IsProgramNative
)
676 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
681 /* continue with fragment-program only queries below */
686 * The following apply to fragment programs only (at this time)
688 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
689 const struct gl_fragment_program
*fp
= ctx
->FragmentProgram
.Current
;
691 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
692 *params
= fp
->NumNativeAluInstructions
;
694 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
695 *params
= fp
->NumAluInstructions
;
697 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
698 *params
= fp
->NumTexInstructions
;
700 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
701 *params
= fp
->NumNativeTexInstructions
;
703 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
704 *params
= fp
->NumTexIndirections
;
706 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
707 *params
= fp
->NumNativeTexIndirections
;
709 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
710 *params
= limits
->MaxAluInstructions
;
712 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
713 *params
= limits
->MaxNativeAluInstructions
;
715 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
716 *params
= limits
->MaxTexInstructions
;
718 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
719 *params
= limits
->MaxNativeTexInstructions
;
721 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
722 *params
= limits
->MaxTexIndirections
;
724 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
725 *params
= limits
->MaxNativeTexIndirections
;
728 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
736 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
738 const struct gl_program
*prog
;
739 GET_CURRENT_CONTEXT(ctx
);
741 if (!ctx
->_CurrentProgram
)
742 ASSERT_OUTSIDE_BEGIN_END(ctx
);
744 if (target
== GL_VERTEX_PROGRAM_ARB
) {
745 prog
= &(ctx
->VertexProgram
.Current
->Base
);
747 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
748 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
751 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
757 if (pname
!= GL_PROGRAM_STRING_ARB
) {
758 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
762 _mesa_memcpy(string
, prog
->String
, _mesa_strlen((char *) prog
->String
));