From f36460e1a7de3bd311135673b3d5b60f3a8655da Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Wed, 23 Jun 2010 12:07:22 -0700 Subject: linker: Write errors to info log instead of stdout --- linker.cpp | 132 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 48 deletions(-) diff --git a/linker.cpp b/linker.cpp index 500a329..4d1ff01 100644 --- a/linker.cpp +++ b/linker.cpp @@ -65,6 +65,11 @@ */ #include #include +#include + +extern "C" { +#include +} #include "main/mtypes.h" #include "glsl_symbol_table.h" @@ -108,6 +113,18 @@ private: }; +void +linker_error_printf(glsl_program *prog, const char *fmt, ...) +{ + va_list ap; + + prog->InfoLog = talloc_strdup_append(prog->InfoLog, "error: "); + va_start(ap, fmt); + prog->InfoLog = talloc_vasprintf_append(prog->InfoLog, fmt, ap); + va_end(ap); +} + + void invalidate_variable_locations(glsl_shader *sh, enum ir_variable_mode mode, int generic_base) @@ -167,20 +184,22 @@ count_attribute_slots(const glsl_type *t) * \param shader Vertex shader executable to be verified */ bool -validate_vertex_shader_executable(struct glsl_shader *shader) +validate_vertex_shader_executable(struct glsl_program *prog, + struct glsl_shader *shader) { if (shader == NULL) return true; if (!shader->symbols->get_function("main")) { - printf("error: vertex shader lacks `main'\n"); + linker_error_printf(prog, "vertex shader lacks `main'\n"); return false; } find_assignment_visitor find("gl_Position"); find.run(&shader->ir); if (!find.variable_found()) { - printf("error: vertex shader does not write to `gl_Position'\n"); + linker_error_printf(prog, + "vertex shader does not write to `gl_Position'\n"); return false; } @@ -194,13 +213,14 @@ validate_vertex_shader_executable(struct glsl_shader *shader) * \param shader Fragment shader executable to be verified */ bool -validate_fragment_shader_executable(struct glsl_shader *shader) +validate_fragment_shader_executable(struct glsl_program *prog, + struct glsl_shader *shader) { if (shader == NULL) return true; if (!shader->symbols->get_function("main")) { - printf("error: fragment shader lacks `main'\n"); + linker_error_printf(prog, "fragment shader lacks `main'\n"); return false; } @@ -211,14 +231,14 @@ validate_fragment_shader_executable(struct glsl_shader *shader) frag_data.run(&shader->ir); if (!frag_color.variable_found() && !frag_data.variable_found()) { - printf("error: fragment shader does not write to `gl_FragColor' or " - "`gl_FragData'\n"); + linker_error_printf(prog, "fragment shader does not write to " + "`gl_FragColor' or `gl_FragData'\n"); return false; } if (frag_color.variable_found() && frag_data.variable_found()) { - printf("error: fragment shader write to both `gl_FragColor' and " - "`gl_FragData'\n"); + linker_error_printf(prog, "fragment shader writes to both " + "`gl_FragColor' and `gl_FragData'\n"); return false; } @@ -230,7 +250,8 @@ validate_fragment_shader_executable(struct glsl_shader *shader) * Perform validation of uniforms used across multiple shader stages */ bool -cross_validate_uniforms(struct glsl_shader **shaders, unsigned num_shaders) +cross_validate_uniforms(struct glsl_program *prog, + struct glsl_shader **shaders, unsigned num_shaders) { /* Examine all of the uniforms in all of the shaders and cross validate * them. @@ -250,18 +271,19 @@ cross_validate_uniforms(struct glsl_shader **shaders, unsigned num_shaders) ir_variable *const existing = uniforms.get_variable(var->name); if (existing != NULL) { if (var->type != existing->type) { - printf("error: uniform `%s' declared as type `%s' and " - "type `%s'\n", - var->name, var->type->name, existing->type->name); + linker_error_printf(prog, "uniform `%s' declared as type " + "`%s' and type `%s'\n", + var->name, var->type->name, + existing->type->name); return false; } if (var->constant_value != NULL) { if (existing->constant_value != NULL) { if (!var->constant_value->has_value(existing->constant_value)) { - printf("error: initializers for uniform `%s' have " - "differing values\n", - var->name); + linker_error_printf(prog, "initializers for uniform " + "`%s' have differing values\n", + var->name); return false; } } else @@ -284,7 +306,8 @@ cross_validate_uniforms(struct glsl_shader **shaders, unsigned num_shaders) * Validate that outputs from one stage match inputs of another */ bool -cross_validate_outputs_to_inputs(glsl_shader *producer, glsl_shader *consumer) +cross_validate_outputs_to_inputs(struct glsl_program *prog, + glsl_shader *producer, glsl_shader *consumer) { glsl_symbol_table parameters; /* FINISHME: Figure these out dynamically. */ @@ -324,47 +347,53 @@ cross_validate_outputs_to_inputs(glsl_shader *producer, glsl_shader *consumer) /* Check that the types match between stages. */ if (input->type != output->type) { - printf("error: %s shader output `%s' delcared as type `%s', but " - "%s shader input declared as type `%s'\n", - producer_stage, output->name, output->type->name, - consumer_stage, input->type->name); + linker_error_printf(prog, + "%s shader output `%s' delcared as " + "type `%s', but %s shader input declared " + "as type `%s'\n", + producer_stage, output->name, + output->type->name, + consumer_stage, input->type->name); return false; } /* Check that all of the qualifiers match between stages. */ if (input->centroid != output->centroid) { - printf("error: %s shader output `%s' %s centroid qualifier, but " - "%s shader input %s centroid qualifier\n", - producer_stage, - output->name, - (output->centroid) ? "has" : "lacks", - consumer_stage, - (input->centroid) ? "has" : "lacks"); + linker_error_printf(prog, + "%s shader output `%s' %s centroid qualifier, " + "but %s shader input %s centroid qualifier\n", + producer_stage, + output->name, + (output->centroid) ? "has" : "lacks", + consumer_stage, + (input->centroid) ? "has" : "lacks"); return false; } if (input->invariant != output->invariant) { - printf("error: %s shader output `%s' %s invariant qualifier, but " - "%s shader input %s invariant qualifier\n", - producer_stage, - output->name, - (output->invariant) ? "has" : "lacks", - consumer_stage, - (input->invariant) ? "has" : "lacks"); + linker_error_printf(prog, + "%s shader output `%s' %s invariant qualifier, " + "but %s shader input %s invariant qualifier\n", + producer_stage, + output->name, + (output->invariant) ? "has" : "lacks", + consumer_stage, + (input->invariant) ? "has" : "lacks"); return false; } if (input->interpolation != output->interpolation) { - printf("error: %s shader output `%s' specifies %s interpolation " - "qualifier, " - "but %s shader input specifies %s interpolation " - "qualifier\n", - producer_stage, - output->name, - output->interpolation_string(), - consumer_stage, - input->interpolation_string()); + linker_error_printf(prog, + "%s shader output `%s' specifies %s " + "interpolation qualifier, " + "but %s shader input specifies %s " + "interpolation qualifier\n", + producer_stage, + output->name, + output->interpolation_string(), + consumer_stage, + input->interpolation_string()); return false; } } @@ -741,6 +770,11 @@ link_shaders(struct glsl_program *prog) prog->Validated = false; prog->_Used = false; + if (prog->InfoLog != NULL) + talloc_free(prog->InfoLog); + + prog->InfoLog = talloc_strdup(NULL, ""); + /* Separate the shaders into groups based on their type. */ struct glsl_shader **vert_shader_list; @@ -775,8 +809,8 @@ link_shaders(struct glsl_program *prog) /* Verify that each of the per-target executables is valid. */ - if (!validate_vertex_shader_executable(vert_shader_list[0]) - || !validate_fragment_shader_executable(frag_shader_list[0])) + if (!validate_vertex_shader_executable(prog, vert_shader_list[0]) + || !validate_fragment_shader_executable(prog, frag_shader_list[0])) goto done; @@ -795,12 +829,14 @@ link_shaders(struct glsl_program *prog) prog->_NumLinkedShaders++; } - if (cross_validate_uniforms(prog->_LinkedShaders, prog->_NumLinkedShaders)) { + if (cross_validate_uniforms(prog, prog->_LinkedShaders, + prog->_NumLinkedShaders)) { /* Validate the inputs of each stage with the output of the preceeding * stage. */ for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) { - if (!cross_validate_outputs_to_inputs(prog->_LinkedShaders[i - 1], + if (!cross_validate_outputs_to_inputs(prog, + prog->_LinkedShaders[i - 1], prog->_LinkedShaders[i])) goto done; } -- cgit v1.2.3