From patchwork Fri Feb 13 16:57:54 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 26156 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 73EFDC32F9 for ; Fri, 13 Feb 2026 16:58:21 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 64BE36221E; Fri, 13 Feb 2026 17:58:20 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="dH1zE17X"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id AA8BF621D2 for ; Fri, 13 Feb 2026 17:58:07 +0100 (CET) Received: from ping.linuxembedded.co.uk (cpc89244-aztw30-2-0-cust6594.18-1.cable.virginm.net [86.31.185.195]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id E0DCFCF5; Fri, 13 Feb 2026 17:57:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1771001839; bh=zJOPvoolvcG7M6jX257CbJH+tLTuqBdd29zxxjVtuO0=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=dH1zE17XPw5NoK8fF0nVf6o0h8mCWeHg+93CqwKiU/0M5bRbB0UXzrFtTCfY02Ckw lOaetCYg7xK/wELNFhPyahw/Ut0ptAqm64BhZ7u+X/CgGu+8vK9MkTJSTC8/vkYjK8 d1KitHifKupH67nv+e+UHQsp+O2xzmxIiOGS78ZM= From: Kieran Bingham Date: Fri, 13 Feb 2026 16:57:54 +0000 Subject: [PATCH v7 15/15] ipa: libipa: fixedpoint: Move float conversion inline MIME-Version: 1.0 Message-Id: <20260213-kbingham-quantizers-v7-15-1626b9aaabf1@ideasonboard.com> References: <20260213-kbingham-quantizers-v7-0-1626b9aaabf1@ideasonboard.com> In-Reply-To: <20260213-kbingham-quantizers-v7-0-1626b9aaabf1@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Kieran Bingham , Isaac Scott , Laurent Pinchart X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1771001883; l=5815; i=kieran.bingham@ideasonboard.com; s=20260207; h=from:subject:message-id; bh=zJOPvoolvcG7M6jX257CbJH+tLTuqBdd29zxxjVtuO0=; b=tis6wbh/f3BJL8eWzgpamzWNmywRg9DyQuRU+XkUKDw5wSVX8VoGttiYM6SyWjluYCoJTQ/CX 5qC0JA4iXOxDFvDNH28BQ+TYJF2q98wsR7JJe8fDRb4J+0w4H+Em34l X-Developer-Key: i=kieran.bingham@ideasonboard.com; a=ed25519; pk=FVXKN7YuwHc6UtbRUeTMAmranfsQomA+vnilfglWdaY= X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" With all users of the floatingToFixedPoint and fixedToFloatingPoint calls converted to use the FixedPoint Quantized types, remove the calls and documentation and move the implementation inline in the FixedPointTraits implementation. Reviewed-by: Isaac Scott Reviewed-by: Laurent Pinchart Signed-off-by: Kieran Bingham --- v5: - Reflow text when moved v6: - Use UT{1} << F instead of 1 << F --- src/ipa/libipa/fixedpoint.cpp | 22 ------------- src/ipa/libipa/fixedpoint.h | 75 +++++++++++++------------------------------ 2 files changed, 22 insertions(+), 75 deletions(-) diff --git a/src/ipa/libipa/fixedpoint.cpp b/src/ipa/libipa/fixedpoint.cpp index caa9ce0fc1ec..7eee3614df6a 100644 --- a/src/ipa/libipa/fixedpoint.cpp +++ b/src/ipa/libipa/fixedpoint.cpp @@ -15,28 +15,6 @@ namespace libcamera { namespace ipa { -/** - * \fn R floatingToFixedPoint(T number) - * \brief Convert a floating point number to a fixed-point representation - * \tparam I Bit width of the integer part of the fixed-point - * \tparam F Bit width of the fractional part of the fixed-point - * \tparam R Return type of the fixed-point representation - * \tparam T Input type of the floating point representation - * \param number The floating point number to convert to fixed point - * \return The converted value - */ - -/** - * \fn R fixedToFloatingPoint(T number) - * \brief Convert a fixed-point number to a floating point representation - * \tparam I Bit width of the integer part of the fixed-point - * \tparam F Bit width of the fractional part of the fixed-point - * \tparam R Return type of the floating point representation - * \tparam T Input type of the fixed-point representation - * \param number The fixed point number to convert to floating point - * \return The converted value - */ - /** * \struct libcamera::ipa::FixedPointQTraits * \brief Traits type implementing fixed-point quantisation conversions diff --git a/src/ipa/libipa/fixedpoint.h b/src/ipa/libipa/fixedpoint.h index b6b611df7fc3..a0da31209271 100644 --- a/src/ipa/libipa/fixedpoint.h +++ b/src/ipa/libipa/fixedpoint.h @@ -16,55 +16,6 @@ namespace libcamera { namespace ipa { -#ifndef __DOXYGEN__ -template && - std::is_floating_point_v> * = nullptr> -#else -template -#endif -constexpr R floatingToFixedPoint(T number) -{ - static_assert(sizeof(int) >= sizeof(R)); - static_assert(I + F <= sizeof(R) * 8); - - /* - * The intermediate cast to int is needed on arm platforms to properly - * cast negative values. See - * https://embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/ - */ - R mask = (1 << (F + I)) - 1; - R frac = static_cast(static_cast(std::round(number * (1 << F)))) & mask; - - return frac; -} - -#ifndef __DOXYGEN__ -template && - std::is_integral_v> * = nullptr> -#else -template -#endif -constexpr R fixedToFloatingPoint(T number) -{ - static_assert(sizeof(int) >= sizeof(T)); - static_assert(I + F <= sizeof(T) * 8); - - if constexpr (std::is_unsigned_v) - return static_cast(number) / static_cast(T{ 1 } << F); - - /* - * Recreate the upper bits in case of a negative number by shifting the sign - * bit from the fixed point to the first bit of the unsigned and then right shifting - * by the same amount which keeps the sign bit in place. - * This can be optimized by the compiler quite well. - */ - int remaining_bits = sizeof(int) * 8 - (I + F); - int t = static_cast(static_cast(number) << remaining_bits) >> remaining_bits; - return static_cast(t) / static_cast(1 << F); -} - template struct FixedPointQTraits { private: @@ -97,11 +48,23 @@ public: static constexpr float toFloat(QuantizedType q) { - return fixedToFloatingPoint(q); + if constexpr (std::is_unsigned_v) + return static_cast(q) / static_cast(UT{ 1 } << F); + + /* + * Recreate the upper bits in case of a negative number by + * shifting the sign bit from the fixed point to the first bit + * of the unsigned and then right shifting by the same amount + * which keeps the sign bit in place. This can be optimized by + * the compiler quite well. + */ + unsigned int remaining_bits = sizeof(UT) * 8 - (I + F); + T t = static_cast(static_cast(q) << remaining_bits) >> remaining_bits; + return static_cast(t) / static_cast(UT{ 1 } << F); } - static constexpr float min = fixedToFloatingPoint(static_cast(qMin)); - static constexpr float max = fixedToFloatingPoint(static_cast(qMax)); + static constexpr float min = toFloat(qMin); + static constexpr float max = toFloat(qMax); static_assert(min < max, "FixedPointQTraits: Minimum must be less than maximum"); @@ -109,7 +72,13 @@ public: static QuantizedType fromFloat(float v) { v = std::clamp(v, min, max); - return floatingToFixedPoint(v); + + /* + * The intermediate cast to int is needed on arm platforms to + * properly cast negative values. See + * https://embeddeduse.com/2013/08/25/casting-a-negative-float-to-an-unsigned-int/ + */ + return static_cast(static_cast(std::round(v * (1 << F)))) & bitMask; } };