mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 19:00:13 +01:00
mesa: Additional SSO validation using program_interface_query data
Fixes the following dEQP tests on SKL: dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_qualifier_vertex_smooth_fragment_flat dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_array_element_type dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_qualifier_vertex_flat_fragment_none dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_order dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_qualifier_vertex_centroid_fragment_flat dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_array_length dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_type dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_location_type dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_qualifier_vertex_flat_fragment_centroid dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_location dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_qualifier_vertex_flat_fragment_smooth dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name It regresses one test: dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names Hoever, this test is based on language in the OpenGL ES 3.1 spec that I believe is incorrect. I have already submitted a spec bug: https://www.khronos.org/bugzilla/show_bug.cgi?id=1500 v2: Move spec quote about built-in variables to the first place where it's relevant. Suggested by Alejandro. v3: Move patch earlier in series, fix rebase issues. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com> [v2] Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com> [v2]
This commit is contained in:
parent
cfff746297
commit
bd3f15cffd
1 changed files with 176 additions and 0 deletions
|
|
@ -1474,6 +1474,178 @@ validate_io(const struct gl_shader *producer,
|
|||
return inputs == outputs;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_io(struct gl_shader_program *producer,
|
||||
struct gl_shader_program *consumer)
|
||||
{
|
||||
if (producer == consumer)
|
||||
return true;
|
||||
|
||||
if (!producer->IsES && !consumer->IsES)
|
||||
return true;
|
||||
|
||||
bool valid = true;
|
||||
|
||||
gl_shader_variable const **outputs =
|
||||
(gl_shader_variable const **) calloc(producer->NumProgramResourceList,
|
||||
sizeof(gl_shader_variable *));
|
||||
if (outputs == NULL)
|
||||
return false;
|
||||
|
||||
/* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
|
||||
* says:
|
||||
*
|
||||
* At an interface between program objects, the set of inputs and
|
||||
* outputs are considered to match exactly if and only if:
|
||||
*
|
||||
* - Every declared input variable has a matching output, as described
|
||||
* above.
|
||||
* - There are no user-defined output variables declared without a
|
||||
* matching input variable declaration.
|
||||
*
|
||||
* Every input has an output, and every output has an input. Scan the list
|
||||
* of producer resources once, and generate the list of outputs. As inputs
|
||||
* and outputs are matched, remove the matched outputs from the set. At
|
||||
* the end, the set must be empty. If the set is not empty, then there is
|
||||
* some output that did not have an input.
|
||||
*/
|
||||
unsigned num_outputs = 0;
|
||||
for (unsigned i = 0; i < producer->NumProgramResourceList; i++) {
|
||||
struct gl_program_resource *res = &producer->ProgramResourceList[i];
|
||||
|
||||
if (res->Type != GL_PROGRAM_OUTPUT)
|
||||
continue;
|
||||
|
||||
gl_shader_variable const *const var = RESOURCE_VAR(res);
|
||||
|
||||
/* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
|
||||
* says:
|
||||
*
|
||||
* Built-in inputs or outputs do not affect interface matching.
|
||||
*/
|
||||
if (is_gl_identifier(var->name))
|
||||
continue;
|
||||
|
||||
outputs[num_outputs++] = var;
|
||||
}
|
||||
|
||||
unsigned match_index = 0;
|
||||
for (unsigned i = 0; i < consumer->NumProgramResourceList; i++) {
|
||||
struct gl_program_resource *res = &consumer->ProgramResourceList[i];
|
||||
|
||||
if (res->Type != GL_PROGRAM_INPUT)
|
||||
continue;
|
||||
|
||||
gl_shader_variable const *const consumer_var = RESOURCE_VAR(res);
|
||||
gl_shader_variable const *producer_var = NULL;
|
||||
|
||||
if (is_gl_identifier(consumer_var->name))
|
||||
continue;
|
||||
|
||||
/* Inputs with explicit locations match other outputs with explicit
|
||||
* locations by location instead of by name.
|
||||
*/
|
||||
if (consumer_var->explicit_location) {
|
||||
for (unsigned j = 0; j < num_outputs; j++) {
|
||||
const gl_shader_variable *const var = outputs[j];
|
||||
|
||||
if (var->explicit_location &&
|
||||
consumer_var->location == var->location) {
|
||||
producer_var = var;
|
||||
match_index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (unsigned j = 0; j < num_outputs; j++) {
|
||||
const gl_shader_variable *const var = outputs[j];
|
||||
|
||||
if (!var->explicit_location &&
|
||||
strcmp(consumer_var->name, var->name) == 0) {
|
||||
producer_var = var;
|
||||
match_index = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
|
||||
* says:
|
||||
*
|
||||
* - An output variable is considered to match an input variable in
|
||||
* the subsequent shader if:
|
||||
*
|
||||
* - the two variables match in name, type, and qualification; or
|
||||
*
|
||||
* - the two variables are declared with the same location
|
||||
* qualifier and match in type and qualification.
|
||||
*/
|
||||
if (producer_var == NULL) {
|
||||
valid = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* An output cannot match more than one input, so remove the output from
|
||||
* the set of possible outputs.
|
||||
*/
|
||||
outputs[match_index] = NULL;
|
||||
num_outputs--;
|
||||
if (match_index < num_outputs)
|
||||
outputs[match_index] = outputs[num_outputs];
|
||||
|
||||
/* Section 9.2.2 (Separable Programs) of the GLSL ES spec says:
|
||||
*
|
||||
* Qualifier Class| Qualifier |in/out
|
||||
* ---------------+-------------+------
|
||||
* Storage | in |
|
||||
* | out | N/A
|
||||
* | uniform |
|
||||
* ---------------+-------------+------
|
||||
* Auxiliary | centroid | No
|
||||
* ---------------+-------------+------
|
||||
* | location | Yes
|
||||
* | Block layout| N/A
|
||||
* | binding | N/A
|
||||
* | offset | N/A
|
||||
* | format | N/A
|
||||
* ---------------+-------------+------
|
||||
* Interpolation | smooth |
|
||||
* | flat | Yes
|
||||
* ---------------+-------------+------
|
||||
* | lowp |
|
||||
* Precision | mediump | Yes
|
||||
* | highp |
|
||||
* ---------------+-------------+------
|
||||
* Variance | invariant | No
|
||||
* ---------------+-------------+------
|
||||
* Memory | all | N/A
|
||||
*
|
||||
* Note that location mismatches are detected by the loops above that
|
||||
* find the producer variable that goes with the consumer variable.
|
||||
*/
|
||||
if (producer_var->type != consumer_var->type ||
|
||||
producer_var->interpolation != consumer_var->interpolation ||
|
||||
producer_var->precision != consumer_var->precision) {
|
||||
valid = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) {
|
||||
valid = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (producer_var->interface_type != consumer_var->interface_type) {
|
||||
valid = false;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
free(outputs);
|
||||
return valid && num_outputs == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate inputs against outputs in a program pipeline.
|
||||
*/
|
||||
|
|
@ -1505,6 +1677,10 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline)
|
|||
shProg[idx]->_LinkedShaders[idx],
|
||||
shProg[prev]->IsES || shProg[idx]->IsES))
|
||||
return false;
|
||||
|
||||
if (!validate_io(shProg[prev], shProg[idx]))
|
||||
return false;
|
||||
|
||||
prev = idx;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue