On Tue, Dec 13, 2011 at 8:55 PM, Rob Clark <rob.clark at linaro.org> wrote: > From: Rob Clark <rob at ti.com> > > Signed-off-by: Rob Clark <rob at ti.com> > --- > ?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..22ac620 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]; /* we only use [0] */
opps, passing unitialized offset values to drmModeAddFB2() causes problems when the driver doesn't actually ignore the offset.. don't merge this yet.. I'm fixing and also adding some test code for multi-planar YUV (which will need Joonyoung Shim's fix) BR, -R > + ? ? ? 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 <connector_id>:<mode>\tset a mode\n"); > ? ? ? ?fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n"); > + ? ? ? fprintf(stderr, "\t-P <connector_id>:<w>x<h>\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(); > ? ? ? ?} > > -- > 1.7.5.4 >