crete an idle task to run when theres ... umm. .. nothing to do ..
[AROS.git] / test / benchmarks / graphics / gfxbench.c
blob7fcda5d3d3deca5d19e76e9c17306d152729638e
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Cumulative graphics benchmarks
6 Lang: English
7 */
8 /*****************************************************************************
10 NAME
12 gfxbench
14 SYNOPSIS
16 LOCATION
18 FUNCTION
20 RESULT
22 NOTES
24 BUGS
26 INTERNALS
28 ******************************************************************************/
30 #include <cybergraphx/cybergraphics.h>
31 #include <proto/exec.h>
32 #include <devices/timer.h>
33 #include <proto/diskfont.h>
34 #include <proto/graphics.h>
35 #include <proto/intuition.h>
36 #include <proto/dos.h>
37 #include <resources/processor.h>
38 #include <proto/processor.h>
39 #include <proto/oop.h>
40 #include <proto/cybergraphics.h>
41 #include <hidd/pci.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <stdio.h>
46 struct Window * win;
47 LONG width = 1280;
48 LONG height = 720;
50 /* COMMON */
51 static void printresults(LONG timems, LONG blits)
53 LONG bpp; QUAD q;
55 bpp = GetCyberMapAttr(win->WScreen->RastPort.BitMap, CYBRMATTR_BPPIX);
56 q = ((QUAD)width) * ((QUAD)height) * ((QUAD)bpp) * ((QUAD)blits) * ((QUAD)1000000) / (QUAD)timems;
58 printf("%.2f|%d|\n", (blits * 1000000.0 / timems), (int)(q / 1048576));
61 static void cleanup(STRPTR msg, ULONG retcode)
63 if (msg)
64 fprintf(stderr, "text: %s\n", msg);
66 exit(retcode);
69 /* TEXT BENCH */
70 #define ONLY_BENCH_CODE
72 STRPTR consttext = "The AROS Development Team. All rights reserved.";
73 LONG mode = JAM1;
74 BOOL antialias = FALSE;
75 LONG linelen = 100;
76 LONG function = 0;
77 LONG pixfmt = RECTFMT_ARGB;
79 #include "text.c"
80 #include "pixelarray.c"
82 /* PCI Vendor/Product name translaction. Taken from PCITool */
84 #include <ctype.h>
85 // it's supposed to become a shared library one day ...
86 //
87 // current implementation:
88 // on pciids_Open(), the file is read in memory, then
89 // an index is built (in computeVendorIndexes()), as an array
90 // of couples (vendor_id, offset)
91 // where offset is the offset where the vendor stuff begins
92 // in the memory file. This array is ascending sorted by vendor_id,
93 // so a binary search can be done to retrieve the vendor offset
94 // given its id. This search is done in getVendorIndex().
95 // All the stringification functions first call this search func,
96 // then parse the memory:
97 // 1234 VendorName (so: s[0] = hex digit, s[4] == ' ', s[6+] == name)
98 // <tab>1234 DeviceName (same with a tab on linestart)
99 // todo: subvendor/subdevice parsing
100 // todo: proper memory reallocation, currently the index is fixed
101 // to 2500 vendors
103 static STRPTR mem = NULL;
104 static ULONG memsize = 0;
106 struct vendor_cell
108 UWORD vendorID;
109 LONG offset;
112 static struct vendor_cell *vendor_index = NULL;
113 static ULONG vi_allocated = 0;
114 static UWORD vi_number = 0;
116 static LONG skip_line(const char *buffer, LONG size, LONG pos)
118 buffer += pos;
119 while (pos < size)
121 if (*buffer++ == '\n')
123 pos++;
124 break;
126 pos++;
128 return pos;
131 static LONG copy_until_eol(STRPTR m, ULONG msize, LONG pos, STRPTR buf,
132 ULONG bufsize)
134 LONG j = 0;
136 m += pos;
137 while ((pos < msize) && (j < bufsize - 1) && (*m != '\n'))
139 buf[j++] = *m++;
141 buf[j] = 0;
142 return j;
145 static BOOL computeVendorIndexes(const char *buffer, LONG size)
147 LONG i, j;
149 vi_allocated = 2500;
150 vendor_index = AllocVec(vi_allocated * sizeof(struct vendor_cell), MEMF_ANY);
151 if (NULL == vendor_index)
152 return FALSE;
154 i = 0;
155 j = 0;
157 while (i < size)
159 // don't use isxdigit, beware of uppercase letter
160 if ((isdigit(buffer[i]) || (buffer[i] >= 'a' && buffer[i] <= 'f'))
161 && (i + 4 < size) && (buffer[i + 4] == ' '))
163 if (sscanf(buffer + i, "%hx", &(vendor_index[j].vendorID)) != 1)
164 return FALSE;
165 vendor_index[j].offset = i;
167 j++;
168 if (j >= vi_allocated)
170 FreeVec(vendor_index);
171 vendor_index = NULL;
172 return FALSE;
175 i = skip_line(buffer, size, i);
177 vi_number = j - 1;
178 return TRUE;
181 static LONG getVendorIndex(UWORD vendorID)
183 LONG lower = 0;
184 LONG upper = vi_number;
186 if (!mem || !vendor_index)
187 return -1;
189 while (upper != lower)
191 UWORD vid;
193 vid = vendor_index[(upper + lower) / 2].vendorID;
194 if (vid == vendorID)
195 return vendor_index[(upper + lower) / 2].offset;
196 if (vendorID > vid)
197 lower = (upper + lower) / 2 + 1;
198 else
199 upper = (upper + lower) / 2;
201 return -1;
204 static LONG getDeviceIndex(LONG vendorIndex, UWORD deviceID)
206 LONG i = vendorIndex;
208 if (i < 0)
209 return i;
211 i = skip_line(mem, memsize, i); // skip vendor
212 while ((i < memsize) && ((mem[i] == '\t') || (mem[i] == '#')))
214 UWORD did;
216 if (mem[i] != '#')
218 if ((i + 6 < memsize) && (mem[i + 5] == ' ')
219 && (sscanf(mem + i + 1, "%hx", &did) == 1) && (did == deviceID))
221 return i;
224 i = skip_line(mem, memsize, i);
226 return -1;
229 static void pciids_Open(void)
231 BPTR fh;
232 LONG size;
234 fh = Open("DEVS:pci.ids", MODE_OLDFILE);
235 if (!fh)
236 goto err_open_ids;
238 Seek(fh, 0, OFFSET_END);
239 size = Seek(fh, 0, OFFSET_CURRENT);
240 if (size <= 0)
241 goto err_size;
243 memsize = (ULONG)size;
244 Seek(fh, 0, OFFSET_BEGINNING);
246 mem = AllocVec(memsize, MEMF_ANY);
247 if (NULL == mem)
248 goto err_mem;
250 if (Read(fh, mem, memsize) != size)
251 goto err_read;
253 if (!computeVendorIndexes(mem, memsize))
254 goto err_index;
256 // success !
257 return;
259 err_index:
260 err_read:
261 FreeVec(mem);
262 mem = NULL;
263 err_mem:
264 err_size:
265 Close(fh);
266 err_open_ids:
267 return;
270 static void pciids_Close(void)
272 if (vendor_index)
274 FreeVec(vendor_index);
275 vendor_index = NULL;
278 if (mem)
280 FreeVec(mem);
281 mem = NULL;
285 static STRPTR pciids_GetVendorName(UWORD vendorID, STRPTR buf, ULONG bufsize)
287 LONG i = getVendorIndex(vendorID);
289 buf[0] = 0;
290 if (i < 0)
291 return buf;
293 copy_until_eol(mem, memsize, i + 6, buf, bufsize);
295 return buf;
298 static STRPTR pciids_GetDeviceName(UWORD vendorID, UWORD deviceID, STRPTR buf, ULONG bufsize)
300 LONG i = getVendorIndex(vendorID);
302 buf[0] = 0;
303 if (i < 0) // unknown vendor
304 return buf;
306 i = getDeviceIndex(i, deviceID);
307 if (i < 0) // unknown device
308 return buf;
310 copy_until_eol(mem, memsize, i + 7, buf, bufsize);
311 return buf;
314 /* PCI Vendor/Product name translaction. Taken from PCITool */
318 OOP_AttrBase HiddPCIDeviceAttrBase = 0;
319 OOP_Object * pciDriver = NULL;
320 OOP_Object * pciBus = NULL;
321 struct Library * OOPBase = NULL;
323 AROS_UFH3(void, Enumerator,
324 AROS_UFHA(struct Hook *, hook, A0),
325 AROS_UFHA(OOP_Object *, pciDevice, A2),
326 AROS_UFHA(APTR, message, A1))
328 AROS_USERFUNC_INIT
330 IPTR productid;
331 IPTR vendorid;
332 IPTR agpcap;
333 IPTR pciecap;
334 TEXT vendor[100] = {0};
335 TEXT product[100] = {0};
337 OOP_GetAttr(pciDevice, aHidd_PCIDevice_ProductID, &productid);
338 OOP_GetAttr(pciDevice, aHidd_PCIDevice_VendorID, &vendorid);
339 OOP_GetAttr(pciDevice, aHidd_PCIDevice_CapabilityAGP, (APTR)&agpcap);
340 OOP_GetAttr(pciDevice, aHidd_PCIDevice_CapabilityPCIE, (APTR)&pciecap);
341 pciids_GetVendorName(vendorid, vendor, 100);
342 pciids_GetDeviceName(vendorid, productid, product, 100);
344 printf("|Video card|0x%x:0x%x %s %s",
345 (unsigned)vendorid, (unsigned)productid, vendor, product);
346 if (agpcap) printf(" AGP");
347 if (pciecap) printf(" PCIe");
348 printf("|\n");
350 AROS_USERFUNC_EXIT
353 static void listvideocards()
355 OOPBase = OpenLibrary("oop.library", 0L);
356 if (!OOPBase) return;
358 HiddPCIDeviceAttrBase = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
360 if (!pciBus)
362 pciBus = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
363 if (!pciBus)
365 CloseLibrary(OOPBase);
366 return;
370 pciids_Open();
372 if (pciBus)
374 struct Hook FindHook = {
375 h_Entry: (IPTR (*)())Enumerator,
376 h_Data: NULL,
379 struct TagItem Requirements[] = {
380 { tHidd_PCI_Interface, 0x00 },
381 { tHidd_PCI_Class, 0x03 },
382 { tHidd_PCI_SubClass, 0x00 },
383 { TAG_DONE, 0UL }
386 struct pHidd_PCI_EnumDevices enummsg = {
387 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
388 callback: &FindHook,
389 requirements: (struct TagItem*)&Requirements,
390 }, *msg = &enummsg;
392 OOP_DoMethod(pciBus, (OOP_Msg)msg);
395 OOP_DisposeObject(pciBus);
396 CloseLibrary(OOPBase);
397 pciids_Close();
400 static void detectsystem()
402 printf("*System information*\n");
404 /* Detect CPU + Memory */
405 APTR ProcessorBase = OpenResource(PROCESSORNAME);
407 if (ProcessorBase)
409 ULONG processorcount;
410 ULONG i;
411 struct TagItem tags [] =
413 { GCIT_NumberOfProcessors, (IPTR)&processorcount },
414 { 0, (IPTR)NULL }
417 GetCPUInfo(tags);
419 printf("|Processor count|%d|\n", (int)processorcount);
421 for (i = 0; i < processorcount; i++)
423 UQUAD frequency = 0;
424 STRPTR modelstr = NULL;
426 struct TagItem tags [] =
428 { GCIT_SelectedProcessor, (IPTR)i },
429 { GCIT_ProcessorSpeed, (IPTR)&frequency },
430 { GCIT_ModelString, (IPTR)&modelstr },
431 { TAG_DONE, TAG_DONE }
434 GetCPUInfo(tags);
436 frequency /= 1000000;
438 printf("|Processor #%d|%s - %d Mhz|\n", (int)i, modelstr, (int)frequency);
442 printf("|Available memory|%dkB|\n", (int)(AvailMem(MEMF_ANY) / 1024));
444 /* Detect video card device */
445 listvideocards();
447 /* Detect screen properties */
449 struct Screen * screen = IntuitionBase->FirstScreen;
450 LONG sdepth = 0, swidth = 0, sheight = 0;
452 swidth = GetCyberMapAttr(screen->RastPort.BitMap, CYBRMATTR_WIDTH);
453 sheight = GetCyberMapAttr(screen->RastPort.BitMap, CYBRMATTR_HEIGHT);
454 sdepth = GetCyberMapAttr(screen->RastPort.BitMap, CYBRMATTR_DEPTH);
456 if (width > swidth) width = swidth;
457 if (height > sheight) height = sheight;
459 printf("|Screen information| %dx%dx%d|\n", (int)swidth, (int)sheight, (int)sdepth);
462 printf("\n\n");
465 static void textbenchmark(LONG optmode, BOOL optantialias, LONG optlen)
467 STRPTR modestr = "UNKNOWN";
468 STRPTR aastr = "UNKNOWN";
469 TEXT lenstr[10] = {0};
471 switch(optmode)
473 case(JAM1): modestr = "JAM1"; break;
474 case(JAM2): modestr = "JAM2"; break;
475 case(COMPLEMENT): modestr = "COMPLEMENT"; break;
477 mode = optmode;
479 if (optantialias)
480 aastr = "ANTIALIASED";
481 else
482 aastr = "NON-ANTIALIASED";
483 antialias = optantialias;
485 sprintf(lenstr, "LEN %d", (int)optlen);
486 linelen = optlen;
488 printf("|%s, %s, %s|", modestr, aastr, lenstr);
490 action_text();
493 static void textbenchmarkset()
495 printf("*Text benchmark %dx%d*\n", (int)width, (int)height);
496 printf("||Test||Blits/s||MB/s||\n");
497 textbenchmark(JAM1, FALSE, 100);
498 textbenchmark(JAM2, FALSE, 100);
499 textbenchmark(COMPLEMENT, FALSE, 100);
500 textbenchmark(JAM1, TRUE, 100);
501 textbenchmark(JAM2, TRUE, 100);
502 textbenchmark(COMPLEMENT, TRUE, 100);
503 textbenchmark(JAM1, FALSE, 5);
504 textbenchmark(JAM2, FALSE, 5);
505 textbenchmark(COMPLEMENT, FALSE, 5);
506 textbenchmark(JAM1, TRUE, 5);
507 textbenchmark(JAM2, TRUE, 5);
508 textbenchmark(COMPLEMENT, TRUE, 5);
509 printf("\n\n");
512 static void pixelarraybenchmark(LONG optpixfmt, LONG optfunction)
514 STRPTR functionstr = "UNKNOWN";
515 STRPTR pixfmtstr = "UNKNOWN";
516 LONG i;
518 switch(optfunction)
520 case(FUNCTION_WRITE): functionstr = "WritePixelAlpha"; break;
521 case(FUNCTION_READ): functionstr = "ReadPixelAlpha"; break;
522 case(FUNCTION_WRITE_ALPHA): functionstr = "WritePixelArrayAlpha"; break;
525 for(i = 0; pixfmt_table[i].name; i++)
527 if (pixfmt_table[i].id == optpixfmt)
529 pixfmtstr = pixfmt_table[i].name;
530 break;
534 pixfmt = optpixfmt;
535 function = optfunction;
537 printf("| %s %s|", functionstr, pixfmtstr);
539 action_pixelarray();
542 static void pixelarraybenchmarkset()
544 printf("*PixelArray benchmark %dx%d*\n", (int)width, (int)height);
545 printf("||Test||Blits/s||MB/s||\n");
546 pixelarraybenchmark(RECTFMT_RGB, FUNCTION_WRITE);
547 pixelarraybenchmark(RECTFMT_ARGB32, FUNCTION_WRITE);
548 pixelarraybenchmark(RECTFMT_RGBA, FUNCTION_WRITE);
549 pixelarraybenchmark(RECTFMT_RGB16PC,FUNCTION_WRITE);
550 pixelarraybenchmark(RECTFMT_LUT8, FUNCTION_WRITE);
551 pixelarraybenchmark(RECTFMT_RGB, FUNCTION_READ);
552 pixelarraybenchmark(RECTFMT_ARGB32, FUNCTION_READ);
553 pixelarraybenchmark(RECTFMT_RGBA, FUNCTION_READ);
554 pixelarraybenchmark(RECTFMT_RGB16PC,FUNCTION_READ);
555 pixelarraybenchmark(RECTFMT_ARGB32, FUNCTION_WRITE_ALPHA);
556 printf("\n\n");
559 int main(void)
561 detectsystem();
563 pixelarraybenchmarkset();
565 textbenchmarkset();
567 cleanup(NULL, 0);
569 return 0;