1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
27 **************************************************************************/
29 * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
37 #include <X11/Xutil.h>
43 #include "sys/types.h"
66 drm_handle_t sAreaOffset
;
70 XVisualInfo visualInfo
;
72 drm_context_t hwContext
;
78 drm_handle_t fbHandle
;
89 __asm__
volatile ("\t"
91 "cpuid\n\t" ".byte 0x0f, 0x31\n\t" "popl %%ebx\n":"=a" (eax
)
102 __asm__
volatile ("\t" "cpuid\n\t" ".byte 0x0f, 0x31\n\t":"=a" (eax
)
104 :"ecx", "edx", "ebx", "cc");
111 bmError(int val
, const char *file
, const char *function
, int line
)
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
);
121 #define BM_CKFATAL(val) \
123 int tstVal = (val); \
125 bmError(tstVal, __FILE__, __FUNCTION__, __LINE__); \
129 time_diff(unsigned t
, unsigned t2
)
131 return ((t
< t2
) ? t2
- t
: 0xFFFFFFFFU
- (t
- t2
- 1));
135 releaseContext(TinyDRIContext
* ctx
)
137 switch (ctx
->state
) {
139 uniDRIDestroyContext(ctx
->display
, ctx
->screen
, ctx
->id
);
141 drmClose(ctx
->drmFD
);
145 XFree(ctx
->driverName
);
147 XFree(ctx
->curBusID
);
148 uniDRICloseConnection(ctx
->display
, ctx
->screen
);
150 XCloseDisplay(ctx
->display
);
158 readBuf(void *buf
, unsigned long size
)
160 volatile unsigned *buf32
= (unsigned *)buf
;
161 unsigned *end
= (unsigned *)buf32
+ size
/ sizeof(*buf32
);
163 while (buf32
< end
) {
169 benchmarkBuffer(TinyDRIContext
* ctx
, unsigned long size
,
170 unsigned long *ticks
)
172 unsigned long curTime
, oldTime
;
178 * Test system memory objects.
180 oldTime
= fastrdtsc();
181 BM_CKFATAL(drmBOCreate(ctx
->drmFD
, size
, 0, NULL
,
184 DRM_BO_FLAG_MEM_LOCAL
, 0, &buf
));
185 curTime
= fastrdtsc();
186 *ticks
++ = time_diff(oldTime
, curTime
);
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
);
194 oldTime
= fastrdtsc();
195 memset(virtual, 0xF0, buf
.size
);
196 curTime
= fastrdtsc();
197 *ticks
++ = time_diff(oldTime
, curTime
);
199 oldTime
= fastrdtsc();
200 memset(virtual, 0x0F, buf
.size
);
201 curTime
= fastrdtsc();
202 *ticks
++ = time_diff(oldTime
, curTime
);
204 oldTime
= fastrdtsc();
205 readBuf(virtual, buf
.size
);
206 curTime
= fastrdtsc();
207 *ticks
++ = time_diff(oldTime
, curTime
);
209 oldTime
= fastrdtsc();
210 BM_CKFATAL(drmBOUnmap(ctx
->drmFD
, &buf
));
211 curTime
= fastrdtsc();
212 *ticks
++ = time_diff(oldTime
, curTime
);
215 * Test TT bound buffer objects.
218 oldTime
= fastrdtsc();
219 BM_CKFATAL(drmBOSetStatus(ctx
->drmFD
, &buf
,
223 curTime
= fastrdtsc();
224 *ticks
++ = time_diff(oldTime
, curTime
);
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
);
232 oldTime
= fastrdtsc();
233 memset(virtual, 0xF0, buf
.size
);
234 curTime
= fastrdtsc();
235 *ticks
++ = time_diff(oldTime
, curTime
);
237 oldTime
= fastrdtsc();
238 memset(virtual, 0x0F, buf
.size
);
239 curTime
= fastrdtsc();
240 *ticks
++ = time_diff(oldTime
, curTime
);
242 oldTime
= fastrdtsc();
243 readBuf(virtual, buf
.size
);
244 curTime
= fastrdtsc();
245 *ticks
++ = time_diff(oldTime
, curTime
);
247 BM_CKFATAL(drmBOUnmap(ctx
->drmFD
, &buf
));
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
);
256 * Test cached buffers objects.
259 oldTime
= fastrdtsc();
260 ret
= drmBOSetStatus(ctx
->drmFD
, &buf
,
263 DRM_BO_FLAG_FORCE_CACHING
,
264 DRM_BO_MASK_MEMTYPE
|
265 DRM_BO_FLAG_FORCE_CACHING
,
267 curTime
= fastrdtsc();
270 printf("Couldn't bind cached. Probably no support\n");
271 BM_CKFATAL(drmBOUnreference(ctx
->drmFD
, &buf
));
274 *ticks
++ = time_diff(oldTime
, curTime
);
276 oldTime
= fastrdtsc();
277 BM_CKFATAL(drmBOMap(ctx
->drmFD
, &buf
,
278 DRM_BO_FLAG_READ
| DRM_BO_FLAG_WRITE
, 0, &virtual));
280 curTime
= fastrdtsc();
281 *ticks
++ = time_diff(oldTime
, curTime
);
283 oldTime
= fastrdtsc();
284 memset(virtual, 0xF0, buf
.size
);
285 curTime
= fastrdtsc();
286 *ticks
++ = time_diff(oldTime
, curTime
);
288 oldTime
= fastrdtsc();
289 memset(virtual, 0x0F, buf
.size
);
290 curTime
= fastrdtsc();
291 *ticks
++ = time_diff(oldTime
, curTime
);
293 oldTime
= fastrdtsc();
294 readBuf(virtual, buf
.size
);
295 curTime
= fastrdtsc();
296 *ticks
++ = time_diff(oldTime
, curTime
);
298 BM_CKFATAL(drmBOUnmap(ctx
->drmFD
, &buf
));
299 BM_CKFATAL(drmBOUnreference(ctx
->drmFD
, &buf
));
305 testAGP(TinyDRIContext
* ctx
)
307 unsigned long ticks
[128], *pTicks
;
308 unsigned long size
= 8 * 1024;
311 ret
= benchmarkBuffer(ctx
, size
, ticks
);
313 fprintf(stderr
, "Buffer error %s\n", strerror(-ret
));
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
++);
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
++);
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
++);
350 int ret
, screen
, isCapable
;
351 char *displayName
= ":0";
356 ctx
.state
= haveNothing
;
357 ctx
.display
= XOpenDisplay(displayName
);
359 fprintf(stderr
, "Could not open display\n");
360 return releaseContext(&ctx
);
362 ctx
.state
= haveDisplay
;
365 uniDRIQueryDirectRenderingCapable(ctx
.display
, ctx
.screen
,
367 if (!ret
|| !isCapable
) {
368 fprintf(stderr
, "No DRI on this display:sceen\n");
369 return releaseContext(&ctx
);
372 if (!uniDRIOpenConnection(ctx
.display
, ctx
.screen
, &ctx
.sAreaOffset
,
374 fprintf(stderr
, "Could not open DRI connection.\n");
375 return releaseContext(&ctx
);
377 ctx
.state
= haveConnection
;
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
);
385 ctx
.state
= haveDriverName
;
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
);
393 ctx
.state
= haveDriverName
;
395 if ((ctx
.drmFD
= drmOpen(NULL
, ctx
.curBusID
)) < 0) {
396 perror("DRM Device could not be opened");
397 return releaseContext(&ctx
);
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
);
407 ret
= XMatchVisualInfo(ctx
.display
, ctx
.screen
, 24, TrueColor
,
410 ret
= XMatchVisualInfo(ctx
.display
, ctx
.screen
, 16, TrueColor
,
413 fprintf(stderr
, "Could not find a matching visual.\n");
414 return releaseContext(&ctx
);
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
);
423 ctx
.state
= haveContext
;
427 releaseContext(&ctx
);
428 printf("Terminating normally\n");