From patchwork Thu Jun 18 12:22:20 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bryan O'Donoghue X-Patchwork-Id: 26939 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 5F770C328C for ; Thu, 18 Jun 2026 12:23:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id BDD6363282; Thu, 18 Jun 2026 14:23:13 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=linaro.org header.i=@linaro.org header.b="ihEb2XJ1"; dkim-atps=neutral Received: from mail-wm1-x331.google.com (mail-wm1-x331.google.com [IPv6:2a00:1450:4864:20::331]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 21716629A8 for ; Thu, 18 Jun 2026 14:23:03 +0200 (CEST) Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-490a76757e5so5337325e9.2 for ; Thu, 18 Jun 2026 05:23:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1781785383; x=1782390183; darn=lists.libcamera.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=VB0s4jG0bcGQ61Eh7lGd1mDOIM5NsnJDGJohBvZSWks=; b=ihEb2XJ1Wy75pBV8OLmM7xQKROslUCHR6mguTV4pgzfi+d6JOcfJBU0Y0D9T2NyAgE 2Ip+a0Saq5j1Xku2GnVaNKqlNVwpG03WCssNKTVESnYurRNBXo7pntJG97F8za1d6ow7 fOO9zj7wCWgmrmtje2qsXPwHkwVUB0Ak7Alp2fd2yMYmR0PTjw7ZesDQJuXV+XyqQp0/ iCWu7OXaURM5UfL5TrIv2zc3cq6d14+/pyh0B2NUOCyMPaFtx8ZQD8uPh9dx8/DCvfqg wo9x35wPRvFxADKHfqPw66BepKc90cRSU33NzTMtqWDOIZeIjYZWIklIqdXaMW9ILMlX jAJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781785383; x=1782390183; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=VB0s4jG0bcGQ61Eh7lGd1mDOIM5NsnJDGJohBvZSWks=; b=oX1+okDic/oG2JnrOAdxHSLhQLoCgTybLIiwARaXngEFLAPdVFqCylCzhfWSi1lRKB bgjDllfK2MNjqdOnwqY/5kt9Jgge5VpuRH+1OeoVCRnv5WGjvK/1X+8IlNNFAZvS6wSl NBjch4muEsp3M2WKw1J2vc/R1xV7tpHtBelKE1C4pWCHedO8v6O3mb5IAPmFrynQc/IM ZRY1+L60U+jBnQ7+MDJP3bKMNknOFxWHhJQTo477iBymtl+vEGpCcXOf805pASuVbF0q eMqp0e+WLuqcjFcpBaUkfdEC7n7BRjepR0OTQ3MEBIUqrMWY04YyKTAp8xnqFfFJQv4m C3jw== X-Gm-Message-State: AOJu0YygPpTc+l4ggEZ7p98EuZSMBx89jXaHK/4LuJzObvyixkQDx6CT 8WTLVxPSTSSOZfR+/CptxYe5znZtlA2A/+sZZnxo3LED++3L5gXDSMPdxzz0hZJssNbcvZPdC/b 3KhTumsU= X-Gm-Gg: AfdE7ckvayd1tRoDXyOFi2FBNQRoUVBY/KLX+N0JRcGf827/83vOArm4BPMBFvAcXFv TP5q9le2A+eQ0nUNAZP1bFdIuXWlSSZThNkx9YYyl44S6xKICErkJlfDkuAT6yL2TLm/Bv8WSH6 HeLnB28rOlAFRvf9rAmcRo68FxHQBOAWDWnY/ObQrvLZyRhlmIyxwaEj95XjNgLUywLRnFOPLeh vYcShumhkBXQEcHh79V5lOKe4UM8HjbIkpt1nu5KXfwibLOU2NROzl6llqH/ZT6HrQmowlecASp tDSX3U3EyIQ0JdjbT6gEIZMpsPV8f7LlsB9WVxuocYu1Z2znHFmIqm7N26/Z5qMvRUfLTRUyOhZ 9wjiI+/RHflgQOfyHOqrpqBSw+AlzRUDeXVQqmtqA7SyDY3oGPxjtMg7gxEnUw689zKMlDkw5Kx 0oYrebTdVHOiIdKQM7/6OembkSV7B5 X-Received: by 2002:a05:600c:5394:b0:490:aef9:aa3b with SMTP id 5b1f17b1804b1-4923822b876mr56053925e9.32.1781785382457; Thu, 18 Jun 2026 05:23:02 -0700 (PDT) Received: from inspiron14p-linux ([109.76.144.236]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4922fa3a4easm275198015e9.3.2026.06.18.05.23.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Jun 2026 05:23:02 -0700 (PDT) From: Bryan O'Donoghue To: libcamera-devel@lists.libcamera.org Cc: bryan.odonoghue@linaro.org, pavel@ucw.cz Subject: [PATCH 07/30] libcamera: software_isp: gpu: Switch to using GpuIspShaderPassDemosiac Date: Thu, 18 Jun 2026 13:22:20 +0100 Message-ID: <20260618122245.946138-8-bryan.odonoghue@linaro.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260618122245.946138-1-bryan.odonoghue@linaro.org> References: <20260618122245.946138-1-bryan.odonoghue@linaro.org> MIME-Version: 1.0 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" Switch to using GpuIspShaderPassDemosiac as the first instance of our multi-pass GPUISP implementation. Subsequent patches will move elements of this leviathan into discreet elements with an objective of eliminating register spill, separation of concerns and de-spaghettification. Code red patches are always best. Signed-off-by: Bryan O'Donoghue --- src/libcamera/egl.cpp | 6 +- .../software_isp_pipeline_gpu.cpp | 325 +----------------- .../software_isp/software_isp_pipeline_gpu.h | 41 +-- 3 files changed, 20 insertions(+), 352 deletions(-) diff --git a/src/libcamera/egl.cpp b/src/libcamera/egl.cpp index 3ea694d7c..4da335a53 100644 --- a/src/libcamera/egl.cpp +++ b/src/libcamera/egl.cpp @@ -153,7 +153,6 @@ int eGL::attachTextureToFBO(eGLImage &eglImage) int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output) { EGLint drm_format; - int ret; ASSERT(tid_ == Thread::currentId()); @@ -213,10 +212,7 @@ int eGL::createDMABufTexture2D(eGLImage &eglImage, int fd, bool output) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (output) - ret = attachTextureToFBO(eglImage); - - return ret; + return 0; } /** diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp index 6f988d672..6f329cf40 100644 --- a/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp +++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.cpp @@ -41,7 +41,7 @@ namespace libcamera { * \param[in] cm The camera manager */ SoftwareIspPipelineGpu::SoftwareIspPipelineGpu(std::unique_ptr stats, const CameraManager &cm) - : SoftwareIspPipeline(cm), stats_(std::move(stats)) + : SoftwareIspPipeline(cm), stats_(std::move(stats)), gpuIspShaderPassDemosiac_(egl_) { } @@ -109,186 +109,13 @@ int SoftwareIspPipelineGpu::getOutputConfig(PixelFormat outputFormat, DebayerOut return -EINVAL; } -int SoftwareIspPipelineGpu::getShaderVariableLocations(void) -{ - attributeVertex_ = glGetAttribLocation(programId_, "vertexIn"); - attributeTexture_ = glGetAttribLocation(programId_, "textureIn"); - - textureUniformBayerDataIn_ = glGetUniformLocation(programId_, "tex_y"); - ccmUniformDataIn_ = glGetUniformLocation(programId_, "ccm"); - blackLevelUniformDataIn_ = glGetUniformLocation(programId_, "blacklevel"); - gammaUniformDataIn_ = glGetUniformLocation(programId_, "gamma"); - contrastExpUniformDataIn_ = glGetUniformLocation(programId_, "contrastExp"); - - textureUniformStep_ = glGetUniformLocation(programId_, "tex_step"); - textureUniformSize_ = glGetUniformLocation(programId_, "tex_size"); - textureUniformStrideFactor_ = glGetUniformLocation(programId_, "stride_factor"); - textureUniformBayerFirstRed_ = glGetUniformLocation(programId_, "tex_bayer_first_red"); - textureUniformProjMatrix_ = glGetUniformLocation(programId_, "proj_matrix"); - - LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ - << " tex_y " << textureUniformBayerDataIn_ - << " ccm " << ccmUniformDataIn_ - << " blacklevel " << blackLevelUniformDataIn_ - << " gamma " << gammaUniformDataIn_ - << " contrastExp " << contrastExpUniformDataIn_ - << " tex_step " << textureUniformStep_ - << " tex_size " << textureUniformSize_ - << " stride_factor " << textureUniformStrideFactor_ - << " tex_bayer_first_red " << textureUniformBayerFirstRed_ - << " proj_matrix " << textureUniformProjMatrix_; - return 0; -} - int SoftwareIspPipelineGpu::initBayerShaders(PixelFormat inputFormat, PixelFormat outputFormat) { - std::vector shaderEnv; - unsigned int fragmentShaderDataLen = 0; - const unsigned char *fragmentShaderData = 0; - unsigned int vertexShaderDataLen = 0; - const unsigned char *vertexShaderData = 0; - GLenum err; - - /* Target gles 100 glsl requires "#version x" as first directive in shader */ - egl_.pushEnv(shaderEnv, "#version 100"); - - /* Specify GL_OES_EGL_image_external */ - egl_.pushEnv(shaderEnv, "#extension GL_OES_EGL_image_external: enable"); - - /* - * Tell shaders how to re-order output taking account of how the pixels - * are actually stored by EGL. - */ - switch (outputFormat) { - case formats::ARGB8888: - case formats::XRGB8888: - break; - case formats::ABGR8888: - case formats::XBGR8888: - egl_.pushEnv(shaderEnv, "#define SWAP_BLUE"); - break; - default: - LOG(Debayer, Error) << "Unsupported output format"; - return -EINVAL; - } - - /* Pixel location parameters */ - glFormat_ = GL_LUMINANCE; - bytesPerPixel_ = 1; - shaderStridePixels_ = inputConfig_.stride; - - switch (inputFormat) { - case libcamera::formats::SBGGR8: - case libcamera::formats::SBGGR10_CSI2P: - case libcamera::formats::SBGGR12_CSI2P: - firstRed_x_ = 1.0; - firstRed_y_ = 1.0; - break; - case libcamera::formats::SGBRG8: - case libcamera::formats::SGBRG10_CSI2P: - case libcamera::formats::SGBRG12_CSI2P: - firstRed_x_ = 0.0; - firstRed_y_ = 1.0; - break; - case libcamera::formats::SGRBG8: - case libcamera::formats::SGRBG10_CSI2P: - case libcamera::formats::SGRBG12_CSI2P: - firstRed_x_ = 1.0; - firstRed_y_ = 0.0; - break; - case libcamera::formats::SRGGB8: - case libcamera::formats::SRGGB10_CSI2P: - case libcamera::formats::SRGGB12_CSI2P: - firstRed_x_ = 0.0; - firstRed_y_ = 0.0; - break; - default: - LOG(Debayer, Error) << "Unsupported input format"; - return -EINVAL; - }; - - /* Shader selection */ - switch (inputFormat) { - case libcamera::formats::SBGGR8: - case libcamera::formats::SGBRG8: - case libcamera::formats::SGRBG8: - case libcamera::formats::SRGGB8: - fragmentShaderData = bayer_unpacked_frag; - fragmentShaderDataLen = bayer_unpacked_frag_len; - vertexShaderData = bayer_unpacked_vert; - vertexShaderDataLen = bayer_unpacked_vert_len; - break; - case libcamera::formats::SBGGR10_CSI2P: - case libcamera::formats::SGBRG10_CSI2P: - case libcamera::formats::SGRBG10_CSI2P: - case libcamera::formats::SRGGB10_CSI2P: - egl_.pushEnv(shaderEnv, "#define RAW10P"); - if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { - fragmentShaderData = bayer_unpacked_frag; - fragmentShaderDataLen = bayer_unpacked_frag_len; - vertexShaderData = bayer_unpacked_vert; - vertexShaderDataLen = bayer_unpacked_vert_len; - glFormat_ = GL_RG; - bytesPerPixel_ = 2; - } else { - fragmentShaderData = bayer_1x_packed_frag; - fragmentShaderDataLen = bayer_1x_packed_frag_len; - vertexShaderData = identity_vert; - vertexShaderDataLen = identity_vert_len; - shaderStridePixels_ = width_; - } - break; - case libcamera::formats::SBGGR12_CSI2P: - case libcamera::formats::SGBRG12_CSI2P: - case libcamera::formats::SGRBG12_CSI2P: - case libcamera::formats::SRGGB12_CSI2P: - egl_.pushEnv(shaderEnv, "#define RAW12P"); - if (BayerFormat::fromPixelFormat(inputFormat).packing == BayerFormat::Packing::None) { - fragmentShaderData = bayer_unpacked_frag; - fragmentShaderDataLen = bayer_unpacked_frag_len; - vertexShaderData = bayer_unpacked_vert; - vertexShaderDataLen = bayer_unpacked_vert_len; - glFormat_ = GL_RG; - bytesPerPixel_ = 2; - } else { - fragmentShaderData = bayer_1x_packed_frag; - fragmentShaderDataLen = bayer_1x_packed_frag_len; - vertexShaderData = identity_vert; - vertexShaderDataLen = identity_vert_len; - shaderStridePixels_ = width_; - } - break; - }; - - if (egl_.compileVertexShader(vertexShaderId_, vertexShaderData, vertexShaderDataLen, shaderEnv)) { - LOG(Debayer, Error) << "Compile vertex shader fail"; - return -ENODEV; - } - utils::scope_exit vShaderGuard([&] { glDeleteShader(vertexShaderId_); }); - - if (egl_.compileFragmentShader(fragmentShaderId_, fragmentShaderData, fragmentShaderDataLen, shaderEnv)) { - LOG(Debayer, Error) << "Compile fragment shader fail"; - return -ENODEV; - } - utils::scope_exit fShaderGuard([&] { glDeleteShader(fragmentShaderId_); }); + int ret; - if (egl_.linkProgram(programId_, vertexShaderId_, fragmentShaderId_)) { - LOG(Debayer, Error) << "Linking program fail"; - return -ENODEV; - } - - egl_.dumpShaderSource(vertexShaderId_); - egl_.dumpShaderSource(fragmentShaderId_); - - /* Ensure we set the programId_ */ - egl_.useProgram(programId_); - err = glGetError(); - if (err != GL_NO_ERROR) { - LOG(Debayer, Error) << "Use program error " << err; - return -ENODEV; - } + ret = gpuIspShaderPassDemosiac_.initShaders(inputFormat, outputFormat); - return getShaderVariableLocations(); + return ret; } int SoftwareIspPipelineGpu::configure(const StreamConfiguration &inputCfg, @@ -351,6 +178,12 @@ int SoftwareIspPipelineGpu::configure(const StreamConfiguration &inputCfg, */ stats_->setWindow(Rectangle(window_.size())); + /* Configure for one pass */ + PassConfig rawSensorIn = { inputCfg.size, inputConfig_.stride, inputPixelFormat_, window_ }; + PassConfig rgbaOut = { outputCfg.size, outputConfig_.stride, outputPixelFormat_, Rectangle(outputSize_) }; + + gpuIspShaderPassDemosiac_.configure(rawSensorIn, rgbaOut); + return 0; } @@ -388,132 +221,10 @@ SoftwareIspPipelineGpu::strideAndFrameSize(const PixelFormat &outputFormat, cons return std::make_tuple(stride, stride * size.height); } -void SoftwareIspPipelineGpu::setShaderVariableValues(const DebayerParams ¶ms) -{ - /* - * Raw Bayer 8-bit, and packed raw Bayer 10-bit/12-bit formats - * are stored in a GL_LUMINANCE texture. The texture width is - * equal to the stride. - */ - GLfloat firstRed[] = { firstRed_x_, firstRed_y_ }; - GLfloat imgSize[] = { (GLfloat)width_, - (GLfloat)height_ }; - GLfloat Step[] = { static_cast(bytesPerPixel_) / (inputConfig_.stride - 1), - 1.0f / (height_ - 1) }; - GLfloat Stride = (GLfloat)width_ / (shaderStridePixels_ / bytesPerPixel_); - /* - * Scale input to output size, keeping the aspect ratio and preferring - * cropping over black bars. - */ - GLfloat scale = std::max((GLfloat)window_.width / width_, - (GLfloat)window_.height / height_); - GLfloat trans = -(1.0f - scale); - GLfloat projMatrix[] = { - scale, 0, 0, 0, - 0, scale, 0, 0, - 0, 0, 1, 0, - trans, trans, 0, 1 - }; - /* Static const coordinates */ - static const GLfloat vcoordinates[4][2] = { - { -1.0f, -1.0f }, - { -1.0f, +1.0f }, - { +1.0f, +1.0f }, - { +1.0f, -1.0f }, - }; - static const GLfloat tcoordinates[4][2] = { - { 0.0f, 0.0f }, - { 0.0f, 1.0f }, - { 1.0f, 1.0f }, - { 1.0f, 0.0f }, - }; - - /* vertexIn - bayer_8.vert */ - glEnableVertexAttribArray(attributeVertex_); - glVertexAttribPointer(attributeVertex_, 2, GL_FLOAT, GL_TRUE, - 2 * sizeof(GLfloat), vcoordinates); - - /* textureIn - bayer_8.vert */ - glEnableVertexAttribArray(attributeTexture_); - glVertexAttribPointer(attributeTexture_, 2, GL_FLOAT, GL_TRUE, - 2 * sizeof(GLfloat), tcoordinates); - - /* - * Set the sampler2D to the respective texture unit for each texutre - * To simultaneously sample multiple textures we need to use multiple - * texture units - */ - glUniform1i(textureUniformBayerDataIn_, eglImageBayerIn_->texture_unit_uniform_id_); - - /* - * These values are: - * firstRed = tex_bayer_first_red - bayer_8.vert - * imgSize = tex_size - bayer_8.vert - * step = tex_step - bayer_8.vert - * Stride = stride_factor identity.vert - * textureUniformProjMatri = No scaling - */ - glUniform2fv(textureUniformBayerFirstRed_, 1, firstRed); - glUniform2fv(textureUniformSize_, 1, imgSize); - glUniform2fv(textureUniformStep_, 1, Step); - glUniform1f(textureUniformStrideFactor_, Stride); - glUniformMatrix4fv(textureUniformProjMatrix_, 1, GL_FALSE, projMatrix); - - LOG(Debayer, Debug) << "vertexIn " << attributeVertex_ << " textureIn " << attributeTexture_ - << " tex_y " << textureUniformBayerDataIn_ - << " tex_step " << textureUniformStep_ - << " tex_size " << textureUniformSize_ - << " stride_factor " << textureUniformStrideFactor_ - << " tex_bayer_first_red " << textureUniformBayerFirstRed_; - - LOG(Debayer, Debug) << "textureUniformY_ = 0 " - << " firstRed.x " << firstRed[0] - << " firstRed.y " << firstRed[1] - << " textureUniformSize_.width " << imgSize[0] - << " textureUniformSize_.height " << imgSize[1] - << " textureUniformStep_.x " << Step[0] - << " textureUniformStep_.y " << Step[1] - << " textureUniformStrideFactor_ " << Stride - << " textureUniformProjMatrix_ " << textureUniformProjMatrix_; - - GLfloat ccm[9] = { - params.combinedMatrix[0][0], - params.combinedMatrix[0][1], - params.combinedMatrix[0][2], - params.combinedMatrix[1][0], - params.combinedMatrix[1][1], - params.combinedMatrix[1][2], - params.combinedMatrix[2][0], - params.combinedMatrix[2][1], - params.combinedMatrix[2][2], - }; - glUniformMatrix3fv(ccmUniformDataIn_, 1, GL_FALSE, ccm); - LOG(Debayer, Debug) << " ccmUniformDataIn_ " << ccmUniformDataIn_ << " data " << params.combinedMatrix; - - /* - * 0 = Red, 1 = Green, 2 = Blue - */ - glUniform3f(blackLevelUniformDataIn_, params.blackLevel[0], params.blackLevel[1], params.blackLevel[2]); - LOG(Debayer, Debug) << " blackLevelUniformDataIn_ " << blackLevelUniformDataIn_ << " data " << params.blackLevel; - - /* - * Gamma - */ - glUniform1f(gammaUniformDataIn_, params.gamma); - LOG(Debayer, Debug) << " gammaUniformDataIn_ " << gammaUniformDataIn_ << " data " << params.gamma; - - /* - * Contrast - */ - glUniform1f(contrastExpUniformDataIn_, params.contrastExp); - LOG(Debayer, Debug) << " contrastExpUniformDataIn_ " << contrastExpUniformDataIn_ << " data " << params.contrastExp; - - return; -} - int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *inMapped, std::optional *inDmaSyncer) { bool dmabuf_import_succeeded = false; + int pipelineResult = 0; /* eGL context switch */ egl_.makeCurrent(); @@ -540,20 +251,17 @@ int SoftwareIspPipelineGpu::processGPU(FrameBuffer *input, FrameBuffer *output, /* Generate the output render framebuffer as render to texture */ egl_.createOutputDMABufTexture2D(*eglImageRGBAOut_, output->planes()[0].fd.get()); - setShaderVariableValues(params); - glViewport(0, 0, width_, height_); - glClear(GL_COLOR_BUFFER_BIT); - glDrawArrays(GL_TRIANGLE_FAN, 0, DEBAYER_OPENGL_COORDS); + pipelineResult = gpuIspShaderPassDemosiac_.process(*eglImageBayerIn_, *eglImageRGBAOut_, width_, height_, params); GLenum err = glGetError(); if (err != GL_NO_ERROR) { LOG(eGL, Error) << "Drawing scene fail " << err; - return -ENODEV; + pipelineResult = -ENODEV; } else { egl_.flushOutput(); } - return 0; + return pipelineResult; } void SoftwareIspPipelineGpu::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms) @@ -623,7 +331,7 @@ int SoftwareIspPipelineGpu::start() return -EINVAL; /* Raw bayer input as texture */ - eglImageBayerIn_ = std::make_unique(glFormat_, inputConfig_.stride / bytesPerPixel_, height_, inputConfig_.stride, GL_TEXTURE0, 0); + eglImageBayerIn_ = std::make_unique(gpuIspShaderPassDemosiac_.glFormat_, inputConfig_.stride / gpuIspShaderPassDemosiac_.getBytesPerPixel(), height_, inputConfig_.stride, GL_TEXTURE0, 0); /* Texture we will render to */ eglImageRGBAOut_ = std::make_unique(GL_RGBA, outputSize_.width, outputSize_.height, outputConfig_.stride, GL_TEXTURE1, 1); @@ -636,8 +344,7 @@ void SoftwareIspPipelineGpu::stop() eglImageRGBAOut_.reset(); eglImageBayerIn_.reset(); - if (programId_) - glDeleteProgram(programId_); + gpuIspShaderPassDemosiac_.stop(); } SizeRange SoftwareIspPipelineGpu::sizes(PixelFormat inputFormat, const Size &inputSize) diff --git a/src/libcamera/software_isp/software_isp_pipeline_gpu.h b/src/libcamera/software_isp/software_isp_pipeline_gpu.h index f0515d889..6a9df2f04 100644 --- a/src/libcamera/software_isp/software_isp_pipeline_gpu.h +++ b/src/libcamera/software_isp/software_isp_pipeline_gpu.h @@ -23,16 +23,12 @@ #include "libcamera/internal/software_isp/benchmark.h" #include "libcamera/internal/software_isp/swstats_cpu.h" -#include -#include -#include - #include "software_isp_pipeline.h" +#include "gpu_pipeline_shader_pass_demosiac.h" namespace libcamera { #define DEBAYER_EGL_MIN_SIMPLE_RGB_GAIN_TEXTURE_UNITS 4 -#define DEBAYER_OPENGL_COORDS 4 class CameraManager; @@ -68,48 +64,17 @@ private: int processGPU(FrameBuffer *input, FrameBuffer *output, const DebayerParams ¶ms, std::optional *mappedInputBuffer, std::optional *inputBufferDmaSyncer); void configureTexture(GLuint &texture); - /* Shader program identifiers */ - GLuint vertexShaderId_ = 0; - GLuint fragmentShaderId_ = 0; - GLuint programId_ = 0; - /* Pointer to object representing input texture */ std::unique_ptr eglImageBayerIn_; std::unique_ptr eglImageRGBAOut_; - /* Shader parameters */ - float firstRed_x_; - float firstRed_y_; - GLint attributeVertex_; - GLint attributeTexture_; - GLint textureUniformStep_; - GLint textureUniformSize_; - GLint textureUniformStrideFactor_; - GLint textureUniformBayerFirstRed_; - GLint textureUniformProjMatrix_; - - GLint textureUniformBayerDataIn_; - - /* Represent per-frame CCM as a uniform vector of floats 3 x 3 */ - GLint ccmUniformDataIn_; - - /* Black Level compensation */ - GLint blackLevelUniformDataIn_; - - /* Gamma */ - GLint gammaUniformDataIn_; - - /* Contrast */ - GLint contrastExpUniformDataIn_; - Rectangle window_; std::unique_ptr stats_; eGL egl_; uint32_t width_; uint32_t height_; - GLint glFormat_; - unsigned int bytesPerPixel_; - uint32_t shaderStridePixels_; + + GpuIspShaderPassDemosiac gpuIspShaderPassDemosiac_; }; } /* namespace libcamera */