Mesa (master): util: Add fast division helpers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Oct 10 18:13:55 UTC 2018


Module: Mesa
Branch: master
Commit: 64eb0738d4e35e9ceb4bf99b028bdd5e12c59c34
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=64eb0738d4e35e9ceb4bf99b028bdd5e12c59c34

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Fri Oct  5 20:28:40 2018 -0500

util: Add fast division helpers

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net>

---

 src/util/fast_idiv_by_const.h | 44 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/src/util/fast_idiv_by_const.h b/src/util/fast_idiv_by_const.h
index ac10cf79ba..1ba9f9a20b 100644
--- a/src/util/fast_idiv_by_const.h
+++ b/src/util/fast_idiv_by_const.h
@@ -130,6 +130,50 @@ struct util_fast_udiv_info {
 struct util_fast_udiv_info
 util_compute_fast_udiv_info(uint_t D, unsigned num_bits);
 
+/* Below are possible options for dividing by a uniform in a shader where
+ * the divisor is constant but not known at compile time.
+ */
+
+/* Full version. */
+static inline uint32_t
+util_fast_udiv32(uint32_t n, struct util_fast_udiv_info info)
+{
+   n = n >> info.pre_shift;
+   /* For non-power-of-two divisors, use a 32-bit ADD that clamps to UINT_MAX. */
+   n = (((uint64_t)n + info.increment) * info.multiplier) >> 32;
+   n = n >> info.post_shift;
+   return n;
+}
+
+/* A little more efficient version if n != UINT_MAX, i.e. no unsigned
+ * wraparound in the computation.
+ */
+static inline uint32_t
+util_fast_udiv32_nuw(uint32_t n, struct util_fast_udiv_info info)
+{
+   assert(n != UINT32_MAX);
+   n = n >> info.pre_shift;
+   n = n + info.increment;
+   n = ((uint64_t)n * info.multiplier) >> 32;
+   n = n >> info.post_shift;
+   return n;
+}
+
+/* Even faster version but both operands must be 31-bit unsigned integers
+ * and the divisor must be greater than 1.
+ *
+ * info must be computed with num_bits == 31.
+ */
+static inline uint32_t
+util_fast_udiv32_u31_d_not_one(uint32_t n, struct util_fast_udiv_info info)
+{
+   assert(info.pre_shift == 0);
+   assert(info.increment == 0);
+   n = ((uint64_t)n * info.multiplier) >> 32;
+   n = n >> info.post_shift;
+   return n;
+}
+
 #ifdef __cplusplus
 } /* extern C */
 #endif




More information about the mesa-commit mailing list