2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2005 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
.VertexAttrib
[index
].Enabled
= GL_TRUE
;
55 ctx
->Array
._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
.VertexAttrib
[index
].Enabled
= GL_FALSE
;
74 ctx
->Array
._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
.VertexAttrib
[index
].Enabled
;
113 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
114 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Size
;
116 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
117 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Stride
;
119 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
120 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].Type
;
122 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
123 params
[0] = ctx
->Array
.VertexAttrib
[index
].Normalized
;
125 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
126 FLUSH_CURRENT(ctx
, 0);
128 COPY_4V(params, ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index]);
130 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
132 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
133 if (!ctx
->Extensions
.ARB_vertex_buffer_object
) {
134 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
137 params
[0] = (GLfloat
) ctx
->Array
.VertexAttrib
[index
].BufferObj
->Name
;
139 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
146 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
149 GET_CURRENT_CONTEXT(ctx
);
150 ASSERT_OUTSIDE_BEGIN_END(ctx
);
152 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
153 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
154 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
155 COPY_4V_CAST(params
, fparams
, GLint
); /* float to int */
158 params
[0] = (GLint
) fparams
[0];
165 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
167 GET_CURRENT_CONTEXT(ctx
);
168 ASSERT_OUTSIDE_BEGIN_END(ctx
);
170 if (index
>= ctx
->Const
.VertexProgram
.MaxAttribs
) {
171 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
175 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
176 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
180 *pointer
= (GLvoid
*) ctx
->Array
.VertexAttrib
[index
].Ptr
;;
185 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
186 const GLvoid
*string
)
188 GET_CURRENT_CONTEXT(ctx
);
189 ASSERT_OUTSIDE_BEGIN_END(ctx
);
191 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
193 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
194 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
198 if (target
== GL_VERTEX_PROGRAM_ARB
199 && ctx
->Extensions
.ARB_vertex_program
) {
200 struct vertex_program
*prog
= ctx
->VertexProgram
.Current
;
201 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
203 if (ctx
->Driver
.ProgramStringNotify
)
204 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
206 else if (target
== GL_FRAGMENT_PROGRAM_ARB
207 && ctx
->Extensions
.ARB_fragment_program
) {
208 struct fragment_program
*prog
= ctx
->FragmentProgram
.Current
;
209 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
211 if (ctx
->Driver
.ProgramStringNotify
)
212 ctx
->Driver
.ProgramStringNotify( ctx
, target
, &prog
->Base
);
215 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
222 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
223 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
225 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
226 (GLfloat
) z
, (GLfloat
) w
);
231 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
232 const GLdouble
*params
)
234 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
235 (GLfloat
) params
[1], (GLfloat
) params
[2],
236 (GLfloat
) params
[3]);
241 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
242 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
244 GET_CURRENT_CONTEXT(ctx
);
245 ASSERT_OUTSIDE_BEGIN_END(ctx
);
247 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
249 if (target
== GL_FRAGMENT_PROGRAM_ARB
250 && ctx
->Extensions
.ARB_fragment_program
) {
251 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
252 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
255 ASSIGN_4V(ctx
->FragmentProgram
.Parameters
[index
], x
, y
, z
, w
);
257 else if (target
== GL_VERTEX_PROGRAM_ARB
258 && ctx
->Extensions
.ARB_vertex_program
) {
259 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
260 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
263 ASSIGN_4V(ctx
->VertexProgram
.Parameters
[index
], x
, y
, z
, w
);
266 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
273 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
274 const GLfloat
*params
)
276 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
277 params
[2], params
[3]);
282 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
285 GET_CURRENT_CONTEXT(ctx
);
288 _mesa_GetProgramEnvParameterfvARB(target
, index
, fparams
);
289 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
290 params
[0] = fparams
[0];
291 params
[1] = fparams
[1];
292 params
[2] = fparams
[2];
293 params
[3] = fparams
[3];
299 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
302 GET_CURRENT_CONTEXT(ctx
);
304 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
306 if (!ctx
->_CurrentProgram
)
307 ASSERT_OUTSIDE_BEGIN_END(ctx
);
309 if (target
== GL_FRAGMENT_PROGRAM_ARB
310 && ctx
->Extensions
.ARB_fragment_program
) {
311 if (index
>= ctx
->Const
.FragmentProgram
.MaxEnvParams
) {
312 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
315 COPY_4V(params
, ctx
->FragmentProgram
.Parameters
[index
]);
317 else if (target
== GL_VERTEX_PROGRAM_ARB
318 && ctx
->Extensions
.ARB_vertex_program
) {
319 if (index
>= ctx
->Const
.VertexProgram
.MaxEnvParams
) {
320 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
323 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
326 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
333 * Note, this function is also used by the GL_NV_fragment_program extension.
336 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
337 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
339 GET_CURRENT_CONTEXT(ctx
);
340 struct program
*prog
;
341 ASSERT_OUTSIDE_BEGIN_END(ctx
);
343 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
345 if ((target
== GL_FRAGMENT_PROGRAM_NV
346 && ctx
->Extensions
.NV_fragment_program
) ||
347 (target
== GL_FRAGMENT_PROGRAM_ARB
348 && ctx
->Extensions
.ARB_fragment_program
)) {
349 if (index
>= ctx
->Const
.FragmentProgram
.MaxLocalParams
) {
350 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
353 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
355 else if (target
== GL_VERTEX_PROGRAM_ARB
356 && ctx
->Extensions
.ARB_vertex_program
) {
357 if (index
>= ctx
->Const
.VertexProgram
.MaxLocalParams
) {
358 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
361 prog
= &(ctx
->VertexProgram
.Current
->Base
);
364 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
368 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
369 prog
->LocalParams
[index
][0] = x
;
370 prog
->LocalParams
[index
][1] = y
;
371 prog
->LocalParams
[index
][2] = z
;
372 prog
->LocalParams
[index
][3] = w
;
377 * Note, this function is also used by the GL_NV_fragment_program extension.
380 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
381 const GLfloat
*params
)
383 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
384 params
[2], params
[3]);
389 * Note, this function is also used by the GL_NV_fragment_program extension.
392 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
393 GLdouble x
, GLdouble y
,
394 GLdouble z
, GLdouble w
)
396 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
397 (GLfloat
) z
, (GLfloat
) w
);
402 * Note, this function is also used by the GL_NV_fragment_program extension.
405 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
406 const GLdouble
*params
)
408 _mesa_ProgramLocalParameter4fARB(target
, index
,
409 (GLfloat
) params
[0], (GLfloat
) params
[1],
410 (GLfloat
) params
[2], (GLfloat
) params
[3]);
415 * Note, this function is also used by the GL_NV_fragment_program extension.
418 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
421 const struct program
*prog
;
423 GET_CURRENT_CONTEXT(ctx
);
424 ASSERT_OUTSIDE_BEGIN_END(ctx
);
426 if (target
== GL_VERTEX_PROGRAM_ARB
427 && ctx
->Extensions
.ARB_vertex_program
) {
428 prog
= &(ctx
->VertexProgram
.Current
->Base
);
429 maxParams
= ctx
->Const
.VertexProgram
.MaxLocalParams
;
431 else if (target
== GL_FRAGMENT_PROGRAM_ARB
432 && ctx
->Extensions
.ARB_fragment_program
) {
433 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
434 maxParams
= ctx
->Const
.FragmentProgram
.MaxLocalParams
;
436 else if (target
== GL_FRAGMENT_PROGRAM_NV
437 && ctx
->Extensions
.NV_fragment_program
) {
438 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
439 maxParams
= MAX_NV_FRAGMENT_PROGRAM_PARAMS
;
442 _mesa_error(ctx
, GL_INVALID_ENUM
,
443 "glGetProgramLocalParameterARB(target)");
447 if (index
>= maxParams
) {
448 _mesa_error(ctx
, GL_INVALID_VALUE
,
449 "glGetProgramLocalParameterARB(index)");
454 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
455 COPY_4V(params
, prog
->LocalParams
[index
]);
460 * Note, this function is also used by the GL_NV_fragment_program extension.
463 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
466 GET_CURRENT_CONTEXT(ctx
);
467 GLfloat floatParams
[4];
468 _mesa_GetProgramLocalParameterfvARB(target
, index
, floatParams
);
469 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
470 COPY_4V(params
, floatParams
);
476 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
478 const struct gl_program_constants
*limits
;
479 struct program
*prog
;
480 GET_CURRENT_CONTEXT(ctx
);
482 if (!ctx
->_CurrentProgram
)
483 ASSERT_OUTSIDE_BEGIN_END(ctx
);
485 if (target
== GL_VERTEX_PROGRAM_ARB
486 && ctx
->Extensions
.ARB_vertex_program
) {
487 prog
= &(ctx
->VertexProgram
.Current
->Base
);
488 limits
= &ctx
->Const
.VertexProgram
;
490 else if (target
== GL_FRAGMENT_PROGRAM_ARB
491 && ctx
->Extensions
.ARB_fragment_program
) {
492 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
493 limits
= &ctx
->Const
.FragmentProgram
;
496 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
503 /* Queries supported for both vertex and fragment programs */
505 case GL_PROGRAM_LENGTH_ARB
:
507 = prog
->String
? (GLint
) _mesa_strlen((char *) prog
->String
) : 0;
509 case GL_PROGRAM_FORMAT_ARB
:
510 *params
= prog
->Format
;
512 case GL_PROGRAM_BINDING_ARB
:
515 case GL_PROGRAM_INSTRUCTIONS_ARB
:
516 *params
= prog
->NumInstructions
;
518 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
519 *params
= limits
->MaxInstructions
;
521 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
522 *params
= prog
->NumNativeInstructions
;
524 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
525 *params
= limits
->MaxNativeInstructions
;
527 case GL_PROGRAM_TEMPORARIES_ARB
:
528 *params
= prog
->NumTemporaries
;
530 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
531 *params
= limits
->MaxTemps
;
533 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
534 *params
= prog
->NumNativeTemporaries
;
536 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
537 *params
= limits
->MaxNativeTemps
;
539 case GL_PROGRAM_PARAMETERS_ARB
:
540 *params
= prog
->NumParameters
;
542 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
543 *params
= limits
->MaxParameters
;
545 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
546 *params
= prog
->NumNativeParameters
;
548 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
549 *params
= limits
->MaxNativeParameters
;
551 case GL_PROGRAM_ATTRIBS_ARB
:
552 *params
= prog
->NumAttributes
;
554 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
555 *params
= limits
->MaxAttribs
;
557 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
558 *params
= prog
->NumNativeAttributes
;
560 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
561 *params
= limits
->MaxNativeAttribs
;
563 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
564 *params
= prog
->NumAddressRegs
;
566 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
567 *params
= limits
->MaxAddressRegs
;
569 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
570 *params
= prog
->NumNativeAddressRegs
;
572 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
573 *params
= limits
->MaxNativeAddressRegs
;
575 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
576 *params
= limits
->MaxLocalParams
;
578 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
579 *params
= limits
->MaxEnvParams
;
581 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
583 * XXX we may not really need a driver callback here.
584 * If the number of native instructions, registers, etc. used
585 * are all below the maximums, we could return true.
586 * The spec says that even if this query returns true, there's
587 * no guarantee that the program will run in hardware.
589 if (ctx
->Driver
.IsProgramNative
)
590 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
595 /* continue with fragment-program only queries below */
600 * The following apply to fragment programs only (at this time)
602 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
603 const struct fragment_program
*fp
= ctx
->FragmentProgram
.Current
;
605 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
606 *params
= fp
->NumNativeAluInstructions
;
608 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
609 *params
= fp
->NumAluInstructions
;
611 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
612 *params
= fp
->NumTexInstructions
;
614 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
615 *params
= fp
->NumNativeTexInstructions
;
617 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
618 *params
= fp
->NumTexIndirections
;
620 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
621 *params
= fp
->NumNativeTexIndirections
;
623 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
624 *params
= limits
->MaxAluInstructions
;
626 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
627 *params
= limits
->MaxNativeAluInstructions
;
629 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
630 *params
= limits
->MaxTexInstructions
;
632 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
633 *params
= limits
->MaxNativeTexInstructions
;
635 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
636 *params
= limits
->MaxTexIndirections
;
638 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
639 *params
= limits
->MaxNativeTexIndirections
;
642 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
650 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
652 const struct program
*prog
;
653 GET_CURRENT_CONTEXT(ctx
);
655 if (!ctx
->_CurrentProgram
)
656 ASSERT_OUTSIDE_BEGIN_END(ctx
);
658 if (target
== GL_VERTEX_PROGRAM_ARB
) {
659 prog
= &(ctx
->VertexProgram
.Current
->Base
);
661 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
662 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
665 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
671 if (pname
!= GL_PROGRAM_STRING_ARB
) {
672 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
676 _mesa_memcpy(string
, prog
->String
, _mesa_strlen((char *) prog
->String
));