Patch Detail
Show a patch.
GET /api/patches/26946/?format=api
{ "id": 26946, "url": "https://patchwork.libcamera.org/api/patches/26946/?format=api", "web_url": "https://patchwork.libcamera.org/patch/26946/", "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": "<20260618122245.946138-14-bryan.odonoghue@linaro.org>", "date": "2026-06-18T12:22:26", "name": "[13/30] libcamera: shaders: bayer_glr16_to_rgba.frag: Use bilinear filtering", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "8db8e8ca37e91591be1df616b62b770035c7cb4b", "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/26946/mbox/", "series": [ { "id": 6005, "url": "https://patchwork.libcamera.org/api/series/6005/?format=api", "web_url": "https://patchwork.libcamera.org/project/libcamera/list/?series=6005", "date": "2026-06-18T12:22:13", "name": "RFC/RFT: gpuisp: Multipass with speed optimisations on top", "version": 1, "mbox": "https://patchwork.libcamera.org/series/6005/mbox/" } ], "comments": "https://patchwork.libcamera.org/api/patches/26946/comments/", "check": "pending", "checks": "https://patchwork.libcamera.org/api/patches/26946/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 09728BF415\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 18 Jun 2026 12:23:25 +0000 (UTC)", "from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6983F656C7;\n\tThu, 18 Jun 2026 14:23:24 +0200 (CEST)", "from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com\n\t[IPv6:2a00:1450:4864:20::32a])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 98D1C62B2B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Jun 2026 14:23:07 +0200 (CEST)", "by mail-wm1-x32a.google.com with SMTP id\n\t5b1f17b1804b1-490b613a17bso6482045e9.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 18 Jun 2026 05:23:07 -0700 (PDT)", "from inspiron14p-linux ([109.76.144.236])\n\tby smtp.gmail.com with ESMTPSA id\n\t5b1f17b1804b1-4922fa3a4easm275198015e9.3.2026.06.18.05.23.06\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tThu, 18 Jun 2026 05:23:06 -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=\"osAukbaX\"; dkim-atps=neutral", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=linaro.org; s=google; t=1781785387; x=1782390187;\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=oHBRpAaxg79VoY7KRUqI2QqDEabR3Qd+XLpjHZnpia4=;\n\tb=osAukbaXFwPLDJRWjC/C1Vm8RQpGMY5Er3HZNocTuRT2FeRre11mv4M3WpFgwITupD\n\t7JytcX2lCo05Fyv96EWKpjY1RjqxaYL4xmd9EZq2BzYgnWip2R8YfGI0V05tsz4Pk/wG\n\t5dHZB2ONugEWmxI8GYwKD/3tJSIa2fBSpmYHBbP1rNrh8dEBvSdUm5NfpD/vqVgVTiaV\n\t7z43ns0n5IxkKc5r668KAGrJh3aCyCu39vEEpPuRIifyC+kkznkch4R6YRocN3aywNGR\n\tsgdvX+Cvw4RkUKdj8zJ0Dm0WEsRACS0M3cKEYhP+qTDtta1/3jzhY8inOYPGwekKTNov\n\tuEUg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20251104; t=1781785387; x=1782390187;\n\th=content-transfer-encoding:mime-version:references:in-reply-to\n\t:message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n\t:to:cc:subject:date:message-id:reply-to;\n\tbh=oHBRpAaxg79VoY7KRUqI2QqDEabR3Qd+XLpjHZnpia4=;\n\tb=Y+8rHuOhAfDswLtcBFrtUzO3Fkcsi8/vx1G5DOBExi1R8K27SitNg+gBJZU/J3VS+a\n\tk3qJgHTwrz8amDZZi1AUO2y8ERuhL/ka0NJkbnJyZYHgxShhLvz1eOfIWWEIZCP5xE/X\n\tlGVyYRuRVIUmQu9Km583uZ6Vts5IL4M2UuLf2ormo9E4wncNw2RnbI9eONDhqBqb2XXA\n\tlOyNcKvaU5Fm4YnwpaPsc6KbDYKCpKq+1ODAESqC0kzqvVyw5Cfq49kkhEIFoyxlvKpF\n\tADWhnPJbKn1/QoXVjTiLvKoz3q57xjHncrYeKDIXOZ9+yugaYOjjSsjMZopG1li1D8J4\n\tviYg==", "X-Gm-Message-State": "AOJu0YyhFYHq0vCDwsXxVu8HKnBgOmHzc+Yyq8iXF0z7VHl0O7vVP5K1\n\tEwbYVbw727JHDRwm9TmzopU8xEPpYRU8zCGzbwF7cZ1RzzERsFvjI8Xp2CudI+1H5s8g1/iT1kQ\n\tgoINmlSs=", "X-Gm-Gg": "AfdE7clJSW2MOl/4JKEcbV2HB+lpd1ASKRznhamAXEWBXz3+uIREp8DlwFJDKq1Wmy7\n\tbU1nNKjImrmffYkHSfVoyJIxOFT/ZmJH90Qc+lg3ompCHs95upauog8ZwpEuzwUgekN/u8cAsnk\n\t7j7DOKyzKiAkqIze80pCAQa/ciYyS/ssi9Yrm4itcZ4w/6Ce21KOd9mtHytI7qV78X9JNy19dBA\n\tIuzclMKjjlvVOZKNC9UkqIqZRbnZtrHMdSF9lo3l6wuTF+AGOsgqOZmVvjd5ntdfKKk+iBWRYZ3\n\tx5uZN8U3ujrFG6r0dLmuzmNmzd1y11cJOc1etLdlacrqtHZa2rDYEwHJTW/vFdw6L2XAloSzlrz\n\tvNpB2fUo09rUJarkhDl74ASAzRgwtPg8rGsLpIu25bOfdjquQkwqpm/ssCaqorks4/Pv0hDjkFb\n\t31BpnWthsDv6kFefpHS/c6woYaLbPk", "X-Received": "by 2002:a05:600c:6085:b0:490:ec79:3077 with SMTP id\n\t5b1f17b1804b1-4923a99cee0mr33476775e9.16.1781785387019; \n\tThu, 18 Jun 2026 05:23:07 -0700 (PDT)", "From": "Bryan O'Donoghue <bryan.odonoghue@linaro.org>", "To": "libcamera-devel@lists.libcamera.org", "Cc": "bryan.odonoghue@linaro.org,\n\tpavel@ucw.cz", "Subject": "[PATCH 13/30] libcamera: shaders: bayer_glr16_to_rgba.frag: Use\n\tbilinear filtering", "Date": "Thu, 18 Jun 2026 13:22:26 +0100", "Message-ID": "<20260618122245.946138-14-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", "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": "Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>\n---\n .../shaders/bayer_glr16_to_rgba.frag | 114 +++++++-----------\n 1 file changed, 43 insertions(+), 71 deletions(-)", "diff": "diff --git a/src/libcamera/shaders/bayer_glr16_to_rgba.frag b/src/libcamera/shaders/bayer_glr16_to_rgba.frag\nindex f3883a82b..4a2e5af87 100644\n--- a/src/libcamera/shaders/bayer_glr16_to_rgba.frag\n+++ b/src/libcamera/shaders/bayer_glr16_to_rgba.frag\n@@ -44,81 +44,53 @@ void main(void) {\n \t#define fetch(x, y) texture2D(tex_y, vec2(x, y)).r\n \n \tfloat C = fetch(center.x, center.y); // ( 0, 0)\n-\tconst vec4 kC = vec4( 4.0, 6.0, 5.0, 5.0) / 8.0;\n \n-\t// Determine which of four types of pixels we are on.\n+\t/* Which of the four CFA phases are we on (0 = even). Same as McGuire. */\n \tvec2 alternate = mod(floor(center.zw), 2.0);\n+\tbool even_col = alternate.x < 1.0;\n+\tbool even_row = alternate.y < 1.0;\n \n-\tvec4 Dvec = vec4(\n-\t\tfetch(xCoord[1], yCoord[1]), // (-1,-1)\n-\t\tfetch(xCoord[1], yCoord[2]), // (-1, 1)\n-\t\tfetch(xCoord[2], yCoord[1]), // ( 1,-1)\n-\t\tfetch(xCoord[2], yCoord[2])); // ( 1, 1)\n-\n-\tvec4 PATTERN = (kC.xyz * C).xyzz;\n-\n-\t// Can also be a dot product with (1,1,1,1) on hardware where that is\n-\t// specially optimized.\n-\t// Equivalent to: D = Dvec[0] + Dvec[1] + Dvec[2] + Dvec[3];\n-\tDvec.xy += Dvec.zw;\n-\tDvec.x += Dvec.y;\n-\n-\tvec4 value = vec4(\n-\t\tfetch(center.x, yCoord[0]), // ( 0,-2)\n-\t\tfetch(center.x, yCoord[1]), // ( 0,-1)\n-\t\tfetch(xCoord[0], center.y), // (-2, 0)\n-\t\tfetch(xCoord[1], center.y)); // (-1, 0)\n-\n+\t/*\n+\t * +----+----+----+\n+\t * | D2 | A1 | D3 |\n+\t * +----+----+----+\n+\t * | B0 | C | B1 |\n+\t * +----+----+----+\n+\t * | D0 | A0 | D1 |\n+\t * +----+----+----+\n+\t *\n+\t * patterns.x = (A0 + A1) / 2 vertical neighbours\n+\t * patterns.y = (B0 + B1) / 2 horizontal neighbours\n+\t * patterns.z = (A0+A1+B0+B1) / 4 cross average (green at R/B sites)\n+\t * patterns.w = (D0+D1+D2+D3) / 4 diagonal average (other colour at R/B sites)\n+\t *\n+\t * xCoord[1] = -1, xCoord[2] = +1, yCoord[1] = -1, yCoord[2] = +1\n+\t * (xCoord[0]/[3] and yCoord[0]/[3] = +-2 are unused here; the vertex\n+\t * shader still emits them so the VS is identical to the McGuire path).\n+\t */\n+\tvec4 patterns = vec4(\n+\t\tfetch(center.x, yCoord[1]),\t/* A0: ( 0,-1) */\n+\t\tfetch(xCoord[1], center.y),\t/* B0: (-1, 0) */\n+\t\tfetch(xCoord[1], yCoord[1]),\t/* D0: (-1,-1) */\n+\t\tfetch(xCoord[2], yCoord[1]));\t/* D1: ( 1,-1) */\n \tvec4 temp = vec4(\n-\t\tfetch(center.x, yCoord[3]), // ( 0, 2)\n-\t\tfetch(center.x, yCoord[2]), // ( 0, 1)\n-\t\tfetch(xCoord[3], center.y), // ( 2, 0)\n-\t\tfetch(xCoord[2], center.y)); // ( 1, 0)\n-\n-\t// Even the simplest compilers should be able to constant-fold these to\n-\t// avoid the division.\n-\t// Note that on scalar processors these constants force computation of some\n-\t// identical products twice.\n-\tconst vec4 kA = vec4(-1.0, -1.5, 0.5, -1.0) / 8.0;\n-\tconst vec4 kB = vec4( 2.0, 0.0, 0.0, 4.0) / 8.0;\n-\tconst vec4 kD = vec4( 0.0, 2.0, -1.0, -1.0) / 8.0;\n-\n-\t// Conserve constant registers and take advantage of free swizzle on load\n-\t#define kE (kA.xywz)\n-\t#define kF (kB.xywz)\n-\n-\tvalue += temp;\n-\n-\t// There are five filter patterns (identity, cross, checker,\n-\t// theta, phi). Precompute the terms from all of them and then\n-\t// use swizzles to assign to color channels.\n-\t//\n-\t// Channel Matches\n-\t// x cross (e.g., EE G)\n-\t// y checker (e.g., EE B)\n-\t// z theta (e.g., EO R)\n-\t// w phi (e.g., EO R)\n-\t#define A (value[0])\n-\t#define B (value[1])\n-\t#define D (Dvec.x)\n-\t#define E (value[2])\n-\t#define F (value[3])\n-\n-\t// Avoid zero elements. On a scalar processor this saves two MADDs\n-\t// and it has no effect on a vector processor.\n-\tPATTERN.yzw += (kD.yz * D).xyy;\n-\n-\tPATTERN += (kA.xyz * A).xyzx + (kE.xyw * E).xyxz;\n-\tPATTERN.xw += kB.xw * B;\n-\tPATTERN.xz += kF.xz * F;\n-\n-\trgb = (alternate.y == 0.0) ?\n-\t((alternate.x == 0.0) ?\n-\t\tvec3(C, PATTERN.xy) :\n-\t\tvec3(PATTERN.z, C, PATTERN.w)) :\n-\t((alternate.x == 0.0) ?\n-\t\tvec3(PATTERN.w, C, PATTERN.z) :\n-\t\tvec3(PATTERN.yx, C));\n+\t\tfetch(center.x, yCoord[2]),\t/* A1: ( 0, 1) */\n+\t\tfetch(xCoord[2], center.y),\t/* B1: ( 1, 0) */\n+\t\tfetch(xCoord[2], yCoord[2]),\t/* D3: ( 1, 1) */\n+\t\tfetch(xCoord[1], yCoord[2]));\t/* D2: (-1, 1) */\n+\n+\tpatterns = (patterns + temp) * 0.5;\n+\t\t/* .x=(A0+A1)/2 .y=(B0+B1)/2 .z=(D0+D3)/2 .w=(D1+D2)/2 */\n+\tpatterns.w = (patterns.z + patterns.w) * 0.5;\t/* diagonal avg */\n+\tpatterns.z = (patterns.x + patterns.y) * 0.5;\t/* cross avg */\n+\n+\trgb = even_col ?\n+\t\t(even_row ?\n+\t\t\tvec3(C, patterns.zw) :\n+\t\t\tvec3(patterns.x, C, patterns.y)) :\n+\t\t(even_row ?\n+\t\t\tvec3(patterns.y, C, patterns.x) :\n+\t\t\tvec3(patterns.wz, C));\n \n \t/*\n \t* CCM is a 3x3 in the format\n", "prefixes": [ "13/30" ] }