From 66fe750137f3462607bad39b617ea8bf16d858ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 12 Apr 2015 17:21:28 -0700 Subject: [PATCH] Moved lcd/gcd and strideAlign functions from bgfx. --- include/bx/uint32_t.h | 58 +++++++++++++++++++++++++++++++++++++++++++ tests/uint32_t.cpp | 22 ++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/uint32_t.cpp diff --git a/include/bx/uint32_t.h b/include/bx/uint32_t.h index 9e77295..16ce229 100644 --- a/include/bx/uint32_t.h +++ b/include/bx/uint32_t.h @@ -679,6 +679,64 @@ namespace bx #endif // BX_COMPILER_ } + /// Greatest common divisor. + inline uint32_t uint32_gcd(uint32_t _a, uint32_t _b) + { + do + { + uint32_t tmp = _a % _b; + _a = _b; + _b = tmp; + } + while (_b); + + return _a; + } + + /// Least common multiple. + inline uint32_t uint32_lcm(uint32_t _a, uint32_t _b) + { + return _a * (_b / uint32_gcd(_a, _b) ); + } + + /// Align to arbitrary stride. + inline uint32_t strideAlign(uint32_t _offset, uint32_t _stride) + { + const uint32_t mod = uint32_mod(_offset, _stride); + const uint32_t add = uint32_sub(_stride, mod); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp = uint32_selb(mask, 0, add); + const uint32_t result = uint32_add(_offset, tmp); + + return result; + } + + /// Align to arbitrary stride and 16-bytes. + inline uint32_t strideAlign16(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(16, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + + /// Align to arbitrary stride and 256-bytes. + inline uint32_t strideAlign256(uint32_t _offset, uint32_t _stride) + { + const uint32_t align = uint32_lcm(256, _stride); + const uint32_t mod = uint32_mod(_offset, align); + const uint32_t mask = uint32_cmpeq(mod, 0); + const uint32_t tmp0 = uint32_selb(mask, 0, align); + const uint32_t tmp1 = uint32_add(_offset, tmp0); + const uint32_t result = uint32_sub(tmp1, mod); + + return result; + } + } // namespace bx #endif // BX_UINT32_T_H_HEADER_GUARD diff --git a/tests/uint32_t.cpp b/tests/uint32_t.cpp new file mode 100644 index 0000000..b232ff6 --- /dev/null +++ b/tests/uint32_t.cpp @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2015 Branimir Karadzic. All rights reserved. + * License: http://www.opensource.org/licenses/BSD-2-Clause + */ + +#include "test.h" +#include + +TEST(StrideAlign) +{ + CHECK(0 == bx::strideAlign(0, 12) ); + for (uint32_t ii = 0; ii < 12; ++ii) + { + CHECK(12 == bx::strideAlign(ii+1, 12) ); + } + + CHECK(0 == bx::strideAlign16(0, 12) ); + for (uint32_t ii = 0; ii < 12; ++ii) + { + CHECK(48 == bx::strideAlign16(ii+1, 12) ); + } +}