void GLAPIENTRY _mesa_GetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar * const *uniformNames, GLuint *uniformIndices) { GET_CURRENT_CONTEXT(ctx); GLsizei i; struct gl_shader_program *shProg; if (!ctx->Extensions.ARB_uniform_buffer_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices"); return; } shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetUniformIndices"); if (!shProg) return; if (uniformCount < 0) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformIndices(uniformCount < 0)"); return; } for (i = 0; i < uniformCount; i++) { unsigned offset; uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg, uniformNames[i], &offset); } }
GLint GLAPIENTRY _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name) { struct gl_shader_program *shProg; GET_CURRENT_CONTEXT(ctx); shProg = _mesa_lookup_shader_program_err(ctx, programObj, "glGetUniformLocation"); if (!shProg) return -1; return _mesa_get_uniform_location(ctx, shProg, name); }
static GLint program_resource_location(struct gl_shader_program *shProg, struct gl_program_resource *res, const char *name) { unsigned index, offset; int array_index = -1; if (res->Type == GL_PROGRAM_INPUT || res->Type == GL_PROGRAM_OUTPUT) { array_index = array_index_of_resource(res, name); if (array_index < 0) return -1; } /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these * offsets are used internally to differentiate between built-in attributes * and user-defined attributes. */ switch (res->Type) { case GL_PROGRAM_INPUT: return RESOURCE_VAR(res)->data.location + array_index - VERT_ATTRIB_GENERIC0; case GL_PROGRAM_OUTPUT: return RESOURCE_VAR(res)->data.location + array_index - FRAG_RESULT_DATA0; case GL_UNIFORM: index = _mesa_get_uniform_location(shProg, name, &offset); if (index == GL_INVALID_INDEX) return -1; /* From the GL_ARB_uniform_buffer_object spec: * * "The value -1 will be returned if <name> does not correspond to an * active uniform variable name in <program>, if <name> is associated * with a named uniform block, or if <name> starts with the reserved * prefix "gl_"." */ if (RESOURCE_UNI(res)->block_index != -1 || RESOURCE_UNI(res)->atomic_buffer_index != -1) return -1; /* location in remap table + array element offset */ return RESOURCE_UNI(res)->remap_location + offset; default: return -1; } }
GLint GLAPIENTRY _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) { struct gl_shader_program *shProg; GLuint index, offset; GET_CURRENT_CONTEXT(ctx); shProg = _mesa_lookup_shader_program_err(ctx, programObj, "glGetUniformLocation"); if (!shProg) return -1; /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: * * "If program has not been successfully linked, the error * INVALID_OPERATION is generated." */ if (shProg->LinkStatus == GL_FALSE) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformLocation(program not linked)"); return -1; } index = _mesa_get_uniform_location(ctx, shProg, name, &offset); if (index == GL_INVALID_INDEX) return -1; /* From the GL_ARB_uniform_buffer_object spec: * * "The value -1 will be returned if <name> does not correspond to an * active uniform variable name in <program>, if <name> is associated * with a named uniform block, or if <name> starts with the reserved * prefix "gl_"." */ if (shProg->UniformStorage[index].block_index != -1 || shProg->UniformStorage[index].atomic_buffer_index != -1) return -1; /* location in remap table + array element offset */ return shProg->UniformStorage[index].remap_location + offset; }
void GLAPIENTRY _mesa_GetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg; struct gl_uniform_block *block; unsigned i; if (!ctx->Extensions.ARB_uniform_buffer_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); return; } shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformBlockiv"); if (!shProg) return; if (uniformBlockIndex >= shProg->NumUniformBlocks) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformBlockiv(block index %u >= %u)", uniformBlockIndex, shProg->NumUniformBlocks); return; } block = &shProg->UniformBlocks[uniformBlockIndex]; switch (pname) { case GL_UNIFORM_BLOCK_BINDING: params[0] = block->Binding; return; case GL_UNIFORM_BLOCK_DATA_SIZE: params[0] = block->UniformBufferSize; return; case GL_UNIFORM_BLOCK_NAME_LENGTH: params[0] = strlen(block->Name) + 1; return; case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: { unsigned count = 0; for (i = 0; i < block->NumUniforms; i++) { unsigned offset; const int idx = _mesa_get_uniform_location(ctx, shProg, block->Uniforms[i].IndexName, &offset); if (idx != -1) count++; } params[0] = count; return; } case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: { unsigned count = 0; for (i = 0; i < block->NumUniforms; i++) { unsigned offset; const int idx = _mesa_get_uniform_location(ctx, shProg, block->Uniforms[i].IndexName, &offset); if (idx != -1) params[count++] = idx; } return; } case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1; return; case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER: params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1; return; case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1; return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformBlockiv(pname 0x%x (%s))", pname, _mesa_lookup_enum_by_nr(pname)); return; } }