Message ID | 20221027135711.24425-1-marcan@marcan.st |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp252878wru; Thu, 27 Oct 2022 07:09:25 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6naQTu/JGMwjTNckXbfEFNdbmykWNfvH5Jei42UmWyd1fYbhOTkXpUy8M4BOyZVJP8r3Sv X-Received: by 2002:a17:90a:480b:b0:213:82b3:1fe7 with SMTP id a11-20020a17090a480b00b0021382b31fe7mr693740pjh.34.1666879765270; Thu, 27 Oct 2022 07:09:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666879765; cv=none; d=google.com; s=arc-20160816; b=AfZhA+ZsEWscWNYVTNRqKcnSHDcrP9fn9ICQxUcrb7bB6h/NLOjqBB6UbUd//LOC+S R9VYGJa0wKWS33FsNl5NxR6ILoA2Aq2Rs6n7yc4vWrz132yFU+Dp8xRakerk3Hk8x4hA sxdn4h0r10a8Z6tjLxDaqDg6sR4wIKsvvtYlTk+NYaxjwGgEcxqTKNDdODfrmI/ykzMA leyo+fD9Y1lg9+85fhQGEsAbHba+qgFAEGNXIOZu/5TMH8juV7aJCX9kg/uU5GaMcblF qJ86oDHhbJs5+3QNN3ZpP/wWTA4qLoyLDF1+ApAg/yTLoYvNBxDmEWS1yhlUNG6yauqq 3W8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=xsGMpkLXAdj2wPjkSXeUlM4n+IRYQEk6poaDN73phn4=; b=xKvkPo/Jc3hTWyW+Dgzu+sM3TH/LNDHpeFWrnEyf8S/8XEN9eBEaQHK7dkFkYV7jUk 8znQ6GP5Zn9TojMETQQrNE6px18/ZFEplwlVGHI4N7EDzXq0Q4SNpOUxgcXVSOpN6SUU Jq38ALpZn9qoKrLog/9wjiR8lFedRfPsFNUeoNGkdL7wbXrHFkJo+G8RCUlFwxD2KgiK iZqLq1perkIsRafF0lSJjxHcteIP3rUyZokAOrPrLzNXI3Kd570FEXrp3l+XXoWICV1b DRZ03xKc+pjAt7J1ZoZJm+Pw4EqDxy5feBkkxy8HiRZcqnzepQN7005ZI6bj61qvlBQc KJCA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marcan.st header.s=default header.b=ww+vPmOG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=marcan.st Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id lx13-20020a17090b4b0d00b002100c234c6dsi7368310pjb.35.2022.10.27.07.09.07; Thu, 27 Oct 2022 07:09:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@marcan.st header.s=default header.b=ww+vPmOG; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=marcan.st Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234417AbiJ0N5X (ORCPT <rfc822;chrisfriedt@gmail.com> + 99 others); Thu, 27 Oct 2022 09:57:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36002 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233701AbiJ0N5W (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 27 Oct 2022 09:57:22 -0400 Received: from mail.marcansoft.com (marcansoft.com [212.63.210.85]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0403118542D; Thu, 27 Oct 2022 06:57:20 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: hector@marcansoft.com) by mail.marcansoft.com (Postfix) with ESMTPSA id E68B73FA55; Thu, 27 Oct 2022 13:57:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=marcan.st; s=default; t=1666879039; bh=TK1fFuny4zxoXEgTLy+wI9CY1SFw6RXNtfSesjtadqU=; h=From:To:Cc:Subject:Date; b=ww+vPmOG62oLzBS2yPE6x7AS+yIRPHjk0TnpYPW4KrokdwFEj7KGJscZ/ESUTyIFy Hg9iiaM81RBNss92uThzw8E9qu8yGyUS8XRbXC48DgoNVbL5SzVWsVbvQvtOWEgm6j ft4XbZ1CfRYZaGMMcivgt6PrBvuwa8zLokgocfrLDNiEjbOQxDR25gwgpsWGyNPdak jAscKJKbFZvho9pAacCczfcfSeyI9FxmfoCM87qZLJ4w+iEHAC8wXh1ZA5qgVuRuO/ PaNKwmIhh9lQ44Uwe0GjNltGn+mQ68tq0FAeCccmqQEBqiTqYnSao5qxk0asvHjr1S GlrEJiwreHJWQ== From: Hector Martin <marcan@marcan.st> To: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Thomas Zimmermann <tzimmermann@suse.de>, David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>, Javier Martinez Canillas <javierm@redhat.com> Cc: Pekka Paalanen <pekka.paalanen@collabora.com>, dri-devel@lists.freedesktop.org, asahi@lists.linux.dev, linux-kernel@vger.kernel.org, Hector Martin <marcan@marcan.st>, stable@vger.kernel.org Subject: [PATCH v2] drm/format-helper: Only advertise supported formats for conversion Date: Thu, 27 Oct 2022 22:57:11 +0900 Message-Id: <20221027135711.24425-1-marcan@marcan.st> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747850116514116785?= X-GMAIL-MSGID: =?utf-8?q?1747850116514116785?= |
Series |
[v2] drm/format-helper: Only advertise supported formats for conversion
|
|
Commit Message
Hector Martin
Oct. 27, 2022, 1:57 p.m. UTC
drm_fb_build_fourcc_list() currently returns all emulated formats
unconditionally as long as the native format is among them, even though
not all combinations have conversion helpers. Although the list is
arguably provided to userspace in precedence order, userspace can pick
something out-of-order (and thus break when it shouldn't), or simply
only support a format that is unsupported (and thus think it can work,
which results in the appearance of a hang as FB blits fail later on,
instead of the initialization error you'd expect in this case).
Add checks to filter the list of emulated formats to only those
supported for conversion to the native format. This presumes that there
is a single native format (only the first is checked, if there are
multiple). Refactoring this API to drop the native list or support it
properly (by returning the appropriate emulated->native mapping table)
is left for a future patch.
The simpledrm driver is left as-is with a full table of emulated
formats. This keeps all currently working conversions available and
drops all the broken ones (i.e. this a strict bugfix patch, adding no
new supported formats nor removing any actually working ones). In order
to avoid proliferation of emulated formats, future drivers should
advertise only XRGB8888 as the sole emulated format (since some
userspace assumes its presence).
This fixes a real user regression where the ?RGB2101010 support commit
started advertising it unconditionally where not supported, and KWin
decided to start to use it over the native format and broke, but also
the fixes the spurious RGB565/RGB888 formats which have been wrongly
unconditionally advertised since the dawn of simpledrm.
Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats")
Fixes: 11e8f5fd223b ("drm: Add simpledrm driver")
Cc: stable@vger.kernel.org
Signed-off-by: Hector Martin <marcan@marcan.st>
---
I'm proposing this alternative approach after a heated discussion on
IRC. I'm out of ideas, if y'all don't like this one you can figure it
out for yourseves :-)
Changes since v1:
This v2 moves all the changes to the helper (so they will apply to
the upcoming ofdrm, though ofdrm also needs to be fixed to trim its
format table to only formats that should be emulated, probably only
XRGB8888, to avoid further proliferating the use of conversions),
and avoids touching more than one file. The API still needs cleanup
as mentioned (supporting more than one native format is fundamentally
broken, since the helper would need to tell the driver *what* native
format to use for *each* emulated format somehow), but all current and
planned users only pass in one native format, so this can (and should)
be fixed later.
Aside: After other IRC discussion, I'm testing nuking the
XRGB2101010 <-> ARGB2101010 advertisement (which does not involve
conversion) by removing those entries from simpledrm in the Asahi Linux
downstream tree. As far as I'm concerned, it can be removed if nobody
complains (by removing those entries from the simpledrm array), if
maintainers are generally okay with removing advertised formats at all.
If so, there might be other opportunities for further trimming the list
non-native formats advertised to userspace.
Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston
on both XRGB2101010 and RGB8888 simpledrm framebuffers.
drivers/gpu/drm/drm_format_helper.c | 66 ++++++++++++++++++++---------
1 file changed, 47 insertions(+), 19 deletions(-)
Comments
On Thu, 27 Oct 2022 22:57:11 +0900 Hector Martin <marcan@marcan.st> wrote: > drm_fb_build_fourcc_list() currently returns all emulated formats > unconditionally as long as the native format is among them, even though > not all combinations have conversion helpers. Although the list is > arguably provided to userspace in precedence order, userspace can pick > something out-of-order (and thus break when it shouldn't), or simply > only support a format that is unsupported (and thus think it can work, > which results in the appearance of a hang as FB blits fail later on, > instead of the initialization error you'd expect in this case). > > Add checks to filter the list of emulated formats to only those > supported for conversion to the native format. This presumes that there > is a single native format (only the first is checked, if there are > multiple). Refactoring this API to drop the native list or support it > properly (by returning the appropriate emulated->native mapping table) > is left for a future patch. > > The simpledrm driver is left as-is with a full table of emulated > formats. This keeps all currently working conversions available and > drops all the broken ones (i.e. this a strict bugfix patch, adding no > new supported formats nor removing any actually working ones). In order > to avoid proliferation of emulated formats, future drivers should > advertise only XRGB8888 as the sole emulated format (since some > userspace assumes its presence). > > This fixes a real user regression where the ?RGB2101010 support commit > started advertising it unconditionally where not supported, and KWin > decided to start to use it over the native format and broke, but also > the fixes the spurious RGB565/RGB888 formats which have been wrongly > unconditionally advertised since the dawn of simpledrm. > > Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > Cc: stable@vger.kernel.org > Signed-off-by: Hector Martin <marcan@marcan.st> Hi Hector, I completely agree with all the rationale here. Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com> Thanks, pq > --- > I'm proposing this alternative approach after a heated discussion on > IRC. I'm out of ideas, if y'all don't like this one you can figure it > out for yourseves :-) > > Changes since v1: > This v2 moves all the changes to the helper (so they will apply to > the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > format table to only formats that should be emulated, probably only > XRGB8888, to avoid further proliferating the use of conversions), > and avoids touching more than one file. The API still needs cleanup > as mentioned (supporting more than one native format is fundamentally > broken, since the helper would need to tell the driver *what* native > format to use for *each* emulated format somehow), but all current and > planned users only pass in one native format, so this can (and should) > be fixed later. > > Aside: After other IRC discussion, I'm testing nuking the > XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > conversion) by removing those entries from simpledrm in the Asahi Linux > downstream tree. As far as I'm concerned, it can be removed if nobody > complains (by removing those entries from the simpledrm array), if > maintainers are generally okay with removing advertised formats at all. > If so, there might be other opportunities for further trimming the list > non-native formats advertised to userspace. > > Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston > on both XRGB2101010 and RGB8888 simpledrm framebuffers. > > drivers/gpu/drm/drm_format_helper.c | 66 ++++++++++++++++++++--------- > 1 file changed, 47 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index e2f76621453c..3ee59bae9d2f 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > return false; > } > > +static const uint32_t conv_from_xrgb8888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XRGB2101010, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_RGB565, > + DRM_FORMAT_RGB888, > +}; > + > +static const uint32_t conv_from_rgb565_888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > +}; > + > +static bool is_conversion_supported(uint32_t from, uint32_t to) > +{ > + switch (from) { > + case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_ARGB8888: > + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); > + case DRM_FORMAT_RGB565: > + case DRM_FORMAT_RGB888: > + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); > + case DRM_FORMAT_XRGB2101010: > + return to == DRM_FORMAT_ARGB2101010; > + case DRM_FORMAT_ARGB2101010: > + return to == DRM_FORMAT_XRGB2101010; > + default: > + return false; > + } > +} > + > /** > * drm_fb_build_fourcc_list - Filters a list of supported color formats against > * the device's native formats > @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > * be handed over to drm_universal_plane_init() et al. Native formats > * will go before emulated formats. Other heuristics might be applied > * to optimize the order. Formats near the beginning of the list are > - * usually preferred over formats near the end of the list. > + * usually preferred over formats near the end of the list. Formats > + * without conversion helpers will be skipped. New drivers should only > + * pass in XRGB8888 and avoid exposing additional emulated formats. > * > * Returns: > * The number of color-formats 4CC codes returned in @fourccs_out. > @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > { > u32 *fourccs = fourccs_out; > const u32 *fourccs_end = fourccs_out + nfourccs_out; > - bool found_native = false; > + uint32_t native_format = 0; > size_t i; > > /* > @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > > drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); > > - if (!found_native) > - found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); > + /* > + * There should only be one native format with the current API. > + * This API needs to be refactored to correctly support arbitrary > + * sets of native formats, since it needs to report which native > + * format to use for each emulated format. > + */ > + if (!native_format) > + native_format = fourcc; > *fourccs = fourcc; > ++fourccs; > } > > - /* > - * The plane's atomic_update helper converts the framebuffer's color format > - * to a native format when copying to device memory. > - * > - * If there is not a single format supported by both, device and > - * driver, the native formats are likely not supported by the conversion > - * helpers. Therefore *only* support the native formats and add a > - * conversion helper ASAP. > - */ > - if (!found_native) { > - drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); > - goto out; > - } > - > /* > * The extra formats, emulated by the driver, go second. > */ > @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > } else if (fourccs == fourccs_end) { > drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); > continue; /* end of available output buffer */ > + } else if (!is_conversion_supported(fourcc, native_format)) { > + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); > + continue; /* format is not supported for conversion */ > } > > drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); > @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > ++fourccs; > } > > -out: > return fourccs - fourccs_out; > } > EXPORT_SYMBOL(drm_fb_build_fourcc_list);
Hi Am 27.10.22 um 15:57 schrieb Hector Martin: > drm_fb_build_fourcc_list() currently returns all emulated formats > unconditionally as long as the native format is among them, even though > not all combinations have conversion helpers. Although the list is > arguably provided to userspace in precedence order, userspace can pick > something out-of-order (and thus break when it shouldn't), or simply > only support a format that is unsupported (and thus think it can work, > which results in the appearance of a hang as FB blits fail later on, > instead of the initialization error you'd expect in this case). > > Add checks to filter the list of emulated formats to only those > supported for conversion to the native format. This presumes that there > is a single native format (only the first is checked, if there are > multiple). Refactoring this API to drop the native list or support it > properly (by returning the appropriate emulated->native mapping table) > is left for a future patch. > > The simpledrm driver is left as-is with a full table of emulated > formats. This keeps all currently working conversions available and > drops all the broken ones (i.e. this a strict bugfix patch, adding no > new supported formats nor removing any actually working ones). In order > to avoid proliferation of emulated formats, future drivers should > advertise only XRGB8888 as the sole emulated format (since some > userspace assumes its presence). > > This fixes a real user regression where the ?RGB2101010 support commit > started advertising it unconditionally where not supported, and KWin > decided to start to use it over the native format and broke, but also > the fixes the spurious RGB565/RGB888 formats which have been wrongly > unconditionally advertised since the dawn of simpledrm. > > Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > Cc: stable@vger.kernel.org > Signed-off-by: Hector Martin <marcan@marcan.st> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Thanks for your patch. I have verified that video=-{16,24} still works with simpledrm. > --- > I'm proposing this alternative approach after a heated discussion on > IRC. I'm out of ideas, if y'all don't like this one you can figure it > out for yourseves :-) > > Changes since v1: > This v2 moves all the changes to the helper (so they will apply to > the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > format table to only formats that should be emulated, probably only > XRGB8888, to avoid further proliferating the use of conversions), > and avoids touching more than one file. The API still needs cleanup > as mentioned (supporting more than one native format is fundamentally > broken, since the helper would need to tell the driver *what* native > format to use for *each* emulated format somehow), but all current and > planned users only pass in one native format, so this can (and should) > be fixed later. > > Aside: After other IRC discussion, I'm testing nuking the > XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > conversion) by removing those entries from simpledrm in the Asahi Linux > downstream tree. As far as I'm concerned, it can be removed if nobody > complains (by removing those entries from the simpledrm array), if > maintainers are generally okay with removing advertised formats at all. > If so, there might be other opportunities for further trimming the list > non-native formats advertised to userspace. IMHO all of the extra A formats can immediately go. We have plenty of simple drivers that only export XRGB8888 plus sometimes a few other non-A formats. If anything in userspace had a hard dependency on an A format, we'd probably heard about it. In yesterday's discussion on IRC, it was said that several devices advertise ARGB framebuffers when the hardware actually uses XRGB? Is there hardware that supports transparent primary planes? Before removing the extra non-A formats, we first have to fix the fbdev console's format selection. So if users set video=-24 without native hardware support, simpledrm (and any other driver) falls back to a supported format. This worked with the old fbdev drivers, such as simplefb and efifb, and some users expect it. If nothing else comes in, I'll merge your patch on Monday. Best regards Thomas > > Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston > on both XRGB2101010 and RGB8888 simpledrm framebuffers. > > drivers/gpu/drm/drm_format_helper.c | 66 ++++++++++++++++++++--------- > 1 file changed, 47 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index e2f76621453c..3ee59bae9d2f 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > return false; > } > > +static const uint32_t conv_from_xrgb8888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XRGB2101010, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_RGB565, > + DRM_FORMAT_RGB888, > +}; > + > +static const uint32_t conv_from_rgb565_888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > +}; > + > +static bool is_conversion_supported(uint32_t from, uint32_t to) > +{ > + switch (from) { > + case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_ARGB8888: > + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); > + case DRM_FORMAT_RGB565: > + case DRM_FORMAT_RGB888: > + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); > + case DRM_FORMAT_XRGB2101010: > + return to == DRM_FORMAT_ARGB2101010; > + case DRM_FORMAT_ARGB2101010: > + return to == DRM_FORMAT_XRGB2101010; > + default: > + return false; > + } > +} > + > /** > * drm_fb_build_fourcc_list - Filters a list of supported color formats against > * the device's native formats > @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > * be handed over to drm_universal_plane_init() et al. Native formats > * will go before emulated formats. Other heuristics might be applied > * to optimize the order. Formats near the beginning of the list are > - * usually preferred over formats near the end of the list. > + * usually preferred over formats near the end of the list. Formats > + * without conversion helpers will be skipped. New drivers should only > + * pass in XRGB8888 and avoid exposing additional emulated formats. > * > * Returns: > * The number of color-formats 4CC codes returned in @fourccs_out. > @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > { > u32 *fourccs = fourccs_out; > const u32 *fourccs_end = fourccs_out + nfourccs_out; > - bool found_native = false; > + uint32_t native_format = 0; > size_t i; > > /* > @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > > drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); > > - if (!found_native) > - found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); > + /* > + * There should only be one native format with the current API. > + * This API needs to be refactored to correctly support arbitrary > + * sets of native formats, since it needs to report which native > + * format to use for each emulated format. > + */ > + if (!native_format) > + native_format = fourcc; > *fourccs = fourcc; > ++fourccs; > } > > - /* > - * The plane's atomic_update helper converts the framebuffer's color format > - * to a native format when copying to device memory. > - * > - * If there is not a single format supported by both, device and > - * driver, the native formats are likely not supported by the conversion > - * helpers. Therefore *only* support the native formats and add a > - * conversion helper ASAP. > - */ > - if (!found_native) { > - drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); > - goto out; > - } > - > /* > * The extra formats, emulated by the driver, go second. > */ > @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > } else if (fourccs == fourccs_end) { > drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); > continue; /* end of available output buffer */ > + } else if (!is_conversion_supported(fourcc, native_format)) { > + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); > + continue; /* format is not supported for conversion */ > } > > drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); > @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > ++fourccs; > } > > -out: > return fourccs - fourccs_out; > } > EXPORT_SYMBOL(drm_fb_build_fourcc_list); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev
On Fri, 28 Oct 2022 10:07:27 +0200 Thomas Zimmermann <tzimmermann@suse.de> wrote: > Hi > > Am 27.10.22 um 15:57 schrieb Hector Martin: > > drm_fb_build_fourcc_list() currently returns all emulated formats > > unconditionally as long as the native format is among them, even though > > not all combinations have conversion helpers. Although the list is > > arguably provided to userspace in precedence order, userspace can pick > > something out-of-order (and thus break when it shouldn't), or simply > > only support a format that is unsupported (and thus think it can work, > > which results in the appearance of a hang as FB blits fail later on, > > instead of the initialization error you'd expect in this case). > > > > Add checks to filter the list of emulated formats to only those > > supported for conversion to the native format. This presumes that there > > is a single native format (only the first is checked, if there are > > multiple). Refactoring this API to drop the native list or support it > > properly (by returning the appropriate emulated->native mapping table) > > is left for a future patch. > > > > The simpledrm driver is left as-is with a full table of emulated > > formats. This keeps all currently working conversions available and > > drops all the broken ones (i.e. this a strict bugfix patch, adding no > > new supported formats nor removing any actually working ones). In order > > to avoid proliferation of emulated formats, future drivers should > > advertise only XRGB8888 as the sole emulated format (since some > > userspace assumes its presence). > > > > This fixes a real user regression where the ?RGB2101010 support commit > > started advertising it unconditionally where not supported, and KWin > > decided to start to use it over the native format and broke, but also > > the fixes the spurious RGB565/RGB888 formats which have been wrongly > > unconditionally advertised since the dawn of simpledrm. > > > > Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > > Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > > Cc: stable@vger.kernel.org > > Signed-off-by: Hector Martin <marcan@marcan.st> > > Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> > > Thanks for your patch. I have verified that video=-{16,24} still works > with simpledrm. > > > --- > > I'm proposing this alternative approach after a heated discussion on > > IRC. I'm out of ideas, if y'all don't like this one you can figure it > > out for yourseves :-) > > > > Changes since v1: > > This v2 moves all the changes to the helper (so they will apply to > > the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > > format table to only formats that should be emulated, probably only > > XRGB8888, to avoid further proliferating the use of conversions), > > and avoids touching more than one file. The API still needs cleanup > > as mentioned (supporting more than one native format is fundamentally > > broken, since the helper would need to tell the driver *what* native > > format to use for *each* emulated format somehow), but all current and > > planned users only pass in one native format, so this can (and should) > > be fixed later. > > > > Aside: After other IRC discussion, I'm testing nuking the > > XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > > conversion) by removing those entries from simpledrm in the Asahi Linux > > downstream tree. As far as I'm concerned, it can be removed if nobody > > complains (by removing those entries from the simpledrm array), if > > maintainers are generally okay with removing advertised formats at all. > > If so, there might be other opportunities for further trimming the list > > non-native formats advertised to userspace. > > IMHO all of the extra A formats can immediately go. We have plenty of > simple drivers that only export XRGB8888 plus sometimes a few other > non-A formats. If anything in userspace had a hard dependency on an A > format, we'd probably heard about it. > > In yesterday's discussion on IRC, it was said that several devices > advertise ARGB framebuffers when the hardware actually uses XRGB? Is > there hardware that supports transparent primary planes? I'm fairly sure such hardware does exist, but I don't know if it's the drivers in question here. It's not uncommon to have extra hardware planes below the primary plane, and then use alpha on primary plane to cut a hole to see through to the "underlay" plane. This is a good setup for video playback, where the video is on the underlay, and (a slow GPU or CPU renders) the subtitles and UI on the primary plane. I've heard that some hardware also has a separate background color "plane" below all hardware planes, but I forget if upstream KMS exposes that. You'd find this mostly in "embedded" display chips. Thanks, pq > Before removing the extra non-A formats, we first have to fix the fbdev > console's format selection. So if users set video=-24 without native > hardware support, simpledrm (and any other driver) falls back to a > supported format. This worked with the old fbdev drivers, such as > simplefb and efifb, and some users expect it. > > If nothing else comes in, I'll merge your patch on Monday. > > Best regards > Thomas
Hi Am 28.10.22 um 10:37 schrieb Pekka Paalanen: > On Fri, 28 Oct 2022 10:07:27 +0200 > Thomas Zimmermann <tzimmermann@suse.de> wrote: > >> Hi >> >> Am 27.10.22 um 15:57 schrieb Hector Martin: >>> drm_fb_build_fourcc_list() currently returns all emulated formats >>> unconditionally as long as the native format is among them, even though >>> not all combinations have conversion helpers. Although the list is >>> arguably provided to userspace in precedence order, userspace can pick >>> something out-of-order (and thus break when it shouldn't), or simply >>> only support a format that is unsupported (and thus think it can work, >>> which results in the appearance of a hang as FB blits fail later on, >>> instead of the initialization error you'd expect in this case). >>> >>> Add checks to filter the list of emulated formats to only those >>> supported for conversion to the native format. This presumes that there >>> is a single native format (only the first is checked, if there are >>> multiple). Refactoring this API to drop the native list or support it >>> properly (by returning the appropriate emulated->native mapping table) >>> is left for a future patch. >>> >>> The simpledrm driver is left as-is with a full table of emulated >>> formats. This keeps all currently working conversions available and >>> drops all the broken ones (i.e. this a strict bugfix patch, adding no >>> new supported formats nor removing any actually working ones). In order >>> to avoid proliferation of emulated formats, future drivers should >>> advertise only XRGB8888 as the sole emulated format (since some >>> userspace assumes its presence). >>> >>> This fixes a real user regression where the ?RGB2101010 support commit >>> started advertising it unconditionally where not supported, and KWin >>> decided to start to use it over the native format and broke, but also >>> the fixes the spurious RGB565/RGB888 formats which have been wrongly >>> unconditionally advertised since the dawn of simpledrm. >>> >>> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") >>> Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") >>> Cc: stable@vger.kernel.org >>> Signed-off-by: Hector Martin <marcan@marcan.st> >> >> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> >> >> Thanks for your patch. I have verified that video=-{16,24} still works >> with simpledrm. >> >>> --- >>> I'm proposing this alternative approach after a heated discussion on >>> IRC. I'm out of ideas, if y'all don't like this one you can figure it >>> out for yourseves :-) >>> >>> Changes since v1: >>> This v2 moves all the changes to the helper (so they will apply to >>> the upcoming ofdrm, though ofdrm also needs to be fixed to trim its >>> format table to only formats that should be emulated, probably only >>> XRGB8888, to avoid further proliferating the use of conversions), >>> and avoids touching more than one file. The API still needs cleanup >>> as mentioned (supporting more than one native format is fundamentally >>> broken, since the helper would need to tell the driver *what* native >>> format to use for *each* emulated format somehow), but all current and >>> planned users only pass in one native format, so this can (and should) >>> be fixed later. >>> >>> Aside: After other IRC discussion, I'm testing nuking the >>> XRGB2101010 <-> ARGB2101010 advertisement (which does not involve >>> conversion) by removing those entries from simpledrm in the Asahi Linux >>> downstream tree. As far as I'm concerned, it can be removed if nobody >>> complains (by removing those entries from the simpledrm array), if >>> maintainers are generally okay with removing advertised formats at all. >>> If so, there might be other opportunities for further trimming the list >>> non-native formats advertised to userspace. >> >> IMHO all of the extra A formats can immediately go. We have plenty of >> simple drivers that only export XRGB8888 plus sometimes a few other >> non-A formats. If anything in userspace had a hard dependency on an A >> format, we'd probably heard about it. >> >> In yesterday's discussion on IRC, it was said that several devices >> advertise ARGB framebuffers when the hardware actually uses XRGB? Is >> there hardware that supports transparent primary planes? > > I'm fairly sure such hardware does exist, but I don't know if it's the > drivers in question here. > > It's not uncommon to have extra hardware planes below the primary > plane, and then use alpha on primary plane to cut a hole to see through > to the "underlay" plane. This is a good setup for video playback, where > the video is on the underlay, and (a slow GPU or CPU renders) the > subtitles and UI on the primary plane. > > I've heard that some hardware also has a separate background color > "plane" below all hardware planes, but I forget if upstream KMS exposes > that. That's also what I heard of. It's not something we can control within simpledrm or any other generic driver. I'm worried that we advertise ARGB to userspace when the scanout buffer is actually XRGB. But if we advertise XRGB and the scanout buffer is really ARGB, any garbage in the X filler byte would interfere. If we have a native ARGB scanout buffer, we could advertise XRGB to userspace and set the filler byte unconditionally during the pageflip step. That should be safe on all hardware. Best regards Thomas > > You'd find this mostly in "embedded" display chips. > > > Thanks, > pq > >> Before removing the extra non-A formats, we first have to fix the fbdev >> console's format selection. So if users set video=-24 without native >> hardware support, simpledrm (and any other driver) falls back to a >> supported format. This worked with the old fbdev drivers, such as >> simplefb and efifb, and some users expect it. >> >> If nothing else comes in, I'll merge your patch on Monday. >> >> Best regards >> Thomas -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev
On Fri, 28 Oct 2022 10:53:49 +0200 Thomas Zimmermann <tzimmermann@suse.de> wrote: > Hi > > Am 28.10.22 um 10:37 schrieb Pekka Paalanen: > > On Fri, 28 Oct 2022 10:07:27 +0200 > > Thomas Zimmermann <tzimmermann@suse.de> wrote: > > > >> Hi > >> > >> Am 27.10.22 um 15:57 schrieb Hector Martin: > >>> drm_fb_build_fourcc_list() currently returns all emulated formats > >>> unconditionally as long as the native format is among them, even though > >>> not all combinations have conversion helpers. Although the list is > >>> arguably provided to userspace in precedence order, userspace can pick > >>> something out-of-order (and thus break when it shouldn't), or simply > >>> only support a format that is unsupported (and thus think it can work, > >>> which results in the appearance of a hang as FB blits fail later on, > >>> instead of the initialization error you'd expect in this case). > >>> > >>> Add checks to filter the list of emulated formats to only those > >>> supported for conversion to the native format. This presumes that there > >>> is a single native format (only the first is checked, if there are > >>> multiple). Refactoring this API to drop the native list or support it > >>> properly (by returning the appropriate emulated->native mapping table) > >>> is left for a future patch. > >>> > >>> The simpledrm driver is left as-is with a full table of emulated > >>> formats. This keeps all currently working conversions available and > >>> drops all the broken ones (i.e. this a strict bugfix patch, adding no > >>> new supported formats nor removing any actually working ones). In order > >>> to avoid proliferation of emulated formats, future drivers should > >>> advertise only XRGB8888 as the sole emulated format (since some > >>> userspace assumes its presence). > >>> > >>> This fixes a real user regression where the ?RGB2101010 support commit > >>> started advertising it unconditionally where not supported, and KWin > >>> decided to start to use it over the native format and broke, but also > >>> the fixes the spurious RGB565/RGB888 formats which have been wrongly > >>> unconditionally advertised since the dawn of simpledrm. > >>> > >>> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > >>> Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > >>> Cc: stable@vger.kernel.org > >>> Signed-off-by: Hector Martin <marcan@marcan.st> > >> > >> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> > >> > >> Thanks for your patch. I have verified that video=-{16,24} still works > >> with simpledrm. > >> > >>> --- > >>> I'm proposing this alternative approach after a heated discussion on > >>> IRC. I'm out of ideas, if y'all don't like this one you can figure it > >>> out for yourseves :-) > >>> > >>> Changes since v1: > >>> This v2 moves all the changes to the helper (so they will apply to > >>> the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > >>> format table to only formats that should be emulated, probably only > >>> XRGB8888, to avoid further proliferating the use of conversions), > >>> and avoids touching more than one file. The API still needs cleanup > >>> as mentioned (supporting more than one native format is fundamentally > >>> broken, since the helper would need to tell the driver *what* native > >>> format to use for *each* emulated format somehow), but all current and > >>> planned users only pass in one native format, so this can (and should) > >>> be fixed later. > >>> > >>> Aside: After other IRC discussion, I'm testing nuking the > >>> XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > >>> conversion) by removing those entries from simpledrm in the Asahi Linux > >>> downstream tree. As far as I'm concerned, it can be removed if nobody > >>> complains (by removing those entries from the simpledrm array), if > >>> maintainers are generally okay with removing advertised formats at all. > >>> If so, there might be other opportunities for further trimming the list > >>> non-native formats advertised to userspace. > >> > >> IMHO all of the extra A formats can immediately go. We have plenty of > >> simple drivers that only export XRGB8888 plus sometimes a few other > >> non-A formats. If anything in userspace had a hard dependency on an A > >> format, we'd probably heard about it. > >> > >> In yesterday's discussion on IRC, it was said that several devices > >> advertise ARGB framebuffers when the hardware actually uses XRGB? Is > >> there hardware that supports transparent primary planes? > > > > I'm fairly sure such hardware does exist, but I don't know if it's the > > drivers in question here. > > > > It's not uncommon to have extra hardware planes below the primary > > plane, and then use alpha on primary plane to cut a hole to see through > > to the "underlay" plane. This is a good setup for video playback, where > > the video is on the underlay, and (a slow GPU or CPU renders) the > > subtitles and UI on the primary plane. > > > > I've heard that some hardware also has a separate background color > > "plane" below all hardware planes, but I forget if upstream KMS exposes > > that. > > That's also what I heard of. It's not something we can control within > simpledrm or any other generic driver. > > I'm worried that we advertise ARGB to userspace when the scanout buffer > is actually XRGB. What would be the problem with that? simpledrm would never expose more than only the primary plane, right? Not even background color. That means that userspace cannot use the alpha channel for anything anyway, there is nothing to show through. Or are you thinking about transparent monitors? Of course, it would be best to advertise strictly what the hardware does. > But if we advertise XRGB and the scanout buffer is > really ARGB, any garbage in the X filler byte would interfere. Yes, probably. Garbage alpha being used would not hurt if a) userspace thinks it's rendering XRGB which means that RGB values are all opaque, and b) the hardware blending mode is pre-multiplied-alpha, and c) whatever is behind the primary plane is all zeroes. > If we have a native ARGB scanout buffer, we could advertise XRGB to > userspace and set the filler byte unconditionally during the pageflip > step. That should be safe on all hardware. Correct. Since you say "filler byte", I assume you are referring to XRGB8888 only. That's good. Other formats should not be emulated. Thanks, pq
Hi Am 28.10.22 um 11:17 schrieb Pekka Paalanen: > On Fri, 28 Oct 2022 10:53:49 +0200 > Thomas Zimmermann <tzimmermann@suse.de> wrote: > >> Hi >> >> Am 28.10.22 um 10:37 schrieb Pekka Paalanen: >>> On Fri, 28 Oct 2022 10:07:27 +0200 >>> Thomas Zimmermann <tzimmermann@suse.de> wrote: >>> >>>> Hi >>>> >>>> Am 27.10.22 um 15:57 schrieb Hector Martin: >>>>> drm_fb_build_fourcc_list() currently returns all emulated formats >>>>> unconditionally as long as the native format is among them, even though >>>>> not all combinations have conversion helpers. Although the list is >>>>> arguably provided to userspace in precedence order, userspace can pick >>>>> something out-of-order (and thus break when it shouldn't), or simply >>>>> only support a format that is unsupported (and thus think it can work, >>>>> which results in the appearance of a hang as FB blits fail later on, >>>>> instead of the initialization error you'd expect in this case). >>>>> >>>>> Add checks to filter the list of emulated formats to only those >>>>> supported for conversion to the native format. This presumes that there >>>>> is a single native format (only the first is checked, if there are >>>>> multiple). Refactoring this API to drop the native list or support it >>>>> properly (by returning the appropriate emulated->native mapping table) >>>>> is left for a future patch. >>>>> >>>>> The simpledrm driver is left as-is with a full table of emulated >>>>> formats. This keeps all currently working conversions available and >>>>> drops all the broken ones (i.e. this a strict bugfix patch, adding no >>>>> new supported formats nor removing any actually working ones). In order >>>>> to avoid proliferation of emulated formats, future drivers should >>>>> advertise only XRGB8888 as the sole emulated format (since some >>>>> userspace assumes its presence). >>>>> >>>>> This fixes a real user regression where the ?RGB2101010 support commit >>>>> started advertising it unconditionally where not supported, and KWin >>>>> decided to start to use it over the native format and broke, but also >>>>> the fixes the spurious RGB565/RGB888 formats which have been wrongly >>>>> unconditionally advertised since the dawn of simpledrm. >>>>> >>>>> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") >>>>> Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") >>>>> Cc: stable@vger.kernel.org >>>>> Signed-off-by: Hector Martin <marcan@marcan.st> >>>> >>>> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> >>>> >>>> Thanks for your patch. I have verified that video=-{16,24} still works >>>> with simpledrm. >>>> >>>>> --- >>>>> I'm proposing this alternative approach after a heated discussion on >>>>> IRC. I'm out of ideas, if y'all don't like this one you can figure it >>>>> out for yourseves :-) >>>>> >>>>> Changes since v1: >>>>> This v2 moves all the changes to the helper (so they will apply to >>>>> the upcoming ofdrm, though ofdrm also needs to be fixed to trim its >>>>> format table to only formats that should be emulated, probably only >>>>> XRGB8888, to avoid further proliferating the use of conversions), >>>>> and avoids touching more than one file. The API still needs cleanup >>>>> as mentioned (supporting more than one native format is fundamentally >>>>> broken, since the helper would need to tell the driver *what* native >>>>> format to use for *each* emulated format somehow), but all current and >>>>> planned users only pass in one native format, so this can (and should) >>>>> be fixed later. >>>>> >>>>> Aside: After other IRC discussion, I'm testing nuking the >>>>> XRGB2101010 <-> ARGB2101010 advertisement (which does not involve >>>>> conversion) by removing those entries from simpledrm in the Asahi Linux >>>>> downstream tree. As far as I'm concerned, it can be removed if nobody >>>>> complains (by removing those entries from the simpledrm array), if >>>>> maintainers are generally okay with removing advertised formats at all. >>>>> If so, there might be other opportunities for further trimming the list >>>>> non-native formats advertised to userspace. >>>> >>>> IMHO all of the extra A formats can immediately go. We have plenty of >>>> simple drivers that only export XRGB8888 plus sometimes a few other >>>> non-A formats. If anything in userspace had a hard dependency on an A >>>> format, we'd probably heard about it. >>>> >>>> In yesterday's discussion on IRC, it was said that several devices >>>> advertise ARGB framebuffers when the hardware actually uses XRGB? Is >>>> there hardware that supports transparent primary planes? >>> >>> I'm fairly sure such hardware does exist, but I don't know if it's the >>> drivers in question here. >>> >>> It's not uncommon to have extra hardware planes below the primary >>> plane, and then use alpha on primary plane to cut a hole to see through >>> to the "underlay" plane. This is a good setup for video playback, where >>> the video is on the underlay, and (a slow GPU or CPU renders) the >>> subtitles and UI on the primary plane. >>> >>> I've heard that some hardware also has a separate background color >>> "plane" below all hardware planes, but I forget if upstream KMS exposes >>> that. >> >> That's also what I heard of. It's not something we can control within >> simpledrm or any other generic driver. >> >> I'm worried that we advertise ARGB to userspace when the scanout buffer >> is actually XRGB. > > What would be the problem with that? > simpledrm would never expose more than only the primary plane, right? > Not even background color. Right. My concerns are the proliferation of A format, and userspace that tries something fancy with that incorrect A byte, which leads to display artifacts. Like fading in/out the content of the primary plane. > > That means that userspace cannot use the alpha channel for anything > anyway, there is nothing to show through. Or are you thinking about > transparent monitors? I can't tell if you're serious, but I'm not going to rule this out. ;) > > Of course, it would be best to advertise strictly what the hardware > does. > >> But if we advertise XRGB and the scanout buffer is >> really ARGB, any garbage in the X filler byte would interfere. > > Yes, probably. Garbage alpha being used would not hurt if a) userspace > thinks it's rendering XRGB which means that RGB values are all opaque, > and b) the hardware blending mode is pre-multiplied-alpha, and c) > whatever is behind the primary plane is all zeroes. To my knowledge, there's no reliable way of detecting any of this. Especially not from within the hardware-agnostic code. Best regards Thomas > >> If we have a native ARGB scanout buffer, we could advertise XRGB to >> userspace and set the filler byte unconditionally during the pageflip >> step. That should be safe on all hardware. > > Correct. Since you say "filler byte", I assume you are referring to > XRGB8888 only. That's good. Other formats should not be emulated. > > > Thanks, > pq -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev
On Fri, 28 Oct 2022 11:34:34 +0200 Thomas Zimmermann <tzimmermann@suse.de> wrote: > Hi > > Am 28.10.22 um 11:17 schrieb Pekka Paalanen: > > On Fri, 28 Oct 2022 10:53:49 +0200 > > Thomas Zimmermann <tzimmermann@suse.de> wrote: > > > >> Hi > >> > >> Am 28.10.22 um 10:37 schrieb Pekka Paalanen: > >>> On Fri, 28 Oct 2022 10:07:27 +0200 > >>> Thomas Zimmermann <tzimmermann@suse.de> wrote: > >>> > >>>> Hi > >>>> > >>>> Am 27.10.22 um 15:57 schrieb Hector Martin: > >>>>> drm_fb_build_fourcc_list() currently returns all emulated formats > >>>>> unconditionally as long as the native format is among them, even though > >>>>> not all combinations have conversion helpers. Although the list is > >>>>> arguably provided to userspace in precedence order, userspace can pick > >>>>> something out-of-order (and thus break when it shouldn't), or simply > >>>>> only support a format that is unsupported (and thus think it can work, > >>>>> which results in the appearance of a hang as FB blits fail later on, > >>>>> instead of the initialization error you'd expect in this case). > >>>>> > >>>>> Add checks to filter the list of emulated formats to only those > >>>>> supported for conversion to the native format. This presumes that there > >>>>> is a single native format (only the first is checked, if there are > >>>>> multiple). Refactoring this API to drop the native list or support it > >>>>> properly (by returning the appropriate emulated->native mapping table) > >>>>> is left for a future patch. > >>>>> > >>>>> The simpledrm driver is left as-is with a full table of emulated > >>>>> formats. This keeps all currently working conversions available and > >>>>> drops all the broken ones (i.e. this a strict bugfix patch, adding no > >>>>> new supported formats nor removing any actually working ones). In order > >>>>> to avoid proliferation of emulated formats, future drivers should > >>>>> advertise only XRGB8888 as the sole emulated format (since some > >>>>> userspace assumes its presence). > >>>>> > >>>>> This fixes a real user regression where the ?RGB2101010 support commit > >>>>> started advertising it unconditionally where not supported, and KWin > >>>>> decided to start to use it over the native format and broke, but also > >>>>> the fixes the spurious RGB565/RGB888 formats which have been wrongly > >>>>> unconditionally advertised since the dawn of simpledrm. > >>>>> > >>>>> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > >>>>> Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > >>>>> Cc: stable@vger.kernel.org > >>>>> Signed-off-by: Hector Martin <marcan@marcan.st> > >>>> > >>>> Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> > >>>> > >>>> Thanks for your patch. I have verified that video=-{16,24} still works > >>>> with simpledrm. > >>>> > >>>>> --- > >>>>> I'm proposing this alternative approach after a heated discussion on > >>>>> IRC. I'm out of ideas, if y'all don't like this one you can figure it > >>>>> out for yourseves :-) > >>>>> > >>>>> Changes since v1: > >>>>> This v2 moves all the changes to the helper (so they will apply to > >>>>> the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > >>>>> format table to only formats that should be emulated, probably only > >>>>> XRGB8888, to avoid further proliferating the use of conversions), > >>>>> and avoids touching more than one file. The API still needs cleanup > >>>>> as mentioned (supporting more than one native format is fundamentally > >>>>> broken, since the helper would need to tell the driver *what* native > >>>>> format to use for *each* emulated format somehow), but all current and > >>>>> planned users only pass in one native format, so this can (and should) > >>>>> be fixed later. > >>>>> > >>>>> Aside: After other IRC discussion, I'm testing nuking the > >>>>> XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > >>>>> conversion) by removing those entries from simpledrm in the Asahi Linux > >>>>> downstream tree. As far as I'm concerned, it can be removed if nobody > >>>>> complains (by removing those entries from the simpledrm array), if > >>>>> maintainers are generally okay with removing advertised formats at all. > >>>>> If so, there might be other opportunities for further trimming the list > >>>>> non-native formats advertised to userspace. > >>>> > >>>> IMHO all of the extra A formats can immediately go. We have plenty of > >>>> simple drivers that only export XRGB8888 plus sometimes a few other > >>>> non-A formats. If anything in userspace had a hard dependency on an A > >>>> format, we'd probably heard about it. > >>>> > >>>> In yesterday's discussion on IRC, it was said that several devices > >>>> advertise ARGB framebuffers when the hardware actually uses XRGB? Is > >>>> there hardware that supports transparent primary planes? > >>> > >>> I'm fairly sure such hardware does exist, but I don't know if it's the > >>> drivers in question here. > >>> > >>> It's not uncommon to have extra hardware planes below the primary > >>> plane, and then use alpha on primary plane to cut a hole to see through > >>> to the "underlay" plane. This is a good setup for video playback, where > >>> the video is on the underlay, and (a slow GPU or CPU renders) the > >>> subtitles and UI on the primary plane. > >>> > >>> I've heard that some hardware also has a separate background color > >>> "plane" below all hardware planes, but I forget if upstream KMS exposes > >>> that. > >> > >> That's also what I heard of. It's not something we can control within > >> simpledrm or any other generic driver. > >> > >> I'm worried that we advertise ARGB to userspace when the scanout buffer > >> is actually XRGB. > > > > What would be the problem with that? > > simpledrm would never expose more than only the primary plane, right? > > Not even background color. > > Right. My concerns are the proliferation of A format, and userspace that > tries something fancy with that incorrect A byte, which leads to display > artifacts. Like fading in/out the content of the primary plane. I agree. > > That means that userspace cannot use the alpha channel for anything > > anyway, there is nothing to show through. Or are you thinking about > > transparent monitors? > > I can't tell if you're serious, but I'm not going to rule this out. ;) I am kind of serious. See-through monitors would be cool if not practical. They actually kind of exist already as projections through semi-mirrors like in AR-goggles or car windscreens, but they don't yet allow displaying opaque black (or do they?). OTOH, one could use a traditional LCD and replace the mirror with another polarizing filter, I guess. Maybe that's a way to implement controllable opacity. I've no idea if anyone has combined these technologies. Hmm, if alpha controls the opacity layer, then RGB values would behave as if pre-multiplied in optical blending. The projected RGB primaries can only add light on top of what passes through the LCD opacity mask. Why don't I have one of those yet! Thanks, pq
On 28/10/2022 17.07, Thomas Zimmermann wrote: > In yesterday's discussion on IRC, it was said that several devices > advertise ARGB framebuffers when the hardware actually uses XRGB? Is > there hardware that supports transparent primary planes? ARGB hardware probably exists in the form of embedded systems with preconfigured blending. For example, one could imagine an OSD-type setup where there is a hardware video scaler controlled entirely outside of DRM/KMS (probably by a horrible vendor driver), and the overlay framebuffer is exposed via simpledrm as a dumb memory region, and expects ARGB to work. So ideally, we wouldn't expose XRGB8888 on ARGB8888 systems. But there is this problem: arch/arm64/boot/dts/qcom/msm8998-oneplus-common.dtsi: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sdm630-sony-xperia-nile.dtsi: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sdm660-xiaomi-lavender.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sdm845-shift-axolotl.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sdm850-samsung-w737.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm6125-sony-xperia-seine-pdx201.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm6350-sony-xperia-lena-pdx213.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm8150-sony-xperia-kumano.dtsi: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm8250-sony-xperia-edo.dtsi: format = "a8r8g8b8"; arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi: format = "a8r8g8b8"; arch/arm64/boot/dts/socionext/uniphier-ld20-akebi96.dts: format = "a8r8g8b8"; I'm pretty sure those phones don't have transparent screens, nor magically put video planes below the firmware framebuffer. If there are 12 device trees for phones in mainline which lie about having alpha support, who knows how many more exist outside? If we stop advertising pretend-XRGB8888 on them, I suspect we're going to break a lot of software... Of course, there is one "correct" solution here: have an actual xrgb8888->argb8888 conversion helper that just clears the high byte. Then those platforms lying about having alpha and using xrgb8888 from userspace will take a performace hit, but they should arguably just fix their device tree in that case. Maybe this is the way to go in this case? Note that there would be no inverse conversion (no advertising argb8888 on xrgb8888 backends), so that one would be dropped vs. what we have today. This effectively keeps the "xrgb8888 helpers and nothing else" rule while actually supporting it for argb8888 backend framebuffers correctly. Any platforms actually wanting to use argb8888 framebuffers with meaningful alpha should be configuring their userspace to preferentially render directly to argb8888 to avoid the perf hit anyway. - Hector
Merged into drm-misc-fixes Am 27.10.22 um 15:57 schrieb Hector Martin: > drm_fb_build_fourcc_list() currently returns all emulated formats > unconditionally as long as the native format is among them, even though > not all combinations have conversion helpers. Although the list is > arguably provided to userspace in precedence order, userspace can pick > something out-of-order (and thus break when it shouldn't), or simply > only support a format that is unsupported (and thus think it can work, > which results in the appearance of a hang as FB blits fail later on, > instead of the initialization error you'd expect in this case). > > Add checks to filter the list of emulated formats to only those > supported for conversion to the native format. This presumes that there > is a single native format (only the first is checked, if there are > multiple). Refactoring this API to drop the native list or support it > properly (by returning the appropriate emulated->native mapping table) > is left for a future patch. > > The simpledrm driver is left as-is with a full table of emulated > formats. This keeps all currently working conversions available and > drops all the broken ones (i.e. this a strict bugfix patch, adding no > new supported formats nor removing any actually working ones). In order > to avoid proliferation of emulated formats, future drivers should > advertise only XRGB8888 as the sole emulated format (since some > userspace assumes its presence). > > This fixes a real user regression where the ?RGB2101010 support commit > started advertising it unconditionally where not supported, and KWin > decided to start to use it over the native format and broke, but also > the fixes the spurious RGB565/RGB888 formats which have been wrongly > unconditionally advertised since the dawn of simpledrm. > > Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB2101010 formats") > Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") > Cc: stable@vger.kernel.org > Signed-off-by: Hector Martin <marcan@marcan.st> > --- > I'm proposing this alternative approach after a heated discussion on > IRC. I'm out of ideas, if y'all don't like this one you can figure it > out for yourseves :-) > > Changes since v1: > This v2 moves all the changes to the helper (so they will apply to > the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > format table to only formats that should be emulated, probably only > XRGB8888, to avoid further proliferating the use of conversions), > and avoids touching more than one file. The API still needs cleanup > as mentioned (supporting more than one native format is fundamentally > broken, since the helper would need to tell the driver *what* native > format to use for *each* emulated format somehow), but all current and > planned users only pass in one native format, so this can (and should) > be fixed later. > > Aside: After other IRC discussion, I'm testing nuking the > XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > conversion) by removing those entries from simpledrm in the Asahi Linux > downstream tree. As far as I'm concerned, it can be removed if nobody > complains (by removing those entries from the simpledrm array), if > maintainers are generally okay with removing advertised formats at all. > If so, there might be other opportunities for further trimming the list > non-native formats advertised to userspace. > > Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston > on both XRGB2101010 and RGB8888 simpledrm framebuffers. > > drivers/gpu/drm/drm_format_helper.c | 66 ++++++++++++++++++++--------- > 1 file changed, 47 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index e2f76621453c..3ee59bae9d2f 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > return false; > } > > +static const uint32_t conv_from_xrgb8888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XRGB2101010, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_RGB565, > + DRM_FORMAT_RGB888, > +}; > + > +static const uint32_t conv_from_rgb565_888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > +}; > + > +static bool is_conversion_supported(uint32_t from, uint32_t to) > +{ > + switch (from) { > + case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_ARGB8888: > + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); > + case DRM_FORMAT_RGB565: > + case DRM_FORMAT_RGB888: > + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); > + case DRM_FORMAT_XRGB2101010: > + return to == DRM_FORMAT_ARGB2101010; > + case DRM_FORMAT_ARGB2101010: > + return to == DRM_FORMAT_XRGB2101010; > + default: > + return false; > + } > +} > + > /** > * drm_fb_build_fourcc_list - Filters a list of supported color formats against > * the device's native formats > @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > * be handed over to drm_universal_plane_init() et al. Native formats > * will go before emulated formats. Other heuristics might be applied > * to optimize the order. Formats near the beginning of the list are > - * usually preferred over formats near the end of the list. > + * usually preferred over formats near the end of the list. Formats > + * without conversion helpers will be skipped. New drivers should only > + * pass in XRGB8888 and avoid exposing additional emulated formats. > * > * Returns: > * The number of color-formats 4CC codes returned in @fourccs_out. > @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > { > u32 *fourccs = fourccs_out; > const u32 *fourccs_end = fourccs_out + nfourccs_out; > - bool found_native = false; > + uint32_t native_format = 0; > size_t i; > > /* > @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > > drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); > > - if (!found_native) > - found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); > + /* > + * There should only be one native format with the current API. > + * This API needs to be refactored to correctly support arbitrary > + * sets of native formats, since it needs to report which native > + * format to use for each emulated format. > + */ > + if (!native_format) > + native_format = fourcc; > *fourccs = fourcc; > ++fourccs; > } > > - /* > - * The plane's atomic_update helper converts the framebuffer's color format > - * to a native format when copying to device memory. > - * > - * If there is not a single format supported by both, device and > - * driver, the native formats are likely not supported by the conversion > - * helpers. Therefore *only* support the native formats and add a > - * conversion helper ASAP. > - */ > - if (!found_native) { > - drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); > - goto out; > - } > - > /* > * The extra formats, emulated by the driver, go second. > */ > @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > } else if (fourccs == fourccs_end) { > drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); > continue; /* end of available output buffer */ > + } else if (!is_conversion_supported(fourcc, native_format)) { > + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); > + continue; /* format is not supported for conversion */ > } > > drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); > @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > ++fourccs; > } > > -out: > return fourccs - fourccs_out; > } > EXPORT_SYMBOL(drm_fb_build_fourcc_list); -- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev
On Thu, Oct 27, 2022 at 8:57 AM Hector Martin <marcan@marcan.st> wrote: > > drm_fb_build_fourcc_list() currently returns all emulated formats > unconditionally as long as the native format is among them, even though > not all combinations have conversion helpers. Although the list is > arguably provided to userspace in precedence order, userspace can pick > something out-of-order (and thus break when it shouldn't), or simply > only support a format that is unsupported (and thus think it can work, > which results in the appearance of a hang as FB blits fail later on, > instead of the initialization error you'd expect in this case). > > Add checks to filter the list of emulated formats to only those > supported for conversion to the native format. This presumes that there > is a single native format (only the first is checked, if there are > multiple). Refactoring this API to drop the native list or support it > properly (by returning the appropriate emulated->native mapping table) > is left for a future patch. > > The simpledrm driver is left as-is with a full table of emulated > formats. This keeps all currently working conversions available and > drops all the broken ones (i.e. this a strict bugfix patch, adding no > new supported formats nor removing any actually working ones). In order > to avoid proliferation of emulated formats, future drivers should > advertise only XRGB8888 as the sole emulated format (since some > userspace assumes its presence). > > This fixes a real user regression where the ?RGB2101010 support commit > started advertising it unconditionally where not supported, and KWin > decided to start to use it over the native format and broke, but also > the fixes the spurious RGB565/RGB888 formats which have been wrongly > unconditionally advertised since the dawn of simpledrm. > > Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB210101 > Cc: stable@vger.kernel.org > Signed-off-by: Hector Martin <marcan@marcan.st> There is a CC for stable on here, but this patch does not apply in any way on 6.0 or older kernels as the fourcc bits and considerable churn came in with the 6.1 merge window. You don't happen to have a backport of this to 6.0 do you? Thanks, Justin > --- > I'm proposing this alternative approach after a heated discussion on > IRC. I'm out of ideas, if y'all don't like this one you can figure it > out for yourseves :-) > > Changes since v1: > This v2 moves all the changes to the helper (so they will apply to > the upcoming ofdrm, though ofdrm also needs to be fixed to trim its > format table to only formats that should be emulated, probably only > XRGB8888, to avoid further proliferating the use of conversions), > and avoids touching more than one file. The API still needs cleanup > as mentioned (supporting more than one native format is fundamentally > broken, since the helper would need to tell the driver *what* native > format to use for *each* emulated format somehow), but all current and > planned users only pass in one native format, so this can (and should) > be fixed later. > > Aside: After other IRC discussion, I'm testing nuking the > XRGB2101010 <-> ARGB2101010 advertisement (which does not involve > conversion) by removing those entries from simpledrm in the Asahi Linux > downstream tree. As far as I'm concerned, it can be removed if nobody > complains (by removing those entries from the simpledrm array), if > maintainers are generally okay with removing advertised formats at all. > If so, there might be other opportunities for further trimming the list > non-native formats advertised to userspace. > > Tested with KWin-X11, KWin-Wayland, GNOME-X11, GNOME-Wayland, and Weston > on both XRGB2101010 and RGB8888 simpledrm framebuffers. > > drivers/gpu/drm/drm_format_helper.c | 66 ++++++++++++++++++++--------- > 1 file changed, 47 insertions(+), 19 deletions(-) > > diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c > index e2f76621453c..3ee59bae9d2f 100644 > --- a/drivers/gpu/drm/drm_format_helper.c > +++ b/drivers/gpu/drm/drm_format_helper.c > @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > return false; > } > > +static const uint32_t conv_from_xrgb8888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > + DRM_FORMAT_XRGB2101010, > + DRM_FORMAT_ARGB2101010, > + DRM_FORMAT_RGB565, > + DRM_FORMAT_RGB888, > +}; > + > +static const uint32_t conv_from_rgb565_888[] = { > + DRM_FORMAT_XRGB8888, > + DRM_FORMAT_ARGB8888, > +}; > + > +static bool is_conversion_supported(uint32_t from, uint32_t to) > +{ > + switch (from) { > + case DRM_FORMAT_XRGB8888: > + case DRM_FORMAT_ARGB8888: > + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); > + case DRM_FORMAT_RGB565: > + case DRM_FORMAT_RGB888: > + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); > + case DRM_FORMAT_XRGB2101010: > + return to == DRM_FORMAT_ARGB2101010; > + case DRM_FORMAT_ARGB2101010: > + return to == DRM_FORMAT_XRGB2101010; > + default: > + return false; > + } > +} > + > /** > * drm_fb_build_fourcc_list - Filters a list of supported color formats against > * the device's native formats > @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t > * be handed over to drm_universal_plane_init() et al. Native formats > * will go before emulated formats. Other heuristics might be applied > * to optimize the order. Formats near the beginning of the list are > - * usually preferred over formats near the end of the list. > + * usually preferred over formats near the end of the list. Formats > + * without conversion helpers will be skipped. New drivers should only > + * pass in XRGB8888 and avoid exposing additional emulated formats. > * > * Returns: > * The number of color-formats 4CC codes returned in @fourccs_out. > @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > { > u32 *fourccs = fourccs_out; > const u32 *fourccs_end = fourccs_out + nfourccs_out; > - bool found_native = false; > + uint32_t native_format = 0; > size_t i; > > /* > @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > > drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); > > - if (!found_native) > - found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); > + /* > + * There should only be one native format with the current API. > + * This API needs to be refactored to correctly support arbitrary > + * sets of native formats, since it needs to report which native > + * format to use for each emulated format. > + */ > + if (!native_format) > + native_format = fourcc; > *fourccs = fourcc; > ++fourccs; > } > > - /* > - * The plane's atomic_update helper converts the framebuffer's color format > - * to a native format when copying to device memory. > - * > - * If there is not a single format supported by both, device and > - * driver, the native formats are likely not supported by the conversion > - * helpers. Therefore *only* support the native formats and add a > - * conversion helper ASAP. > - */ > - if (!found_native) { > - drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); > - goto out; > - } > - > /* > * The extra formats, emulated by the driver, go second. > */ > @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > } else if (fourccs == fourccs_end) { > drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); > continue; /* end of available output buffer */ > + } else if (!is_conversion_supported(fourcc, native_format)) { > + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); > + continue; /* format is not supported for conversion */ > } > > drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); > @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, > ++fourccs; > } > > -out: > return fourccs - fourccs_out; > } > EXPORT_SYMBOL(drm_fb_build_fourcc_list); > -- > 2.35.1 >
On 01/11/2022 01.15, Justin Forbes wrote: > On Thu, Oct 27, 2022 at 8:57 AM Hector Martin <marcan@marcan.st> wrote: >> >> drm_fb_build_fourcc_list() currently returns all emulated formats >> unconditionally as long as the native format is among them, even though >> not all combinations have conversion helpers. Although the list is >> arguably provided to userspace in precedence order, userspace can pick >> something out-of-order (and thus break when it shouldn't), or simply >> only support a format that is unsupported (and thus think it can work, >> which results in the appearance of a hang as FB blits fail later on, >> instead of the initialization error you'd expect in this case). >> >> Add checks to filter the list of emulated formats to only those >> supported for conversion to the native format. This presumes that there >> is a single native format (only the first is checked, if there are >> multiple). Refactoring this API to drop the native list or support it >> properly (by returning the appropriate emulated->native mapping table) >> is left for a future patch. >> >> The simpledrm driver is left as-is with a full table of emulated >> formats. This keeps all currently working conversions available and >> drops all the broken ones (i.e. this a strict bugfix patch, adding no >> new supported formats nor removing any actually working ones). In order >> to avoid proliferation of emulated formats, future drivers should >> advertise only XRGB8888 as the sole emulated format (since some >> userspace assumes its presence). >> >> This fixes a real user regression where the ?RGB2101010 support commit >> started advertising it unconditionally where not supported, and KWin >> decided to start to use it over the native format and broke, but also >> the fixes the spurious RGB565/RGB888 formats which have been wrongly >> unconditionally advertised since the dawn of simpledrm. >> >> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB210101 > > >> Cc: stable@vger.kernel.org >> Signed-off-by: Hector Martin <marcan@marcan.st> > > There is a CC for stable on here, but this patch does not apply in any > way on 6.0 or older kernels as the fourcc bits and considerable churn > came in with the 6.1 merge window. You don't happen to have a > backport of this to 6.0 do you? v1 is probably closer to such a backport, and I offered to figure it out on Matrix but I heard you're already working on it ;) - Hector
On Mon, Oct 31, 2022 at 11:52 AM Hector Martin <marcan@marcan.st> wrote: > > On 01/11/2022 01.15, Justin Forbes wrote: > > On Thu, Oct 27, 2022 at 8:57 AM Hector Martin <marcan@marcan.st> wrote: > >> > >> drm_fb_build_fourcc_list() currently returns all emulated formats > >> unconditionally as long as the native format is among them, even though > >> not all combinations have conversion helpers. Although the list is > >> arguably provided to userspace in precedence order, userspace can pick > >> something out-of-order (and thus break when it shouldn't), or simply > >> only support a format that is unsupported (and thus think it can work, > >> which results in the appearance of a hang as FB blits fail later on, > >> instead of the initialization error you'd expect in this case). > >> > >> Add checks to filter the list of emulated formats to only those > >> supported for conversion to the native format. This presumes that there > >> is a single native format (only the first is checked, if there are > >> multiple). Refactoring this API to drop the native list or support it > >> properly (by returning the appropriate emulated->native mapping table) > >> is left for a future patch. > >> > >> The simpledrm driver is left as-is with a full table of emulated > >> formats. This keeps all currently working conversions available and > >> drops all the broken ones (i.e. this a strict bugfix patch, adding no > >> new supported formats nor removing any actually working ones). In order > >> to avoid proliferation of emulated formats, future drivers should > >> advertise only XRGB8888 as the sole emulated format (since some > >> userspace assumes its presence). > >> > >> This fixes a real user regression where the ?RGB2101010 support commit > >> started advertising it unconditionally where not supported, and KWin > >> decided to start to use it over the native format and broke, but also > >> the fixes the spurious RGB565/RGB888 formats which have been wrongly > >> unconditionally advertised since the dawn of simpledrm. > >> > >> Fixes: 6ea966fca084 ("drm/simpledrm: Add [AX]RGB210101 > > > > > >> Cc: stable@vger.kernel.org > >> Signed-off-by: Hector Martin <marcan@marcan.st> > > > > There is a CC for stable on here, but this patch does not apply in any > > way on 6.0 or older kernels as the fourcc bits and considerable churn > > came in with the 6.1 merge window. You don't happen to have a > > backport of this to 6.0 do you? > > v1 is probably closer to such a backport, and I offered to figure it out > on Matrix but I heard you're already working on it ;) i am, but I didn't want to be, so I thought I would ask. Justin
diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index e2f76621453c..3ee59bae9d2f 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -807,6 +807,38 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t return false; } +static const uint32_t conv_from_xrgb8888[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, + DRM_FORMAT_XRGB2101010, + DRM_FORMAT_ARGB2101010, + DRM_FORMAT_RGB565, + DRM_FORMAT_RGB888, +}; + +static const uint32_t conv_from_rgb565_888[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_ARGB8888, +}; + +static bool is_conversion_supported(uint32_t from, uint32_t to) +{ + switch (from) { + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: + return is_listed_fourcc(conv_from_xrgb8888, ARRAY_SIZE(conv_from_xrgb8888), to); + case DRM_FORMAT_RGB565: + case DRM_FORMAT_RGB888: + return is_listed_fourcc(conv_from_rgb565_888, ARRAY_SIZE(conv_from_rgb565_888), to); + case DRM_FORMAT_XRGB2101010: + return to == DRM_FORMAT_ARGB2101010; + case DRM_FORMAT_ARGB2101010: + return to == DRM_FORMAT_XRGB2101010; + default: + return false; + } +} + /** * drm_fb_build_fourcc_list - Filters a list of supported color formats against * the device's native formats @@ -827,7 +859,9 @@ static bool is_listed_fourcc(const uint32_t *fourccs, size_t nfourccs, uint32_t * be handed over to drm_universal_plane_init() et al. Native formats * will go before emulated formats. Other heuristics might be applied * to optimize the order. Formats near the beginning of the list are - * usually preferred over formats near the end of the list. + * usually preferred over formats near the end of the list. Formats + * without conversion helpers will be skipped. New drivers should only + * pass in XRGB8888 and avoid exposing additional emulated formats. * * Returns: * The number of color-formats 4CC codes returned in @fourccs_out. @@ -839,7 +873,7 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, { u32 *fourccs = fourccs_out; const u32 *fourccs_end = fourccs_out + nfourccs_out; - bool found_native = false; + uint32_t native_format = 0; size_t i; /* @@ -858,26 +892,18 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, drm_dbg_kms(dev, "adding native format %p4cc\n", &fourcc); - if (!found_native) - found_native = is_listed_fourcc(driver_fourccs, driver_nfourccs, fourcc); + /* + * There should only be one native format with the current API. + * This API needs to be refactored to correctly support arbitrary + * sets of native formats, since it needs to report which native + * format to use for each emulated format. + */ + if (!native_format) + native_format = fourcc; *fourccs = fourcc; ++fourccs; } - /* - * The plane's atomic_update helper converts the framebuffer's color format - * to a native format when copying to device memory. - * - * If there is not a single format supported by both, device and - * driver, the native formats are likely not supported by the conversion - * helpers. Therefore *only* support the native formats and add a - * conversion helper ASAP. - */ - if (!found_native) { - drm_warn(dev, "Format conversion helpers required to add extra formats.\n"); - goto out; - } - /* * The extra formats, emulated by the driver, go second. */ @@ -890,6 +916,9 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, } else if (fourccs == fourccs_end) { drm_warn(dev, "Ignoring emulated format %p4cc\n", &fourcc); continue; /* end of available output buffer */ + } else if (!is_conversion_supported(fourcc, native_format)) { + drm_dbg_kms(dev, "Unsupported emulated format %p4cc\n", &fourcc); + continue; /* format is not supported for conversion */ } drm_dbg_kms(dev, "adding emulated format %p4cc\n", &fourcc); @@ -898,7 +927,6 @@ size_t drm_fb_build_fourcc_list(struct drm_device *dev, ++fourccs; } -out: return fourccs - fourccs_out; } EXPORT_SYMBOL(drm_fb_build_fourcc_list);