summaryrefslogtreecommitdiffstats
path: root/src/mesa/program/ir_to_mesa.cpp
diff options
context:
space:
mode:
authorTimothy Arceri <timothy.arceri@collabora.com>2016-02-06 09:30:00 +1100
committerTimothy Arceri <timothy.arceri@collabora.com>2016-02-09 12:02:58 +1100
commitedc108765e71795755efcf7be479e3bcdd7b7ecf (patch)
tree8bdd3593ecfbe38cf4945c87b18019b4c0ba96fa /src/mesa/program/ir_to_mesa.cpp
parentd0e1d6b7e27bf5f05436e47080d326d7daa63af2 (diff)
downloadexternal_mesa3d-edc108765e71795755efcf7be479e3bcdd7b7ecf.zip
external_mesa3d-edc108765e71795755efcf7be479e3bcdd7b7ecf.tar.gz
external_mesa3d-edc108765e71795755efcf7be479e3bcdd7b7ecf.tar.bz2
mesa: compute sampler index in ir_to_mesa rather than using UniformHash
The aim of this is to work towards removing UniformHash from the program struct so that we don't need to hold onto it in memory and pass it around outside the linker. Reviewed-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'src/mesa/program/ir_to_mesa.cpp')
-rw-r--r--src/mesa/program/ir_to_mesa.cpp81
1 files changed, 78 insertions, 3 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 68cc4a5..f2902c9 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1539,6 +1539,82 @@ get_assignment_lhs(ir_dereference *ir, ir_to_mesa_visitor *v)
return dst_reg(v->result);
}
+/* Calculate the sampler index and also calculate the base uniform location
+ * for struct members.
+ */
+static void
+calc_sampler_offsets(struct gl_shader_program *prog, ir_dereference *deref,
+ unsigned *offset, unsigned *array_elements,
+ unsigned *location)
+{
+ if (deref->ir_type == ir_type_dereference_variable)
+ return;
+
+ switch (deref->ir_type) {
+ case ir_type_dereference_array: {
+ ir_dereference_array *deref_arr = deref->as_dereference_array();
+ ir_constant *array_index =
+ deref_arr->array_index->constant_expression_value();
+
+ if (!array_index) {
+ /* 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(&prog->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");
+ } else {
+ *offset += array_index->value.u[0] * *array_elements;
+ }
+
+ *array_elements *= deref_arr->array->type->length;
+
+ calc_sampler_offsets(prog, deref_arr->array->as_dereference(),
+ offset, array_elements, location);
+ break;
+ }
+
+ case ir_type_dereference_record: {
+ ir_dereference_record *deref_record = deref->as_dereference_record();
+ unsigned field_index =
+ deref_record->record->type->field_index(deref_record->field);
+ *location +=
+ deref_record->record->type->record_location_offset(field_index);
+ calc_sampler_offsets(prog, deref_record->record->as_dereference(),
+ offset, array_elements, location);
+ break;
+ }
+
+ default:
+ unreachable("Invalid deref type");
+ break;
+ }
+}
+
+static int
+get_sampler_uniform_value(class ir_dereference *sampler,
+ struct gl_shader_program *shader_program,
+ const struct gl_program *prog)
+{
+ GLuint shader = _mesa_program_enum_to_shader_stage(prog->Target);
+ ir_variable *var = sampler->variable_referenced();
+ unsigned location = var->data.location;
+ unsigned array_elements = 1;
+ unsigned offset = 0;
+
+ calc_sampler_offsets(shader_program, sampler, &offset, &array_elements,
+ &location);
+
+ assert(shader_program->UniformStorage[location].opaque[shader].active);
+ return shader_program->UniformStorage[location].opaque[shader].index +
+ offset;
+}
+
/**
* Process the condition of a conditional assignment
*
@@ -1988,9 +2064,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
if (ir->shadow_comparitor)
inst->tex_shadow = GL_TRUE;
- inst->sampler = _mesa_get_sampler_uniform_value(ir->sampler,
- this->shader_program,
- this->prog);
+ inst->sampler = get_sampler_uniform_value(ir->sampler, shader_program,
+ prog);
switch (sampler_type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D: