[PATCH weston v2 1/1] simple-dmabuf-drm: support DRM_FORMAT_LINEAR for NV12 as well

Guido Günther agx at sigxcpu.org
Mon May 28 15:41:57 UTC 2018


This makes --import-format=NV12 testable on e.g. intel

We only set nv12_format_found to true if we found that format and at
least one understood modifier. Store modifier verbatim instead of using
a boolean flag. Last advertised and supported modifier currently wins.

The NV12 DRM_FORMAT_LINEAR image should be green in the upper left
corner and white in the lower right.

Signed-off-by: Guido Günther <agx at sigxcpu.org>
---
 clients/simple-dmabuf-drm.c | 55 +++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/clients/simple-dmabuf-drm.c b/clients/simple-dmabuf-drm.c
index 725b35d9..df96758c 100644
--- a/clients/simple-dmabuf-drm.c
+++ b/clients/simple-dmabuf-drm.c
@@ -79,7 +79,7 @@ struct display {
 	struct zwp_linux_dmabuf_v1 *dmabuf;
 	int xrgb8888_format_found;
 	int nv12_format_found;
-	int nv12_modifier_found;
+	uint64_t nv12_modifier;
 	int req_dmabuf_immediate;
 	int req_dmabuf_modifiers;
 };
@@ -324,7 +324,7 @@ etna_device_destroy(struct buffer *buf)
 #endif /* HAVE_LIBDRM_ENTAVIV */
 
 static void
-fill_content(struct buffer *my_buf)
+fill_content(struct buffer *my_buf, uint64_t modifier)
 {
 	int x = 0, y = 0;
 	uint32_t *pix;
@@ -332,11 +332,31 @@ fill_content(struct buffer *my_buf)
 	assert(my_buf->mmap);
 
 	if (my_buf->format == DRM_FORMAT_NV12) {
-		pix = (uint32_t *) my_buf->mmap;
-		for (y = 0; y < my_buf->height; y++)
-			memcpy(&pix[y * my_buf->width / 4],
-			       &nv12_tiled[my_buf->width * y / 4],
-			       my_buf->width);
+		if (modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE) {
+			pix = (uint32_t *) my_buf->mmap;
+			for (y = 0; y < my_buf->height; y++)
+				memcpy(&pix[y * my_buf->width / 4],
+				       &nv12_tiled[my_buf->width * y / 4],
+				       my_buf->width);
+		}
+		else if (modifier == DRM_FORMAT_MOD_LINEAR) {
+			uint8_t *pix8;
+			/* first plane: Y (2/3 of the buffer)	*/
+			for (y = 0; y < my_buf->height * 2/3; y++) {
+				pix8 = my_buf->mmap + y * my_buf->stride;
+				for (x = 0; x < my_buf->width; x++)
+					*pix8++ = x % 0xff;
+			}
+			/* second plane (CbCr) is half the size of Y
+			   plane (last 1/3 of the buffer) */
+			for (y = my_buf->height * 2/3; y < my_buf->height; y++) {
+				pix8 = my_buf->mmap + y * my_buf->stride;
+				for (x = 0; x < my_buf->width; x+=2) {
+					*pix8++ = x % 256;
+					*pix8++ = y % 256;
+				}
+			}
+		}
 	}
 	else {
 		for (y = 0; y < my_buf->height; y++) {
@@ -481,7 +501,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer,
 		/* adjust height for allocation of NV12 Y and UV planes */
 		buffer->height = height * 3 / 2;
 		buffer->bpp = 8;
-		modifier = DRM_FORMAT_MOD_SAMSUNG_64_32_TILE;
+		modifier = display->nv12_modifier;
 		break;
 	default:
 		buffer->height = height;
@@ -498,7 +518,7 @@ create_dmabuf_buffer(struct display *display, struct buffer *buffer,
 		fprintf(stderr, "map_bo failed\n");
 		goto error2;
 	}
-	fill_content(buffer);
+	fill_content(buffer, modifier);
 	drm_dev->unmap_bo(buffer);
 
 	if (drm_dev->export_bo_to_prime(buffer) != 0) {
@@ -746,10 +766,13 @@ dmabuf_modifiers(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf,
 		d->xrgb8888_format_found = 1;
 		break;
 	case DRM_FORMAT_NV12:
-		d->nv12_format_found = 1;
-		if (modifier == DRM_FORMAT_MOD_SAMSUNG_64_32_TILE)
-			d->nv12_modifier_found = 1;
-		break;
+		switch (modifier) {
+		case DRM_FORMAT_MOD_SAMSUNG_64_32_TILE:
+		case DRM_FORMAT_MOD_LINEAR:
+			d->nv12_format_found = 1;
+			d->nv12_modifier = modifier;
+			break;
+		}
 	default:
 		break;
 	}
@@ -857,12 +880,10 @@ create_display(int opts, int format)
 	wl_display_roundtrip(display->display);
 
 	if ((format == DRM_FORMAT_XRGB8888 && !display->xrgb8888_format_found) ||
-		(format == DRM_FORMAT_NV12 && (!display->nv12_format_found ||
-			!display->nv12_modifier_found))) {
+	        (format == DRM_FORMAT_NV12 && !display->nv12_format_found)) {
 		fprintf(stderr, "requested format is not available\n");
 		return NULL;
 	}
-
 	return display;
 }
 
@@ -902,7 +923,7 @@ print_usage_and_exit(void)
 		"\t'--y-inverted=<>'\n\t\t0 to not pass Y_INVERTED flag,"
 		"\n\t\t1 to pass Y_INVERTED flag\n"
 		"\t'--import-format=<>'\n\t\tXRGB to import dmabuf as XRGB8888,"
-		"\n\t\tNV12 to import as multi plane NV12 with tiling modifier\n");
+		"\n\t\tNV12 to import as multi plane NV12\n");
 	exit(0);
 }
 
-- 
2.17.0



More information about the wayland-devel mailing list