[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