diff options
author | Ian Romanick <ian.d.romanick@intel.com> | 2010-07-09 15:28:22 -0700 |
---|---|---|
committer | Ian Romanick <ian.d.romanick@intel.com> | 2010-07-12 18:51:55 -0700 |
commit | 15ce87e9f2d4f66ef87af693a284b3cc9fd870c1 (patch) | |
tree | 0f2fcf7868082401abe45fd8dc388257377ae0bd /src | |
parent | 11fc7beb2fa82179cfd9202449e1365b28f868a9 (diff) |
linker: Detect the shader that contains "main" during intrastage linking
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/linker.cpp | 50 |
1 files changed, 45 insertions, 5 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 3d8f24bb44..11deeed593 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -462,6 +462,33 @@ populate_symbol_table(gl_shader *sh) /** + * Get the function signature for main from a shader + */ +static ir_function_signature * +get_main_function_signature(gl_shader *sh) +{ + ir_function *const f = sh->symbols->get_function("main"); + if (f != NULL) { + exec_list void_parameters; + + /* Look for the 'void main()' signature and ensure that it's defined. + * This keeps the linker from accidentally pick a shader that just + * contains a prototype for main. + * + * We don't have to check for multiple definitions of main (in multiple + * shaders) because that would have already been caught above. + */ + ir_function_signature *sig = f->matching_signature(&void_parameters); + if ((sig != NULL) && sig->is_defined) { + return sig; + } + } + + return NULL; +} + + +/** * Combine a group of shaders for a single stage to generate a linked shader * * \note @@ -527,17 +554,30 @@ link_intrastage_shaders(struct gl_shader_program *prog, * it to the shader. Repeat until there are no undefined references or * until a reference cannot be resolved. */ + gl_shader *main = NULL; + for (unsigned i = 0; i < num_shaders; i++) { + if (get_main_function_signature(shader_list[i]) != NULL) { + main = shader_list[i]; + break; + } + } + if (main == NULL) { + linker_error_printf(prog, "%s shader lacks `main'\n", + (shader_list[0]->Type == GL_VERTEX_SHADER) + ? "vertex" : "fragment"); + return NULL; + } - /* Resolve initializers for global variables in the linked shader. - */ - - gl_shader *const linked = _mesa_new_shader(NULL, 0, shader_list[0]->Type); + gl_shader *const linked = _mesa_new_shader(NULL, 0, main->Type); linked->ir = new(linked) exec_list; - clone_ir_list(linked->ir, shader_list[0]->ir); + clone_ir_list(linked->ir, main->ir); populate_symbol_table(linked); + /* Resolve initializers for global variables in the linked shader. + */ + return linked; } |