2 * Mesa 3-D graphics library
5 * Copyright (C) 2004-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Implementation of GLSL-related API functions
33 * 1. Check that the right error code is generated for all _mesa_error() calls.
34 * 2. Insert FLUSH_VERTICES calls in various places
42 #include "prog_parameter.h"
43 #include "shader_api.h"
45 #include "slang_compile.h"
46 #include "slang_link.h"
53 * Copy string from <src> to <dst>, up to maxLength characters, returning
54 * length of <dst> in <length>.
55 * \param src the strings source
56 * \param maxLength max chars to copy
57 * \param length returns number of chars copied
58 * \param dst the string destination
61 copy_string(GLchar
*dst
, GLsizei maxLength
, GLsizei
*length
, const GLchar
*src
)
64 for (len
= 0; len
< maxLength
- 1 && src
&& src
[len
]; len
++)
76 * Called via ctx->Driver.AttachShader()
79 _mesa_attach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
81 struct gl_shader_program
*shProg
82 = _mesa_lookup_shader_program(ctx
, program
);
83 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
84 const GLuint n
= shProg
->NumShaders
;
88 _mesa_error(ctx
, GL_INVALID_OPERATION
,
89 "glAttachShader(bad program or shader name)");
93 for (i
= 0; i
< n
; i
++) {
94 if (shProg
->Shaders
[i
] == sh
) {
95 /* already attached */
101 shProg
->Shaders
= (struct gl_shader
**)
102 _mesa_realloc(shProg
->Shaders
,
103 n
* sizeof(struct gl_shader
*),
104 (n
+ 1) * sizeof(struct gl_shader
*));
105 if (!shProg
->Shaders
) {
106 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glAttachShader");
111 shProg
->Shaders
[n
] = sh
;
113 shProg
->NumShaders
++;
118 _mesa_bind_attrib_location(GLcontext
*ctx
, GLuint program
, GLuint index
,
121 struct gl_shader_program
*shProg
122 = _mesa_lookup_shader_program(ctx
, program
);
125 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glBindAttribLocation(program)");
130 if (name
== NULL
|| index
>= MAX_VERTEX_ATTRIBS
)
131 _mesa_error(ctx
, GL_INVALID_VALUE
, "glBindAttribLocationARB");
132 else if (IS_NAME_WITH_GL_PREFIX(name
))
133 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glBindAttribLocationARB");
135 (**pro
).OverrideAttribBinding(pro
, index
, name
);
136 RELEASE_PROGRAM(pro
);
142 _mesa_create_shader(GLcontext
*ctx
, GLenum type
)
144 struct gl_shader
*sh
;
147 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
150 case GL_FRAGMENT_SHADER
:
151 case GL_VERTEX_SHADER
:
152 sh
= _mesa_new_shader(ctx
, name
, type
);
155 _mesa_error(ctx
, GL_INVALID_ENUM
, "CreateShader(type)");
159 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, sh
);
166 _mesa_create_program(GLcontext
*ctx
)
169 struct gl_shader_program
*shProg
;
171 name
= _mesa_HashFindFreeKeyBlock(ctx
->Shared
->ShaderObjects
, 1);
172 shProg
= _mesa_new_shader_program(ctx
, name
);
174 _mesa_HashInsert(ctx
->Shared
->ShaderObjects
, name
, shProg
);
181 _mesa_delete_program2(GLcontext
*ctx
, GLuint name
)
183 struct gl_shader_program
*shProg
;
185 shProg
= _mesa_lookup_shader_program(ctx
, name
);
187 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glDeleteProgram(name)");
191 /* XXX refcounting! */
192 _mesa_HashRemove(ctx
->Shared
->ShaderObjects
, name
);
193 _mesa_delete_shader_program(ctx
, shProg
);
198 _mesa_delete_shader(GLcontext
*ctx
, GLuint shader
)
200 /* XXX refcounting! */
203 _mesa_DeleteObjectARB(shader);
209 _mesa_detach_shader(GLcontext
*ctx
, GLuint program
, GLuint shader
)
211 struct gl_shader_program
*shProg
212 = _mesa_lookup_shader_program(ctx
, program
);
213 const GLuint n
= shProg
->NumShaders
;
217 _mesa_error(ctx
, GL_INVALID_OPERATION
,
218 "glDetachShader(bad program or shader name)");
222 for (i
= 0; i
< n
; i
++) {
223 if (shProg
->Shaders
[i
]->Name
== shader
) {
224 struct gl_shader
**newList
;
226 /* alloc new, smaller array */
227 newList
= (struct gl_shader
**)
228 _mesa_malloc((n
- 1) * sizeof(struct gl_shader
*));
230 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "glDetachShader");
233 for (j
= 0; j
< i
; j
++) {
234 newList
[j
] = shProg
->Shaders
[j
];
237 newList
[j
++] = shProg
->Shaders
[i
];
238 _mesa_free(shProg
->Shaders
);
240 /* XXX refcounting! */
242 shProg
->Shaders
= newList
;
248 _mesa_error(ctx
, GL_INVALID_OPERATION
,
249 "glDetachShader(shader not found)");
254 _mesa_get_active_attrib(GLcontext
*ctx
, GLuint program
, GLuint index
,
255 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
256 GLenum
*type
, GLchar
*nameOut
)
258 static const GLenum vec_types
[] = {
259 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
261 struct gl_shader_program
*shProg
262 = _mesa_lookup_shader_program(ctx
, program
);
266 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetActiveUniform");
270 if (!shProg
->Attributes
|| index
>= shProg
->Attributes
->NumParameters
) {
271 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
275 copy_string(nameOut
, maxLength
, length
,
276 shProg
->Attributes
->Parameters
[index
].Name
);
277 sz
= shProg
->Attributes
->Parameters
[index
].Size
;
281 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
286 * Called via ctx->Driver.GetActiveUniform().
289 _mesa_get_active_uniform(GLcontext
*ctx
, GLuint program
, GLuint index
,
290 GLsizei maxLength
, GLsizei
*length
, GLint
*size
,
291 GLenum
*type
, GLchar
*nameOut
)
293 static const GLenum vec_types
[] = {
294 GL_FLOAT
, GL_FLOAT_VEC2
, GL_FLOAT_VEC3
, GL_FLOAT_VEC4
296 struct gl_shader_program
*shProg
297 = _mesa_lookup_shader_program(ctx
, program
);
301 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetActiveUniform");
305 if (!shProg
->Uniforms
|| index
>= shProg
->Uniforms
->NumParameters
) {
306 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
310 copy_string(nameOut
, maxLength
, length
,
311 shProg
->Uniforms
->Parameters
[index
].Name
);
312 sz
= shProg
->Uniforms
->Parameters
[index
].Size
;
316 *type
= vec_types
[sz
]; /* XXX this is a temporary hack */
321 * Called via ctx->Driver.GetAttachedShaders().
324 _mesa_get_attached_shaders(GLcontext
*ctx
, GLuint program
, GLsizei maxCount
,
325 GLsizei
*count
, GLuint
*obj
)
327 struct gl_shader_program
*shProg
328 = _mesa_lookup_shader_program(ctx
, program
);
331 for (i
= 0; i
< maxCount
&& i
< shProg
->NumShaders
; i
++) {
332 obj
[i
] = shProg
->Shaders
[i
]->Name
;
338 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetAttachedShaders");
344 _mesa_get_attrib_location(GLcontext
*ctx
, GLuint program
,
347 struct gl_shader_program
*shProg
348 = _mesa_lookup_shader_program(ctx
, program
);
351 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetAttribLocation");
355 if (!shProg
->LinkStatus
) {
356 _mesa_error(ctx
, GL_INVALID_OPERATION
,
357 "glGetAttribLocation(program not linked)");
364 if (shProg
->Attributes
) {
366 for (i
= 0; i
< shProg
->Attributes
->NumParameters
; i
++) {
367 if (!strcmp(shProg
->Attributes
->Parameters
[i
].Name
, name
)) {
377 _mesa_get_handle(GLcontext
*ctx
, GLenum pname
)
380 GET_CURRENT_CONTEXT(ctx
);
383 case GL_PROGRAM_OBJECT_ARB
:
385 struct gl2_program_intf
**pro
= ctx
->Shader
.CurrentProgram
;
388 return (**pro
)._container
._generic
.
389 GetName((struct gl2_generic_intf
**) (pro
));
393 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetHandleARB");
401 _mesa_get_programiv(GLcontext
*ctx
, GLuint program
,
402 GLenum pname
, GLint
*params
)
404 struct gl_shader_program
*shProg
405 = _mesa_lookup_shader_program(ctx
, program
);
408 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramiv(program)");
413 case GL_DELETE_STATUS
:
414 *params
= shProg
->DeletePending
;
417 *params
= shProg
->LinkStatus
;
419 case GL_VALIDATE_STATUS
:
420 *params
= shProg
->Validated
;
422 case GL_INFO_LOG_LENGTH
:
423 *params
= shProg
->InfoLog
? strlen(shProg
->InfoLog
) : 0;
425 case GL_ATTACHED_SHADERS
:
426 *params
= shProg
->NumShaders
;
428 case GL_ACTIVE_ATTRIBUTES
:
429 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
431 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH
:
432 *params
= _mesa_parameter_longest_name(shProg
->Attributes
);
434 case GL_ACTIVE_UNIFORMS
:
435 *params
= shProg
->Uniforms
? shProg
->Uniforms
->NumParameters
: 0;
437 case GL_ACTIVE_UNIFORM_MAX_LENGTH
:
438 *params
= _mesa_parameter_longest_name(shProg
->Uniforms
);
441 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramiv(pname)");
448 _mesa_get_shaderiv(GLcontext
*ctx
, GLuint name
, GLenum pname
, GLint
*params
)
450 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
453 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderiv(shader)");
459 *params
= shader
->Type
;
461 case GL_DELETE_STATUS
:
462 *params
= shader
->DeletePending
;
464 case GL_COMPILE_STATUS
:
465 *params
= shader
->CompileStatus
;
467 case GL_INFO_LOG_LENGTH
:
468 *params
= shader
->InfoLog
? strlen(shader
->InfoLog
) : 0;
470 case GL_SHADER_SOURCE_LENGTH
:
471 *params
= shader
->Source
? strlen((char *) shader
->Source
) : 0;
474 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetShaderiv(pname)");
481 _mesa_get_program_info_log(GLcontext
*ctx
, GLuint program
, GLsizei bufSize
,
482 GLsizei
*length
, GLchar
*infoLog
)
484 struct gl_shader_program
*shProg
485 = _mesa_lookup_shader_program(ctx
, program
);
487 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetProgramInfoLog(program)");
490 copy_string(infoLog
, bufSize
, length
, shProg
->InfoLog
);
495 _mesa_get_shader_info_log(GLcontext
*ctx
, GLuint shader
, GLsizei bufSize
,
496 GLsizei
*length
, GLchar
*infoLog
)
498 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
500 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderInfoLog(shader)");
503 copy_string(infoLog
, bufSize
, length
, sh
->InfoLog
);
508 * Called via ctx->Driver.GetShaderSource().
511 _mesa_get_shader_source(GLcontext
*ctx
, GLuint shader
, GLsizei maxLength
,
512 GLsizei
*length
, GLchar
*sourceOut
)
514 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
516 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetShaderSource(shader)");
519 copy_string(sourceOut
, maxLength
, length
, sh
->Source
);
524 * Called via ctx->Driver.GetUniformfv().
527 _mesa_get_uniformfv(GLcontext
*ctx
, GLuint program
, GLint location
,
530 struct gl_shader_program
*shProg
531 = _mesa_lookup_shader_program(ctx
, program
);
534 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
535 for (i
= 0; i
< shProg
->Uniforms
->Parameters
[location
].Size
; i
++) {
536 params
[i
] = shProg
->Uniforms
->ParameterValues
[location
][i
];
540 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetUniformfv(location)");
544 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformfv(program)");
550 * Called via ctx->Driver.GetUniformLocation().
553 _mesa_get_uniform_location(GLcontext
*ctx
, GLuint program
, const GLchar
*name
)
555 if (ctx
->Shader
.CurrentProgram
) {
556 const struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
558 for (loc
= 0; loc
< shProg
->Uniforms
->NumParameters
; loc
++) {
559 const struct gl_program_parameter
*u
560 = shProg
->Uniforms
->Parameters
+ loc
;
561 if (u
->Type
== PROGRAM_UNIFORM
&& !strcmp(u
->Name
, name
)) {
572 _mesa_is_program(GLcontext
*ctx
, GLuint name
)
574 struct gl_shader_program
*shProg
= _mesa_lookup_shader_program(ctx
, name
);
575 return shProg
? GL_TRUE
: GL_FALSE
;
580 _mesa_is_shader(GLcontext
*ctx
, GLuint name
)
582 struct gl_shader
*shader
= _mesa_lookup_shader(ctx
, name
);
583 return shader
? GL_TRUE
: GL_FALSE
;
589 * Called via ctx->Driver.ShaderSource()
592 _mesa_shader_source(GLcontext
*ctx
, GLuint shader
, const GLchar
*source
)
594 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shader
);
596 _mesa_error(ctx
, GL_INVALID_VALUE
, "glShaderSource(shaderObj)");
600 /* free old shader source string and install new one */
602 _mesa_free((void *) sh
->Source
);
609 * Called via ctx->Driver.CompileShader()
612 _mesa_compile_shader(GLcontext
*ctx
, GLuint shaderObj
)
614 struct gl_shader
*sh
= _mesa_lookup_shader(ctx
, shaderObj
);
615 slang_info_log info_log
;
616 slang_code_object obj
;
617 slang_unit_type type
;
620 _mesa_error(ctx
, GL_INVALID_VALUE
, "glCompileShader(shaderObj)");
624 slang_info_log_construct(&info_log
);
625 _slang_code_object_ctr(&obj
);
627 if (sh
->Type
== GL_VERTEX_SHADER
) {
628 type
= slang_unit_vertex_shader
;
631 assert(sh
->Type
== GL_FRAGMENT_SHADER
);
632 type
= slang_unit_fragment_shader
;
635 if (_slang_compile(sh
->Source
, &obj
, type
, &info_log
, sh
)) {
636 sh
->CompileStatus
= GL_TRUE
;
639 sh
->CompileStatus
= GL_FALSE
;
641 _mesa_problem(ctx
, "Program did not compile!");
647 * Called via ctx->Driver.LinkProgram()
650 _mesa_link_program(GLcontext
*ctx
, GLuint program
)
652 struct gl_shader_program
*shProg
;
654 shProg
= _mesa_lookup_shader_program(ctx
, program
);
656 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glLinkProgram(program)");
660 _slang_link2(ctx
, program
, shProg
);
665 * Called via ctx->Driver.UseProgram()
668 _mesa_use_program(GLcontext
*ctx
, GLuint program
)
670 /* XXXX need to handle reference counting here! */
672 struct gl_shader_program
*shProg
;
673 shProg
= _mesa_lookup_shader_program(ctx
, program
);
675 _mesa_error(ctx
, GL_INVALID_OPERATION
,
676 "glUseProgramObjectARB(programObj)");
679 ctx
->Shader
.CurrentProgram
= shProg
;
682 /* don't use a shader program */
683 ctx
->Shader
.CurrentProgram
= NULL
;
689 * Called via ctx->Driver.Uniform().
692 _mesa_uniform(GLcontext
*ctx
, GLint location
, GLsizei count
,
693 const GLvoid
*values
, GLenum type
)
695 if (ctx
->Shader
.CurrentProgram
) {
696 struct gl_shader_program
*shProg
= ctx
->Shader
.CurrentProgram
;
697 if (location
>= 0 && location
< shProg
->Uniforms
->NumParameters
) {
698 GLfloat
*v
= shProg
->Uniforms
->ParameterValues
[location
];
699 const GLfloat
*fValues
= (const GLfloat
*) values
; /* XXX */
701 if (type
== GL_FLOAT_VEC4
)
703 else if (type
== GL_FLOAT_VEC3
)
708 for (i
= 0; i
< count
; i
++)
714 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniform(program not linked)");
720 * Called by ctx->Driver.UniformMatrix().
723 _mesa_uniform_matrix(GLcontext
*ctx
, GLint cols
, GLint rows
,
724 GLenum matrixType
, GLint location
, GLsizei count
,
725 GLboolean transpose
, const GLfloat
*values
)
727 const char *caller
= "glUniformMatrix";
728 const GLint matElements
= rows
* cols
;
730 if (values
== NULL
) {
731 _mesa_error(ctx
, GL_INVALID_VALUE
, caller
);
735 FLUSH_VERTICES(ctx
, _NEW_PROGRAM
);
742 trans
= (GLfloat
*) _mesa_malloc(count
* matElements
* sizeof(GLfloat
));
744 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, caller
);
750 for (i
= 0; i
< count
; i
++) {
751 /* transpose from pv matrix into pt matrix */
752 for (j
= 0; j
< cols
; j
++) {
753 for (k
= 0; k
< rows
; k
++) {
754 /* XXX verify this */
755 pt
[j
* rows
+ k
] = pv
[k
* cols
+ j
];
763 if (!(**pro
).WriteUniform(pro
, location
, count
, trans
, matrixType
))
764 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
770 if (!(**pro
).WriteUniform(pro
, location
, count
, values
, matrixType
))
771 _mesa_error(ctx
, GL_INVALID_OPERATION
, caller
);
778 _mesa_validate_program(GLcontext
*ctx
, GLuint program
)
780 struct gl_shader_program
*shProg
;
781 shProg
= _mesa_lookup_shader_program(ctx
, program
);
783 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glValidateProgram(program)");
787 shProg
->Validated
= GL_TRUE
;
790 any two active samplers in the current program object are of
791 different types, but refer to the same texture image unit,
793 any active sampler in the current program object refers to a texture
794 image unit where fixed-function fragment processing accesses a
795 texture target that does not match the sampler type, or
797 the sum of the number of active samplers in the program and the
798 number of texture image units enabled for fixed-function fragment
799 processing exceeds the combined limit on the total number of texture
806 /**********************************************************************/
810 * Allocate a new gl_shader_program object, initialize it.
812 struct gl_shader_program
*
813 _mesa_new_shader_program(GLcontext
*ctx
, GLuint name
)
815 struct gl_shader_program
*shProg
;
816 shProg
= CALLOC_STRUCT(gl_shader_program
);
818 shProg
->Type
= GL_SHADER_PROGRAM
;
826 _mesa_free_shader_program_data(GLcontext
*ctx
,
827 struct gl_shader_program
*shProg
)
829 assert(shProg
->Type
== GL_SHADER_PROGRAM
);
831 if (shProg
->VertexProgram
) {
832 if (shProg
->VertexProgram
->Base
.Parameters
== shProg
->Uniforms
) {
833 /* to prevent a double-free in the next call */
834 shProg
->VertexProgram
->Base
.Parameters
= NULL
;
836 _mesa_delete_program(ctx
, &shProg
->VertexProgram
->Base
);
837 shProg
->VertexProgram
= NULL
;
840 if (shProg
->FragmentProgram
) {
841 if (shProg
->FragmentProgram
->Base
.Parameters
== shProg
->Uniforms
) {
842 /* to prevent a double-free in the next call */
843 shProg
->FragmentProgram
->Base
.Parameters
= NULL
;
845 _mesa_delete_program(ctx
, &shProg
->FragmentProgram
->Base
);
846 shProg
->FragmentProgram
= NULL
;
850 if (shProg
->Uniforms
) {
851 _mesa_free_parameter_list(shProg
->Uniforms
);
852 shProg
->Uniforms
= NULL
;
855 if (shProg
->Varying
) {
856 _mesa_free_parameter_list(shProg
->Varying
);
857 shProg
->Varying
= NULL
;
864 _mesa_delete_shader_program(GLcontext
*ctx
, struct gl_shader_program
*shProg
)
866 _mesa_free_shader_program_data(ctx
, shProg
);
872 * Lookup a GLSL program object.
874 struct gl_shader_program
*
875 _mesa_lookup_shader_program(GLcontext
*ctx
, GLuint name
)
877 struct gl_shader_program
*shProg
;
879 shProg
= (struct gl_shader_program
*)
880 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
881 /* Note that both gl_shader and gl_shader_program objects are kept
882 * in the same hash table. Check the object's type to be sure it's
883 * what we're expecting.
885 if (shProg
&& shProg
->Type
!= GL_SHADER_PROGRAM
) {
895 * Allocate a new gl_shader object, initialize it.
898 _mesa_new_shader(GLcontext
*ctx
, GLuint name
, GLenum type
)
900 struct gl_shader
*shader
;
901 assert(type
== GL_FRAGMENT_SHADER
|| type
== GL_VERTEX_SHADER
);
902 shader
= CALLOC_STRUCT(gl_shader
);
912 * Lookup a GLSL shader object.
915 _mesa_lookup_shader(GLcontext
*ctx
, GLuint name
)
918 struct gl_shader
*sh
= (struct gl_shader
*)
919 _mesa_HashLookup(ctx
->Shared
->ShaderObjects
, name
);
920 /* Note that both gl_shader and gl_shader_program objects are kept
921 * in the same hash table. Check the object's type to be sure it's
922 * what we're expecting.
924 if (sh
&& sh
->Type
== GL_SHADER_PROGRAM
) {
925 assert(sh
->Type
== GL_VERTEX_SHADER
||
926 sh
->Type
== GL_FRAGMENT_SHADER
);
936 _mesa_init_shader_state(GLcontext
* ctx
)
938 ctx
->Shader
._FragmentShaderPresent
= GL_FALSE
;
939 ctx
->Shader
._VertexShaderPresent
= GL_FALSE
;