Browse Source

linker: Make linker_error set LinkStatus to false

Remove the other places that set LinkStatus to false since they all
immediately follow a call to linker_error.  The function linker_error
was previously known as linker_error_printf.  The name was changed
because it may seem surprising that a printf function will set an
error flag.

Signed-off-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
tags/mesa-8.0-rc1
Ian Romanick 14 years ago
parent
commit
586e741ac1
4 changed files with 90 additions and 100 deletions
  1. 1
    3
      src/glsl/ir_function_detect_recursion.cpp
  2. 2
    2
      src/glsl/link_functions.cpp
  3. 86
    94
      src/glsl/linker.cpp
  4. 1
    1
      src/glsl/linker.h

+ 1
- 3
src/glsl/ir_function_detect_recursion.cpp View File

f->sig->function_name(), f->sig->function_name(),
&f->sig->parameters); &f->sig->parameters);


linker_error_printf(prog,
"function `%s' has static recursion.\n",
proto);
linker_error(prog, "function `%s' has static recursion.\n", proto);
ralloc_free(proto); ralloc_free(proto);
prog->LinkStatus = false; prog->LinkStatus = false;
} }

+ 2
- 2
src/glsl/link_functions.cpp View File

if (sig == NULL) { if (sig == NULL) {
/* FINISHME: Log the full signature of unresolved function. /* FINISHME: Log the full signature of unresolved function.
*/ */
linker_error_printf(this->prog, "unresolved reference to function "
"`%s'\n", name);
linker_error(this->prog, "unresolved reference to function `%s'\n",
name);
this->success = false; this->success = false;
return visit_stop; return visit_stop;
} }

+ 86
- 94
src/glsl/linker.cpp View File





void void
linker_error_printf(gl_shader_program *prog, const char *fmt, ...)
linker_error(gl_shader_program *prog, const char *fmt, ...)
{ {
va_list ap; va_list ap;


va_start(ap, fmt); va_start(ap, fmt);
ralloc_vasprintf_append(&prog->InfoLog, fmt, ap); ralloc_vasprintf_append(&prog->InfoLog, fmt, ap);
va_end(ap); va_end(ap);

prog->LinkStatus = false;
} }




find_assignment_visitor find("gl_Position"); find_assignment_visitor find("gl_Position");
find.run(shader->ir); find.run(shader->ir);
if (!find.variable_found()) { if (!find.variable_found()) {
linker_error_printf(prog,
"vertex shader does not write to `gl_Position'\n");
linker_error(prog, "vertex shader does not write to `gl_Position'\n");
return false; return false;
} }


frag_data.run(shader->ir); frag_data.run(shader->ir);


if (frag_color.variable_found() && frag_data.variable_found()) { if (frag_color.variable_found() && frag_data.variable_found()) {
linker_error_printf(prog, "fragment shader writes to both "
"`gl_FragColor' and `gl_FragData'\n");
linker_error(prog, "fragment shader writes to both "
"`gl_FragColor' and `gl_FragData'\n");
return false; return false;
} }


