On Tue, Dec 13, 2011 at 8:55 PM, Rob Clark <rob.clark@xxxxxxxxxx> wrote: > From: Rob Clark <rob@xxxxxx> > > Signed-off-by: Rob Clark <rob@xxxxxx> > --- > 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 > _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel