diff options
Diffstat (limited to 'mesalib/src/glsl/linker.cpp')
-rw-r--r-- | mesalib/src/glsl/linker.cpp | 122 |
1 files changed, 58 insertions, 64 deletions
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp index ac010cfbb..942f90615 100644 --- a/mesalib/src/glsl/linker.cpp +++ b/mesalib/src/glsl/linker.cpp @@ -340,12 +340,12 @@ count_attribute_slots(const glsl_type *t) * * \param shader Vertex shader executable to be verified */ -bool +void validate_vertex_shader_executable(struct gl_shader_program *prog, struct gl_shader *shader) { if (shader == NULL) - return true; + return; /* From the GLSL 1.10 spec, page 48: * @@ -378,7 +378,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, find.run(shader->ir); if (!find.variable_found()) { linker_error(prog, "vertex shader does not write to `gl_Position'\n"); - return false; + return; } } @@ -402,7 +402,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, if (clip_vertex.variable_found() && clip_distance.variable_found()) { linker_error(prog, "vertex shader writes to both `gl_ClipVertex' " "and `gl_ClipDistance'\n"); - return false; + return; } prog->Vert.UsesClipDistance = clip_distance.variable_found(); ir_variable *clip_distance_var = @@ -410,8 +410,6 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, if (clip_distance_var) prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length; } - - return true; } @@ -420,12 +418,12 @@ validate_vertex_shader_executable(struct gl_shader_program *prog, * * \param shader Fragment shader executable to be verified */ -bool +void validate_fragment_shader_executable(struct gl_shader_program *prog, struct gl_shader *shader) { if (shader == NULL) - return true; + return; find_assignment_visitor frag_color("gl_FragColor"); find_assignment_visitor frag_data("gl_FragData"); @@ -436,10 +434,7 @@ validate_fragment_shader_executable(struct gl_shader_program *prog, if (frag_color.variable_found() && frag_data.variable_found()) { linker_error(prog, "fragment shader writes to both " "`gl_FragColor' and `gl_FragData'\n"); - return false; } - - return true; } @@ -469,7 +464,7 @@ mode_string(const ir_variable *var) /** * Perform validation of global variables used across multiple shaders */ -bool +void cross_validate_globals(struct gl_shader_program *prog, struct gl_shader **shader_list, unsigned num_shaders, @@ -524,7 +519,7 @@ cross_validate_globals(struct gl_shader_program *prog, mode_string(var), var->name, var->type->name, existing->type->name); - return false; + return; } } @@ -534,7 +529,7 @@ cross_validate_globals(struct gl_shader_program *prog, linker_error(prog, "explicit locations for %s " "`%s' have differing values\n", mode_string(var), var->name); - return false; + return; } existing->location = var->location; @@ -553,7 +548,7 @@ cross_validate_globals(struct gl_shader_program *prog, linker_error(prog, "explicit bindings for %s " "`%s' have differing values\n", mode_string(var), var->name); - return false; + return; } existing->binding = var->binding; @@ -614,7 +609,7 @@ cross_validate_globals(struct gl_shader_program *prog, linker_error(prog, "initializers for %s " "`%s' have differing values\n", mode_string(var), var->name); - return false; + return; } } else { /* If the first-seen instance of a particular uniform did not @@ -643,7 +638,7 @@ cross_validate_globals(struct gl_shader_program *prog, "shared global variable `%s' has multiple " "non-constant initializers.\n", var->name); - return false; + return; } /* Some instance had an initializer, so keep track of that. In @@ -658,31 +653,29 @@ cross_validate_globals(struct gl_shader_program *prog, linker_error(prog, "declarations for %s `%s' have " "mismatching invariant qualifiers\n", mode_string(var), var->name); - return false; + return; } if (existing->centroid != var->centroid) { linker_error(prog, "declarations for %s `%s' have " "mismatching centroid qualifiers\n", mode_string(var), var->name); - return false; + return; } } else variables.add_variable(var); } } - - return true; } /** * Perform validation of uniforms used across multiple shader stages */ -bool +void cross_validate_uniforms(struct gl_shader_program *prog) { - return cross_validate_globals(prog, prog->_LinkedShaders, - MESA_SHADER_TYPES, true); + cross_validate_globals(prog, prog->_LinkedShaders, + MESA_SHADER_TYPES, true); } /** @@ -955,21 +948,21 @@ link_intrastage_shaders(void *mem_ctx, /* Check that global variables defined in multiple shaders are consistent. */ - if (!cross_validate_globals(prog, shader_list, num_shaders, false)) + cross_validate_globals(prog, shader_list, num_shaders, false); + if (!prog->LinkStatus) return NULL; /* Check that interface blocks defined in multiple shaders are consistent. */ - if (!validate_intrastage_interface_blocks((const gl_shader **)shader_list, - num_shaders)) + validate_intrastage_interface_blocks(prog, (const gl_shader **)shader_list, + num_shaders); + if (!prog->LinkStatus) return NULL; - /* Check that uniform blocks between shaders for a stage agree. */ - const int num_uniform_blocks = + /* Link up uniform blocks defined within this stage. */ + const unsigned num_uniform_blocks = link_uniform_blocks(mem_ctx, prog, shader_list, num_shaders, &uniform_blocks); - if (num_uniform_blocks < 0) - return NULL; /* Check that there is only a single definition of each function signature * across all shaders. @@ -1529,7 +1522,7 @@ store_fragdepth_layout(struct gl_shader_program *prog) /** * Validate the resources used by a program versus the implementation limits */ -static bool +static void check_resources(struct gl_context *ctx, struct gl_shader_program *prog) { static const char *const shader_names[MESA_SHADER_TYPES] = { @@ -1626,8 +1619,6 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog) } } } - - return prog->LinkStatus; } void @@ -1638,7 +1629,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) void *mem_ctx = ralloc_context(NULL); // temporary linker context - prog->LinkStatus = false; + prog->LinkStatus = true; /* All error paths will set this to false */ prog->Validated = false; prog->_Used = false; @@ -1724,10 +1715,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list, num_vert_shaders); - if (sh == NULL) + if (!prog->LinkStatus) goto done; - if (!validate_vertex_shader_executable(prog, sh)) + validate_vertex_shader_executable(prog, sh); + if (!prog->LinkStatus) goto done; _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX], @@ -1739,10 +1731,11 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list, num_frag_shaders); - if (sh == NULL) + if (!prog->LinkStatus) goto done; - if (!validate_fragment_shader_executable(prog, sh)) + validate_fragment_shader_executable(prog, sh); + if (!prog->LinkStatus) goto done; _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT], @@ -1753,36 +1746,36 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) * performed, then locations are assigned for uniforms, attributes, and * varyings. */ - if (cross_validate_uniforms(prog)) { - unsigned prev; + cross_validate_uniforms(prog); + if (!prog->LinkStatus) + goto done; - for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { - if (prog->_LinkedShaders[prev] != NULL) - break; - } + unsigned prev; - /* Validate the inputs of each stage with the output of the preceding - * stage. - */ - for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { - if (prog->_LinkedShaders[i] == NULL) - continue; + for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { + if (prog->_LinkedShaders[prev] != NULL) + break; + } - if (!validate_interstage_interface_blocks(prog->_LinkedShaders[prev], - prog->_LinkedShaders[i])) { - linker_error(prog, "interface block mismatch between shader stages\n"); - goto done; - } + /* Validate the inputs of each stage with the output of the preceding + * stage. + */ + for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { + if (prog->_LinkedShaders[i] == NULL) + continue; - if (!cross_validate_outputs_to_inputs(prog, - prog->_LinkedShaders[prev], - prog->_LinkedShaders[i])) - goto done; + validate_interstage_interface_blocks(prog, prog->_LinkedShaders[prev], + prog->_LinkedShaders[i]); + if (!prog->LinkStatus) + goto done; - prev = i; - } + cross_validate_outputs_to_inputs(prog, + prog->_LinkedShaders[prev], + prog->_LinkedShaders[i]); + if (!prog->LinkStatus) + goto done; - prog->LinkStatus = true; + prev = i; } @@ -1971,7 +1964,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) link_assign_uniform_locations(prog); store_fragdepth_layout(prog); - if (!check_resources(ctx, prog)) + check_resources(ctx, prog); + if (!prog->LinkStatus) goto done; /* OpenGL ES requires that a vertex shader and a fragment shader both be |