Patch Detail
Show a patch.
GET /api/patches/23233/?format=api
{ "id": 23233, "url": "https://patchwork.libcamera.org/api/patches/23233/?format=api", "web_url": "https://patchwork.libcamera.org/patch/23233/", "project": { "id": 1, "url": "https://patchwork.libcamera.org/api/projects/1/?format=api", "name": "libcamera", "link_name": "libcamera", "list_id": "libcamera_core", "list_email": "libcamera-devel@lists.libcamera.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20250422215920.4297-21-bryan.odonoghue@linaro.org>", "date": "2025-04-22T21:59:13", "name": "[20/27] libcamera: software_isp: debayer_egl: Extend logic to enable application of softISP RGB debayer params", "commit_ref": null, "pull_url": null, "state": "rfc", "archived": false, "hash": "4628a2610212175bc676a1e332ef89d774ac7841", "submitter": { "id": 175, "url": "https://patchwork.libcamera.org/api/people/175/?format=api", "name": "Bryan O'Donoghue", "email": "bryan.odonoghue@linaro.org" }, "delegate": null, "mbox": "https://patchwork.libcamera.org/patch/23233/mbox/", "series": [ { "id": 5142, "url": "https://patchwork.libcamera.org/api/series/5142/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=5142", "date": "2025-04-22T21:58:53", "name": "RFC: Add in a eGL based GPUISP in libcamera", "version": 1, "mbox": "https://patchwork.libcamera.org/series/5142/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/23233/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/23233/checks/", "tags": {}, "headers": { "Return-Path": "<libcamera-devel-bounces@lists.libcamera.org>", "X-Original-To": "parsemail@patchwork.libcamera.org", "Delivered-To": "parsemail@patchwork.libcamera.org", "Received": [ "from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 2BCF5C331E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tTue, 22 Apr 2025 22:00:00 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6532668AD9;\n\tTue, 22 Apr 2025 23:59:59 +0200 (CEST)", "from mail-wm1-x333.google.com (mail-wm1-x333.google.com\n\t[IPv6:2a00:1450:4864:20::333])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 51F6068B3E\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Apr 2025 23:59:43 +0200 (CEST)", "by mail-wm1-x333.google.com with SMTP id\n\t5b1f17b1804b1-43cebe06e9eso47639735e9.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 22 Apr 2025 14:59:43 -0700 (PDT)", "from inspiron14p-linux.ht.home (188-141-3-146.dynamic.upc.ie.\n\t[188.141.3.146]) by smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-44092d2eccesm2726615e9.20.2025.04.22.14.59.41\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tTue, 22 Apr 2025 14:59:41 -0700 (PDT)" ], "Authentication-Results": "lancelot.ideasonboard.com; dkim=pass (2048-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"TjMPDZ5P\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=linaro.org; s=google; t=1745359182; x=1745963982;\n\tdarn=lists.libcamera.org; \n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:from:to:cc:subject:date\n\t:message-id:reply-to;\n\tbh=1+V+tT+5bE8QKuoSfA3FLpmNoP41vVB3yUTW2/ZNDdc=;\n\tb=TjMPDZ5PXaCXvZstXbX3j1gZVqW9Uu0PiT5TA9E3MGQDPI8K7Sp+Ekg8NZASAq0Qrt\n\tN5qiX0hnsk6NZ/fTZ87rwzr4fIQ1RN42dkGhpYlBH9aXYNyv3xZszWTN51rZNhMzhAJ1\n\t7RmQN8OjULYhEP35EEmj0M22E3xqunYKeOiJZ0Np7rCmE3Ld9AAptdovEbQfupL/U2mr\n\t+zl60DS3eJZHKFetzEF5VFi5BE6IExMxGX9LkUOn3dDQcjIfMEw1gZSfG+nndY1EFU83\n\tgBGkRtDORj3dDEo6HnJCcfv1GA5JTjHORKYP8jHkmmRqO/abNB59JeZvid7/P2eYCaje\n\tv4ew==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20230601; t=1745359182; x=1745963982;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n\t:subject:date:message-id:reply-to;\n\tbh=1+V+tT+5bE8QKuoSfA3FLpmNoP41vVB3yUTW2/ZNDdc=;\n\tb=ND+I9R8bIv0dUef6uGa9GB80t4l8wQQNpE23DqOEbj0Y21Kez9NO50nXA7uxiHF45D\n\t8smK6ZK/Sh8kxcPk0IfBTP8Wc5L3bHR10fJewHZDwEwADQSkxiJV6Sq0K4I+xzLjXLBm\n\tj9//o703mD/15ncewsAosBxvwt9mILypYww7sVVkDIhL6c9fsNMrjKMaL0Uj3EJVI33g\n\tMFQd7GunVx1khXrl9T8Uja4BEPvPaku58zUpc7GDuL1GIAkc2q9boKoQiE4J5EpJStvf\n\tVs1pdJA/5RlXzzj9MYk1sW0EanI/govfbPxAAGkQJdRyZxR88im53gRJlLTARe56/BHA\n\t/ptw==", "X-Gm-Message-State": "AOJu0Yz1QH5TvyELKgTyIl4rfJIc4EZQ/bXiLcqAyNrKYdn8Xbyzi+FQ\n\tKLBiXhLEMUZPieNlwxc/dXPcCWUXfyznOB81egliwg/KfXNbmI9NzfRl2eePx5YXS0vU1h9NDc6\n\t/LsI=", "X-Gm-Gg": "ASbGncvsAoHZHb8y4RFVFuhS4AQj15g0R9DPT9rFTEXkltLusy4dmW6NjuQ2tCBJ+uP\n\tg75QBP1LvI/YyCBJPsNcatNzbO1K18I4VShiFcbQTNF18HF8ev8OO0jRWCao5lZZ/Jc0xfbeB1+\n\tg0vZTMDyts1D8E4MSRpezc+vnJl187pW/Ld7NC1kwYz2Z/RZnKdQohU3F8JIf1iX5P1Q5/D3fVa\n\tiVbp/ParPbbHO2U6/7IkBOkANwMHv3vjWOEPW9hb4gzNJE/1cT5yEluJ3u8nKQ3d/D4iPtjlqxc\n\tgpANtYpJkpqXyWLxoWeuaGkJeLNLP4HCCr4nS+0Oh9LJQgevb0foU/WIWCIKxYI4lQaOV4KgR/V\n\tzI05yJHZOUFP0v10ySo/s", "X-Google-Smtp-Source": "AGHT+IEOxUWQw6/5ixhOH5WdHssUArvknGU+ztgqIBZDDfyZizCqWDwi+O3kWCLH2Lv2XrJdMg9HIw==", "X-Received": "by 2002:a05:600c:5395:b0:43d:db5:7b1a with SMTP id\n\t5b1f17b1804b1-4406ab96f63mr164481765e9.12.1745359182425; \n\tTue, 22 Apr 2025 14:59:42 -0700 (PDT)", "From": "Bryan O'Donoghue <bryan.odonoghue@linaro.org>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "hdegoede@redhat.com, mzamazal@redhat.com, bryan.odonoghue@linaro.org,\n\tbod.linux@nxsw.ie", "Subject": "[PATCH 20/27] libcamera: software_isp: debayer_egl: Extend logic to\n\tenable application of softISP RGB debayer params", "Date": "Tue, 22 Apr 2025 22:59:13 +0100", "Message-ID": "<20250422215920.4297-21-bryan.odonoghue@linaro.org>", "X-Mailer": "git-send-email 2.49.0", "In-Reply-To": "<20250422215920.4297-1-bryan.odonoghue@linaro.org>", "References": "<20250422215920.4297-1-bryan.odonoghue@linaro.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-BeenThere": "libcamera-devel@lists.libcamera.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "<libcamera-devel.lists.libcamera.org>", "List-Unsubscribe": "<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>", "List-Archive": "<https://lists.libcamera.org/pipermail/libcamera-devel/>", "List-Post": "<mailto:libcamera-devel@lists.libcamera.org>", "List-Help": "<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>", "List-Subscribe": "<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>", "Errors-To": "libcamera-devel-bounces@lists.libcamera.org", "Sender": "\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>" }, "content": "The existing SoftISP calculates RGB gain values as a lookup table of 256\nvalues which shifts for each frame depending on the required correction.\n\nWe can pass the required tables into the debayer shaders as textures, one\ntexture for R, G and B respectively.\n\nThe debayer shader will do its debayer interpolation and then if the\nappropriate define is specified use the calculated R, G and B values as\nindexes into our bayer colour gain table.\n\nTODO:\n\t- Validate the number of available texture units and\n\t bail out if < 4\n\t In reality ~ all hardware has at least 16 units\n\t- Rename the debayer class to something like eglDebayer\n\t to reflect the fact its eGL based.\n\t- Add in the CCM tables too.\n\nSigned-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n---\n src/libcamera/software_isp/debayer_egl.cpp | 74 +++++++++++++++++-----\n src/libcamera/software_isp/debayer_egl.h | 15 +++--\n 2 files changed, 69 insertions(+), 20 deletions(-)", "diff": "diff --git a/src/libcamera/software_isp/debayer_egl.cpp b/src/libcamera/software_isp/debayer_egl.cpp\nindex 008938f8..f02ec8b2 100644\n--- a/src/libcamera/software_isp/debayer_egl.cpp\n+++ b/src/libcamera/software_isp/debayer_egl.cpp\n@@ -26,6 +26,15 @@ DebayerEGL::DebayerEGL(std::unique_ptr<SwStatsCpu> stats)\n \n DebayerEGL::~DebayerEGL()\n {\n+\tif (eglImageBlueLookup_)\n+\t\tdelete eglImageBlueLookup_;\n+\n+\tif (eglImageGreenLookup_)\n+\t\tdelete eglImageGreenLookup_;\n+\n+\tif (eglImageRedLookup_)\n+\t\tdelete eglImageRedLookup_;\n+\n \tif (eglImageBayerIn_)\n \t\tdelete eglImageBayerIn_;\n }\n@@ -87,9 +96,11 @@ int DebayerEGL::getShaderVariableLocations(void)\n \tattributeVertex_ = glGetAttribLocation(programId_, \"vertexIn\");\n \tattributeTexture_ = glGetAttribLocation(programId_, \"textureIn\");\n \n-\ttextureUniformY_ = glGetUniformLocation(programId_, \"tex_y\");\n-\ttextureUniformU_ = glGetUniformLocation(programId_, \"tex_u\");\n-\ttextureUniformV_ = glGetUniformLocation(programId_, \"tex_v\");\n+\ttextureUniformBayerDataIn_ = glGetUniformLocation(programId_, \"tex_y\");\n+\ttextureUniformRedLookupDataIn_ = glGetUniformLocation(programId_, \"red_param\");\n+\ttextureUniformGreenLookupDataIn_ = glGetUniformLocation(programId_, \"green_param\");\n+\ttextureUniformBlueLookupDataIn_ = glGetUniformLocation(programId_, \"blue_param\");\n+\n \ttextureUniformStep_ = glGetUniformLocation(programId_, \"tex_step\");\n \ttextureUniformSize_ = glGetUniformLocation(programId_, \"tex_size\");\n \ttextureUniformStrideFactor_ = glGetUniformLocation(programId_, \"stride_factor\");\n@@ -97,9 +108,10 @@ int DebayerEGL::getShaderVariableLocations(void)\n \ttextureUniformProjMatrix_ = glGetUniformLocation(programId_, \"proj_matrix\");\n \n \tLOG(Debayer, Info) << \"vertexIn \" << attributeVertex_ << \" textureIn \" << attributeTexture_\n-\t\t\t << \" tex_y \" << textureUniformY_\n-\t\t\t << \" tex_u \" << textureUniformU_\n-\t\t\t << \" tex_v \" << textureUniformV_\n+\t\t\t << \" tex_y \" << textureUniformBayerDataIn_\n+\t\t\t << \" red_param \" << textureUniformRedLookupDataIn_\n+\t\t\t << \" red_param \" << textureUniformGreenLookupDataIn_\n+\t\t\t << \" red_param \" << textureUniformBlueLookupDataIn_\n \t\t\t << \" tex_step \" << textureUniformStep_\n \t\t\t << \" tex_size \" << textureUniformSize_\n \t\t\t << \" stride_factor \" << textureUniformStrideFactor_\n@@ -202,6 +214,9 @@ int DebayerEGL::initBayerShaders(PixelFormat inputFormat, PixelFormat outputForm\n \t\tbreak;\n \t};\n \n+\t// Flag to shaders that we have parameter gain tables\n+\tegl_.pushEnv(shaderEnv, \"#define APPLY_BAYER_PARAMETERS\");\n+\n \tif (egl_.compileVertexShader(vertexShaderId_, vertexShaderData, vertexShaderDataLen, shaderEnv))\n \t\tgoto compile_fail;\n \n@@ -285,7 +300,24 @@ int DebayerEGL::configure(const StreamConfiguration &inputCfg,\n \tif (egl_.initEGLContext(&gbmSurface_))\n \t\treturn -ENODEV;\n \n-\teglImageBayerIn_ = new eGLImage(width_, height_, 32);\n+\t// Raw bayer input as texture\n+\teglImageBayerIn_ = new eGLImage(width_, height_, 32, GL_TEXTURE0, 0);\n+\tif (!eglImageBayerIn_)\n+\t\treturn -ENOMEM;\n+\n+\t/// RGB correction tables as 2d textures\n+\t// eGL doesn't support glTexImage2D so we do a little hack with 2D to compensate\n+\teglImageRedLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE1, 1);\n+\tif (!eglImageRedLookup_)\n+\t\treturn -ENOMEM;\n+\n+\teglImageGreenLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE2, 2);\n+\tif (!eglImageGreenLookup_)\n+\t\treturn -ENOMEM;\n+\n+\teglImageBlueLookup_ = new eGLImage(DebayerParams::kRGBLookupSize, 1, 32, GL_TEXTURE3, 3);\n+\tif (!eglImageBlueLookup_)\n+\t\treturn -ENOMEM;\n \n \t// Create a single BO (calling gbm_surface_lock_front_buffer() again before gbm_surface_release_buffer() would create another BO)\n \tif (gbmSurface_.mapSurface())\n@@ -394,7 +426,14 @@ void DebayerEGL::setShaderVariableValues(void)\n \tglVertexAttribPointer(attributeTexture_, 2, GL_FLOAT, GL_TRUE,\n \t\t\t 2 * sizeof(GLfloat), tcoordinates);\n \n-\tglUniform1i(textureUniformY_, 0);\t\t\t\t// tex_y - bayer_8.vert - set for no reason\n+\t// Set the sampler2D to the respective texture unit for each texutre\n+\t// To simultaneously sample multiple textures we need to use multiple\n+\t// texture units\n+\tglUniform1i(textureUniformBayerDataIn_, eglImageBayerIn_->texture_unit_uniform_id_);\n+\tglUniform1i(textureUniformRedLookupDataIn_, eglImageRedLookup_->texture_unit_uniform_id_);\n+\tglUniform1i(textureUniformGreenLookupDataIn_, eglImageGreenLookup_->texture_unit_uniform_id_);\n+\tglUniform1i(textureUniformBlueLookupDataIn_, eglImageBlueLookup_->texture_unit_uniform_id_);\n+\n \tglUniform2fv(textureUniformBayerFirstRed_, 1, firstRed);\t// tex_bayer_first_red - bayer_8.vert\n \tglUniform2fv(textureUniformSize_, 1, imgSize);\t\t\t// tex_size - bayer_8.vert\n \tglUniform2fv(textureUniformStep_, 1, Step);\t\t\t// tex_step - bayer_8.vert\n@@ -403,9 +442,10 @@ void DebayerEGL::setShaderVariableValues(void)\n \t\t\t GL_FALSE, projIdentityMatrix);\t\t// No scaling\n \n \tLOG(Debayer, Debug) << \"vertexIn \" << attributeVertex_ << \" textureIn \" << attributeTexture_\n-\t\t\t << \" tex_y \" << textureUniformY_\n-\t\t\t << \" tex_u \" << textureUniformU_\n-\t\t\t << \" tex_v \" << textureUniformV_\n+\t\t\t << \" tex_y \" << textureUniformBayerDataIn_\n+\t\t\t << \" red_param \" << textureUniformRedLookupDataIn_\n+\t\t\t << \" red_param \" << textureUniformGreenLookupDataIn_\n+\t\t\t << \" red_param \" << textureUniformBlueLookupDataIn_\n \t\t\t << \" tex_step \" << textureUniformStep_\n \t\t\t << \" tex_size \" << textureUniformSize_\n \t\t\t << \" stride_factor \" << textureUniformStrideFactor_\n@@ -423,7 +463,7 @@ void DebayerEGL::setShaderVariableValues(void)\n \treturn;\n }\n \n-void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out)\n+void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, DebayerParams ¶ms)\n {\n \tLOG(Debayer, Debug)\n \t\t<< \"Input height \" << height_\n@@ -433,13 +473,15 @@ void DebayerEGL::debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out)\n \t// eGL context switch\n \tegl_.makeCurrent();\n \n-\t// make texture unit 0 explicit this doesn't really matter probably remove ?\n-\tglActiveTexture(GL_TEXTURE0);\n-\n \t// Greate a standard texture\n \t// we will replace this with the DMA version at some point\n \tegl_.createTexture2D(eglImageBayerIn_, inputConfig_.stride, height_, in.planes()[0].data());\n \n+\t// Populate bayer parameters\n+\tegl_.createTexture2D(eglImageRedLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.red);\n+\tegl_.createTexture2D(eglImageGreenLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.green);\n+\tegl_.createTexture2D(eglImageBlueLookup_, DebayerParams::kRGBLookupSize, 1, ¶ms.blue);\n+\n \t// Setup the scene\n \tsetShaderVariableValues();\n \tglViewport(0, 0, width_, height_);\n@@ -482,7 +524,7 @@ void DebayerEGL::process(uint32_t frame, FrameBuffer *input, FrameBuffer *output\n \t\treturn;\n \t}\n \n-\tdebayerGPU(in, out);\n+\tdebayerGPU(in, out, params);\n \n \tdmaSyncers.clear();\n \ndiff --git a/src/libcamera/software_isp/debayer_egl.h b/src/libcamera/software_isp/debayer_egl.h\nindex 14f6997a..c8a19c3c 100644\n--- a/src/libcamera/software_isp/debayer_egl.h\n+++ b/src/libcamera/software_isp/debayer_egl.h\n@@ -110,7 +110,7 @@ private:\n \tint getShaderVariableLocations();\n \tvoid setShaderVariableValues(void);\n \tvoid configureTexture(GLuint &texture);\n-\tvoid debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out);\n+\tvoid debayerGPU(MappedFrameBuffer &in, MappedFrameBuffer &out, DebayerParams ¶ms);\n \n \t// Shader program identifiers\n \tGLuint vertexShaderId_;\n@@ -125,20 +125,27 @@ private:\n \t// Pointer to object representing input texture\n \teGLImage *eglImageBayerIn_;\n \n+\teGLImage *eglImageRedLookup_;\n+\teGLImage *eglImageGreenLookup_;\n+\teGLImage *eglImageBlueLookup_;\n+\n \t// Shader parameters\n \tfloat firstRed_x_;\n \tfloat firstRed_y_;\n \tGLint attributeVertex_;\n \tGLint attributeTexture_;\n-\tGLint textureUniformY_;\n-\tGLint textureUniformU_;\n-\tGLint textureUniformV_;\n \tGLint textureUniformStep_;\n \tGLint textureUniformSize_;\n \tGLint textureUniformStrideFactor_;\n \tGLint textureUniformBayerFirstRed_;\n \tGLint textureUniformProjMatrix_;\n \n+\t#define DEBAYER_EGL_MIN_TEXTURE_UNITS 4\n+\tGLint textureUniformBayerDataIn_;\n+\tGLint textureUniformRedLookupDataIn_;\n+\tGLint textureUniformGreenLookupDataIn_;\n+\tGLint textureUniformBlueLookupDataIn_;\n+\n \tRectangle window_;\n \tstd::unique_ptr<SwStatsCpu> stats_;\n \teGL egl_;\n", "prefixes": [ "20/27" ] }