Skip to content

Commit

Permalink
glsl: add get_pipeline_stage to linker and use it in link_shaders
Browse files Browse the repository at this point in the history
Fixes segfault in glxgears, and should also make it easier to add new shader
types such as tesselation shaders in the future.
  • Loading branch information
Plombo committed Aug 21, 2012
1 parent 3d1f177 commit 74c27c7
Showing 1 changed file with 40 additions and 29 deletions.
69 changes: 40 additions & 29 deletions src/glsl/linker.cpp
Expand Up @@ -243,6 +243,23 @@ link_invalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
}


/**
* Gets the shader type (MESA_SHADER_*) at the specified position in the
* pipeline, from 0 to MESA_SHADER_TYPES.
*/
unsigned
get_pipeline_stage(unsigned pos)
{
unsigned shader_types[MESA_SHADER_TYPES] = {
MESA_SHADER_VERTEX,
MESA_SHADER_GEOMETRY,
MESA_SHADER_FRAGMENT
};
assert(pos >= 0 && pos < MESA_SHADER_TYPES);
return shader_types[pos];
}


/**
* Determine the number of attribute slots required for a particular type
*
Expand Down Expand Up @@ -2623,27 +2640,25 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
unsigned prev;

for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
if (prog->_LinkedShaders[prev] != NULL)
if (prog->_LinkedShaders[get_pipeline_stage(prev)] != NULL)
break;
}

/* Validate the inputs of each stage with the output of the preceding
* stage.
*/
if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
if (!cross_validate_outputs_to_inputs(prog,
prog->_LinkedShaders[MESA_SHADER_VERTEX],
prog->_LinkedShaders[MESA_SHADER_GEOMETRY]))
goto done;
if (!cross_validate_outputs_to_inputs(prog,
prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]))
goto done;
} else {
for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
unsigned type = get_pipeline_stage(i);
unsigned type_prev = get_pipeline_stage(prev);
if (prog->_LinkedShaders[type] == NULL)
continue;

if (!cross_validate_outputs_to_inputs(prog,
prog->_LinkedShaders[MESA_SHADER_VERTEX],
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]))
prog->_LinkedShaders[type_prev],
prog->_LinkedShaders[type]))
goto done;

prev = i;
}

prog->LinkStatus = true;
Expand Down Expand Up @@ -2699,7 +2714,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)

unsigned prev;
for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
if (prog->_LinkedShaders[prev] != NULL)
if (prog->_LinkedShaders[get_pipeline_stage(prev)] != NULL)
break;
}

Expand All @@ -2725,23 +2740,19 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
goto done;
}

if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
if (!assign_varying_locations(
ctx, prog, prog->_LinkedShaders[MESA_SHADER_VERTEX],
prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
0, tfeedback_decls))
goto done;
if (!assign_varying_locations(
ctx, prog, prog->_LinkedShaders[MESA_SHADER_GEOMETRY],
prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
num_tfeedback_decls, tfeedback_decls))
goto done;
} else {
for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
unsigned type = get_pipeline_stage(i);
unsigned type_prev = get_pipeline_stage(prev);
if (prog->_LinkedShaders[type] == NULL)
continue;

if (!assign_varying_locations(
ctx, prog, prog->_LinkedShaders[MESA_SHADER_VERTEX],
prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
num_tfeedback_decls, tfeedback_decls))
ctx, prog, prog->_LinkedShaders[type_prev], prog->_LinkedShaders[type],
type == MESA_SHADER_FRAGMENT ? num_tfeedback_decls : 0,
tfeedback_decls))
goto done;

prev = i;
}

if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL && num_tfeedback_decls != 0) {
Expand Down

0 comments on commit 74c27c7

Please sign in to comment.