diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modetest/modetest.c | 146 | 
1 files changed, 138 insertions, 8 deletions
| diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c index 6c69a570..4739a78b 100644 --- a/tests/modetest/modetest.c +++ b/tests/modetest/modetest.c @@ -46,6 +46,7 @@  #include <unistd.h>  #include <string.h>  #include <errno.h> +#include <sys/poll.h>  #include "xf86drm.h"  #include "xf86drmMode.h" @@ -172,7 +173,7 @@ void dump_connectors(void)  	int i, j;  	printf("Connectors:\n"); -	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n"); +	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");  	for (i = 0; i < resources->count_connectors; i++) {  		connector = drmModeGetConnector(fd, resources->connectors[i]); @@ -182,7 +183,7 @@ void dump_connectors(void)  			continue;  		} -		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n", +		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",  		       connector->connector_id,  		       connector->encoder_id,  		       connector_status_str(connector->connection), @@ -190,6 +191,10 @@ void dump_connectors(void)  		       connector->mmWidth, connector->mmHeight,  		       connector->count_modes); +		for (j = 0; j < connector->count_encoders; j++) +			printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]); +		printf("\n"); +  		if (!connector->count_modes)  			continue; @@ -271,6 +276,10 @@ struct connector {  	drmModeModeInfo *mode;  	drmModeEncoder *encoder;  	int crtc; +	unsigned int fb_id[2], current_fb_id; +	struct timeval start; + +	int swap_count;  };	  static void @@ -457,16 +466,83 @@ create_test_buffer(drm_intel_bufmgr *bufmgr,  #endif +static int +create_grey_buffer(drm_intel_bufmgr *bufmgr, +		   int width, int height, int *stride_out, drm_intel_bo **bo_out) +{ +	drm_intel_bo *bo; +	unsigned int *fb_ptr; +	int size, ret, i, stride; +	div_t d; + +	/* Mode size at 32 bpp */ +	stride = width * 4; +	size = stride * height; + +	bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096); +	if (!bo) { +		fprintf(stderr, "failed to alloc buffer: %s\n", +			strerror(errno)); +		return -1; +	} + +	ret = drm_intel_gem_bo_map_gtt(bo); +	if (ret) { +		fprintf(stderr, "failed to GTT map buffer: %s\n", +			strerror(errno)); +		return -1; +	} + +	memset(bo->virtual, 0x77, size); +	drm_intel_gem_bo_unmap_gtt(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; +	int len, ms; +	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 void -set_mode(struct connector *c, int count) +set_mode(struct connector *c, int count, int page_flip)  {  	drmModeConnector *connector;  	drmModeEncoder *encoder = NULL;  	struct drm_mode_modeinfo *mode = NULL;  	drm_intel_bufmgr *bufmgr; -	drm_intel_bo *bo; -	unsigned int fb_id; +	drm_intel_bo *bo, *other_bo; +	unsigned int fb_id, other_fb_id;  	int i, j, ret, width, height, x, stride; +	drmEventContext evctx;  	width = 0;  	height = 0; @@ -497,7 +573,6 @@ set_mode(struct connector *c, int count)  	x = 0;  	for (i = 0; i < count; i++) { -		int crtc_id;  		if (c[i].mode == NULL)  			continue; @@ -513,11 +588,61 @@ set_mode(struct connector *c, int count)  			return;  		}  	} + +	if (!page_flip) +		return; + +	if (create_grey_buffer(bufmgr, width, height, &stride, &other_bo)) +		return; + +	ret = drmModeAddFB(fd, width, height, 32, 32, stride, other_bo->handle, +			   &other_fb_id); +	if (ret) { +		fprintf(stderr, "failed to add fb: %s\n", strerror(errno)); +		return; +	} + +	for (i = 0; i < count; i++) { +		if (c[i].mode == NULL) +			continue; + +		drmModePageFlip(fd, c[i].crtc, other_fb_id, +				DRM_MODE_PAGE_FLIP_EVENT, &c[i]); +		gettimeofday(&c[i].start, NULL); +		c[i].swap_count = 0; + 		c[i].fb_id[0] = fb_id; + 		c[i].fb_id[1] = other_fb_id; + 		c[i].current_fb_id = fb_id; +	} + +	memset(&evctx, 0, sizeof evctx); +	evctx.version = DRM_EVENT_CONTEXT_VERSION; +	evctx.vblank_handler = NULL; +	evctx.pageflip_handler = page_flip_handler; +	 +	while (1) { +		struct pollfd pfd[2]; + +		pfd[0].fd = 0; +		pfd[0].events = POLLIN; +		pfd[1].fd = fd; +		pfd[1].events = POLLIN; + +		if (poll(pfd, 2, -1) < 0) { +			fprintf(stderr, "poll error\n"); +			break; +		} + +		if (pfd[0].revents) +			break; + +		drmHandleEvent(fd, &evctx); +	}  }  extern char *optarg;  extern int optind, opterr, optopt; -static char optstr[] = "ecpmfs:"; +static char optstr[] = "ecpmfs:v";  void usage(char *name)  { @@ -527,6 +652,7 @@ void usage(char *name)  	fprintf(stderr, "\t-p\tlist CRTCs (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, "\n\tDefault is to dump all info.\n"); @@ -539,6 +665,7 @@ int main(int argc, char **argv)  {  	int c;  	int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0; +	int test_vsync = 0;  	char *modules[] = { "i915", "radeon" };  	char *modeset = NULL, *mode, *connector;  	int i, connector_id, count = 0; @@ -562,6 +689,9 @@ int main(int argc, char **argv)  		case 'f':  			framebuffers = 1;  			break; +		case 'v': +			test_vsync = 1; +			break;  		case 's':  			modeset = strdup(optarg);  			con_args[count].crtc = -1; @@ -614,7 +744,7 @@ int main(int argc, char **argv)  	dump_resource(framebuffers);  	if (count > 0) { -		set_mode(con_args, count); +		set_mode(con_args, count, test_vsync);  		getchar();  	} | 
