diff options
Diffstat (limited to 'mesalib/src/mesa/program/ir_to_mesa.cpp')
-rw-r--r-- | mesalib/src/mesa/program/ir_to_mesa.cpp | 115 |
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, + ¶ms->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: |