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"
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
, _mesa_program_enum_to_shader_stage(target
),
83 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "%s", caller
);
86 _mesa_HashInsert(ctx
->Shared
->Programs
, id
, newProg
);
88 else if (newProg
->Target
!= target
) {
89 _mesa_error(ctx
, GL_INVALID_OPERATION
,
90 "%s(target mismatch)", caller
);
98 * Bind a program (make it current)
99 * \note Called from the GL API dispatcher by both glBindProgramNV
100 * and glBindProgramARB.
103 _mesa_BindProgramARB(GLenum target
, GLuint id
)
105 struct gl_program
*curProg
, *newProg
;
106 GET_CURRENT_CONTEXT(ctx
);
108 /* Error-check target and get curProg */
109 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
110 curProg
= ctx
->VertexProgram
.Current
;
112 else if (target
== GL_FRAGMENT_PROGRAM_ARB
113 && ctx
->Extensions
.ARB_fragment_program
) {
114 curProg
= ctx
->FragmentProgram
.Current
;
117 _mesa_error(ctx
, GL_INVALID_ENUM
, "glBindProgramARB(target)");
122 * Get pointer to new program to bind.
123 * NOTE: binding to a non-existant program is not an error.
124 * That's supposed to be caught in glBegin.
126 newProg
= lookup_or_create_program(id
, target
, "glBindProgram");
130 /** All error checking is complete now **/
132 if (curProg
->Id
== id
) {
133 /* binding same program - no change */
137 /* signal new program (and its new constants) */
138 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
139 flush_vertices_for_program_constants(ctx
, target
);
142 if (target
== GL_VERTEX_PROGRAM_ARB
) {
143 _mesa_reference_program(ctx
, &ctx
->VertexProgram
.Current
, newProg
);
145 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
146 _mesa_reference_program(ctx
, &ctx
->FragmentProgram
.Current
, newProg
);
149 _mesa_update_vertex_processing_mode(ctx
);
151 /* Never null pointers */
152 assert(ctx
->VertexProgram
.Current
);
153 assert(ctx
->FragmentProgram
.Current
);
158 * Delete a list of programs.
159 * \note Not compiled into display lists.
160 * \note Called by both glDeleteProgramsNV and glDeleteProgramsARB.
163 _mesa_DeleteProgramsARB(GLsizei n
, const GLuint
*ids
)
166 GET_CURRENT_CONTEXT(ctx
);
168 FLUSH_VERTICES(ctx
, 0);
171 _mesa_error( ctx
, GL_INVALID_VALUE
, "glDeleteProgramsNV" );
175 for (i
= 0; i
< n
; i
++) {
177 struct gl_program
*prog
= _mesa_lookup_program(ctx
, ids
[i
]);
178 if (prog
== &_mesa_DummyProgram
) {
179 _mesa_HashRemove(ctx
->Shared
->Programs
, ids
[i
]);
182 /* Unbind program if necessary */
183 switch (prog
->Target
) {
184 case GL_VERTEX_PROGRAM_ARB
:
185 if (ctx
->VertexProgram
.Current
&&
186 ctx
->VertexProgram
.Current
->Id
== ids
[i
]) {
187 /* unbind this currently bound program */
188 _mesa_BindProgramARB(prog
->Target
, 0);
191 case GL_FRAGMENT_PROGRAM_ARB
:
192 if (ctx
->FragmentProgram
.Current
&&
193 ctx
->FragmentProgram
.Current
->Id
== ids
[i
]) {
194 /* unbind this currently bound program */
195 _mesa_BindProgramARB(prog
->Target
, 0);
199 _mesa_problem(ctx
, "bad target in glDeleteProgramsNV");
202 /* The ID is immediately available for re-use now */
203 _mesa_HashRemove(ctx
->Shared
->Programs
, ids
[i
]);
204 _mesa_reference_program(ctx
, &prog
, NULL
);
212 * Generate a list of new program identifiers.
213 * \note Not compiled into display lists.
214 * \note Called by both glGenProgramsNV and glGenProgramsARB.
217 _mesa_GenProgramsARB(GLsizei n
, GLuint
*ids
)
221 GET_CURRENT_CONTEXT(ctx
);
224 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGenPrograms");
231 _mesa_HashLockMutex(ctx
->Shared
->Programs
);
233 first
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->Programs
, n
);
235 /* Insert pointer to dummy program as placeholder */
236 for (i
= 0; i
< (GLuint
) n
; i
++) {
237 _mesa_HashInsertLocked(ctx
->Shared
->Programs
, first
+ i
,
238 &_mesa_DummyProgram
);
241 _mesa_HashUnlockMutex(ctx
->Shared
->Programs
);
243 /* Return the program names */
244 for (i
= 0; i
< (GLuint
) n
; i
++) {
251 * Determine if id names a vertex or fragment program.
252 * \note Not compiled into display lists.
253 * \note Called from both glIsProgramNV and glIsProgramARB.
254 * \param id is the program identifier
255 * \return GL_TRUE if id is a program, else GL_FALSE.
258 _mesa_IsProgramARB(GLuint id
)
260 struct gl_program
*prog
= NULL
;
261 GET_CURRENT_CONTEXT(ctx
);
262 ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx
, GL_FALSE
);
267 prog
= _mesa_lookup_program(ctx
, id
);
268 if (prog
&& (prog
!= &_mesa_DummyProgram
))
274 static struct gl_program
*
275 get_current_program(struct gl_context
* ctx
, GLenum target
, const char* caller
)
277 if (target
== GL_VERTEX_PROGRAM_ARB
278 && ctx
->Extensions
.ARB_vertex_program
) {
279 return ctx
->VertexProgram
.Current
;
281 else if (target
== GL_FRAGMENT_PROGRAM_ARB
282 && ctx
->Extensions
.ARB_fragment_program
) {
283 return ctx
->FragmentProgram
.Current
;
286 _mesa_error(ctx
, GL_INVALID_ENUM
,
287 "%s(target)", caller
);
293 get_local_param_pointer(struct gl_context
*ctx
, const char *func
,
294 struct gl_program
* prog
, GLenum target
,
295 GLuint index
, GLfloat
**param
)
299 if (target
== GL_VERTEX_PROGRAM_ARB
) {
300 maxParams
= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxLocalParams
;
302 maxParams
= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxLocalParams
;
305 if (index
>= maxParams
) {
306 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
310 if (!prog
->arb
.LocalParams
) {
311 prog
->arb
.LocalParams
= rzalloc_array_size(prog
, sizeof(float[4]),
313 if (!prog
->arb
.LocalParams
)
317 *param
= prog
->arb
.LocalParams
[index
];
323 get_env_param_pointer(struct gl_context
*ctx
, const char *func
,
324 GLenum target
, GLuint index
, GLfloat
**param
)
326 if (target
== GL_FRAGMENT_PROGRAM_ARB
327 && ctx
->Extensions
.ARB_fragment_program
) {
328 if (index
>= ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxEnvParams
) {
329 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
332 *param
= ctx
->FragmentProgram
.Parameters
[index
];
335 else if (target
== GL_VERTEX_PROGRAM_ARB
&&
336 ctx
->Extensions
.ARB_vertex_program
) {
337 if (index
>= ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxEnvParams
) {
338 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(index)", func
);
341 *param
= ctx
->VertexProgram
.Parameters
[index
];
344 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s(target)", func
);
350 set_program_string(struct gl_program
*prog
, GLenum target
, GLenum format
, GLsizei len
,
351 const GLvoid
*string
)
354 GET_CURRENT_CONTEXT(ctx
);
356 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
358 if (!ctx
->Extensions
.ARB_vertex_program
359 && !ctx
->Extensions
.ARB_fragment_program
) {
360 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glProgramStringARB()");
364 if (format
!= GL_PROGRAM_FORMAT_ASCII_ARB
) {
365 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(format)");
369 #ifdef ENABLE_SHADER_CACHE
370 GLcharARB
*replacement
;
372 gl_shader_stage stage
= _mesa_program_enum_to_shader_stage(target
);
374 /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
375 * if corresponding entry found from MESA_SHADER_READ_PATH.
377 _mesa_dump_shader_source(stage
, string
);
379 replacement
= _mesa_read_shader_source(stage
, string
);
381 string
= replacement
;
382 #endif /* ENABLE_SHADER_CACHE */
384 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
385 _mesa_parse_arb_vertex_program(ctx
, target
, string
, len
, prog
);
387 else if (target
== GL_FRAGMENT_PROGRAM_ARB
388 && ctx
->Extensions
.ARB_fragment_program
) {
389 _mesa_parse_arb_fragment_program(ctx
, target
, string
, len
, prog
);
392 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
396 failed
= ctx
->Program
.ErrorPos
!= -1;
399 /* finally, give the program to the driver for translation/checking */
400 if (!ctx
->Driver
.ProgramStringNotify(ctx
, target
, prog
)) {
402 _mesa_error(ctx
, GL_INVALID_OPERATION
,
403 "glProgramStringARB(rejected by driver");
407 _mesa_update_vertex_processing_mode(ctx
);
409 if (ctx
->_Shader
->Flags
& GLSL_DUMP
) {
410 const char *shader_type
=
411 target
== GL_FRAGMENT_PROGRAM_ARB
? "fragment" : "vertex";
413 fprintf(stderr
, "ARB_%s_program source for program %d:\n",
414 shader_type
, prog
->Id
);
415 fprintf(stderr
, "%s\n", (const char *) string
);
418 fprintf(stderr
, "ARB_%s_program %d failed to compile.\n",
419 shader_type
, prog
->Id
);
421 fprintf(stderr
, "Mesa IR for ARB_%s_program %d:\n",
422 shader_type
, prog
->Id
);
423 _mesa_print_program(prog
);
424 fprintf(stderr
, "\n");
429 /* Capture vp-*.shader_test/fp-*.shader_test files. */
430 const char *capture_path
= _mesa_get_shader_capture_path();
431 if (capture_path
!= NULL
) {
433 const char *shader_type
=
434 target
== GL_FRAGMENT_PROGRAM_ARB
? "fragment" : "vertex";
436 ralloc_asprintf(NULL
, "%s/%cp-%u.shader_test",
437 capture_path
, shader_type
[0], prog
->Id
);
439 file
= fopen(filename
, "w");
442 "[require]\nGL_ARB_%s_program\n\n[%s program]\n%s\n",
443 shader_type
, shader_type
, (const char *) string
);
446 _mesa_warning(ctx
, "Failed to open %s", filename
);
448 ralloc_free(filename
);
453 _mesa_ProgramStringARB(GLenum target
, GLenum format
, GLsizei len
,
454 const GLvoid
*string
)
456 GET_CURRENT_CONTEXT(ctx
);
457 if (target
== GL_VERTEX_PROGRAM_ARB
&& ctx
->Extensions
.ARB_vertex_program
) {
458 set_program_string(ctx
->VertexProgram
.Current
, target
, format
, len
, string
);
460 else if (target
== GL_FRAGMENT_PROGRAM_ARB
461 && ctx
->Extensions
.ARB_fragment_program
) {
462 set_program_string(ctx
->FragmentProgram
.Current
, target
, format
, len
, string
);
465 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramStringARB(target)");
471 _mesa_NamedProgramStringEXT(GLuint program
, GLenum target
, GLenum format
, GLsizei len
,
472 const GLvoid
*string
)
474 struct gl_program
* prog
= lookup_or_create_program(program
, target
, "glNamedProgramStringEXT");
479 set_program_string(prog
, target
, format
, len
, string
);
484 * Set a program env parameter register.
485 * \note Called from the GL API dispatcher.
488 _mesa_ProgramEnvParameter4dARB(GLenum target
, GLuint index
,
489 GLdouble x
, GLdouble y
, GLdouble z
, GLdouble w
)
491 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
492 (GLfloat
) z
, (GLfloat
) w
);
497 * Set a program env parameter register.
498 * \note Called from the GL API dispatcher.
501 _mesa_ProgramEnvParameter4dvARB(GLenum target
, GLuint index
,
502 const GLdouble
*params
)
504 _mesa_ProgramEnvParameter4fARB(target
, index
, (GLfloat
) params
[0],
505 (GLfloat
) params
[1], (GLfloat
) params
[2],
506 (GLfloat
) params
[3]);
511 * Set a program env parameter register.
512 * \note Called from the GL API dispatcher.
515 _mesa_ProgramEnvParameter4fARB(GLenum target
, GLuint index
,
516 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
520 GET_CURRENT_CONTEXT(ctx
);
522 flush_vertices_for_program_constants(ctx
, target
);
524 if (get_env_param_pointer(ctx
, "glProgramEnvParameter",
525 target
, index
, ¶m
)) {
526 ASSIGN_4V(param
, x
, y
, z
, w
);
533 * Set a program env parameter register.
534 * \note Called from the GL API dispatcher.
537 _mesa_ProgramEnvParameter4fvARB(GLenum target
, GLuint index
,
538 const GLfloat
*params
)
542 GET_CURRENT_CONTEXT(ctx
);
544 flush_vertices_for_program_constants(ctx
, target
);
546 if (get_env_param_pointer(ctx
, "glProgramEnvParameter4fv",
547 target
, index
, ¶m
)) {
548 memcpy(param
, params
, 4 * sizeof(GLfloat
));
554 _mesa_ProgramEnvParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
555 const GLfloat
*params
)
557 GET_CURRENT_CONTEXT(ctx
);
560 flush_vertices_for_program_constants(ctx
, target
);
563 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(count)");
566 if (target
== GL_FRAGMENT_PROGRAM_ARB
567 && ctx
->Extensions
.ARB_fragment_program
) {
568 if ((index
+ count
) > ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxEnvParams
) {
569 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
572 dest
= ctx
->FragmentProgram
.Parameters
[index
];
574 else if (target
== GL_VERTEX_PROGRAM_ARB
575 && ctx
->Extensions
.ARB_vertex_program
) {
576 if ((index
+ count
) > ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxEnvParams
) {
577 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramEnvParameters4fv(index + count)");
580 dest
= ctx
->VertexProgram
.Parameters
[index
];
583 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramEnvParameters4fv(target)");
587 memcpy(dest
, params
, count
* 4 * sizeof(GLfloat
));
592 _mesa_GetProgramEnvParameterdvARB(GLenum target
, GLuint index
,
595 GET_CURRENT_CONTEXT(ctx
);
598 if (get_env_param_pointer(ctx
, "glGetProgramEnvParameterdv",
599 target
, index
, &fparam
)) {
600 COPY_4V(params
, fparam
);
606 _mesa_GetProgramEnvParameterfvARB(GLenum target
, GLuint index
,
611 GET_CURRENT_CONTEXT(ctx
);
613 if (get_env_param_pointer(ctx
, "glGetProgramEnvParameterfv",
614 target
, index
, ¶m
)) {
615 COPY_4V(params
, param
);
621 _mesa_ProgramLocalParameter4fARB(GLenum target
, GLuint index
,
622 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
624 GET_CURRENT_CONTEXT(ctx
);
626 struct gl_program
* prog
= get_current_program(ctx
, target
, "glProgramLocalParameterARB");
631 flush_vertices_for_program_constants(ctx
, target
);
633 if (get_local_param_pointer(ctx
, "glProgramLocalParameterARB",
634 prog
, target
, index
, ¶m
)) {
635 assert(index
< MAX_PROGRAM_LOCAL_PARAMS
);
636 ASSIGN_4V(param
, x
, y
, z
, w
);
641 _mesa_NamedProgramLocalParameter4fEXT(GLuint program
, GLenum target
, GLuint index
,
642 GLfloat x
, GLfloat y
, GLfloat z
, GLfloat w
)
644 GET_CURRENT_CONTEXT(ctx
);
646 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
647 "glNamedProgramLocalParameter4fEXT");
653 if ((target
== GL_VERTEX_PROGRAM_ARB
&& prog
== ctx
->VertexProgram
.Current
) ||
654 (target
== GL_FRAGMENT_PROGRAM_ARB
&& prog
== ctx
->FragmentProgram
.Current
)) {
655 flush_vertices_for_program_constants(ctx
, target
);
658 if (get_local_param_pointer(ctx
, "glNamedProgramLocalParameter4fEXT",
659 prog
, target
, index
, ¶m
)) {
660 assert(index
< MAX_PROGRAM_LOCAL_PARAMS
);
661 ASSIGN_4V(param
, x
, y
, z
, w
);
667 _mesa_ProgramLocalParameter4fvARB(GLenum target
, GLuint index
,
668 const GLfloat
*params
)
670 _mesa_ProgramLocalParameter4fARB(target
, index
, params
[0], params
[1],
671 params
[2], params
[3]);
676 _mesa_NamedProgramLocalParameter4fvEXT(GLuint program
, GLenum target
, GLuint index
,
677 const GLfloat
*params
)
679 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
, params
[0],
680 params
[1], params
[2], params
[3]);
685 program_local_parameters4fv(struct gl_program
* prog
, GLuint index
, GLsizei count
,
686 const GLfloat
*params
, const char* caller
)
688 GET_CURRENT_CONTEXT(ctx
);
690 flush_vertices_for_program_constants(ctx
, prog
->Target
);
693 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s(count)", caller
);
696 if (get_local_param_pointer(ctx
, caller
,
697 prog
, prog
->Target
, index
, &dest
)) {
698 GLuint maxParams
= prog
->Target
== GL_FRAGMENT_PROGRAM_ARB
?
699 ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
].MaxLocalParams
:
700 ctx
->Const
.Program
[MESA_SHADER_VERTEX
].MaxLocalParams
;
702 if ((index
+ count
) > maxParams
) {
703 _mesa_error(ctx
, GL_INVALID_VALUE
,
709 memcpy(dest
, params
, count
* 4 * sizeof(GLfloat
));
715 _mesa_ProgramLocalParameters4fvEXT(GLenum target
, GLuint index
, GLsizei count
,
716 const GLfloat
*params
)
718 GET_CURRENT_CONTEXT(ctx
);
719 struct gl_program
* prog
= get_current_program(ctx
, target
,
720 "glProgramLocalParameters4fv");
725 program_local_parameters4fv(prog
, index
, count
, params
,
726 "glProgramLocalParameters4fv");
730 _mesa_NamedProgramLocalParameters4fvEXT(GLuint program
, GLenum target
, GLuint index
,
731 GLsizei count
, const GLfloat
*params
)
733 struct gl_program
* prog
=
734 lookup_or_create_program(program
, target
,
735 "glNamedProgramLocalParameters4fvEXT");
740 program_local_parameters4fv(prog
, index
, count
, params
,
741 "glNamedProgramLocalParameters4fvEXT");
746 _mesa_ProgramLocalParameter4dARB(GLenum target
, GLuint index
,
747 GLdouble x
, GLdouble y
,
748 GLdouble z
, GLdouble w
)
750 _mesa_ProgramLocalParameter4fARB(target
, index
, (GLfloat
) x
, (GLfloat
) y
,
751 (GLfloat
) z
, (GLfloat
) w
);
756 _mesa_NamedProgramLocalParameter4dEXT(GLuint program
, GLenum target
, GLuint index
,
757 GLdouble x
, GLdouble y
,
758 GLdouble z
, GLdouble w
)
760 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
, (GLfloat
) x
, (GLfloat
) y
,
761 (GLfloat
) z
, (GLfloat
) w
);
766 _mesa_ProgramLocalParameter4dvARB(GLenum target
, GLuint index
,
767 const GLdouble
*params
)
769 _mesa_ProgramLocalParameter4fARB(target
, index
,
770 (GLfloat
) params
[0], (GLfloat
) params
[1],
771 (GLfloat
) params
[2], (GLfloat
) params
[3]);
776 _mesa_NamedProgramLocalParameter4dvEXT(GLuint program
, GLenum target
, GLuint index
,
777 const GLdouble
*params
)
779 _mesa_NamedProgramLocalParameter4fEXT(program
, target
, index
,
780 (GLfloat
) params
[0], (GLfloat
) params
[1],
781 (GLfloat
) params
[2], (GLfloat
) params
[3]);
786 _mesa_GetProgramLocalParameterfvARB(GLenum target
, GLuint index
,
790 GET_CURRENT_CONTEXT(ctx
);
791 struct gl_program
* prog
= get_current_program(ctx
, target
, "glGetProgramLocalParameterfvARB");
796 if (get_local_param_pointer(ctx
, "glProgramLocalParameters4fvEXT",
797 prog
, target
, index
, ¶m
)) {
798 COPY_4V(params
, param
);
804 _mesa_GetNamedProgramLocalParameterfvEXT(GLuint program
, GLenum target
, GLuint index
,
808 GET_CURRENT_CONTEXT(ctx
);
809 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
810 "glGetNamedProgramLocalParameterfvEXT");
815 if (get_local_param_pointer(ctx
, "glGetNamedProgramLocalParameterfvEXT",
816 prog
, target
, index
, ¶m
)) {
817 COPY_4V(params
, param
);
823 _mesa_GetProgramLocalParameterdvARB(GLenum target
, GLuint index
,
827 GET_CURRENT_CONTEXT(ctx
);
828 struct gl_program
* prog
= get_current_program(ctx
, target
, "glGetProgramLocalParameterdvARB");
833 if (get_local_param_pointer(ctx
, "glProgramLocalParameters4fvEXT",
834 prog
, target
, index
, ¶m
)) {
835 COPY_4V(params
, param
);
841 _mesa_GetNamedProgramLocalParameterdvEXT(GLuint program
, GLenum target
, GLuint index
,
845 GET_CURRENT_CONTEXT(ctx
);
846 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
847 "glGetNamedProgramLocalParameterdvEXT");
852 if (get_local_param_pointer(ctx
, "glGetNamedProgramLocalParameterdvEXT",
853 prog
, target
, index
, ¶m
)) {
854 COPY_4V(params
, param
);
860 get_program_iv(struct gl_program
*prog
, GLenum target
, GLenum pname
,
863 const struct gl_program_constants
*limits
;
865 GET_CURRENT_CONTEXT(ctx
);
867 if (target
== GL_VERTEX_PROGRAM_ARB
) {
868 limits
= &ctx
->Const
.Program
[MESA_SHADER_VERTEX
];
871 limits
= &ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
];
877 /* Queries supported for both vertex and fragment programs */
879 case GL_PROGRAM_LENGTH_ARB
:
881 = prog
->String
? (GLint
) strlen((char *) prog
->String
) : 0;
883 case GL_PROGRAM_FORMAT_ARB
:
884 *params
= prog
->Format
;
886 case GL_PROGRAM_BINDING_ARB
:
889 case GL_PROGRAM_INSTRUCTIONS_ARB
:
890 *params
= prog
->arb
.NumInstructions
;
892 case GL_MAX_PROGRAM_INSTRUCTIONS_ARB
:
893 *params
= limits
->MaxInstructions
;
895 case GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
896 *params
= prog
->arb
.NumNativeInstructions
;
898 case GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB
:
899 *params
= limits
->MaxNativeInstructions
;
901 case GL_PROGRAM_TEMPORARIES_ARB
:
902 *params
= prog
->arb
.NumTemporaries
;
904 case GL_MAX_PROGRAM_TEMPORARIES_ARB
:
905 *params
= limits
->MaxTemps
;
907 case GL_PROGRAM_NATIVE_TEMPORARIES_ARB
:
908 *params
= prog
->arb
.NumNativeTemporaries
;
910 case GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB
:
911 *params
= limits
->MaxNativeTemps
;
913 case GL_PROGRAM_PARAMETERS_ARB
:
914 *params
= prog
->arb
.NumParameters
;
916 case GL_MAX_PROGRAM_PARAMETERS_ARB
:
917 *params
= limits
->MaxParameters
;
919 case GL_PROGRAM_NATIVE_PARAMETERS_ARB
:
920 *params
= prog
->arb
.NumNativeParameters
;
922 case GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB
:
923 *params
= limits
->MaxNativeParameters
;
925 case GL_PROGRAM_ATTRIBS_ARB
:
926 *params
= prog
->arb
.NumAttributes
;
928 case GL_MAX_PROGRAM_ATTRIBS_ARB
:
929 *params
= limits
->MaxAttribs
;
931 case GL_PROGRAM_NATIVE_ATTRIBS_ARB
:
932 *params
= prog
->arb
.NumNativeAttributes
;
934 case GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB
:
935 *params
= limits
->MaxNativeAttribs
;
937 case GL_PROGRAM_ADDRESS_REGISTERS_ARB
:
938 *params
= prog
->arb
.NumAddressRegs
;
940 case GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB
:
941 *params
= limits
->MaxAddressRegs
;
943 case GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
944 *params
= prog
->arb
.NumNativeAddressRegs
;
946 case GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB
:
947 *params
= limits
->MaxNativeAddressRegs
;
949 case GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
:
950 *params
= limits
->MaxLocalParams
;
952 case GL_MAX_PROGRAM_ENV_PARAMETERS_ARB
:
953 *params
= limits
->MaxEnvParams
;
955 case GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
:
957 * XXX we may not really need a driver callback here.
958 * If the number of native instructions, registers, etc. used
959 * are all below the maximums, we could return true.
960 * The spec says that even if this query returns true, there's
961 * no guarantee that the program will run in hardware.
964 /* default/null program */
967 else if (ctx
->Driver
.IsProgramNative
) {
969 *params
= ctx
->Driver
.IsProgramNative( ctx
, target
, prog
);
972 /* probably running in software */
977 /* continue with fragment-program only queries below */
982 * The following apply to fragment programs only (at this time)
984 if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
985 const struct gl_program
*fp
= ctx
->FragmentProgram
.Current
;
987 case GL_PROGRAM_ALU_INSTRUCTIONS_ARB
:
988 *params
= fp
->arb
.NumNativeAluInstructions
;
990 case GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
991 *params
= fp
->arb
.NumAluInstructions
;
993 case GL_PROGRAM_TEX_INSTRUCTIONS_ARB
:
994 *params
= fp
->arb
.NumTexInstructions
;
996 case GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
997 *params
= fp
->arb
.NumNativeTexInstructions
;
999 case GL_PROGRAM_TEX_INDIRECTIONS_ARB
:
1000 *params
= fp
->arb
.NumTexIndirections
;
1002 case GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
1003 *params
= fp
->arb
.NumNativeTexIndirections
;
1005 case GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB
:
1006 *params
= limits
->MaxAluInstructions
;
1008 case GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
:
1009 *params
= limits
->MaxNativeAluInstructions
;
1011 case GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
:
1012 *params
= limits
->MaxTexInstructions
;
1014 case GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
:
1015 *params
= limits
->MaxNativeTexInstructions
;
1017 case GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
:
1018 *params
= limits
->MaxTexIndirections
;
1020 case GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
:
1021 *params
= limits
->MaxNativeTexIndirections
;
1024 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
1028 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramivARB(pname)");
1035 _mesa_GetProgramivARB(GLenum target
, GLenum pname
, GLint
*params
)
1037 GET_CURRENT_CONTEXT(ctx
);
1038 struct gl_program
* prog
= get_current_program(ctx
, target
,
1039 "glGetProgramivARB");
1043 get_program_iv(prog
, target
, pname
, params
);
1047 _mesa_GetNamedProgramivEXT(GLuint program
, GLenum target
, GLenum pname
,
1050 struct gl_program
* prog
;
1051 if (pname
== GL_PROGRAM_BINDING_ARB
) {
1052 _mesa_GetProgramivARB(target
, pname
, params
);
1055 prog
= lookup_or_create_program(program
, target
,
1056 "glGetNamedProgramivEXT");
1060 get_program_iv(prog
, target
, pname
, params
);
1065 _mesa_GetProgramStringARB(GLenum target
, GLenum pname
, GLvoid
*string
)
1067 const struct gl_program
*prog
;
1068 char *dst
= (char *) string
;
1069 GET_CURRENT_CONTEXT(ctx
);
1071 if (target
== GL_VERTEX_PROGRAM_ARB
) {
1072 prog
= ctx
->VertexProgram
.Current
;
1074 else if (target
== GL_FRAGMENT_PROGRAM_ARB
) {
1075 prog
= ctx
->FragmentProgram
.Current
;
1078 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(target)");
1084 if (pname
!= GL_PROGRAM_STRING_ARB
) {
1085 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramStringARB(pname)");
1090 memcpy(dst
, prog
->String
, strlen((char *) prog
->String
));
1097 _mesa_GetNamedProgramStringEXT(GLuint program
, GLenum target
,
1098 GLenum pname
, GLvoid
*string
) {
1099 char *dst
= (char *) string
;
1100 GET_CURRENT_CONTEXT(ctx
);
1101 struct gl_program
* prog
= lookup_or_create_program(program
, target
,
1102 "glGetNamedProgramStringEXT");
1106 if (pname
!= GL_PROGRAM_STRING_ARB
) {
1107 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetNamedProgramStringEXT(pname)");
1112 memcpy(dst
, prog
->String
, strlen((char *) prog
->String
));