Merge branch '7.8'
[mesa.git] / progs / tests / readrate.c
1 /*
2 * Test glReadPixels speed
3 * Brian Paul
4 * 9 April 2004
5 *
6 * Compile:
7 * gcc readrate.c -L/usr/X11R6/lib -lglut -lGLU -lGL -lX11 -o readrate
8 */
9
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <GL/glew.h>
15 #include <GL/glut.h>
16
17 /* Hack, to test drawing instead of reading */
18 #define DRAW 0
19
20 #define MAX_WIDTH 1280
21 #define MAX_HEIGHT 1024
22
23 #define NUM_WIDTHS 4
24 #define NUM_HEIGHTS 4
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;
30
31 #define NUM_PBO 2
32
33 static GLuint PBObjects[4];
34
35 static GLboolean HavePBO = GL_FALSE;
36
37
38 struct format_type {
39 const char *Name;
40 GLuint Bytes;
41 GLenum Format;
42 GLenum Type;
43 };
44
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 },
56 #endif
57 { "GL_DEPTH_COMPONENT, GLfloat", 4, GL_DEPTH_COMPONENT, GL_FLOAT },
58 { "GL_DEPTH_COMPONENT, GLuint", 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }
59 };
60
61 #define NUM_FORMATS (sizeof(Formats) / sizeof(struct format_type))
62
63
64 static void
65 PrintString(const char *s)
66 {
67 while (*s) {
68 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
69 s++;
70 }
71 }
72
73
74 static void
75 MeasureFormat(struct format_type *fmt, GLint width, GLint height, GLuint pbo)
76 {
77 double t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
78 double t1;
79 int j;
80
81 for (j = 0; ; j++) {
82
83 glBegin(GL_POINTS);
84 glVertex2f(1,1);
85 glEnd();
86
87 #if DRAW
88 glWindowPos2iARB(0,0);
89 glDrawPixels(width, height,
90 fmt->Format, fmt->Type, Buffer);
91 glFinish();
92 #else
93 if (pbo) {
94 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, PBObjects[j % NUM_PBO]);
95 glReadPixels(0, 0, width, height,
96 fmt->Format, fmt->Type, 0);
97 }
98 else {
99 glReadPixels(0, 0, width, height,
100 fmt->Format, fmt->Type, Buffer);
101 }
102 #endif
103
104 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
105 if (t1 - t0 > 2.0) {
106 GLdouble rate = width * height / (1024.0 * 1024.0) * j / (t1 - t0);
107 #if DRAW
108 printf("%-32s %.2f draws/sec %.2f MPixels/sec %.2f MBytes/sec\n",
109 fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes);
110 #else
111 printf("%-32s %.2f reads/sec %.2f MPixels/sec %.2f MBytes/sec\n",
112 fmt->Name, j / (t1-t0), rate, rate * fmt->Bytes);
113 #endif
114 break;
115 }
116
117 if (j == 0) {
118 /* check for error */
119 GLenum err = glGetError();
120 if (err) {
121 printf("GL Error 0x%x for %s\n", err, fmt->Name);
122 return;
123 }
124 }
125 }
126 }
127
128
129
130 static void
131 Draw(void)
132 {
133 char str[1000];
134 int width = Widths[WidthIndex];
135 int height = Heights[HeightIndex];
136 int y = MAX_HEIGHT - 50;
137
138 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
139
140 glWindowPos2iARB(10, y);
141 sprintf(str, "ReadPixels size: %d x %d", width, height);
142 PrintString(str);
143 y -= 14;
144
145 glWindowPos2iARB(10, y);
146 PrintString("Press up/down/left/right to change image size.");
147 y -= 14;
148
149 glWindowPos2iARB(10, y);
150 PrintString("Press 'b' to run benchmark test.");
151 y -= 14;
152
153 if (Benchmark) {
154 glWindowPos2iARB(10, y);
155 PrintString("Testing...");
156 }
157
158 glutSwapBuffers();
159
160 if (Benchmark) {
161 GLuint i, pbo;
162 #if DRAW
163 printf("Draw size: Width=%d Height=%d\n", width, height);
164 #else
165 printf("Read size: Width=%d Height=%d\n", width, height);
166 #endif
167 for (pbo = 0; pbo <= HavePBO; pbo++) {
168 printf("Pixel Buffer Object: %d\n", pbo);
169
170 if (pbo == 0) {
171 glBindBufferARB(GL_PIXEL_PACK_BUFFER_EXT, 0);
172 }
173
174 for (i = 0; i < NUM_FORMATS; i++) {
175 MeasureFormat(Formats + i, width, height, pbo);
176 }
177 }
178
179 Benchmark = GL_FALSE;
180
181 /* redraw window text */
182 glutPostRedisplay();
183 }
184
185 }
186
187
188 static void
189 Reshape(int width, int height)
190 {
191 glViewport(0, 0, width, height);
192 glMatrixMode(GL_PROJECTION);
193 glLoadIdentity();
194 glOrtho(-1, 1, -1, 1, -1, 1);
195 glMatrixMode(GL_MODELVIEW);
196 glLoadIdentity();
197 }
198
199
200 static void
201 Key(unsigned char key, int x, int y)
202 {
203 (void) x;
204 (void) y;
205 switch (key) {
206 case 'b':
207 Benchmark = 1;
208 break;
209 case 27:
210 exit(0);
211 break;
212 }
213 glutPostRedisplay();
214 }
215
216
217 static void
218 SpecialKey(int key, int x, int y)
219 {
220 (void) x;
221 (void) y;
222 switch (key) {
223 case GLUT_KEY_UP:
224 if (HeightIndex + 1 < NUM_WIDTHS)
225 HeightIndex++;
226 break;
227 case GLUT_KEY_DOWN:
228 if (HeightIndex > 0)
229 HeightIndex--;
230 break;
231 case GLUT_KEY_LEFT:
232 if (WidthIndex > 0)
233 WidthIndex--;
234 break;
235 case GLUT_KEY_RIGHT:
236 if (WidthIndex + 1 < NUM_HEIGHTS)
237 WidthIndex++;
238 break;
239 }
240 glutPostRedisplay();
241 }
242
243
244 static void
245 Init(void)
246 {
247 Buffer = malloc(MAX_WIDTH * MAX_HEIGHT * 4);
248 assert(Buffer);
249 #if DRAW
250 printf("glDrawPixels test report:\n");
251 #else
252 printf("glReadPixels test report:\n");
253 #endif
254 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
255 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
256
257 if (glutExtensionSupported("GL_ARB_pixel_buffer_object")) {
258 int i;
259 HavePBO = 1;
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);
265 }
266 }
267 }
268
269
270 int
271 main(int argc, char *argv[])
272 {
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 glewInit();
279 glutReshapeFunc(Reshape);
280 glutKeyboardFunc(Key);
281 glutSpecialFunc(SpecialKey);
282 glutDisplayFunc(Draw);
283 Init();
284 glutMainLoop();
285 return 0;
286 }