X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Flink_functions.cpp;h=6b3e154488aef5e53d10466bb5bc7f48f3aaa9ed;hb=7214451bdce6d553620d2b9b3f1f89d14b113357;hp=ae8818be8718ef54291fac451e8d62b7f1e3138e;hpb=60f898a90ebd29d2593866faa1f2d6f65961a414;p=mesa.git diff --git a/src/glsl/link_functions.cpp b/src/glsl/link_functions.cpp index ae8818be871..6b3e154488a 100644 --- a/src/glsl/link_functions.cpp +++ b/src/glsl/link_functions.cpp @@ -31,7 +31,8 @@ static ir_function_signature * find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders); + gl_shader **shader_list, unsigned num_shaders, + bool use_builtin); class call_link_visitor : public ir_hierarchical_visitor { public: @@ -67,7 +68,7 @@ public: * Doing so will modify the original shader. This may prevent that * shader from being linkable in other programs. */ - const ir_function_signature *const callee = ir->get_callee(); + const ir_function_signature *const callee = ir->callee; assert(callee != NULL); const char *const name = callee->function_name(); @@ -75,9 +76,10 @@ public: * final linked shader. If it does, use it as the target of the call. */ ir_function_signature *sig = - find_matching_signature(name, &callee->parameters, &linked, 1); + find_matching_signature(name, &callee->parameters, &linked, 1, + ir->use_builtin); if (sig != NULL) { - ir->set_callee(sig); + ir->callee = sig; return visit_continue; } @@ -85,12 +87,12 @@ public: * linked. If it's not found there, return an error. */ sig = find_matching_signature(name, &ir->actual_parameters, shader_list, - num_shaders); + num_shaders, ir->use_builtin); if (sig == NULL) { /* FINISHME: Log the full signature of unresolved function. */ - linker_error_printf(this->prog, "unresolved reference to function " - "`%s'\n", name); + linker_error(this->prog, "unresolved reference to function `%s'\n", + name); this->success = false; return visit_stop; } @@ -102,15 +104,19 @@ public: if (f == NULL) { f = new(linked) ir_function(name); - /* Add the new function to the linked IR. + /* Add the new function to the linked IR. Put it at the end + * so that it comes after any global variable declarations + * that it refers to. */ linked->symbols->add_function(f); - linked->ir->push_head(f); + linked->ir->push_tail(f); } ir_function_signature *linked_sig = f->exact_matching_signature(&callee->parameters); - if (linked_sig == NULL) { + if ((linked_sig == NULL) + || ((linked_sig != NULL) + && (linked_sig->is_builtin != ir->use_builtin))) { linked_sig = new(linked) ir_function_signature(callee->return_type); f->add_signature(linked_sig); } @@ -162,7 +168,7 @@ public: */ linked_sig->accept(this); - ir->set_callee(linked_sig); + ir->callee = linked_sig; return visit_continue; } @@ -241,7 +247,8 @@ private: */ ir_function_signature * find_matching_signature(const char *name, const exec_list *actual_parameters, - gl_shader **shader_list, unsigned num_shaders) + gl_shader **shader_list, unsigned num_shaders, + bool use_builtin) { for (unsigned i = 0; i < num_shaders; i++) { ir_function *const f = shader_list[i]->symbols->get_function(name); @@ -254,6 +261,13 @@ find_matching_signature(const char *name, const exec_list *actual_parameters, if ((sig == NULL) || !sig->is_defined) continue; + /* If this function expects to bind to a built-in function and the + * signature that we found isn't a built-in, keep looking. Also keep + * looking if we expect a non-built-in but found a built-in. + */ + if (use_builtin != sig->is_builtin) + continue; + return sig; }