[Mesa-dev] [PATCH v4 2/2] glsl: fix interpolateAtXxx(some_vec[idx], ...) with dynamic idx

Timothy Arceri tarceri at itsqueeze.com
Fri Oct 27 10:41:49 UTC 2017


Reviewed-by: Timothy Arceri <tarceri at itsqueeze.com>

On 10/10/17 23:09, Nicolai Hähnle wrote:
> From: Nicolai Hähnle <nicolai.haehnle at amd.com>
> 
> The dynamic index of a vector (not array!) is lowered to a sequence of
> conditional assignments. However, the interpolate_at_* expressions
> require that the interpolant is an l-value of a shader input.
> 
> So instead of doing conditional assignments of parts of the shader input
> and then interpolating that (which is nonsensical), we interpolate the
> entire shader input and then do conditional assignments of the interpolated
> result.
> ---
>   .../glsl/lower_vec_index_to_cond_assign.cpp        | 31 +++++++++++++++++++++-
>   1 file changed, 30 insertions(+), 1 deletion(-)
> 
> diff --git a/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp b/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> index a26253998e0..89244266602 100644
> --- a/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> +++ b/src/compiler/glsl/lower_vec_index_to_cond_assign.cpp
> @@ -121,21 +121,50 @@ ir_vec_index_to_cond_assign_visitor::convert_vec_index_to_cond_assign(void *mem_
>   
>      this->progress = true;
>      return deref(var).val;
>   }
>   
>   ir_rvalue *
>   ir_vec_index_to_cond_assign_visitor::convert_vector_extract_to_cond_assign(ir_rvalue *ir)
>   {
>      ir_expression *const expr = ir->as_expression();
>   
> -   if (expr == NULL || expr->operation != ir_binop_vector_extract)
> +   if (expr == NULL)
> +      return ir;
> +
> +   if (expr->operation == ir_unop_interpolate_at_centroid ||
> +       expr->operation == ir_binop_interpolate_at_offset ||
> +       expr->operation == ir_binop_interpolate_at_sample) {
> +      /* Lower interpolateAtXxx(some_vec[idx], ...) to
> +       * interpolateAtXxx(some_vec, ...)[idx] before lowering to conditional
> +       * assignments, to maintain the rule that the interpolant is an l-value
> +       * referring to a (part of a) shader input.
> +       *
> +       * This is required when idx is dynamic (otherwise it gets lowered to
> +       * a swizzle).
> +       */
> +      ir_expression *const interpolant = expr->operands[0]->as_expression();
> +      if (!interpolant || interpolant->operation != ir_binop_vector_extract)
> +         return ir;
> +
> +      ir_rvalue *vec_input = interpolant->operands[0];
> +      ir_expression *const vec_interpolate =
> +         new(base_ir) ir_expression(expr->operation, vec_input->type,
> +                                    vec_input, expr->operands[1]);
> +
> +      return convert_vec_index_to_cond_assign(ralloc_parent(ir),
> +                                              vec_interpolate,
> +                                              interpolant->operands[1],
> +                                              ir->type);
> +   }
> +
> +   if (expr->operation != ir_binop_vector_extract)
>         return ir;
>   
>      return convert_vec_index_to_cond_assign(ralloc_parent(ir),
>                                              expr->operands[0],
>                                              expr->operands[1],
>                                              ir->type);
>   }
>   
>   ir_visitor_status
>   ir_vec_index_to_cond_assign_visitor::visit_enter(ir_expression *ir)
> 


More information about the mesa-dev mailing list