existing->type = var->type; existing->type = var->type;
} }
} else { } else {
linker_error_printf(prog, "%s `%s' declared as type "
"`%s' and type `%s'\n",
mode_string(var),
var->name, var->type->name,
existing->type->name);
linker_error(prog, "%s `%s' declared as type "
"`%s' and type `%s'\n",
mode_string(var),
var->name, var->type->name,
existing->type->name);
return false; return false;
} }
} }
if (var->explicit_location) { if (var->explicit_location) {
if (existing->explicit_location if (existing->explicit_location
&& (var->location != existing->location)) { && (var->location != existing->location)) {
linker_error_printf(prog, "explicit locations for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
linker_error(prog, "explicit locations for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
return false; return false;
} }


bool layout_declared = var->depth_layout != ir_depth_layout_none; bool layout_declared = var->depth_layout != ir_depth_layout_none;
bool layout_differs = var->depth_layout != existing->depth_layout; bool layout_differs = var->depth_layout != existing->depth_layout;
if (layout_declared && layout_differs) { if (layout_declared && layout_differs) {
linker_error_printf(prog,
linker_error(prog,
"All redeclarations of gl_FragDepth in all fragment shaders " "All redeclarations of gl_FragDepth in all fragment shaders "
"in a single program must have the same set of qualifiers."); "in a single program must have the same set of qualifiers.");
} }
if (var->used && layout_differs) { if (var->used && layout_differs) {
linker_error_printf(prog,
linker_error(prog,
"If gl_FragDepth is redeclared with a layout qualifier in" "If gl_FragDepth is redeclared with a layout qualifier in"
"any fragment shader, it must be redeclared with the same" "any fragment shader, it must be redeclared with the same"
"layout qualifier in all fragment shaders that have" "layout qualifier in all fragment shaders that have"
if (var->constant_value != NULL) { if (var->constant_value != NULL) {
if (existing->constant_value != NULL) { if (existing->constant_value != NULL) {
if (!var->constant_value->has_value(existing->constant_value)) { if (!var->constant_value->has_value(existing->constant_value)) {
linker_error_printf(prog, "initializers for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
linker_error(prog, "initializers for %s "
"`%s' have differing values\n",
mode_string(var), var->name);
return false; return false;
} }
} else } else
} }


if (existing->invariant != var->invariant) { if (existing->invariant != var->invariant) {
linker_error_printf(prog, "declarations for %s `%s' have "
"mismatching invariant qualifiers\n",
mode_string(var), var->name);
linker_error(prog, "declarations for %s `%s' have "
"mismatching invariant qualifiers\n",
mode_string(var), var->name);
return false; return false;
} }
if (existing->centroid != var->centroid) { if (existing->centroid != var->centroid) {
linker_error_printf(prog, "declarations for %s `%s' have "
"mismatching centroid qualifiers\n",
mode_string(var), var->name);
linker_error(prog, "declarations for %s `%s' have "
"mismatching centroid qualifiers\n",
mode_string(var), var->name);
return false; return false;
} }
} else } else
*/ */
if (!output->type->is_array() if (!output->type->is_array()
|| (strncmp("gl_", output->name, 3) != 0)) { || (strncmp("gl_", output->name, 3) != 0)) {
linker_error_printf(prog,
"%s shader output `%s' declared 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(prog,
"%s shader output `%s' declared 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; return false;
} }
} }
/* Check that all of the qualifiers match between stages. /* Check that all of the qualifiers match between stages.
*/ */
if (input->centroid != output->centroid) { if (input->centroid != output->centroid) {
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");
linker_error(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; return false;
} }


if (input->invariant != output->invariant) { if (input->invariant != output->invariant) {
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");
linker_error(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; return false;
} }


if (input->interpolation != output->interpolation) { if (input->interpolation != output->interpolation) {
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());
linker_error(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; return false;
} }
} }


if ((other_sig != NULL) && other_sig->is_defined if ((other_sig != NULL) && other_sig->is_defined
&& !other_sig->is_builtin) { && !other_sig->is_builtin) {
linker_error_printf(prog,
"function `%s' is multiply defined",
f->name);
linker_error(prog, "function `%s' is multiply defined",
f->name);
return NULL; return NULL;
} }
} }
} }


if (main == NULL) { if (main == NULL) {
linker_error_printf(prog, "%s shader lacks `main'\n",
(shader_list[0]->Type == GL_VERTEX_SHADER)
? "vertex" : "fragment");
linker_error(prog, "%s shader lacks `main'\n",
(shader_list[0]->Type == GL_VERTEX_SHADER)
? "vertex" : "fragment");
return NULL; return NULL;
} }


* attribute overlaps any previously allocated bits. * attribute overlaps any previously allocated bits.
*/ */
if ((~(use_mask << attr) & used_locations) != used_locations) { if ((~(use_mask << attr) & used_locations) != used_locations) {
linker_error_printf(prog,
"insufficient contiguous attribute locations "
"available for vertex shader input `%s'",
var->name);
linker_error(prog,
"insufficient contiguous attribute locations "
"available for vertex shader input `%s'",
var->name);
return false; return false;
} }




if ((var->location >= (int)(max_index + generic_base)) if ((var->location >= (int)(max_index + generic_base))
|| (var->location < 0)) { || (var->location < 0)) {
linker_error_printf(prog,
"invalid explicit location %d specified for "
"`%s'\n",
(var->location < 0) ? var->location : attr,
var->name);
linker_error(prog,
"invalid explicit location %d specified for `%s'\n",
(var->location < 0) ? var->location : attr,
var->name);
return false; return false;
} else if (var->location >= generic_base) { } else if (var->location >= generic_base) {
used_locations |= (use_mask << attr); used_locations |= (use_mask << attr);
const char *const string = (target_index == MESA_SHADER_VERTEX) const char *const string = (target_index == MESA_SHADER_VERTEX)
? "vertex shader input" : "fragment shader output"; ? "vertex shader input" : "fragment shader output";


linker_error_printf(prog,
"insufficient contiguous attribute locations "
"available for %s `%s'",
string, to_assign[i].var->name);
linker_error(prog,
"insufficient contiguous attribute locations "
"available for %s `%s'",
string, to_assign[i].var->name);
return false; return false;
} }


* "glsl1-varying read but not written" in piglit. * "glsl1-varying read but not written" in piglit.
*/ */


linker_error_printf(prog, "fragment shader varying %s not written "
"by vertex shader\n.", var->name);
prog->LinkStatus = false;
linker_error(prog, "fragment shader varying %s not written "
"by vertex shader\n.", var->name);
} }


