modetest.c revision b83ad866220911e5be1704e6df085705e5ba8eae
1731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
2731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * DRM based mode setting test program
3731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Tungsten Graphics
4731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *   Jakob Bornecrantz <jakob@tungstengraphics.com>
5731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Copyright 2008 Intel Corporation
6731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *   Jesse Barnes <jesse.barnes@intel.com>
7731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
8731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Permission is hereby granted, free of charge, to any person obtaining a
9731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * copy of this software and associated documentation files (the "Software"),
10731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * to deal in the Software without restriction, including without limitation
11731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * and/or sell copies of the Software, and to permit persons to whom the
13731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Software is furnished to do so, subject to the following conditions:
14731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
15731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * The above copyright notice and this permission notice shall be included in
16731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * all copies or substantial portions of the Software.
17731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
18731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * IN THE SOFTWARE.
25731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
26731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
27731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
28731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * This fairly simple test program dumps output in a similar format to the
29731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * "xrandr" tool everyone knows & loves.  It's necessarily slightly different
30731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * since the kernel separates outputs into encoder and connector structures,
31731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * each with their own unique ID.  The program also allows test testing of the
32731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * memory management and mode setting APIs by allowing the user to specify a
33731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector and mode to use for mode setting.  If all works as expected, a
34731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * blue background should be painted on the monitor attached to the specified
35731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * connector after the selected mode is set.
36731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *
37731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * TODO: use cairo to write the mode info on the selected output once
38731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes *       the mode has been programmed, along with possible test patterns.
39731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
407a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include "config.h"
417a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
42731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <assert.h>
43731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdio.h>
44731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdlib.h>
45731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <stdint.h>
46731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <unistd.h>
47731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <string.h>
48731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include <errno.h>
491e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg#include <sys/poll.h>
50e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell#include <sys/time.h>
51731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
52731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drm.h"
53731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#include "xf86drmMode.h"
54d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark#include "drm_fourcc.h"
558fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#include "libkms.h"
56731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#ifdef HAVE_CAIRO
587a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <math.h>
597a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#include <cairo.h>
607a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg#endif
617a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
62731cd5526e5c732d51307b26e784f454a724a699Jesse BarnesdrmModeRes *resources;
63731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint fd, modes;
64731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
65731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
66731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
67731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name {
68731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int type;
69731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	char *name;
70731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
71731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
72731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define type_name_fn(res) \
73731cd5526e5c732d51307b26e784f454a724a699Jesse Barneschar * res##_str(int type) {			\
74731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;						\
75731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
76731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (res##_names[i].type == type)	\
77731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			return res##_names[i].name;	\
78731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}						\
79731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return "(invalid)";				\
80731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
81731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
82731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name encoder_type_names[] = {
83731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_NONE, "none" },
84731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_DAC, "DAC" },
85731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
86731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
87731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(encoder_type)
91731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
92731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_status_names[] = {
93731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTED, "connected" },
94731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_DISCONNECTED, "disconnected" },
95731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
96731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
97731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
98731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_status)
99731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
100731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstruct type_name connector_type_names[] = {
101731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Unknown, "unknown" },
102731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_VGA, "VGA" },
103731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
104731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
105731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
106731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Composite, "composite" },
107731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
108731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
109731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_Component, "component" },
110731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
111731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
112731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
113731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
114b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_TV, "TV" },
115b8abe6139e5c6779ee87d983346f0f65bf67462eJesse Barnes	{ DRM_MODE_CONNECTOR_eDP, "embedded displayport" },
116731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes};
117731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
118731cd5526e5c732d51307b26e784f454a724a699Jesse Barnestype_name_fn(connector_type)
119731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
120731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_encoders(void)
121731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
122731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeEncoder *encoder;
123731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
124731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
125731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Encoders:\n");
126731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
127731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
128731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		encoder = drmModeGetEncoder(fd, resources->encoders[i]);
129731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
130731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!encoder) {
131731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
132731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
133731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
134731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
135731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
136731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->encoder_id,
137731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->crtc_id,
138731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder_type_str(encoder->encoder_type),
139731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_crtcs,
140731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       encoder->possible_clones);
141731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeEncoder(encoder);
142731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1430243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
1440243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg}
1450243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
1469fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergvoid dump_mode(drmModeModeInfo *mode)
1470243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg{
148694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki	printf("  %s %d %d %d %d %d %d %d %d %d\n",
1490243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->name,
150694ef59532253727176ed0ce9077ae3ec41dd457Marcin Kościelnicki	       mode->vrefresh,
1510243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hdisplay,
1520243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_start,
1530243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->hsync_end,
1540243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->htotal,
1550243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vdisplay,
1560243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_start,
1570243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vsync_end,
1580243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	       mode->vtotal);
159731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
160731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1619fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergstatic void
1629fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsbergdump_props(drmModeConnector *connector)
1639fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg{
1649fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	drmModePropertyPtr props;
1659fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	int i;
1669fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
1679fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	for (i = 0; i < connector->count_props; i++) {
1689fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg		props = drmModeGetProperty(fd, connector->props[i]);
1699fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg		printf("\t%s, flags %d\n", props->name, props->flags);
1709fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg		drmModeFreeProperty(props);
1719fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	}
1729fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg}
1739fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg
174731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_connectors(void)
175731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
176731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
177731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i, j;
178731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
179731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	printf("Connectors:\n");
1801e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\tencoders\n");
181731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
182731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
183731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
184731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
185731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
186731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
187731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
188731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
189731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\t",
191731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->connector_id,
192731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->encoder_id,
193731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_status_str(connector->connection),
194731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector_type_str(connector->connector_type),
195731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->mmWidth, connector->mmHeight,
196731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       connector->count_modes);
197731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		for (j = 0; j < connector->count_encoders; j++)
1991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			printf("%s%d", j > 0 ? ", " : "", connector->encoders[j]);
2001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		printf("\n");
2011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
202731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes)
203731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
204731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
205731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("  modes:\n");
206731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("  name refresh (Hz) hdisp hss hse htot vdisp "
207731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		       "vss vse vtot)\n");
2080243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		for (j = 0; j < connector->count_modes; j++)
2090243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg			dump_mode(&connector->modes[j]);
2100243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
2119fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg		printf("  props:\n");
2129fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg		dump_props(connector);
2139a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki
2149a37455b35d746d694760cfe8850a8bf856d73c9Marcin Kościelnicki		drmModeFreeConnector(connector);
215731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
2160243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
217731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
218731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
219731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_crtcs(void)
220731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
221731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeCrtc *crtc;
222731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
223731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2240243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("CRTCs:\n");
2250243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tfb\tpos\tsize\n");
226731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_crtcs; i++) {
227731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
228731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
229731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!crtc) {
230731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get crtc %i: %s\n",
231731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->crtcs[i], strerror(errno));
232731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
233731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
2340243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		printf("%d\t%d\t(%d,%d)\t(%dx%d)\n",
2350243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->crtc_id,
2360243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->buffer_id,
2370243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->x, crtc->y,
2380243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       crtc->width, crtc->height);
2390243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		dump_mode(&crtc->mode);
2400243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
241731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeCrtc(crtc);
242731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
2430243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
244731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
245731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
246731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid dump_framebuffers(void)
247731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
248731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFB *fb;
249731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int i;
250731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2510243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("Frame buffers:\n");
2520243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("id\tsize\tpitch\n");
253731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_fbs; i++) {
254731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fb = drmModeGetFB(fd, resources->fbs[i]);
255731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
256731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!fb) {
257731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get fb %i: %s\n",
258731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->fbs[i], strerror(errno));
259731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
260731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
261e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		printf("%u\t(%ux%u)\t%u\n",
2620243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg		       fb->fb_id,
263e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->width, fb->height,
264e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		       fb->pitch);
2650243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg
266731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeFB(fb);
267731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
2680243c9f801a35de3465a0321c02f18a4d07ce5b8Kristian Høgsberg	printf("\n");
269731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
270731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
271d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic void dump_planes(void)
272d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
273d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
274d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
275d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int i, j;
276d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
277d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
278d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
279d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
280d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
281d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return;
282d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
283d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
284d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("Planes:\n");
285d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("id\tcrtc\tfb\tCRTC x,y\tx,y\tgamma size\n");
286d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes; i++) {
287d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
288d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
289d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
290d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
291d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
292d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
293d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
294d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("%d\t%d\t%d\t%d,%d\t\t%d,%d\t%d\n",
295d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->plane_id, ovr->crtc_id, ovr->fb_id,
296d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->crtc_x, ovr->crtc_y, ovr->x, ovr->y,
297d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		       ovr->gamma_size);
298d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
299d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr->count_formats)
300d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			continue;
301d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
302d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("  formats:");
303d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < ovr->count_formats; j++)
304d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			printf(" %4.4s", (char *)&ovr->formats[j]);
305d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		printf("\n");
306d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
307d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
308d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
309d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	printf("\n");
310d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
311d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return;
312d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
313d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
314731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes/*
315731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Mode setting with the kernel interfaces is a bit of a chore.
316731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * First you have to find the connector in question and make sure the
317731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * requested mode is available.
318731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * Then you need to find the encoder attached to that connector so you
319731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes * can bind it with a free crtc.
320731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes */
321669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstruct connector {
322e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	uint32_t id;
323669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	char mode_str[64];
3249fc85b4084b69fefab3dbdf1f6cf97ccb47c963aKristian Høgsberg	drmModeModeInfo *mode;
325669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	drmModeEncoder *encoder;
3268b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	int crtc;
327d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int pipe;
3281e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int fb_id[2], current_fb_id;
3291e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	struct timeval start;
3301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
3311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	int swap_count;
332d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark};
333d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
334d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstruct plane {
335d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t con_id;  /* the id of connector to bind to */
336d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t w, h;
337d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	unsigned int fb_id;
338b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	char format_str[5]; /* need to leave room for terminating \0 */
339d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark};
340669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
341669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergstatic void
342669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsbergconnector_find_mode(struct connector *c)
343731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
344731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeConnector *connector;
345e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	int i, j;
346731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
347731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* First, find the connector & mode */
348669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	c->mode = NULL;
349731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_connectors; i++) {
350731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		connector = drmModeGetConnector(fd, resources->connectors[i]);
351731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
352731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector) {
353731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get connector %i: %s\n",
354731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->connectors[i], strerror(errno));
355731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
356731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
357731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
358731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
359731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (!connector->count_modes) {
360731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
361731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
362731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
363731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
364669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (connector->connector_id != c->id) {
365731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			drmModeFreeConnector(connector);
366731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
367731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
368731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
369731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		for (j = 0; j < connector->count_modes; j++) {
370669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			c->mode = &connector->modes[j];
371669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (!strcmp(c->mode->name, c->mode_str))
372731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				break;
373731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
374731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
375731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		/* Found it, break out */
376669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->mode)
377731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
378731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
379731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmModeFreeConnector(connector);
380731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
381731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
382669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (!c->mode) {
383669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		fprintf(stderr, "failed to find mode \"%s\"\n", c->mode_str);
384731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
385731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
386731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
387731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	/* Now get the encoder */
388731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < resources->count_encoders; i++) {
389669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		c->encoder = drmModeGetEncoder(fd, resources->encoders[i]);
390731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
391669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (!c->encoder) {
392731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			fprintf(stderr, "could not get encoder %i: %s\n",
393731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes				resources->encoders[i], strerror(errno));
394669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			drmModeFreeEncoder(c->encoder);
395731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			continue;
396731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
397731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
398669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c->encoder->encoder_id  == connector->encoder_id)
399731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
400731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
401669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		drmModeFreeEncoder(c->encoder);
402669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	}
4038b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
4048b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	if (c->crtc == -1)
4058b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		c->crtc = c->encoder->crtc_id;
406d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
407d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* and figure out which crtc index it is: */
408d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < resources->count_crtcs; i++) {
409d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (c->crtc == resources->crtcs[i]) {
410d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			c->pipe = i;
411d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
412d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
413d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
414d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
415669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg}
416669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
4178fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkestatic struct kms_bo *
4188fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkeallocate_buffer(struct kms_driver *kms,
4197ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson		int width, int height, int *stride)
4207ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson{
4218fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo;
4228fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	unsigned bo_attribs[] = {
4238fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		KMS_WIDTH,   0,
4248fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		KMS_HEIGHT,  0,
4258fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		KMS_BO_TYPE, KMS_BO_TYPE_SCANOUT_X8R8G8B8,
4268fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		KMS_TERMINATE_PROP_LIST
4278fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	};
4288fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	int ret;
4298fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
4308fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	bo_attribs[1] = width;
4318fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	bo_attribs[3] = height;
4328fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
4338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_bo_create(kms, bo_attribs, &bo);
4348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (ret) {
4358fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to alloc buffer: %s\n",
4368fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
4378fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		return NULL;
4388fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	}
4397a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4408fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_bo_get_prop(bo, KMS_PITCH, stride);
4418fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (ret) {
4428fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to retreive buffer stride: %s\n",
4438fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
4448fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		kms_bo_destroy(&bo);
4458fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		return NULL;
4468fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	}
4477ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
4488fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	return bo;
4497ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson}
4507ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
4517ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilsonstatic void
4528fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkemake_pwetty(void *data, int width, int height, int stride)
453669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg{
4547ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson#ifdef HAVE_CAIRO
4557a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_surface_t *surface;
4567a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_t *cr;
4577a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	int x, y;
458669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
4598fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	surface = cairo_image_surface_create_for_data(data,
4607ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      CAIRO_FORMAT_ARGB32,
4617ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      width, height,
4627ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson						      stride);
4637a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cr = cairo_create(surface);
4647ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson	cairo_surface_destroy(surface);
4657ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
4667a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE);
4677a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (x = 0; x < width; x += 250)
4687a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		for (y = 0; y < height; y += 250) {
4697ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson			char buf[64];
4707ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
4717a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x, y - 20);
4727a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x, y + 20);
4737a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x - 20, y);
4747a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_line_to(cr, x + 20, y);
4757a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_new_sub_path(cr);
4767a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_arc(cr, x, y, 10, 0, M_PI * 2);
4777a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 4);
4787a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
4797a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
4807a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
4817a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_line_width(cr, 2);
4827a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke(cr);
4837ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
4847a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			snprintf(buf, sizeof buf, "%d, %d", x, y);
4857a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_move_to(cr, x + 20, y + 20);
4867a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_text_path(cr, buf);
4877a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 0, 0, 0);
4887a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_stroke_preserve(cr);
4897a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_set_source_rgb(cr, 1, 1, 1);
4907a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			cairo_fill(cr);
4917a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		}
4927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4937a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	cairo_destroy(cr);
4947ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson#endif
4957a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg}
4967a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
4977a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic int
4988fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkecreate_test_buffer(struct kms_driver *kms,
4998fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		   int width, int height, int *stride_out,
5008fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		   struct kms_bo **bo_out)
5017a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
5028fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo;
5037ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson	int ret, i, j, stride;
5048fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	void *virtual;
5057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
5068fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	bo = allocate_buffer(kms, width, height, &stride);
5078fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (!bo)
5087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return -1;
509731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
5108fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_bo_map(bo, &virtual);
511731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
5128fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to map buffer: %s\n",
5138fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
5148fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		kms_bo_destroy(&bo);
5157a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return -1;
516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
518d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg	/* paint the buffer with colored tiles */
5197ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson	for (j = 0; j < height; j++) {
5208fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride);
5217ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson		for (i = 0; i < width; i++) {
5227ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson			div_t d = div(i, width);
5237ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson			fb_ptr[i] =
5247ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson				0x00130502 * (d.quot >> 6) +
5257ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson				0x000a1120 * (d.rem >> 6);
5267ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson		}
527d9c55a6becb530dcf11bc980cb6b31843be0b8c2Kristian Høgsberg	}
5287ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
5298fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	make_pwetty(virtual, width, height, stride);
5307ec9a1effa4f551897f91f3b017723a8adf011d9Chris Wilson
5318fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_unmap(bo);
5327a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
5337a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*bo_out = bo;
5347a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	*stride_out = stride;
5357a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	return 0;
5367a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg}
5377a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
5381e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsbergstatic int
5398fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzkecreate_grey_buffer(struct kms_driver *kms,
5408fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		   int width, int height, int *stride_out,
5418fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		   struct kms_bo **bo_out)
5421e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg{
5438fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo;
544e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	int size, ret, stride;
5458fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	void *virtual;
5461e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5478fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	bo = allocate_buffer(kms, width, height, &stride);
5488fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (!bo)
5491e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return -1;
5501e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5518fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_bo_map(bo, &virtual);
5521e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (ret) {
5538fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to map buffer: %s\n",
5548fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
5558fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		kms_bo_destroy(&bo);
5561e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return -1;
5571e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
5581e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5598fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	size = stride * height;
5608fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	memset(virtual, 0x77, size);
5618fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_unmap(bo);
5621e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5631e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	*bo_out = bo;
5641e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	*stride_out = stride;
5651e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5661e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	return 0;
5671e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg}
5681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsbergvoid
5701e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsbergpage_flip_handler(int fd, unsigned int frame,
5711e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		  unsigned int sec, unsigned int usec, void *data)
5721e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg{
5731e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	struct connector *c;
5741e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int new_fb_id;
5751e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	struct timeval end;
5761e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	double t;
5771e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5781e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	c = data;
5791e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (c->current_fb_id == c->fb_id[0])
5801e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		new_fb_id = c->fb_id[1];
5811e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	else
5821e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		new_fb_id = c->fb_id[0];
5831e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
5841e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	drmModePageFlip(fd, c->crtc, new_fb_id,
5851e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			DRM_MODE_PAGE_FLIP_EVENT, c);
5861e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	c->current_fb_id = new_fb_id;
5871e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	c->swap_count++;
5881e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (c->swap_count == 60) {
5891e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		gettimeofday(&end, NULL);
5901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		t = end.tv_sec + end.tv_usec * 1e-6 -
5911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			(c->start.tv_sec + c->start.tv_usec * 1e-6);
5921e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		fprintf(stderr, "freq: %.02fHz\n", c->swap_count / t);
5931e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		c->swap_count = 0;
5941e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		c->start = end;
5951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
5961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg}
5971e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
598b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark/* swap these for big endian.. */
599b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark#define RED   2
600b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark#define GREEN 1
601b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark#define BLUE  0
602b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
603b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkstatic void
604b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkfill420(unsigned char *y, unsigned char *u, unsigned char *v,
605b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		int cs /*chroma pixel stride */,
606b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		int n, int width, int height, int stride)
607b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark{
608b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	int i, j;
609b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
610b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	/* paint the buffer with colored tiles, in blocks of 2x2 */
611b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	for (j = 0; j < height; j+=2) {
612b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		unsigned char *y1p = y + j * stride;
613b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		unsigned char *y2p = y1p + stride;
614b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		unsigned char *up = u + (j/2) * stride * cs / 2;
615b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		unsigned char *vp = v + (j/2) * stride * cs / 2;
616b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
617b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		for (i = 0; i < width; i+=2) {
618b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			div_t d = div(n+i+j, width);
619b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
620b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char *rgbp = (unsigned char *)&rgb;
621b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
622b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
623b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(y2p++) = *(y1p++) = y;
624b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(y2p++) = *(y1p++) = y;
625b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
626b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*up = (rgbp[BLUE] - y) * 0.565 + 128;
627b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*vp = (rgbp[RED] - y) * 0.713 + 128;
628b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			up += cs;
629b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			vp += cs;
630b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
631b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	}
632b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark}
633b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
634b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkstatic void
635b83ad866220911e5be1704e6df085705e5ba8eaeRob Clarkfill422(unsigned char *virtual, int n, int width, int height, int stride)
636b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark{
637b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	int i, j;
638b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	/* paint the buffer with colored tiles */
639b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	for (j = 0; j < height; j++) {
640b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		uint8_t *ptr = (uint8_t*)((char*)virtual + j * stride);
641b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		for (i = 0; i < width; i++) {
642b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			div_t d = div(n+i+j, width);
643b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			uint32_t rgb = 0x00130502 * (d.quot >> 6) + 0x000a1120 * (d.rem >> 6);
644b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char *rgbp = (unsigned char *)&rgb;
645b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			unsigned char y = (0.299 * rgbp[RED]) + (0.587 * rgbp[GREEN]) + (0.114 * rgbp[BLUE]);
646b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
647b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = y;
648b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = (rgbp[BLUE] - y) * 0.565 + 128;
649b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = y;
650b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			*(ptr++) = (rgbp[RED] - y) * 0.713 + 128;
651b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
652b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	}
653b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark}
654b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
655d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic int
656d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_plane(struct kms_driver *kms, struct connector *c, struct plane *p)
657d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark{
658d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlaneRes *plane_resources;
659d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	drmModePlane *ovr;
660d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t handles[4], pitches[4], offsets[4] = {0}; /* we only use [0] */
661d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	uint32_t plane_id = 0;
662d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	struct kms_bo *plane_bo;
663b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	uint32_t plane_flags = 0, format;
664b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	int i, ret, crtc_x, crtc_y, crtc_w, crtc_h;
665d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
666d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* find an unused plane which can be connected to our crtc */
667d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	plane_resources = drmModeGetPlaneResources(fd);
668d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_resources) {
669d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "drmModeGetPlaneResources failed: %s\n",
670d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
671d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
672d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
673d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
674d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	for (i = 0; i < plane_resources->count_planes && !plane_id; i++) {
675d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		ovr = drmModeGetPlane(fd, plane_resources->planes[i]);
676d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if (!ovr) {
677d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			fprintf(stderr, "drmModeGetPlane failed: %s\n",
678d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				strerror(errno));
679d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			return -1;
680d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		}
681d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
682d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		if ((ovr->possible_crtcs & (1 << c->pipe)) && !ovr->crtc_id)
683d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_id = ovr->plane_id;
684d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
685d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		drmModeFreePlane(ovr);
686d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
687d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
688b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	fprintf(stderr, "testing %dx%d@%s overlay plane\n",
689b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			p->w, p->h, p->format_str);
690b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
691d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (!plane_id) {
692d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to find plane!\n");
693d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
694d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
695d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
696b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	if (!strcmp(p->format_str, "XR24")) {
697b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		if (create_test_buffer(kms, p->w, p->h, &pitches[0], &plane_bo))
698b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			return -1;
699b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]);
700b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		format = DRM_FORMAT_XRGB8888;
701b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	} else {
702b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		void *virtual;
703b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
704b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		/* TODO: this always allocates a buffer for 32bpp RGB.. but for
705b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 * YUV formats, we don't use all of it..  since 4bytes/pixel is
706b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 * worst case, so live with it for now and just don't use all
707b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 * the buffer:
708b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 */
709b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		plane_bo = allocate_buffer(kms, p->w, p->h, &pitches[0]);
710b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		if (!plane_bo)
711b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			return -1;
712b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
713b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		ret = kms_bo_map(plane_bo, &virtual);
714b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		if (ret) {
715b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			fprintf(stderr, "failed to map buffer: %s\n",
716b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark				strerror(-ret));
717b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_destroy(&plane_bo);
718b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			return -1;
719b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
720b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
721b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		/* just testing a limited # of formats to test single
722b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 * and multi-planar path.. would be nice to add more..
723b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		 */
724b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		if (!strcmp(p->format_str, "YUYV")) {
725b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[0] = p->w * 2;
726b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[0] = 0;
727b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]);
728b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
729b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			fill422(virtual, 0, p->w, p->h, pitches[0]);
730b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
731b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			format = DRM_FORMAT_YUYV;
732b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		} else if (!strcmp(p->format_str, "NV12")) {
733b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[0] = p->w;
734b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[0] = 0;
735b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]);
736b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[1] = p->w;
737b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[1] = p->w * p->h;
738b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]);
739b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
740b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			fill420(virtual, virtual+offsets[1], virtual+offsets[1]+1,
741b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					2, 0, p->w, p->h, pitches[0]);
742b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
743b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			format = DRM_FORMAT_NV12;
744b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		} else if (!strcmp(p->format_str, "YV12")) {
745b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[0] = p->w;
746b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[0] = 0;
747b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[0]);
748b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[1] = p->w / 2;
749b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[1] = p->w * p->h;
750b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]);
751b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			pitches[2] = p->w / 2;
752b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			offsets[2] = offsets[1] + (p->w * p->h) / 4;
753b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			kms_bo_get_prop(plane_bo, KMS_HANDLE, &handles[1]);
754b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
755b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			fill420(virtual, virtual+offsets[1], virtual+offsets[2],
756b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					1, 0, p->w, p->h, pitches[0]);
757b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark
758b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			format = DRM_FORMAT_YVU420;
759b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		} else {
760b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			fprintf(stderr, "Unknown format: %s\n", p->format_str);
761b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			return -1;
762b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		}
763d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
764b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark		kms_bo_unmap(plane_bo);
765b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	}
766d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
767d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* just use single plane format for now.. */
768b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	if (drmModeAddFB2(fd, p->w, p->h, format,
769d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			handles, pitches, offsets, &p->fb_id, plane_flags)) {
770d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
771d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
772d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
773d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
774d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* ok, boring.. but for now put in middle of screen: */
775d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_x = c->mode->hdisplay / 3;
776d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_y = c->mode->vdisplay / 3;
777d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_w = crtc_x;
778d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	crtc_h = crtc_y;
779d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
780d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	/* note src coords (last 4 args) are in Q16 format */
781d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	if (drmModeSetPlane(fd, plane_id, c->crtc, p->fb_id,
782d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    plane_flags, crtc_x, crtc_y, crtc_w, crtc_h,
783d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			    0, 0, p->w << 16, p->h << 16)) {
784d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		fprintf(stderr, "failed to enable plane: %s\n",
785d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			strerror(errno));
786d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		return -1;
787d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	}
788d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
789d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	return 0;
790d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark}
791d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
7927a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsbergstatic void
793d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkset_mode(struct connector *c, int count, struct plane *p, int plane_count,
794d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		int page_flip)
7957a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg{
7968fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_driver *kms;
7978fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	struct kms_bo *bo, *other_bo;
7981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	unsigned int fb_id, other_fb_id;
799d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int i, j, ret, width, height, x, stride;
8008fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	unsigned handle;
8011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	drmEventContext evctx;
8027a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
8037a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	width = 0;
8047a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	height = 0;
8057a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	for (i = 0; i < count; i++) {
8067a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		connector_find_mode(&c[i]);
8077a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (c[i].mode == NULL)
8087a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			continue;
8097a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		width += c[i].mode->hdisplay;
8107a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		if (height < c[i].mode->vdisplay)
8117a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg			height = c[i].mode->vdisplay;
8127a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
8137a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
8148fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = kms_create(fd, &kms);
8158fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (ret) {
8168fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke		fprintf(stderr, "failed to create kms driver: %s\n",
8178fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke			strerror(-ret));
8187a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
8197a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg	}
8207a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg
8218fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (create_test_buffer(kms, width, height, &stride, &bo))
8227a389aab86bde183de8806878b8cf055f662ee73Kristian Høgsberg		return;
823731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
8248fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_get_prop(bo, KMS_HANDLE, &handle);
825b317c96361f88a0a4ccb2faeff09b0476d142c68Jesse Barnes	ret = drmModeAddFB(fd, width, height, 24, 32, stride, handle, &fb_id);
826731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (ret) {
827680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz		fprintf(stderr, "failed to add fb (%ux%u): %s\n",
828680b9c4fa3dfb329bd74ec08c17cfc876ea2fc5bJakob Bornecrantz			width, height, strerror(errno));
829731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return;
830731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
831731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
832669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	x = 0;
833669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	for (i = 0; i < count; i++) {
834669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (c[i].mode == NULL)
835669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			continue;
8368b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
8378b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		printf("setting mode %s on connector %d, crtc %d\n",
8388b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		       c[i].mode_str, c[i].id, c[i].crtc);
8398b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg
8408b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg		ret = drmModeSetCrtc(fd, c[i].crtc, fb_id, x, 0,
841669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				     &c[i].id, 1, c[i].mode);
842d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
843d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		/* XXX: Actually check if this is needed */
844d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz		drmModeDirtyFB(fd, fb_id, NULL, 0);
845d23146f3f0ad14c8ad482a4832cae859c8d646f2Jakob Bornecrantz
846669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		x += c[i].mode->hdisplay;
847669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
848669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		if (ret) {
849669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
850669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			return;
851669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg		}
852d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark
853d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		/* if we have a plane/overlay to show, set that up now: */
854d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		for (j = 0; j < plane_count; j++)
855d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			if (p[j].con_id == c[i].id)
856d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				if (set_plane(kms, &c[i], &p[j]))
857d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					return;
858731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
8591e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8601e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (!page_flip)
8611e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
8628fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
8638fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	if (create_grey_buffer(kms, width, height, &stride, &other_bo))
8641e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
8651e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8668fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_get_prop(other_bo, KMS_HANDLE, &handle);
8678fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	ret = drmModeAddFB(fd, width, height, 32, 32, stride, handle,
8681e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			   &other_fb_id);
8691e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	if (ret) {
8701e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
8711e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		return;
8721e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
8731e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8741e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	for (i = 0; i < count; i++) {
8751e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (c[i].mode == NULL)
8761e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			continue;
8771e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8783c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		ret = drmModePageFlip(fd, c[i].crtc, other_fb_id,
8793c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz				      DRM_MODE_PAGE_FLIP_EVENT, &c[i]);
8803c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		if (ret) {
8813c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			fprintf(stderr, "failed to page flip: %s\n", strerror(errno));
8823c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz			return;
8833c8adda6e1e6b0471b3d70a63d795622bbeb1580Jakob Bornecrantz		}
8841e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		gettimeofday(&c[i].start, NULL);
8851e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		c[i].swap_count = 0;
886e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[0] = fb_id;
887e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell		c[i].fb_id[1] = other_fb_id;
888a697fb6acad7992c3d23bb6a663663694782eb7bBenjamin Franzke		c[i].current_fb_id = other_fb_id;
8891e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
8901e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8911e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	memset(&evctx, 0, sizeof evctx);
8921e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.version = DRM_EVENT_CONTEXT_VERSION;
8931e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	evctx.vblank_handler = NULL;
8946f1eba0548cd6a96e91a4e8be7b91ba6a936eb98Jesse Barnes	evctx.page_flip_handler = page_flip_handler;
8951e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
8961e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	while (1) {
897e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#if 0
8981e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		struct pollfd pfd[2];
8991e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
9001e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].fd = 0;
9011e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[0].events = POLLIN;
9021e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].fd = fd;
9031e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		pfd[1].events = POLLIN;
9041e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
9051e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (poll(pfd, 2, -1) < 0) {
9061e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			fprintf(stderr, "poll error\n");
9071e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
9081e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		}
9091e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
9101e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		if (pfd[0].revents)
9111e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
912e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#else
913e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		struct timeval timeout = { .tv_sec = 3, .tv_usec = 0 };
914e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		fd_set fds;
915e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		int ret;
916e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
917e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_ZERO(&fds);
918e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(0, &fds);
919e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		FD_SET(fd, &fds);
920e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		ret = select(fd + 1, &fds, NULL, NULL, &timeout);
921e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes
922e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		if (ret <= 0) {
923e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			fprintf(stderr, "select timed out or error (ret %d)\n",
924e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes				ret);
925e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			continue;
926e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		} else if (FD_ISSET(0, &fds)) {
927e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes			break;
928e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes		}
929e6b3f906cef26e1efb8625f5dd4e460b4c79a771Jesse Barnes#endif
9301e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg
9311e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		drmHandleEvent(fd, &evctx);
9321e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	}
9338fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke
9348fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&bo);
9358fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_bo_destroy(&other_bo);
9368fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	kms_destroy(&kms);
937731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
938731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
939731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern char *optarg;
940731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesextern int optind, opterr, optopt;
941d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clarkstatic char optstr[] = "ecpmfs:P:v";
942731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
943731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesvoid usage(char *name)
944731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
945731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "usage: %s [-ecpmf]\n", name);
946731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-e\tlist encoders\n");
947731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-c\tlist connectors\n");
948d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	fprintf(stderr, "\t-p\tlist CRTCs and planes (pipes)\n");
949731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-m\tlist modes\n");
950731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-f\tlist framebuffers\n");
9511e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	fprintf(stderr, "\t-v\ttest vsynced page flipping\n");
952731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
9538b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg	fprintf(stderr, "\t-s <connector_id>@<crtc_id>:<mode>\tset a mode\n");
954d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	fprintf(stderr, "\t-P <connector_id>:<w>x<h>\tset a plane\n");
955b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	fprintf(stderr, "\t-P <connector_id>:<w>x<h>@<format>\tset a plane\n");
956731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fprintf(stderr, "\n\tDefault is to dump all info.\n");
957731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	exit(0);
958731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
959731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
960731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define dump_resource(res) if (res) dump_##res()
961731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
96259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsbergstatic int page_flipping_supported(int fd)
96359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg{
9648fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	/*FIXME: generic ioctl needed? */
9658fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke	return 1;
9668fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#if 0
96759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	int ret, value;
96859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	struct drm_i915_getparam gp;
96959d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
97059d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.param = I915_PARAM_HAS_PAGEFLIPPING;
97159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	gp.value = &value;
97259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
97359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
97459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	if (ret) {
97559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "drm_i915_getparam: %m\n");
97659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return 0;
97759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
97859d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
979e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	return *gp.value;
9808fef29093fae2a08f8c1cb4946687bf4bb62a1caBenjamin Franzke#endif
98159d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg}
98259d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
983731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint main(int argc, char **argv)
984731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
985731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	int c;
986d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int encoders = 0, connectors = 0, crtcs = 0, planes = 0, framebuffers = 0;
9871e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg	int test_vsync = 0;
988ef1b958cc831df3d33a366d1db2db2c88187229eRob Clark	char *modules[] = { "i915", "radeon", "nouveau", "vmwgfx", "omapdrm" };
989e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell	char *modeset = NULL;
990d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	int i, count = 0, plane_count = 0;
991669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	struct connector con_args[2];
992b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark	struct plane plane_args[2] = {0};
993669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg
994731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	opterr = 0;
995731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	while ((c = getopt(argc, argv, optstr)) != -1) {
996731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		switch (c) {
997731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'e':
998731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			encoders = 1;
999731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1000731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'c':
1001731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			connectors = 1;
1002731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1003731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'p':
1004731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			crtcs = 1;
1005d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			planes = 1;
1006731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1007731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'm':
1008731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modes = 1;
1009731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1010731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 'f':
1011731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			framebuffers = 1;
1012731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
10131e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg		case 'v':
10141e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			test_vsync = 1;
10151e1b3c0a93281ce8df42bbdddfe3e51dccc4d5eaKristian Høgsberg			break;
1016731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		case 's':
1017731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			modeset = strdup(optarg);
10188b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			con_args[count].crtc = -1;
1019669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			if (sscanf(optarg, "%d:%64s",
1020669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				   &con_args[count].id,
1021e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell				   con_args[count].mode_str) != 2 &&
10228b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg			    sscanf(optarg, "%d@%d:%64s",
10238b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].id,
10248b8803695b24d4cb4d041437a4709be06e59471bKristian Høgsberg				   &con_args[count].crtc,
1025e4a519635f75bde38aeb5b09f2ff4efbf73453e9Matthew W. S. Bell				   con_args[count].mode_str) != 3)
1026669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg				usage(argv[0]);
1027669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg			count++;
1028731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1029d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		case 'P':
1030b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			strcpy(plane_args[plane_count].format_str, "XR24");
1031b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark			if (sscanf(optarg, "%d:%dx%d@%4s",
1032b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].con_id,
1033b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].w,
1034b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					&plane_args[plane_count].h,
1035b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark					plane_args[plane_count].format_str) != 4 &&
1036b83ad866220911e5be1704e6df085705e5ba8eaeRob Clark				sscanf(optarg, "%d:%dx%d",
1037d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].con_id,
1038d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].w,
1039d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark					&plane_args[plane_count].h) != 3)
1040d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark				usage(argv[0]);
1041d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			plane_count++;
1042d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark			break;
1043731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		default:
1044731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			usage(argv[0]);
1045731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1046731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
1047731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1048731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1049731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (argc == 1)
1050d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		encoders = connectors = crtcs = planes = modes = framebuffers = 1;
1051731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1052731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	for (i = 0; i < ARRAY_SIZE(modules); i++) {
1053731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		printf("trying to load module %s...", modules[i]);
1054731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fd = drmOpen(modules[i], NULL);
1055731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		if (fd < 0) {
1056731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("failed.\n");
1057731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		} else {
1058731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			printf("success.\n");
1059731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			break;
1060731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		}
1061731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1062731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
106359d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	if (test_vsync && !page_flipping_supported(fd)) {
106459d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		fprintf(stderr, "page flipping not supported by drm.\n");
106559d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg		return -1;
106659d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg	}
106759d97e7d6807d9cd076d4e8374aca1d9e8027a6bKristian Høgsberg
1068731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (i == ARRAY_SIZE(modules)) {
1069731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "failed to load any modules, aborting.\n");
1070731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return -1;
1071731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1072731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1073731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	resources = drmModeGetResources(fd);
1074731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if (!resources) {
1075731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		fprintf(stderr, "drmModeGetResources failed: %s\n",
1076731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			strerror(errno));
1077731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		drmClose(fd);
1078731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes		return 1;
1079731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1080731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1081731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(encoders);
1082731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(connectors);
1083731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(crtcs);
1084d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark	dump_resource(planes);
1085731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	dump_resource(framebuffers);
1086731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1087669fde3472ae71c55cc7526e3b3bd6fe00d6a5a5Kristian Høgsberg	if (count > 0) {
1088d55de747a2bdec5b4885a6c86ea6707e15dfefb5Rob Clark		set_mode(con_args, count, plane_args, plane_count, test_vsync);
10892c113a1b159f57ab94b54316ece49c677cfe04ceKristian Høgsberg		getchar();
1090731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	}
1091731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1092731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	drmModeFreeResources(resources);
1093731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
1094731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return 0;
1095731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
1096