From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 73D1BC433EF for ; Wed, 27 Apr 2022 14:14:27 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id F344510F4DC; Wed, 27 Apr 2022 14:14:24 +0000 (UTC) Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by gabe.freedesktop.org (Postfix) with ESMTPS id 60E0310F4B0 for ; Wed, 27 Apr 2022 14:14:16 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id DE3421F753; Wed, 27 Apr 2022 14:14:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1651068853; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fy4SPdblz7yBijwS5aS0LPTS25UCN1LQ+KbGdfQzUTk=; b=M1sDXYpVcTWCLfXtKAYqR1eEK5IXRWf3910EssWmGerOyGwCnyf9r4+7tHfgHADQhJPVKS 4Z4f+/1ABIkRt6xZNMZ8ngnRcwTDF3S9HPAZaKQ6rb9dOuybrWa2QoqPppPzE3ZK0sFdPR XMx+xmInxLkEL6mumoSjL8B9GO0dkKw= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1651068853; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fy4SPdblz7yBijwS5aS0LPTS25UCN1LQ+KbGdfQzUTk=; b=EA8Sp5L7C9kdKfzCEhDGEkYS6mQ4x91tbq2aPWnUqP0DLSx5SkF2ace2IZDzajU8N2xX/F ObQ79SbaFJQT73DA== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B2FCD13AED; Wed, 27 Apr 2022 14:14:13 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id mBHqKrVPaWLfbwAAMHmgww (envelope-from ); Wed, 27 Apr 2022 14:14:13 +0000 From: Thomas Zimmermann To: javierm@redhat.com, maarten.lankhorst@linux.intel.com, mripard@kernel.org, airlied@linux.ie, daniel@ffwll.ch Subject: [PATCH 4/4] drm/format-helper: Share implementation among conversion helpers Date: Wed, 27 Apr 2022 16:14:09 +0200 Message-Id: <20220427141409.22842-5-tzimmermann@suse.de> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220427141409.22842-1-tzimmermann@suse.de> References: <20220427141409.22842-1-tzimmermann@suse.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Zimmermann , dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Provide format-independent conversion helpers for system and I/O memory. Implement most existing helpers on top of it. The source and destination formats of each conversion is handled by a per-line helper that is given to the generic implementation. Signed-off-by: Thomas Zimmermann --- drivers/gpu/drm/drm_format_helper.c | 370 ++++++++++------------------ 1 file changed, 124 insertions(+), 246 deletions(-) diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index 21d0d282c6a1..6f8030ebb56d 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -40,6 +40,95 @@ unsigned int drm_fb_clip_offset(unsigned int pitch, const struct drm_format_info } EXPORT_SYMBOL(drm_fb_clip_offset); +/* TODO: Make this functon work with multi-plane formats. */ +static int drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize, + const void *vaddr, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool vaddr_cached_hint, + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) +{ + unsigned long linepixels = drm_rect_width(clip); + unsigned long lines = drm_rect_height(clip); + size_t sbuf_len = linepixels * fb->format->cpp[0]; + void *stmp = NULL; + unsigned long i; + const void *sbuf; + + /* + * Some source buffers, such as CMA memory, use write-combine + * caching, so reads are uncached. Speed up access by fetching + * one line at a time. + */ + if (!vaddr_cached_hint) { + stmp = kmalloc(sbuf_len, GFP_KERNEL); + if (!stmp) + return -ENOMEM; + } + + if (!dst_pitch) + dst_pitch = drm_rect_width(clip) * dst_pixsize; + vaddr += clip_offset(clip, fb->pitches[0], fb->format->cpp[0]); + + for (i = 0; i < lines; ++i) { + if (stmp) + sbuf = memcpy(stmp, vaddr, sbuf_len); + else + sbuf = vaddr; + xfrm_line(dst, sbuf, linepixels); + vaddr += fb->pitches[0]; + dst += dst_pitch; + } + + kfree(stmp); + + return 0; +} + +/* TODO: Make this functon work with multi-plane formats. */ +static int drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize, + const void *vaddr, const struct drm_framebuffer *fb, + const struct drm_rect *clip, bool vaddr_cached_hint, + void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels)) +{ + unsigned long linepixels = drm_rect_width(clip); + unsigned long lines = drm_rect_height(clip); + size_t dbuf_len = linepixels * dst_pixsize; + size_t stmp_off = round_up(dbuf_len, ARCH_KMALLOC_MINALIGN); /* for sbuf alignment */ + size_t sbuf_len = linepixels * fb->format->cpp[0]; + void *stmp = NULL; + unsigned long i; + const void *sbuf; + void *dbuf; + + if (vaddr_cached_hint) { + dbuf = kmalloc(dbuf_len, GFP_KERNEL); + } else { + dbuf = kmalloc(stmp_off + sbuf_len, GFP_KERNEL); + stmp = dbuf + stmp_off; + } + if (!dbuf) + return -ENOMEM; + + if (!dst_pitch) + dst_pitch = linepixels * dst_pixsize; + vaddr += clip_offset(clip, fb->pitches[0], fb->format->cpp[0]); + + for (i = 0; i < lines; ++i) { + if (stmp) + sbuf = memcpy(stmp, vaddr, sbuf_len); + else + sbuf = vaddr; + xfrm_line(dbuf, sbuf, linepixels); + memcpy_toio(dst, dbuf, dbuf_len); + vaddr += fb->pitches[0]; + dst += dst_pitch; + } + + kfree(dbuf); + + return 0; +} + + /** * drm_fb_memcpy - Copy clip buffer * @dst: Destination buffer @@ -140,45 +229,23 @@ void drm_fb_swab(void *dst, unsigned int dst_pitch, const void *src, bool cached) { u8 cpp = fb->format->cpp[0]; - unsigned long linepixels = drm_rect_width(clip); - size_t len = linepixels * cpp; - const void *sbuf; - void *dbuf; - unsigned int y; - void *buf = NULL; - - if (WARN_ON_ONCE(cpp != 2 && cpp != 4)) - return; - - if (!dst_pitch) - dst_pitch = len; - src += clip_offset(clip, fb->pitches[0], cpp); - - if (!cached) - buf = kmalloc(len, GFP_KERNEL); - for (y = clip->y1; y < clip->y2; y++) { - if (buf) - sbuf = memcpy(buf, src, len); - else - sbuf = src; - dbuf = dst + clip->x1 * cpp; - - if (cpp == 4) - drm_fb_swab32_line(dbuf, sbuf, linepixels); - else - drm_fb_swab16_line(dbuf, sbuf, linepixels); - - src += fb->pitches[0]; - dst += dst_pitch; + switch (cpp) { + case 4: + drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, drm_fb_swab32_line); + break; + case 2: + drm_fb_xfrm(dst, dst_pitch, cpp, src, fb, clip, cached, drm_fb_swab16_line); + break; + default: + drm_warn_once(fb->dev, "Format %p4cc has unsupported pixel size.\n", + &fb->format->format); + break; } - - kfree(buf); } EXPORT_SYMBOL(drm_fb_swab); -static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels, - bool swab) +static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigned int pixels) { u8 *dbuf8 = dbuf; const __le32 *sbuf32 = sbuf; @@ -206,28 +273,7 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne void drm_fb_xrgb8888_to_rgb332(void *dst, unsigned int dst_pitch, const void *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t width = drm_rect_width(clip); - size_t src_len = width * sizeof(u32); - unsigned int y; - void *sbuf; - - if (!dst_pitch) - dst_pitch = width; - - /* Use a buffer to speed up access on buffers with uncached read mapping (i.e. WC) */ - sbuf = kmalloc(src_len, GFP_KERNEL); - if (!sbuf) - return; - - src += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < drm_rect_height(clip); y++) { - memcpy(sbuf, src, src_len); - drm_fb_xrgb8888_to_rgb332_line(dst, sbuf, width, false); - src += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(sbuf); + drm_fb_xfrm(dst, dst_pitch, 1, src, fb, clip, false, drm_fb_xrgb8888_to_rgb332_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); @@ -278,35 +324,12 @@ void drm_fb_xrgb8888_to_rgb565(void *dst, unsigned int dst_pitch, const void *va const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab) { - size_t linepixels = clip->x2 - clip->x1; - size_t src_len = linepixels * sizeof(u32); - size_t dst_len = linepixels * sizeof(u16); - unsigned y, lines = clip->y2 - clip->y1; - void *sbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - /* - * The cma memory is write-combined so reads are uncached. - * Speed up by fetching one line at a time. - */ - sbuf = kmalloc(src_len, GFP_KERNEL); - if (!sbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < lines; y++) { - memcpy(sbuf, vaddr, src_len); - if (swab) - drm_fb_xrgb8888_to_rgb565_swab_line(dst, sbuf, linepixels); - else - drm_fb_xrgb8888_to_rgb565_line(dst, sbuf, linepixels); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(sbuf); + if (swab) + drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_rgb565_swab_line); + else + drm_fb_xfrm(dst, dst_pitch, 2, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_rgb565_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); @@ -326,30 +349,12 @@ void drm_fb_xrgb8888_to_rgb565_toio(void __iomem *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip, bool swab) { - size_t linepixels = clip->x2 - clip->x1; - size_t dst_len = linepixels * sizeof(u16); - unsigned y, lines = clip->y2 - clip->y1; - void *dbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - dbuf = kmalloc(dst_len, GFP_KERNEL); - if (!dbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < lines; y++) { - if (swab) - drm_fb_xrgb8888_to_rgb565_swab_line(dbuf, vaddr, linepixels); - else - drm_fb_xrgb8888_to_rgb565_line(dbuf, vaddr, linepixels); - memcpy_toio(dst, dbuf, dst_len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(dbuf); + if (swab) + drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_rgb565_swab_line); + else + drm_fb_xfrm_toio(dst, dst_pitch, 2, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_rgb565_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565_toio); @@ -380,28 +385,7 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne void drm_fb_xrgb8888_to_rgb888(void *dst, unsigned int dst_pitch, const void *src, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t width = drm_rect_width(clip); - size_t src_len = width * sizeof(u32); - unsigned int y; - void *sbuf; - - if (!dst_pitch) - dst_pitch = width * 3; - - /* Use a buffer to speed up access on buffers with uncached read mapping (i.e. WC) */ - sbuf = kmalloc(src_len, GFP_KERNEL); - if (!sbuf) - return; - - src += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < drm_rect_height(clip); y++) { - memcpy(sbuf, src, src_len); - drm_fb_xrgb8888_to_rgb888_line(dst, sbuf, width); - src += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(sbuf); + drm_fb_xfrm(dst, dst_pitch, 3, src, fb, clip, false, drm_fb_xrgb8888_to_rgb888_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); @@ -420,27 +404,8 @@ void drm_fb_xrgb8888_to_rgb888_toio(void __iomem *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t linepixels = clip->x2 - clip->x1; - size_t dst_len = linepixels * 3; - unsigned y, lines = clip->y2 - clip->y1; - void *dbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - dbuf = kmalloc(dst_len, GFP_KERNEL); - if (!dbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < lines; y++) { - drm_fb_xrgb8888_to_rgb888_line(dbuf, vaddr, linepixels); - memcpy_toio(dst, dbuf, dst_len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(dbuf); + drm_fb_xfrm_toio(dst, dst_pitch, 3, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_rgb888_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888_toio); @@ -464,27 +429,8 @@ static void drm_fb_rgb565_to_xrgb8888_toio(void __iomem *dst, unsigned int dst_p const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t linepixels = drm_rect_width(clip); - size_t dst_len = linepixels * 4; - unsigned int y, lines = drm_rect_height(clip); - void *dbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - dbuf = kmalloc(dst_len, GFP_KERNEL); - if (!dbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], 2); - for (y = 0; y < lines; y++) { - drm_fb_rgb565_to_xrgb8888_line(dbuf, vaddr, linepixels); - memcpy_toio(dst, dbuf, dst_len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(dbuf); + drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, + drm_fb_rgb565_to_xrgb8888_line); } static void drm_fb_rgb888_to_xrgb8888_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -505,27 +451,8 @@ static void drm_fb_rgb888_to_xrgb8888_toio(void __iomem *dst, unsigned int dst_p const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t linepixels = drm_rect_width(clip); - size_t dst_len = linepixels * 4; - unsigned int y, lines = drm_rect_height(clip); - void *dbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - dbuf = kmalloc(dst_len, GFP_KERNEL); - if (!dbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], 3); - for (y = 0; y < lines; y++) { - drm_fb_rgb888_to_xrgb8888_line(dbuf, vaddr, linepixels); - memcpy_toio(dst, dbuf, dst_len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(dbuf); + drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, + drm_fb_rgb888_to_xrgb8888_line); } static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, unsigned int pixels) @@ -560,27 +487,8 @@ void drm_fb_xrgb8888_to_xrgb2101010_toio(void __iomem *dst, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - size_t linepixels = clip->x2 - clip->x1; - size_t dst_len = linepixels * sizeof(u32); - unsigned int y, lines = clip->y2 - clip->y1; - void *dbuf; - - if (!dst_pitch) - dst_pitch = dst_len; - - dbuf = kmalloc(dst_len, GFP_KERNEL); - if (!dbuf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = 0; y < lines; y++) { - drm_fb_xrgb8888_to_xrgb2101010_line(dbuf, vaddr, linepixels); - memcpy_toio(dst, dbuf, dst_len); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(dbuf); + drm_fb_xfrm_toio(dst, dst_pitch, 4, vaddr, fb, clip, false, + drm_fb_xrgb8888_to_xrgb2101010_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010_toio); @@ -621,37 +529,7 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned void drm_fb_xrgb8888_to_gray8(void *dst, unsigned int dst_pitch, const void *vaddr, const struct drm_framebuffer *fb, const struct drm_rect *clip) { - unsigned int linepixels = clip->x2 - clip->x1; - unsigned int len = linepixels * sizeof(u32); - unsigned int y; - void *buf; - u8 *dst8; - u32 *src32; - - if (WARN_ON(fb->format->format != DRM_FORMAT_XRGB8888)) - return; - - if (!dst_pitch) - dst_pitch = drm_rect_width(clip); - - /* - * The cma memory is write-combined so reads are uncached. - * Speed up by fetching one line at a time. - */ - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return; - - vaddr += clip_offset(clip, fb->pitches[0], sizeof(u32)); - for (y = clip->y1; y < clip->y2; y++) { - dst8 = dst; - src32 = memcpy(buf, vaddr, len); - drm_fb_xrgb8888_to_gray8_line(dst8, src32, linepixels); - vaddr += fb->pitches[0]; - dst += dst_pitch; - } - - kfree(buf); + drm_fb_xfrm(dst, dst_pitch, 1, vaddr, fb, clip, false, drm_fb_xrgb8888_to_gray8_line); } EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); -- 2.36.0