Removes another dependency on the UniformHash hash table. --- src/mesa/program/sampler.cpp | 123 +++++++++++++++++++------------------------ 1 file changed, 53 insertions(+), 70 deletions(-)
diff --git a/src/mesa/program/sampler.cpp b/src/mesa/program/sampler.cpp index ea3024d..01150fa 100644 --- a/src/mesa/program/sampler.cpp +++ b/src/mesa/program/sampler.cpp @@ -35,71 +35,56 @@ #include "program/program.h" -class get_sampler_name : public ir_hierarchical_visitor +/* Calculate the sampler index based on array indicies and also + * calculate the base uniform location for struct members. + */ +static void +calc_sampler_offsets(ir_dereference *deref, unsigned *array_elements, + unsigned *location_offset, unsigned *sampler_offset, + struct gl_shader_program *shader_program) { -public: - get_sampler_name(ir_dereference *last, - struct gl_shader_program *shader_program) - { - this->mem_ctx = ralloc_context(NULL); - this->shader_program = shader_program; - this->name = NULL; - this->offset = 0; - this->last = last; - } + switch (deref->ir_type) { + case ir_type_dereference_array: { + ir_dereference_array *ir = deref->as_dereference_array(); + calc_sampler_offsets(ir->array->as_dereference(), array_elements, + location_offset, sampler_offset, shader_program); - ~get_sampler_name() - { - ralloc_free(this->mem_ctx); + ir_constant *index = ir->array_index->as_constant(); + if (index) { + *sampler_offset += index->value.i[0] * *array_elements; + } else { + /* GLSL 1.10 and 1.20 allowed variable sampler array indices, + * while GLSL 1.30 requires that the array indices be + * constant integer expressions. We don't expect any driver + * to actually work with a really variable array index, so + * all that would work would be an unrolled loop counter that ends + * up being constant above. + */ + ralloc_strcat(&shader_program->InfoLog, + "warning: Variable sampler array index unsupported.\n" + "This feature of the language was removed in GLSL 1.20 " + "and is unlikely to be supported for 1.10 in Mesa.\n"); + } + break; } - virtual ir_visitor_status visit(ir_dereference_variable *ir) - { - this->name = ir->var->name; - return visit_continue; + case ir_type_dereference_record: { + ir_dereference_record *ir = deref->as_dereference_record(); + *location_offset += ir->record->type->field_index(ir->field); + calc_sampler_offsets(ir->record->as_dereference(), array_elements, + location_offset, sampler_offset, shader_program); + break; } - virtual ir_visitor_status visit_leave(ir_dereference_record *ir) - { - this->name = ralloc_asprintf(mem_ctx, "%s.%s", name, ir->field); - return visit_continue; + case ir_type_dereference_variable: { + return; } - virtual ir_visitor_status visit_leave(ir_dereference_array *ir) - { - ir_constant *index = ir->array_index->as_constant(); - int i; - - if (index) { - i = index->value.i[0]; - } else { - /* GLSL 1.10 and 1.20 allowed variable sampler array indices, - * while GLSL 1.30 requires that the array indices be - * constant integer expressions. We don't expect any driver - * to actually work with a really variable array index, so - * all that would work would be an unrolled loop counter that ends - * up being constant above. - */ - ralloc_strcat(&shader_program->InfoLog, - "warning: Variable sampler array index unsupported.\n" - "This feature of the language was removed in GLSL 1.20 " - "and is unlikely to be supported for 1.10 in Mesa.\n"); - i = 0; - } - if (ir != last) { - this->name = ralloc_asprintf(mem_ctx, "%s[%d]", name, i); - } else { - offset = i; - } - return visit_continue; + default: + unreachable("Invalid deref type"); + break; } - - struct gl_shader_program *shader_program; - const char *name; - void *mem_ctx; - int offset; - ir_dereference *last; -}; +} int @@ -107,30 +92,28 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler, struct gl_shader_program *shader_program, const struct gl_program *prog) { - get_sampler_name getname(sampler, shader_program); - + unsigned array_elements = 1; + unsigned location_offset = 0; + unsigned sampler_offset = 0; GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target); - sampler->accept(&getname); + calc_sampler_offsets(sampler, &array_elements, &location_offset, + &sampler_offset, shader_program); - unsigned location; - if (!shader_program->UniformHash->get(location, getname.name)) { - linker_error(shader_program, - "failed to find sampler named %s.\n", getname.name); - return 0; - } + unsigned location = sampler->variable_referenced()->data.location + + location_offset; - if (!shader_program->UniformStorage[location].sampler[shader].active) { + if (location > shader_program->NumUniformStorage - 1 || + !shader_program->UniformStorage[location].sampler[shader].active) { assert(0 && "cannot return a sampler"); linker_error(shader_program, - "cannot return a sampler named %s, because it is not " - "used in this shader stage. This is a driver bug.\n", - getname.name); + "cannot return a sampler, because it is not " + "used in this shader stage. This is a driver bug.\n"); return 0; } return shader_program->UniformStorage[location].sampler[shader].index + - getname.offset; + sampler_offset; } -- 2.4.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev