* [PATCH libdrm v3 1/9] intel: improve checks for big-endian
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 2/9] util: fix 32 bpp patterns on big-endian Geert Uytterhoeven
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
- sparc64-linux-gnu-gcc does not define __BIG_ENDIAN__ or SPARC, but
does define __sparc__, hence replace the check for SPARC by a check
for __sparc__,
- powerpc{,64,64}-linux-gnu-gcc does not define __ppc__ or __ppc64__,
but does define __BIG_ENDIAN__.
powerpc64le-linux-gnu-gcc does not define __ppc__ or __ppc64__, but
does define __LITTLE_ENDIAN__.
Hence remove the checks for __ppc__ and __ppc64__.
- arm-linux-gnueabi-gcc and aarch64-linux-gnu-gcc do not define
__BIG_ENDIAN__ for targets in big-endian mode, but do define
__ARM_BIG_ENDIAN, so add a check for the latter,
- m68k-linux-gnu-gcc does not define __BIG_ENDIAN__, but does define
__mc68000__, so add a check for the latter,
- mips{,64}-linux-gnu{,abi64}-gcc does not define __BIG_ENDIAN__, but
does define __MIPSEB__, so add a check for the latter,
- s390x-linux-gnu-gcc does not define __BIG_ENDIAN__, but does define
__s390__, so add a check for the latter,
- hppa{,64}-linux-gnu-gcc, microblaze-linux-gcc, and sh4-linux-gnu-gcc
in big-endian mode do define __BIG_ENDIAN__, and thus should work
out-of-the-box.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- No changes,
v2:
- Add arm, aarch64, microblaze, s390, and sh.
---
intel/uthash.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/intel/uthash.h b/intel/uthash.h
index 45d1f9fc12a1d6f9..a8465f23ff9fbcac 100644
--- a/intel/uthash.h
+++ b/intel/uthash.h
@@ -648,7 +648,7 @@ do {
#define MUR_PLUS2_ALIGNED(p) (((unsigned long)p & 3UL) == 2UL)
#define MUR_PLUS3_ALIGNED(p) (((unsigned long)p & 3UL) == 3UL)
#define WP(p) ((uint32_t*)((unsigned long)(p) & ~3UL))
-#if (defined(__BIG_ENDIAN__) || defined(SPARC) || defined(__ppc__) || defined(__ppc64__))
+#if (defined(__BIG_ENDIAN__) || defined(__ARM_BIG_ENDIAN) || defined(__mc68000__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__))
#define MUR_THREE_ONE(p) ((((*WP(p))&0x00ffffff) << 8) | (((*(WP(p)+1))&0xff000000) >> 24))
#define MUR_TWO_TWO(p) ((((*WP(p))&0x0000ffff) <<16) | (((*(WP(p)+1))&0xffff0000) >> 16))
#define MUR_ONE_THREE(p) ((((*WP(p))&0x000000ff) <<24) | (((*(WP(p)+1))&0xffffff00) >> 8))
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 2/9] util: fix 32 bpp patterns on big-endian
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 1/9] intel: improve checks for big-endian Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 3/9] util: fix 16 " Geert Uytterhoeven
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Pekka Paalanen, Geert Uytterhoeven
DRM formats are defined to be little-endian, unless the
DRM_FORMAT_BIG_ENDIAN flag is set. Hence writes of multi-byte pixel
values need to take endianness into account.
Introduce a swap32() helper to byteswap 32-bit values, and a
cpu_to_le32() helper to convert 32-bit values from CPU-endian to
little-endian, and use the latter in the various pattern fill functions
for 32-bit formats.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
---
v3:
- Increase indentation after definition of cpu_to_le32(),
v2:
- Add Acked-by,
- Add swap32() intermediate helper,
- Add __ARM_BIG_ENDIAN and __s390__.
---
tests/util/pattern.c | 32 +++++++++++++++++++++++---------
1 file changed, 23 insertions(+), 9 deletions(-)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index f69c5206d96eff02..79d56bd1413cf53c 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -61,6 +61,20 @@ struct color_yuv {
.u = MAKE_YUV_601_U(r, g, b), \
.v = MAKE_YUV_601_V(r, g, b) }
+static inline uint32_t swap32(uint32_t x)
+{
+ return ((x & 0x000000ffU) << 24) |
+ ((x & 0x0000ff00U) << 8) |
+ ((x & 0x00ff0000U) >> 8) |
+ ((x & 0xff000000U) >> 24);
+}
+
+#if defined(__BIG_ENDIAN__) || defined(__ARM_BIG_ENDIAN) || defined(__mc68000__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__)
+#define cpu_to_le32(x) swap32(x)
+#else
+#define cpu_to_le32(x) (x)
+#endif
+
/* This function takes 8-bit color values */
static inline uint32_t shiftcolor8(const struct util_color_component *comp,
uint32_t value)
@@ -520,26 +534,26 @@ static void fill_smpte_rgb32(const struct util_rgb_info *rgb, void *mem,
for (y = 0; y < height * 6 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint32_t *)mem)[x] = colors_top[x * 7 / width];
+ ((uint32_t *)mem)[x] = cpu_to_le32(colors_top[x * 7 / width]);
mem += stride;
}
for (; y < height * 7 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint32_t *)mem)[x] = colors_middle[x * 7 / width];
+ ((uint32_t *)mem)[x] = cpu_to_le32(colors_middle[x * 7 / width]);
mem += stride;
}
for (; y < height; ++y) {
for (x = 0; x < width * 5 / 7; ++x)
((uint32_t *)mem)[x] =
- colors_bottom[x * 4 / (width * 5 / 7)];
+ cpu_to_le32(colors_bottom[x * 4 / (width * 5 / 7)]);
for (; x < width * 6 / 7; ++x)
((uint32_t *)mem)[x] =
- colors_bottom[(x - width * 5 / 7) * 3
- / (width / 7) + 4];
+ cpu_to_le32(colors_bottom[(x - width * 5 / 7) * 3
+ / (width / 7) + 4]);
for (; x < width; ++x)
- ((uint32_t *)mem)[x] = colors_bottom[7];
+ ((uint32_t *)mem)[x] = cpu_to_le32(colors_bottom[7]);
mem += stride;
}
}
@@ -1315,7 +1329,7 @@ static void fill_tiles_rgb32(const struct util_format_info *info, void *mem,
(rgb32 >> 8) & 0xff, rgb32 & 0xff,
alpha);
- ((uint32_t *)mem)[x] = color;
+ ((uint32_t *)mem)[x] = cpu_to_le32(color);
}
mem += stride;
}
@@ -1464,7 +1478,7 @@ static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
for (j = 0; j < width / 2; j++) {
uint32_t value = MAKE_RGBA10(rgb, j & 0x3ff, j & 0x3ff, j & 0x3ff, 0);
- row[2*j] = row[2*j+1] = value;
+ row[2*j] = row[2*j+1] = cpu_to_le32(value);
}
mem += stride;
}
@@ -1474,7 +1488,7 @@ static void fill_gradient_rgb32(const struct util_rgb_info *rgb,
for (j = 0; j < width / 2; j++) {
uint32_t value = MAKE_RGBA10(rgb, j & 0x3fc, j & 0x3fc, j & 0x3fc, 0);
- row[2*j] = row[2*j+1] = value;
+ row[2*j] = row[2*j+1] = cpu_to_le32(value);
}
mem += stride;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 3/9] util: fix 16 bpp patterns on big-endian
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 1/9] intel: improve checks for big-endian Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 2/9] util: fix 32 bpp patterns on big-endian Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 4/9] util: add missing big-endian RGB16 frame buffer formats Geert Uytterhoeven
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
DRM formats are defined to be little-endian, unless the
DRM_FORMAT_BIG_ENDIAN flag is set. Hence writes of multi-byte pixel
values need to take endianness into account.
Introduce a swap16() helper to byteswap 16-bit values, and a
cpu_to_le16() helper to convert 16-bit values from CPU-endian to
little-endian, and use the latter in the various pattern fill functions
for 16-bit formats.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- Increase indentation after definition of cpu_to_le16(),
v2:
- New.
---
tests/util/pattern.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 79d56bd1413cf53c..89e79277c53fe1fe 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -61,6 +61,11 @@ struct color_yuv {
.u = MAKE_YUV_601_U(r, g, b), \
.v = MAKE_YUV_601_V(r, g, b) }
+static inline uint16_t swap16(uint16_t x)
+{
+ return ((x & 0x00ffU) << 8) | ((x & 0xff00U) >> 8);
+}
+
static inline uint32_t swap32(uint32_t x)
{
return ((x & 0x000000ffU) << 24) |
@@ -70,8 +75,10 @@ static inline uint32_t swap32(uint32_t x)
}
#if defined(__BIG_ENDIAN__) || defined(__ARM_BIG_ENDIAN) || defined(__mc68000__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__)
+#define cpu_to_le16(x) swap16(x)
#define cpu_to_le32(x) swap32(x)
#else
+#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#endif
@@ -410,26 +417,26 @@ static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
for (y = 0; y < height * 6 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint16_t *)mem)[x] = colors_top[x * 7 / width];
+ ((uint16_t *)mem)[x] = cpu_to_le16(colors_top[x * 7 / width]);
mem += stride;
}
for (; y < height * 7 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint16_t *)mem)[x] = colors_middle[x * 7 / width];
+ ((uint16_t *)mem)[x] = cpu_to_le16(colors_middle[x * 7 / width]);
mem += stride;
}
for (; y < height; ++y) {
for (x = 0; x < width * 5 / 7; ++x)
((uint16_t *)mem)[x] =
- colors_bottom[x * 4 / (width * 5 / 7)];
+ cpu_to_le16(colors_bottom[x * 4 / (width * 5 / 7)]);
for (; x < width * 6 / 7; ++x)
((uint16_t *)mem)[x] =
- colors_bottom[(x - width * 5 / 7) * 3
- / (width / 7) + 4];
+ cpu_to_le16(colors_bottom[(x - width * 5 / 7) * 3
+ / (width / 7) + 4]);
for (; x < width; ++x)
- ((uint16_t *)mem)[x] = colors_bottom[7];
+ ((uint16_t *)mem)[x] = cpu_to_le16(colors_bottom[7]);
mem += stride;
}
}
@@ -1280,7 +1287,7 @@ static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
(rgb32 >> 8) & 0xff, rgb32 & 0xff,
255);
- ((uint16_t *)mem)[x] = color;
+ ((uint16_t *)mem)[x] = cpu_to_le16(color);
}
mem += stride;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 4/9] util: add missing big-endian RGB16 frame buffer formats
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (2 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 3/9] util: fix 16 " Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 5/9] modetest: add support for parsing big-endian formats Geert Uytterhoeven
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- Update for suffix change from "be" to "_BE", cfr. commit
ffb9375a505700ad ("xf86drm: handle DRM_FORMAT_BIG_ENDIAN in
drmGetFormatName()"),
v2:
- New.
---
tests/util/format.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/tests/util/format.c b/tests/util/format.c
index b99cc9c3599d9237..376a32fe4b485238 100644
--- a/tests/util/format.c
+++ b/tests/util/format.c
@@ -78,6 +78,9 @@ static const struct util_format_info format_info[] = {
{ DRM_FORMAT_BGRX5551, "BX15", MAKE_RGB_INFO(5, 1, 5, 6, 5, 11, 0, 0) },
{ DRM_FORMAT_RGB565, "RG16", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
{ DRM_FORMAT_BGR565, "BG16", MAKE_RGB_INFO(5, 0, 6, 5, 5, 11, 0, 0) },
+ /* Big-endian RGB16 */
+ { DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN, "XR15_BE", MAKE_RGB_INFO(5, 10, 5, 5, 5, 0, 0, 0) },
+ { DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN, "RG16_BE", MAKE_RGB_INFO(5, 11, 6, 5, 5, 0, 0, 0) },
/* RGB24 */
{ DRM_FORMAT_BGR888, "BG24", MAKE_RGB_INFO(8, 0, 8, 8, 8, 16, 0, 0) },
{ DRM_FORMAT_RGB888, "RG24", MAKE_RGB_INFO(8, 16, 8, 8, 8, 0, 0, 0) },
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 5/9] modetest: add support for parsing big-endian formats
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (3 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 4/9] util: add missing big-endian RGB16 frame buffer formats Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 6/9] util: add test pattern support for big-endian XRGB1555/RGB565 Geert Uytterhoeven
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
When specifying a frame buffer format like "RG16_BE" (big-endian RG16),
modetest still uses the little-endian variant, as the format string is
truncated to four characters.
Fix this by increasing the format string size to 8 bytes (7 characters +
NUL terminator).
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- Update for suffix change from "be" to "_BE", cfr. commit
ffb9375a505700ad ("xf86drm: handle DRM_FORMAT_BIG_ENDIAN in
drmGetFormatName()"),
- Replace hardcoded numbers in code by sizeof(),
v2:
- New.
---
tests/modetest/modetest.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
index 9b1aa537be8716cf..cc96015f4a555dd3 100644
--- a/tests/modetest/modetest.c
+++ b/tests/modetest/modetest.c
@@ -817,7 +817,7 @@ struct pipe_arg {
unsigned int num_cons;
uint32_t crtc_id;
char mode_str[64];
- char format_str[5];
+ char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
float vrefresh;
unsigned int fourcc;
drmModeModeInfo *mode;
@@ -841,7 +841,7 @@ struct plane_arg {
unsigned int old_fb_id;
struct bo *bo;
struct bo *old_bo;
- char format_str[5]; /* need to leave room for terminating \0 */
+ char format_str[8]; /* need to leave room for "_BE" and terminating \0 */
unsigned int fourcc;
};
@@ -2032,8 +2032,9 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
}
if (*p == '@') {
- strncpy(pipe->format_str, p + 1, 4);
- pipe->format_str[4] = '\0';
+ len = sizeof(pipe->format_str) - 1;
+ strncpy(pipe->format_str, p + 1, len);
+ pipe->format_str[len] = '\0';
}
pipe->fourcc = util_format_fourcc(pipe->format_str);
@@ -2047,6 +2048,7 @@ static int parse_connector(struct pipe_arg *pipe, const char *arg)
static int parse_plane(struct plane_arg *plane, const char *p)
{
+ unsigned int len;
char *end;
plane->plane_id = strtoul(p, &end, 10);
@@ -2085,8 +2087,9 @@ static int parse_plane(struct plane_arg *plane, const char *p)
}
if (*end == '@') {
- strncpy(plane->format_str, end + 1, 4);
- plane->format_str[4] = '\0';
+ len = sizeof(plane->format_str) - 1;
+ strncpy(plane->format_str, end + 1, len);
+ plane->format_str[len] = '\0';
} else {
strcpy(plane->format_str, "XR24");
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 6/9] util: add test pattern support for big-endian XRGB1555/RGB565
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (4 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 5/9] modetest: add support for parsing big-endian formats Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 7/9] util: fix pwetty on big-endian Geert Uytterhoeven
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
Add support for drawing the SMPTE and tiles test patterns in buffers
using big-endian formats.
For now this is limited to XRGB1555 and RGB565, which are the most
common big-endian formats.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- Increase indentation after definition of cpu_to_be16(),
v2:
- New.
---
tests/util/pattern.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 89e79277c53fe1fe..1eee384f4c611d24 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -23,6 +23,7 @@
* IN THE SOFTWARE.
*/
+#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -75,13 +76,17 @@ static inline uint32_t swap32(uint32_t x)
}
#if defined(__BIG_ENDIAN__) || defined(__ARM_BIG_ENDIAN) || defined(__mc68000__) || defined(__MIPSEB__) || defined(__s390__) || defined(__sparc__)
+#define cpu_to_be16(x) (x)
#define cpu_to_le16(x) swap16(x)
#define cpu_to_le32(x) swap32(x)
#else
+#define cpu_to_be16(x) swap16(x)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#endif
+#define cpu_to_fb16(x) (fb_be ? cpu_to_be16(x) : cpu_to_le16(x))
+
/* This function takes 8-bit color values */
static inline uint32_t shiftcolor8(const struct util_color_component *comp,
uint32_t value)
@@ -382,7 +387,7 @@ static void fill_smpte_yuv_packed(const struct util_yuv_info *yuv, void *mem,
static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
unsigned int width, unsigned int height,
- unsigned int stride)
+ unsigned int stride, bool fb_be)
{
const uint16_t colors_top[] = {
MAKE_RGBA(rgb, 192, 192, 192, 255), /* grey */
@@ -417,26 +422,26 @@ static void fill_smpte_rgb16(const struct util_rgb_info *rgb, void *mem,
for (y = 0; y < height * 6 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint16_t *)mem)[x] = cpu_to_le16(colors_top[x * 7 / width]);
+ ((uint16_t *)mem)[x] = cpu_to_fb16(colors_top[x * 7 / width]);
mem += stride;
}
for (; y < height * 7 / 9; ++y) {
for (x = 0; x < width; ++x)
- ((uint16_t *)mem)[x] = cpu_to_le16(colors_middle[x * 7 / width]);
+ ((uint16_t *)mem)[x] = cpu_to_fb16(colors_middle[x * 7 / width]);
mem += stride;
}
for (; y < height; ++y) {
for (x = 0; x < width * 5 / 7; ++x)
((uint16_t *)mem)[x] =
- cpu_to_le16(colors_bottom[x * 4 / (width * 5 / 7)]);
+ cpu_to_fb16(colors_bottom[x * 4 / (width * 5 / 7)]);
for (; x < width * 6 / 7; ++x)
((uint16_t *)mem)[x] =
- cpu_to_le16(colors_bottom[(x - width * 5 / 7) * 3
+ cpu_to_fb16(colors_bottom[(x - width * 5 / 7) * 3
/ (width / 7) + 4]);
for (; x < width; ++x)
- ((uint16_t *)mem)[x] = cpu_to_le16(colors_bottom[7]);
+ ((uint16_t *)mem)[x] = cpu_to_fb16(colors_bottom[7]);
mem += stride;
}
}
@@ -1089,9 +1094,11 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRA4444:
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@@ -1099,7 +1106,8 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
return fill_smpte_rgb16(&info->rgb, planes[0],
- width, height, stride);
+ width, height, stride,
+ info->format & DRM_FORMAT_BIG_ENDIAN);
case DRM_FORMAT_BGR888:
case DRM_FORMAT_RGB888:
@@ -1271,7 +1279,7 @@ static void fill_tiles_yuv_packed(const struct util_format_info *info,
static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
unsigned int width, unsigned int height,
- unsigned int stride)
+ unsigned int stride, bool fb_be)
{
const struct util_rgb_info *rgb = &info->rgb;
void *mem_base = mem;
@@ -1287,7 +1295,7 @@ static void fill_tiles_rgb16(const struct util_format_info *info, void *mem,
(rgb32 >> 8) & 0xff, rgb32 & 0xff,
255);
- ((uint16_t *)mem)[x] = cpu_to_le16(color);
+ ((uint16_t *)mem)[x] = cpu_to_fb16(color);
}
mem += stride;
}
@@ -1411,9 +1419,11 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRA4444:
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@@ -1421,7 +1431,8 @@ static void fill_tiles(const struct util_format_info *info, void *planes[3],
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
return fill_tiles_rgb16(info, planes[0],
- width, height, stride);
+ width, height, stride,
+ info->format & DRM_FORMAT_BIG_ENDIAN);
case DRM_FORMAT_BGR888:
case DRM_FORMAT_RGB888:
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 7/9] util: fix pwetty on big-endian
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (5 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 6/9] util: add test pattern support for big-endian XRGB1555/RGB565 Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 8/9] util: add pwetty support for big-endian RGB565 Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 9/9] modetest: add support for big-endian XRGB1555/RGB565 Geert Uytterhoeven
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
Cairo always uses native byte order for rendering.
Hence if the byte order of the frame buffer differs from the byte order
of the CPU, the frame buffer contents need to be byteswapped twice: once
before rendering, to convert to native byte order, and a second time
after rendering, to restore the frame buffer format's byte order.
Note that byte swapping is not done for ARGB32 formats, as for these
formats, byte order only affects the order of the red, green, and blue
channels, which we do not care about here.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- Wrap byteswap_buffer{16,32}() implementation inside #if HAVE_CAIRO
to avoid defined-but-not-used compiler warnings,
v2:
- RGB30 is untested.
---
tests/util/pattern.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index 1eee384f4c611d24..aeac84a9b0dfed09 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -79,10 +79,12 @@ static inline uint32_t swap32(uint32_t x)
#define cpu_to_be16(x) (x)
#define cpu_to_le16(x) swap16(x)
#define cpu_to_le32(x) swap32(x)
+#define fb_foreign_endian(format) (!((format) & DRM_FORMAT_BIG_ENDIAN))
#else
#define cpu_to_be16(x) swap16(x)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
+#define fb_foreign_endian(format) ((format) & DRM_FORMAT_BIG_ENDIAN)
#endif
#define cpu_to_fb16(x) (fb_be ? cpu_to_be16(x) : cpu_to_le16(x))
@@ -1141,6 +1143,32 @@ static void fill_smpte(const struct util_format_info *info, void *planes[3],
}
}
+#if HAVE_CAIRO
+static void byteswap_buffer16(void *mem, unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint16_t *)mem)[x] = swap16(((uint16_t *)mem)[x]);
+ mem += stride;
+ }
+}
+
+static void byteswap_buffer32(void *mem, unsigned int width, unsigned int height,
+ unsigned int stride)
+{
+ unsigned int x, y;
+
+ for (y = 0; y < height; ++y) {
+ for (x = 0; x < width; ++x)
+ ((uint32_t *)mem)[x] = swap32(((uint32_t *)mem)[x]);
+ mem += stride;
+ }
+}
+#endif
+
static void make_pwetty(void *data, unsigned int width, unsigned int height,
unsigned int stride, uint32_t format)
{
@@ -1148,6 +1176,8 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
cairo_surface_t *surface;
cairo_t *cr;
cairo_format_t cairo_format;
+ bool swap16 = false;
+ bool swap32 = false;
/* we can ignore the order of R,G,B channels */
switch (format) {
@@ -1160,6 +1190,7 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
case DRM_FORMAT_RGB565:
case DRM_FORMAT_BGR565:
cairo_format = CAIRO_FORMAT_RGB16_565;
+ swap16 = fb_foreign_endian(format);
break;
#if CAIRO_VERSION_MAJOR > 1 || (CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR >= 12)
case DRM_FORMAT_ARGB2101010:
@@ -1167,12 +1198,19 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
case DRM_FORMAT_ABGR2101010:
case DRM_FORMAT_XBGR2101010:
cairo_format = CAIRO_FORMAT_RGB30;
+ swap32 = fb_foreign_endian(format);
break;
#endif
default:
return;
}
+ /* Cairo uses native byte order, so we may have to byteswap before... */
+ if (swap16)
+ byteswap_buffer16(data, width, height, stride);
+ if (swap32)
+ byteswap_buffer32(data, width, height, stride);
+
surface = cairo_image_surface_create_for_data(data,
cairo_format,
width, height,
@@ -1208,6 +1246,12 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
}
cairo_destroy(cr);
+
+ /* ... and after */
+ if (swap16)
+ byteswap_buffer16(data, width, height, stride);
+ if (swap32)
+ byteswap_buffer32(data, width, height, stride);
#endif
}
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 8/9] util: add pwetty support for big-endian RGB565
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (6 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 7/9] util: fix pwetty on big-endian Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
2023-10-25 7:23 ` [PATCH libdrm v3 9/9] modetest: add support for big-endian XRGB1555/RGB565 Geert Uytterhoeven
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
Add support for rendering the crosshairs in a buffer using the
big-endian RGB565 format.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- No changes,
v2:
- New.
---
tests/util/pattern.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tests/util/pattern.c b/tests/util/pattern.c
index aeac84a9b0dfed09..4d6e9e32ab0f4e93 100644
--- a/tests/util/pattern.c
+++ b/tests/util/pattern.c
@@ -1188,6 +1188,7 @@ static void make_pwetty(void *data, unsigned int width, unsigned int height,
cairo_format = CAIRO_FORMAT_ARGB32;
break;
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
cairo_format = CAIRO_FORMAT_RGB16_565;
swap16 = fb_foreign_endian(format);
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH libdrm v3 9/9] modetest: add support for big-endian XRGB1555/RGB565
2023-10-25 7:23 [PATCH libdrm v3 0/9] Big-endian fixes Geert Uytterhoeven
` (7 preceding siblings ...)
2023-10-25 7:23 ` [PATCH libdrm v3 8/9] util: add pwetty support for big-endian RGB565 Geert Uytterhoeven
@ 2023-10-25 7:23 ` Geert Uytterhoeven
8 siblings, 0 replies; 10+ messages in thread
From: Geert Uytterhoeven @ 2023-10-25 7:23 UTC (permalink / raw)
To: dri-devel; +Cc: Geert Uytterhoeven
Add support for creating buffers using big-endian formats.
For now this is limited to XRGB1555 and RGB565, which are the most
common big-endian formats.
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
v3:
- No changes,
v2:
- New.
---
tests/modetest/buffers.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/tests/modetest/buffers.c b/tests/modetest/buffers.c
index 65f1cfb32ab9eeae..c8aafadd5145b64a 100644
--- a/tests/modetest/buffers.c
+++ b/tests/modetest/buffers.c
@@ -158,6 +158,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@@ -165,6 +166,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_UYVY:
case DRM_FORMAT_VYUY:
@@ -318,6 +320,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRX4444:
case DRM_FORMAT_ARGB1555:
case DRM_FORMAT_XRGB1555:
+ case DRM_FORMAT_XRGB1555 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_ABGR1555:
case DRM_FORMAT_XBGR1555:
case DRM_FORMAT_RGBA5551:
@@ -325,6 +328,7 @@ bo_create(int fd, unsigned int format,
case DRM_FORMAT_BGRA5551:
case DRM_FORMAT_BGRX5551:
case DRM_FORMAT_RGB565:
+ case DRM_FORMAT_RGB565 | DRM_FORMAT_BIG_ENDIAN:
case DRM_FORMAT_BGR565:
case DRM_FORMAT_BGR888:
case DRM_FORMAT_RGB888:
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread