summaryrefslogtreecommitdiff
path: root/src/mesa/program
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-08-31 11:16:09 -0700
committerEric Anholt <eric@anholt.net>2010-08-31 11:34:29 -0700
commit99f3c9caa39fbe9dfa7561c919202395720e9472 (patch)
tree3462d7dd822a157cdf7ff0d8bda83dbaf82b2017 /src/mesa/program
parent2a78807db7a3bc852da0cda1e933a157204c3a47 (diff)
ir_to_mesa: Sort the uniform list we're adding to Parameters[] order.
Fixes glsl-uniform-linking-1 and failure to link a shader in Unigine. An alternative here would be to just ditch using _mesa_add_parameter and build the initial params list on our own, but that would require two walks of the list as well. Bug #29822
Diffstat (limited to 'src/mesa/program')
-rw-r--r--src/mesa/program/ir_to_mesa.cpp46
1 files changed, 41 insertions, 5 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 337ecbaa93..8f39a225af 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2264,6 +2264,25 @@ count_resources(struct gl_program *prog)
_mesa_update_shader_textures_used(prog);
}
+struct uniform_sort {
+ struct gl_uniform *u;
+ int pos;
+};
+
+/* The shader_program->Uniforms list is almost sorted in increasing
+ * uniform->{Frag,Vert}Pos locations, but not quite when there are
+ * uniforms shared between targets. We need to add parameters in
+ * increasing order for the targets.
+ */
+static int
+sort_uniforms(const void *a, const void *b)
+{
+ struct uniform_sort *u1 = (struct uniform_sort *)a;
+ struct uniform_sort *u2 = (struct uniform_sort *)b;
+
+ return u1->pos - u2->pos;
+}
+
/* Add the uniforms to the parameters. The linker chose locations
* in our parameters lists (which weren't created yet), which the
* uniforms code will use to poke values into our parameters list
@@ -2275,12 +2294,14 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
struct gl_program *prog)
{
unsigned int i;
- unsigned int next_sampler = 0;
+ unsigned int next_sampler = 0, num_uniforms = 0;
+ struct uniform_sort *sorted_uniforms;
+
+ sorted_uniforms = talloc_array(NULL, struct uniform_sort,
+ shader_program->Uniforms->NumUniforms);
for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
- const glsl_type *type = uniform->Type;
- unsigned int size;
int parameter_index = -1;
switch (shader->Type) {
@@ -2296,8 +2317,21 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
}
/* Only add uniforms used in our target. */
- if (parameter_index == -1)
- continue;
+ if (parameter_index != -1) {
+ sorted_uniforms[num_uniforms].pos = parameter_index;
+ sorted_uniforms[num_uniforms].u = uniform;
+ num_uniforms++;
+ }
+ }
+
+ qsort(sorted_uniforms, num_uniforms, sizeof(struct uniform_sort),
+ sort_uniforms);
+
+ for (i = 0; i < num_uniforms; i++) {
+ struct gl_uniform *uniform = sorted_uniforms[i].u;
+ int parameter_index = sorted_uniforms[i].pos;
+ const glsl_type *type = uniform->Type;
+ unsigned int size;
if (type->is_vector() ||
type->is_scalar()) {
@@ -2344,6 +2378,8 @@ add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
}
}
}
+
+ talloc_free(sorted_uniforms);
}
static void