summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIan Romanick <[email protected]>2016-09-15 11:09:34 -0700
committerIan Romanick <[email protected]>2016-11-10 14:30:49 -0800
commit9788b3b6f363580fd8d9d7e221cab28879e4d169 (patch)
tree4b7a4156d35ba43246068616e99e89410d2df054 /src
parent7372d2153ab68eefec792a8cb094a6557bdb8b4a (diff)
glsl/linker: Allow link_intrastage_shaders when there is no main()
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 <[email protected]> Reviewed-by: Iago Toral Quiroga <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/compiler/glsl/linker.cpp28
-rw-r--r--src/compiler/glsl/linker.h9
2 files changed, 26 insertions, 11 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 81678af23f5..cc28b26964a 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -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)
diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h
index d30aeda4f65..8363d549428 100644
--- a/src/compiler/glsl/linker.h
+++ b/src/compiler/glsl/linker.h
@@ -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.