summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2011-09-09 18:27:36 -0700
committerIan Romanick <[email protected]>2011-10-18 17:26:38 -0700
commitb2572928a50ce42abc2733202d08f5a00733d707 (patch)
tree8d0fc7b60ae88515af82f5ad8ecf51a183c3d019
parentbbbb8345ab9df2d634dc2a34d257ee2cbf930292 (diff)
ir_to_mesa: Generate gl_program_parameter list by walking the GLSL IR.
Generate the program parameters list by walking the IR instead of by walking the list of linked uniforms. This simplifies the code quite a bit, and is probably a bit more correct. The list of linked uniforms should really only be used by the GL API to interact with the application. Signed-off-by: Ian Romanick <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]> Cc: Bryan Cain <[email protected]> Cc: Eric Anholt <[email protected]>
-rw-r--r--src/mesa/program/ir_to_mesa.cpp163
-rw-r--r--src/mesa/program/ir_to_mesa.h7
2 files changed, 70 insertions, 100 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 8330bc501a2..fecab50f753 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -2588,121 +2588,83 @@ check_resources(const struct gl_context *ctx,
}
-
-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
- * when uniforms are updated.
- */
-static void
-add_uniforms_to_parameters_list(struct gl_shader_program *shader_program,
- struct gl_shader *shader,
- struct gl_program *prog)
+add_uniform_to_shader(ir_variable *var,
+ struct gl_program_parameter_list *params,
+ unsigned int &next_sampler)
{
- unsigned int i;
- unsigned int next_sampler = 0, num_uniforms = 0;
- struct uniform_sort *sorted_uniforms;
+ const glsl_type *type = var->type;
+ unsigned int size;
- sorted_uniforms = ralloc_array(NULL, struct uniform_sort,
- shader_program->Uniforms->NumUniforms);
+ if (type->is_vector() || type->is_scalar()) {
+ size = type->vector_elements;
+ } else {
+ size = type_size(type) * 4;
+ }
- for (i = 0; i < shader_program->Uniforms->NumUniforms; i++) {
- struct gl_uniform *uniform = shader_program->Uniforms->Uniforms + i;
- int parameter_index = -1;
+ gl_register_file file;
+ if (type->is_sampler() ||
+ (type->is_array() && type->fields.array->is_sampler())) {
+ file = PROGRAM_SAMPLER;
+ } else {
+ file = PROGRAM_UNIFORM;
+ }
- switch (shader->Type) {
- case GL_VERTEX_SHADER:
- parameter_index = uniform->VertPos;
- break;
- case GL_FRAGMENT_SHADER:
- parameter_index = uniform->FragPos;
- break;
- case GL_GEOMETRY_SHADER:
- parameter_index = uniform->GeomPos;
- break;
- }
+ int index = _mesa_lookup_parameter_index(params, -1, var->name);
+ if (index < 0) {
+ index = _mesa_add_parameter(params, file,
+ var->name, size, type->gl_type,
+ NULL, NULL, 0x0);
- /* Only add uniforms used in our target. */
- if (parameter_index != -1) {
- sorted_uniforms[num_uniforms].pos = parameter_index;
- sorted_uniforms[num_uniforms].u = uniform;
- num_uniforms++;
+ /* Sampler uniform values are stored in prog->SamplerUnits,
+ * and the entry in that array is selected by this index we
+ * store in ParameterValues[].
+ */
+ if (file == PROGRAM_SAMPLER) {
+ for (unsigned int j = 0; j < size / 4; j++)
+ params->ParameterValues[index + j][0].f = next_sampler++;
}
}
- 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()) {
- size = type->vector_elements;
- } else {
- size = type_size(type) * 4;
- }
+ return index;
+}
- gl_register_file file;
- if (type->is_sampler() ||
- (type->is_array() && type->fields.array->is_sampler())) {
- file = PROGRAM_SAMPLER;
- } else {
- file = PROGRAM_UNIFORM;
- }
+/**
+ * Generate the program parameters list for the user uniforms in a shader
+ *
+ * \param shader_program Linked shader program. This is only used to
+ * emit possible link errors to the info log.
+ * \param sh Shader whose uniforms are to be processed.
+ * \param params Parameter list to be filled in.
+ */
+void
+_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+ *shader_program,
+ struct gl_shader *sh,
+ struct gl_program_parameter_list
+ *params)
+{
+ unsigned int next_sampler = 0;
- GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
- uniform->Name);
+ foreach_list(node, sh->ir) {
+ ir_variable *var = ((ir_instruction *) node)->as_variable();
- if (index < 0) {
- index = _mesa_add_parameter(prog->Parameters, file,
- uniform->Name, size, type->gl_type,
- NULL, NULL, 0x0);
+ if ((var == NULL) || (var->mode != ir_var_uniform)
+ || (strncmp(var->name, "gl_", 3) == 0))
+ continue;
- /* Sampler uniform values are stored in prog->SamplerUnits,
- * and the entry in that array is selected by this index we
- * store in ParameterValues[].
- */
- if (file == PROGRAM_SAMPLER) {
- for (unsigned int j = 0; j < size / 4; j++)
- prog->Parameters->ParameterValues[index + j][0].f = next_sampler++;
- }
+ int loc = add_uniform_to_shader(var, params, next_sampler);
- /* The location chosen in the Parameters list here (returned
- * from _mesa_add_uniform) has to match what the linker chose.
- */
- if (index != parameter_index) {
- linker_error(shader_program,
- "Allocation of uniform `%s' to target failed "
- "(%d vs %d)\n",
- uniform->Name, index, parameter_index);
- }
+ /* The location chosen in the Parameters list here (returned from
+ * _mesa_add_parameter) has to match what the linker chose.
+ */
+ if (var->location != loc) {
+ linker_error(shader_program,
+ "Allocation of uniform `%s' to target failed "
+ "(%d vs %d)\n",
+ var->name, loc, var->location);
}
}
-
- ralloc_free(sorted_uniforms);
}
static void
@@ -3046,7 +3008,8 @@ get_mesa_program(struct gl_context *ctx,
v.shader_program = shader_program;
v.options = options;
- add_uniforms_to_parameters_list(shader_program, shader, prog);
+ _mesa_generate_parameters_list_for_uniforms(shader_program, shader,
+ prog->Parameters);
/* Emit Mesa IR for main(). */
visit_exec_list(shader->ir, &v);
diff --git a/src/mesa/program/ir_to_mesa.h b/src/mesa/program/ir_to_mesa.h
index 5649282f03f..d046b0fcf9b 100644
--- a/src/mesa/program/ir_to_mesa.h
+++ b/src/mesa/program/ir_to_mesa.h
@@ -38,4 +38,11 @@ GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program
#ifdef __cplusplus
}
+
+void
+_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
+ *shader_program,
+ struct gl_shader *sh,
+ struct gl_program_parameter_list
+ *params);
#endif