2 * Mesa 3-D graphics library
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. 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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
30 * Implementation of GLSL-related API functions.
31 * The glUniform* functions are in uniforms.c
35 * 1. Check that the right error code is generated for all _mesa_error() calls.
36 * 2. Insert FLUSH_VERTICES calls in various places
41 #include "main/glheader.h"
42 #include "main/context.h"
43 #include "main/dispatch.h"
44 #include "main/enums.h"
45 #include "main/hash.h"
46 #include "main/mtypes.h"
47 #include "main/pipelineobj.h"
48 #include "main/shaderapi.h"
49 #include "main/shaderobj.h"
50 #include "main/transformfeedback.h"
51 #include "main/uniforms.h"
52 #include "compiler/glsl/glsl_parser_extras.h"
53 #include "compiler/glsl/ir.h"
54 #include "compiler/glsl/ir_uniform.h"
55 #include "compiler/glsl/program.h"
56 #include "program/program.h"
57 #include "program/prog_print.h"
58 #include "program/prog_parameter.h"
59 #include "util/ralloc.h"
60 #include "util/hash_table.h"
61 #include "util/mesa-sha1.h"
62 #include "util/crc32.h"
65 * Return mask of GLSL_x flags by examining the MESA_GLSL env var.
68 _mesa_get_shader_flags(void)
70 GLbitfield flags
= 0x0;
71 const char *env
= getenv("MESA_GLSL");
74 if (strstr(env
, "dump_on_error"))
75 flags
|= GLSL_DUMP_ON_ERROR
;
76 else if (strstr(env
, "dump"))
78 if (strstr(env
, "log"))
80 if (strstr(env
, "cache_info"))
81 flags
|= GLSL_CACHE_INFO
;
82 if (strstr(env
, "nopvert"))
83 flags
|= GLSL_NOP_VERT
;
84 if (strstr(env
, "nopfrag"))
85 flags
|= GLSL_NOP_FRAG
;
86 if (strstr(env
, "uniform"))
87 flags
|= GLSL_UNIFORMS
;
88 if (strstr(env
, "useprog"))
89 flags
|= GLSL_USE_PROG
;
90 if (strstr(env
, "errors"))
91 flags
|= GLSL_REPORT_ERRORS
;
98 * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH").
101 _mesa_get_shader_capture_path(void)
103 static bool read_env_var
= false;
104 static const char *path
= NULL
;
107 path
= getenv("MESA_SHADER_CAPTURE_PATH");
115 * Initialize context's shader state.
118 _mesa_init_shader_state(struct gl_context
*ctx
)
120 /* Device drivers may override these to control what kind of instructions
121 * are generated by the GLSL compiler.
123 struct gl_shader_compiler_options options
;
127 memset(&options
, 0, sizeof(options
));
128 options
.MaxUnrollIterations
= 32;
129 options
.MaxIfDepth
= UINT_MAX
;
131 for (sh
= 0; sh
< MESA_SHADER_STAGES
; ++sh
)
132 memcpy(&ctx
->Const
.ShaderCompilerOptions
[sh
], &options
, sizeof(options
));
134 ctx
->Shader
.Flags
= _mesa_get_shader_flags();
136 if (ctx
->Shader
.Flags
!= 0)
137 ctx
->Const
.GenerateTemporaryNames
= true;
139 /* Extended for ARB_separate_shader_objects */
140 ctx
->Shader
.RefCount
= 1;
141 mtx_init(&ctx
->Shader
.Mutex
, mtx_plain
);
143 ctx
->TessCtrlProgram
.patch_vertices
= 3;
144 for (i
= 0; i
< 4; ++i
)
145 ctx
->TessCtrlProgram
.patch_default_outer_level
[i
] = 1.0;
146 for (i
= 0; i
< 2; ++i
)
147 ctx
->TessCtrlProgram
.patch_default_inner_level
[i
] = 1.0;
152 * Free the per-context shader-related state.
155 _mesa_free_shader_state(struct gl_context
*ctx
)
157 for (int i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
158 _mesa_reference_program(ctx
, &ctx
->Shader
.CurrentProgram
[i
], NULL
);
160 _mesa_reference_program(ctx
, &ctx
->Shader
._CurrentFragmentProgram
, NULL
);
161 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.ActiveProgram
, NULL
);
163 /* Extended for ARB_separate_shader_objects */
164 _mesa_reference_pipeline_object(ctx
, &ctx
->_Shader
, NULL
);
166 assert(ctx
->Shader
.RefCount
== 1);
167 mtx_destroy(&ctx
->Shader
.Mutex
);
172 * Copy string from <src> to <dst>, up to maxLength characters, returning
173 * length of <dst> in <length>.
174 * \param src the strings source
175 * \param maxLength max chars to copy
176 * \param length returns number of chars copied
177 * \param dst the string destination
180 _mesa_copy_string(GLchar
*dst
, GLsizei maxLength
,
181 GLsizei
*length
, const GLchar
*src
)
184 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
195 * Confirm that the a shader type is valid and supported by the implementation
197 * \param ctx Current GL context
198 * \param type Shader target
202 _mesa_validate_shader_target(const struct gl_context
*ctx
, GLenum type
)
204 /* Note: when building built-in GLSL functions, this function may be
205 * invoked with ctx == NULL. In that case, we can only validate that it's
206 * a shader target we recognize, not that it's supported in the current
207 * context. But that's fine--we don't need any further validation than
208 * that when building built-in GLSL functions.
212 case GL_FRAGMENT_SHADER
:
213 return ctx
== NULL
|| ctx
->Extensions
.ARB_fragment_shader
;
214 case GL_VERTEX_SHADER
:
215 return ctx
== NULL
|| ctx
->Extensions
.ARB_vertex_shader
;
216 case GL_GEOMETRY_SHADER_ARB
:
217 return ctx
== NULL
|| _mesa_has_geometry_shaders(ctx
);
218 case GL_TESS_CONTROL_SHADER
:
219 case GL_TESS_EVALUATION_SHADER
:
220 return ctx
== NULL
|| _mesa_has_tessellation(ctx
);
221 case GL_COMPUTE_SHADER
:
222 return ctx
== NULL
|| _mesa_has_compute_shaders(ctx
);
230 is_program(struct gl_context
*ctx
, GLuint name
)
232 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
233 return shProg
? GL_TRUE
: GL_FALSE
;
238 is_shader(struct gl_context
*ctx
, GLuint name
)
240 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
241 return shader
? GL_TRUE
: GL_FALSE
;
246 * Attach shader to a shader program.
249 attach_shader(struct gl_context
*ctx
, GLuint program
, GLuint shader
)
251 struct gl_shader_program
*shProg
;
252 struct gl_shader
*sh
;
255 const bool same_type_disallowed
= _mesa_is_gles(ctx
);
257 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glAttachShader");
261 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glAttachShader");
266 n
= shProg
->NumShaders
;
267 for (i
= 0; i
< n
; i
++) {
268 if (shProg
->Shaders
[i
] == sh
) {
269 /* The shader is already attched to this program. The
270 * GL_ARB_shader_objects spec says:
272 * "The error INVALID_OPERATION is generated by AttachObjectARB
273 * if <obj> is already attached to <containerObj>."
275 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
277 } else if (same_type_disallowed
&&
278 shProg
->Shaders
[i
]->Stage
== sh
->Stage
) {
279 /* Shader with the same type is already attached to this program,
280 * OpenGL ES 2.0 and 3.0 specs say:
282 * "Multiple shader objects of the same type may not be attached
283 * to a single program object. [...] The error INVALID_OPERATION
284 * is generated if [...] another shader object of the same type
285 * as shader is already attached to program."
287 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glAttachShader");
293 shProg
->Shaders
= realloc(shProg
->Shaders
,
294 (n
+ 1) * sizeof(struct gl_shader
*));
295 if (!shProg
->Shaders
) {
296 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
301 shProg
->Shaders
[n
] = NULL
; /* since realloc() didn't zero the new space */
302 _mesa_reference_shader(ctx
, &shProg
->Shaders
[n
], sh
);
303 shProg
->NumShaders
++;
308 create_shader(struct gl_context
*ctx
, GLenum type
)
310 struct gl_shader
*sh
;
313 if (!_mesa_validate_shader_target(ctx
, type
)) {
314 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(%s)",
315 _mesa_enum_to_string(type
));
319 _mesa_HashLockMutex(ctx
->Shared
->ShaderObjects
);
320 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
321 sh
= _mesa_new_shader(name
, _mesa_shader_enum_to_shader_stage(type
));
323 _mesa_HashInsertLocked(ctx
->Shared
->ShaderObjects
, name
, sh
);
324 _mesa_HashUnlockMutex(ctx
->Shared
->ShaderObjects
);
331 create_shader_program(struct gl_context
*ctx
)
334 struct gl_shader_program
*shProg
;
336 _mesa_HashLockMutex(ctx
->Shared
->ShaderObjects
);
338 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
340 shProg
= _mesa_new_shader_program(name
);
342 _mesa_HashInsertLocked(ctx
->Shared
->ShaderObjects
, name
, shProg
);
344 assert(shProg
->RefCount
== 1);
346 _mesa_HashUnlockMutex(ctx
->Shared
->ShaderObjects
);
353 * Delete a shader program. Actually, just decrement the program's
354 * reference count and mark it as DeletePending.
355 * Used to implement glDeleteProgram() and glDeleteObjectARB().
358 delete_shader_program(struct gl_context
*ctx
, GLuint name
)
361 * NOTE: deleting shaders/programs works a bit differently than
362 * texture objects (and buffer objects, etc). Shader/program
363 * handles/IDs exist in the hash table until the object is really
364 * deleted (refcount==0). With texture objects, the handle/ID is
365 * removed from the hash table in glDeleteTextures() while the tex
366 * object itself might linger until its refcount goes to zero.
368 struct gl_shader_program
*shProg
;
370 shProg
= _mesa_lookup_shader_program_err(ctx
, name
, "glDeleteProgram");
374 if (!shProg
->DeletePending
) {
375 shProg
->DeletePending
= GL_TRUE
;
377 /* effectively, decr shProg's refcount */
378 _mesa_reference_shader_program(ctx
, &shProg
, NULL
);
384 delete_shader(struct gl_context
*ctx
, GLuint shader
)
386 struct gl_shader
*sh
;
388 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glDeleteShader");
392 if (!sh
->DeletePending
) {
393 sh
->DeletePending
= GL_TRUE
;
395 /* effectively, decr sh's refcount */
396 _mesa_reference_shader(ctx
, &sh
, NULL
);
402 detach_shader(struct gl_context
*ctx
, GLuint program
, GLuint shader
)
404 struct gl_shader_program
*shProg
;
408 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glDetachShader");
412 n
= shProg
->NumShaders
;
414 for (i
= 0; i
< n
; i
++) {
415 if (shProg
->Shaders
[i
]->Name
== shader
) {
417 struct gl_shader
**newList
;
420 _mesa_reference_shader(ctx
, &shProg
->Shaders
[i
], NULL
);
422 /* alloc new, smaller array */
423 newList
= malloc((n
- 1) * sizeof(struct gl_shader
*));
425 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
428 /* Copy old list entries to new list, skipping removed entry at [i] */
429 for (j
= 0; j
< i
; j
++) {
430 newList
[j
] = shProg
->Shaders
[j
];
433 newList
[j
++] = shProg
->Shaders
[i
];
436 /* Free old list and install new one */
437 free(shProg
->Shaders
);
438 shProg
->Shaders
= newList
;
439 shProg
->NumShaders
= n
- 1;
442 /* sanity check - make sure the new list's entries are sensible */
443 for (j
= 0; j
< shProg
->NumShaders
; j
++) {
444 assert(shProg
->Shaders
[j
]->Stage
== MESA_SHADER_VERTEX
||
445 shProg
->Shaders
[j
]->Stage
== MESA_SHADER_TESS_CTRL
||
446 shProg
->Shaders
[j
]->Stage
== MESA_SHADER_TESS_EVAL
||
447 shProg
->Shaders
[j
]->Stage
== MESA_SHADER_GEOMETRY
||
448 shProg
->Shaders
[j
]->Stage
== MESA_SHADER_FRAGMENT
);
449 assert(shProg
->Shaders
[j
]->RefCount
> 0);
460 if (is_shader(ctx
, shader
) || is_program(ctx
, shader
))
461 err
= GL_INVALID_OPERATION
;
463 err
= GL_INVALID_VALUE
;
464 _mesa_error(ctx
, err
, "glDetachShader(shader)");
471 * Return list of shaders attached to shader program.
474 get_attached_shaders(struct gl_context
*ctx
, GLuint program
, GLsizei maxCount
,
475 GLsizei
*count
, GLuint
*obj
)
477 struct gl_shader_program
*shProg
;
480 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetAttachedShaders(maxCount < 0)");
485 _mesa_lookup_shader_program_err(ctx
, program
, "glGetAttachedShaders");
489 for (i
= 0; i
< (GLuint
) maxCount
&& i
< shProg
->NumShaders
; i
++) {
490 obj
[i
] = shProg
->Shaders
[i
]->Name
;
499 * glGetHandleARB() - return ID/name of currently bound shader program.
502 get_handle(struct gl_context
*ctx
, GLenum pname
)
504 if (pname
== GL_PROGRAM_OBJECT_ARB
) {
505 if (ctx
->_Shader
->ActiveProgram
)
506 return ctx
->_Shader
->ActiveProgram
->Name
;
511 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
518 * Check if a geometry shader query is valid at this time. If not, report an
519 * error and return false.
521 * From GL 3.2 section 6.1.16 (Shader and Program Queries):
523 * "If GEOMETRY_VERTICES_OUT, GEOMETRY_INPUT_TYPE, or GEOMETRY_OUTPUT_TYPE
524 * are queried for a program which has not been linked successfully, or
525 * which does not contain objects to form a geometry shader, then an
526 * INVALID_OPERATION error is generated."
529 check_gs_query(struct gl_context
*ctx
, const struct gl_shader_program
*shProg
)
531 if (shProg
->data
->LinkStatus
&&
532 shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
] != NULL
) {
536 _mesa_error(ctx
, GL_INVALID_OPERATION
,
537 "glGetProgramv(linked geometry shader required)");
543 * Check if a tessellation control shader query is valid at this time.
544 * If not, report an error and return false.
546 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
548 * "If TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has
549 * not been linked successfully, or which does not contain objects to
550 * form a tessellation control shader, then an INVALID_OPERATION error is
554 check_tcs_query(struct gl_context
*ctx
, const struct gl_shader_program
*shProg
)
556 if (shProg
->data
->LinkStatus
&&
557 shProg
->_LinkedShaders
[MESA_SHADER_TESS_CTRL
] != NULL
) {
561 _mesa_error(ctx
, GL_INVALID_OPERATION
,
562 "glGetProgramv(linked tessellation control shader required)");
568 * Check if a tessellation evaluation shader query is valid at this time.
569 * If not, report an error and return false.
571 * From GL 4.0 section 6.1.12 (Shader and Program Queries):
573 * "If any of the pname values in this paragraph are queried for a program
574 * which has not been linked successfully, or which does not contain
575 * objects to form a tessellation evaluation shader, then an
576 * INVALID_OPERATION error is generated."
580 check_tes_query(struct gl_context
*ctx
, const struct gl_shader_program
*shProg
)
582 if (shProg
->data
->LinkStatus
&&
583 shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
] != NULL
) {
587 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramv(linked tessellation "
588 "evaluation shader required)");
594 * glGetProgramiv() - get shader program state.
595 * Note that this is for GLSL shader programs, not ARB vertex/fragment
596 * programs (see glGetProgramivARB).
599 get_programiv(struct gl_context
*ctx
, GLuint program
, GLenum pname
,
602 struct gl_shader_program
*shProg
603 = _mesa_lookup_shader_program_err(ctx
, program
, "glGetProgramiv(program)");
605 /* Is transform feedback available in this context?
608 (ctx
->API
== API_OPENGL_COMPAT
&& ctx
->Extensions
.EXT_transform_feedback
)
609 || ctx
->API
== API_OPENGL_CORE
610 || _mesa_is_gles3(ctx
);
612 /* True if geometry shaders (of the form that was adopted into GLSL 1.50
613 * and GL 3.2) are available in this context
615 const bool has_core_gs
= _mesa_has_geometry_shaders(ctx
);
616 const bool has_tess
= _mesa_has_tessellation(ctx
);
618 /* Are uniform buffer objects available in this context?
621 (ctx
->API
== API_OPENGL_COMPAT
&&
622 ctx
->Extensions
.ARB_uniform_buffer_object
)
623 || ctx
->API
== API_OPENGL_CORE
624 || _mesa_is_gles3(ctx
);
631 case GL_DELETE_STATUS
:
632 *params
= shProg
->DeletePending
;
635 *params
= shProg
->data
->LinkStatus
? GL_TRUE
: GL_FALSE
;
637 case GL_VALIDATE_STATUS
:
638 *params
= shProg
->data
->Validated
;
640 case GL_INFO_LOG_LENGTH
:
641 *params
= (shProg
->data
->InfoLog
&& shProg
->data
->InfoLog
[0] != '\0') ?
642 strlen(shProg
->data
->InfoLog
) + 1 : 0;
644 case GL_ATTACHED_SHADERS
:
645 *params
= shProg
->NumShaders
;
647 case GL_ACTIVE_ATTRIBUTES
:
648 *params
= _mesa_count_active_attribs(shProg
);
650 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
651 *params
= _mesa_longest_attribute_name_length(shProg
);
653 case GL_ACTIVE_UNIFORMS
: {
655 const unsigned num_uniforms
=
656 shProg
->data
->NumUniformStorage
- shProg
->data
->NumHiddenUniforms
;
657 for (*params
= 0, i
= 0; i
< num_uniforms
; i
++) {
658 if (!shProg
->data
->UniformStorage
[i
].is_shader_storage
)
663 case GL_ACTIVE_UNIFORM_MAX_LENGTH
: {
666 const unsigned num_uniforms
=
667 shProg
->data
->NumUniformStorage
- shProg
->data
->NumHiddenUniforms
;
669 for (i
= 0; i
< num_uniforms
; i
++) {
670 if (shProg
->data
->UniformStorage
[i
].is_shader_storage
)
673 /* Add one for the terminating NUL character for a non-array, and
674 * 4 for the "[0]" and the NUL for an array.
676 const GLint len
= strlen(shProg
->data
->UniformStorage
[i
].name
) + 1 +
677 ((shProg
->data
->UniformStorage
[i
].array_elements
!= 0) ? 3 : 0);
686 case GL_TRANSFORM_FEEDBACK_VARYINGS
:
689 *params
= shProg
->TransformFeedback
.NumVarying
;
691 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
: {
697 for (i
= 0; i
< shProg
->TransformFeedback
.NumVarying
; i
++) {
698 /* Add one for the terminating NUL character.
701 strlen(shProg
->TransformFeedback
.VaryingNames
[i
]) + 1;
710 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE
:
713 *params
= shProg
->TransformFeedback
.BufferMode
;
715 case GL_GEOMETRY_VERTICES_OUT
:
718 if (check_gs_query(ctx
, shProg
)) {
719 *params
= shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->
720 Program
->info
.gs
.vertices_out
;
723 case GL_GEOMETRY_SHADER_INVOCATIONS
:
724 if (!has_core_gs
|| !ctx
->Extensions
.ARB_gpu_shader5
)
726 if (check_gs_query(ctx
, shProg
)) {
727 *params
= shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->
728 Program
->info
.gs
.invocations
;
731 case GL_GEOMETRY_INPUT_TYPE
:
734 if (check_gs_query(ctx
, shProg
)) {
735 *params
= shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->
736 Program
->info
.gs
.input_primitive
;
739 case GL_GEOMETRY_OUTPUT_TYPE
:
742 if (check_gs_query(ctx
, shProg
)) {
743 *params
= shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->
744 Program
->info
.gs
.output_primitive
;
747 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH
: {
754 for (i
= 0; i
< shProg
->data
->NumUniformBlocks
; i
++) {
755 /* Add one for the terminating NUL character.
757 const GLint len
= strlen(shProg
->data
->UniformBlocks
[i
].Name
) + 1;
766 case GL_ACTIVE_UNIFORM_BLOCKS
:
770 *params
= shProg
->data
->NumUniformBlocks
;
772 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT
:
773 /* This enum isn't part of the OES extension for OpenGL ES 2.0. It is
774 * only available with desktop OpenGL 3.0+ with the
775 * GL_ARB_get_program_binary extension or OpenGL ES 3.0.
777 * On desktop, we ignore the 3.0+ requirement because it is silly.
779 if (!_mesa_is_desktop_gl(ctx
) && !_mesa_is_gles3(ctx
))
782 *params
= shProg
->BinaryRetreivableHint
;
784 case GL_PROGRAM_BINARY_LENGTH
:
787 case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS
:
788 if (!ctx
->Extensions
.ARB_shader_atomic_counters
)
791 *params
= shProg
->data
->NumAtomicBuffers
;
793 case GL_COMPUTE_WORK_GROUP_SIZE
: {
795 if (!_mesa_has_compute_shaders(ctx
))
797 if (!shProg
->data
->LinkStatus
) {
798 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramiv(program not "
802 if (shProg
->_LinkedShaders
[MESA_SHADER_COMPUTE
] == NULL
) {
803 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramiv(no compute "
807 for (i
= 0; i
< 3; i
++)
808 params
[i
] = shProg
->_LinkedShaders
[MESA_SHADER_COMPUTE
]->
809 Program
->info
.cs
.local_size
[i
];
812 case GL_PROGRAM_SEPARABLE
:
813 /* If the program has not been linked, return initial value 0. */
814 *params
= (shProg
->data
->LinkStatus
== linking_failure
) ? 0 : shProg
->SeparateShader
;
817 /* ARB_tessellation_shader */
818 case GL_TESS_CONTROL_OUTPUT_VERTICES
:
821 if (check_tcs_query(ctx
, shProg
)) {
822 *params
= shProg
->_LinkedShaders
[MESA_SHADER_TESS_CTRL
]->
823 Program
->info
.tess
.tcs_vertices_out
;
826 case GL_TESS_GEN_MODE
:
829 if (check_tes_query(ctx
, shProg
)) {
830 *params
= shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
]->
831 Program
->info
.tess
.primitive_mode
;
834 case GL_TESS_GEN_SPACING
:
837 if (check_tes_query(ctx
, shProg
)) {
838 const struct gl_linked_shader
*tes
=
839 shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
];
840 switch (tes
->Program
->info
.tess
.spacing
) {
841 case TESS_SPACING_EQUAL
:
844 case TESS_SPACING_FRACTIONAL_ODD
:
845 *params
= GL_FRACTIONAL_ODD
;
847 case TESS_SPACING_FRACTIONAL_EVEN
:
848 *params
= GL_FRACTIONAL_EVEN
;
850 case TESS_SPACING_UNSPECIFIED
:
856 case GL_TESS_GEN_VERTEX_ORDER
:
859 if (check_tes_query(ctx
, shProg
)) {
860 *params
= shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
]->
861 Program
->info
.tess
.ccw
? GL_CCW
: GL_CW
;
864 case GL_TESS_GEN_POINT_MODE
:
867 if (check_tes_query(ctx
, shProg
)) {
868 *params
= shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
]->
869 Program
->info
.tess
.point_mode
? GL_TRUE
: GL_FALSE
;
876 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname=%s)",
877 _mesa_enum_to_string(pname
));
882 * glGetShaderiv() - get GLSL shader state
885 get_shaderiv(struct gl_context
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
887 struct gl_shader
*shader
=
888 _mesa_lookup_shader_err(ctx
, name
, "glGetShaderiv");
896 *params
= shader
->Type
;
898 case GL_DELETE_STATUS
:
899 *params
= shader
->DeletePending
;
901 case GL_COMPILE_STATUS
:
902 *params
= shader
->CompileStatus
? GL_TRUE
: GL_FALSE
;
904 case GL_INFO_LOG_LENGTH
:
905 *params
= (shader
->InfoLog
&& shader
->InfoLog
[0] != '\0') ?
906 strlen(shader
->InfoLog
) + 1 : 0;
908 case GL_SHADER_SOURCE_LENGTH
:
909 *params
= shader
->Source
? strlen((char *) shader
->Source
) + 1 : 0;
912 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
919 get_program_info_log(struct gl_context
*ctx
, GLuint program
, GLsizei bufSize
,
920 GLsizei
*length
, GLchar
*infoLog
)
922 struct gl_shader_program
*shProg
;
924 /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
925 * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
927 * "If a negative number is provided where an argument of type sizei or
928 * sizeiptr is specified, an INVALID_VALUE error is generated."
931 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(bufSize < 0)");
935 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
936 "glGetProgramInfoLog(program)");
941 _mesa_copy_string(infoLog
, bufSize
, length
, shProg
->data
->InfoLog
);
946 get_shader_info_log(struct gl_context
*ctx
, GLuint shader
, GLsizei bufSize
,
947 GLsizei
*length
, GLchar
*infoLog
)
949 struct gl_shader
*sh
;
951 /* Section 2.5 GL Errors (page 18) of the OpenGL ES 3.0.4 spec and
952 * section 2.3.1 (Errors) of the OpenGL 4.5 spec say:
954 * "If a negative number is provided where an argument of type sizei or
955 * sizeiptr is specified, an INVALID_VALUE error is generated."
958 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(bufSize < 0)");
962 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderInfoLog(shader)");
967 _mesa_copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
972 * Return shader source code.
975 get_shader_source(struct gl_context
*ctx
, GLuint shader
, GLsizei maxLength
,
976 GLsizei
*length
, GLchar
*sourceOut
)
978 struct gl_shader
*sh
;
981 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(bufSize < 0)");
985 sh
= _mesa_lookup_shader_err(ctx
, shader
, "glGetShaderSource");
989 _mesa_copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
994 * Set/replace shader source code. A helper function used by
995 * glShaderSource[ARB].
998 shader_source(struct gl_shader
*sh
, const GLchar
*source
)
1002 if (sh
->CompileStatus
== compile_skipped
&& !sh
->FallbackSource
) {
1003 /* If shader was previously compiled back-up the source in case of cache
1006 sh
->FallbackSource
= sh
->Source
;
1007 sh
->Source
= source
;
1009 /* free old shader source string and install new one */
1010 free((void *)sh
->Source
);
1011 sh
->Source
= source
;
1015 sh
->SourceChecksum
= util_hash_crc32(sh
->Source
, strlen(sh
->Source
));
1024 _mesa_compile_shader(struct gl_context
*ctx
, struct gl_shader
*sh
)
1030 /* If the user called glCompileShader without first calling
1031 * glShaderSource, we should fail to compile, but not raise a GL_ERROR.
1033 sh
->CompileStatus
= compile_failure
;
1035 if (ctx
->_Shader
->Flags
& GLSL_DUMP
) {
1036 _mesa_log("GLSL source for %s shader %d:\n",
1037 _mesa_shader_stage_to_string(sh
->Stage
), sh
->Name
);
1038 _mesa_log("%s\n", sh
->Source
);
1041 /* this call will set the shader->CompileStatus field to indicate if
1042 * compilation was successful.
1044 _mesa_glsl_compile_shader(ctx
, sh
, false, false, false);
1046 if (ctx
->_Shader
->Flags
& GLSL_LOG
) {
1047 _mesa_write_shader_to_file(sh
);
1050 if (ctx
->_Shader
->Flags
& GLSL_DUMP
) {
1051 if (sh
->CompileStatus
) {
1053 _mesa_log("GLSL IR for shader %d:\n", sh
->Name
);
1054 _mesa_print_ir(_mesa_get_log_file(), sh
->ir
, NULL
);
1056 _mesa_log("No GLSL IR for shader %d (shader may be from "
1057 "cache)\n", sh
->Name
);
1061 _mesa_log("GLSL shader %d failed to compile.\n", sh
->Name
);
1063 if (sh
->InfoLog
&& sh
->InfoLog
[0] != 0) {
1064 _mesa_log("GLSL shader %d info log:\n", sh
->Name
);
1065 _mesa_log("%s\n", sh
->InfoLog
);
1070 if (!sh
->CompileStatus
) {
1071 if (ctx
->_Shader
->Flags
& GLSL_DUMP_ON_ERROR
) {
1072 _mesa_log("GLSL source for %s shader %d:\n",
1073 _mesa_shader_stage_to_string(sh
->Stage
), sh
->Name
);
1074 _mesa_log("%s\n", sh
->Source
);
1075 _mesa_log("Info Log:\n%s\n", sh
->InfoLog
);
1078 if (ctx
->_Shader
->Flags
& GLSL_REPORT_ERRORS
) {
1079 _mesa_debug(ctx
, "Error compiling shader %u:\n%s\n",
1080 sh
->Name
, sh
->InfoLog
);
1087 * Link a program's shaders.
1090 _mesa_link_program(struct gl_context
*ctx
, struct gl_shader_program
*shProg
)
1095 /* From the ARB_transform_feedback2 specification:
1096 * "The error INVALID_OPERATION is generated by LinkProgram if <program> is
1097 * the name of a program being used by one or more transform feedback
1098 * objects, even if the objects are not currently bound or are paused."
1100 if (_mesa_transform_feedback_is_using_program(ctx
, shProg
)) {
1101 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1102 "glLinkProgram(transform feedback is using the program)");
1106 unsigned programs_in_use
= 0;
1108 for (unsigned stage
= 0; stage
< MESA_SHADER_STAGES
; stage
++) {
1109 if (ctx
->_Shader
->CurrentProgram
[stage
] &&
1110 ctx
->_Shader
->CurrentProgram
[stage
]->Id
== shProg
->Name
) {
1111 programs_in_use
|= 1 << stage
;
1115 FLUSH_VERTICES(ctx
, 0);
1116 _mesa_glsl_link_shader(ctx
, shProg
);
1118 /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec:
1120 * "If LinkProgram or ProgramBinary successfully re-links a program
1121 * object that is active for any shader stage, then the newly generated
1122 * executable code will be installed as part of the current rendering
1123 * state for all shader stages where the program is active.
1124 * Additionally, the newly generated executable code is made part of
1125 * the state of any program pipeline for all stages where the program
1128 if (shProg
->data
->LinkStatus
&& programs_in_use
) {
1129 while (programs_in_use
) {
1130 const int stage
= u_bit_scan(&programs_in_use
);
1132 struct gl_program
*prog
= NULL
;
1133 if (shProg
->_LinkedShaders
[stage
])
1134 prog
= shProg
->_LinkedShaders
[stage
]->Program
;
1136 _mesa_use_program(ctx
, stage
, shProg
, prog
, ctx
->_Shader
);
1140 /* Capture .shader_test files. */
1141 const char *capture_path
= _mesa_get_shader_capture_path();
1142 if (shProg
->Name
!= 0 && shProg
->Name
!= ~0 && capture_path
!= NULL
) {
1144 char *filename
= ralloc_asprintf(NULL
, "%s/%u.shader_test",
1145 capture_path
, shProg
->Name
);
1146 file
= fopen(filename
, "w");
1148 fprintf(file
, "[require]\nGLSL%s >= %u.%02u\n",
1149 shProg
->IsES
? " ES" : "",
1150 shProg
->data
->Version
/ 100, shProg
->data
->Version
% 100);
1151 if (shProg
->SeparateShader
)
1152 fprintf(file
, "GL_ARB_separate_shader_objects\nSSO ENABLED\n");
1153 fprintf(file
, "\n");
1155 for (unsigned i
= 0; i
< shProg
->NumShaders
; i
++) {
1156 fprintf(file
, "[%s shader]\n%s\n",
1157 _mesa_shader_stage_to_string(shProg
->Shaders
[i
]->Stage
),
1158 shProg
->Shaders
[i
]->Source
);
1162 _mesa_warning(ctx
, "Failed to open %s", filename
);
1165 ralloc_free(filename
);
1168 if (shProg
->data
->LinkStatus
== linking_failure
&&
1169 (ctx
->_Shader
->Flags
& GLSL_REPORT_ERRORS
)) {
1170 _mesa_debug(ctx
, "Error linking program %u:\n%s\n",
1171 shProg
->Name
, shProg
->data
->InfoLog
);
1178 printf("Link %u shaders in program %u: %s\n",
1179 shProg
->NumShaders
, shProg
->Name
,
1180 shProg
->data
->LinkStatus
? "Success" : "Failed");
1182 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1183 printf(" shader %u, stage %u\n",
1184 shProg
->Shaders
[i
]->Name
,
1185 shProg
->Shaders
[i
]->Stage
);
1192 * Print basic shader info (for debug).
1195 print_shader_info(const struct gl_shader_program
*shProg
)
1199 printf("Mesa: glUseProgram(%u)\n", shProg
->Name
);
1200 for (i
= 0; i
< shProg
->NumShaders
; i
++) {
1202 printf(" %s shader %u, checksum %u\n",
1203 _mesa_shader_stage_to_string(shProg
->Shaders
[i
]->Stage
),
1204 shProg
->Shaders
[i
]->Name
,
1205 shProg
->Shaders
[i
]->SourceChecksum
);
1207 printf(" %s shader %u\n",
1208 _mesa_shader_stage_to_string(shProg
->Shaders
[i
]->Stage
),
1209 shProg
->Shaders
[i
]->Name
);
1212 if (shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
])
1213 printf(" vert prog %u\n",
1214 shProg
->_LinkedShaders
[MESA_SHADER_VERTEX
]->Program
->Id
);
1215 if (shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
])
1216 printf(" frag prog %u\n",
1217 shProg
->_LinkedShaders
[MESA_SHADER_FRAGMENT
]->Program
->Id
);
1218 if (shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
])
1219 printf(" geom prog %u\n",
1220 shProg
->_LinkedShaders
[MESA_SHADER_GEOMETRY
]->Program
->Id
);
1221 if (shProg
->_LinkedShaders
[MESA_SHADER_TESS_CTRL
])
1222 printf(" tesc prog %u\n",
1223 shProg
->_LinkedShaders
[MESA_SHADER_TESS_CTRL
]->Program
->Id
);
1224 if (shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
])
1225 printf(" tese prog %u\n",
1226 shProg
->_LinkedShaders
[MESA_SHADER_TESS_EVAL
]->Program
->Id
);
1231 * Use the named shader program for subsequent glUniform calls
1234 _mesa_active_program(struct gl_context
*ctx
, struct gl_shader_program
*shProg
,
1237 if ((shProg
!= NULL
) && !shProg
->data
->LinkStatus
) {
1238 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1239 "%s(program %u not linked)", caller
, shProg
->Name
);
1243 if (ctx
->Shader
.ActiveProgram
!= shProg
) {
1244 _mesa_reference_shader_program(ctx
, &ctx
->Shader
.ActiveProgram
, shProg
);
1250 use_program(struct gl_context
*ctx
, gl_shader_stage stage
,
1251 struct gl_shader_program
*shProg
, struct gl_program
*new_prog
,
1252 struct gl_pipeline_object
*shTarget
)
1254 struct gl_program
**target
;
1256 target
= &shTarget
->CurrentProgram
[stage
];
1258 _mesa_program_init_subroutine_defaults(ctx
, new_prog
);
1261 if (*target
!= new_prog
) {
1262 /* Program is current, flush it */
1263 if (shTarget
== ctx
->_Shader
) {
1264 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
| _NEW_PROGRAM_CONSTANTS
);
1267 /* If the shader is also bound as the current rendering shader, unbind
1268 * it from that binding point as well. This ensures that the correct
1269 * semantics of glDeleteProgram are maintained.
1272 case MESA_SHADER_VERTEX
:
1273 case MESA_SHADER_TESS_CTRL
:
1274 case MESA_SHADER_TESS_EVAL
:
1275 case MESA_SHADER_GEOMETRY
:
1276 case MESA_SHADER_COMPUTE
:
1277 /* Empty for now. */
1279 case MESA_SHADER_FRAGMENT
:
1280 if (*target
== ctx
->_Shader
->_CurrentFragmentProgram
) {
1281 _mesa_reference_program(ctx
,
1282 &ctx
->_Shader
->_CurrentFragmentProgram
,
1288 _mesa_reference_shader_program(ctx
,
1289 &shTarget
->ReferencedPrograms
[stage
],
1291 _mesa_reference_program(ctx
, target
, new_prog
);
1298 * Use the named shader program for subsequent rendering.
1301 _mesa_use_shader_program(struct gl_context
*ctx
,
1302 struct gl_shader_program
*shProg
)
1304 for (int i
= 0; i
< MESA_SHADER_STAGES
; i
++) {
1305 struct gl_program
*new_prog
= NULL
;
1306 if (shProg
&& shProg
->_LinkedShaders
[i
])
1307 new_prog
= shProg
->_LinkedShaders
[i
]->Program
;
1308 use_program(ctx
, i
, shProg
, new_prog
, &ctx
->Shader
);
1310 _mesa_active_program(ctx
, shProg
, "glUseProgram");
1315 * Do validation of the given shader program.
1316 * \param errMsg returns error message if validation fails.
1317 * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
1320 validate_shader_program(const struct gl_shader_program
*shProg
,
1323 if (!shProg
->data
->LinkStatus
) {
1327 /* From the GL spec, a program is invalid if any of these are true:
1329 any two active samplers in the current program object are of
1330 different types, but refer to the same texture image unit,
1332 any active sampler in the current program object refers to a texture
1333 image unit where fixed-function fragment processing accesses a
1334 texture target that does not match the sampler type, or
1336 the sum of the number of active samplers in the program and the
1337 number of texture image units enabled for fixed-function fragment
1338 processing exceeds the combined limit on the total number of texture
1339 image units allowed.
1343 * Check: any two active samplers in the current program object are of
1344 * different types, but refer to the same texture image unit,
1346 if (!_mesa_sampler_uniforms_are_valid(shProg
, errMsg
, 100))
1354 * Called via glValidateProgram()
1357 validate_program(struct gl_context
*ctx
, GLuint program
)
1359 struct gl_shader_program
*shProg
;
1360 char errMsg
[100] = "";
1362 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glValidateProgram");
1367 shProg
->data
->Validated
= validate_shader_program(shProg
, errMsg
);
1368 if (!shProg
->data
->Validated
) {
1369 /* update info log */
1370 if (shProg
->data
->InfoLog
) {
1371 ralloc_free(shProg
->data
->InfoLog
);
1373 shProg
->data
->InfoLog
= ralloc_strdup(shProg
->data
, errMsg
);
1380 _mesa_AttachObjectARB(GLhandleARB program
, GLhandleARB shader
)
1382 GET_CURRENT_CONTEXT(ctx
);
1383 attach_shader(ctx
, program
, shader
);
1388 _mesa_AttachShader(GLuint program
, GLuint shader
)
1390 GET_CURRENT_CONTEXT(ctx
);
1391 attach_shader(ctx
, program
, shader
);
1396 _mesa_CompileShader(GLuint shaderObj
)
1398 GET_CURRENT_CONTEXT(ctx
);
1399 if (MESA_VERBOSE
& VERBOSE_API
)
1400 _mesa_debug(ctx
, "glCompileShader %u\n", shaderObj
);
1401 _mesa_compile_shader(ctx
, _mesa_lookup_shader_err(ctx
, shaderObj
,
1402 "glCompileShader"));
1407 _mesa_CreateShader(GLenum type
)
1409 GET_CURRENT_CONTEXT(ctx
);
1410 if (MESA_VERBOSE
& VERBOSE_API
)
1411 _mesa_debug(ctx
, "glCreateShader %s\n", _mesa_enum_to_string(type
));
1412 return create_shader(ctx
, type
);
1416 GLhandleARB GLAPIENTRY
1417 _mesa_CreateShaderObjectARB(GLenum type
)
1419 GET_CURRENT_CONTEXT(ctx
);
1420 return create_shader(ctx
, type
);
1425 _mesa_CreateProgram(void)
1427 GET_CURRENT_CONTEXT(ctx
);
1428 if (MESA_VERBOSE
& VERBOSE_API
)
1429 _mesa_debug(ctx
, "glCreateProgram\n");
1430 return create_shader_program(ctx
);
1434 GLhandleARB GLAPIENTRY
1435 _mesa_CreateProgramObjectARB(void)
1437 GET_CURRENT_CONTEXT(ctx
);
1438 return create_shader_program(ctx
);
1443 _mesa_DeleteObjectARB(GLhandleARB obj
)
1445 if (MESA_VERBOSE
& VERBOSE_API
) {
1446 GET_CURRENT_CONTEXT(ctx
);
1447 _mesa_debug(ctx
, "glDeleteObjectARB(%lu)\n", (unsigned long)obj
);
1451 GET_CURRENT_CONTEXT(ctx
);
1452 FLUSH_VERTICES(ctx
, 0);
1453 if (is_program(ctx
, obj
)) {
1454 delete_shader_program(ctx
, obj
);
1456 else if (is_shader(ctx
, obj
)) {
1457 delete_shader(ctx
, obj
);
1467 _mesa_DeleteProgram(GLuint name
)
1470 GET_CURRENT_CONTEXT(ctx
);
1471 FLUSH_VERTICES(ctx
, 0);
1472 delete_shader_program(ctx
, name
);
1478 _mesa_DeleteShader(GLuint name
)
1481 GET_CURRENT_CONTEXT(ctx
);
1482 FLUSH_VERTICES(ctx
, 0);
1483 delete_shader(ctx
, name
);
1489 _mesa_DetachObjectARB(GLhandleARB program
, GLhandleARB shader
)
1491 GET_CURRENT_CONTEXT(ctx
);
1492 detach_shader(ctx
, program
, shader
);
1497 _mesa_DetachShader(GLuint program
, GLuint shader
)
1499 GET_CURRENT_CONTEXT(ctx
);
1500 detach_shader(ctx
, program
, shader
);
1505 _mesa_GetAttachedObjectsARB(GLhandleARB container
, GLsizei maxCount
,
1506 GLsizei
* count
, GLhandleARB
* obj
)
1508 GET_CURRENT_CONTEXT(ctx
);
1509 get_attached_shaders(ctx
, container
, maxCount
, count
, obj
);
1514 _mesa_GetAttachedShaders(GLuint program
, GLsizei maxCount
,
1515 GLsizei
*count
, GLuint
*obj
)
1517 GET_CURRENT_CONTEXT(ctx
);
1518 get_attached_shaders(ctx
, program
, maxCount
, count
, obj
);
1523 _mesa_GetInfoLogARB(GLhandleARB object
, GLsizei maxLength
, GLsizei
* length
,
1524 GLcharARB
* infoLog
)
1526 GET_CURRENT_CONTEXT(ctx
);
1527 if (is_program(ctx
, object
)) {
1528 get_program_info_log(ctx
, object
, maxLength
, length
, infoLog
);
1530 else if (is_shader(ctx
, object
)) {
1531 get_shader_info_log(ctx
, object
, maxLength
, length
, infoLog
);
1534 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetInfoLogARB");
1540 _mesa_GetObjectParameterivARB(GLhandleARB object
, GLenum pname
, GLint
*params
)
1542 GET_CURRENT_CONTEXT(ctx
);
1543 /* Implement in terms of GetProgramiv, GetShaderiv */
1544 if (is_program(ctx
, object
)) {
1545 if (pname
== GL_OBJECT_TYPE_ARB
) {
1546 *params
= GL_PROGRAM_OBJECT_ARB
;
1549 get_programiv(ctx
, object
, pname
, params
);
1552 else if (is_shader(ctx
, object
)) {
1553 if (pname
== GL_OBJECT_TYPE_ARB
) {
1554 *params
= GL_SHADER_OBJECT_ARB
;
1557 get_shaderiv(ctx
, object
, pname
, params
);
1561 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetObjectParameterivARB");
1567 _mesa_GetObjectParameterfvARB(GLhandleARB object
, GLenum pname
,
1570 GLint iparams
[1] = {0}; /* XXX is one element enough? */
1571 _mesa_GetObjectParameterivARB(object
, pname
, iparams
);
1572 params
[0] = (GLfloat
) iparams
[0];
1577 _mesa_GetProgramiv(GLuint program
, GLenum pname
, GLint
*params
)
1579 GET_CURRENT_CONTEXT(ctx
);
1580 get_programiv(ctx
, program
, pname
, params
);
1585 _mesa_GetShaderiv(GLuint shader
, GLenum pname
, GLint
*params
)
1587 GET_CURRENT_CONTEXT(ctx
);
1588 get_shaderiv(ctx
, shader
, pname
, params
);
1593 _mesa_GetProgramInfoLog(GLuint program
, GLsizei bufSize
,
1594 GLsizei
*length
, GLchar
*infoLog
)
1596 GET_CURRENT_CONTEXT(ctx
);
1597 get_program_info_log(ctx
, program
, bufSize
, length
, infoLog
);
1602 _mesa_GetShaderInfoLog(GLuint shader
, GLsizei bufSize
,
1603 GLsizei
*length
, GLchar
*infoLog
)
1605 GET_CURRENT_CONTEXT(ctx
);
1606 get_shader_info_log(ctx
, shader
, bufSize
, length
, infoLog
);
1611 _mesa_GetShaderSource(GLuint shader
, GLsizei maxLength
,
1612 GLsizei
*length
, GLchar
*sourceOut
)
1614 GET_CURRENT_CONTEXT(ctx
);
1615 get_shader_source(ctx
, shader
, maxLength
, length
, sourceOut
);
1619 GLhandleARB GLAPIENTRY
1620 _mesa_GetHandleARB(GLenum pname
)
1622 GET_CURRENT_CONTEXT(ctx
);
1623 return get_handle(ctx
, pname
);
1627 GLboolean GLAPIENTRY
1628 _mesa_IsProgram(GLuint name
)
1630 GET_CURRENT_CONTEXT(ctx
);
1631 return is_program(ctx
, name
);
1635 GLboolean GLAPIENTRY
1636 _mesa_IsShader(GLuint name
)
1638 GET_CURRENT_CONTEXT(ctx
);
1639 return is_shader(ctx
, name
);
1644 _mesa_LinkProgram(GLuint programObj
)
1646 GET_CURRENT_CONTEXT(ctx
);
1647 if (MESA_VERBOSE
& VERBOSE_API
)
1648 _mesa_debug(ctx
, "glLinkProgram %u\n", programObj
);
1649 _mesa_link_program(ctx
, _mesa_lookup_shader_program_err(ctx
, programObj
,
1653 #ifdef ENABLE_SHADER_CACHE
1655 * Generate a SHA-1 hash value string for given source string.
1658 generate_sha1(const char *source
, char sha_str
[64])
1660 unsigned char sha
[20];
1661 _mesa_sha1_compute(source
, strlen(source
), sha
);
1662 _mesa_sha1_format(sha_str
, sha
);
1666 * Construct a full path for shader replacement functionality using
1669 * <path>/<stage prefix>_<CHECKSUM>.glsl
1672 construct_name(const gl_shader_stage stage
, const char *source
,
1676 static const char *types
[] = {
1677 "VS", "TC", "TE", "GS", "FS", "CS",
1680 generate_sha1(source
, sha
);
1681 return ralloc_asprintf(NULL
, "%s/%s_%s.glsl", path
, types
[stage
], sha
);
1685 * Write given shader source to a file in MESA_SHADER_DUMP_PATH.
1688 dump_shader(const gl_shader_stage stage
, const char *source
)
1690 static bool path_exists
= true;
1697 dump_path
= getenv("MESA_SHADER_DUMP_PATH");
1699 path_exists
= false;
1703 char *name
= construct_name(stage
, source
, dump_path
);
1705 f
= fopen(name
, "w");
1710 GET_CURRENT_CONTEXT(ctx
);
1711 _mesa_warning(ctx
, "could not open %s for dumping shader (%s)", name
,
1718 * Read shader source code from a file.
1719 * Useful for debugging to override an app's shader.
1722 read_shader(const gl_shader_stage stage
, const char *source
)
1725 static bool path_exists
= true;
1726 int len
, shader_size
= 0;
1733 read_path
= getenv("MESA_SHADER_READ_PATH");
1735 path_exists
= false;
1739 char *name
= construct_name(stage
, source
, read_path
);
1740 f
= fopen(name
, "r");
1745 /* allocate enough room for the entire shader */
1746 fseek(f
, 0, SEEK_END
);
1747 shader_size
= ftell(f
);
1749 assert(shader_size
);
1751 /* add one for terminating zero */
1754 buffer
= malloc(shader_size
);
1757 len
= fread(buffer
, 1, shader_size
, f
);
1765 #endif /* ENABLE_SHADER_CACHE */
1768 * Called via glShaderSource() and glShaderSourceARB() API functions.
1769 * Basically, concatenate the source code strings into one long string
1770 * and pass it to _mesa_shader_source().
1773 _mesa_ShaderSource(GLuint shaderObj
, GLsizei count
,
1774 const GLchar
* const * string
, const GLint
* length
)
1776 GET_CURRENT_CONTEXT(ctx
);
1778 GLsizei i
, totalLength
;
1780 struct gl_shader
*sh
;
1782 sh
= _mesa_lookup_shader_err(ctx
, shaderObj
, "glShaderSourceARB");
1786 if (string
== NULL
) {
1787 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSourceARB");
1792 * This array holds offsets of where the appropriate string ends, thus the
1793 * last element will be set to the total length of the source code.
1795 offsets
= malloc(count
* sizeof(GLint
));
1796 if (offsets
== NULL
) {
1797 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glShaderSourceARB");
1801 for (i
= 0; i
< count
; i
++) {
1802 if (string
[i
] == NULL
) {
1803 free((GLvoid
*) offsets
);
1804 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1805 "glShaderSourceARB(null string)");
1808 if (length
== NULL
|| length
[i
] < 0)
1809 offsets
[i
] = strlen(string
[i
]);
1811 offsets
[i
] = length
[i
];
1812 /* accumulate string lengths */
1814 offsets
[i
] += offsets
[i
- 1];
1817 /* Total length of source string is sum off all strings plus two.
1818 * One extra byte for terminating zero, another extra byte to silence
1819 * valgrind warnings in the parser/grammer code.
1821 totalLength
= offsets
[count
- 1] + 2;
1822 source
= malloc(totalLength
* sizeof(GLcharARB
));
1823 if (source
== NULL
) {
1824 free((GLvoid
*) offsets
);
1825 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glShaderSourceARB");
1829 for (i
= 0; i
< count
; i
++) {
1830 GLint start
= (i
> 0) ? offsets
[i
- 1] : 0;
1831 memcpy(source
+ start
, string
[i
],
1832 (offsets
[i
] - start
) * sizeof(GLcharARB
));
1834 source
[totalLength
- 1] = '\0';
1835 source
[totalLength
- 2] = '\0';
1837 #ifdef ENABLE_SHADER_CACHE
1838 GLcharARB
*replacement
;
1840 /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace
1841 * if corresponding entry found from MESA_SHADER_READ_PATH.
1843 dump_shader(sh
->Stage
, source
);
1845 replacement
= read_shader(sh
->Stage
, source
);
1848 source
= replacement
;
1850 #endif /* ENABLE_SHADER_CACHE */
1852 shader_source(sh
, source
);
1859 _mesa_UseProgram(GLuint program
)
1861 GET_CURRENT_CONTEXT(ctx
);
1862 struct gl_shader_program
*shProg
;
1864 if (MESA_VERBOSE
& VERBOSE_API
)
1865 _mesa_debug(ctx
, "glUseProgram %u\n", program
);
1867 if (_mesa_is_xfb_active_and_unpaused(ctx
)) {
1868 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1869 "glUseProgram(transform feedback active)");
1874 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glUseProgram");
1878 if (!shProg
->data
->LinkStatus
) {
1879 _mesa_error(ctx
, GL_INVALID_OPERATION
,
1880 "glUseProgram(program %u not linked)", program
);
1885 if (ctx
->_Shader
->Flags
& GLSL_USE_PROG
) {
1886 print_shader_info(shProg
);
1893 /* The ARB_separate_shader_object spec says:
1895 * "The executable code for an individual shader stage is taken from
1896 * the current program for that stage. If there is a current program
1897 * object established by UseProgram, that program is considered current
1898 * for all stages. Otherwise, if there is a bound program pipeline
1899 * object (section 2.14.PPO), the program bound to the appropriate
1900 * stage of the pipeline object is considered current."
1903 /* Attach shader state to the binding point */
1904 _mesa_reference_pipeline_object(ctx
, &ctx
->_Shader
, &ctx
->Shader
);
1905 /* Update the program */
1906 _mesa_use_shader_program(ctx
, shProg
);
1908 /* Must be done first: detach the progam */
1909 _mesa_use_shader_program(ctx
, shProg
);
1910 /* Unattach shader_state binding point */
1911 _mesa_reference_pipeline_object(ctx
, &ctx
->_Shader
, ctx
->Pipeline
.Default
);
1912 /* If a pipeline was bound, rebind it */
1913 if (ctx
->Pipeline
.Current
) {
1914 _mesa_BindProgramPipeline(ctx
->Pipeline
.Current
->Name
);
1921 _mesa_ValidateProgram(GLuint program
)
1923 GET_CURRENT_CONTEXT(ctx
);
1924 validate_program(ctx
, program
);
1929 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1932 _mesa_GetShaderPrecisionFormat(GLenum shadertype
, GLenum precisiontype
,
1933 GLint
* range
, GLint
* precision
)
1935 const struct gl_program_constants
*limits
;
1936 const struct gl_precision
*p
;
1937 GET_CURRENT_CONTEXT(ctx
);
1939 switch (shadertype
) {
1940 case GL_VERTEX_SHADER
:
1941 limits
= &ctx
->Const
.Program
[MESA_SHADER_VERTEX
];
1943 case GL_FRAGMENT_SHADER
:
1944 limits
= &ctx
->Const
.Program
[MESA_SHADER_FRAGMENT
];
1947 _mesa_error(ctx
, GL_INVALID_ENUM
,
1948 "glGetShaderPrecisionFormat(shadertype)");
1952 switch (precisiontype
) {
1954 p
= &limits
->LowFloat
;
1956 case GL_MEDIUM_FLOAT
:
1957 p
= &limits
->MediumFloat
;
1960 p
= &limits
->HighFloat
;
1963 p
= &limits
->LowInt
;
1966 p
= &limits
->MediumInt
;
1969 p
= &limits
->HighInt
;
1972 _mesa_error(ctx
, GL_INVALID_ENUM
,
1973 "glGetShaderPrecisionFormat(precisiontype)");
1977 range
[0] = p
->RangeMin
;
1978 range
[1] = p
->RangeMax
;
1979 precision
[0] = p
->Precision
;
1984 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1987 _mesa_ReleaseShaderCompiler(void)
1989 _mesa_destroy_shader_compiler_caches();
1994 * For OpenGL ES 2.0, GL_ARB_ES2_compatibility
1997 _mesa_ShaderBinary(GLint n
, const GLuint
* shaders
, GLenum binaryformat
,
1998 const void* binary
, GLint length
)
2000 GET_CURRENT_CONTEXT(ctx
);
2002 (void) binaryformat
;
2005 /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and
2006 * page 88 of the OpenGL 4.5 specs state:
2008 * "An INVALID_VALUE error is generated if count or length is negative.
2009 * An INVALID_ENUM error is generated if binaryformat is not a supported
2010 * format returned in SHADER_BINARY_FORMATS."
2012 if (n
< 0 || length
< 0) {
2013 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderBinary(count or length < 0)");
2017 _mesa_error(ctx
, GL_INVALID_ENUM
, "glShaderBinary(format)");
2022 _mesa_GetProgramBinary(GLuint program
, GLsizei bufSize
, GLsizei
*length
,
2023 GLenum
*binaryFormat
, GLvoid
*binary
)
2025 struct gl_shader_program
*shProg
;
2026 GLsizei length_dummy
;
2027 GET_CURRENT_CONTEXT(ctx
);
2030 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramBinary(bufSize < 0)");
2034 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetProgramBinary");
2038 /* The ARB_get_program_binary spec says:
2040 * "If <length> is NULL, then no length is returned."
2042 * Ensure that length always points to valid storage to avoid multiple NULL
2043 * pointer checks below.
2046 length
= &length_dummy
;
2049 /* The ARB_get_program_binary spec says:
2051 * "When a program object's LINK_STATUS is FALSE, its program binary
2052 * length is zero, and a call to GetProgramBinary will generate an
2053 * INVALID_OPERATION error.
2055 if (!shProg
->data
->LinkStatus
) {
2056 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2057 "glGetProgramBinary(program %u not linked)",
2064 _mesa_error(ctx
, GL_INVALID_OPERATION
,
2065 "glGetProgramBinary(driver supports zero binary formats)");
2067 (void) binaryFormat
;
2072 _mesa_ProgramBinary(GLuint program
, GLenum binaryFormat
,
2073 const GLvoid
*binary
, GLsizei length
)
2075 struct gl_shader_program
*shProg
;
2076 GET_CURRENT_CONTEXT(ctx
);
2078 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glProgramBinary");
2082 (void) binaryFormat
;
2085 /* Section 2.3.1 (Errors) of the OpenGL 4.5 spec says:
2087 * "If a negative number is provided where an argument of type sizei or
2088 * sizeiptr is specified, an INVALID_VALUE error is generated."
2091 _mesa_error(ctx
, GL_INVALID_VALUE
, "glProgramBinary(length < 0)");
2095 /* The ARB_get_program_binary spec says:
2097 * "<binaryFormat> and <binary> must be those returned by a previous
2098 * call to GetProgramBinary, and <length> must be the length of the
2099 * program binary as returned by GetProgramBinary or GetProgramiv with
2100 * <pname> PROGRAM_BINARY_LENGTH. Loading the program binary will fail,
2101 * setting the LINK_STATUS of <program> to FALSE, if these conditions
2104 * Since any value of binaryFormat passed "is not one of those specified as
2105 * allowable for [this] command, an INVALID_ENUM error is generated."
2107 shProg
->data
->LinkStatus
= linking_failure
;
2108 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramBinary");
2113 _mesa_ProgramParameteri(GLuint program
, GLenum pname
, GLint value
)
2115 struct gl_shader_program
*shProg
;
2116 GET_CURRENT_CONTEXT(ctx
);
2118 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
2119 "glProgramParameteri");
2124 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT
:
2125 /* This enum isn't part of the OES extension for OpenGL ES 2.0, but it
2126 * is part of OpenGL ES 3.0. For the ES2 case, this function shouldn't
2127 * even be in the dispatch table, so we shouldn't need to expclicitly
2130 * On desktop, we ignore the 3.0+ requirement because it is silly.
2133 /* The ARB_get_program_binary extension spec says:
2135 * "An INVALID_VALUE error is generated if the <value> argument to
2136 * ProgramParameteri is not TRUE or FALSE."
2138 if (value
!= GL_TRUE
&& value
!= GL_FALSE
) {
2142 /* No need to notify the driver. Any changes will actually take effect
2143 * the next time the shader is linked.
2145 * The ARB_get_program_binary extension spec says:
2147 * "To indicate that a program binary is likely to be retrieved,
2148 * ProgramParameteri should be called with <pname>
2149 * PROGRAM_BINARY_RETRIEVABLE_HINT and <value> TRUE. This setting
2150 * will not be in effect until the next time LinkProgram or
2151 * ProgramBinary has been called successfully."
2153 * The resloution of issue 9 in the extension spec also says:
2155 * "The application may use the PROGRAM_BINARY_RETRIEVABLE_HINT hint
2156 * to indicate to the GL implementation that this program will
2157 * likely be saved with GetProgramBinary at some point. This will
2158 * give the GL implementation the opportunity to track any state
2159 * changes made to the program before being saved such that when it
2160 * is loaded again a recompile can be avoided."
2162 shProg
->BinaryRetreivableHint
= value
;
2165 case GL_PROGRAM_SEPARABLE
:
2166 /* Spec imply that the behavior is the same as ARB_get_program_binary
2167 * Chapter 7.3 Program Objects
2169 if (value
!= GL_TRUE
&& value
!= GL_FALSE
) {
2172 shProg
->SeparateShader
= value
;
2176 _mesa_error(ctx
, GL_INVALID_ENUM
, "glProgramParameteri(pname=%s)",
2177 _mesa_enum_to_string(pname
));
2182 _mesa_error(ctx
, GL_INVALID_VALUE
,
2183 "glProgramParameteri(pname=%s, value=%d): "
2184 "value must be 0 or 1.",
2185 _mesa_enum_to_string(pname
),
2191 _mesa_use_program(struct gl_context
*ctx
, gl_shader_stage stage
,
2192 struct gl_shader_program
*shProg
, struct gl_program
*prog
,
2193 struct gl_pipeline_object
*shTarget
)
2195 use_program(ctx
, stage
, shProg
, prog
, shTarget
);
2200 * Copy program-specific data generated by linking from the gl_shader_program
2201 * object to the gl_program object referred to by the gl_linked_shader.
2203 * This function expects _mesa_reference_program() to have been previously
2204 * called setting the gl_linked_shaders program reference.
2207 _mesa_copy_linked_program_data(const struct gl_shader_program
*src
,
2208 struct gl_linked_shader
*dst_sh
)
2210 assert(dst_sh
->Program
);
2212 struct gl_program
*dst
= dst_sh
->Program
;
2214 dst
->info
.separate_shader
= src
->SeparateShader
;
2216 switch (dst_sh
->Stage
) {
2217 case MESA_SHADER_GEOMETRY
: {
2218 dst
->info
.gs
.vertices_in
= src
->Geom
.VerticesIn
;
2219 dst
->info
.gs
.uses_end_primitive
= src
->Geom
.UsesEndPrimitive
;
2220 dst
->info
.gs
.uses_streams
= src
->Geom
.UsesStreams
;
2223 case MESA_SHADER_FRAGMENT
: {
2224 dst
->info
.fs
.depth_layout
= src
->FragDepthLayout
;
2227 case MESA_SHADER_COMPUTE
: {
2228 dst
->info
.cs
.shared_size
= src
->Comp
.SharedSize
;
2237 * ARB_separate_shader_objects: Compile & Link Program
2240 _mesa_CreateShaderProgramv(GLenum type
, GLsizei count
,
2241 const GLchar
* const *strings
)
2243 GET_CURRENT_CONTEXT(ctx
);
2245 const GLuint shader
= create_shader(ctx
, type
);
2249 * According to OpenGL 4.5 and OpenGL ES 3.1 standards, section 7.3:
2250 * GL_INVALID_VALUE should be generated if count < 0
2253 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCreateShaderProgram (count < 0)");
2258 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
2260 _mesa_ShaderSource(shader
, count
, strings
, NULL
);
2261 _mesa_compile_shader(ctx
, sh
);
2263 program
= create_shader_program(ctx
);
2265 struct gl_shader_program
*shProg
;
2266 GLint compiled
= GL_FALSE
;
2268 shProg
= _mesa_lookup_shader_program(ctx
, program
);
2270 shProg
->SeparateShader
= GL_TRUE
;
2272 get_shaderiv(ctx
, shader
, GL_COMPILE_STATUS
, &compiled
);
2274 attach_shader(ctx
, program
, shader
);
2275 _mesa_link_program(ctx
, shProg
);
2276 detach_shader(ctx
, program
, shader
);
2280 if (active
-user
-defined
-varyings
-in
-linked
-program
) {
2281 append
-error
-to
-info
-log
;
2282 shProg
->data
->LinkStatus
= linking_failure
;
2287 ralloc_strcat(&shProg
->data
->InfoLog
, sh
->InfoLog
);
2290 delete_shader(ctx
, shader
);
2298 * For GL_ARB_tessellation_shader
2300 extern void GLAPIENTRY
2301 _mesa_PatchParameteri(GLenum pname
, GLint value
)
2303 GET_CURRENT_CONTEXT(ctx
);
2305 if (!_mesa_has_tessellation(ctx
)) {
2306 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glPatchParameteri");
2310 if (pname
!= GL_PATCH_VERTICES
) {
2311 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPatchParameteri");
2315 if (value
<= 0 || value
> ctx
->Const
.MaxPatchVertices
) {
2316 _mesa_error(ctx
, GL_INVALID_VALUE
, "glPatchParameteri");
2320 ctx
->TessCtrlProgram
.patch_vertices
= value
;
2324 extern void GLAPIENTRY
2325 _mesa_PatchParameterfv(GLenum pname
, const GLfloat
*values
)
2327 GET_CURRENT_CONTEXT(ctx
);
2329 if (!_mesa_has_tessellation(ctx
)) {
2330 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glPatchParameterfv");
2335 case GL_PATCH_DEFAULT_OUTER_LEVEL
:
2336 FLUSH_VERTICES(ctx
, 0);
2337 memcpy(ctx
->TessCtrlProgram
.patch_default_outer_level
, values
,
2338 4 * sizeof(GLfloat
));
2339 ctx
->NewDriverState
|= ctx
->DriverFlags
.NewDefaultTessLevels
;
2341 case GL_PATCH_DEFAULT_INNER_LEVEL
:
2342 FLUSH_VERTICES(ctx
, 0);
2343 memcpy(ctx
->TessCtrlProgram
.patch_default_inner_level
, values
,
2344 2 * sizeof(GLfloat
));
2345 ctx
->NewDriverState
|= ctx
->DriverFlags
.NewDefaultTessLevels
;
2348 _mesa_error(ctx
, GL_INVALID_ENUM
, "glPatchParameterfv");
2354 * ARB_shader_subroutine
2357 _mesa_GetSubroutineUniformLocation(GLuint program
, GLenum shadertype
,
2360 GET_CURRENT_CONTEXT(ctx
);
2361 const char *api_name
= "glGetSubroutineUniformLocation";
2362 struct gl_shader_program
*shProg
;
2363 GLenum resource_type
;
2364 gl_shader_stage stage
;
2366 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2367 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2371 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2372 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2376 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2380 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2381 if (!shProg
->_LinkedShaders
[stage
]) {
2382 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2386 resource_type
= _mesa_shader_stage_to_subroutine_uniform(stage
);
2387 return _mesa_program_resource_location(shProg
, resource_type
, name
);
2391 _mesa_GetSubroutineIndex(GLuint program
, GLenum shadertype
,
2394 GET_CURRENT_CONTEXT(ctx
);
2395 const char *api_name
= "glGetSubroutineIndex";
2396 struct gl_shader_program
*shProg
;
2397 struct gl_program_resource
*res
;
2398 GLenum resource_type
;
2399 gl_shader_stage stage
;
2401 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2402 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2406 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2407 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2411 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2415 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2416 if (!shProg
->_LinkedShaders
[stage
]) {
2417 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2421 resource_type
= _mesa_shader_stage_to_subroutine(stage
);
2422 res
= _mesa_program_resource_find_name(shProg
, resource_type
, name
, NULL
);
2427 return _mesa_program_resource_index(shProg
, res
);
2432 _mesa_GetActiveSubroutineUniformiv(GLuint program
, GLenum shadertype
,
2433 GLuint index
, GLenum pname
, GLint
*values
)
2435 GET_CURRENT_CONTEXT(ctx
);
2436 const char *api_name
= "glGetActiveSubroutineUniformiv";
2437 struct gl_shader_program
*shProg
;
2438 struct gl_linked_shader
*sh
;
2439 gl_shader_stage stage
;
2440 struct gl_program_resource
*res
;
2441 const struct gl_uniform_storage
*uni
;
2442 GLenum resource_type
;
2445 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2446 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2450 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2451 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2455 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2459 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2460 resource_type
= _mesa_shader_stage_to_subroutine_uniform(stage
);
2462 sh
= shProg
->_LinkedShaders
[stage
];
2464 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2468 struct gl_program
*p
= shProg
->_LinkedShaders
[stage
]->Program
;
2469 if (index
>= p
->sh
.NumSubroutineUniforms
) {
2470 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name
);
2475 case GL_NUM_COMPATIBLE_SUBROUTINES
: {
2476 res
= _mesa_program_resource_find_index(shProg
, resource_type
, index
);
2479 values
[0] = uni
->num_compatible_subroutines
;
2483 case GL_COMPATIBLE_SUBROUTINES
: {
2484 res
= _mesa_program_resource_find_index(shProg
, resource_type
, index
);
2488 for (i
= 0; i
< p
->sh
.NumSubroutineFunctions
; i
++) {
2489 struct gl_subroutine_function
*fn
= &p
->sh
.SubroutineFunctions
[i
];
2490 for (j
= 0; j
< fn
->num_compat_types
; j
++) {
2491 if (fn
->types
[j
] == uni
->type
) {
2492 values
[count
++] = i
;
2500 case GL_UNIFORM_SIZE
:
2501 res
= _mesa_program_resource_find_index(shProg
, resource_type
, index
);
2504 values
[0] = uni
->array_elements
? uni
->array_elements
: 1;
2507 case GL_UNIFORM_NAME_LENGTH
:
2508 res
= _mesa_program_resource_find_index(shProg
, resource_type
, index
);
2510 values
[0] = strlen(_mesa_program_resource_name(res
)) + 1
2511 + ((_mesa_program_resource_array_size(res
) != 0) ? 3 : 0);
2515 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2522 _mesa_GetActiveSubroutineUniformName(GLuint program
, GLenum shadertype
,
2523 GLuint index
, GLsizei bufsize
,
2524 GLsizei
*length
, GLchar
*name
)
2526 GET_CURRENT_CONTEXT(ctx
);
2527 const char *api_name
= "glGetActiveSubroutineUniformName";
2528 struct gl_shader_program
*shProg
;
2529 GLenum resource_type
;
2530 gl_shader_stage stage
;
2532 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2533 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2537 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2538 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2542 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2546 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2547 if (!shProg
->_LinkedShaders
[stage
]) {
2548 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2552 resource_type
= _mesa_shader_stage_to_subroutine_uniform(stage
);
2553 /* get program resource name */
2554 _mesa_get_program_resource_name(shProg
, resource_type
,
2556 length
, name
, api_name
);
2561 _mesa_GetActiveSubroutineName(GLuint program
, GLenum shadertype
,
2562 GLuint index
, GLsizei bufsize
,
2563 GLsizei
*length
, GLchar
*name
)
2565 GET_CURRENT_CONTEXT(ctx
);
2566 const char *api_name
= "glGetActiveSubroutineName";
2567 struct gl_shader_program
*shProg
;
2568 GLenum resource_type
;
2569 gl_shader_stage stage
;
2571 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2572 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2576 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2577 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2581 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2585 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2586 if (!shProg
->_LinkedShaders
[stage
]) {
2587 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2590 resource_type
= _mesa_shader_stage_to_subroutine(stage
);
2591 _mesa_get_program_resource_name(shProg
, resource_type
,
2593 length
, name
, api_name
);
2597 _mesa_UniformSubroutinesuiv(GLenum shadertype
, GLsizei count
,
2598 const GLuint
*indices
)
2600 GET_CURRENT_CONTEXT(ctx
);
2601 const char *api_name
= "glUniformSubroutinesuiv";
2602 gl_shader_stage stage
;
2605 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2606 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2610 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2611 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2615 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2616 struct gl_program
*p
= ctx
->_Shader
->CurrentProgram
[stage
];
2618 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2622 if (count
!= p
->sh
.NumSubroutineUniformRemapTable
) {
2623 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s", api_name
);
2629 struct gl_uniform_storage
*uni
= p
->sh
.SubroutineUniformRemapTable
[i
];
2635 int uni_count
= uni
->array_elements
? uni
->array_elements
: 1;
2638 for (j
= i
; j
< i
+ uni_count
; j
++) {
2639 struct gl_subroutine_function
*subfn
= NULL
;
2640 if (indices
[j
] > p
->sh
.MaxSubroutineFunctionIndex
) {
2641 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s", api_name
);
2645 for (f
= 0; f
< p
->sh
.NumSubroutineFunctions
; f
++) {
2646 if (p
->sh
.SubroutineFunctions
[f
].index
== indices
[j
])
2647 subfn
= &p
->sh
.SubroutineFunctions
[f
];
2654 for (k
= 0; k
< subfn
->num_compat_types
; k
++) {
2655 if (subfn
->types
[k
] == uni
->type
)
2658 if (k
== subfn
->num_compat_types
) {
2659 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2663 ctx
->SubroutineIndex
[p
->info
.stage
].IndexPtr
[j
] = indices
[j
];
2668 FLUSH_VERTICES(ctx
, _NEW_PROGRAM_CONSTANTS
);
2673 _mesa_GetUniformSubroutineuiv(GLenum shadertype
, GLint location
,
2676 GET_CURRENT_CONTEXT(ctx
);
2677 const char *api_name
= "glGetUniformSubroutineuiv";
2678 gl_shader_stage stage
;
2680 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2681 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2685 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2686 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2690 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2691 struct gl_program
*p
= ctx
->_Shader
->CurrentProgram
[stage
];
2693 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2697 if (location
>= p
->sh
.NumSubroutineUniformRemapTable
) {
2698 _mesa_error(ctx
, GL_INVALID_VALUE
, "%s", api_name
);
2702 *params
= ctx
->SubroutineIndex
[p
->info
.stage
].IndexPtr
[location
];
2707 _mesa_GetProgramStageiv(GLuint program
, GLenum shadertype
,
2708 GLenum pname
, GLint
*values
)
2710 GET_CURRENT_CONTEXT(ctx
);
2711 const char *api_name
= "glGetProgramStageiv";
2712 struct gl_shader_program
*shProg
;
2713 struct gl_linked_shader
*sh
;
2714 gl_shader_stage stage
;
2716 if (!_mesa_has_ARB_shader_subroutine(ctx
)) {
2717 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2721 if (!_mesa_validate_shader_target(ctx
, shadertype
)) {
2722 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2726 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, api_name
);
2730 stage
= _mesa_shader_enum_to_shader_stage(shadertype
);
2731 sh
= shProg
->_LinkedShaders
[stage
];
2733 /* ARB_shader_subroutine doesn't ask the program to be linked, or list any
2734 * INVALID_OPERATION in the case of not be linked.
2736 * And for some pnames, like GL_ACTIVE_SUBROUTINE_UNIFORMS, you can ask the
2737 * same info using other specs (ARB_program_interface_query), without the
2738 * need of the program to be linked, being the value for that case 0.
2740 * But at the same time, some other methods require the program to be
2741 * linked for pname related to locations, so it would be inconsistent to
2742 * not do the same here. So we are:
2743 * * Return GL_INVALID_OPERATION if not linked only for locations.
2744 * * Setting a default value of 0, to be returned if not linked.
2748 if (pname
== GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
) {
2749 _mesa_error(ctx
, GL_INVALID_OPERATION
, "%s", api_name
);
2754 struct gl_program
*p
= sh
->Program
;
2756 case GL_ACTIVE_SUBROUTINES
:
2757 values
[0] = p
->sh
.NumSubroutineFunctions
;
2759 case GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
:
2760 values
[0] = p
->sh
.NumSubroutineUniformRemapTable
;
2762 case GL_ACTIVE_SUBROUTINE_UNIFORMS
:
2763 values
[0] = p
->sh
.NumSubroutineUniforms
;
2765 case GL_ACTIVE_SUBROUTINE_MAX_LENGTH
:
2769 GLenum resource_type
;
2770 struct gl_program_resource
*res
;
2772 resource_type
= _mesa_shader_stage_to_subroutine(stage
);
2773 for (i
= 0; i
< p
->sh
.NumSubroutineFunctions
; i
++) {
2774 res
= _mesa_program_resource_find_index(shProg
, resource_type
, i
);
2776 const GLint len
= strlen(_mesa_program_resource_name(res
)) + 1;
2781 values
[0] = max_len
;
2784 case GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH
:
2788 GLenum resource_type
;
2789 struct gl_program_resource
*res
;
2791 resource_type
= _mesa_shader_stage_to_subroutine_uniform(stage
);
2792 for (i
= 0; i
< p
->sh
.NumSubroutineUniformRemapTable
; i
++) {
2793 res
= _mesa_program_resource_find_index(shProg
, resource_type
, i
);
2795 const GLint len
= strlen(_mesa_program_resource_name(res
)) + 1
2796 + ((_mesa_program_resource_array_size(res
) != 0) ? 3 : 0);
2802 values
[0] = max_len
;
2806 _mesa_error(ctx
, GL_INVALID_ENUM
, "%s", api_name
);
2813 find_compat_subroutine(struct gl_program
*p
, const struct glsl_type
*type
)
2817 for (i
= 0; i
< p
->sh
.NumSubroutineFunctions
; i
++) {
2818 struct gl_subroutine_function
*fn
= &p
->sh
.SubroutineFunctions
[i
];
2819 for (j
= 0; j
< fn
->num_compat_types
; j
++) {
2820 if (fn
->types
[j
] == type
)
2828 _mesa_shader_write_subroutine_index(struct gl_context
*ctx
,
2829 struct gl_program
*p
)
2833 if (p
->sh
.NumSubroutineUniformRemapTable
== 0)
2838 struct gl_uniform_storage
*uni
= p
->sh
.SubroutineUniformRemapTable
[i
];
2847 uni_count
= uni
->array_elements
? uni
->array_elements
: 1;
2848 for (j
= 0; j
< uni_count
; j
++) {
2849 val
= ctx
->SubroutineIndex
[p
->info
.stage
].IndexPtr
[i
+ j
];
2850 memcpy(&uni
->storage
[j
], &val
, sizeof(int));
2853 _mesa_propagate_uniforms_to_driver_storage(uni
, 0, uni_count
);
2855 } while(i
< p
->sh
.NumSubroutineUniformRemapTable
);
2859 _mesa_shader_write_subroutine_indices(struct gl_context
*ctx
,
2860 gl_shader_stage stage
)
2862 if (ctx
->_Shader
->CurrentProgram
[stage
])
2863 _mesa_shader_write_subroutine_index(ctx
,
2864 ctx
->_Shader
->CurrentProgram
[stage
]);
2868 _mesa_program_init_subroutine_defaults(struct gl_context
*ctx
,
2869 struct gl_program
*p
)
2873 struct gl_subroutine_index_binding
*binding
= &ctx
->SubroutineIndex
[p
->info
.stage
];
2874 if (binding
->NumIndex
!= p
->sh
.NumSubroutineUniformRemapTable
) {
2875 binding
->IndexPtr
= realloc(binding
->IndexPtr
,
2876 p
->sh
.NumSubroutineUniformRemapTable
* (sizeof(GLuint
)));
2877 binding
->NumIndex
= p
->sh
.NumSubroutineUniformRemapTable
;
2880 for (int i
= 0; i
< p
->sh
.NumSubroutineUniformRemapTable
; i
++) {
2881 struct gl_uniform_storage
*uni
= p
->sh
.SubroutineUniformRemapTable
[i
];
2886 binding
->IndexPtr
[i
] = find_compat_subroutine(p
, uni
->type
);