diff options
-rw-r--r-- | src/glsl/ir.h | 6 | ||||
-rw-r--r-- | src/glsl/ir_uniform.h | 6 | ||||
-rw-r--r-- | src/glsl/link_uniforms.cpp | 50 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 1 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 6 |
5 files changed, 67 insertions, 2 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 5c7faf6ee64..a0f48b2af66 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -342,6 +342,12 @@ enum ir_var_declaration_type { * re-declared by the shader. */ ir_var_declared_implicitly, + + /** + * Variable is implicitly generated by the compiler and should not be + * visible via the API. + */ + ir_var_hidden, }; /** diff --git a/src/glsl/ir_uniform.h b/src/glsl/ir_uniform.h index b9ecf7cdd3c..21b5d05c11a 100644 --- a/src/glsl/ir_uniform.h +++ b/src/glsl/ir_uniform.h @@ -175,6 +175,12 @@ struct gl_uniform_storage { * arrays this is the first element in the array. */ unsigned remap_location; + + /** + * This is a compiler-generated uniform that should not be advertised + * via the API. + */ + bool hidden; }; #ifdef __cplusplus diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index 400e1347933..de2f6c9ac99 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -585,6 +585,8 @@ private: this->uniforms[id].driver_storage = NULL; this->uniforms[id].storage = this->values; this->uniforms[id].atomic_buffer_index = -1; + this->uniforms[id].hidden = + current_var->data.how_declared == ir_var_hidden; if (this->ubo_block_index != -1) { this->uniforms[id].block_index = this->ubo_block_index; @@ -806,6 +808,50 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog) } } +/** + * Sort the array of uniform storage so that the non-hidden uniforms are first + * + * This function sorts the list "in place." This is important because some of + * the storage accessible from \c uniforms has \c uniforms as its \c ralloc + * context. If \c uniforms is freed, some other storage will also be freed. + */ +static unsigned +move_hidden_uniforms_to_end(struct gl_shader_program *prog, + struct gl_uniform_storage *uniforms, + unsigned num_elements) +{ + struct gl_uniform_storage *sorted_uniforms = + ralloc_array(prog, struct gl_uniform_storage, num_elements); + unsigned hidden_uniforms = 0; + unsigned j = 0; + + /* Add the non-hidden uniforms. */ + for (unsigned i = 0; i < num_elements; i++) { + if (!uniforms[i].hidden) + sorted_uniforms[j++] = uniforms[i]; + } + + /* Add and count the hidden uniforms. */ + for (unsigned i = 0; i < num_elements; i++) { + if (uniforms[i].hidden) { + sorted_uniforms[j++] = uniforms[i]; + hidden_uniforms++; + } + } + + assert(prog->UniformHash != NULL); + prog->UniformHash->clear(); + for (unsigned i = 0; i < num_elements; i++) { + if (sorted_uniforms[i].name != NULL) + prog->UniformHash->put(i, sorted_uniforms[i].name); + } + + memcpy(uniforms, sorted_uniforms, sizeof(uniforms[0]) * num_elements); + ralloc_free(sorted_uniforms); + + return hidden_uniforms; +} + void link_assign_uniform_locations(struct gl_shader_program *prog, unsigned int boolean_true) @@ -926,6 +972,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog, sizeof(prog->_LinkedShaders[i]->SamplerTargets)); } + const unsigned hidden_uniforms = + move_hidden_uniforms_to_end(prog, uniforms, num_user_uniforms); + /* Reserve all the explicit locations of the active uniforms. */ for (unsigned i = 0; i < num_user_uniforms; i++) { if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) { @@ -978,6 +1027,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog, #endif prog->NumUserUniformStorage = num_user_uniforms; + prog->NumHiddenUniforms = hidden_uniforms; prog->UniformStorage = uniforms; link_set_image_access_qualifiers(prog); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index be79ed3590e..7389baa1d02 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2843,6 +2843,7 @@ struct gl_shader_program /* post-link info: */ unsigned NumUserUniformStorage; + unsigned NumHiddenUniforms; struct gl_uniform_storage *UniformStorage; /** diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 2be9092c10d..66578204f08 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -565,13 +565,15 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param *params = _mesa_longest_attribute_name_length(shProg); return; case GL_ACTIVE_UNIFORMS: - *params = shProg->NumUserUniformStorage; + *params = shProg->NumUserUniformStorage - shProg->NumHiddenUniforms; return; case GL_ACTIVE_UNIFORM_MAX_LENGTH: { unsigned i; GLint max_len = 0; + const unsigned num_uniforms = + shProg->NumUserUniformStorage - shProg->NumHiddenUniforms; - for (i = 0; i < shProg->NumUserUniformStorage; i++) { + for (i = 0; i < num_uniforms; i++) { /* Add one for the terminating NUL character for a non-array, and * 4 for the "[0]" and the NUL for an array. */ |