[05/30] libcamera: software_isp: gpu_pipeline_shader_pass: Add base class GpuPipelineShaderPass
diff mbox series

Message ID 20260618122245.946138-6-bryan.odonoghue@linaro.org
State New
Headers show
Series
  • RFC/RFT: gpuisp: Multipass with speed optimisations on top
Related show

Commit Message

Bryan O'Donoghue June 18, 2026, 12:22 p.m. UTC
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
---
 .../software_isp/gpu_pipeline_shader_pass.cpp | 74 +++++++++++++++++
 .../software_isp/gpu_pipeline_shader_pass.h   | 83 +++++++++++++++++++
 src/libcamera/software_isp/meson.build        |  1 +
 3 files changed, 158 insertions(+)
 create mode 100644 src/libcamera/software_isp/gpu_pipeline_shader_pass.cpp
 create mode 100644 src/libcamera/software_isp/gpu_pipeline_shader_pass.h

Patch
diff mbox series

diff --git a/src/libcamera/software_isp/gpu_pipeline_shader_pass.cpp b/src/libcamera/software_isp/gpu_pipeline_shader_pass.cpp
new file mode 100644
index 000000000..669a1c1b6
--- /dev/null
+++ b/src/libcamera/software_isp/gpu_pipeline_shader_pass.cpp
@@ -0,0 +1,74 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026, Linaro Ltd
+ *
+ * Simple software ISP implementation
+ */
+
+#include <cmath>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/thread.h>
+#include <libcamera/base/utils.h>
+
+#include <libcamera/controls.h>
+#include <libcamera/formats.h>
+#include <libcamera/stream.h>
+
+#include "libcamera/internal/framebuffer.h"
+#include "libcamera/internal/ipa_manager.h"
+#include "libcamera/internal/software_isp/debayer_params.h"
+
+#include "gpu_pipeline_shader_pass.h"
+
+/**
+ * \file software_isp.cpp
+ * \brief Simple software ISP implementation
+ */
+
+namespace libcamera {
+
+LOG_DEFINE_CATEGORY(GpuShaderPass)
+
+int GpuIspShaderPass::process(eGLImage &eglImageIn, eGLImage &eglImageOut, uint32_t width, uint32_t height, const DebayerParams &params)
+{
+	/* Switch to the output framebuffer */
+	egl_.useProgram(programId_);
+	egl_.attachTextureToFBO(eglImageOut);
+
+	setShaderVariableValues(params, eglImageIn);
+	glViewport(0, 0, width, height);
+	glClear(GL_COLOR_BUFFER_BIT);
+	glDrawArrays(GL_TRIANGLE_FAN, 0, DEBAYER_OPENGL_COORDS);
+
+	GLenum err = glGetError();
+	if (err != GL_NO_ERROR) {
+		LOG(GpuShaderPass, Error) << "Drawing scene fail " << err;
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+int GpuIspShaderPass::start()
+{
+	return 0;
+}
+
+void GpuIspShaderPass::stop()
+{
+	if (programId_)
+		glDeleteProgram(programId_);
+}
+
+void GpuIspShaderPass::configure(const struct PassConfig &passInputCfg, const struct PassConfig &passOutputCfg)
+{
+	passInputCfg_ = passInputCfg;
+	passOutputCfg_ = passOutputCfg;
+}
+
+}
diff --git a/src/libcamera/software_isp/gpu_pipeline_shader_pass.h b/src/libcamera/software_isp/gpu_pipeline_shader_pass.h
new file mode 100644
index 000000000..d4d4cf34d
--- /dev/null
+++ b/src/libcamera/software_isp/gpu_pipeline_shader_pass.h
@@ -0,0 +1,83 @@ 
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * Copyright (C) 2026, Linaro Ltd
+ *
+ * Authors:
+ * Bryan O'Donoghue <bryan.odonoghue@linaro.org>
+ *
+ * GpuIspIspShaderPass base class
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <libcamera/base/log.h>
+#include <libcamera/base/object.h>
+#include <libcamera/base/signal.h>
+
+#include <libcamera/geometry.h>
+#include <libcamera/stream.h>
+
+#include "libcamera/internal/egl.h"
+#include "libcamera/internal/software_isp/debayer_params.h"
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES3/gl32.h>
+
+#include "../glsl_shaders.h"
+
+namespace libcamera {
+
+#define DEBAYER_OPENGL_COORDS 4
+
+class FrameBuffer;
+
+struct PassConfig {
+	Size size;
+	unsigned int stride;
+	PixelFormat format;
+	Rectangle window;
+};
+
+class GpuIspShaderPass : public Object
+{
+public:
+	GpuIspShaderPass(eGL& egl) : egl_(egl) {}
+	~GpuIspShaderPass() {}
+
+	virtual int process(eGLImage &eglImageIn, eGLImage &eglImageOut, uint32_t width, uint32_t height, const DebayerParams &params);
+	virtual int start();
+	virtual void stop();
+	virtual void configure(const struct PassConfig &passInputCfg, const struct PassConfig &passOutputCfg);
+	virtual int initShaders(PixelFormat inputFormat, PixelFormat outputFormat) = 0;
+	virtual int getShaderVariableLocations(void) = 0;
+	virtual void setShaderVariableValues(const DebayerParams &params, eGLImage &eglImageIn) = 0;
+	virtual const char *name() const { return "GpuIspShaderPass"; }
+
+	unsigned int getBytesPerPixel() { return bytesPerPixel_; };
+
+	/* glFormat_ is a special case we are moving to one shader which will use GL_R
+	 * so rather than do a hack make ShaderPasses do the Textrue allocation and thus have
+	 * access to glFormat_. Make glFormat_ available to the upper level class.
+	 * This variabile will be dropped at the end of the series anyway.
+	 */
+	GLint glFormat_;
+
+protected:
+	eGL& egl_;
+
+	/* Shader calculates this getter provides ability to interrogate if needed */
+	unsigned int bytesPerPixel_;
+
+	/* Shader program identifiers */
+	GLuint vertexShaderId_ = 0;
+	GLuint fragmentShaderId_ = 0;
+	GLuint programId_ = 0;
+
+	struct PassConfig passInputCfg_;
+	struct PassConfig passOutputCfg_;
+};
+
+} /* namespace libcamera */
diff --git a/src/libcamera/software_isp/meson.build b/src/libcamera/software_isp/meson.build
index 51cc6ac3e..f8bce5203 100644
--- a/src/libcamera/software_isp/meson.build
+++ b/src/libcamera/software_isp/meson.build
@@ -32,6 +32,7 @@  if mesa_works
     libcamera_internal_sources += files([
         '../egl.cpp',
         'software_isp_pipeline_gpu.cpp',
+        'gpu_pipeline_shader_pass.cpp',
     ])
     libcamera_deps += [
         libegl,