2 * Test glReadPixels speed
7 * gcc readrate.c -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -o readrate
10 #define GL_GLEXT_PROTOTYPES
17 /* Hack, to test drawing instead of reading */
20 #define MAX_WIDTH 1280
21 #define MAX_HEIGHT 1024
25 static const GLint Widths
[] = {256, 512, 1024, 1280};
26 static const GLint Heights
[] = {4, 32, 256, 512, 768, 1024};
27 static int WidthIndex
= 1, HeightIndex
= 3;
28 static GLubyte
*Buffer
= NULL
;
29 static GLboolean Benchmark
= GL_TRUE
;
33 static GLuint PBObjects
[4];
35 static GLboolean HavePBO
= GL_FALSE
;
45 static struct format_type Formats
[] = {
46 { "GL_RGB, GLubyte", 3, GL_RGB
, GL_UNSIGNED_BYTE
},
47 { "GL_BGR, GLubyte", 3, GL_BGR
, GL_UNSIGNED_BYTE
},
48 { "GL_RGBA, GLubyte", 4, GL_RGBA
, GL_UNSIGNED_BYTE
},
49 { "GL_BGRA, GLubyte", 4, GL_BGRA
, GL_UNSIGNED_BYTE
},
50 { "GL_ABGR, GLubyte", 4, GL_ABGR_EXT
, GL_UNSIGNED_BYTE
},
51 { "GL_RGBA, GLuint_8_8_8_8", 4, GL_RGBA
, GL_UNSIGNED_INT_8_8_8_8
},
52 { "GL_BGRA, GLuint_8_8_8_8", 4, GL_BGRA_EXT
, GL_UNSIGNED_INT_8_8_8_8
},
53 { "GL_BGRA, GLuint_8_8_8_8_rev", 4, GL_BGRA_EXT
, GL_UNSIGNED_INT_8_8_8_8_REV
},
54 #ifdef GL_EXT_packed_depth_stencil
55 { "GL_DEPTH_STENCIL_EXT, GLuint24+8", 4, GL_DEPTH_STENCIL_EXT
, GL_UNSIGNED_INT_24_8_EXT
},
57 { "GL_DEPTH_COMPONENT, GLfloat", 4, GL_DEPTH_COMPONENT
, GL_FLOAT
},
58 { "GL_DEPTH_COMPONENT, GLuint", 4, GL_DEPTH_COMPONENT
, GL_UNSIGNED_INT
}
61 #define NUM_FORMATS (sizeof(Formats) / sizeof(struct format_type))
65 PrintString(const char *s
)
68 glutBitmapCharacter(GLUT_BITMAP_8_BY_13
, (int) *s
);
75 MeasureFormat(struct format_type
*fmt
, GLint width
, GLint height
, GLuint pbo
)
77 double t0
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
88 glWindowPos2iARB(0,0);
89 glDrawPixels(width
, height
,
90 fmt
->Format
, fmt
->Type
, Buffer
);
94 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT
, PBObjects
[j
% NUM_PBO
]);
95 glReadPixels(0, 0, width
, height
,
96 fmt
->Format
, fmt
->Type
, 0);
99 glReadPixels(0, 0, width
, height
,
100 fmt
->Format
, fmt
->Type
, Buffer
);
104 t1
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
106 GLdouble rate
= width
* height
/ (1024.0 * 1024.0) * j
/ (t1
- t0
);
108 printf("%-32s %.2f draws/sec %.2f MPixels/sec %.2f MBytes/sec\n",
109 fmt
->Name
, j
/ (t1
-t0
), rate
, rate
* fmt
->Bytes
);
111 printf("%-32s %.2f reads/sec %.2f MPixels/sec %.2f MBytes/sec\n",
112 fmt
->Name
, j
/ (t1
-t0
), rate
, rate
* fmt
->Bytes
);
118 /* check for error */
119 GLenum err
= glGetError();
121 printf("GL Error 0x%x for %s\n", err
, fmt
->Name
);
134 int width
= Widths
[WidthIndex
];
135 int height
= Heights
[HeightIndex
];
136 int y
= MAX_HEIGHT
- 50;
138 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
140 glWindowPos2iARB(10, y
);
141 sprintf(str
, "ReadPixels size: %d x %d", width
, height
);
145 glWindowPos2iARB(10, y
);
146 PrintString("Press up/down/left/right to change image size.");
149 glWindowPos2iARB(10, y
);
150 PrintString("Press 'b' to run benchmark test.");
154 glWindowPos2iARB(10, y
);
155 PrintString("Testing...");
163 printf("Draw size: Width=%d Height=%d\n", width
, height
);
165 printf("Read size: Width=%d Height=%d\n", width
, height
);
167 for (pbo
= 0; pbo
<= HavePBO
; pbo
++) {
168 printf("Pixel Buffer Object: %d\n", pbo
);
171 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT
, 0);
174 for (i
= 0; i
< NUM_FORMATS
; i
++) {
175 MeasureFormat(Formats
+ i
, width
, height
, pbo
);
179 Benchmark
= GL_FALSE
;
181 /* redraw window text */
189 Reshape(int width
, int height
)
191 glViewport(0, 0, width
, height
);
192 glMatrixMode(GL_PROJECTION
);
194 glOrtho(-1, 1, -1, 1, -1, 1);
195 glMatrixMode(GL_MODELVIEW
);
201 Key(unsigned char key
, int x
, int y
)
218 SpecialKey(int key
, int x
, int y
)
224 if (HeightIndex
+ 1 < NUM_WIDTHS
)
236 if (WidthIndex
+ 1 < NUM_HEIGHTS
)
247 Buffer
= malloc(MAX_WIDTH
* MAX_HEIGHT
* 4);
250 printf("glDrawPixels test report:\n");
252 printf("glReadPixels test report:\n");
254 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
255 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
257 if (glutExtensionSupported("GL_ARB_pixel_buffer_object")) {
260 glGenBuffersARB(NUM_PBO
, PBObjects
);
261 for (i
= 0; i
< NUM_PBO
; i
++) {
262 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT
, PBObjects
[i
]);
263 glBufferDataARB(GL_PIXEL_PACK_BUFFER_EXT
,
264 MAX_WIDTH
* MAX_HEIGHT
* 4, NULL
, GL_STREAM_READ
);
271 main(int argc
, char *argv
[])
273 glutInit(&argc
, argv
);
274 glutInitWindowPosition(0, 0);
275 glutInitWindowSize(MAX_WIDTH
, MAX_HEIGHT
);
276 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
| GLUT_STENCIL
);
277 glutCreateWindow(argv
[0]);
278 glutReshapeFunc(Reshape
);
279 glutKeyboardFunc(Key
);
280 glutSpecialFunc(SpecialKey
);
281 glutDisplayFunc(Draw
);