From patchwork Thu Dec 15 04:28:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rob Clark X-Patchwork-Id: 5743 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 056A723E04 for ; Thu, 15 Dec 2011 04:28:33 +0000 (UTC) Received: from mail-ey0-f180.google.com (mail-ey0-f180.google.com [209.85.215.180]) by fiordland.canonical.com (Postfix) with ESMTP id CB341A18144 for ; Thu, 15 Dec 2011 04:28:33 +0000 (UTC) Received: by eaak10 with SMTP id k10so1643784eaa.11 for ; Wed, 14 Dec 2011 20:28:33 -0800 (PST) Received: by 10.205.127.12 with SMTP id gy12mr320628bkc.108.1323923313432; Wed, 14 Dec 2011 20:28:33 -0800 (PST) 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.205.129.2 with SMTP id hg2cs28589bkc; Wed, 14 Dec 2011 20:28:33 -0800 (PST) Received: by 10.236.200.131 with SMTP id z3mr1862590yhn.129.1323923311628; Wed, 14 Dec 2011 20:28:31 -0800 (PST) Received: from mail-gy0-f178.google.com (mail-gy0-f178.google.com [209.85.160.178]) by mx.google.com with ESMTPS id n7si2852812ybe.64.2011.12.14.20.28.31 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 14 Dec 2011 20:28:31 -0800 (PST) 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 (test mode) header.i=@gmail.com Received: by ghbg21 with SMTP id g21so1386680ghb.37 for ; Wed, 14 Dec 2011 20:28:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer; bh=iWKInU6cNWHebDvLmfHXtuV6zWQ71I4A2wxtm1lwfK0=; b=wYgcs3TVAQikfXN2wKgBBmFRlTVOjuOxs3e3PH2op42WdZNsld2+QOP9p07zSkNrLU 1oGXaHe56j3R3kCK/P6tM62lZst0968BEYCz7RntZ31jPmvEoUcmgW07WrxUdwVt2Gtm 3Ruqqa0rM6jWDa/oWvgp+nBywQMn6GnT38SSQ= Received: by 10.236.128.197 with SMTP id f45mr2239905yhi.44.1323923310856; Wed, 14 Dec 2011 20:28:30 -0800 (PST) Received: from localhost (ppp-70-253-156-7.dsl.rcsntx.swbell.net. [70.253.156.7]) by mx.google.com with ESMTPS id n64sm7171697yhk.4.2011.12.14.20.28.29 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 14 Dec 2011 20:28:30 -0800 (PST) Sender: Rob Clark From: Rob Clark To: dri-devel@lists.freedesktop.org Cc: patches@linaro.org, Rob Clark Subject: [PATCH 1/2] modetest: add drm_plane support Date: Wed, 14 Dec 2011 22:28:32 -0600 Message-Id: <1323923313-4231-1-git-send-email-rob.clark@linaro.org> X-Mailer: git-send-email 1.7.5.4 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(); }