diff options
author | Ian Romanick <[email protected]> | 2010-07-15 20:20:36 -0700 |
---|---|---|
committer | Ian Romanick <[email protected]> | 2010-07-19 14:50:43 -0700 |
commit | fc9ae101b4b7a71ca7a5d4f185e887064007e0d1 (patch) | |
tree | 35f60e728a215a240c2d1f14a2428f521f4e3f69 /src/glsl/link_functions.cpp | |
parent | 532c2d30850908b75f4b0ad0aa5fa7ce88f8202d (diff) |
linker: Recursively resolve function calls in imported functions
Diffstat (limited to 'src/glsl/link_functions.cpp')
-rw-r--r-- | src/glsl/link_functions.cpp | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index 721bec65f3e..a9ed49a3492 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -51,6 +51,20 @@ public: 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) @@ -143,12 +157,36 @@ public: } 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; } @@ -178,6 +216,11 @@ private: * global variables from the shader where the function originated. */ gl_shader *linked; + + /** + * Table of variables local to the function. + */ + hash_table *locals; }; |