summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/glsl')
-rw-r--r--src/compiler/glsl/linker.cpp78
-rw-r--r--src/compiler/glsl/lower_ubo_reference.cpp10
-rw-r--r--src/compiler/glsl/standalone.cpp2
-rw-r--r--src/compiler/glsl/standalone_scaffolding.cpp10
-rw-r--r--src/compiler/glsl/standalone_scaffolding.h3
5 files changed, 64 insertions, 39 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index f5c177e..f62a848 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -181,7 +181,43 @@ private:
};
-class array_resize_visitor : public ir_hierarchical_visitor {
+/**
+ * A visitor helper that provides methods for updating the types of
+ * ir_dereferences. Classes that update variable types (say, updating
+ * array sizes) will want to use this so that dereference types stay in sync.
+ */
+class deref_type_updater : public ir_hierarchical_visitor {
+public:
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ ir->type = ir->var->type;
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
+ {
+ const glsl_type *const vt = ir->array->type;
+ if (vt->is_array())
+ ir->type = vt->fields.array;
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
+ {
+ for (unsigned i = 0; i < ir->record->type->length; i++) {
+ const struct glsl_struct_field *field =
+ &ir->record->type->fields.structure[i];
+ if (strcmp(field->name, ir->field) == 0) {
+ ir->type = field->type;
+ break;
+ }
+ }
+ return visit_continue;
+ }
+};
+
+
+class array_resize_visitor : public deref_type_updater {
public:
unsigned num_vertices;
gl_shader_program *prog;
@@ -240,24 +276,6 @@ public:
return visit_continue;
}
-
- /* Dereferences of input variables need to be updated so that their type
- * matches the newly assigned type of the variable they are accessing. */
- virtual ir_visitor_status visit(ir_dereference_variable *ir)
- {
- ir->type = ir->var->type;
- return visit_continue;
- }
-
- /* Dereferences of 2D input arrays need to be updated so that their type
- * matches the newly assigned type of the array they are accessing. */
- virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
- {
- const glsl_type *const vt = ir->array->type;
- if (vt->is_array())
- ir->type = vt->fields.array;
- return visit_continue;
- }
};
/**
@@ -1353,7 +1371,7 @@ move_non_declarations(exec_list *instructions, exec_node *last,
* it inside that function leads to compiler warnings with some versions of
* gcc.
*/
-class array_sizing_visitor : public ir_hierarchical_visitor {
+class array_sizing_visitor : public deref_type_updater {
public:
array_sizing_visitor()
: mem_ctx(ralloc_context(NULL)),
@@ -2273,6 +2291,8 @@ update_array_sizes(struct gl_shader_program *prog)
if (prog->_LinkedShaders[i] == NULL)
continue;
+ bool types_were_updated = false;
+
foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
ir_variable *const var = node->as_variable();
@@ -2328,11 +2348,15 @@ update_array_sizes(struct gl_shader_program *prog)
var->type = glsl_type::get_array_instance(var->type->fields.array,
size + 1);
- /* FINISHME: We should update the types of array
- * dereferences of this variable now.
- */
+ types_were_updated = true;
}
}
+
+ /* Update the types of dereferences in case we changed any. */
+ if (types_were_updated) {
+ deref_type_updater v;
+ v.run(prog->_LinkedShaders[i]->ir);
+ }
}
}
@@ -4785,14 +4809,6 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
"type of shader\n");
}
- for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) {
- if (prog->_LinkedShaders[i] != NULL) {
- _mesa_delete_linked_shader(ctx, prog->_LinkedShaders[i]);
- }
-
- prog->_LinkedShaders[i] = NULL;
- }
-
/* Link all shaders for a particular stage and validate the result.
*/
for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
diff --git a/src/compiler/glsl/lower_ubo_reference.cpp b/src/compiler/glsl/lower_ubo_reference.cpp
index 37134a9..eafa1dd 100644
--- a/src/compiler/glsl/lower_ubo_reference.cpp
+++ b/src/compiler/glsl/lower_ubo_reference.cpp
@@ -107,7 +107,6 @@ public:
struct gl_linked_shader *shader;
bool clamp_block_indices;
- struct gl_uniform_buffer_variable *ubo_var;
const struct glsl_struct_field *struct_field;
ir_variable *variable;
ir_rvalue *uniform_block;
@@ -308,8 +307,11 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx,
this->uniform_block = index;
}
- this->ubo_var = var->is_interface_instance()
- ? &blocks[i]->Uniforms[0] : &blocks[i]->Uniforms[var->data.location];
+ if (var->is_interface_instance()) {
+ *const_offset = 0;
+ } else {
+ *const_offset = blocks[i]->Uniforms[var->data.location].Offset;
+ }
break;
}
@@ -317,8 +319,6 @@ lower_ubo_reference_visitor::setup_for_load_or_store(void *mem_ctx,
assert(this->uniform_block);
- *const_offset = ubo_var->Offset;
-
this->struct_field = NULL;
setup_buffer_access(mem_ctx, deref, offset, const_offset, row_major,
matrix_columns, &this->struct_field, packing);
diff --git a/src/compiler/glsl/standalone.cpp b/src/compiler/glsl/standalone.cpp
index 055c433..f096490 100644
--- a/src/compiler/glsl/standalone.cpp
+++ b/src/compiler/glsl/standalone.cpp
@@ -421,7 +421,7 @@ standalone_compile_shader(const struct standalone_options *_options,
}
if ((status == EXIT_SUCCESS) && options->do_link) {
- _mesa_clear_shader_program_data(whole_program);
+ _mesa_clear_shader_program_data(ctx, whole_program);
link_shaders(ctx, whole_program);
status = (whole_program->LinkStatus) ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/src/compiler/glsl/standalone_scaffolding.cpp b/src/compiler/glsl/standalone_scaffolding.cpp
index 35e40d6..d229368 100644
--- a/src/compiler/glsl/standalone_scaffolding.cpp
+++ b/src/compiler/glsl/standalone_scaffolding.cpp
@@ -123,8 +123,16 @@ _mesa_delete_linked_shader(struct gl_context *ctx,
}
void
-_mesa_clear_shader_program_data(struct gl_shader_program *shProg)
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
{
+ for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
+ if (shProg->_LinkedShaders[i] != NULL) {
+ _mesa_delete_linked_shader(ctx, shProg->_LinkedShaders[i]);
+ shProg->_LinkedShaders[i] = NULL;
+ }
+ }
+
shProg->NumUniformStorage = 0;
shProg->UniformStorage = NULL;
shProg->NumUniformRemapTable = 0;
diff --git a/src/compiler/glsl/standalone_scaffolding.h b/src/compiler/glsl/standalone_scaffolding.h
index b56dd3e..2c04548 100644
--- a/src/compiler/glsl/standalone_scaffolding.h
+++ b/src/compiler/glsl/standalone_scaffolding.h
@@ -56,7 +56,8 @@ _mesa_delete_linked_shader(struct gl_context *ctx,
struct gl_linked_shader *sh);
extern "C" void
-_mesa_clear_shader_program_data(struct gl_shader_program *);
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *);
extern "C" void
_mesa_shader_debug(struct gl_context *ctx, GLenum type, GLuint *id,