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.
6 * Copyright © 2010 Intel Corporation
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
29 * Functions related to GLSL uniform variables.
35 * 1. Check that the right error code is generated for all _mesa_error() calls.
36 * 2. Insert FLUSH_VERTICES calls in various places
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/shaderapi.h"
43 #include "main/shaderobj.h"
44 #include "main/uniforms.h"
45 #include "main/enums.h"
46 #include "ir_uniform.h"
47 #include "glsl_types.h"
48 #include "program/program.h"
51 * Update the vertex/fragment program's TexturesUsed array.
53 * This needs to be called after glUniform(set sampler var) is called.
54 * A call to glUniform(samplerVar, value) causes a sampler to point to a
55 * particular texture unit. We know the sampler's texture target
56 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
57 * set by glUniform() calls.
59 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
60 * information to update the prog->TexturesUsed[] values.
61 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
62 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
63 * We'll use that info for state validation before rendering.
66 _mesa_update_shader_textures_used(struct gl_shader_program
*shProg
,
67 struct gl_program
*prog
)
70 struct gl_shader
*shader
=
71 shProg
->_LinkedShaders
[_mesa_program_target_to_index(prog
->Target
)];
75 memcpy(prog
->SamplerUnits
, shader
->SamplerUnits
, sizeof(prog
->SamplerUnits
));
76 memset(prog
->TexturesUsed
, 0, sizeof(prog
->TexturesUsed
));
78 for (s
= 0; s
< MAX_SAMPLERS
; s
++) {
79 if (prog
->SamplersUsed
& (1 << s
)) {
80 GLuint unit
= shader
->SamplerUnits
[s
];
81 GLuint tgt
= shader
->SamplerTargets
[s
];
82 assert(unit
< Elements(prog
->TexturesUsed
));
83 assert(tgt
< NUM_TEXTURE_TARGETS
);
84 prog
->TexturesUsed
[unit
] |= (1 << tgt
);
90 * Connect a piece of driver storage with a part of a uniform
92 * \param uni The uniform with which the storage will be associated
93 * \param element_stride Byte-stride between array elements.
94 * \sa gl_uniform_driver_storage::element_stride.
95 * \param vector_stride Byte-stride between vectors (in a matrix).
96 * \sa gl_uniform_driver_storage::vector_stride.
97 * \param format Conversion from native format to driver format
98 * required by the driver.
99 * \param data Location to dump the data.
102 _mesa_uniform_attach_driver_storage(struct gl_uniform_storage
*uni
,
103 unsigned element_stride
,
104 unsigned vector_stride
,
105 enum gl_uniform_driver_format format
,
108 uni
->driver_storage
=
109 realloc(uni
->driver_storage
,
110 sizeof(struct gl_uniform_driver_storage
)
111 * (uni
->num_driver_storage
+ 1));
113 uni
->driver_storage
[uni
->num_driver_storage
].element_stride
= element_stride
;
114 uni
->driver_storage
[uni
->num_driver_storage
].vector_stride
= vector_stride
;
115 uni
->driver_storage
[uni
->num_driver_storage
].format
= (uint8_t) format
;
116 uni
->driver_storage
[uni
->num_driver_storage
].data
= data
;
118 uni
->num_driver_storage
++;
122 * Sever all connections with all pieces of driver storage for all uniforms
125 * This function does \b not release any of the \c data pointers
126 * previously passed in to \c _mesa_uniform_attach_driver_stoarge.
129 _mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage
*uni
)
131 free(uni
->driver_storage
);
132 uni
->driver_storage
= NULL
;
133 uni
->num_driver_storage
= 0;
137 _mesa_Uniform1f(GLint location
, GLfloat v0
)
139 GET_CURRENT_CONTEXT(ctx
);
140 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_FLOAT
);
144 _mesa_Uniform2f(GLint location
, GLfloat v0
, GLfloat v1
)
146 GET_CURRENT_CONTEXT(ctx
);
150 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC2
);
154 _mesa_Uniform3f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
)
156 GET_CURRENT_CONTEXT(ctx
);
161 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC3
);
165 _mesa_Uniform4f(GLint location
, GLfloat v0
, GLfloat v1
, GLfloat v2
,
168 GET_CURRENT_CONTEXT(ctx
);
174 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_FLOAT_VEC4
);
178 _mesa_Uniform1i(GLint location
, GLint v0
)
180 GET_CURRENT_CONTEXT(ctx
);
181 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_INT
);
185 _mesa_Uniform2i(GLint location
, GLint v0
, GLint v1
)
187 GET_CURRENT_CONTEXT(ctx
);
191 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC2
);
195 _mesa_Uniform3i(GLint location
, GLint v0
, GLint v1
, GLint v2
)
197 GET_CURRENT_CONTEXT(ctx
);
202 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC3
);
206 _mesa_Uniform4i(GLint location
, GLint v0
, GLint v1
, GLint v2
, GLint v3
)
208 GET_CURRENT_CONTEXT(ctx
);
214 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_INT_VEC4
);
218 _mesa_Uniform1fv(GLint location
, GLsizei count
, const GLfloat
* value
)
220 GET_CURRENT_CONTEXT(ctx
);
221 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT
);
225 _mesa_Uniform2fv(GLint location
, GLsizei count
, const GLfloat
* value
)
227 GET_CURRENT_CONTEXT(ctx
);
228 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC2
);
232 _mesa_Uniform3fv(GLint location
, GLsizei count
, const GLfloat
* value
)
234 GET_CURRENT_CONTEXT(ctx
);
235 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC3
);
239 _mesa_Uniform4fv(GLint location
, GLsizei count
, const GLfloat
* value
)
241 GET_CURRENT_CONTEXT(ctx
);
242 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_FLOAT_VEC4
);
246 _mesa_Uniform1iv(GLint location
, GLsizei count
, const GLint
* value
)
248 GET_CURRENT_CONTEXT(ctx
);
249 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT
);
253 _mesa_Uniform2iv(GLint location
, GLsizei count
, const GLint
* value
)
255 GET_CURRENT_CONTEXT(ctx
);
256 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC2
);
260 _mesa_Uniform3iv(GLint location
, GLsizei count
, const GLint
* value
)
262 GET_CURRENT_CONTEXT(ctx
);
263 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC3
);
267 _mesa_Uniform4iv(GLint location
, GLsizei count
, const GLint
* value
)
269 GET_CURRENT_CONTEXT(ctx
);
270 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_INT_VEC4
);
274 /** OpenGL 3.0 GLuint-valued functions **/
276 _mesa_Uniform1ui(GLint location
, GLuint v0
)
278 GET_CURRENT_CONTEXT(ctx
);
279 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, &v0
, GL_UNSIGNED_INT
);
283 _mesa_Uniform2ui(GLint location
, GLuint v0
, GLuint v1
)
285 GET_CURRENT_CONTEXT(ctx
);
289 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC2
);
293 _mesa_Uniform3ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
)
295 GET_CURRENT_CONTEXT(ctx
);
300 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC3
);
304 _mesa_Uniform4ui(GLint location
, GLuint v0
, GLuint v1
, GLuint v2
, GLuint v3
)
306 GET_CURRENT_CONTEXT(ctx
);
312 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, 1, v
, GL_UNSIGNED_INT_VEC4
);
316 _mesa_Uniform1uiv(GLint location
, GLsizei count
, const GLuint
*value
)
318 GET_CURRENT_CONTEXT(ctx
);
319 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT
);
323 _mesa_Uniform2uiv(GLint location
, GLsizei count
, const GLuint
*value
)
325 GET_CURRENT_CONTEXT(ctx
);
326 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC2
);
330 _mesa_Uniform3uiv(GLint location
, GLsizei count
, const GLuint
*value
)
332 GET_CURRENT_CONTEXT(ctx
);
333 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC3
);
337 _mesa_Uniform4uiv(GLint location
, GLsizei count
, const GLuint
*value
)
339 GET_CURRENT_CONTEXT(ctx
);
340 _mesa_uniform(ctx
, ctx
->Shader
.ActiveProgram
, location
, count
, value
, GL_UNSIGNED_INT_VEC4
);
346 _mesa_UniformMatrix2fv(GLint location
, GLsizei count
, GLboolean transpose
,
347 const GLfloat
* value
)
349 GET_CURRENT_CONTEXT(ctx
);
350 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
351 2, 2, location
, count
, transpose
, value
);
355 _mesa_UniformMatrix3fv(GLint location
, GLsizei count
, GLboolean transpose
,
356 const GLfloat
* value
)
358 GET_CURRENT_CONTEXT(ctx
);
359 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
360 3, 3, location
, count
, transpose
, value
);
364 _mesa_UniformMatrix4fv(GLint location
, GLsizei count
, GLboolean transpose
,
365 const GLfloat
* value
)
367 GET_CURRENT_CONTEXT(ctx
);
368 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
369 4, 4, location
, count
, transpose
, value
);
374 * Non-square UniformMatrix are OpenGL 2.1
377 _mesa_UniformMatrix2x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
378 const GLfloat
*value
)
380 GET_CURRENT_CONTEXT(ctx
);
381 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
382 2, 3, location
, count
, transpose
, value
);
386 _mesa_UniformMatrix3x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
387 const GLfloat
*value
)
389 GET_CURRENT_CONTEXT(ctx
);
390 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
391 3, 2, location
, count
, transpose
, value
);
395 _mesa_UniformMatrix2x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
396 const GLfloat
*value
)
398 GET_CURRENT_CONTEXT(ctx
);
399 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
400 2, 4, location
, count
, transpose
, value
);
404 _mesa_UniformMatrix4x2fv(GLint location
, GLsizei count
, GLboolean transpose
,
405 const GLfloat
*value
)
407 GET_CURRENT_CONTEXT(ctx
);
408 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
409 4, 2, location
, count
, transpose
, value
);
413 _mesa_UniformMatrix3x4fv(GLint location
, GLsizei count
, GLboolean transpose
,
414 const GLfloat
*value
)
416 GET_CURRENT_CONTEXT(ctx
);
417 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
418 3, 4, location
, count
, transpose
, value
);
422 _mesa_UniformMatrix4x3fv(GLint location
, GLsizei count
, GLboolean transpose
,
423 const GLfloat
*value
)
425 GET_CURRENT_CONTEXT(ctx
);
426 _mesa_uniform_matrix(ctx
, ctx
->Shader
.ActiveProgram
,
427 4, 3, location
, count
, transpose
, value
);
432 _mesa_GetnUniformfvARB(GLhandleARB program
, GLint location
,
433 GLsizei bufSize
, GLfloat
*params
)
435 GET_CURRENT_CONTEXT(ctx
);
436 _mesa_get_uniform(ctx
, program
, location
, bufSize
, GLSL_TYPE_FLOAT
, params
);
440 _mesa_GetUniformfv(GLhandleARB program
, GLint location
, GLfloat
*params
)
442 _mesa_GetnUniformfvARB(program
, location
, INT_MAX
, params
);
447 _mesa_GetnUniformivARB(GLhandleARB program
, GLint location
,
448 GLsizei bufSize
, GLint
*params
)
450 GET_CURRENT_CONTEXT(ctx
);
451 _mesa_get_uniform(ctx
, program
, location
, bufSize
, GLSL_TYPE_INT
, params
);
455 _mesa_GetUniformiv(GLhandleARB program
, GLint location
, GLint
*params
)
457 _mesa_GetnUniformivARB(program
, location
, INT_MAX
, params
);
463 _mesa_GetnUniformuivARB(GLhandleARB program
, GLint location
,
464 GLsizei bufSize
, GLuint
*params
)
466 GET_CURRENT_CONTEXT(ctx
);
467 _mesa_get_uniform(ctx
, program
, location
, bufSize
, GLSL_TYPE_UINT
, params
);
471 _mesa_GetUniformuiv(GLhandleARB program
, GLint location
, GLuint
*params
)
473 _mesa_GetnUniformuivARB(program
, location
, INT_MAX
, params
);
479 _mesa_GetnUniformdvARB(GLhandleARB program
, GLint location
,
480 GLsizei bufSize
, GLdouble
*params
)
482 GET_CURRENT_CONTEXT(ctx
);
490 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
492 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformdvARB"
493 "(GL_ARB_gpu_shader_fp64 not implemented)");
497 _mesa_GetUniformdv(GLhandleARB program
, GLint location
, GLdouble
*params
)
499 _mesa_GetnUniformdvARB(program
, location
, INT_MAX
, params
);
504 _mesa_GetUniformLocation(GLhandleARB programObj
, const GLcharARB
*name
)
506 struct gl_shader_program
*shProg
;
507 GLuint index
, offset
;
509 GET_CURRENT_CONTEXT(ctx
);
511 shProg
= _mesa_lookup_shader_program_err(ctx
, programObj
,
512 "glGetUniformLocation");
516 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
518 * "If program has not been successfully linked, the error
519 * INVALID_OPERATION is generated."
521 if (shProg
->LinkStatus
== GL_FALSE
) {
522 _mesa_error(ctx
, GL_INVALID_OPERATION
,
523 "glGetUniformLocation(program not linked)");
527 index
= _mesa_get_uniform_location(ctx
, shProg
, name
, &offset
);
528 if (index
== GL_INVALID_INDEX
)
531 /* From the GL_ARB_uniform_buffer_object spec:
533 * "The value -1 will be returned if <name> does not correspond to an
534 * active uniform variable name in <program>, if <name> is associated
535 * with a named uniform block, or if <name> starts with the reserved
538 if (shProg
->UniformStorage
[index
].block_index
!= -1)
541 return _mesa_uniform_merge_location_offset(index
, offset
);
545 _mesa_GetUniformBlockIndex(GLuint program
,
546 const GLchar
*uniformBlockName
)
548 GET_CURRENT_CONTEXT(ctx
);
550 struct gl_shader_program
*shProg
;
552 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
553 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformBlockIndex");
554 return GL_INVALID_INDEX
;
557 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
558 "glGetUniformBlockIndex");
560 return GL_INVALID_INDEX
;
562 for (i
= 0; i
< shProg
->NumUniformBlocks
; i
++) {
563 if (!strcmp(shProg
->UniformBlocks
[i
].Name
, uniformBlockName
))
567 return GL_INVALID_INDEX
;
571 _mesa_GetUniformIndices(GLuint program
,
572 GLsizei uniformCount
,
573 const GLchar
* const *uniformNames
,
574 GLuint
*uniformIndices
)
576 GET_CURRENT_CONTEXT(ctx
);
578 struct gl_shader_program
*shProg
;
580 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
581 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetUniformIndices");
585 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
586 "glGetUniformIndices");
590 if (uniformCount
< 0) {
591 _mesa_error(ctx
, GL_INVALID_VALUE
,
592 "glGetUniformIndices(uniformCount < 0)");
596 for (i
= 0; i
< uniformCount
; i
++) {
598 uniformIndices
[i
] = _mesa_get_uniform_location(ctx
, shProg
,
599 uniformNames
[i
], &offset
);
604 _mesa_UniformBlockBinding(GLuint program
,
605 GLuint uniformBlockIndex
,
606 GLuint uniformBlockBinding
)
608 GET_CURRENT_CONTEXT(ctx
);
609 struct gl_shader_program
*shProg
;
611 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
612 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glUniformBlockBinding");
616 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
617 "glUniformBlockBinding");
621 if (uniformBlockIndex
>= shProg
->NumUniformBlocks
) {
622 _mesa_error(ctx
, GL_INVALID_VALUE
,
623 "glUniformBlockBinding(block index %u >= %u)",
624 uniformBlockIndex
, shProg
->NumUniformBlocks
);
628 if (uniformBlockBinding
>= ctx
->Const
.MaxUniformBufferBindings
) {
629 _mesa_error(ctx
, GL_INVALID_VALUE
,
630 "glUniformBlockBinding(block binding %u >= %u)",
631 uniformBlockBinding
, ctx
->Const
.MaxUniformBufferBindings
);
635 if (shProg
->UniformBlocks
[uniformBlockIndex
].Binding
!=
636 uniformBlockBinding
) {
639 FLUSH_VERTICES(ctx
, 0);
640 ctx
->NewDriverState
|= ctx
->DriverFlags
.NewUniformBuffer
;
642 shProg
->UniformBlocks
[uniformBlockIndex
].Binding
= uniformBlockBinding
;
644 for (i
= 0; i
< MESA_SHADER_TYPES
; i
++) {
645 int stage_index
= shProg
->UniformBlockStageIndex
[i
][uniformBlockIndex
];
647 if (stage_index
!= -1) {
648 struct gl_shader
*sh
= shProg
->_LinkedShaders
[i
];
649 sh
->UniformBlocks
[stage_index
].Binding
= uniformBlockBinding
;
656 _mesa_GetActiveUniformBlockiv(GLuint program
,
657 GLuint uniformBlockIndex
,
661 GET_CURRENT_CONTEXT(ctx
);
662 struct gl_shader_program
*shProg
;
663 struct gl_uniform_block
*block
;
666 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
667 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetActiveUniformBlockiv");
671 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
672 "glGetActiveUniformBlockiv");
676 if (uniformBlockIndex
>= shProg
->NumUniformBlocks
) {
677 _mesa_error(ctx
, GL_INVALID_VALUE
,
678 "glGetActiveUniformBlockiv(block index %u >= %u)",
679 uniformBlockIndex
, shProg
->NumUniformBlocks
);
683 block
= &shProg
->UniformBlocks
[uniformBlockIndex
];
686 case GL_UNIFORM_BLOCK_BINDING
:
687 params
[0] = block
->Binding
;
690 case GL_UNIFORM_BLOCK_DATA_SIZE
:
691 params
[0] = block
->UniformBufferSize
;
694 case GL_UNIFORM_BLOCK_NAME_LENGTH
:
695 params
[0] = strlen(block
->Name
) + 1;
698 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS
:
699 params
[0] = block
->NumUniforms
;
702 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES
:
703 for (i
= 0; i
< block
->NumUniforms
; i
++) {
705 params
[i
] = _mesa_get_uniform_location(ctx
, shProg
,
706 block
->Uniforms
[i
].IndexName
,
711 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER
:
712 params
[0] = shProg
->UniformBlockStageIndex
[MESA_SHADER_VERTEX
][uniformBlockIndex
] != -1;
715 case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER
:
716 params
[0] = shProg
->UniformBlockStageIndex
[MESA_SHADER_GEOMETRY
][uniformBlockIndex
] != -1;
719 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER
:
720 params
[0] = shProg
->UniformBlockStageIndex
[MESA_SHADER_FRAGMENT
][uniformBlockIndex
] != -1;
724 _mesa_error(ctx
, GL_INVALID_ENUM
,
725 "glGetActiveUniformBlockiv(pname 0x%x (%s))",
726 pname
, _mesa_lookup_enum_by_nr(pname
));
732 _mesa_GetActiveUniformBlockName(GLuint program
,
733 GLuint uniformBlockIndex
,
736 GLchar
*uniformBlockName
)
738 GET_CURRENT_CONTEXT(ctx
);
739 struct gl_shader_program
*shProg
;
740 struct gl_uniform_block
*block
;
742 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
743 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetActiveUniformBlockiv");
748 _mesa_error(ctx
, GL_INVALID_VALUE
,
749 "glGetActiveUniformBlockName(bufSize %d < 0)",
754 shProg
= _mesa_lookup_shader_program_err(ctx
, program
,
755 "glGetActiveUniformBlockiv");
759 if (uniformBlockIndex
>= shProg
->NumUniformBlocks
) {
760 _mesa_error(ctx
, GL_INVALID_VALUE
,
761 "glGetActiveUniformBlockiv(block index %u >= %u)",
762 uniformBlockIndex
, shProg
->NumUniformBlocks
);
766 block
= &shProg
->UniformBlocks
[uniformBlockIndex
];
768 if (uniformBlockName
) {
769 _mesa_copy_string(uniformBlockName
, bufSize
, length
, block
->Name
);
774 _mesa_GetActiveUniformName(GLuint program
, GLuint uniformIndex
,
775 GLsizei bufSize
, GLsizei
*length
,
778 GET_CURRENT_CONTEXT(ctx
);
779 struct gl_shader_program
*shProg
;
781 if (!ctx
->Extensions
.ARB_uniform_buffer_object
) {
782 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetActiveUniformBlockiv");
787 _mesa_error(ctx
, GL_INVALID_VALUE
,
788 "glGetActiveUniformName(bufSize %d < 0)",
793 shProg
= _mesa_lookup_shader_program_err(ctx
, program
, "glGetActiveUniformName");
798 if (uniformIndex
>= shProg
->NumUserUniformStorage
) {
799 _mesa_error(ctx
, GL_INVALID_VALUE
, "glGetActiveUniform(index)");
804 _mesa_get_uniform_name(& shProg
->UniformStorage
[uniformIndex
],
805 bufSize
, length
, uniformName
);
810 _mesa_get_uniform_name(const struct gl_uniform_storage
*uni
,
811 GLsizei maxLength
, GLsizei
*length
,
817 length
= &localLength
;
819 _mesa_copy_string(nameOut
, maxLength
, length
, uni
->name
);
821 /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
824 * "If the active uniform is an array, the uniform name returned in
825 * name will always be the name of the uniform array appended with
828 * The same text also appears in the OpenGL 4.2 spec. It does not,
829 * however, appear in any previous spec. Previous specifications are
830 * ambiguous in this regard. However, either name can later be passed
831 * to glGetUniformLocation (and related APIs), so there shouldn't be any
832 * harm in always appending "[0]" to uniform array names.
834 if (uni
->array_elements
!= 0) {
837 /* The comparison is strange because *length does *NOT* include the
838 * terminating NUL, but maxLength does.
840 for (i
= 0; i
< 3 && (*length
+ i
+ 1) < maxLength
; i
++)
841 nameOut
[*length
+ i
] = "[0]"[i
];
843 nameOut
[*length
+ i
] = '\0';