SpirvShader: Implement GLSLstd450Determinant
Bug: b/126873455
Tests: dEQP-VK.glsl.matrix.determinant.*
Change-Id: I81ae56951b9fa2e1aedb327039160cf44f7f0a18
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/28728
Tested-by: Ben Clayton <bclayton@google.com>
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 3c785cf..e79fa94 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -103,6 +103,44 @@
((~xIsNan & yIsNan) & As<sw::SIMD::Int>(x)) |
(( xIsNan ) & As<sw::SIMD::Int>(y)));
}
+
+ // Returns the determinant of a 2x2 matrix.
+ rr::RValue<sw::SIMD::Float> Determinant(
+ rr::RValue<sw::SIMD::Float> const &a, rr::RValue<sw::SIMD::Float> const &b,
+ rr::RValue<sw::SIMD::Float> const &c, rr::RValue<sw::SIMD::Float> const &d)
+ {
+ return a*d - b*c;
+ }
+
+ // Returns the determinant of a 3x3 matrix.
+ rr::RValue<sw::SIMD::Float> Determinant(
+ rr::RValue<sw::SIMD::Float> const &a, rr::RValue<sw::SIMD::Float> const &b, rr::RValue<sw::SIMD::Float> const &c,
+ rr::RValue<sw::SIMD::Float> const &d, rr::RValue<sw::SIMD::Float> const &e, rr::RValue<sw::SIMD::Float> const &f,
+ rr::RValue<sw::SIMD::Float> const &g, rr::RValue<sw::SIMD::Float> const &h, rr::RValue<sw::SIMD::Float> const &i)
+ {
+ return a*e*i + b*f*g + c*d*h - c*e*g - b*d*i - a*f*h;
+ }
+
+ // Returns the determinant of a 4x4 matrix.
+ rr::RValue<sw::SIMD::Float> Determinant(
+ rr::RValue<sw::SIMD::Float> const &a, rr::RValue<sw::SIMD::Float> const &b, rr::RValue<sw::SIMD::Float> const &c, rr::RValue<sw::SIMD::Float> const &d,
+ rr::RValue<sw::SIMD::Float> const &e, rr::RValue<sw::SIMD::Float> const &f, rr::RValue<sw::SIMD::Float> const &g, rr::RValue<sw::SIMD::Float> const &h,
+ rr::RValue<sw::SIMD::Float> const &i, rr::RValue<sw::SIMD::Float> const &j, rr::RValue<sw::SIMD::Float> const &k, rr::RValue<sw::SIMD::Float> const &l,
+ rr::RValue<sw::SIMD::Float> const &m, rr::RValue<sw::SIMD::Float> const &n, rr::RValue<sw::SIMD::Float> const &o, rr::RValue<sw::SIMD::Float> const &p)
+ {
+ return a * Determinant(f, g, h,
+ j, k, l,
+ n, o, p) -
+ b * Determinant(e, g, h,
+ i, k, l,
+ m, o, p) +
+ c * Determinant(e, f, h,
+ i, j, l,
+ m, n, p) -
+ d * Determinant(e, f, g,
+ i, j, k,
+ m, n, o);
+ }
}
namespace sw
@@ -3518,7 +3556,31 @@
}
case GLSLstd450Determinant:
{
- UNIMPLEMENTED("GLSLstd450Determinant");
+ auto mat = GenericValue(this, routine, insn.word(5));
+ auto numComponents = getType(mat.type).sizeInComponents;
+ switch (numComponents)
+ {
+ case 4: // 2x2
+ dst.move(0, Determinant(
+ mat.Float(0), mat.Float(1),
+ mat.Float(2), mat.Float(3)));
+ break;
+ case 9: // 3x3
+ dst.move(0, Determinant(
+ mat.Float(0), mat.Float(1), mat.Float(2),
+ mat.Float(3), mat.Float(4), mat.Float(5),
+ mat.Float(6), mat.Float(7), mat.Float(8)));
+ break;
+ case 16: // 4x4
+ dst.move(0, Determinant(
+ mat.Float(0), mat.Float(1), mat.Float(2), mat.Float(3),
+ mat.Float(4), mat.Float(5), mat.Float(6), mat.Float(7),
+ mat.Float(8), mat.Float(9), mat.Float(10), mat.Float(11),
+ mat.Float(12), mat.Float(13), mat.Float(14), mat.Float(15)));
+ break;
+ default:
+ UNREACHABLE("GLSLstd450Determinant can only operate with square matrices. Got %d elements", int(numComponents));
+ }
break;
}
case GLSLstd450MatrixInverse: