summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorTapani Pälli <[email protected]>2014-03-06 11:00:17 +0200
committerTapani Pälli <[email protected]>2014-03-10 09:46:24 +0200
commit56b1be4399d76c0fe5ddf099a7ac5b45ab58e8cf (patch)
tree0ee265183905dec2e7c8d5679c5014e07f1bdb21 /src/mesa/main
parentaa0d95a08dbf8f0e3ed66b624ccbc60753b61ef1 (diff)
mesa/glsl: introduce a remap table for uniform locations
Patch adds a remap table for uniforms that is used to provide a mapping from application specified uniform location to actual location in the UniformStorage. Existing UniformLocationBaseScale usage is removed as table can be used to set sequential values for array uniform elements. This mapping helps to implement GL_ARB_explicit_uniform_location so that uniforms locations can be reorganized and handled in a more easy manner. v2: small fixes + rename parameters for merge and split functions (Ian) improve documentation, remove old check for location bounds (Eric) Signed-off-by: Tapani Pälli <[email protected]> Reviewed-by: Ian Romanick <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
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]);
}
/*@}*/