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); }