diff options
author | Brian Paul <[email protected]> | 2010-11-23 17:18:44 -0700 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-11-23 17:18:48 -0700 |
commit | 6162773ea4b0e84c3ab9c9952fb5e838519c2564 (patch) | |
tree | 81603c1b4d08061ccdaa1f767c1f2a5b1a7c5464 /src/mesa | |
parent | 2900e56f9dda864f2c5b75d3db4dcc452dc91373 (diff) |
glsl: better handling of linker failures
Upon link error, exit translation loop, free program instructions.
Check for null pointers in calling code.
Diffstat (limited to 'src/mesa')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 52 |
1 files changed, 33 insertions, 19 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index c5f11e010da..2561bf0880a 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2609,8 +2609,9 @@ set_uniform_initializers(struct gl_context *ctx, /** * Convert a shader's GLSL IR into a Mesa gl_program. */ -struct gl_program * -get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_program, +static struct gl_program * +get_mesa_program(struct gl_context *ctx, + struct gl_shader_program *shader_program, struct gl_shader *shader) { ir_to_mesa_visitor v; @@ -2756,6 +2757,15 @@ get_mesa_program(struct gl_context *ctx, struct gl_shader_program *shader_progra mesa_inst++; i++; + + if (!shader_program->LinkStatus) + break; + } + + if (!shader_program->LinkStatus) { + free(mesa_instructions); + _mesa_reference_program(ctx, &shader->Program, NULL); + return NULL; } set_branchtargets(&v, mesa_instructions, num_instructions); @@ -2866,30 +2876,34 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog) for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { struct gl_program *linked_prog; - bool ok = true; if (prog->_LinkedShaders[i] == NULL) continue; linked_prog = get_mesa_program(ctx, prog, prog->_LinkedShaders[i]); - switch (prog->_LinkedShaders[i]->Type) { - case GL_VERTEX_SHADER: - _mesa_reference_vertprog(ctx, &prog->VertexProgram, - (struct gl_vertex_program *)linked_prog); - ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, - linked_prog); - break; - case GL_FRAGMENT_SHADER: - _mesa_reference_fragprog(ctx, &prog->FragmentProgram, - (struct gl_fragment_program *)linked_prog); - ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, - linked_prog); - break; - } - if (!ok) { - return GL_FALSE; + if (linked_prog) { + bool ok = true; + + switch (prog->_LinkedShaders[i]->Type) { + case GL_VERTEX_SHADER: + _mesa_reference_vertprog(ctx, &prog->VertexProgram, + (struct gl_vertex_program *)linked_prog); + ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, + linked_prog); + break; + case GL_FRAGMENT_SHADER: + _mesa_reference_fragprog(ctx, &prog->FragmentProgram, + (struct gl_fragment_program *)linked_prog); + ok = ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_PROGRAM_ARB, + linked_prog); + break; + } + if (!ok) { + return GL_FALSE; + } } + _mesa_reference_program(ctx, &linked_prog, NULL); } |