From 0ba14879e0e2beb18113276d11edeb23dc2c7d6e Mon Sep 17 00:00:00 2001 From: assiduous Date: Fri, 10 Apr 2020 17:02:02 -0700 Subject: MathLib: added FastFloor and FastCeil functions --- Common/interface/BasicMath.hpp | 81 ++++++++++++++++++++++++++++++++++++- Common/interface/FastRand.hpp | 2 +- Common/interface/FilteringTools.hpp | 2 +- 3 files changed, 82 insertions(+), 3 deletions(-) (limited to 'Common/interface') diff --git a/Common/interface/BasicMath.hpp b/Common/interface/BasicMath.hpp index 867c91cd..757244e1 100644 --- a/Common/interface/BasicMath.hpp +++ b/Common/interface/BasicMath.hpp @@ -1942,6 +1942,86 @@ inline Uint32 F4Color_To_RGBA8Unorm(const float4& f4Color) return RGBA8U; } + +// At least on MSVC std::floor is an actual function call into ucrtbase.dll. +// For floats/doubles that fit into Int64 representable range we can do much better. +template +T FastFloor(T x) +{ + auto i = static_cast(x); + auto flr = static_cast(i); + // x flr floor(x) flr <= x + // +1.0 -> 1.0 1.0 true + // +0.5 -> 0.0 0.0 true + // 0.0 -> 0.0 0.0 true + // -0.5 -> 0.0 -1.0 false + // -1.0 -> -1.0 -1.0 true + + return flr <= x ? flr : flr - 1; +} + +template +T FastCeil(T x) +{ + return -FastFloor(-x); +} + + +template +Diligent::Vector2 FastFloor(const Diligent::Vector2& vec) +{ + return Diligent::Vector2{ + FastFloor(vec.x), + FastFloor(vec.y)}; +} + +template +Diligent::Vector3 FastFloor(const Diligent::Vector3& vec) +{ + return Diligent::Vector3{ + FastFloor(vec.x), + FastFloor(vec.y), + FastFloor(vec.z)}; +} + +template +Diligent::Vector4 FastFloor(const Diligent::Vector4& vec) +{ + return Diligent::Vector4{ + FastFloor(vec.x), + FastFloor(vec.y), + FastFloor(vec.z), + FastFloor(vec.w)}; +} + + +template +Diligent::Vector2 FastCeil(const Diligent::Vector2& vec) +{ + return Diligent::Vector2{ + FastCeil(vec.x), + FastCeil(vec.y)}; +} + +template +Diligent::Vector3 FastCeil(const Diligent::Vector3& vec) +{ + return Diligent::Vector3{ + FastCeil(vec.x), + FastCeil(vec.y), + FastCeil(vec.z)}; +} + +template +Diligent::Vector4 FastCeil(const Diligent::Vector4& vec) +{ + return Diligent::Vector4{ + FastCeil(vec.x), + FastCeil(vec.y), + FastCeil(vec.z), + FastCeil(vec.w)}; +} + } // namespace Diligent @@ -2003,7 +2083,6 @@ Diligent::Vector4 min(const Diligent::Vector4& Left, const Diligent::Vecto std::min(Left.w, Right.w)); } - template Diligent::Vector2 floor(const Diligent::Vector2& vec) { diff --git a/Common/interface/FastRand.hpp b/Common/interface/FastRand.hpp index 2494fc83..546da633 100644 --- a/Common/interface/FastRand.hpp +++ b/Common/interface/FastRand.hpp @@ -93,7 +93,7 @@ public: Range{_Max - _Min + 1} { VERIFY_EXPR(_Max > _Min); - VERIFY(Range < FastRand::Max / 8, "Range is too large"); + VERIFY(Range <= FastRand::Max, "Range is too large"); } Type operator()() diff --git a/Common/interface/FilteringTools.hpp b/Common/interface/FilteringTools.hpp index e256f88d..73871093 100644 --- a/Common/interface/FilteringTools.hpp +++ b/Common/interface/FilteringTools.hpp @@ -100,7 +100,7 @@ template LinearTexFilterSampleInfo GetLinearTexFilterSampleInfo(Uint32 Width, float u) { float x = IsNormalizedCoord ? u * static_cast(Width) : u; - float x0 = std::floor(x - 0.5f); + float x0 = FastFloor(x - 0.5f); // clang-format off LinearTexFilterSampleInfo SampleInfo -- cgit v1.2.3