[Mesa-dev] [PATCH v2] nir/spirv: implement ordered / unordered floating point comparisons properly
Lionel Landwerlin
lionel.g.landwerlin at intel.com
Tue Nov 22 12:15:54 UTC 2016
Sounds good to me, thanks!
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
On 17/11/16 08:36, Iago Toral Quiroga wrote:
> Besides the logical operation involved, these also require that we test if the
> operands are ordered / unordered.
>
> For ordered operations, both operands must be ordered (and they must pass the
> conditional test) while for unordered operations it is sufficient if only one
> of the operands is unordered (or they pass the logical test).
>
> Fixes the following Vulkan CTS tests:
>
> dEQP-VK.spirv_assembly.instruction.compute.opfunord.equal
> dEQP-VK.spirv_assembly.instruction.compute.opfunord.greater
> dEQP-VK.spirv_assembly.instruction.compute.opfunord.greaterequal
> dEQP-VK.spirv_assembly.instruction.compute.opfunord.less
> dEQP-VK.spirv_assembly.instruction.compute.opfunord.lessequal
>
> v2: Fixed typo: s/nir_eq/nir_feq
> ---
> src/compiler/spirv/vtn_alu.c | 54 +++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/src/compiler/spirv/vtn_alu.c b/src/compiler/spirv/vtn_alu.c
> index 6d98a62..6d97f6c 100644
> --- a/src/compiler/spirv/vtn_alu.c
> +++ b/src/compiler/spirv/vtn_alu.c
> @@ -257,7 +257,10 @@ vtn_nir_alu_op_for_spirv_opcode(SpvOp opcode, bool *swap)
> case SpvOpBitReverse: return nir_op_bitfield_reverse;
> case SpvOpBitCount: return nir_op_bit_count;
>
> - /* Comparisons: (TODO: How do we want to handled ordered/unordered?) */
> + /* The ordered / unordered operators need special implementation besides
> + * the logical operator to use since they also need to check if operands are
> + * ordered.
> + */
> case SpvOpFOrdEqual: return nir_op_feq;
> case SpvOpFUnordEqual: return nir_op_feq;
> case SpvOpINotEqual: return nir_op_ine;
> @@ -447,6 +450,55 @@ vtn_handle_alu(struct vtn_builder *b, SpvOp opcode,
> nir_imm_float(&b->nb, INFINITY));
> break;
>
Maybe drop the additional empty line?
> +
> + case SpvOpFUnordEqual:
> + case SpvOpFUnordNotEqual:
> + case SpvOpFUnordLessThan:
> + case SpvOpFUnordGreaterThan:
> + case SpvOpFUnordLessThanEqual:
> + case SpvOpFUnordGreaterThanEqual: {
> + bool swap;
> + nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
> +
> + if (swap) {
> + nir_ssa_def *tmp = src[0];
> + src[0] = src[1];
> + src[1] = tmp;
> + }
> +
> + val->ssa->def =
> + nir_ior(&b->nb,
> + nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
> + nir_ior(&b->nb,
> + nir_fne(&b->nb, src[0], src[0]),
> + nir_fne(&b->nb, src[1], src[1])));
> + break;
> + }
> +
> + case SpvOpFOrdEqual:
> + case SpvOpFOrdNotEqual:
> + case SpvOpFOrdLessThan:
> + case SpvOpFOrdGreaterThan:
> + case SpvOpFOrdLessThanEqual:
> + case SpvOpFOrdGreaterThanEqual: {
> + bool swap;
> + nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
> +
> + if (swap) {
> + nir_ssa_def *tmp = src[0];
> + src[0] = src[1];
> + src[1] = tmp;
> + }
> +
> + val->ssa->def =
> + nir_iand(&b->nb,
> + nir_build_alu(&b->nb, op, src[0], src[1], NULL, NULL),
> + nir_iand(&b->nb,
> + nir_feq(&b->nb, src[0], src[0]),
> + nir_feq(&b->nb, src[1], src[1])));
> + break;
> + }
> +
> default: {
> bool swap;
> nir_op op = vtn_nir_alu_op_for_spirv_opcode(opcode, &swap);
More information about the mesa-dev
mailing list