linker: Assign varying locations for separable programs

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
Ian Romanick 2014-02-14 12:10:27 -08:00
parent 7d73c3e99e
commit 1ff5a2b1ba
2 changed files with 30 additions and 3 deletions

View File

@ -1198,6 +1198,23 @@ assign_varying_locations(struct gl_context *ctx,
matches.record(output_var, input_var);
}
}
} else {
/* If there's no producer stage, then this must be a separable program.
* For example, we may have a program that has just a fragment shader.
* Later this program will be used with some arbitrary vertex (or
* geometry) shader program. This means that locations must be assigned
* for all the inputs.
*/
foreach_list(node, consumer->ir) {
ir_variable *const input_var =
((ir_instruction *) node)->as_variable();
if ((input_var == NULL) ||
(input_var->data.mode != ir_var_shader_in))
continue;
matches.record(NULL, input_var);
}
}
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {

View File

@ -2502,7 +2502,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
if (last >= 0 && last < MESA_SHADER_FRAGMENT) {
gl_shader *const sh = prog->_LinkedShaders[last];
if (num_tfeedback_decls != 0) {
if (num_tfeedback_decls != 0 || prog->SeparateShader) {
/* There was no fragment shader, but we still have to assign varying
* locations for use by transform feedback.
*/
@ -2516,7 +2516,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
do_dead_builtin_varyings(ctx, sh, NULL,
num_tfeedback_decls, tfeedback_decls);
demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
if (!prog->SeparateShader)
demote_shader_inputs_and_outputs(sh, ir_var_shader_out);
/* Eliminate code that is now dead due to unused outputs being demoted.
*/
@ -2531,7 +2532,16 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
do_dead_builtin_varyings(ctx, NULL, sh,
num_tfeedback_decls, tfeedback_decls);
demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
if (prog->SeparateShader) {
if (!assign_varying_locations(ctx, mem_ctx, prog,
NULL /* producer */,
sh /* consumer */,
0 /* num_tfeedback_decls */,
NULL /* tfeedback_decls */,
0 /* gs_input_vertices */))
goto done;
} else
demote_shader_inputs_and_outputs(sh, ir_var_shader_in);
while (do_dead_code(sh->ir, false))
;