mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-06 05:08:08 +02:00
linker: Initial implementation of interstage uniform validation
This commit is contained in:
parent
1e8b7a714e
commit
cc22c5a544
1 changed files with 69 additions and 1 deletions
70
linker.cpp
70
linker.cpp
|
|
@ -170,6 +170,60 @@ 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)
|
||||
{
|
||||
/* Examine all of the uniforms in all of the shaders and cross validate
|
||||
* them.
|
||||
*/
|
||||
glsl_symbol_table uniforms;
|
||||
for (unsigned i = 0; i < num_shaders; i++) {
|
||||
foreach_list(node, &shaders[i]->ir) {
|
||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||
|
||||
if ((var == NULL) || (var->mode != ir_var_uniform))
|
||||
continue;
|
||||
|
||||
/* If a uniform with this name has already been seen, verify that the
|
||||
* new instance has the same type. In addition, if the uniforms have
|
||||
* initializers, the values of the initializers must be the same.
|
||||
*/
|
||||
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);
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
/* If the first-seen instance of a particular uniform did not
|
||||
* have an initializer but a later instance does, copy the
|
||||
* initializer to the version stored in the symbol table.
|
||||
*/
|
||||
existing->constant_value = var->constant_value->clone();
|
||||
}
|
||||
} else
|
||||
uniforms.add_variable(var->name, var);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
link_shaders(struct glsl_program *prog)
|
||||
{
|
||||
|
|
@ -217,8 +271,22 @@ link_shaders(struct glsl_program *prog)
|
|||
|
||||
|
||||
/* FINISHME: Perform inter-stage linking. */
|
||||
glsl_shader *shader_executables[2];
|
||||
unsigned num_shader_executables;
|
||||
|
||||
prog->LinkStatus = true;
|
||||
num_shader_executables = 0;
|
||||
if (num_vert_shaders > 0) {
|
||||
shader_executables[num_shader_executables] = vert_shader_list[0];
|
||||
num_shader_executables++;
|
||||
}
|
||||
|
||||
if (num_frag_shaders > 0) {
|
||||
shader_executables[num_shader_executables] = frag_shader_list[0];
|
||||
num_shader_executables++;
|
||||
}
|
||||
|
||||
if (cross_validate_uniforms(shader_executables, num_shader_executables))
|
||||
prog->LinkStatus = true;
|
||||
|
||||
done:
|
||||
free(vert_shader_list);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue