[v9,01/26] libcamera: software_isp: gbm: Add a GBM helper class for GPU surface access
diff mbox series

Message ID 20251217100138.82525-2-bryan.odonoghue@linaro.org
State New
Headers show
Series
  • Add GLES 2.0 GPUISP to libcamera
Related show

Commit Message

Bryan O'Donoghue Dec. 17, 2025, 10:01 a.m. UTC
A helper class to interact with GBM. This will allow us to specify the
internal storage format of the GPU when making a texture for the Debayer
vertex/fragment shaders and thus ensure we receive an uncompressed and
untiled output buffer.

Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 include/libcamera/internal/gbm.h       |  39 ++++++++
 include/libcamera/internal/meson.build |   1 +
 src/libcamera/gbm.cpp                  | 130 +++++++++++++++++++++++++
 src/libcamera/meson.build              |  10 ++
 4 files changed, 180 insertions(+)
 create mode 100644 include/libcamera/internal/gbm.h
 create mode 100644 src/libcamera/gbm.cpp

Comments

Robert Mader Dec. 17, 2025, 10:30 a.m. UTC | #1
We might want switch away from the GBM platform in a follow-up. For now:

Reviewed-by: Robert Mader <robert.mader@collabora.com>

On 17.12.25 11:01, Bryan O'Donoghue wrote:
> A helper class to interact with GBM. This will allow us to specify the
> internal storage format of the GPU when making a texture for the Debayer
> vertex/fragment shaders and thus ensure we receive an uncompressed and
> untiled output buffer.
>
> Acked-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> Reviewed-by: Milan Zamazal <mzamazal@redhat.com>
> Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> ---
>   include/libcamera/internal/gbm.h       |  39 ++++++++
>   include/libcamera/internal/meson.build |   1 +
>   src/libcamera/gbm.cpp                  | 130 +++++++++++++++++++++++++
>   src/libcamera/meson.build              |  10 ++
>   4 files changed, 180 insertions(+)
>   create mode 100644 include/libcamera/internal/gbm.h
>   create mode 100644 src/libcamera/gbm.cpp
>
> diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h
> new file mode 100644
> index 000000000..09811d1ef
> --- /dev/null
> +++ b/include/libcamera/internal/gbm.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Linaro Ltd.
> + *
> + * Authors:
> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> + *
> + * Helper class for managing GBM interactions
> + */
> +
> +#pragma once
> +
> +#include <gbm.h>
> +
> +#include <libcamera/base/log.h>
> +
> +#include <libcamera/formats.h>
> +
> +namespace libcamera {
> +
> +LOG_DECLARE_CATEGORY(GBM)
> +
> +class GBM
> +{
> +public:
> +	GBM();
> +	~GBM();
> +
> +	int createDevice();
> +	struct gbm_device *getDevice();
> +	PixelFormat getPixelFormat();
> +
> +private:
> +	int fd_;
> +	struct gbm_device *gbmDevice_;
> +	PixelFormat format_;
> +};
> +
> +} /* namespace libcamera */
> diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
> index e9540a2f7..b8324996b 100644
> --- a/include/libcamera/internal/meson.build
> +++ b/include/libcamera/internal/meson.build
> @@ -23,6 +23,7 @@ libcamera_internal_headers = files([
>       'dma_buf_allocator.h',
>       'formats.h',
>       'framebuffer.h',
> +    'gbm.h',
>       'global_configuration.h',
>       'ipa_data_serializer.h',
>       'ipa_manager.h',
> diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp
> new file mode 100644
> index 000000000..659860500
> --- /dev/null
> +++ b/src/libcamera/gbm.cpp
> @@ -0,0 +1,130 @@
> +/* SPDX-License-Identifier: LGPL-2.1-or-later */
> +/*
> + * Copyright (C) 2024, Linaro Ltd.
> + *
> + * Authors:
> + * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
> + *
> + * Helper class for managing GBM interactions
> + */
> +
> +#include "libcamera/internal/gbm.h"
> +
> +#include <errno.h>
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +#include <sys/mman.h>
> +#include <unistd.h>
> +
> +#include <linux/dma-buf.h>
> +#include <linux/dma-heap.h>
> +
> +namespace libcamera {
> +
> +LOG_DEFINE_CATEGORY(GBM)
> +
> +/**
> + * \class GBM
> + * \brief Helper class for managing GBM interactions
> + *
> + * The GBM class provides a simplified interface for creating and managing
> + * GBM devices. It handles the initialization and teardown of GBM devices
> + * used for buffer allocation in graphics and camera pipelines.
> + *
> + * This class is responsible for opening a DRI render node, creating a GBM
> + * device, and providing access to the device and its associated pixel format.
> + */
> +
> +/**
> + *\var GBM::fd_
> + *\brief file descriptor to DRI device
> + */
> +
> +/**
> + *\var GBM::gbmDevice_
> + *\brief Pointer to GBM device structure derived from fd_
> + */
> +
> +/**
> + *\var GBM::format_
> + *\brief Pixel format the GBM surface was created in
> + */
> +
> +/**
> + *\brief GBM constructor.
> + *
> + * Creates a GBM instance with unitialised state.
> + */
> +GBM::GBM()
> +{
> +	fd_ = 0;
> +	gbmDevice_ = nullptr;
> +}
> +
> +/**
> + *\brief GBM destructor
> + *
> + * Cleans up the GBM device if it was successfully created, and closes
> + * the associated file descriptor.
> + */
> +GBM::~GBM()
> +{
> +	if (gbmDevice_)
> +		gbm_device_destroy(gbmDevice_);
> +}
> +
> +/**
> + * \brief Create and initialize a GBM device
> + *
> + * \todo Get dri device name from envOption setting
> + *
> + * Opens the DRI render node (/dev/dri/renderD128) and creates a GBM
> + * device using the libgbm library. Sets the default pixel format to
> + * ARGB8888.
> + *
> + * \return 0 on success, or a negative error code on failure
> + */
> +int GBM::createDevice()
> +{
> +	const char *dri_node = "/dev/dri/renderD128";
> +
> +	fd_ = open(dri_node, O_RDWR | O_CLOEXEC);
> +	if (fd_ < 0) {
> +		LOG(GBM, Error) << "Open " << dri_node << " fail " << fd_;
> +		return fd_;
> +	}
> +
> +	gbmDevice_ = gbm_create_device(fd_);
> +	if (!gbmDevice_) {
> +		LOG(GBM, Error) << "gbm_create_device fail";
> +		close(fd_);
> +		return -errno;
> +	}
> +
> +	format_ = libcamera::formats::ARGB8888;
> +
> +	return 0;
> +}
> +
> +/**
> + * \brief Retrieve the GBM device handle
> + *
> + * \return Pointer to the gbm_device structure, or nullptr if the device
> + * has not been created
> + */
> +struct gbm_device *GBM::getDevice()
> +{
> +	return gbmDevice_;
> +}
> +
> +/**
> + * \brief Retrieve the pixel format
> + *
> + * \return The PixelFormat used by this GBM instance (ARGB8888)
> + */
> +
> +PixelFormat GBM::getPixelFormat()
> +{
> +	return format_;
> +}
> +} /* namespace libcamera */
> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
> index 575408b2c..e5b5330a8 100644
> --- a/src/libcamera/meson.build
> +++ b/src/libcamera/meson.build
> @@ -70,6 +70,15 @@ libcamera_deps = []
>   libatomic = cc.find_library('atomic', required : false)
>   libthreads = dependency('threads')
>   
> +libgbm = cc.find_library('gbm', required: false)
> +gbm_works = cc.check_header('gbm.h', required: false)
> +
> +if libgbm.found() and gbm_works
> +    libcamera_internal_sources += files([
> +        'gbm.cpp',
> +    ])
> +endif
> +
>   subdir('base')
>   subdir('converter')
>   subdir('ipa')
> @@ -178,6 +187,7 @@ libcamera_deps += [
>       libcamera_base_private,
>       libcrypto,
>       libdl,
> +    libgbm,
>       liblttng,
>       libudev,
>       libyaml,

Patch
diff mbox series

diff --git a/include/libcamera/internal/gbm.h b/include/libcamera/internal/gbm.h
new file mode 100644
index 000000000..09811d1ef
--- /dev/null
+++ b/include/libcamera/internal/gbm.h
@@ -0,0 +1,39 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Linaro Ltd.
+ *
+ * Authors:
+ * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+ *
+ * Helper class for managing GBM interactions
+ */
+
+#pragma once
+
+#include <gbm.h>
+
+#include <libcamera/base/log.h>
+
+#include <libcamera/formats.h>
+
+namespace libcamera {
+
+LOG_DECLARE_CATEGORY(GBM)
+
+class GBM
+{
+public:
+	GBM();
+	~GBM();
+
+	int createDevice();
+	struct gbm_device *getDevice();
+	PixelFormat getPixelFormat();
+
+private:
+	int fd_;
+	struct gbm_device *gbmDevice_;
+	PixelFormat format_;
+};
+
+} /* namespace libcamera */
diff --git a/include/libcamera/internal/meson.build b/include/libcamera/internal/meson.build
index e9540a2f7..b8324996b 100644
--- a/include/libcamera/internal/meson.build
+++ b/include/libcamera/internal/meson.build
@@ -23,6 +23,7 @@  libcamera_internal_headers = files([
     'dma_buf_allocator.h',
     'formats.h',
     'framebuffer.h',
+    'gbm.h',
     'global_configuration.h',
     'ipa_data_serializer.h',
     'ipa_manager.h',
diff --git a/src/libcamera/gbm.cpp b/src/libcamera/gbm.cpp
new file mode 100644
index 000000000..659860500
--- /dev/null
+++ b/src/libcamera/gbm.cpp
@@ -0,0 +1,130 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2024, Linaro Ltd.
+ *
+ * Authors:
+ * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+ *
+ * Helper class for managing GBM interactions
+ */
+
+#include "libcamera/internal/gbm.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#include <linux/dma-buf.h>
+#include <linux/dma-heap.h>
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(GBM)
+
+/**
+ * \class GBM
+ * \brief Helper class for managing GBM interactions
+ *
+ * The GBM class provides a simplified interface for creating and managing
+ * GBM devices. It handles the initialization and teardown of GBM devices
+ * used for buffer allocation in graphics and camera pipelines.
+ *
+ * This class is responsible for opening a DRI render node, creating a GBM
+ * device, and providing access to the device and its associated pixel format.
+ */
+
+/**
+ *\var GBM::fd_
+ *\brief file descriptor to DRI device
+ */
+
+/**
+ *\var GBM::gbmDevice_
+ *\brief Pointer to GBM device structure derived from fd_
+ */
+
+/**
+ *\var GBM::format_
+ *\brief Pixel format the GBM surface was created in
+ */
+
+/**
+ *\brief GBM constructor.
+ *
+ * Creates a GBM instance with unitialised state.
+ */
+GBM::GBM()
+{
+	fd_ = 0;
+	gbmDevice_ = nullptr;
+}
+
+/**
+ *\brief GBM destructor
+ *
+ * Cleans up the GBM device if it was successfully created, and closes
+ * the associated file descriptor.
+ */
+GBM::~GBM()
+{
+	if (gbmDevice_)
+		gbm_device_destroy(gbmDevice_);
+}
+
+/**
+ * \brief Create and initialize a GBM device
+ *
+ * \todo Get dri device name from envOption setting
+ *
+ * Opens the DRI render node (/dev/dri/renderD128) and creates a GBM
+ * device using the libgbm library. Sets the default pixel format to
+ * ARGB8888.
+ *
+ * \return 0 on success, or a negative error code on failure
+ */
+int GBM::createDevice()
+{
+	const char *dri_node = "/dev/dri/renderD128";
+
+	fd_ = open(dri_node, O_RDWR | O_CLOEXEC);
+	if (fd_ < 0) {
+		LOG(GBM, Error) << "Open " << dri_node << " fail " << fd_;
+		return fd_;
+	}
+
+	gbmDevice_ = gbm_create_device(fd_);
+	if (!gbmDevice_) {
+		LOG(GBM, Error) << "gbm_create_device fail";
+		close(fd_);
+		return -errno;
+	}
+
+	format_ = libcamera::formats::ARGB8888;
+
+	return 0;
+}
+
+/**
+ * \brief Retrieve the GBM device handle
+ *
+ * \return Pointer to the gbm_device structure, or nullptr if the device
+ * has not been created
+ */
+struct gbm_device *GBM::getDevice()
+{
+	return gbmDevice_;
+}
+
+/**
+ * \brief Retrieve the pixel format
+ *
+ * \return The PixelFormat used by this GBM instance (ARGB8888)
+ */
+
+PixelFormat GBM::getPixelFormat()
+{
+	return format_;
+}
+} /* namespace libcamera */
diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build
index 575408b2c..e5b5330a8 100644
--- a/src/libcamera/meson.build
+++ b/src/libcamera/meson.build
@@ -70,6 +70,15 @@  libcamera_deps = []
 libatomic = cc.find_library('atomic', required : false)
 libthreads = dependency('threads')
 
+libgbm = cc.find_library('gbm', required: false)
+gbm_works = cc.check_header('gbm.h', required: false)
+
+if libgbm.found() and gbm_works
+    libcamera_internal_sources += files([
+        'gbm.cpp',
+    ])
+endif
+
 subdir('base')
 subdir('converter')
 subdir('ipa')
@@ -178,6 +187,7 @@  libcamera_deps += [
     libcamera_base_private,
     libcrypto,
     libdl,
+    libgbm,
     liblttng,
     libudev,
     libyaml,