From patchwork Wed Sep 16 14:39:40 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jai Luthra X-Patchwork-Id: 28304 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 5E160BDE6B for ; Wed, 16 Sep 2026 14:40:32 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 09B0B68244; Wed, 16 Sep 2026 16:40:32 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="JquGt0f7"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id ACB1168244 for ; Wed, 16 Sep 2026 16:40:30 +0200 (CEST) Received: from mail.ideasonboard.com (unknown [IPv6:2401:4900:1c69:85de:a3c9:9357:b164:bf0b]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id D86C0558; Wed, 16 Sep 2026 16:38:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1789569529; bh=V7yGi9L5nYMxY54Fe8boNqNFVbYzH/t9drOEkMoqKf8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=JquGt0f7aEHCxETWHT5n21skgCMIObCuBjnJJQmCGSeRtFiEpLGqYJCs0TTtYwEP8 a9aD86JJyuGz0+Lr72td8O02rYEOe58/7T6eJG/QnOJyvlTXv04oSAu6X56kEpGSI3 SI9dsonN8g9B3ejcYNo2JlKotnAQ9jmZ9/7hDqQk= From: Jai Luthra Date: Wed, 16 Sep 2026 20:09:40 +0530 Subject: [PATCH v3 4/8] ipa: rpi: Allow sharing params buffer to the IPA MIME-Version: 1.0 Message-Id: <20260916-pi4-upstream-v3-4-4666708d8829@ideasonboard.com> References: <20260916-pi4-upstream-v3-0-4666708d8829@ideasonboard.com> In-Reply-To: <20260916-pi4-upstream-v3-0-4666708d8829@ideasonboard.com> To: libcamera-devel@lists.libcamera.org Cc: Naushir Patuck , David Plowman , Laurent Pinchart , Kieran Bingham , Paul Elder , Jai Luthra X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=openpgp-sha256; l=7108; i=jai.luthra@ideasonboard.com; h=from:subject:message-id; bh=V7yGi9L5nYMxY54Fe8boNqNFVbYzH/t9drOEkMoqKf8=; b=owEBbQKS/ZANAwAKAUPekfkkmnFFAcsmYgBqqqpAXtogDET7fcK/tog5lclj/kMHcCK4rvbcX 2pp1DHnVgeJAjMEAAEKAB0WIQRN4NgY5dV16NRar8VD3pH5JJpxRQUCaqqqQAAKCRBD3pH5JJpx RfCgD/9rpTbsRwfSIIwTGPR4h3f3N6a6S2rv5mIK+c30Zc1vqsiofv82I81QJUX6SL7R07zztx0 OHXnmedmJd//PAxdN90Jp9hIkPJRl63dZrlcQJG1jvAyOvYj1w9rW29oAxRZe3Q+lfjb7AIrFfp 6j6+TS0V1X1alCnLTocjGh7hPUz2n7pyKz+ZBUtGfuTSBgjMtOUqbx4y2OUA/aexkfejVCpC96j IsYAQaHrZm58ZqzbVRHqNsnQ9Em2erLPD/U9pvrCA4fNLo9ZpnBLx+4KC/yhaJImWpUBCLeGMgs sQ/WNld43I9O+jIBqOYSf/KbfO5uVYUsicov1MQeWIKjssV7/Tm6U7DH0VLpFgNZ2/elj5BrWuQ hReQz4dY4PN+BLtbnH/bYjk/lLH3s1WIWF34mIludj8emhSkI59sJ7fpnDvSSYYQDMNJd5M8z71 lusJwU2q63NmnbxTIkBM8ezXX/8KcrupMMlEZvHtI0cRUvqMHSUoIDnYEoZQxk1wuXWMYAuO5e3 3Ro6qCtZY8CrhnhsVQSeLIwxyIDWwvd0KwYPC0WToEf+zdvEo1/fLeT/Is5CKEgQUfHECRz/aka tJUPdA8Iatq1B5ycb3NaN7f3oNoEzIgFf0sKuARMv93R6ZSRwWSqwydZUkU2rkLIApW+IOg6enG x9Fu1I5evsm9cTA== X-Developer-Key: i=jai.luthra@ideasonboard.com; a=openpgp; fpr=4DE0D818E5D575E8D45AAFC543DE91F9249A7145 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" While the VC4 IPA currently writes control values for configuration, the mainline driver expects a parameter buffer. In preparation for the migration, add plumbing to pass the parameter buffer to the IPA, while reporting back how many bytes were filled through the prepareIspComplete() callback. This is unused for now, VC4 will use it in subsequent commits. Reviewed-by: Paul Elder Tested-by: Paul Elder Signed-off-by: Jai Luthra --- include/libcamera/ipa/raspberrypi.mojom | 6 ++++-- src/ipa/rpi/common/ipa_base.cpp | 11 ++++++++++- src/ipa/rpi/common/ipa_base.h | 4 ++++ src/libcamera/pipeline/rpi/pisp/pisp.cpp | 6 ++++-- src/libcamera/pipeline/rpi/vc4/vc4.cpp | 6 ++++-- 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/include/libcamera/ipa/raspberrypi.mojom b/include/libcamera/ipa/raspberrypi.mojom index 1b7e03582e0e..84566648d213 100644 --- a/include/libcamera/ipa/raspberrypi.mojom +++ b/include/libcamera/ipa/raspberrypi.mojom @@ -33,6 +33,7 @@ struct BufferIds { uint32 bayer; uint32 embedded; uint32 stats; + uint32 params; }; struct ConfigParams { @@ -219,15 +220,16 @@ interface IPARPiEventInterface { /** * \fn prepareIspComplete() * \brief Signal completion of \a prepareIsp - * \param[in] buffers Bayer and embedded buffers actioned. + * \param[in] buffers Bayer, embedded and parameter buffers actioned. * \param[in] stitchSwapBuffers Whether the stitch block buffers need to be swapped. + * \param[in] paramsBytesUsed Number of bytes used in the parameter buffer * * This asynchronous event is signalled to the pipeline handler once * the \a prepareIsp signal has completed, and the ISP is ready to start * processing the frame. The embedded data buffer may be recycled after * this event. */ - prepareIspComplete(BufferIds buffers, bool stitchSwapBuffers); + prepareIspComplete(BufferIds buffers, bool stitchSwapBuffers, uint32 paramsBytesUsed); /** * \fn processStatsComplete() diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp index 293f68454a84..5af1025650d4 100644 --- a/src/ipa/rpi/common/ipa_base.cpp +++ b/src/ipa/rpi/common/ipa_base.cpp @@ -418,6 +418,7 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) unsigned int ipaContext = params.ipaContext % rpiMetadata_.size(); RPiController::Metadata &rpiMetadata = rpiMetadata_[ipaContext]; std::span embeddedBuffer; + std::span paramsBuffer; rpiMetadata.clear(); fillDeviceStatus(params.sensorControls, ipaContext); @@ -441,6 +442,13 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) embeddedBuffer = it->second.planes()[0]; } + if (params.buffers.params) { + auto it = buffers_.find(params.buffers.params); + ASSERT(it != buffers_.end()); + paramsBuffer = it->second.planes()[0]; + platformParamsBufferInit(paramsBuffer); + } + /* * AGC wants to know the algorithm status from the time it actioned the * sensor exposure/gain changes. So fetch it from the metadata list @@ -513,7 +521,8 @@ void IpaBase::prepareIsp(const PrepareParams ¶ms) reportMetadata(ipaContext); /* Ready to push the input buffer into the ISP. */ - prepareIspComplete.emit(params.buffers, stitchSwapBuffers_); + prepareIspComplete.emit(params.buffers, stitchSwapBuffers_, + platformParamsBytesUsed()); } void IpaBase::processStats(const ProcessParams ¶ms) diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h index 1c375669c9f7..88773e1ac759 100644 --- a/src/ipa/rpi/common/ipa_base.h +++ b/src/ipa/rpi/common/ipa_base.h @@ -79,6 +79,8 @@ protected: /* Whether the stitch block (if available) needs to swap buffers. */ bool stitchSwapBuffers_; + virtual size_t platformParamsBytesUsed() const { return 0; } + private: /* Number of metadata objects available in the context list. */ static constexpr unsigned int numMetadataContexts = 16; @@ -87,7 +89,9 @@ private: virtual int32_t platformStart(const ControlList &controls, StartResult *result) = 0; virtual int32_t platformConfigure(const ConfigParams ¶ms, ConfigResult *result) = 0; + virtual void platformParamsBufferInit([[maybe_unused]] std::span paramsBuffer) {} virtual void platformPrepareIsp(RPiController::Metadata &rpiMetadata) = 0; + virtual void platformPrepareAgc(RPiController::Metadata &rpiMetadata) = 0; virtual RPiController::StatisticsPtr platformProcessStats(std::span mem) = 0; diff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp index 159c6b05ee7b..d0103adbe17c 100644 --- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp +++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp @@ -759,7 +759,8 @@ public: void beOutputDequeue(FrameBuffer *buffer); void processStatsComplete(const ipa::RPi::BufferIds &buffers); - void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers); + void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + unsigned int paramsBytesUsed); void setCameraTimeout(uint32_t maxFrameLengthMs); /* Array of CFE and ISP device streams and associated buffers/streams. */ @@ -1885,7 +1886,8 @@ void PiSPCameraData::setCameraTimeout(uint32_t maxFrameLengthMs) cfe_[Cfe::Output0].dev()->setDequeueTimeout(timeout); } -void PiSPCameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers) +void PiSPCameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + [[maybe_unused]] unsigned int paramsBytesUsed) { unsigned int embeddedId = buffers.embedded & RPi::MaskID; unsigned int bayerId = buffers.bayer & RPi::MaskID; diff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp index 200e3b58724a..dca2c1c12549 100644 --- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp +++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp @@ -79,7 +79,8 @@ public: void ispOutputDequeue(FrameBuffer *buffer); void processStatsComplete(const ipa::RPi::BufferIds &buffers); - void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers); + void prepareIspComplete(const ipa::RPi::BufferIds &buffers, bool stitchSwapBuffers, + unsigned int paramsBytesUsed); void setIspControls(const ControlList &controls); void setCameraTimeout(uint32_t maxFrameLengthMs); @@ -863,7 +864,8 @@ void Vc4CameraData::processStatsComplete(const ipa::RPi::BufferIds &buffers) } void Vc4CameraData::prepareIspComplete(const ipa::RPi::BufferIds &buffers, - [[maybe_unused]] bool stitchSwapBuffers) + [[maybe_unused]] bool stitchSwapBuffers, + [[maybe_unused]] unsigned int paramsBytesUsed) { unsigned int embeddedId = buffers.embedded & RPi::MaskID; unsigned int bayer = buffers.bayer & RPi::MaskID;