diff options
-rw-r--r-- | tests/modetest/modetest.c | 383 |
1 files changed, 192 insertions, 191 deletions
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index ec3121e1..496aac57 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -657,112 +657,39 @@ make_pwetty(void *data, int width, int height, int stride) #endif } -static int -create_test_buffer(struct kms_driver *kms, - int width, int height, int *stride_out, - struct kms_bo **bo_out) -{ - struct kms_bo *bo; - int ret, i, j, stride; - void *virtual; - - bo = allocate_buffer(kms, width, height, &stride); - if (!bo) - return -1; - - ret = kms_bo_map(bo, &virtual); - if (ret) { - fprintf(stderr, "failed to map buffer: %s\n", - strerror(-ret)); - kms_bo_destroy(&bo); - return -1; - } - - /* paint the buffer with colored tiles */ - for (j = 0; j < height; j++) { - uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride); - for (i = 0; i < width; i++) { - div_t d = div(i, width); - fb_ptr[i] = - 0x00130502 * (d.quot >> 6) + - 0x000a1120 * (d.rem >> 6); - } - } +/* ----------------------------------------------------------------------------- + * Buffers management + */ - make_pwetty(virtual, width, height, stride); +/* swap these for big endian.. */ +#define RED 2 +#define GREEN 1 +#define BLUE 0 - kms_bo_unmap(bo); +struct format_name { + unsigned int format; + const char *name; +}; - *bo_out = bo; - *stride_out = stride; - return 0; -} +static const struct format_name format_names[] = { + { DRM_FORMAT_YUYV, "YUYV" }, + { DRM_FORMAT_NV12, "NV12" }, + { DRM_FORMAT_YVU420, "YV12" }, + { DRM_FORMAT_XRGB1555, "XR15" }, + { DRM_FORMAT_XRGB8888, "XR24" }, + { DRM_FORMAT_ARGB1555, "AR15" }, +}; -static int -create_grey_buffer(struct kms_driver *kms, - int width, int height, int *stride_out, - struct kms_bo **bo_out) +unsigned int format_fourcc(const char *name) { - struct kms_bo *bo; - int size, ret, stride; - void *virtual; - - bo = allocate_buffer(kms, width, height, &stride); - if (!bo) - return -1; - - ret = kms_bo_map(bo, &virtual); - if (ret) { - fprintf(stderr, "failed to map buffer: %s\n", - strerror(-ret)); - kms_bo_destroy(&bo); - return -1; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(format_names); i++) { + if (!strcmp(format_names[i].name, name)) + return format_names[i].format; } - - size = stride * height; - memset(virtual, 0x77, size); - kms_bo_unmap(bo); - - *bo_out = bo; - *stride_out = stride; - return 0; } -void -page_flip_handler(int fd, unsigned int frame, - unsigned int sec, unsigned int usec, void *data) -{ - struct connector *c; - unsigned int new_fb_id; - struct timeval end; - double t; - - c = data; - if (c->current_fb_id == c->fb_id[0]) - new_fb_id = c->fb_id[1]; - else - new_fb_id = c->fb_id[0]; - - drmModePageFlip(fd, c->crtc, new_fb_id, - DRM_MODE_PAGE_FLIP_EVENT, c); - c->current_fb_id = new_fb_id; - c->swap_count++; - if (c->swap_count == 60) { - gettimeofday(&end, NULL); - t = end.tv_sec + end.tv_usec * 1e-6 - - (c->start.tv_sec + c->start.tv_usec * 1e-6); - fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); - c->swap_count = 0; - c->start = end; - } -} - -/* 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 */, @@ -835,6 +762,154 @@ fill1555(unsigned char *virtual, int n, int width, int height, int stride) } } +static void +fill8888(unsigned char *virtual, int width, int height, int stride) +{ + int i, j; + /* paint the buffer with colored tiles */ + for (j = 0; j < height; j++) { + uint32_t *ptr = (uint32_t*)((char*)virtual + j * stride); + for (i = 0; i < width; i++) { + div_t d = div(i, width); + ptr[i] = + 0x00130502 * (d.quot >> 6) + + 0x000a1120 * (d.rem >> 6); + } + } + + make_pwetty(virtual, width, height, stride); +} + +static void +fill_grey(unsigned char *virtual, int width, int height, int stride) +{ + memset(virtual, 0x77, stride * height); +} + +static struct kms_bo * +create_test_buffer(struct kms_driver *kms, unsigned int format, + int width, int height, int handles[4], + int pitches[4], int offsets[4], int grey) +{ + struct kms_bo *bo; + int ret, stride; + void *virtual; + + bo = allocate_buffer(kms, width, height, &pitches[0]); + if (!bo) + return NULL; + + ret = kms_bo_map(bo, &virtual); + if (ret) { + fprintf(stderr, "failed to map buffer: %s\n", + strerror(-ret)); + kms_bo_destroy(&bo); + return NULL; + } + + /* just testing a limited # of formats to test single + * and multi-planar path.. would be nice to add more.. + */ + switch (format) { + case DRM_FORMAT_YUYV: + pitches[0] = width * 2; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + + fill422(virtual, 0, width, height, pitches[0]); + break; + + case DRM_FORMAT_NV12: + pitches[0] = width; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + pitches[1] = width; + offsets[1] = width * height; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]); + + fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1, + 2, 0, width, height, pitches[0]); + break; + + case DRM_FORMAT_YVU420: + pitches[0] = width; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + pitches[1] = width / 2; + offsets[1] = width * height; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[1]); + pitches[2] = width / 2; + offsets[2] = offsets[1] + (width * height) / 4; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[2]); + + fill420(virtual, virtual+offsets[1], virtual+offsets[2], + 1, 0, width, height, pitches[0]); + break; + + case DRM_FORMAT_XRGB1555: + pitches[0] = width * 2; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + + fill1555(virtual, 0, width, height, pitches[0]); + break; + + case DRM_FORMAT_XRGB8888: + pitches[0] = width * 4; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + + if (grey) + fill_grey(virtual, width, height, pitches[0]); + else + fill8888(virtual, width, height, pitches[0]); + break; + + case DRM_FORMAT_ARGB1555: + pitches[0] = width * 2; + offsets[0] = 0; + kms_bo_get_prop(bo, KMS_HANDLE, &handles[0]); + + fill1555(virtual, 0, width, height, pitches[0]); + break; + } + + kms_bo_unmap(bo); + + return bo; +} + +/* -------------------------------------------------------------------------- */ + +void +page_flip_handler(int fd, unsigned int frame, + unsigned int sec, unsigned int usec, void *data) +{ + struct connector *c; + unsigned int new_fb_id; + struct timeval end; + double t; + + c = data; + if (c->current_fb_id == c->fb_id[0]) + new_fb_id = c->fb_id[1]; + else + new_fb_id = c->fb_id[0]; + + drmModePageFlip(fd, c->crtc, new_fb_id, + DRM_MODE_PAGE_FLIP_EVENT, c); + c->current_fb_id = new_fb_id; + c->swap_count++; + if (c->swap_count == 60) { + gettimeofday(&end, NULL); + t = end.tv_sec + end.tv_usec * 1e-6 - + (c->start.tv_sec + c->start.tv_usec * 1e-6); + fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t); + c->swap_count = 0; + c->start = end; + } +} + static int set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) { @@ -847,6 +922,12 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) int ret, crtc_x, crtc_y, crtc_w, crtc_h; unsigned int i; + format = format_fourcc(p->format_str); + if (format == 0) { + fprintf(stderr, "Unknown format: %s\n", p->format_str); + return -1; + } + /* find an unused plane which can be connected to our crtc */ plane_resources = drmModeGetPlaneResources(fd); if (!plane_resources) { @@ -877,92 +958,10 @@ set_plane(struct kms_driver *kms, struct connector *c, struct plane *p) 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; - - 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[2]); - - fill420(virtual, virtual+offsets[1], virtual+offsets[2], - 1, 0, p->w, p->h, pitches[0]); - - format = DRM_FORMAT_YVU420; - } else if (!strcmp(p->format_str, "XR15")) { - pitches[0] = p->w * 2; - offsets[0] = 0; - kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); - - fill1555(virtual, 0, p->w, p->h, pitches[0]); - - format = DRM_FORMAT_XRGB1555; - } else if (!strcmp(p->format_str, "AR15")) { - pitches[0] = p->w * 2; - offsets[0] = 0; - kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]); - - fill1555(virtual, 0, p->w, p->h, pitches[0]); - - format = DRM_FORMAT_ARGB1555; - } else { - fprintf(stderr, "Unknown format: %s\n", p->format_str); - return -1; - } - - kms_bo_unmap(plane_bo); - } + plane_bo = create_test_buffer(kms, format, p->w, p->h, handles, + pitches, offsets, 0); + if (plane_bo == NULL) + return -1; /* just use single plane format for now.. */ if (drmModeAddFB2(fd, p->w, p->h, format, @@ -996,8 +995,8 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, struct kms_driver *kms; struct kms_bo *bo, *other_bo; unsigned int fb_id, other_fb_id; - int i, j, ret, width, height, x, stride; - unsigned handle; + int i, j, ret, width, height, x; + uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */ drmEventContext evctx; width = 0; @@ -1018,11 +1017,12 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, return; } - if (create_test_buffer(kms, width, height, &stride, &bo)) + bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles, + pitches, offsets, 0); + if (bo == NULL) return; - kms_bo_get_prop(bo, KMS_HANDLE, &handle); - ret = drmModeAddFB(fd, width, height, 24, 32, stride, handle, &fb_id); + ret = drmModeAddFB(fd, width, height, 24, 32, pitches[0], handles[0], &fb_id); if (ret) { fprintf(stderr, "failed to add fb (%ux%u): %s\n", width, height, strerror(errno)); @@ -1060,11 +1060,12 @@ set_mode(struct connector *c, int count, struct plane *p, int plane_count, if (!page_flip) return; - if (create_grey_buffer(kms, width, height, &stride, &other_bo)) + other_bo = create_test_buffer(kms, DRM_FORMAT_XRGB8888, width, height, handles, + pitches, offsets, 1); + if (other_bo == NULL) return; - kms_bo_get_prop(other_bo, KMS_HANDLE, &handle); - ret = drmModeAddFB(fd, width, height, 32, 32, stride, handle, + ret = drmModeAddFB(fd, width, height, 32, 32, pitches[0], handles[0], &other_fb_id); if (ret) { fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); |