+extern "C" void GLAPIENTRY
+_mesa_GetActiveUniformsiv(GLuint program,
+ GLsizei uniformCount,
+ const GLuint *uniformIndices,
+ GLenum pname,
+ GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_shader_program *shProg;
+ GLsizei i;
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
+ if (!shProg)
+ return;
+
+ if (uniformCount < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetUniformIndices(uniformCount < 0)");
+ return;
+ }
+
+ for (i = 0; i < uniformCount; i++) {
+ GLuint index = uniformIndices[i];
+
+ if (index >= shProg->NumUserUniformStorage) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)");
+ return;
+ }
+ }
+
+ for (i = 0; i < uniformCount; i++) {
+ GLuint index = uniformIndices[i];
+ const struct gl_uniform_storage *uni = &shProg->UniformStorage[index];
+
+ switch (pname) {
+ case GL_UNIFORM_TYPE:
+ params[i] = uni->type->gl_type;
+ break;
+
+ case GL_UNIFORM_SIZE:
+ /* array_elements is zero for non-arrays, but the API requires that 1 be
+ * returned.
+ */
+ params[i] = MAX2(1, uni->array_elements);
+ break;
+
+ case GL_UNIFORM_NAME_LENGTH:
+ params[i] = strlen(uni->name) + 1;
+
+ /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
+ * spec says:
+ *
+ * "If the active uniform is an array, the uniform name returned
+ * in name will always be the name of the uniform array appended
+ * with "[0]"."
+ */
+ if (uni->array_elements != 0)
+ params[i] += 3;
+ break;
+
+ case GL_UNIFORM_BLOCK_INDEX:
+ params[i] = uni->block_index;
+ break;
+
+ case GL_UNIFORM_OFFSET:
+ params[i] = uni->offset;
+ break;
+
+ case GL_UNIFORM_ARRAY_STRIDE:
+ params[i] = uni->array_stride;
+ break;
+
+ case GL_UNIFORM_MATRIX_STRIDE:
+ params[i] = uni->matrix_stride;
+ break;
+
+ case GL_UNIFORM_IS_ROW_MAJOR:
+ params[i] = uni->row_major;
+ break;
+
+ case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX:
+ if (!ctx->Extensions.ARB_shader_atomic_counters)
+ goto invalid_enum;
+ params[i] = uni->atomic_buffer_index;
+ break;
+
+ default:
+ goto invalid_enum;
+ }
+ }
+
+ return;
+
+ invalid_enum:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
+}
+