Skip to content

Instantly share code, notes, and snippets.

@notro
Created March 9, 2021 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notro/a94d381cf98b7e15fcddbc90e4af0a21 to your computer and use it in GitHub Desktop.
Save notro/a94d381cf98b7e15fcddbc90e4af0a21 to your computer and use it in GitHub Desktop.
gud: Fix R1 and RGB111
From 3e1ad239a4382f2da5bc7466cb3cfb28e235be0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= <noralf@tronnes.org>
Date: Tue, 9 Mar 2021 15:14:18 +0100
Subject: [PATCH v8 11/11] gud: Fix R1 and RGB111
---
drivers/gpu/drm/gud/gud_drv.c | 2 +-
drivers/gpu/drm/gud/gud_pipe.c | 49 +++++++++++++++++++++-------------
2 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index 75ed3dc4333d..4d4345e4060c 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -511,7 +511,7 @@ static int gud_probe(struct usb_interface *intf, const struct usb_device_id *id)
drm->mode_config.max_height;
max_buffer_size = max(max_buffer_size, fmt_buf_size);
- if (format == GUD_DRM_FORMAT_R1)
+ if (format == GUD_DRM_FORMAT_R1 || format == GUD_DRM_FORMAT_RGB111)
continue; /* Internal not for userspace */
formats[num_formats++] = format;
diff --git a/drivers/gpu/drm/gud/gud_pipe.c b/drivers/gpu/drm/gud/gud_pipe.c
index 5623fbf27c04..91914026bf13 100644
--- a/drivers/gpu/drm/gud/gud_pipe.c
+++ b/drivers/gpu/drm/gud/gud_pipe.c
@@ -39,7 +39,7 @@ static size_t gud_xrgb8888_to_r124(u8 *dst, const struct drm_format_info *format
unsigned int block_width = drm_format_info_block_width(format, 0);
unsigned int bits_per_pixel = 8 / block_width;
unsigned int x, y, width, height;
- u8 *p, *block = dst; /* Assign to silence compiler warning */
+ u8 pix, *pix8, *block = dst; /* Assign to silence compiler warning */
size_t len;
void *buf;
@@ -56,17 +56,20 @@ static size_t gud_xrgb8888_to_r124(u8 *dst, const struct drm_format_info *format
return 0;
drm_fb_xrgb8888_to_gray8(buf, src, fb, rect);
+ pix8 = buf;
- p = buf;
- for (y = 0; y < drm_rect_height(rect); y++) {
- for (x = 0; x < drm_rect_width(rect); x++) {
- if (!(x % block_width)) {
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ unsigned int pixpos = x % block_width; /* within byte from the left */
+ unsigned int pixshift = (block_width - pixpos - 1) * bits_per_pixel;
+
+ if (!pixpos) {
block = dst++;
*block = 0;
}
- *block <<= bits_per_pixel;
- *block |= (*p++) >> (8 - bits_per_pixel);
+ pix = (*pix8++) >> (8 - bits_per_pixel);
+ *block |= pix << pixshift;
}
}
@@ -76,40 +79,48 @@ static size_t gud_xrgb8888_to_r124(u8 *dst, const struct drm_format_info *format
}
static size_t gud_xrgb8888_to_color(u8 *dst, const struct drm_format_info *format,
- u32 *src, struct drm_framebuffer *fb,
+ void *src, struct drm_framebuffer *fb,
struct drm_rect *rect)
{
unsigned int block_width = drm_format_info_block_width(format, 0);
- unsigned int x, y, width, height;
- u8 r, g, b, *block = dst; /* Assign to silence compiler warning */
+ unsigned int bits_per_pixel = 8 / block_width;
+ u8 r, g, b, pix, *block = dst; /* Assign to silence compiler warning */
+ unsigned int x, y, width;
+ u32 *pix32;
size_t len;
/* Start on a byte boundary */
rect->x1 = ALIGN_DOWN(rect->x1, block_width);
width = drm_rect_width(rect);
- height = drm_rect_height(rect);
- len = drm_format_info_min_pitch(format, 0, width) * height;
+ len = drm_format_info_min_pitch(format, 0, width) * drm_rect_height(rect);
+
+ for (y = rect->y1; y < rect->y2; y++) {
+ pix32 = src + (y * fb->pitches[0]);
+ pix32 += rect->x1;
- for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
- if (!(x % block_width)) {
+ unsigned int pixpos = x % block_width; /* within byte from the left */
+ unsigned int pixshift = (block_width - pixpos - 1) * bits_per_pixel;
+
+ if (!pixpos) {
block = dst++;
*block = 0;
}
- r = *src >> 16;
- g = *src >> 8;
- b = *src++;
+ r = *pix32 >> 16;
+ g = *pix32 >> 8;
+ b = *pix32++;
switch (format->format) {
case GUD_DRM_FORMAT_RGB111:
- *block <<= 4;
- *block |= ((r >> 7) << 2) | ((g >> 7) << 1) | (b >> 7);
+ pix = ((r >> 7) << 2) | ((g >> 7) << 1) | (b >> 7);
break;
default:
WARN_ON_ONCE(1);
return len;
};
+
+ *block |= pix << pixshift;
}
}
--
2.23.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment