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)); | 
