glsl/linker: Allow link_intrastage_shaders when there is no main()
authorIan Romanick <ian.d.romanick@intel.com>
Thu, 15 Sep 2016 18:09:34 +0000 (11:09 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Thu, 10 Nov 2016 22:30:49 +0000 (14:30 -0800)
This enables a sort of par-linking.  The primary use for this feature is
resolving built-in functions in the stand-alone compiler.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/compiler/glsl/linker.cpp
src/compiler/glsl/linker.h

index 81678af23f5f6c4b23061067705e133ae660b256..cc28b26964a46bd64b3576f17e7f04937338dfc3 100644 (file)
@@ -2093,12 +2093,13 @@ link_cs_input_layout_qualifiers(struct gl_shader_program *prog,
  * If this function is supplied a single shader, it is cloned, and the new
  * shader is returned.
  */
-static struct gl_linked_shader *
+struct gl_linked_shader *
 link_intrastage_shaders(void *mem_ctx,
                         struct gl_context *ctx,
                         struct gl_shader_program *prog,
                         struct gl_shader **shader_list,
-                        unsigned num_shaders)
+                        unsigned num_shaders,
+                        bool allow_missing_main)
 {
    struct gl_uniform_block *ubo_blocks = NULL;
    struct gl_uniform_block *ssbo_blocks = NULL;
@@ -2176,6 +2177,9 @@ link_intrastage_shaders(void *mem_ctx,
       }
    }
 
+   if (main == NULL && allow_missing_main)
+      main = shader_list[0];
+
    if (main == NULL) {
       linker_error(prog, "%s shader lacks `main'\n",
                    _mesa_shader_stage_to_string(shader_list[0]->Stage));
@@ -2205,16 +2209,18 @@ link_intrastage_shaders(void *mem_ctx,
    /* Move any instructions other than variable declarations or function
     * declarations into main.
     */
-   exec_node *insertion_point =
-      move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false,
-                            linked);
+   if (main_sig != NULL) {
+      exec_node *insertion_point =
+         move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false,
+                               linked);
 
-   for (unsigned i = 0; i < num_shaders; i++) {
-      if (shader_list[i] == main)
-         continue;
+      for (unsigned i = 0; i < num_shaders; i++) {
+         if (shader_list[i] == main)
+            continue;
 
-      insertion_point = move_non_declarations(shader_list[i]->ir,
-                                              insertion_point, true, linked);
+         insertion_point = move_non_declarations(shader_list[i]->ir,
+                                                 insertion_point, true, linked);
+      }
    }
 
    if (!link_function_calls(prog, linked, shader_list, num_shaders)) {
@@ -4824,7 +4830,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
       if (num_shaders[stage] > 0) {
          gl_linked_shader *const sh =
             link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage],
-                                    num_shaders[stage]);
+                                    num_shaders[stage], false);
 
          if (!prog->LinkStatus) {
             if (sh)
index d30aeda4f653d704823144a7009ea7da056c8c2f..8363d549428da53ede9eee4aeff81041807da372 100644 (file)
@@ -85,6 +85,15 @@ extern void
 link_check_atomic_counter_resources(struct gl_context *ctx,
                                     struct gl_shader_program *prog);
 
+
+extern struct gl_linked_shader *
+link_intrastage_shaders(void *mem_ctx,
+                        struct gl_context *ctx,
+                        struct gl_shader_program *prog,
+                        struct gl_shader **shader_list,
+                        unsigned num_shaders,
+                        bool allow_missing_main);
+
 /**
  * Class for processing all of the leaf fields of a variable that corresponds
  * to a program resource.