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/mtypes.h"
46 #include "main/nvprogram.h"
47 #include "program/arbprogparse.h"
48 #include "program/nvfragparse.h"
49 #include "program/nvvertparse.h"
50 #include "program/program.h"
51 #include "program/prog_instruction.h"
52 #include "program/prog_parameter.h"
57 * Execute a vertex state program.
58 * \note Called from the GL API dispatcher.
61 _mesa_ExecuteProgramNV(GLenum target
, GLuint id
, const GLfloat
*params
)
63 struct gl_vertex_program
*vprog
;
64 GET_CURRENT_CONTEXT(ctx
);
65 ASSERT_OUTSIDE_BEGIN_END(ctx
);
67 if (target
!= GL_VERTEX_STATE_PROGRAM_NV
) {
68 _mesa_error(ctx
, GL_INVALID_ENUM
, "glExecuteProgramNV");
72 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
74 vprog
= (struct gl_vertex_program
*) _mesa_lookup_program(ctx
, id
);
76 if (!vprog
|| vprog
->Base
.Target
!= GL_VERTEX_STATE_PROGRAM_NV
) {
77 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glExecuteProgramNV");
81 _mesa_problem(ctx
, "glExecuteProgramNV() not supported");
86 * Determine if a set of programs is resident in hardware.
87 * \note Not compiled into display lists.
88 * \note Called from the GL API dispatcher.
91 _mesa_AreProgramsResidentNV(GLsizei n
, const GLuint
*ids
,
92 GLboolean
*residences
)
95 GLboolean allResident
= GL_TRUE
;
96 GET_CURRENT_CONTEXT(ctx
);
97 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
100 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV(n)");
104 for (i
= 0; i
< n
; i
++) {
105 const struct gl_program
*prog
;
107 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV");
110 prog
= _mesa_lookup_program(ctx
, ids
[i
]);
112 _mesa_error(ctx
, GL_INVALID_VALUE
, "glAreProgramsResidentNV");
115 if (prog
->Resident
) {
117 residences
[i
] = GL_TRUE
;
121 allResident
= GL_FALSE
;
122 for (j
= 0; j
< i
; j
++)
123 residences
[j
] = GL_TRUE
;
125 residences
[i
] = GL_FALSE
;
134 * Request that a set of programs be resident in hardware.
135 * \note Called from the GL API dispatcher.
138 _mesa_RequestResidentProgramsNV(GLsizei n
, const GLuint
*ids
)
141 GET_CURRENT_CONTEXT(ctx
);
142 ASSERT_OUTSIDE_BEGIN_END(ctx
);
145 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(n)");
149 /* just error checking for now */
150 for (i
= 0; i
< n
; i
++) {
151 struct gl_program
*prog
;
154 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(id)");
158 prog
= _mesa_lookup_program(ctx
, ids
[i
]);
160 _mesa_error(ctx
, GL_INVALID_VALUE
, "glRequestResidentProgramsNV(id)");
164 /* XXX this is really a hardware thing we should hook out */
165 prog
->Resident
= GL_TRUE
;
171 * Get a program parameter register.
172 * \note Not compiled into display lists.
173 * \note Called from the GL API dispatcher.
176 _mesa_GetProgramParameterfvNV(GLenum target
, GLuint index
,
177 GLenum pname
, GLfloat
*params
)
179 GET_CURRENT_CONTEXT(ctx
);
180 ASSERT_OUTSIDE_BEGIN_END(ctx
);
182 if (target
== GL_VERTEX_PROGRAM_NV
) {
183 if (pname
== GL_PROGRAM_PARAMETER_NV
) {
184 if (index
< MAX_NV_VERTEX_PROGRAM_PARAMS
) {
185 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
188 _mesa_error(ctx
, GL_INVALID_VALUE
,
189 "glGetProgramParameterfvNV(index)");
194 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterfvNV(pname)");
199 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterfvNV(target)");
206 * Get a program parameter register.
207 * \note Not compiled into display lists.
208 * \note Called from the GL API dispatcher.
211 _mesa_GetProgramParameterdvNV(GLenum target
, GLuint index
,
212 GLenum pname
, GLdouble
*params
)
214 GET_CURRENT_CONTEXT(ctx
);
215 ASSERT_OUTSIDE_BEGIN_END(ctx
);
217 if (target
== GL_VERTEX_PROGRAM_NV
) {
218 if (pname
== GL_PROGRAM_PARAMETER_NV
) {
219 if (index
< MAX_NV_VERTEX_PROGRAM_PARAMS
) {
220 COPY_4V(params
, ctx
->VertexProgram
.Parameters
[index
]);
223 _mesa_error(ctx
, GL_INVALID_VALUE
,
224 "glGetProgramParameterdvNV(index)");
229 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterdvNV(pname)");
234 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramParameterdvNV(target)");
241 * Get a program attribute.
242 * \note Not compiled into display lists.
243 * \note Called from the GL API dispatcher.
246 _mesa_GetProgramivNV(GLuint id
, GLenum pname
, GLint
*params
)
248 struct gl_program
*prog
;
249 GET_CURRENT_CONTEXT(ctx
);
251 ASSERT_OUTSIDE_BEGIN_END(ctx
);
253 prog
= _mesa_lookup_program(ctx
, id
);
255 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramivNV");
260 case GL_PROGRAM_TARGET_NV
:
261 *params
= prog
->Target
;
263 case GL_PROGRAM_LENGTH_NV
:
264 *params
= prog
->String
?(GLint
) strlen((char *) prog
->String
) : 0;
266 case GL_PROGRAM_RESIDENT_NV
:
267 *params
= prog
->Resident
;
270 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivNV(pname)");
277 * Get the program source code.
278 * \note Not compiled into display lists.
279 * \note Called from the GL API dispatcher.
282 _mesa_GetProgramStringNV(GLuint id
, GLenum pname
, GLubyte
*program
)
284 struct gl_program
*prog
;
285 GET_CURRENT_CONTEXT(ctx
);
287 ASSERT_OUTSIDE_BEGIN_END(ctx
);
289 if (pname
!= GL_PROGRAM_STRING_NV
) {
290 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringNV(pname)");
294 prog
= _mesa_lookup_program(ctx
, id
);
296 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramStringNV");
301 memcpy(program
, prog
->String
, strlen((char *) prog
->String
));
310 * Get matrix tracking information.
311 * \note Not compiled into display lists.
312 * \note Called from the GL API dispatcher.
315 _mesa_GetTrackMatrixivNV(GLenum target
, GLuint address
,
316 GLenum pname
, GLint
*params
)
318 GET_CURRENT_CONTEXT(ctx
);
319 ASSERT_OUTSIDE_BEGIN_END(ctx
);
321 if (target
== GL_VERTEX_PROGRAM_NV
322 && ctx
->Extensions
.NV_vertex_program
) {
325 if ((address
& 0x3) || address
>= MAX_NV_VERTEX_PROGRAM_PARAMS
) {
326 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetTrackMatrixivNV(address)");
333 case GL_TRACK_MATRIX_NV
:
334 params
[0] = (GLint
) ctx
->VertexProgram
.TrackMatrix
[i
];
336 case GL_TRACK_MATRIX_TRANSFORM_NV
:
337 params
[0] = (GLint
) ctx
->VertexProgram
.TrackMatrixTransform
[i
];
340 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTrackMatrixivNV");
345 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetTrackMatrixivNV");
352 * Get a vertex (or vertex array) attribute.
353 * \note Not compiled into display lists.
354 * \note Called from the GL API dispatcher.
357 _mesa_GetVertexAttribdvNV(GLuint index
, GLenum pname
, GLdouble
*params
)
359 const struct gl_client_array
*array
;
360 GET_CURRENT_CONTEXT(ctx
);
361 ASSERT_OUTSIDE_BEGIN_END(ctx
);
363 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
364 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
368 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[VERT_ATTRIB_GENERIC(index
)];
371 case GL_ATTRIB_ARRAY_SIZE_NV
:
372 params
[0] = array
->Size
;
374 case GL_ATTRIB_ARRAY_STRIDE_NV
:
375 params
[0] = array
->Stride
;
377 case GL_ATTRIB_ARRAY_TYPE_NV
:
378 params
[0] = array
->Type
;
380 case GL_CURRENT_ATTRIB_NV
:
382 _mesa_error(ctx
, GL_INVALID_OPERATION
,
383 "glGetVertexAttribdvNV(index == 0)");
386 FLUSH_CURRENT(ctx
, 0);
387 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
390 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
396 * Get a vertex (or vertex array) attribute.
397 * \note Not compiled into display lists.
398 * \note Called from the GL API dispatcher.
401 _mesa_GetVertexAttribfvNV(GLuint index
, GLenum pname
, GLfloat
*params
)
403 const struct gl_client_array
*array
;
404 GET_CURRENT_CONTEXT(ctx
);
405 ASSERT_OUTSIDE_BEGIN_END(ctx
);
407 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
408 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
412 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[VERT_ATTRIB_GENERIC(index
)];
415 case GL_ATTRIB_ARRAY_SIZE_NV
:
416 params
[0] = (GLfloat
) array
->Size
;
418 case GL_ATTRIB_ARRAY_STRIDE_NV
:
419 params
[0] = (GLfloat
) array
->Stride
;
421 case GL_ATTRIB_ARRAY_TYPE_NV
:
422 params
[0] = (GLfloat
) array
->Type
;
424 case GL_CURRENT_ATTRIB_NV
:
426 _mesa_error(ctx
, GL_INVALID_OPERATION
,
427 "glGetVertexAttribfvNV(index == 0)");
430 FLUSH_CURRENT(ctx
, 0);
431 COPY_4V(params
, ctx
->Current
.Attrib
[index
]);
434 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
440 * Get a vertex (or vertex array) attribute.
441 * \note Not compiled into display lists.
442 * \note Called from the GL API dispatcher.
445 _mesa_GetVertexAttribivNV(GLuint index
, GLenum pname
, GLint
*params
)
447 const struct gl_client_array
*array
;
448 GET_CURRENT_CONTEXT(ctx
);
449 ASSERT_OUTSIDE_BEGIN_END(ctx
);
451 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
452 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribdvNV(index)");
456 array
= &ctx
->Array
.ArrayObj
->VertexAttrib
[VERT_ATTRIB_GENERIC(index
)];
459 case GL_ATTRIB_ARRAY_SIZE_NV
:
460 params
[0] = array
->Size
;
462 case GL_ATTRIB_ARRAY_STRIDE_NV
:
463 params
[0] = array
->Stride
;
465 case GL_ATTRIB_ARRAY_TYPE_NV
:
466 params
[0] = array
->Type
;
468 case GL_CURRENT_ATTRIB_NV
:
470 _mesa_error(ctx
, GL_INVALID_OPERATION
,
471 "glGetVertexAttribivNV(index == 0)");
474 FLUSH_CURRENT(ctx
, 0);
475 params
[0] = (GLint
) ctx
->Current
.Attrib
[index
][0];
476 params
[1] = (GLint
) ctx
->Current
.Attrib
[index
][1];
477 params
[2] = (GLint
) ctx
->Current
.Attrib
[index
][2];
478 params
[3] = (GLint
) ctx
->Current
.Attrib
[index
][3];
480 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB
:
481 params
[0] = array
->BufferObj
->Name
;
484 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribdvNV");
491 * Get a vertex array attribute pointer.
492 * \note Not compiled into display lists.
493 * \note Called from the GL API dispatcher.
496 _mesa_GetVertexAttribPointervNV(GLuint index
, GLenum pname
, GLvoid
**pointer
)
498 GET_CURRENT_CONTEXT(ctx
);
499 ASSERT_OUTSIDE_BEGIN_END(ctx
);
501 if (index
>= MAX_NV_VERTEX_PROGRAM_INPUTS
) {
502 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetVertexAttribPointerNV(index)");
506 if (pname
!= GL_ATTRIB_ARRAY_POINTER_NV
) {
507 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetVertexAttribPointerNV(pname)");
511 *pointer
= (GLvoid
*) ctx
->Array
.ArrayObj
->VertexAttrib
[VERT_ATTRIB_GENERIC(index
)].Ptr
;
515 _mesa_emit_nv_temp_initialization(struct gl_context
*ctx
,
516 struct gl_program
*program
)
518 struct prog_instruction
*inst
;
520 struct gl_shader_compiler_options
* options
=
521 &ctx
->ShaderCompilerOptions
[_mesa_program_target_to_index(program
->Target
)];
523 if (!options
->EmitNVTempInitialization
)
526 /* We'll swizzle up a zero temporary so we can use it for the
529 if (program
->NumTemporaries
== 0)
530 program
->NumTemporaries
= 1;
532 _mesa_insert_instructions(program
, 0, program
->NumTemporaries
+ 1);
534 for (i
= 0; i
< program
->NumTemporaries
; i
++) {
535 struct prog_instruction
*inst
= &program
->Instructions
[i
];
537 inst
->Opcode
= OPCODE_SWZ
;
538 inst
->DstReg
.File
= PROGRAM_TEMPORARY
;
539 inst
->DstReg
.Index
= i
;
540 inst
->DstReg
.WriteMask
= WRITEMASK_XYZW
;
541 inst
->SrcReg
[0].File
= PROGRAM_TEMPORARY
;
542 inst
->SrcReg
[0].Index
= 0;
543 inst
->SrcReg
[0].Swizzle
= MAKE_SWIZZLE4(SWIZZLE_ZERO
,
549 inst
= &program
->Instructions
[i
];
550 inst
->Opcode
= OPCODE_ARL
;
551 inst
->DstReg
.File
= PROGRAM_ADDRESS
;
552 inst
->DstReg
.Index
= 0;
553 inst
->DstReg
.WriteMask
= WRITEMASK_XYZW
;
554 inst
->SrcReg
[0].File
= PROGRAM_TEMPORARY
;
555 inst
->SrcReg
[0].Index
= 0;
556 inst
->SrcReg
[0].Swizzle
= SWIZZLE_XXXX
;
558 if (program
->NumAddressRegs
== 0)
559 program
->NumAddressRegs
= 1;
563 _mesa_setup_nv_temporary_count(struct gl_program
*program
)
567 program
->NumTemporaries
= 0;
568 for (i
= 0; i
< program
->NumInstructions
; i
++) {
569 struct prog_instruction
*inst
= &program
->Instructions
[i
];
571 if (inst
->DstReg
.File
== PROGRAM_TEMPORARY
) {
572 program
->NumTemporaries
= MAX2(program
->NumTemporaries
,
573 inst
->DstReg
.Index
+ 1);
575 if (inst
->SrcReg
[0].File
== PROGRAM_TEMPORARY
) {
576 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
577 inst
->SrcReg
[0].Index
+ 1);
579 if (inst
->SrcReg
[1].File
== PROGRAM_TEMPORARY
) {
580 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
581 inst
->SrcReg
[1].Index
+ 1);
583 if (inst
->SrcReg
[2].File
== PROGRAM_TEMPORARY
) {
584 program
->NumTemporaries
= MAX2((GLint
)program
->NumTemporaries
,
585 inst
->SrcReg
[2].Index
+ 1);
591 * Load/parse/compile a program.
592 * \note Called from the GL API dispatcher.
595 _mesa_LoadProgramNV(GLenum target
, GLuint id
, GLsizei len
,
596 const GLubyte
*program
)
598 struct gl_program
*prog
;
599 GET_CURRENT_CONTEXT(ctx
);
600 ASSERT_OUTSIDE_BEGIN_END(ctx
);
602 if (!ctx
->Extensions
.NV_vertex_program
603 && !ctx
->Extensions
.NV_fragment_program
) {
604 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glLoadProgramNV()");
609 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLoadProgramNV(id)");
614 _mesa_error(ctx
, GL_INVALID_VALUE
, "glLoadProgramNV(len)");
618 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
620 prog
= _mesa_lookup_program(ctx
, id
);
622 if (prog
&& prog
->Target
!= 0 && prog
->Target
!= target
) {
623 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glLoadProgramNV(target)");
627 if ((target
== GL_VERTEX_PROGRAM_NV
||
628 target
== GL_VERTEX_STATE_PROGRAM_NV
)
629 && ctx
->Extensions
.NV_vertex_program
) {
630 struct gl_vertex_program
*vprog
= (struct gl_vertex_program
*) prog
;
631 if (!vprog
|| prog
== &_mesa_DummyProgram
) {
632 vprog
= (struct gl_vertex_program
*)
633 ctx
->Driver
.NewProgram(ctx
, target
, id
);
635 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
638 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, vprog
);
641 if (ctx
->Extensions
.ARB_vertex_program
642 && (strncmp((char *) program
, "!!ARB", 5) == 0)) {
643 _mesa_parse_arb_vertex_program(ctx
, target
, program
, len
, vprog
);
645 _mesa_parse_nv_vertex_program(ctx
, target
, program
, len
, vprog
);
648 else if (target
== GL_FRAGMENT_PROGRAM_NV
649 && ctx
->Extensions
.NV_fragment_program
) {
650 struct gl_fragment_program
*fprog
= (struct gl_fragment_program
*) prog
;
651 if (!fprog
|| prog
== &_mesa_DummyProgram
) {
652 fprog
= (struct gl_fragment_program
*)
653 ctx
->Driver
.NewProgram(ctx
, target
, id
);
655 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
658 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, fprog
);
660 _mesa_parse_nv_fragment_program(ctx
, target
, program
, len
, fprog
);
662 else if (target
== GL_FRAGMENT_PROGRAM_ARB
663 && ctx
->Extensions
.ARB_fragment_program
) {
664 struct gl_fragment_program
*fprog
= (struct gl_fragment_program
*) prog
;
665 if (!fprog
|| prog
== &_mesa_DummyProgram
) {
666 fprog
= (struct gl_fragment_program
*)
667 ctx
->Driver
.NewProgram(ctx
, target
, id
);
669 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glLoadProgramNV");
672 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, fprog
);
674 _mesa_parse_arb_fragment_program(ctx
, target
, program
, len
, fprog
);
677 _mesa_error(ctx
, GL_INVALID_ENUM
, "glLoadProgramNV(target)");
684 * Set a sequence of program parameter registers.
685 * \note Called from the GL API dispatcher.
688 _mesa_ProgramParameters4dvNV(GLenum target
, GLuint index
,
689 GLsizei num
, const GLdouble
*params
)
691 GET_CURRENT_CONTEXT(ctx
);
692 ASSERT_OUTSIDE_BEGIN_END(ctx
);
694 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
696 if (index
+ num
> MAX_NV_VERTEX_PROGRAM_PARAMS
) {
697 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramParameters4dvNV");
700 for (i
= 0; i
< num
; i
++) {
701 ctx
->VertexProgram
.Parameters
[index
+ i
][0] = (GLfloat
) params
[0];
702 ctx
->VertexProgram
.Parameters
[index
+ i
][1] = (GLfloat
) params
[1];
703 ctx
->VertexProgram
.Parameters
[index
+ i
][2] = (GLfloat
) params
[2];
704 ctx
->VertexProgram
.Parameters
[index
+ i
][3] = (GLfloat
) params
[3];
709 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramParameters4dvNV");
716 * Set a sequence of program parameter registers.
717 * \note Called from the GL API dispatcher.
720 _mesa_ProgramParameters4fvNV(GLenum target
, GLuint index
,
721 GLsizei num
, const GLfloat
*params
)
723 GET_CURRENT_CONTEXT(ctx
);
724 ASSERT_OUTSIDE_BEGIN_END(ctx
);
726 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
728 if (index
+ num
> MAX_NV_VERTEX_PROGRAM_PARAMS
) {
729 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramParameters4fvNV");
732 for (i
= 0; i
< num
; i
++) {
733 COPY_4V(ctx
->VertexProgram
.Parameters
[index
+ i
], params
);
738 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramParameters4fvNV");
746 * Setup tracking of matrices into program parameter registers.
747 * \note Called from the GL API dispatcher.
750 _mesa_TrackMatrixNV(GLenum target
, GLuint address
,
751 GLenum matrix
, GLenum transform
)
753 GET_CURRENT_CONTEXT(ctx
);
754 ASSERT_OUTSIDE_BEGIN_END(ctx
);
756 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
758 if (target
== GL_VERTEX_PROGRAM_NV
&& ctx
->Extensions
.NV_vertex_program
) {
760 /* addr must be multiple of four */
761 _mesa_error(ctx
, GL_INVALID_VALUE
, "glTrackMatrixNV(address)");
771 case GL_MODELVIEW_PROJECTION_NV
:
780 /* OK, fallthrough */
783 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(matrix)");
790 case GL_TRANSPOSE_NV
:
791 case GL_INVERSE_TRANSPOSE_NV
:
792 /* OK, fallthrough */
795 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(transform)");
799 ctx
->VertexProgram
.TrackMatrix
[address
/ 4] = matrix
;
800 ctx
->VertexProgram
.TrackMatrixTransform
[address
/ 4] = transform
;
803 _mesa_error(ctx
, GL_INVALID_ENUM
, "glTrackMatrixNV(target)");
810 _mesa_ProgramNamedParameter4fNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
811 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
813 struct gl_program
*prog
;
814 struct gl_fragment_program
*fragProg
;
815 gl_constant_value
*v
;
817 GET_CURRENT_CONTEXT(ctx
);
818 ASSERT_OUTSIDE_BEGIN_END(ctx
);
820 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
822 prog
= _mesa_lookup_program(ctx
, id
);
823 if (!prog
|| prog
->Target
!= GL_FRAGMENT_PROGRAM_NV
) {
824 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glProgramNamedParameterNV");
829 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramNamedParameterNV(len)");
833 fragProg
= (struct gl_fragment_program
*) prog
;
834 v
= _mesa_lookup_parameter_value(fragProg
->Base
.Parameters
, len
,
844 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramNamedParameterNV(name)");
849 _mesa_ProgramNamedParameter4fvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
852 _mesa_ProgramNamedParameter4fNV(id
, len
, name
, v
[0], v
[1], v
[2], v
[3]);
857 _mesa_ProgramNamedParameter4dNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
858 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
860 _mesa_ProgramNamedParameter4fNV(id
, len
, name
, (GLfloat
)x
, (GLfloat
)y
,
861 (GLfloat
)z
, (GLfloat
)w
);
866 _mesa_ProgramNamedParameter4dvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
869 _mesa_ProgramNamedParameter4fNV(id
, len
, name
,
870 (GLfloat
)v
[0], (GLfloat
)v
[1],
871 (GLfloat
)v
[2], (GLfloat
)v
[3]);
876 _mesa_GetProgramNamedParameterfvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
879 struct gl_program
*prog
;
880 struct gl_fragment_program
*fragProg
;
881 const gl_constant_value
*v
;
883 GET_CURRENT_CONTEXT(ctx
);
885 ASSERT_OUTSIDE_BEGIN_END(ctx
);
887 prog
= _mesa_lookup_program(ctx
, id
);
888 if (!prog
|| prog
->Target
!= GL_FRAGMENT_PROGRAM_NV
) {
889 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramNamedParameterNV");
894 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramNamedParameterNV");
898 fragProg
= (struct gl_fragment_program
*) prog
;
899 v
= _mesa_lookup_parameter_value(fragProg
->Base
.Parameters
,
909 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramNamedParameterNV");
914 _mesa_GetProgramNamedParameterdvNV(GLuint id
, GLsizei len
, const GLubyte
*name
,
917 GLfloat floatParams
[4];
918 _mesa_GetProgramNamedParameterfvNV(id
, len
, name
, floatParams
);
919 COPY_4V(params
, floatParams
);