SpirvShader: Implement OpQuantizeToF16
Bug: b/126873455
Test: *opquantize*
Change-Id: I941ce6e2f39b81686eeb91b92694a14fa3b9f5f7
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/29569
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index ff6c164..d63c97b 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -745,6 +745,7 @@
case spv::OpSNegate:
case spv::OpFNegate:
case spv::OpLogicalNot:
+ case spv::OpQuantizeToF16:
// Binary ops
case spv::OpIAdd:
case spv::OpISub:
@@ -2271,6 +2272,7 @@
case spv::OpDPdxFine:
case spv::OpDPdyFine:
case spv::OpFwidthFine:
+ case spv::OpQuantizeToF16:
return EmitUnaryOp(insn, state);
case spv::OpIAdd:
@@ -3040,6 +3042,21 @@
dst.move(i, Abs(dpdx) + Abs(dpdy));
break;
}
+ case spv::OpQuantizeToF16:
+ {
+ auto abs = Abs(src.Float(i));
+ auto sign = src.Int(i) & SIMD::Int(0x80000000);
+ auto isZero = CmpLT(abs, SIMD::Float(0.000061035));
+ auto isInf = CmpGT(abs, SIMD::Float(65504.0f));
+ auto isNaN = IsNan(abs);
+ auto isInfOrNan = isInf | isNaN;
+ SIMD::Int v = src.Int(i) & SIMD::Int(0xFFFFE000);
+ v &= ~isZero | SIMD::Int(0x80000000);
+ v = sign | (isInfOrNan & SIMD::Int(0x7F800000)) | (~isInfOrNan & v);
+ v |= isNaN & SIMD::Int(0x400000);
+ dst.move(i, v);
+ break;
+ }
default:
UNIMPLEMENTED("Unhandled unary operator %s", OpcodeName(insn.opcode()).c_str());
}