[PATCH 2/2] drm/mgag200: Use 24bit format in VRAM
Jocelyn Falempe
jfalempe at redhat.com
Wed Apr 12 13:39:12 UTC 2023
The bandwidth between system memory and VRAM is very limited
on G200.
So when using a 32bit framebuffer on system memory, convert it to 24bit
when copying the frame to the VRAM, this allows to go 33% faster.
Converting the format on the fly is negligible, even on low end CPU.
small benchmark on my Dell T310:
1280x1024 32bits: ~125ms to transfert a single frame.
1280x1024 24bits: ~95ms
Signed-off-by: Jocelyn Falempe <jfalempe at redhat.com>
---
drivers/gpu/drm/mgag200/mgag200_mode.c | 28 ++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index e3f0da338b95..a8d6b08bf959 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -289,6 +289,8 @@ void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mod
static u32 mgag200_calculate_offset(struct mga_device *mdev,
const struct drm_framebuffer *fb)
{
+ if (fb->format->format == DRM_FORMAT_XRGB8888)
+ return (fb->pitches[0] * 3) >> 6;
return fb->pitches[0] >> 4;
}
@@ -314,17 +316,16 @@ void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_in
struct drm_device *dev = &mdev->base;
unsigned int scale;
u8 crtcext3, xmulctrl;
+ u8 cpp;
switch (format->format) {
case DRM_FORMAT_RGB565:
xmulctrl = MGA1064_MUL_CTL_16bits;
break;
+ case DRM_FORMAT_XRGB8888: /* use 24bit format in VRAM */
case DRM_FORMAT_RGB888:
xmulctrl = MGA1064_MUL_CTL_24bits;
break;
- case DRM_FORMAT_XRGB8888:
- xmulctrl = MGA1064_MUL_CTL_32_24bits;
- break;
default:
/* BUG: We should have caught this problem already. */
drm_WARN_ON(dev, "invalid drm format\n");
@@ -346,8 +347,12 @@ void mgag200_set_format_regs(struct mga_device *mdev, const struct drm_format_in
WREG_GFX(7, 0x0f);
WREG_GFX(8, 0x0f);
+ cpp = format->cpp[0];
+ if (cpp == 4) /* use 24 bit format in VRAM */
+ cpp = 3;
+
/* scale is the number of bytes per pixels - 1 */
- scale = format->cpp[0] - 1;
+ scale = cpp - 1;
RREG_ECRT(3, crtcext3);
crtcext3 &= ~GENMASK(2, 0);
@@ -403,8 +408,19 @@ static void mgag200_handle_damage(struct mga_device *mdev, const struct iosys_ma
{
struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(mdev->vram);
- iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));
- drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip);
+ if (fb->format->format == DRM_FORMAT_XRGB8888) {
+ /* use 24 bit format for VRAM, to save memory bandwidth,
+ * converting on the fly is much faster than sending the bytes
+ */
+ u32 dst_pitch[3] = {(fb->pitches[0] * 3) / 4,
+ (fb->pitches[1] * 3) / 4,
+ (fb->pitches[2] * 3) / 4};
+ iosys_map_incr(&dst, clip->y1 * dst_pitch[0] + clip->x1 * 3);
+ drm_fb_xrgb8888_to_rgb888(&dst, dst_pitch, vmap, fb, clip);
+ } else {
+ iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));
+ drm_fb_memcpy(&dst, fb->pitches, vmap, fb, clip);
+ }
}
/*
--
2.39.2
More information about the dri-devel
mailing list