Patch makes following changes for interface matching: - do not try to match builtin variables - handle swizzle in input name, as example 'a.z' should match with 'a' - check that amount of inputs and outputs matches
These changes make interface matching tests to work in: ES31-CTS.sepshaderobjs.StateInteraction Test does not still pass completely due to errors in rendering output. IMO this is unrelated to interface matching. v2: add spec reference, return true on desktop since we do not have failing cases for it, inputs and outputs amount do not need to match on desktop. Signed-off-by: Tapani Pälli <tapani.pa...@intel.com> --- src/mesa/main/shader_query.cpp | 54 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index ced10a9..bc01b97 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -1377,19 +1377,38 @@ validate_io(const struct gl_shader *input_stage, const struct gl_shader *output_stage, bool isES) { assert(input_stage && output_stage); + unsigned inputs = 0, outputs = 0; + + /* Currently no matching done for desktop. */ + if (!isES) + return true; /* For each output in a, find input in b and do any required checks. */ foreach_in_list(ir_instruction, out, input_stage->ir) { ir_variable *out_var = out->as_variable(); - if (!out_var || out_var->data.mode != ir_var_shader_out) + if (!out_var || out_var->data.mode != ir_var_shader_out || + is_gl_identifier(out_var->name)) continue; + outputs++; + + inputs = 0; foreach_in_list(ir_instruction, in, output_stage->ir) { ir_variable *in_var = in->as_variable(); - if (!in_var || in_var->data.mode != ir_var_shader_in) + if (!in_var || in_var->data.mode != ir_var_shader_in || + is_gl_identifier(in_var->name)) continue; - if (strcmp(in_var->name, out_var->name) == 0) { + inputs++; + + unsigned len = strlen(in_var->name); + + /* Handle input swizzle in variable name. */ + const char *dot = strchr(in_var->name, '.'); + if (dot) + len = dot - in_var->name; + + if (strncmp(in_var->name, out_var->name, len) == 0) { /* Since we now only validate precision, we can skip this step for * desktop GLSL shaders, there precision qualifier is ignored. * @@ -1412,7 +1431,34 @@ validate_io(const struct gl_shader *input_stage, } } } - return true; + + /* Amount of inputs vs outputs should match when using OpenGL ES. + * + * From OpenGL ES 3.1 spec (Interface matching): + * + * "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. + * + * - All matched input and output variables have identical precision + * qualification. + * + * When the set of inputs and outputs on an interface between programs + * matches exactly, all inputs are well-defined except when the + * corresponding outputs were not written in the previous shader. However, + * any mismatch between inputs and outputs will result in a validation + * failure." + * + * OpenGL Core 4.5 spec includes same paragraph as above but without last + * precision or the last 'validation failure' clause. Therefore behaviour is + * more relaxed, input and output amount does not need to match on desktop. + */ + return isES ? inputs == outputs : true; } /** -- 2.5.0 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev