[Mesa-dev] [PATCH v2] mesa: fix interface matching done in validate_io

Timothy Arceri timothy.arceri at collabora.com
Mon Dec 14 17:31:27 PST 2015


On Mon, 2015-12-14 at 10:29 +0200, Tapani Pälli wrote:
> 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.palli at intel.com>

Hi Tapani,

Just a general comment first.

I think we should first move _mesa_validate_pipeline_io() and
 validate_io() to src/mesa/main/pipelineobj.c I don't think it belongs
here right?


> ---
>  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. */

I think the spec quote should be moved here as it applies to all the
rules in the function then you can also have the comment explaining why
validation for desktop it not done.

I've also filed a spec bug for desktop for the reasons I outlined in
irc previously. It would be great if you could quote the bug here also.
Something like:

/* FIXME: Update once Khronos spec bug #15331 is resolved. */

> +   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();


It's existing code but it would also be nice to have a patch that
renames input_stage/output_stage to producer_stage/consumer_stage this
it what they are called in the linker code. Maybe its just me but
getting the outputs from input_stage just looks wrong.


> -      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) {

Two comments here:

1. Take a look at cross_validate_outputs_to_inputs() in
link_varyings.cpp for a way to avoid the nested loop? Although it may
cause even more overhaed using the symbol table not sure.

2. Take a look at the same function for matching via explicit location.
Does the CTS not test for mismatched explicit locations? Maybe we
should create a piglit test for this as your existing code doesn't take
into account explicit locations.

I was going to suggest sharing the code between here and the linker
however I'm about to add a bunch of rules for matching the component
qualifier for enhanced layouts so not entirely sure if we should do
this what do you think?

>           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;

Hmm ... I wonder if this is also missing from the linker or maybe the
symbol table stuff handles this.

> +
> +         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.

Well they do need to match if they are all used but it doesn't seem the
spec requires it to validated so maybe "does not need to match" -> "is
not required by the spec to be validated".

You are also exiting for desktop at the top of the if below is not
required.

> +    */
> +   return isES ? inputs == outputs : true;
>  }
>  
>  /**


More information about the mesa-dev mailing list