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 * NVIDIA vertex/fragment program state management functions.
32 * Regarding GL_NV_fragment/vertex_program, GL_NV_vertex_program1_1, etc:
34 * Portions of this software may use or implement intellectual
35 * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
36 * any and all warranties with respect to such intellectual property,
37 * including any use thereof or modifications thereto.
40 #include "main/glheader.h"
41 #include "main/context.h"
42 #include "main/hash.h"
43 #include "main/imports.h"
44 #include "main/macros.h"
45 #include "main/nvprogram.h"
46 #include "program/arbprogparse.h"
47 #include "program/nvfragparse.h"
48 #include "program/nvvertparse.h"
49 #include "program/program.h"
50 #include "program/prog_instruction.h"
51 #include "program/prog_parameter.h"
56 * Execute a vertex state program.
57 * \note Called from the GL API dispatcher.
60 _mesa_ExecuteProgramNV(GLenum target
, GLuint id
, const GLfloat
*params
)
62 struct gl_vertex_program
*vprog
;
63 GET_CURRENT_CONTEXT(ctx
);
64 ASSERT_OUTSIDE_BEGIN_END(ctx
);
66 if (target
!= GL_VERTEX_STATE_PROGRAM_NV
) {
67 _mesa_error(ctx
, GL_INVALID_ENUM
, "glExecuteProgramNV");
71 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
73 vprog
= (struct gl_vertex_program
*) _mesa_lookup_program(ctx
, id
);
75 if (!vprog
|| vprog
->Base
.Target
!= GL_VERTEX_STATE_PROGRAM_NV
) {
76 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glExecuteProgramNV");
80 _mesa_problem(ctx
, "glExecuteProgramNV() not supported");
85 * Determine if a set of programs is resident in hardware.
86 * \note Not compiled into display lists.
87 * \note Called from the GL API dispatcher.
90 _mesa_AreProgramsResidentNV(GLsizei n
, const GLuint
*ids
,
91 GLboolean
*residences
)
94 GLboolean allResident
= GL_TRUE
;
95 GET_CURRENT_CONTEXT(ctx
);
96 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
99 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV(n)");
103 for (i
= 0; i
< n
; i
++) {
104 const struct gl_program
*prog
;
106 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV");
109 prog
= _mesa_lookup_program(ctx
, ids
[i
]);
111 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV");
114 if (prog
->Resident
) {
116 residences
[i
] = GL_TRUE
;
120 allResident
= GL_FALSE
;
121 for (j
= 0; j
< i
; j
++)
122 residences
[j
] = GL_TRUE
;
124 residences
[i
] = GL_FALSE
;
133 * Request that a set of programs be resident in hardware.
134 * \note Called from the GL API dispatcher.
137 _mesa_RequestResidentProgramsNV(GLsizei n
, const GLuint
*ids
)
140 GET_CURRENT_CONTEXT(ctx
);
141 ASSERT_OUTSIDE_BEGIN_END(ctx
);
144 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(n)");
148 /* just error checking for now */
149 for (i
= 0; i
< n
; i
++) {
150 struct gl_program
*prog
;
153 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(id)");
157 prog
= _mesa_lookup_program(ctx
, ids
[i
]);
159 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(id)");
163 /* XXX this is really a hardware thing we should hook out */
164 prog
->Resident
= GL_TRUE
;
170 * Get a program parameter register.
171 * \note Not compiled into display lists.
172 * \note Called from the GL API dispatcher.
175 _mesa_GetProgramParameterfvNV(GLenum target
, GLuint index
,
176 GLenum pname
, GLfloat
*params
)
178 GET_CURRENT_CONTEXT(ctx
);
179 ASSERT_OUTSIDE_BEGIN_END(ctx
);
181 if (target
== GL_VERTEX_PROGRAM_NV
) {
182 if (pname
== GL_PROGRAM_PARAMETER_NV
) {
183 if (index
< MAX_NV_VERTEX_PROGRAM_PARAMS
) {
184 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
187 _mesa_error(ctx
, GL_INVALID_VALUE
,
188 "glGetProgramParameterfvNV(index)");
193 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterfvNV(pname)");
198 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterfvNV(target)");
205 * Get a program parameter register.
206 * \note Not compiled into display lists.
207 * \note Called from the GL API dispatcher.
210 _mesa_GetProgramParameterdvNV(GLenum target
, GLuint index
,
211 GLenum pname
, GLdouble
*params
)
213 GET_CURRENT_CONTEXT(ctx
);
214 ASSERT_OUTSIDE_BEGIN_END(ctx
);
216 if (target
== GL_VERTEX_PROGRAM_NV
) {
217 if (pname
== GL_PROGRAM_PARAMETER_NV
) {
218 if (index
< MAX_NV_VERTEX_PROGRAM_PARAMS
) {
219 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
222 _mesa_error(ctx
, GL_INVALID_VALUE
,
223 "glGetProgramParameterdvNV(index)");
228 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterdvNV(pname)");
233 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterdvNV(target)");
240 * Get a program attribute.
241 * \note Not compiled into display lists.
242 * \note Called from the GL API dispatcher.
245 _mesa_GetProgramivNV(GLuint id
, GLenum pname
, GLint
*params
)
247 struct gl_program
*prog
;
248 GET_CURRENT_CONTEXT(ctx
);
250 ASSERT_OUTSIDE_BEGIN_END(ctx
);
252 prog
= _mesa_lookup_program(ctx
, id
);
254 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramivNV");
259 case GL_PROGRAM_TARGET_NV
:
260 *params
= prog
->Target
;
262 case GL_PROGRAM_LENGTH_NV
:
263 *params
= prog
->String
?(GLint
) strlen((char *) prog
->String
) : 0;
265 case GL_PROGRAM_RESIDENT_NV
:
266 *params
= prog
->Resident
;
269 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivNV(pname)");
276 * Get the program source code.
277 * \note Not compiled into display lists.
278 * \note Called from the GL API dispatcher.
281 _mesa_GetProgramStringNV(GLuint id
, GLenum pname
, GLubyte
*program
)
283 struct gl_program
*prog
;
284 GET_CURRENT_CONTEXT(ctx
);
286 ASSERT_OUTSIDE_BEGIN_END(ctx
);
288 if (pname
!= GL_PROGRAM_STRING_NV
) {
289 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringNV(pname)");
293 prog
= _mesa_lookup_program(ctx
, id
);
295 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramStringNV");
300 memcpy(program
, prog
->String
, strlen((char *) prog
->String
));
309 * Get matrix tracking information.
310 * \note Not compiled into display lists.
311 * \note Called from the GL API dispatcher.
314 _mesa_GetTrackMatrixivNV(GLenum target
, GLuint address
,
315 GLenum pname
, GLint
*params
)
317 GET_CURRENT_CONTEXT(ctx
);
318 ASSERT_OUTSIDE_BEGIN_END(ctx
);
320 if (target
== GL_VERTEX_PROGRAM_NV
321 && ctx
->Extensions
.NV_vertex_program
) {
324 if ((address
& 0x3) || address
>= MAX_NV_VERTEX_PROGRAM_PARAMS
) {
325 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetTrackMatrixivNV(address)");
332 case GL_TRACK_MATRIX_NV
:
333 params
[0] = (GLint
) ctx
->VertexProgram
.TrackMatrix
[i
];
335 case GL_TRACK_MATRIX_TRANSFORM_NV
:
336 params
[0] = (GLint
) ctx
->VertexProgram
.TrackMatrixTransform
[i
];
339 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTrackMatrixivNV");
344 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTrackMatrixivNV");
351 * Get a vertex (or vertex array) attribute.
352 * \note Not compiled into display lists.
353 * \note Called from the GL API dispatcher.
356 _mesa_GetVertexAttribdvNV(GLuint index
, GLenum pname
, GLdouble
*params
)
358 const struct gl_client_array
*array
;
359 GET_CURRENT_CONTEXT(ctx
);
360 ASSERT_OUTSIDE_BEGIN_END(ctx
);
362 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
363 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
367 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[index
];
370 case GL_ATTRIB_ARRAY_SIZE_NV
:
371 params
[0] = array
->Size
;
373 case GL_ATTRIB_ARRAY_STRIDE_NV
:
374 params
[0] = array
->Stride
;
376 case GL_ATTRIB_ARRAY_TYPE_NV
:
377 params
[0] = array
->Type
;
379 case GL_CURRENT_ATTRIB_NV
:
381 _mesa_error(ctx
, GL_INVALID_OPERATION
,
382 "glGetVertexAttribdvNV(index == 0)");
385 FLUSH_CURRENT(ctx
, 0);
386 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
389 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
395 * Get a vertex (or vertex array) attribute.
396 * \note Not compiled into display lists.
397 * \note Called from the GL API dispatcher.
400 _mesa_GetVertexAttribfvNV(GLuint index
, GLenum pname
, GLfloat
*params
)
402 const struct gl_client_array
*array
;
403 GET_CURRENT_CONTEXT(ctx
);
404 ASSERT_OUTSIDE_BEGIN_END(ctx
);
406 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
407 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
411 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[index
];
414 case GL_ATTRIB_ARRAY_SIZE_NV
:
415 params
[0] = (GLfloat
) array
->Size
;
417 case GL_ATTRIB_ARRAY_STRIDE_NV
:
418 params
[0] = (GLfloat
) array
->Stride
;
420 case GL_ATTRIB_ARRAY_TYPE_NV
:
421 params
[0] = (GLfloat
) array
->Type
;
423 case GL_CURRENT_ATTRIB_NV
:
425 _mesa_error(ctx
, GL_INVALID_OPERATION
,
426 "glGetVertexAttribfvNV(index == 0)");
429 FLUSH_CURRENT(ctx
, 0);
430 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
433 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
439 * Get a vertex (or vertex array) attribute.
440 * \note Not compiled into display lists.
441 * \note Called from the GL API dispatcher.
444 _mesa_GetVertexAttribivNV(GLuint index
, GLenum pname
, GLint
*params
)
446 const struct gl_client_array
*array
;
447 GET_CURRENT_CONTEXT(ctx
);
448 ASSERT_OUTSIDE_BEGIN_END(ctx
);
450 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
451 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
455 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[index
];
458 case GL_ATTRIB_ARRAY_SIZE_NV
:
459 params
[0] = array
->Size
;
461 case GL_ATTRIB_ARRAY_STRIDE_NV
:
462 params
[0] = array
->Stride
;
464 case GL_ATTRIB_ARRAY_TYPE_NV
:
465 params
[0] = array
->Type
;
467 case GL_CURRENT_ATTRIB_NV
:
469 _mesa_error(ctx
, GL_INVALID_OPERATION
,
470 "glGetVertexAttribivNV(index == 0)");
473 FLUSH_CURRENT(ctx
, 0);
474 params
[0] = (GLint
) ctx
->Current
.Attrib
[index
][0];
475 params
[1] = (GLint
) ctx
->Current
.Attrib
[index
][1];
476 params
[2] = (GLint
) ctx
->Current
.Attrib
[index
][2];
477 params
[3] = (GLint
) ctx
->Current
.Attrib
[index
][3];
479 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
480 params
[0] = array
->BufferObj
->Name
;
483 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
490 * Get a vertex array attribute pointer.
491 * \note Not compiled into display lists.
492 * \note Called from the GL API dispatcher.
495 _mesa_GetVertexAttribPointervNV(GLuint index
, GLenum pname
, GLvoid
**pointer
)
497 GET_CURRENT_CONTEXT(ctx
);
498 ASSERT_OUTSIDE_BEGIN_END(ctx
);
500 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
501 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerNV(index)");
505 if (pname
!= GL_ATTRIB_ARRAY_POINTER_NV
) {
506 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerNV(pname)");
510 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[index
].Ptr
;
514 _mesa_emit_nv_temp_initialization(GLcontext
*ctx
,
515 struct gl_program
*program
)
517 struct prog_instruction
*inst
;
519 struct gl_shader_compiler_options
* options
=
520 &ctx
->ShaderCompilerOptions
[_mesa_program_target_to_index(program
->Target
)];
522 if (!options
->EmitNVTempInitialization
)
525 /* We'll swizzle up a zero temporary so we can use it for the
528 if (program
->NumTemporaries
== 0)
529 program
->NumTemporaries
= 1;
531 _mesa_insert_instructions(program
, 0, program
->NumTemporaries
+ 1);
533 for (i
= 0; i
< program
->NumTemporaries
; i
++) {
534 struct prog_instruction
*inst
= &program
->Instructions
[i
];
536 inst
->Opcode
= OPCODE_SWZ
;
537 inst
->DstReg
.File
= PROGRAM_TEMPORARY
;
538 inst
->DstReg
.Index
= i
;
539 inst
->DstReg
.WriteMask
= WRITEMASK_XYZW
;
540 inst
->SrcReg
[0].File
= PROGRAM_TEMPORARY
;
541 inst
->SrcReg
[0].Index
= 0;
542 inst
->SrcReg
[0].Swizzle
= MAKE_SWIZZLE4(SWIZZLE_ZERO
,
548 inst
= &program
->Instructions
[i
];
549 inst
->Opcode
= OPCODE_ARL
;
550 inst
->DstReg
.File
= PROGRAM_ADDRESS
;
551 inst
->DstReg
.Index
= 0;
552 inst
->DstReg
.WriteMask
= WRITEMASK_XYZW
;
553 inst
->SrcReg
[0].File
= PROGRAM_TEMPORARY
;
554 inst
->SrcReg
[0].Index
= 0;
555 inst
->SrcReg
[0].Swizzle
= SWIZZLE_XXXX
;
557 if (program
->NumAddressRegs
== 0)
558 program
->NumAddressRegs
= 1;
562 _mesa_setup_nv_temporary_count(GLcontext
*ctx
, struct gl_program
*program
)
566 program
->NumTemporaries
= 0;
567 for (i
= 0; i
< program
->NumInstructions
; i
++) {
568 struct prog_instruction
*inst
= &program
->Instructions
[i
];
570 if (inst
->DstReg
.File
== PROGRAM_TEMPORARY
) {
571 program
->NumTemporaries
= MAX2(program
->NumTemporaries
,
572 inst
->DstReg
.Index
+ 1);
574 if (inst
->SrcReg
[0].File
== PROGRAM_TEMPORARY
) {
575 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
576 inst
->SrcReg
[0].Index
+ 1);
578 if (inst
->SrcReg
[1].File
== PROGRAM_TEMPORARY
) {
579 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
580 inst
->SrcReg
[1].Index
+ 1);
582 if (inst
->SrcReg
[2].File
== PROGRAM_TEMPORARY
) {
583 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
584 inst
->SrcReg
[2].Index
+ 1);
590 * Load/parse/compile a program.
591 * \note Called from the GL API dispatcher.
594 _mesa_LoadProgramNV(GLenum target
, GLuint id
, GLsizei len
,
595 const GLubyte
*program
)
597 struct gl_program
*prog
;
598 GET_CURRENT_CONTEXT(ctx
);
599 ASSERT_OUTSIDE_BEGIN_END(ctx
);
601 if (!ctx
->Extensions
.NV_vertex_program
602 && !ctx
->Extensions
.NV_fragment_program
) {
603 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glLoadProgramNV()");
608 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLoadProgramNV(id)");
613 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLoadProgramNV(len)");
617 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
619 prog
= _mesa_lookup_program(ctx
, id
);
621 if (prog
&& prog
->Target
!= 0 && prog
->Target
!= target
) {
622 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glLoadProgramNV(target)");
626 if ((target
== GL_VERTEX_PROGRAM_NV
||
627 target
== GL_VERTEX_STATE_PROGRAM_NV
)
628 && ctx
->Extensions
.NV_vertex_program
) {
629 struct gl_vertex_program
*vprog
= (struct gl_vertex_program
*) prog
;
630 if (!vprog
|| prog
== &_mesa_DummyProgram
) {
631 vprog
= (struct gl_vertex_program
*)
632 ctx
->Driver
.NewProgram(ctx
, target
, id
);
634 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
637 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, vprog
);
640 if (ctx
->Extensions
.ARB_vertex_program
641 && (strncmp((char *) program
, "!!ARB", 5) == 0)) {
642 _mesa_parse_arb_vertex_program(ctx
, target
, program
, len
, vprog
);
644 _mesa_parse_nv_vertex_program(ctx
, target
, program
, len
, vprog
);
647 else if (target
== GL_FRAGMENT_PROGRAM_NV
648 && ctx
->Extensions
.NV_fragment_program
) {
649 struct gl_fragment_program
*fprog
= (struct gl_fragment_program
*) prog
;
650 if (!fprog
|| prog
== &_mesa_DummyProgram
) {
651 fprog
= (struct gl_fragment_program
*)
652 ctx
->Driver
.NewProgram(ctx
, target
, id
);
654 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
657 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, fprog
);
659 _mesa_parse_nv_fragment_program(ctx
, target
, program
, len
, fprog
);
661 else if (target
== GL_FRAGMENT_PROGRAM_ARB
662 && ctx
->Extensions
.ARB_fragment_program
) {
663 struct gl_fragment_program
*fprog
= (struct gl_fragment_program
*) prog
;
664 if (!fprog
|| prog
== &_mesa_DummyProgram
) {
665 fprog
= (struct gl_fragment_program
*)
666 ctx
->Driver
.NewProgram(ctx
, target
, id
);
668 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
671 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, fprog
);
673 _mesa_parse_arb_fragment_program(ctx
, target
, program
, len
, fprog
);
676 _mesa_error(ctx
, GL_INVALID_ENUM
, "glLoadProgramNV(target)");
683 * Set a sequence of program parameter registers.
684 * \note Called from the GL API dispatcher.
687 _mesa_ProgramParameters4dvNV(GLenum target
, GLuint index
,
688 GLuint num
, const GLdouble
*params
)
690 GET_CURRENT_CONTEXT(ctx
);
691 ASSERT_OUTSIDE_BEGIN_END(ctx
);
693 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
695 if (index
+ num
> MAX_NV_VERTEX_PROGRAM_PARAMS
) {
696 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramParameters4dvNV");
699 for (i
= 0; i
< num
; i
++) {
700 ctx
->VertexProgram
.Parameters
[index
+ i
][0] = (GLfloat
) params
[0];
701 ctx
->VertexProgram
.Parameters
[index
+ i
][1] = (GLfloat
) params
[1];
702 ctx
->VertexProgram
.Parameters
[index
+ i
][2] = (GLfloat
) params
[2];
703 ctx
->VertexProgram
.Parameters
[index
+ i
][3] = (GLfloat
) params
[3];
708 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramParameters4dvNV");
715 * Set a sequence of program parameter registers.
716 * \note Called from the GL API dispatcher.
719 _mesa_ProgramParameters4fvNV(GLenum target
, GLuint index
,
720 GLuint num
, const GLfloat
*params
)
722 GET_CURRENT_CONTEXT(ctx
);
723 ASSERT_OUTSIDE_BEGIN_END(ctx
);
725 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
727 if (index
+ num
> MAX_NV_VERTEX_PROGRAM_PARAMS
) {
728 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramParameters4fvNV");
731 for (i
= 0; i
< num
; i
++) {
732 COPY_4V(ctx
->VertexProgram
.Parameters
[index
+ i
], params
);
737 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramParameters4fvNV");
745 * Setup tracking of matrices into program parameter registers.
746 * \note Called from the GL API dispatcher.
749 _mesa_TrackMatrixNV(GLenum target
, GLuint address
,
750 GLenum matrix
, GLenum transform
)
752 GET_CURRENT_CONTEXT(ctx
);
753 ASSERT_OUTSIDE_BEGIN_END(ctx
);
755 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
757 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
759 /* addr must be multiple of four */
760 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTrackMatrixNV(address)");
770 case GL_MODELVIEW_PROJECTION_NV
:
779 /* OK, fallthrough */
782 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(matrix)");
789 case GL_TRANSPOSE_NV
:
790 case GL_INVERSE_TRANSPOSE_NV
:
791 /* OK, fallthrough */
794 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(transform)");
798 ctx
->VertexProgram
.TrackMatrix
[address
/ 4] = matrix
;
799 ctx
->VertexProgram
.TrackMatrixTransform
[address
/ 4] = transform
;
802 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(target)");
809 _mesa_ProgramNamedParameter4fNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
810 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
812 struct gl_program
*prog
;
813 struct gl_fragment_program
*fragProg
;
816 GET_CURRENT_CONTEXT(ctx
);
817 ASSERT_OUTSIDE_BEGIN_END(ctx
);
819 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
821 prog
= _mesa_lookup_program(ctx
, id
);
822 if (!prog
|| prog
->Target
!= GL_FRAGMENT_PROGRAM_NV
) {
823 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glProgramNamedParameterNV");
828 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramNamedParameterNV(len)");
832 fragProg
= (struct gl_fragment_program
*) prog
;
833 v
= _mesa_lookup_parameter_value(fragProg
->Base
.Parameters
, len
,
843 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramNamedParameterNV(name)");
848 _mesa_ProgramNamedParameter4fvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
851 _mesa_ProgramNamedParameter4fNV(id
, len
, name
, v
[0], v
[1], v
[2], v
[3]);
856 _mesa_ProgramNamedParameter4dNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
857 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
859 _mesa_ProgramNamedParameter4fNV(id
, len
, name
, (GLfloat
)x
, (GLfloat
)y
,
860 (GLfloat
)z
, (GLfloat
)w
);
865 _mesa_ProgramNamedParameter4dvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
868 _mesa_ProgramNamedParameter4fNV(id
, len
, name
,
869 (GLfloat
)v
[0], (GLfloat
)v
[1],
870 (GLfloat
)v
[2], (GLfloat
)v
[3]);
875 _mesa_GetProgramNamedParameterfvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
878 struct gl_program
*prog
;
879 struct gl_fragment_program
*fragProg
;
882 GET_CURRENT_CONTEXT(ctx
);
884 ASSERT_OUTSIDE_BEGIN_END(ctx
);
886 prog
= _mesa_lookup_program(ctx
, id
);
887 if (!prog
|| prog
->Target
!= GL_FRAGMENT_PROGRAM_NV
) {
888 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramNamedParameterNV");
893 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramNamedParameterNV");
897 fragProg
= (struct gl_fragment_program
*) prog
;
898 v
= _mesa_lookup_parameter_value(fragProg
->Base
.Parameters
,
908 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramNamedParameterNV");
913 _mesa_GetProgramNamedParameterdvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
916 GLfloat floatParams
[4];
917 _mesa_GetProgramNamedParameterfvNV(id
, len
, name
, floatParams
);
918 COPY_4V(params
, floatParams
);