From patchwork Wed Mar 21 18:01:02 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 7392 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 2A2E923E01 for ; Wed, 21 Mar 2012 18:01:12 +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 E6D25A1881F for ; Wed, 21 Mar 2012 18:01:11 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id e36so2504095iag.11 for ; Wed, 21 Mar 2012 11:01:11 -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 :x-gm-message-state; bh=iWKInU6cNWHebDvLmfHXtuV6zWQ71I4A2wxtm1lwfK0=; b=FqUDsgNaN4qwJPRsmCLwkv0EY7kL0i+B7L2X1MEzBk57lI5kskGqB6wEh9/uSkkNbv w15867pKTZ5Opv4iQrvSaznD/cgmzVAl2ICGoeU6/0mcp3KdQbNtUmABoExkeIlJmmOB 08eFuyFkVBn9Wru3hYORKLWHW/Zv7crQ3juK9zFBw2Umqg7L2tdPtZXr5fx5WzMclJ6h V30MLjjxZlQTkVEv0fJDRnuRq0t/VInYRZn4YqoZX7JvW5q1SxECCNmlXDmx+MU0ZmK9 0v+kXdjRcgZ6lyIpZ/x91m9IckWN0XHXOnDXaHBsxmVnp4Wg2cQc1hl9tO/DwobHDXBi r1Lg== Received: by 10.42.72.130 with SMTP id o2mr3347634icj.8.1332352871636; Wed, 21 Mar 2012 11:01:11 -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 fh15csp23253ibb; Wed, 21 Mar 2012 11:01:11 -0700 (PDT) Received: by 10.236.126.168 with SMTP id b28mr4814610yhi.88.1332352870389; Wed, 21 Mar 2012 11:01:10 -0700 (PDT) Received: from mail-yx0-f178.google.com (mail-yx0-f178.google.com [209.85.213.178]) by mx.google.com with ESMTPS id s67si1411571yhs.0.2012.03.21.11.01.10 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 21 Mar 2012 11:01:10 -0700 (PDT) Received-SPF: pass (google.com: domain of robdclark@gmail.com designates 209.85.213.178 as permitted sender) client-ip=209.85.213.178; Authentication-Results: mx.google.com; spf=pass (google.com: domain of robdclark@gmail.com designates 209.85.213.178 as permitted sender) smtp.mail=robdclark@gmail.com; dkim=pass header.i=@gmail.com Received: by yenm14 with SMTP id m14so1402187yen.37 for ; Wed, 21 Mar 2012 11:01:10 -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; bh=iWKInU6cNWHebDvLmfHXtuV6zWQ71I4A2wxtm1lwfK0=; b=phxDAV9xthxqtbORFn0FpUxuEhQfodi2A0ATdegsGgUcve1OcNEClDigzu3gl1+ifn lIOcNd85LoDmTUbyCysDupjm5fdvgZEGS6kPxDTZGyvNcX4OJs56J4mR6cTmzgNTl7tk WEfqiZNuuc9btdZe0KZPtfkplP+4skpOKR9rZoLLGjrBTlbGIKWxfcPAyn1oKeJLFQHT 7aaQGgW+EG2enHo3PwMf331Iw9cQLyzdC9yH7nWIGtomGO9p01jCCRAZiTUU1/Y9Zk3/ qTFEcOqvE2yvm8ysqZ8yV9u4B3KWeKw3/MgtK4nuiTFC/WVFnzzvL0e7a4baJP6cZjcL AGLQ== Received: by 10.182.155.97 with SMTP id vv1mr6086098obb.5.1332352869892; Wed, 21 Mar 2012 11:01:09 -0700 (PDT) Received: from localhost (dragon.ti.com. [192.94.94.33]) by mx.google.com with ESMTPS id d9sm2249731obq.0.2012.03.21.11.01.08 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 21 Mar 2012 11:01:09 -0700 (PDT) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH libdrm 1/3] modetest: add drm_plane support Date: Wed, 21 Mar 2012 13:01:02 -0500 Message-Id: <1332352864-18723-1-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.5.4 X-Gm-Message-State: ALoCoQk1DGN6DQ4reHxsHGsNDHCBZH7kT5xdGZihyDMAu5Y6XI+hfLQJ56vrzpzgXEghRm9J0JrB From: Rob Clark Signed-off-by: Rob Clark --- tests/modetest/modetest.c | 166 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 157 insertions(+), 9 deletions(-) diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 1e4ec91..2936de0 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -51,6 +51,7 @@ #include "xf86drm.h" #include "xf86drmMode.h" +#include "drm_fourcc.h" #include "libkms.h" #ifdef HAVE_CAIRO @@ -267,6 +268,49 @@ void dump_framebuffers(void) printf("\n"); } +static void dump_planes(void) +{ + drmModePlaneRes *plane_resources; + drmModePlane *ovr; + int i, j; + + plane_resources = drmModeGetPlaneResources(fd); + if (!plane_resources) { + fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", + strerror(errno)); + return; + } + + printf("Planes:\n"); + printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\n"); + for (i = 0; i < plane_resources->count_planes; i++) { + ovr = drmModeGetPlane(fd, plane_resources->planes[i]); + if (!ovr) { + fprintf(stderr, "drmModeGetPlane failed: %s\n", + strerror(errno)); + continue; + } + + printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%d\n", + ovr->plane_id, ovr->crtc_id, ovr->fb_id, + ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y, + ovr->gamma_size); + + if (!ovr->count_formats) + continue; + + printf(" formats:"); + for (j = 0; j < ovr->count_formats; j++) + printf(" %4.4s", (char *)&ovr->formats[j]); + printf("\n"); + + drmModeFreePlane(ovr); + } + printf("\n"); + + return; +} + /* * Mode setting with the kernel interfaces is a bit of a chore. * First you have to find the connector in question and make sure the @@ -280,11 +324,18 @@ struct connector { drmModeModeInfo *mode; drmModeEncoder *encoder; int crtc; + int pipe; unsigned int fb_id[2], current_fb_id; struct timeval start; int swap_count; -}; +}; + +struct plane { + uint32_t con_id; /* the id of connector to bind to */ + uint32_t w, h; + unsigned int fb_id; +}; static void connector_find_mode(struct connector *c) @@ -351,6 +402,15 @@ connector_find_mode(struct connector *c) if (c->crtc == -1) c->crtc = c->encoder->crtc_id; + + /* and figure out which crtc index it is: */ + for (i = 0; i < resources->count_crtcs; i++) { + if (c->crtc == resources->crtcs[i]) { + c->pipe = i; + break; + } + } + } static struct kms_bo * @@ -534,13 +594,83 @@ page_flip_handler(int fd, unsigned int frame, } } +static int +set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) +{ + drmModePlaneRes *plane_resources; + drmModePlane *ovr; + 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; + + /* find an unused plane which can be connected to our crtc */ + plane_resources = drmModeGetPlaneResources(fd); + if (!plane_resources) { + fprintf(stderr, "drmModeGetPlaneResources failed: %s\n", + strerror(errno)); + return -1; + } + + for (i = 0; i < plane_resources->count_planes && !plane_id; i++) { + ovr = drmModeGetPlane(fd, plane_resources->planes[i]); + if (!ovr) { + fprintf(stderr, "drmModeGetPlane failed: %s\n", + strerror(errno)); + return -1; + } + + if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id) + plane_id = ovr->plane_id; + + drmModeFreePlane(ovr); + } + + 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; + + kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); + + /* just use single plane format for now.. */ + if (drmModeAddFB2(fd, p->w, p->h, DRM_FORMAT_XRGB8888, + handles, pitches, offsets, &p->fb_id, plane_flags)) { + fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); + return -1; + } + + /* ok, boring.. but for now put in middle of screen: */ + crtc_x = c->mode->hdisplay / 3; + crtc_y = c->mode->vdisplay / 3; + crtc_w = crtc_x; + crtc_h = crtc_y; + + /* note src coords (last 4 args) are in Q16 format */ + if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id, + plane_flags, crtc_x, crtc_y, crtc_w, crtc_h, + 0, 0, p->w << 16, p->h << 16)) { + fprintf(stderr, "failed to enable plane: %s\n", + strerror(errno)); + return -1; + } + + return 0; +} + static void -set_mode(struct connector *c, int count, int page_flip) +set_mode(struct connector *c, int count, struct plane *p, int plane_count, + int page_flip) { struct kms_driver *kms; struct kms_bo *bo, *other_bo; unsigned int fb_id, other_fb_id; - int i, ret, width, height, x, stride; + int i, j, ret, width, height, x, stride; unsigned handle; drmEventContext evctx; @@ -593,6 +723,12 @@ set_mode(struct connector *c, int count, int page_flip) fprintf(stderr, "failed to set mode: %s\n", strerror(errno)); return; } + + /* if we have a plane/overlay to show, set that up now: */ + for (j = 0; j < plane_count; j++) + if (p[j].con_id == c[i].id) + if (set_plane(kms, &c[i], &p[j])) + return; } if (!page_flip) @@ -676,19 +812,20 @@ set_mode(struct connector *c, int count, int page_flip) extern char *optarg; extern int optind, opterr, optopt; -static char optstr[] = "ecpmfs:v"; +static char optstr[] = "ecpmfs:P:v"; void usage(char *name) { fprintf(stderr, "usage: %s [-ecpmf]\n", name); fprintf(stderr, "\t-e\tlist encoders\n"); fprintf(stderr, "\t-c\tlist connectors\n"); - fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n"); + fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n"); fprintf(stderr, "\t-m\tlist modes\n"); fprintf(stderr, "\t-f\tlist framebuffers\n"); fprintf(stderr, "\t-v\ttest vsynced page flipping\n"); 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, "\n\tDefault is to dump all info.\n"); exit(0); } @@ -719,12 +856,13 @@ static int page_flipping_supported(int fd) int main(int argc, char **argv) { int c; - int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; + int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0; int test_vsync = 0; char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" }; char *modeset = NULL; - int i, count = 0; + int i, count = 0, plane_count = 0; struct connector con_args[2]; + struct plane plane_args[2]; opterr = 0; while ((c = getopt(argc, argv, optstr)) != -1) { @@ -737,6 +875,7 @@ int main(int argc, char **argv) break; case 'p': crtcs = 1; + planes = 1; break; case 'm': modes = 1; @@ -760,6 +899,14 @@ int main(int argc, char **argv) usage(argv[0]); count++; break; + case 'P': + if (sscanf(optarg, "%d:%dx%d", + &plane_args[plane_count].con_id, + &plane_args[plane_count].w, + &plane_args[plane_count].h) != 3) + usage(argv[0]); + plane_count++; + break; default: usage(argv[0]); break; @@ -767,7 +914,7 @@ int main(int argc, char **argv) } if (argc == 1) - encoders = connectors = crtcs = modes = framebuffers = 1; + encoders = connectors = crtcs = planes = modes = framebuffers = 1; for (i = 0; i < ARRAY_SIZE(modules); i++) { printf("trying to load module %s...", modules[i]); @@ -801,10 +948,11 @@ int main(int argc, char **argv) dump_resource(encoders); dump_resource(connectors); dump_resource(crtcs); + dump_resource(planes); dump_resource(framebuffers); if (count > 0) { - set_mode(con_args, count, test_vsync); + set_mode(con_args, count, plane_args, plane_count, test_vsync); getchar(); }