/* An 'in' variable is only really a shader input if its /* An 'in' variable is only really a shader input if its


if (ctx->API == API_OPENGLES2 || prog->Version == 100) { if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
if (varying_vectors > ctx->Const.MaxVarying) { if (varying_vectors > ctx->Const.MaxVarying) {
linker_error_printf(prog, "shader uses too many varying vectors "
"(%u > %u)\n",
varying_vectors, ctx->Const.MaxVarying);
linker_error(prog, "shader uses too many varying vectors "
"(%u > %u)\n",
varying_vectors, ctx->Const.MaxVarying);
return false; return false;
} }
} else { } else {
const unsigned float_components = varying_vectors * 4; const unsigned float_components = varying_vectors * 4;
if (float_components > ctx->Const.MaxVarying * 4) { if (float_components > ctx->Const.MaxVarying * 4) {
linker_error_printf(prog, "shader uses too many varying components "
"(%u > %u)\n",
float_components, ctx->Const.MaxVarying * 4);
linker_error(prog, "shader uses too many varying components "
"(%u > %u)\n",
float_components, ctx->Const.MaxVarying * 4);
return false; return false;
} }
} }
assert(max_version <= 130); assert(max_version <= 130);
if ((max_version >= 130 || min_version == 100) if ((max_version >= 130 || min_version == 100)
&& min_version != max_version) { && min_version != max_version) {
linker_error_printf(prog, "all shaders must use same shading "
"language version\n");
linker_error(prog, "all shaders must use same shading "
"language version\n");
goto done; goto done;
} }


* FINISHME: at least 16, so hardcode 16 for now. * FINISHME: at least 16, so hardcode 16 for now.
*/ */
if (!assign_attribute_or_color_locations(prog, MESA_SHADER_VERTEX, 16)) { if (!assign_attribute_or_color_locations(prog, MESA_SHADER_VERTEX, 16)) {
prog->LinkStatus = false;
goto done; goto done;
} }


if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) { if (!assign_attribute_or_color_locations(prog, MESA_SHADER_FRAGMENT, ctx->Const.MaxDrawBuffers)) {
prog->LinkStatus = false;
goto done; goto done;
} }


if (!assign_varying_locations(ctx, prog, if (!assign_varying_locations(ctx, prog,
prog->_LinkedShaders[prev], prog->_LinkedShaders[prev],
prog->_LinkedShaders[i])) { prog->_LinkedShaders[i])) {
prog->LinkStatus = false;
goto done; goto done;
} }


*/ */
if (ctx->API == API_OPENGLES2 || prog->Version == 100) { if (ctx->API == API_OPENGLES2 || prog->Version == 100) {
if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
linker_error_printf(prog, "program lacks a vertex shader\n");
prog->LinkStatus = false;
linker_error(prog, "program lacks a vertex shader\n");
} else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
linker_error_printf(prog, "program lacks a fragment shader\n");
prog->LinkStatus = false;
linker_error(prog, "program lacks a fragment shader\n");
} }
} }



+ 1
- 1
src/glsl/linker.h View File

#define GLSL_LINKER_H #define GLSL_LINKER_H


extern void extern void
linker_error_printf(gl_shader_program *prog, const char *fmt, ...);
linker_error(gl_shader_program *prog, const char *fmt, ...);


extern bool extern bool
link_function_calls(gl_shader_program *prog, gl_shader *main, link_function_calls(gl_shader_program *prog, gl_shader *main,

Loading…
Cancel
Save