1d722e3fbSopenharmony_ci/**************************************************************************
2d722e3fbSopenharmony_ci *
3d722e3fbSopenharmony_ci * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
4d722e3fbSopenharmony_ci * All Rights Reserved.
5d722e3fbSopenharmony_ci *
6d722e3fbSopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7d722e3fbSopenharmony_ci * copy of this software and associated documentation files (the
8d722e3fbSopenharmony_ci * "Software"), to deal in the Software without restriction, including
9d722e3fbSopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10d722e3fbSopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11d722e3fbSopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12d722e3fbSopenharmony_ci * the following conditions:
13d722e3fbSopenharmony_ci *
14d722e3fbSopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15d722e3fbSopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16d722e3fbSopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17d722e3fbSopenharmony_ci * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18d722e3fbSopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19d722e3fbSopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20d722e3fbSopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
21d722e3fbSopenharmony_ci *
22d722e3fbSopenharmony_ci * The above copyright notice and this permission notice (including the
23d722e3fbSopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
24d722e3fbSopenharmony_ci * of the Software.
25d722e3fbSopenharmony_ci *
26d722e3fbSopenharmony_ci *
27d722e3fbSopenharmony_ci **************************************************************************/
28d722e3fbSopenharmony_ci/*
29d722e3fbSopenharmony_ci * Authors: Thomas Hellstr�m <thomas-at-tungstengraphics-dot-com>
30d722e3fbSopenharmony_ci */
31d722e3fbSopenharmony_ci
32d722e3fbSopenharmony_ci#ifdef HAVE_CONFIG_H
33d722e3fbSopenharmony_ci#include "config.h"
34d722e3fbSopenharmony_ci#endif
35d722e3fbSopenharmony_ci
36d722e3fbSopenharmony_ci#include <X11/Xlib.h>
37d722e3fbSopenharmony_ci#include <X11/Xutil.h>
38d722e3fbSopenharmony_ci#include <stdint.h>
39d722e3fbSopenharmony_ci#include <drm/drm.h>
40d722e3fbSopenharmony_ci#include "xf86dri.h"
41d722e3fbSopenharmony_ci#include "xf86drm.h"
42d722e3fbSopenharmony_ci#include "stdio.h"
43d722e3fbSopenharmony_ci#include "sys/types.h"
44d722e3fbSopenharmony_ci#include <unistd.h>
45d722e3fbSopenharmony_ci#include <string.h>
46d722e3fbSopenharmony_ci#include <errno.h>
47d722e3fbSopenharmony_ci#include <stdlib.h>
48d722e3fbSopenharmony_ci#include "sys/mman.h"
49d722e3fbSopenharmony_ci
50d722e3fbSopenharmony_citypedef struct
51d722e3fbSopenharmony_ci{
52d722e3fbSopenharmony_ci    enum
53d722e3fbSopenharmony_ci    {
54d722e3fbSopenharmony_ci	haveNothing,
55d722e3fbSopenharmony_ci	haveDisplay,
56d722e3fbSopenharmony_ci	haveConnection,
57d722e3fbSopenharmony_ci	haveDriverName,
58d722e3fbSopenharmony_ci	haveDeviceInfo,
59d722e3fbSopenharmony_ci	haveDRM,
60d722e3fbSopenharmony_ci	haveContext
61d722e3fbSopenharmony_ci    }
62d722e3fbSopenharmony_ci    state;
63d722e3fbSopenharmony_ci
64d722e3fbSopenharmony_ci    Display *display;
65d722e3fbSopenharmony_ci    int screen;
66d722e3fbSopenharmony_ci    drm_handle_t sAreaOffset;
67d722e3fbSopenharmony_ci    char *curBusID;
68d722e3fbSopenharmony_ci    char *driverName;
69d722e3fbSopenharmony_ci    int drmFD;
70d722e3fbSopenharmony_ci    XVisualInfo visualInfo;
71d722e3fbSopenharmony_ci    XID id;
72d722e3fbSopenharmony_ci    drm_context_t hwContext;
73d722e3fbSopenharmony_ci    void *driPriv;
74d722e3fbSopenharmony_ci    int driPrivSize;
75d722e3fbSopenharmony_ci    int fbSize;
76d722e3fbSopenharmony_ci    int fbOrigin;
77d722e3fbSopenharmony_ci    int fbStride;
78d722e3fbSopenharmony_ci    drm_handle_t fbHandle;
79d722e3fbSopenharmony_ci    int ddxDriverMajor;
80d722e3fbSopenharmony_ci    int ddxDriverMinor;
81d722e3fbSopenharmony_ci    int ddxDriverPatch;
82d722e3fbSopenharmony_ci} TinyDRIContext;
83d722e3fbSopenharmony_ci
84d722e3fbSopenharmony_ci#ifndef __x86_64__
85d722e3fbSopenharmony_cistatic unsigned
86d722e3fbSopenharmony_cifastrdtsc(void)
87d722e3fbSopenharmony_ci{
88d722e3fbSopenharmony_ci    unsigned eax;
89d722e3fbSopenharmony_ci    __asm__ volatile ("\t"
90d722e3fbSopenharmony_ci	"pushl  %%ebx\n\t"
91d722e3fbSopenharmony_ci	"cpuid\n\t" ".byte 0x0f, 0x31\n\t" "popl %%ebx\n":"=a" (eax)
92d722e3fbSopenharmony_ci	:"0"(0)
93d722e3fbSopenharmony_ci	:"ecx", "edx", "cc");
94d722e3fbSopenharmony_ci
95d722e3fbSopenharmony_ci    return eax;
96d722e3fbSopenharmony_ci}
97d722e3fbSopenharmony_ci#else
98d722e3fbSopenharmony_cistatic unsigned
99d722e3fbSopenharmony_cifastrdtsc(void)
100d722e3fbSopenharmony_ci{
101d722e3fbSopenharmony_ci    unsigned eax;
102d722e3fbSopenharmony_ci    __asm__ volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax)
103d722e3fbSopenharmony_ci	:"0"(0)
104d722e3fbSopenharmony_ci	:"ecx", "edx", "ebx", "cc");
105d722e3fbSopenharmony_ci
106d722e3fbSopenharmony_ci    return eax;
107d722e3fbSopenharmony_ci}
108d722e3fbSopenharmony_ci#endif
109d722e3fbSopenharmony_ci
110d722e3fbSopenharmony_civoid
111d722e3fbSopenharmony_cibmError(int val, const char *file, const char *function, int line)
112d722e3fbSopenharmony_ci{
113d722e3fbSopenharmony_ci    fprintf(stderr, "Fatal video memory manager error \"%s\".\n"
114d722e3fbSopenharmony_ci	"Check kernel logs or set the LIBGL_DEBUG\n"
115d722e3fbSopenharmony_ci	"environment variable to \"verbose\" for more info.\n"
116d722e3fbSopenharmony_ci	"Detected in file %s, line %d, function %s.\n",
117d722e3fbSopenharmony_ci	strerror(-val), file, line, function);
118d722e3fbSopenharmony_ci    abort();
119d722e3fbSopenharmony_ci}
120d722e3fbSopenharmony_ci
121d722e3fbSopenharmony_ci#define BM_CKFATAL(val)					       \
122d722e3fbSopenharmony_ci  do{							       \
123d722e3fbSopenharmony_ci    int tstVal = (val);					       \
124d722e3fbSopenharmony_ci    if (tstVal) 					       \
125d722e3fbSopenharmony_ci      bmError(tstVal, __FILE__, __FUNCTION__, __LINE__);       \
126d722e3fbSopenharmony_ci  } while(0);
127d722e3fbSopenharmony_ci
128d722e3fbSopenharmony_cistatic unsigned
129d722e3fbSopenharmony_citime_diff(unsigned t, unsigned t2)
130d722e3fbSopenharmony_ci{
131d722e3fbSopenharmony_ci    return ((t < t2) ? t2 - t : 0xFFFFFFFFU - (t - t2 - 1));
132d722e3fbSopenharmony_ci}
133d722e3fbSopenharmony_ci
134d722e3fbSopenharmony_cistatic int
135d722e3fbSopenharmony_cireleaseContext(TinyDRIContext * ctx)
136d722e3fbSopenharmony_ci{
137d722e3fbSopenharmony_ci    switch (ctx->state) {
138d722e3fbSopenharmony_ci    case haveContext:
139d722e3fbSopenharmony_ci	uniDRIDestroyContext(ctx->display, ctx->screen, ctx->id);
140d722e3fbSopenharmony_ci    case haveDRM:
141d722e3fbSopenharmony_ci	drmClose(ctx->drmFD);
142d722e3fbSopenharmony_ci    case haveDeviceInfo:
143d722e3fbSopenharmony_ci	XFree(ctx->driPriv);
144d722e3fbSopenharmony_ci    case haveDriverName:
145d722e3fbSopenharmony_ci	XFree(ctx->driverName);
146d722e3fbSopenharmony_ci    case haveConnection:
147d722e3fbSopenharmony_ci	XFree(ctx->curBusID);
148d722e3fbSopenharmony_ci	uniDRICloseConnection(ctx->display, ctx->screen);
149d722e3fbSopenharmony_ci    case haveDisplay:
150d722e3fbSopenharmony_ci	XCloseDisplay(ctx->display);
151d722e3fbSopenharmony_ci    default:
152d722e3fbSopenharmony_ci	break;
153d722e3fbSopenharmony_ci    }
154d722e3fbSopenharmony_ci    return -1;
155d722e3fbSopenharmony_ci}
156d722e3fbSopenharmony_ci
157d722e3fbSopenharmony_cistatic void
158d722e3fbSopenharmony_cireadBuf(void *buf, unsigned long size)
159d722e3fbSopenharmony_ci{
160d722e3fbSopenharmony_ci    volatile unsigned *buf32 = (unsigned *)buf;
161d722e3fbSopenharmony_ci    unsigned *end = (unsigned *)buf32 + size / sizeof(*buf32);
162d722e3fbSopenharmony_ci
163d722e3fbSopenharmony_ci    while (buf32 < end) {
164d722e3fbSopenharmony_ci	(void)*buf32++;
165d722e3fbSopenharmony_ci    }
166d722e3fbSopenharmony_ci}
167d722e3fbSopenharmony_ci
168d722e3fbSopenharmony_cistatic int
169d722e3fbSopenharmony_cibenchmarkBuffer(TinyDRIContext * ctx, unsigned long size,
170d722e3fbSopenharmony_ci    unsigned long *ticks)
171d722e3fbSopenharmony_ci{
172d722e3fbSopenharmony_ci    unsigned long curTime, oldTime;
173d722e3fbSopenharmony_ci    int ret;
174d722e3fbSopenharmony_ci    drmBO buf;
175d722e3fbSopenharmony_ci    void *virtual;
176d722e3fbSopenharmony_ci
177d722e3fbSopenharmony_ci    /*
178d722e3fbSopenharmony_ci     * Test system memory objects.
179d722e3fbSopenharmony_ci     */
180d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
181d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOCreate(ctx->drmFD, size, 0, NULL,
182d722e3fbSopenharmony_ci			   DRM_BO_FLAG_READ |
183d722e3fbSopenharmony_ci			   DRM_BO_FLAG_WRITE |
184d722e3fbSopenharmony_ci			   DRM_BO_FLAG_MEM_LOCAL, 0, &buf));
185d722e3fbSopenharmony_ci    curTime = fastrdtsc();
186d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
187d722e3fbSopenharmony_ci
188d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
189d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOMap(ctx->drmFD, &buf,
190d722e3fbSopenharmony_ci	    DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual));
191d722e3fbSopenharmony_ci    curTime = fastrdtsc();
192d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
193d722e3fbSopenharmony_ci
194d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
195d722e3fbSopenharmony_ci    memset(virtual, 0xF0, buf.size);
196d722e3fbSopenharmony_ci    curTime = fastrdtsc();
197d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
198d722e3fbSopenharmony_ci
199d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
200d722e3fbSopenharmony_ci    memset(virtual, 0x0F, buf.size);
201d722e3fbSopenharmony_ci    curTime = fastrdtsc();
202d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
203d722e3fbSopenharmony_ci
204d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
205d722e3fbSopenharmony_ci    readBuf(virtual, buf.size);
206d722e3fbSopenharmony_ci    curTime = fastrdtsc();
207d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
208d722e3fbSopenharmony_ci
209d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
210d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf));
211d722e3fbSopenharmony_ci    curTime = fastrdtsc();
212d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
213d722e3fbSopenharmony_ci
214d722e3fbSopenharmony_ci    /*
215d722e3fbSopenharmony_ci     * Test TT bound buffer objects.
216d722e3fbSopenharmony_ci     */
217d722e3fbSopenharmony_ci
218d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
219d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf,
220d722e3fbSopenharmony_ci			     DRM_BO_FLAG_MEM_TT,
221d722e3fbSopenharmony_ci			     DRM_BO_MASK_MEM,
222d722e3fbSopenharmony_ci			      0,0,0));
223d722e3fbSopenharmony_ci    curTime = fastrdtsc();
224d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
225d722e3fbSopenharmony_ci
226d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
227d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOMap(ctx->drmFD, &buf,
228d722e3fbSopenharmony_ci	    DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual));
229d722e3fbSopenharmony_ci    curTime = fastrdtsc();
230d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
231d722e3fbSopenharmony_ci
232d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
233d722e3fbSopenharmony_ci    memset(virtual, 0xF0, buf.size);
234d722e3fbSopenharmony_ci    curTime = fastrdtsc();
235d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
236d722e3fbSopenharmony_ci
237d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
238d722e3fbSopenharmony_ci    memset(virtual, 0x0F, buf.size);
239d722e3fbSopenharmony_ci    curTime = fastrdtsc();
240d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
241d722e3fbSopenharmony_ci
242d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
243d722e3fbSopenharmony_ci    readBuf(virtual, buf.size);
244d722e3fbSopenharmony_ci    curTime = fastrdtsc();
245d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
246d722e3fbSopenharmony_ci
247d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf));
248d722e3fbSopenharmony_ci
249d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
250d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOSetStatus(ctx->drmFD, &buf,
251d722e3fbSopenharmony_ci			     DRM_BO_FLAG_MEM_LOCAL, DRM_BO_MASK_MEM, 0, 0,0));
252d722e3fbSopenharmony_ci    curTime = fastrdtsc();
253d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
254d722e3fbSopenharmony_ci
255d722e3fbSopenharmony_ci    /*
256d722e3fbSopenharmony_ci     * Test cached buffers objects.
257d722e3fbSopenharmony_ci     */
258d722e3fbSopenharmony_ci
259d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
260d722e3fbSopenharmony_ci    ret = drmBOSetStatus(ctx->drmFD, &buf,
261d722e3fbSopenharmony_ci			 DRM_BO_FLAG_MEM_TT |
262d722e3fbSopenharmony_ci			 DRM_BO_FLAG_CACHED |
263d722e3fbSopenharmony_ci			 DRM_BO_FLAG_FORCE_CACHING,
264d722e3fbSopenharmony_ci			 DRM_BO_MASK_MEMTYPE |
265d722e3fbSopenharmony_ci			 DRM_BO_FLAG_FORCE_CACHING,
266d722e3fbSopenharmony_ci			 0, 0, 0);
267d722e3fbSopenharmony_ci    curTime = fastrdtsc();
268d722e3fbSopenharmony_ci
269d722e3fbSopenharmony_ci    if (ret) {
270d722e3fbSopenharmony_ci	printf("Couldn't bind cached. Probably no support\n");
271d722e3fbSopenharmony_ci	BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf));
272d722e3fbSopenharmony_ci	return 1;
273d722e3fbSopenharmony_ci    }
274d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
275d722e3fbSopenharmony_ci
276d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
277d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOMap(ctx->drmFD, &buf,
278d722e3fbSopenharmony_ci	    DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &virtual));
279d722e3fbSopenharmony_ci
280d722e3fbSopenharmony_ci    curTime = fastrdtsc();
281d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
282d722e3fbSopenharmony_ci
283d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
284d722e3fbSopenharmony_ci    memset(virtual, 0xF0, buf.size);
285d722e3fbSopenharmony_ci    curTime = fastrdtsc();
286d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
287d722e3fbSopenharmony_ci
288d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
289d722e3fbSopenharmony_ci    memset(virtual, 0x0F, buf.size);
290d722e3fbSopenharmony_ci    curTime = fastrdtsc();
291d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
292d722e3fbSopenharmony_ci
293d722e3fbSopenharmony_ci    oldTime = fastrdtsc();
294d722e3fbSopenharmony_ci    readBuf(virtual, buf.size);
295d722e3fbSopenharmony_ci    curTime = fastrdtsc();
296d722e3fbSopenharmony_ci    *ticks++ = time_diff(oldTime, curTime);
297d722e3fbSopenharmony_ci
298d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOUnmap(ctx->drmFD, &buf));
299d722e3fbSopenharmony_ci    BM_CKFATAL(drmBOUnreference(ctx->drmFD, &buf));
300d722e3fbSopenharmony_ci
301d722e3fbSopenharmony_ci    return 0;
302d722e3fbSopenharmony_ci}
303d722e3fbSopenharmony_ci
304d722e3fbSopenharmony_cistatic void
305d722e3fbSopenharmony_citestAGP(TinyDRIContext * ctx)
306d722e3fbSopenharmony_ci{
307d722e3fbSopenharmony_ci    unsigned long ticks[128], *pTicks;
308d722e3fbSopenharmony_ci    unsigned long size = 8 * 1024;
309d722e3fbSopenharmony_ci    int ret;
310d722e3fbSopenharmony_ci
311d722e3fbSopenharmony_ci    ret = benchmarkBuffer(ctx, size, ticks);
312d722e3fbSopenharmony_ci    if (ret < 0) {
313d722e3fbSopenharmony_ci	fprintf(stderr, "Buffer error %s\n", strerror(-ret));
314d722e3fbSopenharmony_ci	return;
315d722e3fbSopenharmony_ci    }
316d722e3fbSopenharmony_ci    pTicks = ticks;
317d722e3fbSopenharmony_ci
318d722e3fbSopenharmony_ci    printf("Buffer size %d bytes\n", size);
319d722e3fbSopenharmony_ci    printf("System memory timings ********************************\n");
320d722e3fbSopenharmony_ci    printf("Creation took            %12lu ticks\n", *pTicks++);
321d722e3fbSopenharmony_ci    printf("Mapping took             %12lu ticks\n", *pTicks++);
322d722e3fbSopenharmony_ci    printf("Writing took             %12lu ticks\n", *pTicks++);
323d722e3fbSopenharmony_ci    printf("Writing Again took       %12lu ticks\n", *pTicks++);
324d722e3fbSopenharmony_ci    printf("Reading took             %12lu ticks\n", *pTicks++);
325d722e3fbSopenharmony_ci    printf("Unmapping took           %12lu ticks\n", *pTicks++);
326d722e3fbSopenharmony_ci
327d722e3fbSopenharmony_ci    printf("\nTT Memory timings ************************************\n");
328d722e3fbSopenharmony_ci    printf("Moving to TT took        %12lu ticks\n", *pTicks++);
329d722e3fbSopenharmony_ci    printf("Mapping in TT took       %12lu ticks\n", *pTicks++);
330d722e3fbSopenharmony_ci    printf("Writing to TT took       %12lu ticks\n", *pTicks++);
331d722e3fbSopenharmony_ci    printf("Writing again to TT took %12lu ticks\n", *pTicks++);
332d722e3fbSopenharmony_ci    printf("Reading from TT took     %12lu ticks\n", *pTicks++);
333d722e3fbSopenharmony_ci    printf("Moving to system took    %12lu ticks\n", *pTicks++);
334d722e3fbSopenharmony_ci
335d722e3fbSopenharmony_ci    if (ret == 1)
336d722e3fbSopenharmony_ci	return;
337d722e3fbSopenharmony_ci
338d722e3fbSopenharmony_ci    printf("\nCached TT Memory timings *****************************\n");
339d722e3fbSopenharmony_ci    printf("Moving to CTT took       %12lu ticks\n", *pTicks++);
340d722e3fbSopenharmony_ci    printf("Mapping in CTT took      %12lu ticks\n", *pTicks++);
341d722e3fbSopenharmony_ci    printf("Writing to CTT took      %12lu ticks\n", *pTicks++);
342d722e3fbSopenharmony_ci    printf("Re-writing to CTT took   %12lu ticks\n", *pTicks++);
343d722e3fbSopenharmony_ci    printf("Reading from CTT took    %12lu ticks\n", *pTicks++);
344d722e3fbSopenharmony_ci    printf("\n\n");
345d722e3fbSopenharmony_ci}
346d722e3fbSopenharmony_ci
347d722e3fbSopenharmony_ciint
348d722e3fbSopenharmony_cimain()
349d722e3fbSopenharmony_ci{
350d722e3fbSopenharmony_ci    int ret, screen, isCapable;
351d722e3fbSopenharmony_ci    char *displayName = ":0";
352d722e3fbSopenharmony_ci    TinyDRIContext ctx;
353d722e3fbSopenharmony_ci    unsigned magic;
354d722e3fbSopenharmony_ci
355d722e3fbSopenharmony_ci    ctx.screen = 0;
356d722e3fbSopenharmony_ci    ctx.state = haveNothing;
357d722e3fbSopenharmony_ci    ctx.display = XOpenDisplay(displayName);
358d722e3fbSopenharmony_ci    if (!ctx.display) {
359d722e3fbSopenharmony_ci	fprintf(stderr, "Could not open display\n");
360d722e3fbSopenharmony_ci	return releaseContext(&ctx);
361d722e3fbSopenharmony_ci    }
362d722e3fbSopenharmony_ci    ctx.state = haveDisplay;
363d722e3fbSopenharmony_ci
364d722e3fbSopenharmony_ci    ret =
365d722e3fbSopenharmony_ci	uniDRIQueryDirectRenderingCapable(ctx.display, ctx.screen,
366d722e3fbSopenharmony_ci	&isCapable);
367d722e3fbSopenharmony_ci    if (!ret || !isCapable) {
368d722e3fbSopenharmony_ci	fprintf(stderr, "No DRI on this display:sceen\n");
369d722e3fbSopenharmony_ci	return releaseContext(&ctx);
370d722e3fbSopenharmony_ci    }
371d722e3fbSopenharmony_ci
372d722e3fbSopenharmony_ci    if (!uniDRIOpenConnection(ctx.display, ctx.screen, &ctx.sAreaOffset,
373d722e3fbSopenharmony_ci	    &ctx.curBusID)) {
374d722e3fbSopenharmony_ci	fprintf(stderr, "Could not open DRI connection.\n");
375d722e3fbSopenharmony_ci	return releaseContext(&ctx);
376d722e3fbSopenharmony_ci    }
377d722e3fbSopenharmony_ci    ctx.state = haveConnection;
378d722e3fbSopenharmony_ci
379d722e3fbSopenharmony_ci    if (!uniDRIGetClientDriverName(ctx.display, ctx.screen,
380d722e3fbSopenharmony_ci	    &ctx.ddxDriverMajor, &ctx.ddxDriverMinor,
381d722e3fbSopenharmony_ci	    &ctx.ddxDriverPatch, &ctx.driverName)) {
382d722e3fbSopenharmony_ci	fprintf(stderr, "Could not get DRI driver name.\n");
383d722e3fbSopenharmony_ci	return releaseContext(&ctx);
384d722e3fbSopenharmony_ci    }
385d722e3fbSopenharmony_ci    ctx.state = haveDriverName;
386d722e3fbSopenharmony_ci
387d722e3fbSopenharmony_ci    if (!uniDRIGetDeviceInfo(ctx.display, ctx.screen,
388d722e3fbSopenharmony_ci	    &ctx.fbHandle, &ctx.fbOrigin, &ctx.fbSize,
389d722e3fbSopenharmony_ci	    &ctx.fbStride, &ctx.driPrivSize, &ctx.driPriv)) {
390d722e3fbSopenharmony_ci	fprintf(stderr, "Could not get DRI device info.\n");
391d722e3fbSopenharmony_ci	return releaseContext(&ctx);
392d722e3fbSopenharmony_ci    }
393d722e3fbSopenharmony_ci    ctx.state = haveDriverName;
394d722e3fbSopenharmony_ci
395d722e3fbSopenharmony_ci    if ((ctx.drmFD = drmOpen(NULL, ctx.curBusID)) < 0) {
396d722e3fbSopenharmony_ci	perror("DRM Device could not be opened");
397d722e3fbSopenharmony_ci	return releaseContext(&ctx);
398d722e3fbSopenharmony_ci    }
399d722e3fbSopenharmony_ci    ctx.state = haveDRM;
400d722e3fbSopenharmony_ci
401d722e3fbSopenharmony_ci    drmGetMagic(ctx.drmFD, &magic);
402d722e3fbSopenharmony_ci    if (!uniDRIAuthConnection(ctx.display, ctx.screen, magic)) {
403d722e3fbSopenharmony_ci	fprintf(stderr, "Could not get X server to authenticate us.\n");
404d722e3fbSopenharmony_ci	return releaseContext(&ctx);
405d722e3fbSopenharmony_ci    }
406d722e3fbSopenharmony_ci
407d722e3fbSopenharmony_ci    ret = XMatchVisualInfo(ctx.display, ctx.screen, 24, TrueColor,
408d722e3fbSopenharmony_ci	&ctx.visualInfo);
409d722e3fbSopenharmony_ci    if (!ret) {
410d722e3fbSopenharmony_ci	ret = XMatchVisualInfo(ctx.display, ctx.screen, 16, TrueColor,
411d722e3fbSopenharmony_ci	    &ctx.visualInfo);
412d722e3fbSopenharmony_ci	if (!ret) {
413d722e3fbSopenharmony_ci	    fprintf(stderr, "Could not find a matching visual.\n");
414d722e3fbSopenharmony_ci	    return releaseContext(&ctx);
415d722e3fbSopenharmony_ci	}
416d722e3fbSopenharmony_ci    }
417d722e3fbSopenharmony_ci
418d722e3fbSopenharmony_ci    if (!uniDRICreateContext(ctx.display, ctx.screen, ctx.visualInfo.visual,
419d722e3fbSopenharmony_ci	    &ctx.id, &ctx.hwContext)) {
420d722e3fbSopenharmony_ci	fprintf(stderr, "Could not create DRI context.\n");
421d722e3fbSopenharmony_ci	return releaseContext(&ctx);
422d722e3fbSopenharmony_ci    }
423d722e3fbSopenharmony_ci    ctx.state = haveContext;
424d722e3fbSopenharmony_ci
425d722e3fbSopenharmony_ci    testAGP(&ctx);
426d722e3fbSopenharmony_ci
427d722e3fbSopenharmony_ci    releaseContext(&ctx);
428d722e3fbSopenharmony_ci    printf("Terminating normally\n");
429d722e3fbSopenharmony_ci    return 0;
430d722e3fbSopenharmony_ci}
431