aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/program/ir_to_mesa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/program/ir_to_mesa.cpp')
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp115
1 files changed, 98 insertions, 17 deletions
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 3c2eb5707..1b8b48e53 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -35,6 +35,7 @@
#include "ir_visitor.h"
#include "ir_print_visitor.h"
#include "ir_expression_flattening.h"
+#include "ir_uniform.h"
#include "glsl_types.h"
#include "glsl_parser_extras.h"
#include "../glsl/program.h"
@@ -53,7 +54,6 @@ extern "C" {
#include "program/prog_optimize.h"
#include "program/prog_print.h"
#include "program/program.h"
-#include "program/prog_uniform.h"
#include "program/prog_parameter.h"
#include "program/sampler.h"
}
@@ -2597,17 +2597,17 @@ class add_uniform_to_shader : public uniform_field_visitor {
public:
add_uniform_to_shader(struct gl_shader_program *shader_program,
struct gl_program_parameter_list *params)
- : shader_program(shader_program), params(params), next_sampler(0)
+ : shader_program(shader_program), params(params)
{
/* empty */
}
- int process(ir_variable *var)
+ void process(ir_variable *var)
{
this->idx = -1;
this->uniform_field_visitor::process(var);
- return this->idx;
+ var->location = this->idx;
}
private:
@@ -2615,7 +2615,6 @@ private:
struct gl_shader_program *shader_program;
struct gl_program_parameter_list *params;
- int next_sampler;
int idx;
};
@@ -2648,8 +2647,20 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name)
* store in ParameterValues[].
*/
if (file == PROGRAM_SAMPLER) {
+ unsigned location;
+ const bool found =
+ this->shader_program->UniformHash->get(location,
+ params->Parameters[index].Name);
+ assert(found);
+
+ if (!found)
+ return;
+
+ struct gl_uniform_storage *storage =
+ &this->shader_program->UniformStorage[location];
+
for (unsigned int j = 0; j < size / 4; j++)
- params->ParameterValues[index + j][0].f = this->next_sampler++;
+ params->ParameterValues[index + j][0].f = storage->sampler + j;
}
}
@@ -2684,16 +2695,77 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
|| (strncmp(var->name, "gl_", 3) == 0))
continue;
- int loc = add.process(var);
+ add.process(var);
+ }
+}
- /* 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);
+void
+_mesa_associate_uniform_storage(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params)
+{
+ /* After adding each uniform to the parameter list, connect the storage for
+ * the parameter with the tracking structure used by the API for the
+ * uniform.
+ */
+ unsigned last_location = unsigned(~0);
+ for (unsigned i = 0; i < params->NumParameters; i++) {
+ if (params->Parameters[i].Type != PROGRAM_UNIFORM)
+ continue;
+
+ unsigned location;
+ const bool found =
+ shader_program->UniformHash->get(location, params->Parameters[i].Name);
+ assert(found);
+
+ if (!found)
+ continue;
+
+ if (location != last_location) {
+ struct gl_uniform_storage *storage =
+ &shader_program->UniformStorage[location];
+ enum gl_uniform_driver_format format = uniform_native;
+
+ unsigned columns = 0;
+ switch (storage->type->base_type) {
+ case GLSL_TYPE_UINT:
+ assert(ctx->Const.NativeIntegers);
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_INT:
+ format =
+ (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
+ columns = 1;
+ break;
+ case GLSL_TYPE_FLOAT:
+ format = uniform_native;
+ columns = storage->type->matrix_columns;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (ctx->Const.NativeIntegers) {
+ format = (ctx->Const.UniformBooleanTrue == 1)
+ ? uniform_bool_int_0_1 : uniform_bool_int_0_not0;
+ } else {
+ format = uniform_bool_float;
+ }
+ columns = 1;
+ break;
+ case GLSL_TYPE_SAMPLER:
+ format = uniform_native;
+ columns = 1;
+ break;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ _mesa_uniform_attach_driver_storage(storage,
+ 4 * sizeof(float) * columns,
+ 4 * sizeof(float),
+ format,
+ &params->ParameterValues[i]);
+ last_location = location;
}
}
}
@@ -2759,12 +2831,12 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
element_type->matrix_columns,
element_type->vector_elements,
loc, 1, GL_FALSE, (GLfloat *)values);
- loc += element_type->matrix_columns;
} else {
_mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
values, element_type->gl_type);
- loc += type_size(element_type);
}
+
+ loc++;
}
}
@@ -3211,6 +3283,15 @@ get_mesa_program(struct gl_context *ctx,
_mesa_optimize_program(ctx, prog);
}
+ /* This has to be done last. Any operation that can cause
+ * prog->ParameterValues to get reallocated (e.g., anything that adds a
+ * program constant) has to happen before creating this linkage.
+ */
+ _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
+ if (!shader_program->LinkStatus) {
+ goto fail_exit;
+ }
+
return prog;
fail_exit: