this->num_shaders = num_shaders;
this->success = true;
this->linked = linked;
+
+ this->locals = hash_table_ctor(0, hash_table_pointer_hash,
+ hash_table_pointer_compare);
+ }
+
+ ~call_link_visitor()
+ {
+ hash_table_dtor(this->locals);
+ }
+
+ virtual ir_visitor_status visit(ir_variable *ir)
+ {
+ hash_table_insert(locals, ir, ir);
+ return visit_continue;
}
virtual ir_visitor_status visit_enter(ir_call *ir)
}
linked_sig->is_defined = true;
+ hash_table_dtor(ht);
- /* FINISHME: Patch references inside the function to things outside the
- * FINISHME: function (i.e., function calls and global variables).
+ /* Patch references inside the function to things outside the function
+ * (i.e., function calls and global variables).
*/
+ linked_sig->accept(this);
- hash_table_dtor(ht);
+ return visit_continue;
+ }
+
+ virtual ir_visitor_status visit(ir_dereference_variable *ir)
+ {
+ if (hash_table_find(locals, ir->var) == NULL) {
+ /* The non-function variable must be a global, so try to find the
+ * variable in the shader's symbol table. If the variable is not
+ * found, then it's a global that *MUST* be defined in the original
+ * shader.
+ */
+ ir_variable *var = linked->symbols->get_variable(ir->var->name);
+ if (var == NULL) {
+ /* Clone the ir_variable that the dereference already has and add
+ * it to the linked shader.
+ */
+ var = ir->var->clone(NULL);
+ linked->symbols->add_variable(var->name, var);
+ linked->ir->push_head(var);
+ }
+
+ ir->var = var;
+ }
return visit_continue;
}
* global variables from the shader where the function originated.
*/
gl_shader *linked;
+
+ /**
+ * Table of variables local to the function.
+ */
+ hash_table *locals;
};