From patchwork Wed Mar 21 18:01:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 7393 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 97E4E23E01 for ; Wed, 21 Mar 2012 18:01:14 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 5F987A188D9 for ; Wed, 21 Mar 2012 18:01:14 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so2504095iag.11 for ; Wed, 21 Mar 2012 11:01:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :dkim-signature:sender:from:to:cc:subject:date:message-id:x-mailer :in-reply-to:references:x-gm-message-state; bh=T1kbeljjl6DGftc8gbL47qM5xQyL5zBxostKhiFBkzk=; b=HgMsegU7YtsOPe6b5Zd3PdKryv4sBN1U1wgNWNhl3GzJjjuPCTXlf/tXUlbmvv2EaJ FospoxndZVQwKGjRn6QQ3PWDQ1PYpJh25ycM6QE/vVvRuTnAOFUtBQDxN3x8lsaY0FPx 7rc6Lc/A1/7RMKMW7duNK8Yc3Bh06+l6D/8LntOA281wnOFOGk6IlYoqKWGqbyFruMV8 Hp8IeDwTHvDFPJ77ii7E3YJGlkeVbWiIcH+TUjyC3ZY7HJeTE5nWCA6WEvWe9P+RmcCy Ve65+TQCwizTVw0chOK6XmKIaoIJsBAaVIUIk5ghybTNV93G+plo30UZhgwZ39IbT5iK XKSA== Received: by 10.50.156.226 with SMTP id wh2mr3562269igb.2.1332352874094; Wed, 21 Mar 2012 11:01:14 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.203.79 with SMTP id fh15csp23254ibb; Wed, 21 Mar 2012 11:01:13 -0700 (PDT) Received: by 10.236.109.198 with SMTP id s46mr5053889yhg.43.1332352873167; Wed, 21 Mar 2012 11:01:13 -0700 (PDT) Received: from mail-gy0-f178.google.com (mail-gy0-f178.google.com [209.85.160.178]) by mx.google.com with ESMTPS id c50si2227507yhh.127.2012.03.21.11.01.13 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 21 Mar 2012 11:01:13 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) client-ip=209.85.160.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.160.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by ghbf1 with SMTP id f1so1398640ghb.37 for ; Wed, 21 Mar 2012 11:01:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=T1kbeljjl6DGftc8gbL47qM5xQyL5zBxostKhiFBkzk=; b=xPS+H7/Psi4sueekdMQnf8yCfiM4dvGQW0mCGdqmeXDGGegSyLGQdXAiL2hFFICHuB +B4kPCjo5INp83ugrGBybZz9NqEyW5eildSZYiVZmgivU81PWziKDoeST22eJ94zDA3l Hlk/opti0IHiWRabaj5L4iKw68WsF/2MpJ4o4l3ZsIsebvYgmzsBFEDew6gINiEyQc72 zuiHxur9Zgze0lLCoN0CjBPCPZtJGhsp9MJkYVBIY3uDnBiXleSz14OKsHQEWzyArQot 0RbGPhkzedQy7nIcIJNK62mGCziW/eJVOBXfNdbnDQXuOvuReQZMe5K2XQO3aZlRJINS A1Kg== Received: by 10.60.29.10 with SMTP id f10mr5754657oeh.32.1332352872842; Wed, 21 Mar 2012 11:01:12 -0700 (PDT) Received: from localhost (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id v9sm2241828obo.9.2012.03.21.11.01.12 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 21 Mar 2012 11:01:12 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH libdrm 2/3] modetest: add YUV and multi-planar support Date: Wed, 21 Mar 2012 13:01:03 -0500 Message-Id: <1332352864-18723-2-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1332352864-18723-1-git-send-email-rob.clark@linaro.org> References: <1332352864-18723-1-git-send-email-rob.clark@linaro.org> X-Gm-Message-State: ALoCoQk+DwzvGqjlf8NCoM46ghWkSVqIyf8u7mUE66CVwE4gxgAA8jgk92Sv0eZg2GVVBDFKgucm From: Rob Clark Signed-off-by: Rob Clark --- tests/modetest/modetest.c | 151 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 142 insertions(+), 9 deletions(-) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 2936de0..36bdfff 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -335,6 +335,7 @@ struct plane { uint32_t con_id; /* the id of connector to bind to */ uint32_t w, h; unsigned int fb_id; + char format_str[5]; /* need to leave room for terminating \0 */ }; static void @@ -594,6 +595,63 @@ page_flip_handler(int fd, unsigned int frame, } } +/* swap these for big endian.. */ +#define RED 2 +#define GREEN 1 +#define BLUE 0 + +static void +fill420(unsigned char *y, unsigned char *u, unsigned char *v, + int cs /*chroma pixel stride */, + int n, int width, int height, int stride) +{ + int i, j; + + /* paint the buffer with colored tiles, in blocks of 2x2 */ + for (j = 0; j < height; j+=2) { + unsigned char *y1p = y + j * stride; + unsigned char *y2p = y1p + stride; + unsigned char *up = u + (j/2) * stride * cs / 2; + unsigned char *vp = v + (j/2) * stride * cs / 2; + + for (i = 0; i < width; i+=2) { + div_t d = div(n+i+j, width); + uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); + unsigned char *rgbp = (unsigned char *)&rgb; + unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]); + + *(y2p++) = *(y1p++) = y; + *(y2p++) = *(y1p++) = y; + + *up = (rgbp[BLUE] - y) * 0.565 + 128; + *vp = (rgbp[RED] - y) * 0.713 + 128; + up += cs; + vp += cs; + } + } +} + +static void +fill422(unsigned char *virtual, int n, int width, int height, int stride) +{ + int i, j; + /* paint the buffer with colored tiles */ + for (j = 0; j < height; j++) { + uint8_t *ptr = (uint8_t*)((char*)virtual + j * stride); + for (i = 0; i < width; i++) { + div_t d = div(n+i+j, width); + uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6); + unsigned char *rgbp = (unsigned char *)&rgb; + unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]); + + *(ptr++) = y; + *(ptr++) = (rgbp[BLUE] - y) * 0.565 + 128; + *(ptr++) = y; + *(ptr++) = (rgbp[RED] - y) * 0.713 + 128; + } + } +} + static int set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) { @@ -602,8 +660,8 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ uint32_t plane_id = 0; struct kms_bo *plane_bo; - uint32_t plane_flags = 0; - int i, crtc_x, crtc_y, crtc_w, crtc_h; + uint32_t plane_flags = 0, format; + int i, ret, crtc_x, crtc_y, crtc_w, crtc_h; /* find an unused plane which can be connected to our crtc */ plane_resources = drmModeGetPlaneResources(fd); @@ -627,19 +685,87 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) drmModeFreePlane(ovr); } + fprintf(stderr, "testing %dx%d@%s overlay plane\n", + p->w, p->h, p->format_str); + if (!plane_id) { fprintf(stderr, "failed to find plane!\n"); return -1; } - /* TODO.. would be nice to test YUV overlays.. */ - if (create_test_buffer(kms, p->w, p->h, &pitches[0], &plane_bo)) - return -1; + if (!strcmp(p->format_str, "XR24")) { + if (create_test_buffer(kms, p->w, p->h, &pitches[0], &plane_bo)) + return -1; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + format = DRM_FORMAT_XRGB8888; + } else { + void *virtual; + + /* TODO: this always allocates a buffer for 32bpp RGB.. but for + * YUV formats, we don't use all of it.. since 4bytes/pixel is + * worst case, so live with it for now and just don't use all + * the buffer: + */ + plane_bo = allocate_buffer(kms, p->w, p->h, &pitches[0]); + if (!plane_bo) + return -1; - kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + ret = kms_bo_map(plane_bo, &virtual); + if (ret) { + fprintf(stderr, "failed to map buffer: %s\n", + strerror(-ret)); + kms_bo_destroy(&plane_bo); + return -1; + } + + /* just testing a limited # of formats to test single + * and multi-planar path.. would be nice to add more.. + */ + if (!strcmp(p->format_str, "YUYV")) { + pitches[0] = p->w * 2; + offsets[0] = 0; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + + fill422(virtual, 0, p->w, p->h, pitches[0]); + + format = DRM_FORMAT_YUYV; + } else if (!strcmp(p->format_str, "NV12")) { + pitches[0] = p->w; + offsets[0] = 0; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + pitches[1] = p->w; + offsets[1] = p->w * p->h; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]); + + fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1, + 2, 0, p->w, p->h, pitches[0]); + + format = DRM_FORMAT_NV12; + } else if (!strcmp(p->format_str, "YV12")) { + pitches[0] = p->w; + offsets[0] = 0; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + pitches[1] = p->w / 2; + offsets[1] = p->w * p->h; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]); + pitches[2] = p->w / 2; + offsets[2] = offsets[1] + (p->w * p->h) / 4; + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]); + + fill420(virtual, virtual+offsets[1], virtual+offsets[2], + 1, 0, p->w, p->h, pitches[0]); + + format = DRM_FORMAT_YVU420; + } else { + fprintf(stderr, "Unknown format: %s\n", p->format_str); + return -1; + } + + kms_bo_unmap(plane_bo); + } /* just use single plane format for now.. */ - if (drmModeAddFB2(fd, p->w, p->h, DRM_FORMAT_XRGB8888, + if (drmModeAddFB2(fd, p->w, p->h, format, handles, pitches, offsets, &p->fb_id, plane_flags)) { fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); return -1; @@ -826,6 +952,7 @@ void usage(char *name) fprintf(stderr, "\t-s :\tset a mode\n"); fprintf(stderr, "\t-s @:\tset a mode\n"); fprintf(stderr, "\t-P :x\tset a plane\n"); + fprintf(stderr, "\t-P :x@\tset a plane\n"); fprintf(stderr, "\n\tDefault is to dump all info.\n"); exit(0); } @@ -862,7 +989,7 @@ int main(int argc, char **argv) char *modeset = NULL; int i, count = 0, plane_count = 0; struct connector con_args[2]; - struct plane plane_args[2]; + struct plane plane_args[2] = {0}; opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { @@ -900,7 +1027,13 @@ int main(int argc, char **argv) count++; break; case 'P': - if (sscanf(optarg, "%d:%dx%d", + strcpy(plane_args[plane_count].format_str, "XR24"); + if (sscanf(optarg, "%d:%dx%d@%4s", + &plane_args[plane_count].con_id, + &plane_args[plane_count].w, + &plane_args[plane_count].h, + plane_args[plane_count].format_str) != 4 && + sscanf(optarg, "%d:%dx%d", &plane_args[plane_count].con_id, &plane_args[plane_count].w, &plane_args[plane_count].h) != 3)