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 * Init context's program state
51 _mesa_init_program(GLcontext
*ctx
)
55 ctx
->Program
.ErrorPos
= -1;
56 ctx
->Program
.ErrorString
= _mesa_strdup("");
58 #if FEATURE_NV_vertex_program || FEATURE_ARB_vertex_program
59 ctx
->VertexProgram
.Enabled
= GL_FALSE
;
60 ctx
->VertexProgram
.PointSizeEnabled
= GL_FALSE
;
61 ctx
->VertexProgram
.TwoSideEnabled
= GL_FALSE
;
62 ctx
->VertexProgram
.Current
= NULL
;
63 ctx
->VertexProgram
.Current
= (struct vertex_program
*) ctx
->Shared
->DefaultVertexProgram
;
64 assert(ctx
->VertexProgram
.Current
);
65 ctx
->VertexProgram
.Current
->Base
.RefCount
++;
66 for (i
= 0; i
< VP_NUM_PROG_REGS
/ 4; i
++) {
67 ctx
->VertexProgram
.TrackMatrix
[i
] = GL_NONE
;
68 ctx
->VertexProgram
.TrackMatrixTransform
[i
] = GL_IDENTITY_NV
;
72 #if FEATURE_NV_fragment_program || FEATURE_ARB_fragment_program
73 ctx
->FragmentProgram
.Enabled
= GL_FALSE
;
74 ctx
->FragmentProgram
.Current
= (struct fragment_program
*) ctx
->Shared
->DefaultFragmentProgram
;
75 assert(ctx
->FragmentProgram
.Current
);
76 ctx
->FragmentProgram
.Current
->Base
.RefCount
++;
82 _mesa_EnableVertexAttribArrayARB(GLuint index
)
84 GET_CURRENT_CONTEXT(ctx
);
85 ASSERT_OUTSIDE_BEGIN_END(ctx
);
87 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
88 _mesa_error(ctx
, GL_INVALID_VALUE
,
89 "glEnableVertexAttribArrayARB(index)");
93 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_TRUE
;
94 ctx
->Array
._Enabled
|= _NEW_ARRAY_ATTRIB(index
);
95 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
100 _mesa_DisableVertexAttribArrayARB(GLuint index
)
102 GET_CURRENT_CONTEXT(ctx
);
103 ASSERT_OUTSIDE_BEGIN_END(ctx
);
105 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
106 _mesa_error(ctx
, GL_INVALID_VALUE
,
107 "glEnableVertexAttribArrayARB(index)");
111 ctx
->Array
.VertexAttrib
[index
].Enabled
= GL_FALSE
;
112 ctx
->Array
._Enabled
&= ~_NEW_ARRAY_ATTRIB(index
);
113 ctx
->Array
.NewState
|= _NEW_ARRAY_ATTRIB(index
);
118 _mesa_GetVertexAttribdvARB(GLuint index
, GLenum pname
, GLdouble
*params
)
121 GET_CURRENT_CONTEXT(ctx
);
122 ASSERT_OUTSIDE_BEGIN_END(ctx
);
124 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
125 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
126 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
127 COPY_4V(params
, fparams
);
130 params
[0] = fparams
[0];
137 _mesa_GetVertexAttribfvARB(GLuint index
, GLenum pname
, GLfloat
*params
)
139 GET_CURRENT_CONTEXT(ctx
);
140 ASSERT_OUTSIDE_BEGIN_END(ctx
);
142 if (index
== 0 || index
>= VERT_ATTRIB_MAX
) {
143 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribfvARB(index)");
148 case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB
:
149 params
[0] = ctx
->Array
.VertexAttrib
[index
].Enabled
;
151 case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB
:
152 params
[0] = ctx
->Array
.VertexAttrib
[index
].Size
;
154 case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB
:
155 params
[0] = ctx
->Array
.VertexAttrib
[index
].Stride
;
157 case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB
:
158 params
[0] = ctx
->Array
.VertexAttrib
[index
].Type
;
160 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB
:
161 params
[0] = ctx
->Array
.VertexAttrib
[index
].Normalized
;
163 case GL_CURRENT_VERTEX_ATTRIB_ARB
:
164 FLUSH_CURRENT(ctx
, 0);
165 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
168 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribfvARB(pname)");
175 _mesa_GetVertexAttribivARB(GLuint index
, GLenum pname
, GLint
*params
)
178 GET_CURRENT_CONTEXT(ctx
);
179 ASSERT_OUTSIDE_BEGIN_END(ctx
);
181 _mesa_GetVertexAttribfvARB(index
, pname
, fparams
);
182 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
183 if (pname
== GL_CURRENT_VERTEX_ATTRIB_ARB
) {
184 COPY_4V(params
, fparams
); /* float to int */
187 params
[0] = fparams
[0];
194 _mesa_GetVertexAttribPointervARB(GLuint index
, GLenum pname
, GLvoid
**pointer
)
196 GET_CURRENT_CONTEXT(ctx
);
197 ASSERT_OUTSIDE_BEGIN_END(ctx
);
199 if (index
>= ctx
->Const
.MaxVertexProgramAttribs
) {
200 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerARB(index)");
204 if (pname
!= GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB
) {
205 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerARB(pname)");
209 *pointer
= ctx
->Array
.VertexAttrib
[index
].Ptr
;;
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 if (target
== GL_VERTEX_PROGRAM_ARB
221 && ctx
->Extensions
.ARB_vertex_program
) {
222 struct vertex_program
*prog
= ctx
->VertexProgram
.Current
;
223 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
224 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
227 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
229 else if (target
== GL_FRAGMENT_PROGRAM_ARB
230 && ctx
->Extensions
.ARB_fragment_program
) {
231 struct fragment_program
*prog
= ctx
->FragmentProgram
.Current
;
232 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
233 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
236 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
239 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
245 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
246 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
248 _mesa_ProgramEnvParameter4fARB(target
, index
, x
, y
, z
, w
);
253 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
254 const GLdouble
*params
)
256 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
257 params
[2], params
[3]);
262 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
263 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
265 GET_CURRENT_CONTEXT(ctx
);
266 ASSERT_OUTSIDE_BEGIN_END(ctx
);
268 if (target
== GL_FRAGMENT_PROGRAM_ARB
269 && ctx
->Extensions
.ARB_fragment_program
) {
270 if (index
>= ctx
->Const
.MaxFragmentProgramEnvParams
) {
271 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
274 index
+= FP_PROG_REG_START
;
275 ASSIGN_4V(ctx
->FragmentProgram
.Machine
.Registers
[index
], x
, y
, z
, w
);
277 if (target
== GL_VERTEX_PROGRAM_ARB
278 && ctx
->Extensions
.ARB_vertex_program
) {
279 if (index
>= ctx
->Const
.MaxVertexProgramEnvParams
) {
280 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameter(index)");
283 index
+= VP_PROG_REG_START
;
284 ASSIGN_4V(ctx
->VertexProgram
.Machine
.Registers
[index
], x
, y
, z
, w
);
287 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameter(target)");
294 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
295 const GLfloat
*params
)
297 _mesa_ProgramEnvParameter4fARB(target
, index
, params
[0], params
[1],
298 params
[2], params
[3]);
303 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
306 GET_CURRENT_CONTEXT(ctx
);
309 _mesa_GetProgramEnvParameterfvARB(target
, index
, fparams
);
310 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
311 params
[0] = fparams
[0];
312 params
[1] = fparams
[1];
313 params
[2] = fparams
[2];
314 params
[3] = fparams
[3];
320 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
323 GET_CURRENT_CONTEXT(ctx
);
325 if (!ctx
->_CurrentProgram
)
326 ASSERT_OUTSIDE_BEGIN_END(ctx
);
328 if (target
== GL_FRAGMENT_PROGRAM_ARB
329 && ctx
->Extensions
.ARB_fragment_program
) {
330 if (index
>= ctx
->Const
.MaxFragmentProgramEnvParams
) {
331 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
334 index
+= FP_PROG_REG_START
;
335 COPY_4V(params
, ctx
->FragmentProgram
.Machine
.Registers
[index
]);
337 if (target
== GL_VERTEX_PROGRAM_ARB
338 && ctx
->Extensions
.ARB_vertex_program
) {
339 if (index
>= ctx
->Const
.MaxVertexProgramEnvParams
) {
340 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramEnvParameter(index)");
343 index
+= VP_PROG_REG_START
;
344 COPY_4V(params
, ctx
->VertexProgram
.Machine
.Registers
[index
]);
347 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramEnvParameter(target)");
354 * Note, this function is also used by the GL_NV_fragment_program extension.
357 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
358 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
360 GET_CURRENT_CONTEXT(ctx
);
361 struct program
*prog
;
362 ASSERT_OUTSIDE_BEGIN_END(ctx
);
364 if ((target
== GL_FRAGMENT_PROGRAM_NV
365 && ctx
->Extensions
.NV_fragment_program
) ||
366 (target
== GL_FRAGMENT_PROGRAM_ARB
367 && ctx
->Extensions
.ARB_fragment_program
)) {
368 if (index
>= ctx
->Const
.MaxFragmentProgramLocalParams
) {
369 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
372 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
374 else if (target
== GL_VERTEX_PROGRAM_ARB
375 && ctx
->Extensions
.ARB_vertex_program
) {
376 if (index
>= ctx
->Const
.MaxVertexProgramLocalParams
) {
377 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramLocalParameterARB");
380 prog
= &(ctx
->VertexProgram
.Current
->Base
);
383 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramLocalParameterARB");
387 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
388 prog
->LocalParams
[index
][0] = x
;
389 prog
->LocalParams
[index
][1] = y
;
390 prog
->LocalParams
[index
][2] = z
;
391 prog
->LocalParams
[index
][3] = w
;
396 * Note, this function is also used by the GL_NV_fragment_program extension.
399 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
400 const GLfloat
*params
)
402 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
403 params
[2], params
[3]);
408 * Note, this function is also used by the GL_NV_fragment_program extension.
411 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
412 GLdouble x
, GLdouble y
,
413 GLdouble z
, GLdouble w
)
415 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
416 (GLfloat
) z
, (GLfloat
) w
);
421 * Note, this function is also used by the GL_NV_fragment_program extension.
424 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
425 const GLdouble
*params
)
427 _mesa_ProgramLocalParameter4fARB(target
, index
,
428 (GLfloat
) params
[0], (GLfloat
) params
[1],
429 (GLfloat
) params
[2], (GLfloat
) params
[3]);
434 * Note, this function is also used by the GL_NV_fragment_program extension.
437 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
440 const struct program
*prog
;
442 GET_CURRENT_CONTEXT(ctx
);
443 ASSERT_OUTSIDE_BEGIN_END(ctx
);
445 if (target
== GL_VERTEX_PROGRAM_ARB
446 && ctx
->Extensions
.ARB_vertex_program
) {
447 prog
= &(ctx
->VertexProgram
.Current
->Base
);
448 maxParams
= ctx
->Const
.MaxVertexProgramLocalParams
;
450 else if (target
== GL_FRAGMENT_PROGRAM_ARB
451 && ctx
->Extensions
.ARB_fragment_program
) {
452 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
453 maxParams
= ctx
->Const
.MaxFragmentProgramLocalParams
;
455 else if (target
== GL_FRAGMENT_PROGRAM_NV
456 && ctx
->Extensions
.NV_fragment_program
) {
457 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
458 maxParams
= MAX_NV_FRAGMENT_PROGRAM_PARAMS
;
461 _mesa_error(ctx
, GL_INVALID_ENUM
,
462 "glGetProgramLocalParameterARB(target)");
466 if (index
>= maxParams
) {
467 _mesa_error(ctx
, GL_INVALID_VALUE
,
468 "glGetProgramLocalParameterARB(index)");
473 ASSERT(index
< MAX_PROGRAM_LOCAL_PARAMS
);
474 COPY_4V(params
, prog
->LocalParams
[index
]);
479 * Note, this function is also used by the GL_NV_fragment_program extension.
482 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
485 GET_CURRENT_CONTEXT(ctx
);
486 GLfloat floatParams
[4];
487 _mesa_GetProgramLocalParameterfvARB(target
, index
, floatParams
);
488 if (ctx
->ErrorValue
== GL_NO_ERROR
) {
489 COPY_4V(params
, floatParams
);
495 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
497 struct program
*prog
;
498 GET_CURRENT_CONTEXT(ctx
);
500 if (!ctx
->_CurrentProgram
)
501 ASSERT_OUTSIDE_BEGIN_END(ctx
);
503 if (target
== GL_VERTEX_PROGRAM_ARB
504 && ctx
->Extensions
.ARB_vertex_program
) {
505 prog
= &(ctx
->VertexProgram
.Current
->Base
);
507 else if (target
== GL_FRAGMENT_PROGRAM_ARB
508 && ctx
->Extensions
.ARB_fragment_program
) {
509 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
512 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
519 case GL_PROGRAM_LENGTH_ARB
:
520 *params
= prog
->String
? _mesa_strlen((char *) prog
->String
) : 0;
522 case GL_PROGRAM_FORMAT_ARB
:
523 *params
= prog
->Format
;
525 case GL_PROGRAM_BINDING_ARB
:
528 case GL_PROGRAM_INSTRUCTIONS_ARB
:
529 *params
= prog
->NumInstructions
;
531 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
532 if (target
== GL_VERTEX_PROGRAM_ARB
)
533 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
535 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
537 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
538 *params
= prog
->NumInstructions
;
540 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
541 if (target
== GL_VERTEX_PROGRAM_ARB
)
542 *params
= ctx
->Const
.MaxVertexProgramInstructions
;
544 *params
= ctx
->Const
.MaxFragmentProgramInstructions
;
546 case GL_PROGRAM_TEMPORARIES_ARB
:
547 *params
= prog
->NumTemporaries
;
549 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
550 if (target
== GL_VERTEX_PROGRAM_ARB
)
551 *params
= ctx
->Const
.MaxVertexProgramTemps
;
553 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
555 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
556 /* XXX same as GL_PROGRAM_TEMPORARIES_ARB? */
557 *params
= prog
->NumTemporaries
;
559 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
560 /* XXX same as GL_MAX_PROGRAM_TEMPORARIES_ARB? */
561 if (target
== GL_VERTEX_PROGRAM_ARB
)
562 *params
= ctx
->Const
.MaxVertexProgramTemps
;
564 *params
= ctx
->Const
.MaxFragmentProgramTemps
;
566 case GL_PROGRAM_PARAMETERS_ARB
:
567 *params
= prog
->NumParameters
;
569 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
570 if (target
== GL_VERTEX_PROGRAM_ARB
)
571 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
573 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
575 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
576 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
577 *params
= prog
->NumParameters
;
579 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
580 /* XXX same as GL_MAX_PROGRAM_PARAMETERS_ARB? */
581 if (target
== GL_VERTEX_PROGRAM_ARB
)
582 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
584 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
586 case GL_PROGRAM_ATTRIBS_ARB
:
587 *params
= prog
->NumAttributes
;
589 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
590 if (target
== GL_VERTEX_PROGRAM_ARB
)
591 *params
= ctx
->Const
.MaxVertexProgramAttribs
;
593 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
595 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
596 /* XXX same as GL_PROGRAM_ATTRIBS_ARB? */
597 *params
= prog
->NumAttributes
;
599 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
600 /* XXX same as GL_MAX_PROGRAM_ATTRIBS_ARB? */
601 if (target
== GL_VERTEX_PROGRAM_ARB
)
602 *params
= ctx
->Const
.MaxVertexProgramAttribs
;
604 *params
= ctx
->Const
.MaxFragmentProgramAttribs
;
606 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
607 *params
= prog
->NumAddressRegs
;
609 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
610 if (target
== GL_VERTEX_PROGRAM_ARB
)
611 *params
= ctx
->Const
.MaxVertexProgramAddressRegs
;
613 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
615 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
616 /* XXX same as GL_PROGRAM_ADDRESS_REGISTERS_ARB? */
617 *params
= prog
->NumAddressRegs
;
619 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
620 /* XXX same as GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB? */
621 if (target
== GL_VERTEX_PROGRAM_ARB
)
622 *params
= ctx
->Const
.MaxVertexProgramAddressRegs
;
624 *params
= ctx
->Const
.MaxFragmentProgramAddressRegs
;
626 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
627 if (target
== GL_VERTEX_PROGRAM_ARB
)
628 *params
= ctx
->Const
.MaxVertexProgramLocalParams
;
630 *params
= ctx
->Const
.MaxFragmentProgramLocalParams
;
632 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
633 if (target
== GL_VERTEX_PROGRAM_ARB
)
634 *params
= ctx
->Const
.MaxVertexProgramEnvParams
;
636 *params
= ctx
->Const
.MaxFragmentProgramEnvParams
;
638 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
644 * The following apply to fragment programs only.
646 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
647 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
648 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
649 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
652 *params
= ctx
->FragmentProgram
.Current
->NumAluInstructions
;
654 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
655 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
656 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
657 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
660 *params
= ctx
->FragmentProgram
.Current
->NumTexInstructions
;
662 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
663 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
664 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
665 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
668 *params
= ctx
->FragmentProgram
.Current
->NumTexIndirections
;
670 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
671 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
672 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
673 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
676 *params
= ctx
->Const
.MaxFragmentProgramAluInstructions
;
678 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
679 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
680 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
681 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
684 *params
= ctx
->Const
.MaxFragmentProgramTexInstructions
;
686 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
687 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
688 if (target
!= GL_FRAGMENT_PROGRAM_ARB
) {
689 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(target)");
692 *params
= ctx
->Const
.MaxFragmentProgramTexIndirections
;
695 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
702 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
704 struct program
*prog
;
705 GET_CURRENT_CONTEXT(ctx
);
707 if (!ctx
->_CurrentProgram
)
708 ASSERT_OUTSIDE_BEGIN_END(ctx
);
710 if (target
== GL_VERTEX_PROGRAM_ARB
) {
711 prog
= &(ctx
->VertexProgram
.Current
->Base
);
713 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
714 prog
= &(ctx
->FragmentProgram
.Current
->Base
);
717 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
723 if (pname
!= GL_PROGRAM_STRING_ARB
) {
724 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
728 MEMCPY(string
, prog
->String
, _mesa_strlen((char *) prog
->String
));
735 glProgramCallbackMESA(GLenum target
, GLprogramcallbackMESA callback
,
738 _mesa_ProgramCallbackMESA(target
, callback
, data
);
743 _mesa_ProgramCallbackMESA(GLenum target
, GLprogramcallbackMESA callback
,
746 GET_CURRENT_CONTEXT(ctx
);
749 case GL_FRAGMENT_PROGRAM_ARB
:
750 if (!ctx
->Extensions
.ARB_fragment_program
) {
751 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
754 ctx
->FragmentProgram
.Callback
= callback
;
755 ctx
->FragmentProgram
.CallbackData
= data
;
757 case GL_FRAGMENT_PROGRAM_NV
:
758 if (!ctx
->Extensions
.NV_fragment_program
) {
759 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
762 ctx
->FragmentProgram
.Callback
= callback
;
763 ctx
->FragmentProgram
.CallbackData
= data
;
765 case GL_VERTEX_PROGRAM_ARB
: /* == GL_VERTEX_PROGRAM_NV */
766 if (!ctx
->Extensions
.ARB_vertex_program
&&
767 !ctx
->Extensions
.NV_vertex_program
) {
768 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
771 ctx
->VertexProgram
.Callback
= callback
;
772 ctx
->VertexProgram
.CallbackData
= data
;
775 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramCallbackMESA(target)");
783 glGetProgramRegisterfvMESA(GLenum target
,
784 GLsizei len
, const GLubyte
*registerName
,
787 _mesa_GetProgramRegisterfvMESA(target
, len
, registerName
, v
);
792 _mesa_GetProgramRegisterfvMESA(GLenum target
,
793 GLsizei len
, const GLubyte
*registerName
,
797 GET_CURRENT_CONTEXT(ctx
);
799 /* We _should_ be inside glBegin/glEnd */
801 if (ctx
->Driver
.CurrentExecPrimitive
== PRIM_OUTSIDE_BEGIN_END
) {
802 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramRegisterfvMESA");
807 /* make null-terminated copy of registerName */
808 _mesa_memcpy(reg
, registerName
, len
);
812 case GL_VERTEX_PROGRAM_NV
:
813 if (!ctx
->Extensions
.ARB_vertex_program
&&
814 !ctx
->Extensions
.NV_vertex_program
) {
815 _mesa_error(ctx
, GL_INVALID_ENUM
,
816 "glGetProgramRegisterfvMESA(target)");
819 if (!ctx
->VertexProgram
.Enabled
) {
820 _mesa_error(ctx
, GL_INVALID_OPERATION
,
821 "glGetProgramRegisterfvMESA");
824 /* GL_NV_vertex_program */
827 GLint i
= _mesa_atoi(reg
+ 1);
828 if (i
>= ctx
->Const
.MaxVertexProgramTemps
) {
829 _mesa_error(ctx
, GL_INVALID_VALUE
,
830 "glGetProgramRegisterfvMESA(registerName)");
833 COPY_4V(v
, ctx
->VertexProgram
.Machine
.Registers
834 [VP_TEMP_REG_START
+ i
]);
836 else if (reg
[0] == 'v' && reg
[1] == '[') {
837 /* Vertex Input attribute */
839 for (i
= 0; i
< ctx
->Const
.MaxVertexProgramAttribs
; i
++) {
840 const char *name
= _mesa_nv_vertex_input_register_name(i
);
842 sprintf(number
, "%d", i
);
843 if (_mesa_strncmp(reg
+ 2, name
, 4) == 0 ||
844 _mesa_strncmp(reg
+ 2, number
, _mesa_strlen(number
)) == 0) {
845 COPY_4V(v
, ctx
->VertexProgram
.Machine
.Registers
846 [VP_INPUT_REG_START
+ i
]);
850 _mesa_error(ctx
, GL_INVALID_VALUE
,
851 "glGetProgramRegisterfvMESA(registerName)");
854 else if (reg
[0] == 'o' && reg
[1] == '[') {
855 /* Vertex output attribute */
857 /* GL_ARB_vertex_program */
858 else if (_mesa_strncmp(reg
, "vertex.", 7) == 0) {
862 _mesa_error(ctx
, GL_INVALID_VALUE
,
863 "glGetProgramRegisterfvMESA(registerName)");
867 case GL_FRAGMENT_PROGRAM_ARB
:
868 if (!ctx
->Extensions
.ARB_fragment_program
) {
869 _mesa_error(ctx
, GL_INVALID_ENUM
,
870 "glGetProgramRegisterfvMESA(target)");
873 if (!ctx
->FragmentProgram
.Enabled
) {
874 _mesa_error(ctx
, GL_INVALID_OPERATION
,
875 "glGetProgramRegisterfvMESA");
880 case GL_FRAGMENT_PROGRAM_NV
:
881 if (!ctx
->Extensions
.NV_fragment_program
) {
882 _mesa_error(ctx
, GL_INVALID_ENUM
,
883 "glGetProgramRegisterfvMESA(target)");
886 if (!ctx
->FragmentProgram
.Enabled
) {
887 _mesa_error(ctx
, GL_INVALID_OPERATION
,
888 "glGetProgramRegisterfvMESA");
893 GLint i
= _mesa_atoi(reg
+ 1);
894 if (i
>= ctx
->Const
.MaxFragmentProgramTemps
) {
895 _mesa_error(ctx
, GL_INVALID_VALUE
,
896 "glGetProgramRegisterfvMESA(registerName)");
900 ctx
->FragmentProgram
.Machine
.Registers
[FP_TEMP_REG_START
+ i
]);
902 else if (reg
[0] == 'f' && reg
[1] == '[') {
903 /* Fragment input attribute */
905 for (i
= 0; i
< ctx
->Const
.MaxFragmentProgramAttribs
; i
++) {
906 const char *name
= _mesa_nv_fragment_input_register_name(i
);
907 if (_mesa_strncmp(reg
+ 2, name
, 4) == 0) {
908 COPY_4V(v
, ctx
->FragmentProgram
.Machine
.Registers
909 [FP_INPUT_REG_START
+ i
]);
913 _mesa_error(ctx
, GL_INVALID_VALUE
,
914 "glGetProgramRegisterfvMESA(registerName)");
917 else if (_mesa_strcmp(reg
, "o[COLR]") == 0) {
918 /* Fragment output color */
919 COPY_4V(v
, ctx
->FragmentProgram
.Machine
.Registers
920 [FP_OUTPUT_REG_START
+ FRAG_OUTPUT_COLR
]);
922 else if (_mesa_strcmp(reg
, "o[COLH]") == 0) {
923 /* Fragment output color */
924 COPY_4V(v
, ctx
->FragmentProgram
.Machine
.Registers
925 [FP_OUTPUT_REG_START
+ FRAG_OUTPUT_COLH
]);
927 else if (_mesa_strcmp(reg
, "o[DEPR]") == 0) {
928 /* Fragment output depth */
929 COPY_4V(v
, ctx
->FragmentProgram
.Machine
.Registers
930 [FP_OUTPUT_REG_START
+ FRAG_OUTPUT_DEPR
]);
933 _mesa_error(ctx
, GL_INVALID_VALUE
,
934 "glGetProgramRegisterfvMESA(registerName)");
939 _mesa_error(ctx
, GL_INVALID_ENUM
,
940 "glGetProgramRegisterfvMESA(target)");