1/* 2 * This program is under the GNU GPL. 3 * Use at your own risk. 4 * 5 * written by David Bucciarelli (tech.hmw@plus.it) 6 * Humanware s.r.l. 7 */ 8 9#include <stdlib.h> 10#include <stdio.h> 11#include <string.h> 12#include <math.h> 13#include "glut_wrap.h" 14 15typedef struct 16{ 17 char *name; 18 char *unit; 19 void (*init) (void); 20 int (*run) (int, int); 21 int type; 22 int numsize; 23 int size[10]; 24} 25benchmark; 26 27static int frontbuffer = 1; 28 29/***************************************************************************/ 30 31static void 32init_test01(void) 33{ 34 glMatrixMode(GL_PROJECTION); 35 glLoadIdentity(); 36 gluOrtho2D(-0.5, 639.5, -0.5, 479.5); 37 glMatrixMode(GL_MODELVIEW); 38 39 glShadeModel(GL_FLAT); 40 glDisable(GL_DEPTH_TEST); 41 42 glClearColor(0.0, 0.1, 1.0, 0.0); 43 glClear(GL_COLOR_BUFFER_BIT); 44 glColor3f(1.0, 0.0, 0.0); 45} 46 47static int 48test01(int size, int num) 49{ 50 int x, y; 51 52 glBegin(GL_POINTS); 53 for (y = 0; y < num; y++) 54 for (x = 0; x < 480; x++) 55 glVertex2i(x, x); 56 glEnd(); 57 58 return 480 * num; 59} 60 61/***************************************************************************/ 62 63static void 64init_test02(void) 65{ 66 glMatrixMode(GL_PROJECTION); 67 glLoadIdentity(); 68 gluOrtho2D(-0.5, 639.5, -0.5, 479.5); 69 glMatrixMode(GL_MODELVIEW); 70 71 glShadeModel(GL_SMOOTH); 72 glDisable(GL_DEPTH_TEST); 73 74 glClearColor(0.0, 0.1, 1.0, 0.0); 75 glClear(GL_COLOR_BUFFER_BIT); 76} 77 78static int 79test02(int size, int num) 80{ 81 int x, y; 82 83 glBegin(GL_LINES); 84 for (y = 0; y < num; y++) 85 for (x = 0; x < size; x++) { 86 glColor3f(0.0, 1.0, y / (float) num); 87 glVertex2i(0, size - 1); 88 glColor3f(1.0, 0.0, x / (float) size); 89 glVertex2i(x, x); 90 } 91 glEnd(); 92 93 return num * size; 94} 95 96/***************************************************************************/ 97 98static void 99init_test03(void) 100{ 101 glMatrixMode(GL_PROJECTION); 102 glLoadIdentity(); 103 glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0); 104 glMatrixMode(GL_MODELVIEW); 105 106 glShadeModel(GL_SMOOTH); 107 glEnable(GL_DEPTH_TEST); 108 109 glClearColor(0.0, 0.1, 1.0, 0.0); 110 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 111} 112 113static int 114test03(int size, int num) 115{ 116 int x, y, z; 117 118 glBegin(GL_TRIANGLES); 119 for (y = 0; y < num; y++) 120 for (x = 0; x < size; x += 5) { 121 z = num * size - (y * size + x); 122 glColor3f(0.0, 1.0, 0.0); 123 glVertex3i(0, x, z); 124 125 glColor3f(1.0, 0.0, x / (float) size); 126 glVertex3i(size - 1 - x, 0, z); 127 128 glColor3f(1.0, x / (float) size, 0.0); 129 glVertex3i(x, size - 1 - x, z); 130 } 131 glEnd(); 132 133 return size * num / 5; 134} 135 136/***************************************************************************/ 137 138static void 139init_test04(void) 140{ 141 int x, y; 142 GLubyte tex[128 * 128 * 3]; 143 GLenum gluerr; 144 145 glMatrixMode(GL_PROJECTION); 146 glLoadIdentity(); 147 glOrtho(-0.5, 639.5, -0.5, 479.5, 1.0, -1000.0 * 480.0); 148 149 glMatrixMode(GL_MODELVIEW); 150 151 glShadeModel(GL_SMOOTH); 152 glEnable(GL_DEPTH_TEST); 153 154 glEnable(GL_BLEND); 155 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 156 157 for (y = 0; y < 128; y++) 158 for (x = 0; x < 128; x++) { 159 tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0; 160 tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0; 161 tex[(x + y * 128) * 3 + 2] = x; 162 } 163 164 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 165 if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, 166 GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) { 167 fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); 168 exit(-1); 169 } 170 171 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 172 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 173 174 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 175 GL_LINEAR_MIPMAP_NEAREST); 176 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 177 178 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 179 glEnable(GL_TEXTURE_2D); 180 181 glClearColor(0.0, 0.1, 1.0, 0.0); 182 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 183} 184 185static int 186test04(int size, int num) 187{ 188 int x, y, z; 189 190 glBegin(GL_TRIANGLES); 191 for (y = 0; y < num; y++) 192 for (x = 0; x < size; x += 5) { 193 z = num * size - (y * size + x); 194 glTexCoord2f(1.0, 1.0); 195 glColor3f(1.0, 0.0, 0.0); 196 glVertex3i(0, x, z); 197 198 glTexCoord2f(0.0, 1.0); 199 glColor3f(0.0, 1.0, 0.0); 200 glVertex3i(size - 1 - x, 0, z); 201 202 glTexCoord2f(1.0, 0.0); 203 glColor3f(0.0, 0.0, 1.0); 204 glVertex3i(x, size - 1 - x, z); 205 } 206 glEnd(); 207 208 return num * size / 5; 209} 210 211/***************************************************************************/ 212 213static void 214init_test05(void) 215{ 216 int x, y; 217 GLubyte tex[128 * 128 * 3]; 218 GLenum gluerr; 219 220 glMatrixMode(GL_PROJECTION); 221 glLoadIdentity(); 222 glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0); 223 224 glMatrixMode(GL_MODELVIEW); 225 226 glShadeModel(GL_SMOOTH); 227 glEnable(GL_DEPTH_TEST); 228 229 glEnable(GL_BLEND); 230 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 231 232 for (y = 0; y < 128; y++) 233 for (x = 0; x < 128; x++) { 234 tex[(x + y * 128) * 3 + 0] = ((x % (128 / 4)) < (128 / 8)) ? 255 : 0; 235 tex[(x + y * 128) * 3 + 1] = ((y % (128 / 4)) < (128 / 8)) ? 255 : 0; 236 tex[(x + y * 128) * 3 + 2] = x; 237 } 238 239 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 240 if ((gluerr = gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 128, 128, GL_RGB, 241 GL_UNSIGNED_BYTE, (GLvoid *) (&tex[0])))) { 242 fprintf(stderr, "GLULib%s\n", (char *) gluErrorString(gluerr)); 243 exit(-1); 244 } 245 246 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 247 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 248 249 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 250 GL_LINEAR_MIPMAP_NEAREST); 251 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 252 253 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 254 glEnable(GL_TEXTURE_2D); 255 256 glDepthFunc(GL_ALWAYS); 257 258 glClearColor(0.0, 0.1, 1.0, 0.0); 259 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 260} 261 262static int 263test05(int size, int num) 264{ 265 int y; 266 float v0[3], v1[3], v2[3], v3[3]; 267 float cv0[3], cv1[3], cv2[3], cv3[3]; 268 float tv0[3], tv1[3], tv2[3], tv3[3]; 269 270 v0[0] = 320 - size / 2; 271 v0[1] = 240 - size / 2; 272 v0[2] = 0.0; 273 v1[0] = 320 + size / 2; 274 v1[1] = 240 - size / 2; 275 v1[2] = 0.0; 276 v2[0] = 320 - size / 2; 277 v2[1] = 240 + size / 2; 278 v2[2] = 0.0; 279 v3[0] = 320 + size / 2; 280 v3[1] = 240 + size / 2; 281 v3[2] = 0.0; 282 cv0[0] = 1.0; 283 cv0[1] = 0.0; 284 cv0[2] = 0.0; 285 cv1[0] = 1.0; 286 cv1[1] = 1.0; 287 cv1[2] = 0.0; 288 cv2[0] = 1.0; 289 cv2[1] = 0.0; 290 cv2[2] = 1.0; 291 cv3[0] = 1.0; 292 cv3[1] = 1.0; 293 cv3[2] = 1.0; 294 tv0[0] = 0.0; 295 tv0[1] = 0.0; 296 tv0[2] = 0.0; 297 tv1[0] = 1.0; 298 tv1[1] = 0.0; 299 tv1[2] = 0.0; 300 tv2[0] = 0.0; 301 tv2[1] = 1.0; 302 tv2[2] = 0.0; 303 tv3[0] = 1.0; 304 tv3[1] = 1.0; 305 tv3[2] = 0.0; 306 307 glBegin(GL_TRIANGLE_STRIP); 308 for (y = 0; y < num; y++) { 309 glColor3fv(cv0); 310 glTexCoord2fv(tv0); 311 glVertex3fv(v0); 312 313 glColor3fv(cv1); 314 glTexCoord2fv(tv1); 315 glVertex3fv(v1); 316 317 glColor3fv(cv2); 318 glTexCoord2fv(tv2); 319 glVertex3fv(v2); 320 321 glColor3fv(cv3); 322 glTexCoord2fv(tv3); 323 glVertex3fv(v3); 324 } 325 glEnd(); 326 327 return 4 * num - 2; 328} 329 330/***************************************************************************/ 331 332static void 333init_test06(void) 334{ 335 glMatrixMode(GL_PROJECTION); 336 glLoadIdentity(); 337 gluOrtho2D(-0.5, 639.5, -0.5, 479.5); 338 glMatrixMode(GL_MODELVIEW); 339 340 glShadeModel(GL_SMOOTH); 341 glEnable(GL_DEPTH_TEST); 342 343 glClearColor(0.0, 0.1, 1.0, 0.0); 344 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 345} 346 347static int 348test06(int size, int num) 349{ 350 int y; 351 352 for (y = 0; y < num; y++) { 353 glClearColor(y / (float) num, 0.1, 1.0, 0.0); 354 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 355 } 356 357 return num; 358} 359 360/***************************************************************************/ 361 362#define BMARKS_TIME 5.0 363 364#define NUM_BMARKS 6 365 366/* 554 ~= sqrt(640*480) */ 367 368static benchmark bmarks[NUM_BMARKS] = { 369 {"Simple Points", "Pnts", init_test01, test01, 0, 0, 370 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, 371 {"Smooth Lines", "Lins", init_test02, test02, 1, 5, 372 {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, 373 {"ZSmooth Triangles", "Tris", init_test03, test03, 1, 5, 374 {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, 375 {"ZSmooth Tex Blend Triangles", "Tris", init_test04, test04, 1, 5, 376 {480, 250, 100, 50, 25, 0, 0, 0, 0, 0}}, 377 {"ZSmooth Tex Blend TMesh Triangles", "Tris", init_test05, test05, 2, 8, 378 {400, 250, 100, 50, 25, 10, 5, 2, 0, 0}}, 379 {"Color/Depth Buffer Clears", "Clrs", init_test06, test06, 3, 0, 380 {554, 0, 0, 0, 0, 0, 0, 0, 0, 0}} 381}; 382 383/***************************************************************************/ 384 385static void 386dotest0param(benchmark * bmark) 387{ 388 float stime, etime, dtime, tottime, maxtime, mintime; 389 int num, numelem, calibnum, j; 390 391 glPushAttrib(GL_ALL_ATTRIB_BITS); 392 bmark->init(); 393 394 stime = glutGet(GLUT_ELAPSED_TIME); 395 396 dtime = 0.0; 397 calibnum = 0; 398 while (dtime < 2.0) { 399 bmark->run(0, 1); 400 glFinish(); 401 etime = glutGet(GLUT_ELAPSED_TIME); 402 dtime = (etime - stime) / 1000.0; 403 calibnum++; 404 } 405 glPopAttrib(); 406 407 fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n", 408 calibnum, dtime); 409 410 num = (int) ((BMARKS_TIME / dtime) * calibnum); 411 412 if (num < 1) 413 num = 1; 414 415 fprintf(stderr, "Selected number of benchmark iterations: %d\n", num); 416 417 mintime = HUGE_VAL; 418 maxtime = -HUGE_VAL; 419 420 for (tottime = 0.0, j = 0; j < 5; j++) { 421 glPushAttrib(GL_ALL_ATTRIB_BITS); 422 bmark->init(); 423 424 stime = glutGet(GLUT_ELAPSED_TIME); 425 numelem = bmark->run(0, num); 426 glFinish(); 427 etime = glutGet(GLUT_ELAPSED_TIME); 428 429 glPopAttrib(); 430 431 dtime = (etime - stime) / 1000.0; 432 tottime += dtime; 433 434 fprintf(stderr, "Elapsed time for run %d: %f\n", j, dtime); 435 436 if (dtime < mintime) 437 mintime = dtime; 438 if (dtime > maxtime) 439 maxtime = dtime; 440 } 441 442 tottime -= mintime + maxtime; 443 444 fprintf(stdout, "%s\n%f %s/sec", bmark->name, numelem / (tottime / 3.0), 445 bmark->unit); 446 447 if (bmark->type == 3) 448 fprintf(stdout, ", MPixel Fill/sec: %f\n\n", 449 (numelem * bmark->size[0] * (float) bmark->size[0]) / 450 (1000000.0 * tottime / 3.0)); 451 else 452 fprintf(stdout, "\n\n"); 453} 454 455/***************************************************************************/ 456 457static void 458dotest1param(benchmark * bmark) 459{ 460 float stime, etime, dtime, tottime, maxtime, mintime; 461 int num, numelem, calibnum, j, k; 462 463 fprintf(stdout, "%s\n", bmark->name); 464 465 for (j = 0; j < bmark->numsize; j++) { 466 fprintf(stderr, "Current size: %d\n", bmark->size[j]); 467 468 glPushAttrib(GL_ALL_ATTRIB_BITS); 469 bmark->init(); 470 471 stime = glutGet(GLUT_ELAPSED_TIME); 472 473 dtime = 0.0; 474 calibnum = 0; 475 while (dtime < 2.0) { 476 bmark->run(bmark->size[j], 1); 477 glFinish(); 478 etime = glutGet(GLUT_ELAPSED_TIME); 479 dtime = (etime - stime) / 1000.0; 480 calibnum++; 481 } 482 glPopAttrib(); 483 484 fprintf(stderr, "Elapsed time for the calibration test (%d): %f\n", 485 calibnum, dtime); 486 487 num = (int) ((BMARKS_TIME / dtime) * calibnum); 488 489 if (num < 1) 490 num = 1; 491 492 fprintf(stderr, "Selected number of benchmark iterations: %d\n", num); 493 494 mintime = HUGE_VAL; 495 maxtime = -HUGE_VAL; 496 497 for (numelem = 1, tottime = 0.0, k = 0; k < 5; k++) { 498 glPushAttrib(GL_ALL_ATTRIB_BITS); 499 bmark->init(); 500 501 stime = glutGet(GLUT_ELAPSED_TIME); 502 numelem = bmark->run(bmark->size[j], num); 503 glFinish(); 504 etime = glutGet(GLUT_ELAPSED_TIME); 505 506 glPopAttrib(); 507 508 dtime = (etime - stime) / 1000.0; 509 tottime += dtime; 510 511 fprintf(stderr, "Elapsed time for run %d: %f\n", k, dtime); 512 513 if (dtime < mintime) 514 mintime = dtime; 515 if (dtime > maxtime) 516 maxtime = dtime; 517 } 518 519 tottime -= mintime + maxtime; 520 521 fprintf(stdout, "SIZE=%03d => %f %s/sec", bmark->size[j], 522 numelem / (tottime / 3.0), bmark->unit); 523 if (bmark->type == 2) 524 fprintf(stdout, ", MPixel Fill/sec: %f\n", 525 (numelem * bmark->size[j] * bmark->size[j] / 2) / 526 (1000000.0 * tottime / 3.0)); 527 else 528 fprintf(stdout, "\n"); 529 } 530 531 fprintf(stdout, "\n\n"); 532} 533 534/***************************************************************************/ 535 536static void 537display(void) 538{ 539 int i; 540 541 if (frontbuffer) 542 glDrawBuffer(GL_FRONT); 543 else 544 glDrawBuffer(GL_BACK); 545 546 for (i = 0; i < NUM_BMARKS; i++) { 547 fprintf(stderr, "Benchmark: %d\n", i); 548 549 switch (bmarks[i].type) { 550 case 0: 551 case 3: 552 dotest0param(&bmarks[i]); 553 break; 554 case 1: 555 case 2: 556 dotest1param(&bmarks[i]); 557 break; 558 } 559 } 560 561 exit(0); 562} 563 564int 565main(int ac, char **av) 566{ 567 fprintf(stderr, "GLTest v1.0\nWritten by David Bucciarelli\n"); 568 569 if (ac == 2) 570 frontbuffer = 0; 571 572 glutInitWindowSize(640, 480); 573 glutInit(&ac, av); 574 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 575 glutCreateWindow("OpenGL/Mesa Performances"); 576 glutDisplayFunc(display); 577 glutMainLoop(); 578 579 return 0; 580} 581