linker: Refactor cross_validate_uniforms into cross_validate_globals
The later, more generic function will be used in the intra-stage linker.
This commit is contained in:
@@ -242,42 +242,72 @@ validate_fragment_shader_executable(struct gl_shader_program *prog,
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform validation of uniforms used across multiple shader stages
|
* Generate a string describing the mode of a variable
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
mode_string(const ir_variable *var)
|
||||||
|
{
|
||||||
|
switch (var->mode) {
|
||||||
|
case ir_var_auto:
|
||||||
|
return (var->read_only) ? "global constant" : "global variable";
|
||||||
|
|
||||||
|
case ir_var_uniform: return "uniform";
|
||||||
|
case ir_var_in: return "shader input";
|
||||||
|
case ir_var_out: return "shader output";
|
||||||
|
case ir_var_inout: return "shader inout";
|
||||||
|
default:
|
||||||
|
assert(!"Should not get here.");
|
||||||
|
return "invalid variable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform validation of global variables used across multiple shaders
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
cross_validate_uniforms(struct gl_shader_program *prog)
|
cross_validate_globals(struct gl_shader_program *prog,
|
||||||
|
struct gl_shader **shader_list,
|
||||||
|
unsigned num_shaders,
|
||||||
|
bool uniforms_only)
|
||||||
{
|
{
|
||||||
/* Examine all of the uniforms in all of the shaders and cross validate
|
/* Examine all of the uniforms in all of the shaders and cross validate
|
||||||
* them.
|
* them.
|
||||||
*/
|
*/
|
||||||
glsl_symbol_table uniforms;
|
glsl_symbol_table variables;
|
||||||
for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
|
for (unsigned i = 0; i < num_shaders; i++) {
|
||||||
foreach_list(node, prog->_LinkedShaders[i]->ir) {
|
foreach_list(node, shader_list[i]->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((var == NULL) || (var->mode != ir_var_uniform))
|
if (var == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* If a uniform with this name has already been seen, verify that the
|
if (uniforms_only && (var->mode != ir_var_uniform))
|
||||||
* new instance has the same type. In addition, if the uniforms have
|
continue;
|
||||||
|
|
||||||
|
/* If a global with this name has already been seen, verify that the
|
||||||
|
* new instance has the same type. In addition, if the globals have
|
||||||
* initializers, the values of the initializers must be the same.
|
* initializers, the values of the initializers must be the same.
|
||||||
*/
|
*/
|
||||||
ir_variable *const existing = uniforms.get_variable(var->name);
|
ir_variable *const existing = variables.get_variable(var->name);
|
||||||
if (existing != NULL) {
|
if (existing != NULL) {
|
||||||
if (var->type != existing->type) {
|
if (var->type != existing->type) {
|
||||||
linker_error_printf(prog, "uniform `%s' declared as type "
|
linker_error_printf(prog, "%s `%s' declared as type "
|
||||||
"`%s' and type `%s'\n",
|
"`%s' and type `%s'\n",
|
||||||
|
mode_string(var),
|
||||||
var->name, var->type->name,
|
var->name, var->type->name,
|
||||||
existing->type->name);
|
existing->type->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FINISHME: Handle non-constant initializers.
|
||||||
|
*/
|
||||||
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 uniform "
|
linker_error_printf(prog, "initializers for %s "
|
||||||
"`%s' have differing values\n",
|
"`%s' have differing values\n",
|
||||||
var->name);
|
mode_string(var), var->name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -289,7 +319,7 @@ cross_validate_uniforms(struct gl_shader_program *prog)
|
|||||||
(ir_constant *)var->constant_value->clone(NULL);
|
(ir_constant *)var->constant_value->clone(NULL);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
uniforms.add_variable(var->name, var);
|
variables.add_variable(var->name, var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,6 +327,17 @@ cross_validate_uniforms(struct gl_shader_program *prog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform validation of uniforms used across multiple shader stages
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
cross_validate_uniforms(struct gl_shader_program *prog)
|
||||||
|
{
|
||||||
|
return cross_validate_globals(prog, prog->_LinkedShaders,
|
||||||
|
prog->_NumLinkedShaders, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate that outputs from one stage match inputs of another
|
* Validate that outputs from one stage match inputs of another
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user