diff --git a/include/libcamera/internal/software_isp/swisp_stats.h b/include/libcamera/internal/software_isp/swisp_stats.h
index 3c9860185..d9d0d9be8 100644
--- a/include/libcamera/internal/software_isp/swisp_stats.h
+++ b/include/libcamera/internal/software_isp/swisp_stats.h
@@ -10,6 +10,8 @@
 #include <array>
 #include <stdint.h>
 
+#include "libcamera/internal/vector.h"
+
 namespace libcamera {
 
 /**
@@ -26,17 +28,9 @@ struct SwIspStats {
 	 */
 	bool valid;
 	/**
-	 * \brief Holds the sum of all sampled red pixels
-	 */
-	uint64_t sumR_;
-	/**
-	 * \brief Holds the sum of all sampled green pixels
-	 */
-	uint64_t sumG_;
-	/**
-	 * \brief Holds the sum of all sampled blue pixels
+	 * \brief Sums of colour channels of all the sampled pixels
 	 */
-	uint64_t sumB_;
+	RGB<uint64_t> sum_;
 	/**
 	 * \brief Number of bins in the yHistogram
 	 */
@@ -46,7 +40,7 @@ struct SwIspStats {
 	 */
 	using Histogram = std::array<uint32_t, kYHistogramSize>;
 	/**
-	 * \brief A histogram of luminance values
+	 * \brief A histogram of luminance values of all the sampled pixels
 	 */
 	Histogram yHistogram;
 };
diff --git a/src/ipa/simple/algorithms/awb.cpp b/src/ipa/simple/algorithms/awb.cpp
index 0080865aa..75e4ae4a4 100644
--- a/src/ipa/simple/algorithms/awb.cpp
+++ b/src/ipa/simple/algorithms/awb.cpp
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 /*
- * Copyright (C) 2024, Red Hat Inc.
+ * Copyright (C) 2024-2026 Red Hat Inc.
  *
  * Auto white balance
  */
@@ -73,9 +73,7 @@ void Awb::process(IPAContext &context,
 		histogram.begin(), histogram.end(), uint64_t(0));
 	const uint64_t offset = blackLevel * nPixels;
 	const uint64_t minValid = 1;
-	const uint64_t sumR = stats->sumR_ > offset / 4 ? stats->sumR_ - offset / 4 : minValid;
-	const uint64_t sumG = stats->sumG_ > offset / 2 ? stats->sumG_ - offset / 2 : minValid;
-	const uint64_t sumB = stats->sumB_ > offset / 4 ? stats->sumB_ - offset / 4 : minValid;
+	const RGB<uint64_t> sum = (stats->sum_ - offset).max(minValid);
 
 	/*
 	 * Calculate red and blue gains for AWB.
@@ -83,9 +81,9 @@ void Awb::process(IPAContext &context,
 	 */
 	auto &gains = context.activeState.awb.gains;
 	gains = { {
-		sumR <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumR,
+		sum.r() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.r(),
 		1.0,
-		sumB <= sumG / 4 ? 4.0f : static_cast<float>(sumG) / sumB,
+		sum.b() <= sum.g() / 4 ? 4.0f : static_cast<float>(sum.g()) / sum.b(),
 	} };
 
 	RGB<double> rgbGains{ { 1 / gains.r(), 1 / gains.g(), 1 / gains.b() } };
diff --git a/src/libcamera/software_isp/swstats_cpu.cpp b/src/libcamera/software_isp/swstats_cpu.cpp
index c931edb41..5c3011a7f 100644
--- a/src/libcamera/software_isp/swstats_cpu.cpp
+++ b/src/libcamera/software_isp/swstats_cpu.cpp
@@ -185,9 +185,9 @@ static constexpr unsigned int kBlueYMul = 29; /* 0.114 * 256 */
 	stats_.yHistogram[yVal * SwIspStats::kYHistogramSize / (256 * 256 * (div))]++;
 
 #define SWSTATS_FINISH_LINE_STATS() \
-	stats_.sumR_ += sumR;       \
-	stats_.sumG_ += sumG;       \
-	stats_.sumB_ += sumB;
+	stats_.sum_.r() += sumR;    \
+	stats_.sum_.g() += sumG;    \
+	stats_.sum_.b() += sumB;
 
 void SwStatsCpu::statsBGGR8Line0(const uint8_t *src[])
 {
@@ -332,9 +332,7 @@ void SwStatsCpu::startFrame(uint32_t frame)
 	if (window_.width == 0)
 		LOG(SwStatsCpu, Error) << "Calling startFrame() without setWindow()";
 
-	stats_.sumR_ = 0;
-	stats_.sumB_ = 0;
-	stats_.sumG_ = 0;
+	stats_.sum_ = RGB<uint64_t>({ 0, 0, 0 });
 	stats_.yHistogram.fill(0);
 }
 
