summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/mtypes.h23
-rw-r--r--src/mesa/main/shaderobj.c7
-rw-r--r--src/mesa/main/uniform_query.cpp7
-rw-r--r--src/mesa/main/uniforms.h43
4 files changed, 43 insertions, 37 deletions
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index e5f10baab10..7c83d664f60 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2702,6 +2702,14 @@ struct gl_shader_program
struct gl_uniform_storage *UniformStorage;
/**
+ * Mapping from GL uniform locations returned by \c glUniformLocation to
+ * UniformStorage entries. Arrays will have multiple contiguous slots
+ * in the UniformRemapTable, all pointing to the same UniformStorage entry.
+ */
+ unsigned NumUniformRemapTable;
+ struct gl_uniform_storage **UniformRemapTable;
+
+ /**
* Size of the gl_ClipDistance array that is output from the last pipeline
* stage before the fragment shader.
*/
@@ -2711,21 +2719,6 @@ struct gl_shader_program
unsigned NumUniformBlocks;
/**
- * Scale factor for the uniform base location
- *
- * This is used to generate locations (returned by \c glGetUniformLocation)
- * of uniforms. The base location of the uniform is multiplied by this
- * value, and the array index is added.
- *
- * \note
- * Must be >= 1.
- *
- * \sa
- * _mesa_uniform_merge_location_offset, _mesa_uniform_split_location_offset
- */
- unsigned UniformLocationBaseScale;
-
- /**
* Indices into the _LinkedShaders's UniformBlocks[] array for each stage
* they're used in, or -1.
*
diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c
index d5c3d8099a7..b0f0bfa915b 100644
--- a/src/mesa/main/shaderobj.c
+++ b/src/mesa/main/shaderobj.c
@@ -285,7 +285,12 @@ _mesa_clear_shader_program_data(struct gl_context *ctx,
ralloc_free(shProg->UniformStorage);
shProg->NumUserUniformStorage = 0;
shProg->UniformStorage = NULL;
- shProg->UniformLocationBaseScale = 0;
+ }
+
+ if (shProg->UniformRemapTable) {
+ ralloc_free(shProg->UniformRemapTable);
+ shProg->NumUniformRemapTable = 0;
+ shProg->UniformRemapTable = NULL;
}
if (shProg->UniformHash) {
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index 8cc5da752ac..20ffbe8494c 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -246,14 +246,15 @@ validate_uniform_parameters(struct gl_context *ctx,
return false;
}
- _mesa_uniform_split_location_offset(shProg, location, loc, array_index);
-
- if (*loc >= shProg->NumUserUniformStorage) {
+ /* 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;
}
+ _mesa_uniform_split_location_offset(shProg, location, loc, array_index);
+
if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(count > 1 for non-array, location=%d)",
diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h
index bd50fd9b84d..4a5a1aa1513 100644
--- a/src/mesa/main/uniforms.h
+++ b/src/mesa/main/uniforms.h
@@ -340,39 +340,46 @@ struct gl_builtin_uniform_desc {
* element. We could insert dummy entries in the list for each array
* element after [0] but that causes complications elsewhere.
*
- * We solve this problem by encoding two values in the location that's
- * returned by glGetUniformLocation():
- * a) index into gl_uniform_list::Uniforms[] for the uniform
- * b) an array/field offset (0 for simple types)
+ * We solve this problem by creating multiple entries for uniform arrays
+ * in the UniformRemapTable so that their elements get sequential locations.
+ *
+ * Utility functions below offer functionality to split UniformRemapTable
+ * location in to location of the uniform in UniformStorage + offset to the
+ * array element (0 if not an array) and also merge it back again as the
+ * UniformRemapTable location.
*
- * These two values are encoded in the high and low halves of a GLint.
- * By putting the uniform number in the high part and the offset in the
- * low part, we can support the unofficial ability to index into arrays
- * by adding offsets to the location value.
*/
/*@{*/
/**
- * Combine the uniform's base location and the offset
+ * Combine the uniform's storage index and the array index
*/
static inline GLint
_mesa_uniform_merge_location_offset(const struct gl_shader_program *prog,
- unsigned base_location, unsigned offset)
+ unsigned storage_index,
+ unsigned uniform_array_index)
{
- assert(prog->UniformLocationBaseScale >= 1);
- assert(offset < prog->UniformLocationBaseScale);
- return (base_location * prog->UniformLocationBaseScale) + offset;
+ /* location in remap table + array element offset */
+ return prog->UniformStorage[storage_index].remap_location +
+ uniform_array_index;
}
/**
- * Separate the uniform base location and parameter offset
+ * Separate the uniform storage index and array index
*/
static inline void
_mesa_uniform_split_location_offset(const struct gl_shader_program *prog,
- GLint location, unsigned *base_location,
- unsigned *offset)
+ GLint location, unsigned *storage_index,
+ unsigned *uniform_array_index)
{
- *offset = location % prog->UniformLocationBaseScale;
- *base_location = location / prog->UniformLocationBaseScale;
+ *storage_index = prog->UniformRemapTable[location] - prog->UniformStorage;
+ *uniform_array_index = location -
+ prog->UniformRemapTable[location]->remap_location;
+
+ /*gl_uniform_storage in UniformStorage with the calculated base_location
+ * must match with the entry in remap table
+ */
+ assert(&prog->UniformStorage[*storage_index] ==
+ prog->UniformRemapTable[location]);
}
/*@}*/