OSDN Git Service

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