Make shader math functions SIMD width agnostic This change replaces explicit 4-wide vectors with their SIMD counterpart. Currently these sw::SIMD types still alias to packed 4-wide vector types, but these aliases will be changed to rr::SIMD types in a subsequent change. Functions such Sqrt<>, Pow<>, reciprocal(), halfToFloatBits() etc. are not changed at this time because we have code paths with use packed 4-wide vector arguments, as well as SIMD types. These functions will be split up in a subsequent change. Bug: b/214588983 Change-Id: I20c5289467f860c078f6e6b10ec1ad29ea14777c Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/66809 Reviewed-by: Alexis Hétu <sugoi@google.com> Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/ShaderCore.cpp b/src/Pipeline/ShaderCore.cpp index 6c49e0f..ced3ed6 100644 --- a/src/Pipeline/ShaderCore.cpp +++ b/src/Pipeline/ShaderCore.cpp
@@ -157,253 +157,253 @@ } // Approximation of atan in [0..1] -static RValue<Float4> Atan_01(Float4 x) +static RValue<SIMD::Float> Atan_01(SIMD::Float x) { // From 4.4.49, page 81 of the Handbook of Mathematical Functions, by Milton Abramowitz and Irene Stegun - const Float4 a2(-0.3333314528f); - const Float4 a4(0.1999355085f); - const Float4 a6(-0.1420889944f); - const Float4 a8(0.1065626393f); - const Float4 a10(-0.0752896400f); - const Float4 a12(0.0429096138f); - const Float4 a14(-0.0161657367f); - const Float4 a16(0.0028662257f); - Float4 x2 = x * x; + const SIMD::Float a2(-0.3333314528f); + const SIMD::Float a4(0.1999355085f); + const SIMD::Float a6(-0.1420889944f); + const SIMD::Float a8(0.1065626393f); + const SIMD::Float a10(-0.0752896400f); + const SIMD::Float a12(0.0429096138f); + const SIMD::Float a14(-0.0161657367f); + const SIMD::Float a16(0.0028662257f); + SIMD::Float x2 = x * x; return (x + x * (x2 * (a2 + x2 * (a4 + x2 * (a6 + x2 * (a8 + x2 * (a10 + x2 * (a12 + x2 * (a14 + x2 * a16))))))))); } // Polynomial approximation of order 5 for sin(x * 2 * pi) in the range [-1/4, 1/4] -static RValue<Float4> Sin5(Float4 x) +static RValue<SIMD::Float> Sin5(SIMD::Float x) { // A * x^5 + B * x^3 + C * x // Exact at x = 0, 1/12, 1/6, 1/4, and their negatives, which correspond to x * 2 * pi = 0, pi/6, pi/3, pi/2 - const Float4 A = (36288 - 20736 * sqrt(3)) / 5; - const Float4 B = 288 * sqrt(3) - 540; - const Float4 C = (47 - 9 * sqrt(3)) / 5; + const SIMD::Float A = (36288 - 20736 * sqrt(3)) / 5; + const SIMD::Float B = 288 * sqrt(3) - 540; + const SIMD::Float C = (47 - 9 * sqrt(3)) / 5; - Float4 x2 = x * x; + SIMD::Float x2 = x * x; return MulAdd(MulAdd(A, x2, B), x2, C) * x; } -RValue<Float4> Sin(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Sin(RValue<SIMD::Float> x, bool relaxedPrecision) { - const Float4 q = 0.25f; - const Float4 pi2 = 1 / (2 * 3.1415926535f); + const SIMD::Float q = 0.25f; + const SIMD::Float pi2 = 1 / (2 * 3.1415926535f); // Range reduction and mirroring - Float4 x_2 = MulAdd(x, -pi2, q); - Float4 z = q - Abs(x_2 - Round(x_2)); + SIMD::Float x_2 = MulAdd(x, -pi2, q); + SIMD::Float z = q - Abs(x_2 - Round(x_2)); return Sin5(z); } -RValue<Float4> Cos(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Cos(RValue<SIMD::Float> x, bool relaxedPrecision) { - const Float4 q = 0.25f; - const Float4 pi2 = 1 / (2 * 3.1415926535f); + const SIMD::Float q = 0.25f; + const SIMD::Float pi2 = 1 / (2 * 3.1415926535f); // Phase shift, range reduction, and mirroring - Float4 x_2 = x * pi2; - Float4 z = q - Abs(x_2 - Round(x_2)); + SIMD::Float x_2 = x * pi2; + SIMD::Float z = q - Abs(x_2 - Round(x_2)); return Sin5(z); } -RValue<Float4> Tan(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Tan(RValue<SIMD::Float> x, bool relaxedPrecision) { - return sw::Sin(x, relaxedPrecision) / sw::Cos(x, relaxedPrecision); + return Sin(x, relaxedPrecision) / Cos(x, relaxedPrecision); } -static RValue<Float4> Asin_4_terms(RValue<Float4> x) +static RValue<SIMD::Float> Asin_4_terms(RValue<SIMD::Float> x) { // From 4.4.45, page 81 of the Handbook of Mathematical Functions, by Milton Abramowitz and Irene Stegun // |e(x)| <= 5e-8 - const Float4 half_pi(1.57079632f); - const Float4 a0(1.5707288f); - const Float4 a1(-0.2121144f); - const Float4 a2(0.0742610f); - const Float4 a3(-0.0187293f); - Float4 absx = Abs(x); - return As<Float4>(As<Int4>(half_pi - Sqrt<Highp>(1.0f - absx) * (a0 + absx * (a1 + absx * (a2 + absx * a3)))) ^ - (As<Int4>(x) & Int4(0x80000000))); + const SIMD::Float half_pi(1.57079632f); + const SIMD::Float a0(1.5707288f); + const SIMD::Float a1(-0.2121144f); + const SIMD::Float a2(0.0742610f); + const SIMD::Float a3(-0.0187293f); + SIMD::Float absx = Abs(x); + return As<SIMD::Float>(As<SIMD::Int>(half_pi - Sqrt<Highp>(1.0f - absx) * (a0 + absx * (a1 + absx * (a2 + absx * a3)))) ^ + (As<SIMD::Int>(x) & SIMD::Int(0x80000000))); } -static RValue<Float4> Asin_8_terms(RValue<Float4> x) +static RValue<SIMD::Float> Asin_8_terms(RValue<SIMD::Float> x) { // From 4.4.46, page 81 of the Handbook of Mathematical Functions, by Milton Abramowitz and Irene Stegun // |e(x)| <= 0e-8 - const Float4 half_pi(1.5707963268f); - const Float4 a0(1.5707963050f); - const Float4 a1(-0.2145988016f); - const Float4 a2(0.0889789874f); - const Float4 a3(-0.0501743046f); - const Float4 a4(0.0308918810f); - const Float4 a5(-0.0170881256f); - const Float4 a6(0.006700901f); - const Float4 a7(-0.0012624911f); - Float4 absx = Abs(x); - return As<Float4>(As<Int4>(half_pi - Sqrt<Highp>(1.0f - absx) * (a0 + absx * (a1 + absx * (a2 + absx * (a3 + absx * (a4 + absx * (a5 + absx * (a6 + absx * a7)))))))) ^ - (As<Int4>(x) & Int4(0x80000000))); + const SIMD::Float half_pi(1.5707963268f); + const SIMD::Float a0(1.5707963050f); + const SIMD::Float a1(-0.2145988016f); + const SIMD::Float a2(0.0889789874f); + const SIMD::Float a3(-0.0501743046f); + const SIMD::Float a4(0.0308918810f); + const SIMD::Float a5(-0.0170881256f); + const SIMD::Float a6(0.006700901f); + const SIMD::Float a7(-0.0012624911f); + SIMD::Float absx = Abs(x); + return As<SIMD::Float>(As<SIMD::Int>(half_pi - Sqrt<Highp>(1.0f - absx) * (a0 + absx * (a1 + absx * (a2 + absx * (a3 + absx * (a4 + absx * (a5 + absx * (a6 + absx * a7)))))))) ^ + (As<SIMD::Int>(x) & SIMD::Int(0x80000000))); } -RValue<Float4> Asin(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Asin(RValue<SIMD::Float> x, bool relaxedPrecision) { // TODO(b/169755566): Surprisingly, deqp-vk's precision.acos.highp/mediump tests pass when using the 4-term polynomial // approximation version of acos, unlike for Asin, which requires higher precision algorithms. if(!relaxedPrecision) { - return rr::Asin(x); + return Asin(x); } return Asin_8_terms(x); } -RValue<Float4> Acos(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Acos(RValue<SIMD::Float> x, bool relaxedPrecision) { // pi/2 - arcsin(x) return 1.57079632e+0f - Asin_4_terms(x); } -RValue<Float4> Atan(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Atan(RValue<SIMD::Float> x, bool relaxedPrecision) { - Float4 absx = Abs(x); - Int4 O = CmpNLT(absx, 1.0f); - Float4 y = As<Float4>((O & As<Int4>(1.0f / absx)) | (~O & As<Int4>(absx))); // FIXME: Vector select + SIMD::Float absx = Abs(x); + SIMD::Int O = CmpNLT(absx, 1.0f); + SIMD::Float y = As<SIMD::Float>((O & As<SIMD::Int>(1.0f / absx)) | (~O & As<SIMD::Int>(absx))); // FIXME: Vector select - const Float4 half_pi(1.57079632f); - Float4 theta = Atan_01(y); - return As<Float4>(((O & As<Int4>(half_pi - theta)) | (~O & As<Int4>(theta))) ^ // FIXME: Vector select - (As<Int4>(x) & Int4(0x80000000))); + const SIMD::Float half_pi(1.57079632f); + SIMD::Float theta = Atan_01(y); + return As<SIMD::Float>(((O & As<SIMD::Int>(half_pi - theta)) | (~O & As<SIMD::Int>(theta))) ^ // FIXME: Vector select + (As<SIMD::Int>(x) & SIMD::Int(0x80000000))); } -RValue<Float4> Atan2(RValue<Float4> y, RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Atan2(RValue<SIMD::Float> y, RValue<SIMD::Float> x, bool relaxedPrecision) { - const Float4 pi(3.14159265f); // pi - const Float4 minus_pi(-3.14159265f); // -pi - const Float4 half_pi(1.57079632f); // pi/2 - const Float4 quarter_pi(7.85398163e-1f); // pi/4 + const SIMD::Float pi(3.14159265f); // pi + const SIMD::Float minus_pi(-3.14159265f); // -pi + const SIMD::Float half_pi(1.57079632f); // pi/2 + const SIMD::Float quarter_pi(7.85398163e-1f); // pi/4 // Rotate to upper semicircle when in lower semicircle - Int4 S = CmpLT(y, 0.0f); - Float4 theta = As<Float4>(S & As<Int4>(minus_pi)); - Float4 x0 = As<Float4>((As<Int4>(y) & Int4(0x80000000)) ^ As<Int4>(x)); - Float4 y0 = Abs(y); + SIMD::Int S = CmpLT(y, 0.0f); + SIMD::Float theta = As<SIMD::Float>(S & As<SIMD::Int>(minus_pi)); + SIMD::Float x0 = As<SIMD::Float>((As<SIMD::Int>(y) & SIMD::Int(0x80000000)) ^ As<SIMD::Int>(x)); + SIMD::Float y0 = Abs(y); // Rotate to right quadrant when in left quadrant - Int4 Q = CmpLT(x0, 0.0f); - theta += As<Float4>(Q & As<Int4>(half_pi)); - Float4 x1 = As<Float4>((Q & As<Int4>(y0)) | (~Q & As<Int4>(x0))); // FIXME: Vector select - Float4 y1 = As<Float4>((Q & As<Int4>(-x0)) | (~Q & As<Int4>(y0))); // FIXME: Vector select + SIMD::Int Q = CmpLT(x0, 0.0f); + theta += As<SIMD::Float>(Q & As<SIMD::Int>(half_pi)); + SIMD::Float x1 = As<SIMD::Float>((Q & As<SIMD::Int>(y0)) | (~Q & As<SIMD::Int>(x0))); // FIXME: Vector select + SIMD::Float y1 = As<SIMD::Float>((Q & As<SIMD::Int>(-x0)) | (~Q & As<SIMD::Int>(y0))); // FIXME: Vector select // Mirror to first octant when in second octant - Int4 O = CmpNLT(y1, x1); - Float4 x2 = As<Float4>((O & As<Int4>(y1)) | (~O & As<Int4>(x1))); // FIXME: Vector select - Float4 y2 = As<Float4>((O & As<Int4>(x1)) | (~O & As<Int4>(y1))); // FIXME: Vector select + SIMD::Int O = CmpNLT(y1, x1); + SIMD::Float x2 = As<SIMD::Float>((O & As<SIMD::Int>(y1)) | (~O & As<SIMD::Int>(x1))); // FIXME: Vector select + SIMD::Float y2 = As<SIMD::Float>((O & As<SIMD::Int>(x1)) | (~O & As<SIMD::Int>(y1))); // FIXME: Vector select // Approximation of atan in [0..1] - Int4 zero_x = CmpEQ(x2, 0.0f); - Int4 inf_y = IsInf(y2); // Since x2 >= y2, this means x2 == y2 == inf, so we use 45 degrees or pi/4 - Float4 atan2_theta = Atan_01(y2 / x2); - theta += As<Float4>((~zero_x & ~inf_y & ((O & As<Int4>(half_pi - atan2_theta)) | (~O & (As<Int4>(atan2_theta))))) | // FIXME: Vector select - (inf_y & As<Int4>(quarter_pi))); + SIMD::Int zero_x = CmpEQ(x2, 0.0f); + SIMD::Int inf_y = IsInf(y2); // Since x2 >= y2, this means x2 == y2 == inf, so we use 45 degrees or pi/4 + SIMD::Float atan2_theta = Atan_01(y2 / x2); + theta += As<SIMD::Float>((~zero_x & ~inf_y & ((O & As<SIMD::Int>(half_pi - atan2_theta)) | (~O & (As<SIMD::Int>(atan2_theta))))) | // FIXME: Vector select + (inf_y & As<SIMD::Int>(quarter_pi))); // Recover loss of precision for tiny theta angles // This combination results in (-pi + half_pi + half_pi - atan2_theta) which is equivalent to -atan2_theta - Int4 precision_loss = S & Q & O & ~inf_y; + SIMD::Int precision_loss = S & Q & O & ~inf_y; - return As<Float4>((precision_loss & As<Int4>(-atan2_theta)) | (~precision_loss & As<Int4>(theta))); // FIXME: Vector select + return As<SIMD::Float>((precision_loss & As<SIMD::Int>(-atan2_theta)) | (~precision_loss & As<SIMD::Int>(theta))); // FIXME: Vector select } // TODO(chromium:1299047) -static RValue<Float4> Exp2_legacy(RValue<Float4> x0) +static RValue<SIMD::Float> Exp2_legacy(RValue<SIMD::Float> x0) { - Int4 i = RoundInt(x0 - 0.5f); - Float4 ii = As<Float4>((i + Int4(127)) << 23); + SIMD::Int i = RoundInt(x0 - 0.5f); + SIMD::Float ii = As<SIMD::Float>((i + SIMD::Int(127)) << 23); - Float4 f = x0 - Float4(i); - Float4 ff = As<Float4>(Int4(0x3AF61905)); - ff = ff * f + As<Float4>(Int4(0x3C134806)); - ff = ff * f + As<Float4>(Int4(0x3D64AA23)); - ff = ff * f + As<Float4>(Int4(0x3E75EAD4)); - ff = ff * f + As<Float4>(Int4(0x3F31727B)); + SIMD::Float f = x0 - SIMD::Float(i); + SIMD::Float ff = As<SIMD::Float>(SIMD::Int(0x3AF61905)); + ff = ff * f + As<SIMD::Float>(SIMD::Int(0x3C134806)); + ff = ff * f + As<SIMD::Float>(SIMD::Int(0x3D64AA23)); + ff = ff * f + As<SIMD::Float>(SIMD::Int(0x3E75EAD4)); + ff = ff * f + As<SIMD::Float>(SIMD::Int(0x3F31727B)); ff = ff * f + 1.0f; return ii * ff; } -RValue<Float4> Exp2(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Exp2(RValue<SIMD::Float> x, bool relaxedPrecision) { // Clamp to prevent overflow past the representation of infinity. - Float4 x0 = x; + SIMD::Float x0 = x; x0 = Min(x0, 128.0f); - x0 = Max(x0, As<Float4>(Int4(0xC2FDFFFF))); // -126.999992 + x0 = Max(x0, As<SIMD::Float>(SIMD::Int(0xC2FDFFFF))); // -126.999992 if(SWIFTSHADER_LEGACY_PRECISION) // TODO(chromium:1299047) { return Exp2_legacy(x0); } - Float4 xi = Floor(x0); - Float4 f = x0 - xi; + SIMD::Float xi = Floor(x0); + SIMD::Float f = x0 - xi; if(!relaxedPrecision) // highp { // Polynomial which approximates (2^x-x-1)/x. Multiplying with x // gives us a correction term to be added to 1+x to obtain 2^x. - const Float4 a = 1.8852974e-3f; - const Float4 b = 8.9733787e-3f; - const Float4 c = 5.5835927e-2f; - const Float4 d = 2.4015281e-1f; - const Float4 e = -3.0684753e-1f; + const SIMD::Float a = 1.8852974e-3f; + const SIMD::Float b = 8.9733787e-3f; + const SIMD::Float c = 5.5835927e-2f; + const SIMD::Float d = 2.4015281e-1f; + const SIMD::Float e = -3.0684753e-1f; - Float4 r = MulAdd(MulAdd(MulAdd(MulAdd(a, f, b), f, c), f, d), f, e); + SIMD::Float r = MulAdd(MulAdd(MulAdd(MulAdd(a, f, b), f, c), f, d), f, e); // bit_cast<float>(int(x * 2^23)) is a piecewise linear approximation of 2^x. // See "Fast Exponential Computation on SIMD Architectures" by Malossi et al. - Float4 y = MulAdd(r, f, x0); - Int4 i = Int4(y * (1 << 23)) + (127 << 23); + SIMD::Float y = MulAdd(r, f, x0); + SIMD::Int i = SIMD::Int(y * (1 << 23)) + (127 << 23); - return As<Float4>(i); + return As<SIMD::Float>(i); } else // RelaxedPrecision / mediump { // Polynomial which approximates (2^x-x-1)/x. Multiplying with x // gives us a correction term to be added to 1+x to obtain 2^x. - const Float4 a = 7.8145574e-2f; - const Float4 b = 2.2617357e-1f; - const Float4 c = -3.0444314e-1f; + const SIMD::Float a = 7.8145574e-2f; + const SIMD::Float b = 2.2617357e-1f; + const SIMD::Float c = -3.0444314e-1f; - Float4 r = MulAdd(MulAdd(a, f, b), f, c); + SIMD::Float r = MulAdd(MulAdd(a, f, b), f, c); // bit_cast<float>(int(x * 2^23)) is a piecewise linear approximation of 2^x. // See "Fast Exponential Computation on SIMD Architectures" by Malossi et al. - Float4 y = MulAdd(r, f, x0); - Int4 i = Int4(MulAdd((1 << 23), y, (127 << 23))); + SIMD::Float y = MulAdd(r, f, x0); + SIMD::Int i = SIMD::Int(MulAdd((1 << 23), y, (127 << 23))); - return As<Float4>(i); + return As<SIMD::Float>(i); } } -RValue<Float4> Log2_legacy(RValue<Float4> x) +RValue<SIMD::Float> Log2_legacy(RValue<SIMD::Float> x) { - Float4 x1 = As<Float4>(As<Int4>(x) & Int4(0x7F800000)); - x1 = As<Float4>(As<UInt4>(x1) >> 8); - x1 = As<Float4>(As<Int4>(x1) | As<Int4>(Float4(1.0f))); + SIMD::Float x1 = As<SIMD::Float>(As<SIMD::Int>(x) & SIMD::Int(0x7F800000)); + x1 = As<SIMD::Float>(As<SIMD::UInt>(x1) >> 8); + x1 = As<SIMD::Float>(As<SIMD::Int>(x1) | As<SIMD::Int>(SIMD::Float(1.0f))); x1 = (x1 - 1.4960938f) * 256.0f; - Float4 x0 = As<Float4>((As<Int4>(x) & Int4(0x007FFFFF)) | As<Int4>(Float4(1.0f))); + SIMD::Float x0 = As<SIMD::Float>((As<SIMD::Int>(x) & SIMD::Int(0x007FFFFF)) | As<SIMD::Int>(SIMD::Float(1.0f))); - Float4 x2 = MulAdd(MulAdd(9.5428179e-2f, x0, 4.7779095e-1f), x0, 1.9782813e-1f); - Float4 x3 = MulAdd(MulAdd(MulAdd(1.6618466e-2f, x0, 2.0350508e-1f), x0, 2.7382900e-1f), x0, 4.0496687e-2f); + SIMD::Float x2 = MulAdd(MulAdd(9.5428179e-2f, x0, 4.7779095e-1f), x0, 1.9782813e-1f); + SIMD::Float x3 = MulAdd(MulAdd(MulAdd(1.6618466e-2f, x0, 2.0350508e-1f), x0, 2.7382900e-1f), x0, 4.0496687e-2f); x1 += (x0 - 1.0f) * (x2 / x3); - Int4 pos_inf_x = CmpEQ(As<Int4>(x), Int4(0x7F800000)); - return As<Float4>((pos_inf_x & As<Int4>(x)) | (~pos_inf_x & As<Int4>(x1))); + SIMD::Int pos_inf_x = CmpEQ(As<SIMD::Int>(x), SIMD::Int(0x7F800000)); + return As<SIMD::Float>((pos_inf_x & As<SIMD::Int>(x)) | (~pos_inf_x & As<SIMD::Int>(x1))); } -RValue<Float4> Log2(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Log2(RValue<SIMD::Float> x, bool relaxedPrecision) { if(SWIFTSHADER_LEGACY_PRECISION) // TODO(chromium:1299047) { @@ -414,25 +414,25 @@ { // Reinterpretation as an integer provides a piecewise linear // approximation of log2(). Scale to the radix and subtract exponent bias. - Int4 im = As<Int4>(x); - Float4 y = Float4(im - (127 << 23)) * (1.0f / (1 << 23)); + SIMD::Int im = As<SIMD::Int>(x); + SIMD::Float y = SIMD::Float(im - (127 << 23)) * (1.0f / (1 << 23)); // Handle log2(inf) = inf. - y = As<Float4>(As<Int4>(y) | (CmpEQ(im, 0x7F800000) & As<Int4>(Float4::infinity()))); + y = As<SIMD::Float>(As<SIMD::Int>(y) | (CmpEQ(im, 0x7F800000) & As<SIMD::Int>(SIMD::Float::infinity()))); - Float4 m = Float4(im & 0x007FFFFF) * (1.0f / (1 << 23)); // Normalized mantissa of x. + SIMD::Float m = SIMD::Float(im & 0x007FFFFF) * (1.0f / (1 << 23)); // Normalized mantissa of x. // Add a polynomial approximation of log2(m+1)-m to the result's mantissa. - const Float4 a = -9.3091638e-3f; - const Float4 b = 5.2059003e-2f; - const Float4 c = -1.3752135e-1f; - const Float4 d = 2.4186478e-1f; - const Float4 e = -3.4730109e-1f; - const Float4 f = 4.786837e-1f; - const Float4 g = -7.2116581e-1f; - const Float4 h = 4.4268988e-1f; + const SIMD::Float a = -9.3091638e-3f; + const SIMD::Float b = 5.2059003e-2f; + const SIMD::Float c = -1.3752135e-1f; + const SIMD::Float d = 2.4186478e-1f; + const SIMD::Float e = -3.4730109e-1f; + const SIMD::Float f = 4.786837e-1f; + const SIMD::Float g = -7.2116581e-1f; + const SIMD::Float h = 4.4268988e-1f; - Float4 z = MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(a, m, b), m, c), m, d), m, e), m, f), m, g), m, h); + SIMD::Float z = MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(MulAdd(a, m, b), m, c), m, d), m, e), m, f), m, g), m, h); return MulAdd(z, m, y); } @@ -440,77 +440,77 @@ { // Reinterpretation as an integer provides a piecewise linear // approximation of log2(). Scale to the radix and subtract exponent bias. - Int4 im = As<Int4>(x); - Float4 y = MulAdd(Float4(im), (1.0f / (1 << 23)), -127.0f); + SIMD::Int im = As<SIMD::Int>(x); + SIMD::Float y = MulAdd(SIMD::Float(im), (1.0f / (1 << 23)), -127.0f); // Handle log2(inf) = inf. - y = As<Float4>(As<Int4>(y) | (CmpEQ(im, 0x7F800000) & As<Int4>(Float4::infinity()))); + y = As<SIMD::Float>(As<SIMD::Int>(y) | (CmpEQ(im, 0x7F800000) & As<SIMD::Int>(SIMD::Float::infinity()))); - Float4 m = Float4(im & 0x007FFFFF); // Unnormalized mantissa of x. + SIMD::Float m = SIMD::Float(im & 0x007FFFFF); // Unnormalized mantissa of x. // Add a polynomial approximation of log2(m+1)-m to the result's mantissa. - const Float4 a = 2.8017103e-22f; - const Float4 b = -8.373131e-15f; - const Float4 c = 5.0615534e-8f; + const SIMD::Float a = 2.8017103e-22f; + const SIMD::Float b = -8.373131e-15f; + const SIMD::Float c = 5.0615534e-8f; - Float4 f = MulAdd(MulAdd(a, m, b), m, c); + SIMD::Float f = MulAdd(MulAdd(a, m, b), m, c); return MulAdd(f, m, y); } } -RValue<Float4> Exp(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Exp(RValue<SIMD::Float> x, bool relaxedPrecision) { - return sw::Exp2(1.44269504f * x, relaxedPrecision); // 1/ln(2) + return Exp2(1.44269504f * x, relaxedPrecision); // 1/ln(2) } -RValue<Float4> Log(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Log(RValue<SIMD::Float> x, bool relaxedPrecision) { - return 6.93147181e-1f * sw::Log2(x, relaxedPrecision); // ln(2) + return 6.93147181e-1f * Log2(x, relaxedPrecision); // ln(2) } -RValue<Float4> Pow(RValue<Float4> x, RValue<Float4> y, bool relaxedPrecision) +RValue<SIMD::Float> Pow(RValue<SIMD::Float> x, RValue<SIMD::Float> y, bool relaxedPrecision) { - Float4 log = sw::Log2(x, relaxedPrecision); + SIMD::Float log = Log2(x, relaxedPrecision); log *= y; - return sw::Exp2(log, relaxedPrecision); + return Exp2(log, relaxedPrecision); } -RValue<Float4> Sinh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Sinh(RValue<SIMD::Float> x, bool relaxedPrecision) { - return (sw::Exp(x, relaxedPrecision) - sw::Exp(-x, relaxedPrecision)) * 0.5f; + return (Exp(x, relaxedPrecision) - Exp(-x, relaxedPrecision)) * 0.5f; } -RValue<Float4> Cosh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Cosh(RValue<SIMD::Float> x, bool relaxedPrecision) { - return (sw::Exp(x, relaxedPrecision) + sw::Exp(-x, relaxedPrecision)) * 0.5f; + return (Exp(x, relaxedPrecision) + Exp(-x, relaxedPrecision)) * 0.5f; } -RValue<Float4> Tanh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Tanh(RValue<SIMD::Float> x, bool relaxedPrecision) { - Float4 e_x = sw::Exp(x, relaxedPrecision); - Float4 e_minus_x = sw::Exp(-x, relaxedPrecision); + SIMD::Float e_x = Exp(x, relaxedPrecision); + SIMD::Float e_minus_x = Exp(-x, relaxedPrecision); return (e_x - e_minus_x) / (e_x + e_minus_x); } -RValue<Float4> Asinh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Asinh(RValue<SIMD::Float> x, bool relaxedPrecision) { - return sw::Log(x + Sqrt(x * x + 1.0f, relaxedPrecision), relaxedPrecision); + return Log(x + Sqrt(x * x + 1.0f, relaxedPrecision), relaxedPrecision); } -RValue<Float4> Acosh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Acosh(RValue<SIMD::Float> x, bool relaxedPrecision) { - return sw::Log(x + Sqrt(x + 1.0f, relaxedPrecision) * Sqrt(x - 1.0f, relaxedPrecision), relaxedPrecision); + return Log(x + Sqrt(x + 1.0f, relaxedPrecision) * Sqrt(x - 1.0f, relaxedPrecision), relaxedPrecision); } -RValue<Float4> Atanh(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Atanh(RValue<SIMD::Float> x, bool relaxedPrecision) { - return sw::Log((1.0f + x) / (1.0f - x), relaxedPrecision) * 0.5f; + return Log((1.0f + x) / (1.0f - x), relaxedPrecision) * 0.5f; } -RValue<Float4> Sqrt(RValue<Float4> x, bool relaxedPrecision) +RValue<SIMD::Float> Sqrt(RValue<SIMD::Float> x, bool relaxedPrecision) { - return rr::Sqrt(x); // TODO(b/222218659): Optimize for relaxed precision. + return Sqrt(x); // TODO(b/222218659): Optimize for relaxed precision. } RValue<Float4> reciprocal(RValue<Float4> x, bool pp, bool exactAtPow2) @@ -531,14 +531,14 @@ } // TODO(chromium:1299047): Eliminate when Chromium tests accept both fused and unfused multiply-add. -RValue<Float4> mulAdd(RValue<Float4> x, RValue<Float4> y, RValue<Float4> z) +RValue<SIMD::Float> mulAdd(RValue<SIMD::Float> x, RValue<SIMD::Float> y, RValue<SIMD::Float> z) { if(SWIFTSHADER_LEGACY_PRECISION) { return x * y + z; } - return rr::MulAdd(x, y, z); + return MulAdd(x, y, z); } void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3) @@ -717,15 +717,15 @@ return As<Float4>((linear & As<Int4>(lc)) | (~linear & As<Int4>(ec))); // TODO: IfThenElse() } -rr::RValue<sw::SIMD::Float> Sign(rr::RValue<sw::SIMD::Float> const &val) +rr::RValue<SIMD::Float> Sign(rr::RValue<SIMD::Float> const &val) { - return rr::As<sw::SIMD::Float>((rr::As<sw::SIMD::UInt>(val) & sw::SIMD::UInt(0x80000000)) | sw::SIMD::UInt(0x3f800000)); + return rr::As<SIMD::Float>((rr::As<SIMD::UInt>(val) & SIMD::UInt(0x80000000)) | SIMD::UInt(0x3f800000)); } // Returns the <whole, frac> of val. // Both whole and frac will have the same sign as val. -std::pair<rr::RValue<sw::SIMD::Float>, rr::RValue<sw::SIMD::Float>> -Modf(rr::RValue<sw::SIMD::Float> const &val) +std::pair<rr::RValue<SIMD::Float>, rr::RValue<SIMD::Float>> +Modf(rr::RValue<SIMD::Float> const &val) { auto abs = Abs(val); auto sign = Sign(val); @@ -735,96 +735,96 @@ } // Returns the number of 1s in bits, per lane. -sw::SIMD::UInt CountBits(rr::RValue<sw::SIMD::UInt> const &bits) +SIMD::UInt CountBits(rr::RValue<SIMD::UInt> const &bits) { // TODO: Add an intrinsic to reactor. Even if there isn't a // single vector instruction, there may be target-dependent // ways to make this faster. // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel - sw::SIMD::UInt c = bits - ((bits >> 1) & sw::SIMD::UInt(0x55555555)); - c = ((c >> 2) & sw::SIMD::UInt(0x33333333)) + (c & sw::SIMD::UInt(0x33333333)); - c = ((c >> 4) + c) & sw::SIMD::UInt(0x0F0F0F0F); - c = ((c >> 8) + c) & sw::SIMD::UInt(0x00FF00FF); - c = ((c >> 16) + c) & sw::SIMD::UInt(0x0000FFFF); + SIMD::UInt c = bits - ((bits >> 1) & SIMD::UInt(0x55555555)); + c = ((c >> 2) & SIMD::UInt(0x33333333)) + (c & SIMD::UInt(0x33333333)); + c = ((c >> 4) + c) & SIMD::UInt(0x0F0F0F0F); + c = ((c >> 8) + c) & SIMD::UInt(0x00FF00FF); + c = ((c >> 16) + c) & SIMD::UInt(0x0000FFFF); return c; } // Returns 1 << bits. // If the resulting bit overflows a 32 bit integer, 0 is returned. -rr::RValue<sw::SIMD::UInt> NthBit32(rr::RValue<sw::SIMD::UInt> const &bits) +rr::RValue<SIMD::UInt> NthBit32(rr::RValue<SIMD::UInt> const &bits) { - return ((sw::SIMD::UInt(1) << bits) & rr::CmpLT(bits, sw::SIMD::UInt(32))); + return ((SIMD::UInt(1) << bits) & CmpLT(bits, SIMD::UInt(32))); } // Returns bitCount number of of 1's starting from the LSB. -rr::RValue<sw::SIMD::UInt> Bitmask32(rr::RValue<sw::SIMD::UInt> const &bitCount) +rr::RValue<SIMD::UInt> Bitmask32(rr::RValue<SIMD::UInt> const &bitCount) { - return NthBit32(bitCount) - sw::SIMD::UInt(1); + return NthBit32(bitCount) - SIMD::UInt(1); } // Returns the exponent of the floating point number f. // Assumes IEEE 754 -rr::RValue<sw::SIMD::Int> Exponent(rr::RValue<sw::SIMD::Float> f) +rr::RValue<SIMD::Int> Exponent(rr::RValue<SIMD::Float> f) { - auto v = rr::As<sw::SIMD::UInt>(f); - return (sw::SIMD::Int((v >> sw::SIMD::UInt(23)) & sw::SIMD::UInt(0xFF)) - sw::SIMD::Int(126)); + auto v = rr::As<SIMD::UInt>(f); + return (SIMD::Int((v >> SIMD::UInt(23)) & SIMD::UInt(0xFF)) - SIMD::Int(126)); } // Returns y if y < x; otherwise result is x. // If one operand is a NaN, the other operand is the result. // If both operands are NaN, the result is a NaN. -rr::RValue<sw::SIMD::Float> NMin(rr::RValue<sw::SIMD::Float> const &x, rr::RValue<sw::SIMD::Float> const &y) +rr::RValue<SIMD::Float> NMin(rr::RValue<SIMD::Float> const &x, rr::RValue<SIMD::Float> const &y) { auto xIsNan = IsNan(x); auto yIsNan = IsNan(y); - return As<sw::SIMD::Float>( + return As<SIMD::Float>( // If neither are NaN, return min - ((~xIsNan & ~yIsNan) & As<sw::SIMD::Int>(Min(x, y))) | + ((~xIsNan & ~yIsNan) & As<SIMD::Int>(Min(x, y))) | // If one operand is a NaN, the other operand is the result // If both operands are NaN, the result is a NaN. - ((~xIsNan & yIsNan) & As<sw::SIMD::Int>(x)) | - (xIsNan & As<sw::SIMD::Int>(y))); + ((~xIsNan & yIsNan) & As<SIMD::Int>(x)) | + (xIsNan & As<SIMD::Int>(y))); } // Returns y if y > x; otherwise result is x. // If one operand is a NaN, the other operand is the result. // If both operands are NaN, the result is a NaN. -rr::RValue<sw::SIMD::Float> NMax(rr::RValue<sw::SIMD::Float> const &x, rr::RValue<sw::SIMD::Float> const &y) +rr::RValue<SIMD::Float> NMax(rr::RValue<SIMD::Float> const &x, rr::RValue<SIMD::Float> const &y) { auto xIsNan = IsNan(x); auto yIsNan = IsNan(y); - return As<sw::SIMD::Float>( + return As<SIMD::Float>( // If neither are NaN, return max - ((~xIsNan & ~yIsNan) & As<sw::SIMD::Int>(Max(x, y))) | + ((~xIsNan & ~yIsNan) & As<SIMD::Int>(Max(x, y))) | // If one operand is a NaN, the other operand is the result // If both operands are NaN, the result is a NaN. - ((~xIsNan & yIsNan) & As<sw::SIMD::Int>(x)) | - (xIsNan & As<sw::SIMD::Int>(y))); + ((~xIsNan & yIsNan) & As<SIMD::Int>(x)) | + (xIsNan & As<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) +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, + rr::RValue<SIMD::Float> const &c, rr::RValue<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) +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, + rr::RValue<SIMD::Float> const &d, rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, + rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, rr::RValue<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) +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d, + rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, + rr::RValue<SIMD::Float> const &i, rr::RValue<SIMD::Float> const &j, rr::RValue<SIMD::Float> const &k, rr::RValue<SIMD::Float> const &l, + rr::RValue<SIMD::Float> const &m, rr::RValue<SIMD::Float> const &n, rr::RValue<SIMD::Float> const &o, rr::RValue<SIMD::Float> const &p) { return a * Determinant(f, g, h, j, k, l, @@ -841,24 +841,24 @@ } // Returns the inverse of a 2x2 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 4> MatrixInverse( - 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) +std::array<rr::RValue<SIMD::Float>, 4> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, + rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d) { - auto s = sw::SIMD::Float(1.0f) / Determinant(a, b, c, d); + auto s = SIMD::Float(1.0f) / Determinant(a, b, c, d); return { { s * d, -s * b, -s * c, s * a } }; } // Returns the inverse of a 3x3 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 9> MatrixInverse( - 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) +std::array<rr::RValue<SIMD::Float>, 9> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, + rr::RValue<SIMD::Float> const &d, rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, + rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, rr::RValue<SIMD::Float> const &i) { - auto s = sw::SIMD::Float(1.0f) / Determinant( - a, b, c, - d, e, f, - g, h, i); // TODO: duplicate arithmetic calculating the det and below. + auto s = SIMD::Float(1.0f) / Determinant( + a, b, c, + d, e, f, + g, h, i); // TODO: duplicate arithmetic calculating the det and below. return { { s * (e * i - f * h), @@ -874,17 +874,17 @@ } // Returns the inverse of a 4x4 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 16> MatrixInverse( - 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) +std::array<rr::RValue<SIMD::Float>, 16> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d, + rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, + rr::RValue<SIMD::Float> const &i, rr::RValue<SIMD::Float> const &j, rr::RValue<SIMD::Float> const &k, rr::RValue<SIMD::Float> const &l, + rr::RValue<SIMD::Float> const &m, rr::RValue<SIMD::Float> const &n, rr::RValue<SIMD::Float> const &o, rr::RValue<SIMD::Float> const &p) { - auto s = sw::SIMD::Float(1.0f) / Determinant( - a, b, c, d, - e, f, g, h, - i, j, k, l, - m, n, o, p); // TODO: duplicate arithmetic calculating the det and below. + auto s = SIMD::Float(1.0f) / Determinant( + a, b, c, d, + e, f, g, h, + i, j, k, l, + m, n, o, p); // TODO: duplicate arithmetic calculating the det and below. auto kplo = k * p - l * o, jpln = j * p - l * n, jokn = j * o - k * n; auto gpho = g * p - h * o, fphn = f * p - h * n, fogn = f * o - g * n;
diff --git a/src/Pipeline/ShaderCore.hpp b/src/Pipeline/ShaderCore.hpp index c5dd4a3..b02f767 100644 --- a/src/Pipeline/ShaderCore.hpp +++ b/src/Pipeline/ShaderCore.hpp
@@ -93,25 +93,25 @@ } // namespace SIMD // Vulkan 'SPIR-V Extended Instructions for GLSL' (GLSL.std.450) compliant transcendental functions -RValue<Float4> Sin(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Cos(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Tan(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Asin(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Acos(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Atan(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Atan2(RValue<Float4> y, RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Exp2(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Log2(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Exp(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Log(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Pow(RValue<Float4> x, RValue<Float4> y, bool relaxedPrecision); -RValue<Float4> Sinh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Cosh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Tanh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Asinh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Acosh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Atanh(RValue<Float4> x, bool relaxedPrecision); -RValue<Float4> Sqrt(RValue<Float4> x, bool relaxedPrecision); +RValue<SIMD::Float> Sin(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Cos(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Tan(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Asin(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Acos(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Atan(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Atan2(RValue<SIMD::Float> y, RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Exp2(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Log2(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Exp(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Log(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Pow(RValue<SIMD::Float> x, RValue<SIMD::Float> y, bool relaxedPrecision); +RValue<SIMD::Float> Sinh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Cosh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Tanh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Asinh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Acosh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Atanh(RValue<SIMD::Float> x, bool relaxedPrecision); +RValue<SIMD::Float> Sqrt(RValue<SIMD::Float> x, bool relaxedPrecision); // Math functions with uses outside of shaders can be invoked using a verbose template argument instead // of a Boolean argument to indicate precision. For example Sqrt<Mediump>(x) equals Sqrt(x, true). @@ -135,7 +135,7 @@ RValue<Float4> reciprocal(RValue<Float4> x, bool pp = false, bool exactAtPow2 = false); RValue<Float4> reciprocalSquareRoot(RValue<Float4> x, bool abs, bool pp = false); -RValue<Float4> mulAdd(RValue<Float4> x, RValue<Float4> y, RValue<Float4> z); // TODO(chromium:1299047) +RValue<SIMD::Float> mulAdd(RValue<SIMD::Float> x, RValue<SIMD::Float> y, RValue<SIMD::Float> z); // TODO(chromium:1299047) void transpose4x4(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3); void transpose4x3(Short4 &row0, Short4 &row1, Short4 &row2, Short4 &row3); @@ -159,78 +159,78 @@ template<typename T> inline rr::RValue<T> OrAll(rr::RValue<T> const &mask); -rr::RValue<sw::SIMD::Float> Sign(rr::RValue<sw::SIMD::Float> const &val); +rr::RValue<SIMD::Float> Sign(rr::RValue<SIMD::Float> const &val); // Returns the <whole, frac> of val. // Both whole and frac will have the same sign as val. -std::pair<rr::RValue<sw::SIMD::Float>, rr::RValue<sw::SIMD::Float>> -Modf(rr::RValue<sw::SIMD::Float> const &val); +std::pair<rr::RValue<SIMD::Float>, rr::RValue<SIMD::Float>> +Modf(rr::RValue<SIMD::Float> const &val); // Returns the number of 1s in bits, per lane. -sw::SIMD::UInt CountBits(rr::RValue<sw::SIMD::UInt> const &bits); +SIMD::UInt CountBits(rr::RValue<SIMD::UInt> const &bits); // Returns 1 << bits. // If the resulting bit overflows a 32 bit integer, 0 is returned. -rr::RValue<sw::SIMD::UInt> NthBit32(rr::RValue<sw::SIMD::UInt> const &bits); +rr::RValue<SIMD::UInt> NthBit32(rr::RValue<SIMD::UInt> const &bits); // Returns bitCount number of of 1's starting from the LSB. -rr::RValue<sw::SIMD::UInt> Bitmask32(rr::RValue<sw::SIMD::UInt> const &bitCount); +rr::RValue<SIMD::UInt> Bitmask32(rr::RValue<SIMD::UInt> const &bitCount); // Computes `a * b + c`, which may be fused into one operation to produce a higher-precision result. -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); +rr::RValue<SIMD::Float> FMA( + rr::RValue<SIMD::Float> const &a, + rr::RValue<SIMD::Float> const &b, + rr::RValue<SIMD::Float> const &c); // Returns the exponent of the floating point number f. // Assumes IEEE 754 -rr::RValue<sw::SIMD::Int> Exponent(rr::RValue<sw::SIMD::Float> f); +rr::RValue<SIMD::Int> Exponent(rr::RValue<SIMD::Float> f); // Returns y if y < x; otherwise result is x. // If one operand is a NaN, the other operand is the result. // If both operands are NaN, the result is a NaN. -rr::RValue<sw::SIMD::Float> NMin(rr::RValue<sw::SIMD::Float> const &x, rr::RValue<sw::SIMD::Float> const &y); +rr::RValue<SIMD::Float> NMin(rr::RValue<SIMD::Float> const &x, rr::RValue<SIMD::Float> const &y); // Returns y if y > x; otherwise result is x. // If one operand is a NaN, the other operand is the result. // If both operands are NaN, the result is a NaN. -rr::RValue<sw::SIMD::Float> NMax(rr::RValue<sw::SIMD::Float> const &x, rr::RValue<sw::SIMD::Float> const &y); +rr::RValue<SIMD::Float> NMax(rr::RValue<SIMD::Float> const &x, rr::RValue<SIMD::Float> const &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); +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, + rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d); // 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); +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, + rr::RValue<SIMD::Float> const &d, rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, + rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, rr::RValue<SIMD::Float> const &i); // 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); +rr::RValue<SIMD::Float> Determinant( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d, + rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, + rr::RValue<SIMD::Float> const &i, rr::RValue<SIMD::Float> const &j, rr::RValue<SIMD::Float> const &k, rr::RValue<SIMD::Float> const &l, + rr::RValue<SIMD::Float> const &m, rr::RValue<SIMD::Float> const &n, rr::RValue<SIMD::Float> const &o, rr::RValue<SIMD::Float> const &p); // Returns the inverse of a 2x2 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 4> MatrixInverse( - 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); +std::array<rr::RValue<SIMD::Float>, 4> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, + rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d); // Returns the inverse of a 3x3 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 9> MatrixInverse( - 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); +std::array<rr::RValue<SIMD::Float>, 9> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, + rr::RValue<SIMD::Float> const &d, rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, + rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, rr::RValue<SIMD::Float> const &i); // Returns the inverse of a 4x4 matrix. -std::array<rr::RValue<sw::SIMD::Float>, 16> MatrixInverse( - 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); +std::array<rr::RValue<SIMD::Float>, 16> MatrixInverse( + rr::RValue<SIMD::Float> const &a, rr::RValue<SIMD::Float> const &b, rr::RValue<SIMD::Float> const &c, rr::RValue<SIMD::Float> const &d, + rr::RValue<SIMD::Float> const &e, rr::RValue<SIMD::Float> const &f, rr::RValue<SIMD::Float> const &g, rr::RValue<SIMD::Float> const &h, + rr::RValue<SIMD::Float> const &i, rr::RValue<SIMD::Float> const &j, rr::RValue<SIMD::Float> const &k, rr::RValue<SIMD::Float> const &l, + rr::RValue<SIMD::Float> const &m, rr::RValue<SIMD::Float> const &n, rr::RValue<SIMD::Float> const &o, rr::RValue<SIMD::Float> const &p); //////////////////////////////////////////////////////////////////////////// // Inline functions
diff --git a/tests/PipelineBenchmarks/PipelineBenchmarks.cpp b/tests/PipelineBenchmarks/PipelineBenchmarks.cpp index 34aeddb..fa2e331 100644 --- a/tests/PipelineBenchmarks/PipelineBenchmarks.cpp +++ b/tests/PipelineBenchmarks/PipelineBenchmarks.cpp
@@ -19,9 +19,6 @@ #include <vector> -using namespace rr; -using namespace sw; - BENCHMARK_MAIN(); // Macro that creates a lambda wrapper around the input overloaded function, @@ -33,6 +30,8 @@ return fname(std::forward<decltype(args)>(args)...); \ } +namespace sw { + template<typename Func, class... Args> static void Transcendental1(benchmark::State &state, Func func, Args &&...args) { @@ -40,8 +39,8 @@ FunctionT<void(float *, float *)> function; { - Pointer<Float4> r = Pointer<Float>(function.Arg<0>()); - Pointer<Float4> a = Pointer<Float>(function.Arg<1>()); + Pointer<SIMD::Float> r = Pointer<Float>(function.Arg<0>()); + Pointer<SIMD::Float> a = Pointer<Float>(function.Arg<1>()); for(int i = 0; i < REPS; i++) { @@ -51,8 +50,8 @@ auto routine = function("one"); - std::vector<float> r(REPS * 4); - std::vector<float> a(REPS * 4, 1.0f); + std::vector<float> r(REPS * SIMD::Width); + std::vector<float> a(REPS * SIMD::Width, 1.0f); for(auto _ : state) { @@ -67,9 +66,9 @@ FunctionT<void(float *, float *, float *)> function; { - Pointer<Float4> r = Pointer<Float>(function.Arg<0>()); - Pointer<Float4> a = Pointer<Float>(function.Arg<1>()); - Pointer<Float4> b = Pointer<Float>(function.Arg<2>()); + Pointer<SIMD::Float> r = Pointer<Float>(function.Arg<0>()); + Pointer<SIMD::Float> a = Pointer<Float>(function.Arg<1>()); + Pointer<SIMD::Float> b = Pointer<Float>(function.Arg<2>()); for(int i = 0; i < REPS; i++) { @@ -79,9 +78,9 @@ auto routine = function("two"); - std::vector<float> r(REPS * 4); - std::vector<float> a(REPS * 4, 0.456f); - std::vector<float> b(REPS * 4, 0.789f); + std::vector<float> r(REPS * SIMD::Width); + std::vector<float> a(REPS * SIMD::Width, 0.456f); + std::vector<float> b(REPS * SIMD::Width, 0.789f); for(auto _ : state) { @@ -90,7 +89,7 @@ } // No operation; just copy the input to the output, for use as a baseline. -static Float4 Nop(RValue<Float4> x) +static SIMD::Float Nop(RValue<SIMD::Float> x) { return x; } @@ -156,4 +155,6 @@ BENCHMARK_CAPTURE(Transcendental1, sw_Exp2_mediump, LIFT(sw::Exp2), true /* relaxedPrecision */)->Arg(REPS); BENCHMARK_CAPTURE(Transcendental1, rr_Log2, LIFT(rr::Log2))->Arg(REPS); BENCHMARK_CAPTURE(Transcendental1, sw_Log2_highp, LIFT(sw::Log2), false /* relaxedPrecision */)->Arg(REPS); -BENCHMARK_CAPTURE(Transcendental1, sw_Log2_mediump, LIFT(sw::Log2), true /* relaxedPrecision */)->Arg(REPS); \ No newline at end of file +BENCHMARK_CAPTURE(Transcendental1, sw_Log2_mediump, LIFT(sw::Log2), true /* relaxedPrecision */)->Arg(REPS); + +} // namespace sw \ No newline at end of file