tweaked the animation rate
[mesa.git] / progs / demos / texdown.c
1 /* $Id: texdown.c,v 1.1 2000/01/28 16:25:44 brianp Exp $ */
2
3 /*
4 * Copyright (C) 1999 Brian Paul All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24
25 /*
26 * texdown
27 *
28 * Measure texture download speed.
29 * Use keyboard to change texture size, format, datatype, scale/bias,
30 * subimageload, etc.
31 *
32 * Brian Paul 28 January 2000
33 */
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <math.h>
39 #include <GL/glut.h>
40
41
42 static GLsizei MaxSize = 1024;
43 static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0;
44 static GLenum TexFormat = GL_RGBA, TexType = GL_UNSIGNED_BYTE;
45 static GLenum TexIntFormat = GL_RGBA;
46 static GLboolean ScaleAndBias = GL_FALSE;
47 static GLboolean SubImage = GL_FALSE;
48 static GLdouble DownloadRate = 0.0; /* texels/sec */
49
50 static GLuint Mode = 0;
51
52
53 static int
54 BytesPerTexel(GLenum format, GLenum type)
55 {
56 int b, c;
57
58 switch (type) {
59 case GL_UNSIGNED_BYTE:
60 b = 1;
61 break;
62 case GL_UNSIGNED_SHORT:
63 b = 2;
64 break;
65 default:
66 abort();
67 }
68
69 switch (format) {
70 case GL_RGB:
71 c = 3;
72 break;
73 case GL_RGBA:
74 c = 4;
75 break;
76 default:
77 abort();
78 }
79
80 return b * c;
81 }
82
83
84 static const char *
85 FormatStr(GLenum format)
86 {
87 switch (format) {
88 case GL_RGB:
89 return "GL_RGB";
90 case GL_RGBA:
91 return "GL_RGBA";
92 default:
93 return "";
94 }
95 }
96
97
98 static const char *
99 TypeStr(GLenum type)
100 {
101 switch (type) {
102 case GL_UNSIGNED_BYTE:
103 return "GLubyte";
104 case GL_UNSIGNED_SHORT:
105 return "GLushort";
106 default:
107 return "";
108 }
109 }
110
111
112 static void
113 MeasureDownloadRate(void)
114 {
115 const int w = TexWidth + 2 * TexBorder;
116 const int h = TexHeight + 2 * TexBorder;
117 const int bytes = w * h * BytesPerTexel(TexFormat, TexType);
118 GLubyte *texImage, *getImage;
119 GLdouble t0, t1, time;
120 int count;
121 int i;
122
123 texImage = (GLubyte *) malloc(bytes);
124 getImage = (GLubyte *) malloc(bytes);
125 if (!texImage || !getImage) {
126 DownloadRate = 0.0;
127 return;
128 }
129
130 for (i = 0; i < bytes; i++) {
131 texImage[i] = i & 0xff;
132 }
133
134 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
135 glPixelStorei(GL_PACK_ALIGNMENT, 1);
136
137 if (ScaleAndBias) {
138 glPixelTransferf(GL_RED_SCALE, 0.5);
139 glPixelTransferf(GL_GREEN_SCALE, 0.5);
140 glPixelTransferf(GL_BLUE_SCALE, 0.5);
141 glPixelTransferf(GL_RED_BIAS, 0.5);
142 glPixelTransferf(GL_GREEN_BIAS, 0.5);
143 glPixelTransferf(GL_BLUE_BIAS, 0.5);
144 }
145 else {
146 glPixelTransferf(GL_RED_SCALE, 1.0);
147 glPixelTransferf(GL_GREEN_SCALE, 1.0);
148 glPixelTransferf(GL_BLUE_SCALE, 1.0);
149 glPixelTransferf(GL_RED_BIAS, 0.0);
150 glPixelTransferf(GL_GREEN_BIAS, 0.0);
151 glPixelTransferf(GL_BLUE_BIAS, 0.0);
152 }
153
154 count = 0;
155 t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
156 do {
157 if (SubImage && count > 0) {
158 glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
159 TexFormat, TexType, texImage);
160 }
161 else {
162 glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat, w, h,
163 TexBorder, TexFormat, TexType, texImage);
164 }
165
166 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
167 time = t1 - t0;
168 count++;
169 } while (time < 3.0);
170
171 printf("w*h=%d count=%d time=%f\n", w*h, count, time);
172 DownloadRate = w * h * count / time;
173
174 #if 0
175 if (!ScaleAndBias) {
176 /* verify texture readback */
177 glGetTexImage(GL_TEXTURE_2D, 0, TexFormat, TexType, getImage);
178 for (i = 0; i < w * h; i++) {
179 if (texImage[i] != getImage[i]) {
180 printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
181 }
182 }
183 }
184 #endif
185
186 free(texImage);
187 free(getImage);
188
189 {
190 GLint err = glGetError();
191 if (err)
192 printf("GL error %d\n", err);
193 }
194 }
195
196
197 static void
198 PrintString(const char *s)
199 {
200 while (*s) {
201 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
202 s++;
203 }
204 }
205
206
207 static void
208 Display(void)
209 {
210 const int w = TexWidth + 2 * TexBorder;
211 const int h = TexHeight + 2 * TexBorder;
212 char s[1000];
213
214 glClear(GL_COLOR_BUFFER_BIT);
215
216 glRasterPos2i(10, 70);
217 sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder);
218 PrintString(s);
219
220 glRasterPos2i(10, 55);
221 sprintf(s, "Texture format[f]: %s Type[t]: %s IntFormat[i]: %s",
222 FormatStr(TexFormat), TypeStr(TexType), FormatStr(TexIntFormat));
223 PrintString(s);
224
225 glRasterPos2i(10, 40);
226 sprintf(s, "Pixel Scale&Bias[p]: %s TexSubImage[s]: %s",
227 ScaleAndBias ? "Yes" : "No",
228 SubImage ? "Yes" : "No");
229 PrintString(s);
230
231 if (Mode == 0) {
232 glRasterPos2i(200, 10);
233 sprintf(s, "...Measuring...");
234 PrintString(s);
235 glutSwapBuffers();
236 glutPostRedisplay();
237 Mode++;
238 }
239 else if (Mode == 1) {
240 MeasureDownloadRate();
241 glutPostRedisplay();
242 Mode++;
243 }
244 else {
245 /* show results */
246 glRasterPos2i(10, 10);
247 sprintf(s, "Download rate: %g Mtexels/second %g MB/second",
248 DownloadRate / 1000000.0,
249 DownloadRate * BytesPerTexel(TexFormat, TexType) / 1000000.0);
250 PrintString(s);
251 glutSwapBuffers();
252 }
253 }
254
255
256 static void
257 Reshape(int width, int height)
258 {
259 glViewport( 0, 0, width, height );
260 glMatrixMode( GL_PROJECTION );
261 glLoadIdentity();
262 glOrtho(0, width, 0, height, -1, 1);
263 glMatrixMode( GL_MODELVIEW );
264 glLoadIdentity();
265 }
266
267
268 static GLenum
269 NextFormat(GLenum format)
270 {
271 if (format == GL_RGB) {
272 return GL_RGBA;
273 }
274 else if (format == GL_RGBA) {
275 return GL_RGB;
276 }
277 else {
278 return GL_RGBA;
279 }
280 }
281
282
283 static GLenum
284 NextType(GLenum type)
285 {
286 if (type == GL_UNSIGNED_BYTE) {
287 return GL_UNSIGNED_SHORT;
288 }
289 else if (type == GL_UNSIGNED_SHORT) {
290 return GL_UNSIGNED_BYTE;
291 }
292 else {
293 return GL_UNSIGNED_SHORT;
294 }
295 }
296
297
298 static void
299 Key(unsigned char key, int x, int y)
300 {
301 (void) x;
302 (void) y;
303 switch (key) {
304 case ' ':
305 break;
306 case 'b':
307 /* toggle border */
308 TexBorder = 1 - TexBorder;
309 Mode = 0;
310 break;
311 case 'f':
312 /* change format */
313 TexFormat = NextFormat(TexFormat);
314 Mode = 0;
315 break;
316 case 'i':
317 /* change internal format */
318 TexIntFormat = NextFormat(TexIntFormat);
319 Mode = 0;
320 break;
321 case 'p':
322 /* toggle border */
323 ScaleAndBias = !ScaleAndBias;
324 Mode = 0;
325 break;
326 case 's':
327 SubImage = !SubImage;
328 Mode = 0;
329 break;
330 case 't':
331 /* change type */
332 TexType = NextType(TexType);
333 Mode = 0;
334 break;
335 case 27:
336 exit(0);
337 break;
338 }
339 glutPostRedisplay();
340 }
341
342
343 static void
344 SpecialKey(int key, int x, int y)
345 {
346 (void) x;
347 (void) y;
348 switch (key) {
349 case GLUT_KEY_UP:
350 if (TexHeight < MaxSize)
351 TexHeight *= 2;
352 break;
353 case GLUT_KEY_DOWN:
354 if (TexHeight > 1)
355 TexHeight /= 2;
356 break;
357 case GLUT_KEY_LEFT:
358 if (TexWidth > 1)
359 TexWidth /= 2;
360 break;
361 case GLUT_KEY_RIGHT:
362 if (TexWidth < MaxSize)
363 TexWidth *= 2;
364 break;
365 }
366 Mode = 0;
367 glutPostRedisplay();
368 }
369
370
371 static void
372 Init(void)
373 {
374 printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR));
375 printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION));
376 printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER));
377 }
378
379
380 int
381 main(int argc, char *argv[])
382 {
383 glutInit( &argc, argv );
384 glutInitWindowPosition( 0, 0 );
385 glutInitWindowSize( 600, 100 );
386 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
387 glutCreateWindow(argv[0]);
388 glutReshapeFunc( Reshape );
389 glutKeyboardFunc( Key );
390 glutSpecialFunc( SpecialKey );
391 glutDisplayFunc( Display );
392 Init();
393 glutMainLoop();
394 return 0;
395 }