SpirvShader: Implement GLSLstd450Fma
Bug: b/126873455
Tests: dEQP-VK.glsl.builtin.function.common.fma.*
Change-Id: I00e890a6a051b45bc552944ec5364f070ee3a768
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28629
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 0c1f43d..fb7e620 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -50,6 +50,15 @@
{
return NthBit32(bitCount) - sw::SIMD::UInt(1);
}
+
+ // Performs a fused-multiply add, returning a * b + c.
+ rr::RValue<sw::SIMD::Float> FMA(
+ rr::RValue<sw::SIMD::Float> const &a,
+ rr::RValue<sw::SIMD::Float> const &b,
+ rr::RValue<sw::SIMD::Float> const &c)
+ {
+ return a * b + c;
+ }
}
namespace sw
@@ -3179,6 +3188,17 @@
dst.move(1, HalfToFloatBits((val.UInt(0) & SIMD::UInt(0xFFFF0000)) >> 16));
break;
}
+ case GLSLstd450Fma:
+ {
+ auto a = GenericValue(this, routine, insn.word(5));
+ auto b = GenericValue(this, routine, insn.word(6));
+ auto c = GenericValue(this, routine, insn.word(7));
+ for (auto i = 0u; i < type.sizeInComponents; i++)
+ {
+ dst.move(i, FMA(a.Float(i), b.Float(i), c.Float(i)));
+ }
+ break;
+ }
case GLSLstd450Frexp:
{
auto val = GenericValue(this, routine, insn.word(5));