2 * Mesa 3-D graphics library
4 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
27 * ARB_vertex/fragment_program state management functions.
32 #include "main/glheader.h"
33 #include "main/context.h"
34 #include "main/hash.h"
35 #include "main/imports.h"
36 #include "main/macros.h"
37 #include "main/mtypes.h"
38 #include "main/arbprogram.h"
39 #include "main/shaderapi.h"
40 #include "main/state.h"
41 #include "program/arbprogparse.h"
42 #include "program/program.h"
43 #include "program/prog_print.h"
46 flush_vertices_for_program_constants(struct gl_context
*ctx
, GLenum target
)
48 uint64_t new_driver_state
;
50 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
52 ctx
->DriverFlags
.NewShaderConstants
[MESA_SHADER_FRAGMENT
];
55 ctx
->DriverFlags
.NewShaderConstants
[MESA_SHADER_VERTEX
];
58 FLUSH_VERTICES(ctx
, new_driver_state
? 0 : _NEW_PROGRAM_CONSTANTS
);
59 ctx
->NewDriverState
|= new_driver_state
;
62 static struct gl_program
*
63 lookup_or_create_program(GLuint id
, GLenum target
, const char* caller
)
65 GET_CURRENT_CONTEXT(ctx
);
66 struct gl_program
* newProg
;
69 /* Bind a default program */
70 if (target
== GL_VERTEX_PROGRAM_ARB
)
71 newProg
= ctx
->Shared
->DefaultVertexProgram
;
73 newProg
= ctx
->Shared
->DefaultFragmentProgram
;
76 /* Bind a user program */
77 newProg
= _mesa_lookup_program(ctx
, id
);
78 if (!newProg
|| newProg
== &_mesa_DummyProgram
) {
79 /* allocate a new program now */
80 newProg
= ctx
->Driver
.NewProgram(ctx
, target
, id
, true);
82 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "%s", caller
);
85 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, newProg
);
87 else if (newProg
->Target
!= target
) {
88 _mesa_error(ctx
, GL_INVALID_OPERATION
,
89 "%s(target mismatch)", caller
);
97 * Bind a program (make it current)
98 * \note Called from the GL API dispatcher by both glBindProgramNV
99 * and glBindProgramARB.
102 _mesa_BindProgramARB(GLenum target
, GLuint id
)
104 struct gl_program
*curProg
, *newProg
;
105 GET_CURRENT_CONTEXT(ctx
);
107 /* Error-check target and get curProg */
108 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
109 curProg
= ctx
->VertexProgram
.Current
;
111 else if (target
== GL_FRAGMENT_PROGRAM_ARB
112 && ctx
->Extensions
.ARB_fragment_program
) {
113 curProg
= ctx
->FragmentProgram
.Current
;
116 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBindProgramARB(target)");
121 * Get pointer to new program to bind.
122 * NOTE: binding to a non-existant program is not an error.
123 * That's supposed to be caught in glBegin.
125 newProg
= lookup_or_create_program(id
, target
, "glBindProgram");
129 /** All error checking is complete now **/
131 if (curProg
->Id
== id
) {
132 /* binding same program - no change */
136 /* signal new program (and its new constants) */
137 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
138 flush_vertices_for_program_constants(ctx
, target
);
141 if (target
== GL_VERTEX_PROGRAM_ARB
) {
142 _mesa_reference_program(ctx
, &ctx
->VertexProgram
.Current
, newProg
);
144 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
145 _mesa_reference_program(ctx
, &ctx
->FragmentProgram
.Current
, newProg
);
148 _mesa_update_vertex_processing_mode(ctx
);
150 /* Never null pointers */
151 assert(ctx
->VertexProgram
.Current
);
152 assert(ctx
->FragmentProgram
.Current
);
157 * Delete a list of programs.
158 * \note Not compiled into display lists.
159 * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
162 _mesa_DeleteProgramsARB(GLsizei n
, const GLuint
*ids
)
165 GET_CURRENT_CONTEXT(ctx
);
167 FLUSH_VERTICES(ctx
, 0);
170 _mesa_error( ctx
, GL_INVALID_VALUE
, "glDeleteProgramsNV" );
174 for (i
= 0; i
< n
; i
++) {
176 struct gl_program
*prog
= _mesa_lookup_program(ctx
, ids
[i
]);
177 if (prog
== &_mesa_DummyProgram
) {
178 _mesa_HashRemove(ctx
->Shared
->Programs
, ids
[i
]);
181 /* Unbind program if necessary */
182 switch (prog
->Target
) {
183 case GL_VERTEX_PROGRAM_ARB
:
184 if (ctx
->VertexProgram
.Current
&&
185 ctx
->VertexProgram
.Current
->Id
== ids
[i
]) {
186 /* unbind this currently bound program */
187 _mesa_BindProgramARB(prog
->Target
, 0);
190 case GL_FRAGMENT_PROGRAM_ARB
:
191 if (ctx
->FragmentProgram
.Current
&&
192 ctx
->FragmentProgram
.Current
->Id
== ids
[i
]) {
193 /* unbind this currently bound program */
194 _mesa_BindProgramARB(prog
->Target
, 0);
198 _mesa_problem(ctx
, "bad target in glDeleteProgramsNV");
201 /* The ID is immediately available for re-use now */
202 _mesa_HashRemove(ctx
->Shared
->Programs
, ids
[i
]);
203 _mesa_reference_program(ctx
, &prog
, NULL
);
211 * Generate a list of new program identifiers.
212 * \note Not compiled into display lists.
213 * \note Called by both glGenProgramsNV and glGenProgramsARB.
216 _mesa_GenProgramsARB(GLsizei n
, GLuint
*ids
)
220 GET_CURRENT_CONTEXT(ctx
);
223 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGenPrograms");
230 _mesa_HashLockMutex(ctx
->Shared
->Programs
);
232 first
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->Programs
, n
);
234 /* Insert pointer to dummy program as placeholder */
235 for (i
= 0; i
< (GLuint
) n
; i
++) {
236 _mesa_HashInsertLocked(ctx
->Shared
->Programs
, first
+ i
,
237 &_mesa_DummyProgram
);
240 _mesa_HashUnlockMutex(ctx
->Shared
->Programs
);
242 /* Return the program names */
243 for (i
= 0; i
< (GLuint
) n
; i
++) {
250 * Determine if id names a vertex or fragment program.
251 * \note Not compiled into display lists.
252 * \note Called from both glIsProgramNV and glIsProgramARB.
253 * \param id is the program identifier
254 * \return GL_TRUE if id is a program, else GL_FALSE.
257 _mesa_IsProgramARB(GLuint id
)
259 struct gl_program
*prog
= NULL
;
260 GET_CURRENT_CONTEXT(ctx
);
261 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
266 prog
= _mesa_lookup_program(ctx
, id
);
267 if (prog
&& (prog
!= &_mesa_DummyProgram
))
273 static struct gl_program
*
274 get_current_program(struct gl_context
* ctx
, GLenum target
, const char* caller
)
276 if (target
== GL_VERTEX_PROGRAM_ARB
277 && ctx
->Extensions
.ARB_vertex_program
) {
278 return ctx
->VertexProgram
.Current
;
280 else if (target
== GL_FRAGMENT_PROGRAM_ARB
281 && ctx
->Extensions
.ARB_fragment_program
) {
282 return ctx
->FragmentProgram
.Current
;
285 _mesa_error(ctx
, GL_INVALID_ENUM
,
286 "%s(target)", caller
);
292 get_local_param_pointer(struct gl_context
*ctx
, const char *func
,
293 struct gl_program
* prog
, GLenum target
,
294 GLuint index
, GLfloat
**param
)
298 if (target
== GL_VERTEX_PROGRAM_ARB
) {
299 maxParams
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxLocalParams
;
301 maxParams
= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxLocalParams
;
304 if (index
>= maxParams
) {
305 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
309 if (!prog
->arb
.LocalParams
) {
310 prog
->arb
.LocalParams
= rzalloc_array_size(prog
, sizeof(float[4]),
312 if (!prog
->arb
.LocalParams
)
316 *param
= prog
->arb
.LocalParams
[index
];
322 get_env_param_pointer(struct gl_context
*ctx
, const char *func
,
323 GLenum target
, GLuint index
, GLfloat
**param
)
325 if (target
== GL_FRAGMENT_PROGRAM_ARB
326 && ctx
->Extensions
.ARB_fragment_program
) {
327 if (index
>= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxEnvParams
) {
328 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
331 *param
= ctx
->FragmentProgram
.Parameters
[index
];
334 else if (target
== GL_VERTEX_PROGRAM_ARB
&&
335 ctx
->Extensions
.ARB_vertex_program
) {
336 if (index
>= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxEnvParams
) {
337 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
340 *param
= ctx
->VertexProgram
.Parameters
[index
];
343 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(target)", func
);
349 set_program_string(struct gl_program
*prog
, GLenum target
, GLenum format
, GLsizei len
,
350 const GLvoid
*string
)
353 GET_CURRENT_CONTEXT(ctx
);
355 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
357 if (!ctx
->Extensions
.ARB_vertex_program
358 && !ctx
->Extensions
.ARB_fragment_program
) {
359 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glProgramStringARB()");
363 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
364 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
368 #ifdef ENABLE_SHADER_CACHE
369 GLcharARB
*replacement
;
371 gl_shader_stage stage
= _mesa_program_enum_to_shader_stage(target
);
373 /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
374 * if corresponding entry found from MESA_SHADER_READ_PATH.
376 _mesa_dump_shader_source(stage
, string
);
378 replacement
= _mesa_read_shader_source(stage
, string
);
380 string
= replacement
;
381 #endif /* ENABLE_SHADER_CACHE */
383 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
384 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
386 else if (target
== GL_FRAGMENT_PROGRAM_ARB
387 && ctx
->Extensions
.ARB_fragment_program
) {
388 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
391 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
395 failed
= ctx
->Program
.ErrorPos
!= -1;
398 /* finally, give the program to the driver for translation/checking */
399 if (!ctx
->Driver
.ProgramStringNotify(ctx
, target
, prog
)) {
401 _mesa_error(ctx
, GL_INVALID_OPERATION
,
402 "glProgramStringARB(rejected by driver");
406 _mesa_update_vertex_processing_mode(ctx
);
408 if (ctx
->_Shader
->Flags
& GLSL_DUMP
) {
409 const char *shader_type
=
410 target
== GL_FRAGMENT_PROGRAM_ARB
? "fragment" : "vertex";
412 fprintf(stderr
, "ARB_%s_program source for program %d:\n",
413 shader_type
, prog
->Id
);
414 fprintf(stderr
, "%s\n", (const char *) string
);
417 fprintf(stderr
, "ARB_%s_program %d failed to compile.\n",
418 shader_type
, prog
->Id
);
420 fprintf(stderr
, "Mesa IR for ARB_%s_program %d:\n",
421 shader_type
, prog
->Id
);
422 _mesa_print_program(prog
);
423 fprintf(stderr
, "\n");
428 /* Capture vp-*.shader_test/fp-*.shader_test files. */
429 const char *capture_path
= _mesa_get_shader_capture_path();
430 if (capture_path
!= NULL
) {
432 const char *shader_type
=
433 target
== GL_FRAGMENT_PROGRAM_ARB
? "fragment" : "vertex";
435 ralloc_asprintf(NULL
, "%s/%cp-%u.shader_test",
436 capture_path
, shader_type
[0], prog
->Id
);
438 file
= fopen(filename
, "w");
441 "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n",
442 shader_type
, shader_type
, (const char *) string
);
445 _mesa_warning(ctx
, "Failed to open %s", filename
);
447 ralloc_free(filename
);
452 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
453 const GLvoid
*string
)
455 GET_CURRENT_CONTEXT(ctx
);
456 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
457 set_program_string(ctx
->VertexProgram
.Current
, target
, format
, len
, string
);
459 else if (target
== GL_FRAGMENT_PROGRAM_ARB
460 && ctx
->Extensions
.ARB_fragment_program
) {
461 set_program_string(ctx
->FragmentProgram
.Current
, target
, format
, len
, string
);
464 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
470 _mesa_NamedProgramStringEXT(GLuint program
, GLenum target
, GLenum format
, GLsizei len
,
471 const GLvoid
*string
)
473 struct gl_program
* prog
= lookup_or_create_program(program
, target
, "glNamedProgramStringEXT");
478 set_program_string(prog
, target
, format
, len
, string
);
483 * Set a program env parameter register.
484 * \note Called from the GL API dispatcher.
487 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
488 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
490 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
491 (GLfloat
) z
, (GLfloat
) w
);
496 * Set a program env parameter register.
497 * \note Called from the GL API dispatcher.
500 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
501 const GLdouble
*params
)
503 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
504 (GLfloat
) params
[1], (GLfloat
) params
[2],
505 (GLfloat
) params
[3]);
510 * Set a program env parameter register.
511 * \note Called from the GL API dispatcher.
514 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
515 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
519 GET_CURRENT_CONTEXT(ctx
);
521 flush_vertices_for_program_constants(ctx
, target
);
523 if (get_env_param_pointer(ctx
, "glProgramEnvParameter",
524 target
, index
, ¶m
)) {
525 ASSIGN_4V(param
, x
, y
, z
, w
);
532 * Set a program env parameter register.
533 * \note Called from the GL API dispatcher.
536 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
537 const GLfloat
*params
)
541 GET_CURRENT_CONTEXT(ctx
);
543 flush_vertices_for_program_constants(ctx
, target
);
545 if (get_env_param_pointer(ctx
, "glProgramEnvParameter4fv",
546 target
, index
, ¶m
)) {
547 memcpy(param
, params
, 4 * sizeof(GLfloat
));
553 _mesa_ProgramEnvParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
554 const GLfloat
*params
)
556 GET_CURRENT_CONTEXT(ctx
);
559 flush_vertices_for_program_constants(ctx
, target
);
562 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(count)");
565 if (target
== GL_FRAGMENT_PROGRAM_ARB
566 && ctx
->Extensions
.ARB_fragment_program
) {
567 if ((index
+ count
) > ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxEnvParams
) {
568 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
571 dest
= ctx
->FragmentProgram
.Parameters
[index
];
573 else if (target
== GL_VERTEX_PROGRAM_ARB
574 && ctx
->Extensions
.ARB_vertex_program
) {
575 if ((index
+ count
) > ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxEnvParams
) {
576 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
579 dest
= ctx
->VertexProgram
.Parameters
[index
];
582 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameters4fv(target)");
586 memcpy(dest
, params
, count
* 4 * sizeof(GLfloat
));
591 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
594 GET_CURRENT_CONTEXT(ctx
);
597 if (get_env_param_pointer(ctx
, "glGetProgramEnvParameterdv",
598 target
, index
, &fparam
)) {
599 COPY_4V(params
, fparam
);
605 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
610 GET_CURRENT_CONTEXT(ctx
);
612 if (get_env_param_pointer(ctx
, "glGetProgramEnvParameterfv",
613 target
, index
, ¶m
)) {
614 COPY_4V(params
, param
);
620 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
621 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
623 GET_CURRENT_CONTEXT(ctx
);
625 struct gl_program
* prog
= get_current_program(ctx
, target
, "glProgramLocalParameterARB");
630 flush_vertices_for_program_constants(ctx
, target
);
632 if (get_local_param_pointer(ctx
, "glProgramLocalParameterARB",
633 prog
, target
, index
, ¶m
)) {
634 assert(index
< MAX_PROGRAM_LOCAL_PARAMS
);
635 ASSIGN_4V(param
, x
, y
, z
, w
);
640 _mesa_NamedProgramLocalParameter4fEXT(GLuint program
, GLenum target
, GLuint index
,
641 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
643 GET_CURRENT_CONTEXT(ctx
);
645 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
646 "glNamedProgramLocalParameter4fEXT");
652 if ((target
== GL_VERTEX_PROGRAM_ARB
&& prog
== ctx
->VertexProgram
.Current
) ||
653 (target
== GL_FRAGMENT_PROGRAM_ARB
&& prog
== ctx
->FragmentProgram
.Current
)) {
654 flush_vertices_for_program_constants(ctx
, target
);
657 if (get_local_param_pointer(ctx
, "glNamedProgramLocalParameter4fEXT",
658 prog
, target
, index
, ¶m
)) {
659 assert(index
< MAX_PROGRAM_LOCAL_PARAMS
);
660 ASSIGN_4V(param
, x
, y
, z
, w
);
666 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
667 const GLfloat
*params
)
669 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
670 params
[2], params
[3]);
675 _mesa_NamedProgramLocalParameter4fvEXT(GLuint program
, GLenum target
, GLuint index
,
676 const GLfloat
*params
)
678 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
, params
[0],
679 params
[1], params
[2], params
[3]);
684 program_local_parameters4fv(struct gl_program
* prog
, GLuint index
, GLsizei count
,
685 const GLfloat
*params
, const char* caller
)
687 GET_CURRENT_CONTEXT(ctx
);
689 flush_vertices_for_program_constants(ctx
, prog
->Target
);
692 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(count)", caller
);
695 if (get_local_param_pointer(ctx
, caller
,
696 prog
, prog
->Target
, index
, &dest
)) {
697 GLuint maxParams
= prog
->Target
== GL_FRAGMENT_PROGRAM_ARB
?
698 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxLocalParams
:
699 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxLocalParams
;
701 if ((index
+ count
) > maxParams
) {
702 _mesa_error(ctx
, GL_INVALID_VALUE
,
708 memcpy(dest
, params
, count
* 4 * sizeof(GLfloat
));
714 _mesa_ProgramLocalParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
715 const GLfloat
*params
)
717 GET_CURRENT_CONTEXT(ctx
);
718 struct gl_program
* prog
= get_current_program(ctx
, target
,
719 "glProgramLocalParameters4fv");
724 program_local_parameters4fv(prog
, index
, count
, params
,
725 "glProgramLocalParameters4fv");
729 _mesa_NamedProgramLocalParameters4fvEXT(GLuint program
, GLenum target
, GLuint index
,
730 GLsizei count
, const GLfloat
*params
)
732 struct gl_program
* prog
=
733 lookup_or_create_program(program
, target
,
734 "glNamedProgramLocalParameters4fvEXT");
739 program_local_parameters4fv(prog
, index
, count
, params
,
740 "glNamedProgramLocalParameters4fvEXT");
745 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
746 GLdouble x
, GLdouble y
,
747 GLdouble z
, GLdouble w
)
749 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
750 (GLfloat
) z
, (GLfloat
) w
);
755 _mesa_NamedProgramLocalParameter4dEXT(GLuint program
, GLenum target
, GLuint index
,
756 GLdouble x
, GLdouble y
,
757 GLdouble z
, GLdouble w
)
759 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
, (GLfloat
) x
, (GLfloat
) y
,
760 (GLfloat
) z
, (GLfloat
) w
);
765 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
766 const GLdouble
*params
)
768 _mesa_ProgramLocalParameter4fARB(target
, index
,
769 (GLfloat
) params
[0], (GLfloat
) params
[1],
770 (GLfloat
) params
[2], (GLfloat
) params
[3]);
775 _mesa_NamedProgramLocalParameter4dvEXT(GLuint program
, GLenum target
, GLuint index
,
776 const GLdouble
*params
)
778 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
,
779 (GLfloat
) params
[0], (GLfloat
) params
[1],
780 (GLfloat
) params
[2], (GLfloat
) params
[3]);
785 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
789 GET_CURRENT_CONTEXT(ctx
);
790 struct gl_program
* prog
= get_current_program(ctx
, target
, "glGetProgramLocalParameterfvARB");
795 if (get_local_param_pointer(ctx
, "glProgramLocalParameters4fvEXT",
796 prog
, target
, index
, ¶m
)) {
797 COPY_4V(params
, param
);
803 _mesa_GetNamedProgramLocalParameterfvEXT(GLuint program
, GLenum target
, GLuint index
,
807 GET_CURRENT_CONTEXT(ctx
);
808 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
809 "glGetNamedProgramLocalParameterfvEXT");
814 if (get_local_param_pointer(ctx
, "glGetNamedProgramLocalParameterfvEXT",
815 prog
, target
, index
, ¶m
)) {
816 COPY_4V(params
, param
);
822 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
826 GET_CURRENT_CONTEXT(ctx
);
827 struct gl_program
* prog
= get_current_program(ctx
, target
, "glGetProgramLocalParameterdvARB");
832 if (get_local_param_pointer(ctx
, "glProgramLocalParameters4fvEXT",
833 prog
, target
, index
, ¶m
)) {
834 COPY_4V(params
, param
);
840 _mesa_GetNamedProgramLocalParameterdvEXT(GLuint program
, GLenum target
, GLuint index
,
844 GET_CURRENT_CONTEXT(ctx
);
845 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
846 "glGetNamedProgramLocalParameterdvEXT");
851 if (get_local_param_pointer(ctx
, "glGetNamedProgramLocalParameterdvEXT",
852 prog
, target
, index
, ¶m
)) {
853 COPY_4V(params
, param
);
859 get_program_iv(struct gl_program
*prog
, GLenum target
, GLenum pname
,
862 const struct gl_program_constants
*limits
;
864 GET_CURRENT_CONTEXT(ctx
);
866 if (target
== GL_VERTEX_PROGRAM_ARB
) {
867 limits
= &ctx
->Const
.Program
[MESA_SHADER_VERTEX
];
870 limits
= &ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
];
876 /* Queries supported for both vertex and fragment programs */
878 case GL_PROGRAM_LENGTH_ARB
:
880 = prog
->String
? (GLint
) strlen((char *) prog
->String
) : 0;
882 case GL_PROGRAM_FORMAT_ARB
:
883 *params
= prog
->Format
;
885 case GL_PROGRAM_BINDING_ARB
:
888 case GL_PROGRAM_INSTRUCTIONS_ARB
:
889 *params
= prog
->arb
.NumInstructions
;
891 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
892 *params
= limits
->MaxInstructions
;
894 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
895 *params
= prog
->arb
.NumNativeInstructions
;
897 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
898 *params
= limits
->MaxNativeInstructions
;
900 case GL_PROGRAM_TEMPORARIES_ARB
:
901 *params
= prog
->arb
.NumTemporaries
;
903 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
904 *params
= limits
->MaxTemps
;
906 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
907 *params
= prog
->arb
.NumNativeTemporaries
;
909 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
910 *params
= limits
->MaxNativeTemps
;
912 case GL_PROGRAM_PARAMETERS_ARB
:
913 *params
= prog
->arb
.NumParameters
;
915 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
916 *params
= limits
->MaxParameters
;
918 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
919 *params
= prog
->arb
.NumNativeParameters
;
921 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
922 *params
= limits
->MaxNativeParameters
;
924 case GL_PROGRAM_ATTRIBS_ARB
:
925 *params
= prog
->arb
.NumAttributes
;
927 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
928 *params
= limits
->MaxAttribs
;
930 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
931 *params
= prog
->arb
.NumNativeAttributes
;
933 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
934 *params
= limits
->MaxNativeAttribs
;
936 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
937 *params
= prog
->arb
.NumAddressRegs
;
939 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
940 *params
= limits
->MaxAddressRegs
;
942 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
943 *params
= prog
->arb
.NumNativeAddressRegs
;
945 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
946 *params
= limits
->MaxNativeAddressRegs
;
948 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
949 *params
= limits
->MaxLocalParams
;
951 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
952 *params
= limits
->MaxEnvParams
;
954 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
956 * XXX we may not really need a driver callback here.
957 * If the number of native instructions, registers, etc. used
958 * are all below the maximums, we could return true.
959 * The spec says that even if this query returns true, there's
960 * no guarantee that the program will run in hardware.
963 /* default/null program */
966 else if (ctx
->Driver
.IsProgramNative
) {
968 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
971 /* probably running in software */
976 /* continue with fragment-program only queries below */
981 * The following apply to fragment programs only (at this time)
983 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
984 const struct gl_program
*fp
= ctx
->FragmentProgram
.Current
;
986 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
987 *params
= fp
->arb
.NumNativeAluInstructions
;
989 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
990 *params
= fp
->arb
.NumAluInstructions
;
992 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
993 *params
= fp
->arb
.NumTexInstructions
;
995 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
996 *params
= fp
->arb
.NumNativeTexInstructions
;
998 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
999 *params
= fp
->arb
.NumTexIndirections
;
1001 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
1002 *params
= fp
->arb
.NumNativeTexIndirections
;
1004 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
1005 *params
= limits
->MaxAluInstructions
;
1007 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
1008 *params
= limits
->MaxNativeAluInstructions
;
1010 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
1011 *params
= limits
->MaxTexInstructions
;
1013 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
1014 *params
= limits
->MaxNativeTexInstructions
;
1016 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
1017 *params
= limits
->MaxTexIndirections
;
1019 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
1020 *params
= limits
->MaxNativeTexIndirections
;
1023 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
1027 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
1034 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
1036 GET_CURRENT_CONTEXT(ctx
);
1037 struct gl_program
* prog
= get_current_program(ctx
, target
,
1038 "glGetProgramivARB");
1042 get_program_iv(prog
, target
, pname
, params
);
1046 _mesa_GetNamedProgramivEXT(GLuint program
, GLenum target
, GLenum pname
,
1049 struct gl_program
* prog
;
1050 if (pname
== GL_PROGRAM_BINDING_ARB
) {
1051 _mesa_GetProgramivARB(target
, pname
, params
);
1054 prog
= lookup_or_create_program(program
, target
,
1055 "glGetNamedProgramivEXT");
1059 get_program_iv(prog
, target
, pname
, params
);
1064 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
1066 const struct gl_program
*prog
;
1067 char *dst
= (char *) string
;
1068 GET_CURRENT_CONTEXT(ctx
);
1070 if (target
== GL_VERTEX_PROGRAM_ARB
) {
1071 prog
= ctx
->VertexProgram
.Current
;
1073 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
1074 prog
= ctx
->FragmentProgram
.Current
;
1077 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
1083 if (pname
!= GL_PROGRAM_STRING_ARB
) {
1084 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
1089 memcpy(dst
, prog
->String
, strlen((char *) prog
->String
));
1096 _mesa_GetNamedProgramStringEXT(GLuint program
, GLenum target
,
1097 GLenum pname
, GLvoid
*string
) {
1098 char *dst
= (char *) string
;
1099 GET_CURRENT_CONTEXT(ctx
);
1100 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
1101 "glGetNamedProgramStringEXT");
1105 if (pname
!= GL_PROGRAM_STRING_ARB
) {
1106 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetNamedProgramStringEXT(pname)");
1111 memcpy(dst
, prog
->String
, strlen((char *) prog
->String
));