summaryrefslogtreecommitdiffstats
path: root/src/glsl/linker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/glsl/linker.cpp')
-rw-r--r--src/glsl/linker.cpp58
1 files changed, 49 insertions, 9 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index d76cd9068c2..eb1bdc05932 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -3362,6 +3362,30 @@ build_stageref(struct gl_shader_program *shProg, const char *name,
return stages;
}
+/**
+ * Create gl_shader_variable from ir_variable class.
+ */
+static gl_shader_variable *
+create_shader_variable(struct gl_shader_program *shProg, const ir_variable *in)
+{
+ gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable);
+ if (!out)
+ return NULL;
+
+ out->type = in->type;
+ out->name = ralloc_strdup(shProg, in->name);
+
+ if (!out->name)
+ return NULL;
+
+ out->location = in->data.location;
+ out->index = in->data.index;
+ out->patch = in->data.patch;
+ out->mode = in->data.mode;
+
+ return out;
+}
+
static bool
add_interface_variables(struct gl_shader_program *shProg,
exec_list *ir, GLenum programInterface)
@@ -3413,9 +3437,13 @@ add_interface_variables(struct gl_shader_program *shProg,
if (strncmp(var->name, "gl_out_FragData", 15) == 0)
continue;
- if (!add_program_resource(shProg, programInterface, var,
- build_stageref(shProg, var->name,
- var->data.mode) | mask))
+ gl_shader_variable *sha_v = create_shader_variable(shProg, var);
+ if (!sha_v)
+ return false;
+
+ if (!add_program_resource(shProg, programInterface, sha_v,
+ build_stageref(shProg, sha_v->name,
+ sha_v->mode) | mask))
return false;
}
return true;
@@ -3445,9 +3473,12 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type)
}
if (type == iface) {
- if (!add_program_resource(shProg, iface, var,
- build_stageref(shProg, var->name,
- var->data.mode)))
+ gl_shader_variable *sha_v = create_shader_variable(shProg, var);
+ if (!sha_v)
+ return false;
+ if (!add_program_resource(shProg, iface, sha_v,
+ build_stageref(shProg, sha_v->name,
+ sha_v->mode)))
return false;
}
}
@@ -3467,7 +3498,10 @@ add_fragdata_arrays(struct gl_shader_program *shProg)
ir_variable *var = node->as_variable();
if (var) {
assert(var->data.mode == ir_var_shader_out);
- if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, var,
+ gl_shader_variable *sha_v = create_shader_variable(shProg, var);
+ if (!sha_v)
+ return false;
+ if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v,
1 << MESA_SHADER_FRAGMENT))
return false;
}
@@ -3718,8 +3752,14 @@ build_program_resource_list(struct gl_shader_program *shProg)
if (shProg->SeparateShader) {
if (!add_packed_varyings(shProg, input_stage, GL_PROGRAM_INPUT))
return;
- if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT))
- return;
+
+ /* Only when dealing with multiple stages, otherwise we would have
+ * duplicate gl_shader_variable entries.
+ */
+ if (input_stage != output_stage) {
+ if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT))
+ return;
+ }
}
if (!add_fragdata_arrays(shProg))