132001f49Smrg/* 232001f49Smrg * Measure glCopyPixels speed 332001f49Smrg * 432001f49Smrg * Brian Paul 532001f49Smrg * 26 Jan 2006 632001f49Smrg */ 732001f49Smrg 832001f49Smrg#include <stdio.h> 932001f49Smrg#include <stdlib.h> 1032001f49Smrg#include <string.h> 1132001f49Smrg#include <math.h> 1232001f49Smrg#include <GL/glew.h> 1332001f49Smrg#include "glut_wrap.h" 1432001f49Smrg 1532001f49Smrgstatic GLint WinWidth = 1000, WinHeight = 800; 1632001f49Smrgstatic GLint ImgWidth, ImgHeight; 1732001f49Smrg 1832001f49Smrgstatic GLenum Buffer = GL_FRONT; 1932001f49Smrgstatic GLenum AlphaTest = GL_FALSE; 2032001f49Smrgstatic GLboolean UseBlit = GL_FALSE; 2132001f49Smrg 2232001f49Smrg 2332001f49Smrg/** 2432001f49Smrg * draw teapot in lower-left corner of window 2532001f49Smrg */ 2632001f49Smrgstatic void 2732001f49SmrgDrawTestImage(void) 2832001f49Smrg{ 2932001f49Smrg GLfloat ar; 3032001f49Smrg 3132001f49Smrg ImgWidth = WinWidth / 3; 3232001f49Smrg ImgHeight = WinHeight / 3; 3332001f49Smrg 3432001f49Smrg glViewport(0, 0, ImgWidth, ImgHeight); 3532001f49Smrg glScissor(0, 0, ImgWidth, ImgHeight); 3632001f49Smrg glEnable(GL_SCISSOR_TEST); 3732001f49Smrg 3832001f49Smrg glClearColor(0.5, 0.5, 0.5, 0.0); 3932001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4032001f49Smrg 4132001f49Smrg ar = (float) WinWidth / WinHeight; 4232001f49Smrg 4332001f49Smrg glMatrixMode(GL_PROJECTION); 4432001f49Smrg glLoadIdentity(); 4532001f49Smrg glFrustum(-ar, ar, -1.0, 1.0, 5.0, 25.0); 4632001f49Smrg glMatrixMode(GL_MODELVIEW); 4732001f49Smrg 4832001f49Smrg glEnable(GL_LIGHTING); 4932001f49Smrg glEnable(GL_LIGHT0); 5032001f49Smrg glEnable(GL_DEPTH_TEST); 5132001f49Smrg glFrontFace(GL_CW); 5232001f49Smrg glPushMatrix(); 5332001f49Smrg glRotatef(45, 1, 0, 0); 5432001f49Smrg glutSolidTeapot(2.0); 5532001f49Smrg glPopMatrix(); 5632001f49Smrg glFrontFace(GL_CCW); 5732001f49Smrg glDisable(GL_DEPTH_TEST); 5832001f49Smrg glDisable(GL_LIGHTING); 5932001f49Smrg 6032001f49Smrg glDisable(GL_SCISSOR_TEST); 6132001f49Smrg 6232001f49Smrg glViewport(0, 0, WinWidth, WinHeight); 6332001f49Smrg glFinish(); 6432001f49Smrg} 6532001f49Smrg 6632001f49Smrg 6732001f49Smrgstatic int 6832001f49SmrgRand(int max) 6932001f49Smrg{ 7032001f49Smrg return ((int) rand()) % max; 7132001f49Smrg} 7232001f49Smrg 7332001f49Smrg 7432001f49Smrgstatic void 7532001f49SmrgBlitOne(void) 7632001f49Smrg{ 7732001f49Smrg int x, y; 7832001f49Smrg 7932001f49Smrg do { 8032001f49Smrg x = Rand(WinWidth); 8132001f49Smrg y = Rand(WinHeight); 8232001f49Smrg } while (x <= ImgWidth && y <= ImgHeight); 8332001f49Smrg 8432001f49Smrg#ifdef GL_EXT_framebuffer_blit 8532001f49Smrg if (UseBlit) 8632001f49Smrg { 8732001f49Smrg glBlitFramebufferEXT(0, 0, ImgWidth, ImgHeight, 8832001f49Smrg x, y, x + ImgWidth, y + ImgHeight, 8932001f49Smrg GL_COLOR_BUFFER_BIT, GL_LINEAR); 9032001f49Smrg } 9132001f49Smrg else 9232001f49Smrg#endif 9332001f49Smrg { 9432001f49Smrg glWindowPos2iARB(x, y); 9532001f49Smrg glCopyPixels(0, 0, ImgWidth, ImgHeight, GL_COLOR); 9632001f49Smrg } 9732001f49Smrg} 9832001f49Smrg 9932001f49Smrg 10032001f49Smrg/** 10132001f49Smrg * Measure glCopyPixels rate 10232001f49Smrg */ 10332001f49Smrgstatic void 10432001f49SmrgRunTest(void) 10532001f49Smrg{ 10632001f49Smrg double t1, t0 = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 10732001f49Smrg int iters = 0; 10832001f49Smrg float copyRate, mbRate; 10932001f49Smrg int r, g, b, a, bpp; 11032001f49Smrg 11132001f49Smrg if (AlphaTest) { 11232001f49Smrg glEnable(GL_ALPHA_TEST); 11332001f49Smrg glAlphaFunc(GL_GREATER, 0.0); 11432001f49Smrg } 11532001f49Smrg 11632001f49Smrg glGetIntegerv(GL_RED_BITS, &r); 11732001f49Smrg glGetIntegerv(GL_GREEN_BITS, &g); 11832001f49Smrg glGetIntegerv(GL_BLUE_BITS, &b); 11932001f49Smrg glGetIntegerv(GL_ALPHA_BITS, &a); 12032001f49Smrg bpp = (r + g + b + a) / 8; 12132001f49Smrg 12232001f49Smrg do { 12332001f49Smrg BlitOne(); 12432001f49Smrg 12532001f49Smrg if (Buffer == GL_FRONT) 12632001f49Smrg glFinish(); /* XXX to view progress */ 12732001f49Smrg 12832001f49Smrg iters++; 12932001f49Smrg 13032001f49Smrg t1 = glutGet(GLUT_ELAPSED_TIME) / 1000.0; 13132001f49Smrg } while (t1 - t0 < 5.0); 13232001f49Smrg 13332001f49Smrg glDisable(GL_ALPHA_TEST); 13432001f49Smrg 13532001f49Smrg copyRate = iters / (t1 - t0); 13632001f49Smrg mbRate = ImgWidth * ImgHeight * bpp * copyRate / (1024 * 1024); 13732001f49Smrg 13832001f49Smrg printf("Image size: %d x %d, %d Bpp\n", ImgWidth, ImgHeight, bpp); 13932001f49Smrg printf("%d copies in %.2f = %.2f copies/sec, %.2f MB/s\n", 14032001f49Smrg iters, t1-t0, copyRate, mbRate); 14132001f49Smrg} 14232001f49Smrg 14332001f49Smrg 14432001f49Smrgstatic void 14532001f49SmrgDraw(void) 14632001f49Smrg{ 14732001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 14832001f49Smrg glClearColor(0.2, 0.2, 0.8, 0); 14932001f49Smrg glReadBuffer(Buffer); 15032001f49Smrg glDrawBuffer(Buffer); 15132001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 15232001f49Smrg 15332001f49Smrg DrawTestImage(); 15432001f49Smrg 15532001f49Smrg RunTest(); 15632001f49Smrg 15732001f49Smrg if (Buffer == GL_FRONT) 15832001f49Smrg glFinish(); 15932001f49Smrg else 16032001f49Smrg glutSwapBuffers(); 16132001f49Smrg 16232001f49Smrg#if 1 16332001f49Smrg printf("exiting\n"); 16432001f49Smrg exit(0); 16532001f49Smrg#endif 16632001f49Smrg} 16732001f49Smrg 16832001f49Smrg 16932001f49Smrgstatic void 17032001f49SmrgReshape(int width, int height) 17132001f49Smrg{ 17232001f49Smrg glViewport(0, 0, width, height); 17332001f49Smrg glMatrixMode(GL_PROJECTION); 17432001f49Smrg glLoadIdentity(); 17532001f49Smrg glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 17632001f49Smrg glMatrixMode(GL_MODELVIEW); 17732001f49Smrg glLoadIdentity(); 17832001f49Smrg glTranslatef(0.0, 0.0, -15.0); 17932001f49Smrg} 18032001f49Smrg 18132001f49Smrg 18232001f49Smrgstatic void 18332001f49SmrgKey(unsigned char key, int x, int y) 18432001f49Smrg{ 18532001f49Smrg (void) x; 18632001f49Smrg (void) y; 18732001f49Smrg switch (key) { 18832001f49Smrg case 'b': 18932001f49Smrg BlitOne(); 19032001f49Smrg break; 19132001f49Smrg case 27: 19232001f49Smrg exit(0); 19332001f49Smrg break; 19432001f49Smrg } 19532001f49Smrg glutPostRedisplay(); 19632001f49Smrg} 19732001f49Smrg 19832001f49Smrg 19932001f49Smrgstatic void 20032001f49SmrgSpecialKey(int key, int x, int y) 20132001f49Smrg{ 20232001f49Smrg (void) x; 20332001f49Smrg (void) y; 20432001f49Smrg switch (key) { 20532001f49Smrg case GLUT_KEY_UP: 20632001f49Smrg break; 20732001f49Smrg case GLUT_KEY_DOWN: 20832001f49Smrg break; 20932001f49Smrg case GLUT_KEY_LEFT: 21032001f49Smrg break; 21132001f49Smrg case GLUT_KEY_RIGHT: 21232001f49Smrg break; 21332001f49Smrg } 21432001f49Smrg glutPostRedisplay(); 21532001f49Smrg} 21632001f49Smrg 21732001f49Smrg 21832001f49Smrgstatic void 21932001f49SmrgParseArgs(int argc, char *argv[]) 22032001f49Smrg{ 22132001f49Smrg int i; 22232001f49Smrg for (i = 1; i < argc; i++) { 22332001f49Smrg if (strcmp(argv[i], "-back") == 0) 22432001f49Smrg Buffer = GL_BACK; 22532001f49Smrg else if (strcmp(argv[i], "-alpha") == 0) 22632001f49Smrg AlphaTest = GL_TRUE; 22732001f49Smrg else if (strcmp(argv[i], "-blit") == 0) 22832001f49Smrg UseBlit = GL_TRUE; 22932001f49Smrg } 23032001f49Smrg} 23132001f49Smrg 23232001f49Smrg 23332001f49Smrgstatic void 23432001f49SmrgInit(void) 23532001f49Smrg{ 23632001f49Smrg if (glutExtensionSupported("GL_EXT_framebuffer_blit")) { 23732001f49Smrg } 23832001f49Smrg else if (UseBlit) { 23932001f49Smrg printf("Warning: GL_EXT_framebuffer_blit not supported.\n"); 24032001f49Smrg UseBlit = GL_FALSE; 24132001f49Smrg } 24232001f49Smrg} 24332001f49Smrg 24432001f49Smrg 24532001f49Smrgint 24632001f49Smrgmain(int argc, char *argv[]) 24732001f49Smrg{ 24832001f49Smrg GLint mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH; 24932001f49Smrg glutInit(&argc, argv); 25032001f49Smrg 25132001f49Smrg ParseArgs(argc, argv); 25232001f49Smrg if (AlphaTest) 25332001f49Smrg mode |= GLUT_ALPHA; 25432001f49Smrg 25532001f49Smrg glutInitWindowPosition(0, 0); 25632001f49Smrg glutInitWindowSize(WinWidth, WinHeight); 25732001f49Smrg glutInitDisplayMode(mode); 25832001f49Smrg glutCreateWindow(argv[0]); 25932001f49Smrg glewInit(); 26032001f49Smrg glutReshapeFunc(Reshape); 26132001f49Smrg glutKeyboardFunc(Key); 26232001f49Smrg glutSpecialFunc(SpecialKey); 26332001f49Smrg glutDisplayFunc(Draw); 26432001f49Smrg 26532001f49Smrg printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); 26632001f49Smrg printf("Draw Buffer: %s\n", (Buffer == GL_BACK) ? "Back" : "Front"); 26732001f49Smrg Init(); 26832001f49Smrg 26932001f49Smrg printf("Mode: %s\n", (UseBlit ? "glBlitFramebuffer" : "glCopyPixels")); 27032001f49Smrg printf("Alpha Test: %s\n", (AlphaTest ? "yes" : "no")); 27132001f49Smrg 27232001f49Smrg glutMainLoop(); 27332001f49Smrg return 0; 27432001f49Smrg} 275