1 /*
2 * Copyright © 2011 Texas Instruments, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Soft-
6 * ware"), to deal in the Software without restriction, including without
7 * limitation the rights to use, copy, modify, merge, publish, distribute,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, provided that the above copyright
10 * notice(s) and this permission notice appear in all copies of the Soft-
11 * ware and that both the above copyright notice(s) and this permission
12 * notice appear in supporting documentation.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
17 * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
18 * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
19 * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
22 * MANCE OF THIS SOFTWARE.
23 *
24 * Except as contained in this notice, the name of a copyright holder shall
25 * not be used in advertising or otherwise to promote the sale, use or
26 * other dealings in this Software without prior written authorization of
27 * the copyright holder.
28 *
29 * Authors:
30 * Rob Clark (rob@ti.com)
31 */
33 #ifdef HAVE_CONFIG_H
34 # include "config.h"
35 #endif
37 #include "dri2test.h"
39 static Bool WireToEvent(Display *dpy, XExtDisplayInfo *info,
40 XEvent *event, xEvent *wire)
41 {
42 switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
44 case DRI2_BufferSwapComplete:
45 {
46 // xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
47 MSG("BufferSwapComplete");
48 return True;
49 }
50 case DRI2_InvalidateBuffers:
51 {
52 // xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
53 MSG("InvalidateBuffers");
54 // dri2InvalidateBuffers(dpy, awire->drawable);
55 return False;
56 }
57 default:
58 /* client doesn't support server event */
59 break;
60 }
62 return False;
63 }
65 static Status EventToWire(Display *dpy, XExtDisplayInfo *info,
66 XEvent *event, xEvent *wire)
67 {
68 switch (event->type) {
69 default:
70 /* client doesn't support server event */
71 break;
72 }
74 return Success;
75 }
77 static const DRI2EventOps ops = {
78 .WireToEvent = WireToEvent,
79 .EventToWire = EventToWire,
80 };
82 static int dri2_connect(Display *dpy, char **driver)
83 {
84 int eventBase, errorBase, major, minor;
85 char *device;
86 drm_magic_t magic;
87 Window root;
88 int fd;
90 if (!DRI2InitDisplay(dpy, &ops)) {
91 ERROR_MSG("DRI2InitDisplay failed");
92 return -1;
93 }
95 if (!DRI2QueryExtension(dpy, &eventBase, &errorBase)) {
96 ERROR_MSG("DRI2QueryExtension failed");
97 return -1;
98 }
100 MSG("DRI2QueryExtension: eventBase=%d, errorBase=%d", eventBase, errorBase);
102 if (!DRI2QueryVersion(dpy, &major, &minor)) {
103 ERROR_MSG("DRI2QueryVersion failed");
104 return -1;
105 }
107 MSG("DRI2QueryVersion: major=%d, minor=%d", major, minor);
109 root = RootWindow(dpy, DefaultScreen(dpy));
111 if (!DRI2Connect(dpy, root, driver, &device)) {
112 ERROR_MSG("DRI2Connect failed");
113 return -1;
114 }
116 MSG("DRI2Connect: driver=%s, device=%s", *driver, device);
118 fd = open(device, O_RDWR);
119 if (fd < 0) {
120 ERROR_MSG("open failed");
121 return fd;
122 }
124 if (drmGetMagic(fd, &magic)) {
125 ERROR_MSG("drmGetMagic failed");
126 return -1;
127 }
129 if (!DRI2Authenticate(dpy, root, magic)) {
130 ERROR_MSG("DRI2Authenticate failed");
131 return -1;
132 }
134 return fd;
135 }
137 #ifdef HAVE_NOUVEAU
138 extern Backend nouveau_backend;
139 #endif
141 #ifdef HAVE_OMAP
142 extern Backend omap_backend;
143 #endif
145 /* stolen from modetest.c */
146 static void fill(char *virtual, int n, int width, int height, int stride)
147 {
148 int i, j;
149 /* paint the buffer with colored tiles */
150 for (j = 0; j < height; j++) {
151 uint32_t *fb_ptr = (uint32_t*)((char*)virtual + j * stride);
152 for (i = 0; i < width; i++) {
153 div_t d = div(n+i, width);
154 fb_ptr[i] =
155 0x00130502 * (d.quot >> 6) +
156 0x000a1120 * (d.rem >> 6);
157 }
158 }
159 }
162 int main(int argc, char **argv)
163 {
164 static unsigned attachments[] = {
165 DRI2BufferFrontLeft,
166 DRI2BufferBackLeft,
167 };
168 Display *dpy;
169 Window win;
170 Backend *backend = NULL;
171 DRI2Buffer *dri2bufs;
172 Buffer *bufs;
173 char *driver;
174 int fd, nbufs, i, w, h;
176 dpy = XOpenDisplay(NULL);
177 win = XCreateSimpleWindow(dpy, RootWindow(dpy, 0),
178 1, 1, WIDTH, HEIGHT, 0, BlackPixel (dpy, 0), BlackPixel(dpy, 0));
179 XMapWindow(dpy, win);
180 XFlush(dpy);
182 if ((fd = dri2_connect(dpy, &driver)) < 0) {
183 return -1;
184 }
186 #ifdef HAVE_NOUVEAU
187 if (!strcmp(driver, "nouveau")) {
188 backend = &nouveau_backend;
189 }
190 #endif
192 #ifdef HAVE_OMAP
193 if (!strcmp(driver, "omap")) {
194 backend = &omap_backend;
195 }
196 #endif
198 if (!backend) {
199 ERROR_MSG("no suitable backend DRM driver found");
200 return -1;
201 }
203 backend->setup(fd);
205 DRI2CreateDrawable(dpy, win);
207 dri2bufs = DRI2GetBuffers(dpy, win, &w, &h, attachments, 2, &nbufs);
208 if (!dri2bufs) {
209 ERROR_MSG("DRI2GetBuffers failed");
210 return -1;
211 }
213 MSG("DRI2GetBuffers: w=%d, h=%d, nbufs=%d", w, h, nbufs);
215 bufs = calloc(nbufs, sizeof(Buffer));
217 for (i = 0; i < nbufs; i++) {
218 bufs[i].dri2buf = &dri2bufs[i];
219 bufs[i].hdl = backend->init(bufs[i].dri2buf);
220 }
222 for (i = 0; i < NFRAMES; i++) {
223 CARD64 count;
225 char *buf = backend->prep(bufs[i % nbufs].hdl);
226 fill(buf, i, w, h, bufs[i % nbufs].dri2buf->pitch);
227 backend->fini(bufs[i % nbufs].hdl);
228 DRI2SwapBuffers(dpy, win, 0, 0, 0, &count);
229 MSG("DRI2SwapBuffers: count=%lu", count);
230 if (i > 0) {
231 /* XXX wait.. */
232 }
233 }
235 return 0;
236 }