[Mesa-dev] [PATCH V3 6/6] mesa: simplify sampler indexing
Timothy Arceri
t_arceri at yahoo.com.au
Tue Sep 1 19:44:38 PDT 2015
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
More information about the mesa-dev
mailing list