if (uniformCount < 0) {
_mesa_error(ctx, GL_INVALID_VALUE,
- "glGetUniformIndices(uniformCount < 0)");
+ "glGetActiveUniformsiv(uniformCount < 0)");
return;
}
_mesa_error(ctx, GL_INVALID_ENUM, "glGetActiveUniformsiv(pname)");
}
-static bool
+static struct gl_uniform_storage *
validate_uniform_parameters(struct gl_context *ctx,
struct gl_shader_program *shProg,
GLint location, GLsizei count,
- unsigned *loc,
unsigned *array_index,
const char *caller,
bool negative_one_is_not_valid)
{
if (!shProg || !shProg->LinkStatus) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller);
- return false;
+ return NULL;
}
if (location == -1) {
caller, location);
}
- return false;
+ return NULL;
}
/* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec:
*/
if (count < 0) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller);
- return false;
+ return NULL;
+ }
+
+ /* Check that the given location is in bounds of uniform remap table. */
+ if (location >= (GLint) shProg->NumUniformRemapTable) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
+ caller, location);
+ return NULL;
}
/* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says:
* - if count is greater than one, and the uniform declared in the
* shader is not an array variable,
*/
- if (location < -1) {
+ if (location < -1 || !shProg->UniformRemapTable[location]) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
caller, location);
- return false;
- }
-
- /* Check that the given location is in bounds of uniform remap table. */
- if (location >= (GLint) shProg->NumUniformRemapTable) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
- caller, location);
- return false;
+ return NULL;
}
/* If the driver storage pointer in remap table is -1, we ignore silently.
*/
if (shProg->UniformRemapTable[location] ==
INACTIVE_UNIFORM_EXPLICIT_LOCATION)
- return false;
+ return NULL;
- _mesa_uniform_split_location_offset(shProg, location, loc, array_index);
+ struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location];
- if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) {
+ if (uni->array_elements == 0 && count > 1) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(count > 1 for non-array, location=%d)",
caller, location);
- return false;
+ return NULL;
}
+ /* The array index specified by the uniform location is just the uniform
+ * location minus the base location of of the uniform.
+ */
+ *array_index = location - uni->remap_location;
+
/* If the uniform is an array, check that array_index is in bounds.
* If not an array, check that array_index is zero.
* array_index is unsigned so no need to check for less than zero.
*/
- unsigned limit = shProg->UniformStorage[*loc].array_elements;
- if (limit == 0)
- limit = 1;
+ const unsigned limit = MAX2(uni->array_elements, 1);
if (*array_index >= limit) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)",
caller, location);
- return false;
+ return NULL;
}
- return true;
+ return uni;
}
/**
{
struct gl_shader_program *shProg =
_mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv");
- struct gl_uniform_storage *uni;
- unsigned loc, offset;
+ unsigned offset;
- if (!validate_uniform_parameters(ctx, shProg, location, 1,
- &loc, &offset, "glGetUniform", true))
+ struct gl_uniform_storage *const uni =
+ validate_uniform_parameters(ctx, shProg, location, 1,
+ &offset, "glGetUniform", true);
+ if (uni == NULL)
return;
- uni = &shProg->UniformStorage[loc];
-
{
unsigned elements = (uni->type->is_sampler())
? 1 : uni->type->components();
GLint location, GLsizei count,
const GLvoid *values, GLenum type)
{
- unsigned loc, offset;
+ unsigned offset;
unsigned components;
unsigned src_components;
enum glsl_base_type basicType;
- struct gl_uniform_storage *uni;
- if (!validate_uniform_parameters(ctx, shProg, location, count,
- &loc, &offset, "glUniform", false))
+ struct gl_uniform_storage *const uni =
+ validate_uniform_parameters(ctx, shProg, location, count,
+ &offset, "glUniform", false);
+ if (uni == NULL)
return;
- uni = &shProg->UniformStorage[loc];
-
/* Verify that the types are compatible.
*/
switch (type) {
for (i = 0; i < elems; i++) {
if (basicType == GLSL_TYPE_FLOAT) {
- dst[i].i = src[i].f != 0.0f ? 1 : 0;
+ dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0;
} else {
- dst[i].i = src[i].i != 0 ? 1 : 0;
+ dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0;
}
}
}
GLint location, GLsizei count,
GLboolean transpose, const GLfloat *values)
{
- unsigned loc, offset;
+ unsigned offset;
unsigned vectors;
unsigned components;
unsigned elements;
- struct gl_uniform_storage *uni;
- if (!validate_uniform_parameters(ctx, shProg, location, count,
- &loc, &offset, "glUniformMatrix", false))
+ struct gl_uniform_storage *const uni =
+ validate_uniform_parameters(ctx, shProg, location, count,
+ &offset, "glUniformMatrix", false);
+ if (uni == NULL)
return;
- uni = &shProg->UniformStorage[loc];
if (!uni->type->is_matrix()) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glUniformMatrix(non-matrix uniform)");
*
* Returns the uniform index into UniformStorage (also the
* glGetActiveUniformsiv uniform index), and stores the referenced
- * array offset in *offset, or GL_INVALID_INDEX (-1). Those two
- * return values can be encoded into a uniform location for
- * glUniform* using _mesa_uniform_merge_location_offset(index, offset).
+ * array offset in *offset, or GL_INVALID_INDEX (-1).
*/
extern "C" unsigned
_mesa_get_uniform_location(struct gl_context *ctx,
_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,
char *errMsg, size_t errMsgLength)
{
- const glsl_type *unit_types[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
-
- memset(unit_types, 0, sizeof(unit_types));
-
- for (unsigned i = 0; i < shProg->NumUserUniformStorage; i++) {
- const struct gl_uniform_storage *const storage =
- &shProg->UniformStorage[i];
- const glsl_type *const t = (storage->type->is_array())
- ? storage->type->fields.array : storage->type;
-
- if (!t->is_sampler())
- continue;
-
- const unsigned count = MAX2(1, storage->type->array_size());
- for (unsigned j = 0; j < count; j++) {
- const unsigned unit = storage->storage[j].i;
-
- /* The types of the samplers associated with a particular texture
- * unit must be an exact match. Page 74 (page 89 of the PDF) of the
- * OpenGL 3.3 core spec says:
- *
- * "It is not allowed to have variables of different sampler
- * types pointing to the same texture image unit within a program
- * object."
- */
- if (unit_types[unit] == NULL) {
- unit_types[unit] = t;
- } else if (unit_types[unit] != t) {
- _mesa_snprintf(errMsg, errMsgLength,
- "Texture unit %d is accessed both as %s and %s",
- unit, unit_types[unit]->name, t->name);
- return false;
- }
- }
+ /* Shader does not have samplers. */
+ if (shProg->NumUserUniformStorage == 0)
+ return true;
+
+ if (!shProg->SamplersValidated) {
+ _mesa_snprintf(errMsg, errMsgLength,
+ "active samplers with a different type "
+ "refer to the same texture image unit");
+ return false;
}
-
return true;
}