initial check-in
[mesa.git] / progs / demos / texdown.c
1 /* $Id: texdown.c,v 1.3 2000/03/29 18:02:52 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 GLboolean ScaleAndBias = GL_FALSE;
45 static GLboolean SubImage = GL_FALSE;
46 static GLdouble DownloadRate = 0.0; /* texels/sec */
47
48 static GLuint Mode = 0;
49
50
51 #define NUM_FORMATS 4
52 struct FormatRec {
53 GLenum Format;
54 GLenum Type;
55 GLenum IntFormat;
56 GLint TexelSize;
57 };
58
59
60 static const struct FormatRec FormatTable[NUM_FORMATS] = {
61 /* Format Type IntFormat TexelSize */
62 { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, 3 },
63 { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, 4 },
64 { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB, 4 },
65 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, 2 },
66 };
67 static GLint Format;
68
69
70 static int
71 BytesPerTexel(GLint format)
72 {
73 return FormatTable[format].TexelSize;
74 }
75
76
77 static const char *
78 FormatStr(GLenum format)
79 {
80 switch (format) {
81 case GL_RGB:
82 return "GL_RGB";
83 case GL_RGBA:
84 return "GL_RGBA";
85 default:
86 return "";
87 }
88 }
89
90
91 static const char *
92 TypeStr(GLenum type)
93 {
94 switch (type) {
95 case GL_UNSIGNED_BYTE:
96 return "GL_UNSIGNED_BYTE";
97 case GL_UNSIGNED_SHORT:
98 return "GL_UNSIGNED_SHORT";
99 case GL_UNSIGNED_SHORT_5_6_5:
100 return "GL_UNSIGNED_SHORT_5_6_5";
101 case GL_UNSIGNED_SHORT_5_6_5_REV:
102 return "GL_UNSIGNED_SHORT_5_6_5_REV";
103 default:
104 return "";
105 }
106 }
107
108
109 static void
110 MeasureDownloadRate(void)
111 {
112 const int w = TexWidth + 2 * TexBorder;
113 const int h = TexHeight + 2 * TexBorder;
114 const int bytes = w * h * BytesPerTexel(Format);
115 GLubyte *texImage, *getImage;
116 GLdouble t0, t1, time;
117 int count;
118 int i;
119
120 texImage = (GLubyte *) malloc(bytes);
121 getImage = (GLubyte *) malloc(bytes);
122 if (!texImage || !getImage) {
123 DownloadRate = 0.0;
124 return;
125 }
126
127 for (i = 0; i < bytes; i++) {
128 texImage[i] = i & 0xff;
129 }
130
131 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
132 glPixelStorei(GL_PACK_ALIGNMENT, 1);
133
134 if (ScaleAndBias) {
135 glPixelTransferf(GL_RED_SCALE, 0.5);
136 glPixelTransferf(GL_GREEN_SCALE, 0.5);
137 glPixelTransferf(GL_BLUE_SCALE, 0.5);
138 glPixelTransferf(GL_RED_BIAS, 0.5);
139 glPixelTransferf(GL_GREEN_BIAS, 0.5);
140 glPixelTransferf(GL_BLUE_BIAS, 0.5);
141 }
142 else {
143 glPixelTransferf(GL_RED_SCALE, 1.0);
144 glPixelTransferf(GL_GREEN_SCALE, 1.0);
145 glPixelTransferf(GL_BLUE_SCALE, 1.0);
146 glPixelTransferf(GL_RED_BIAS, 0.0);
147 glPixelTransferf(GL_GREEN_BIAS, 0.0);
148 glPixelTransferf(GL_BLUE_BIAS, 0.0);
149 }
150
151 count = 0;
152 t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
153 do {
154 if (SubImage && count > 0) {
155 glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
156 FormatTable[Format].Format,
157 FormatTable[Format].Type, texImage);
158 }
159 else {
160 glTexImage2D(GL_TEXTURE_2D, 0,
161 FormatTable[Format].IntFormat, w, h, TexBorder,
162 FormatTable[Format].Format,
163 FormatTable[Format].Type, texImage);
164 }
165
166 if (count == 0) {
167 /* draw a tiny polygon to force texture into texram */
168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
170 glEnable(GL_TEXTURE_2D);
171 glBegin(GL_TRIANGLES);
172 glTexCoord2f(0, 0); glVertex2f(1, 1);
173 glTexCoord2f(1, 0); glVertex2f(3, 1);
174 glTexCoord2f(0.5, 1); glVertex2f(2, 3);
175 glEnd();
176 glDisable(GL_TEXTURE_2D);
177 }
178
179 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
180 time = t1 - t0;
181 count++;
182 } while (time < 3.0);
183
184 printf("w*h=%d count=%d time=%f\n", w*h, count, time);
185 DownloadRate = w * h * count / time;
186
187 #if 0
188 if (!ScaleAndBias) {
189 /* verify texture readback */
190 glGetTexImage(GL_TEXTURE_2D, 0,
191 FormatTable[Format].Format,
192 FormatTable[Format].Type, getImage);
193 for (i = 0; i < w * h; i++) {
194 if (texImage[i] != getImage[i]) {
195 printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
196 }
197 }
198 }
199 #endif
200
201 free(texImage);
202 free(getImage);
203
204 {
205 GLint err = glGetError();
206 if (err)
207 printf("GL error %d\n", err);
208 }
209 }
210
211
212 static void
213 PrintString(const char *s)
214 {
215 while (*s) {
216 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
217 s++;
218 }
219 }
220
221
222 static void
223 Display(void)
224 {
225 const int w = TexWidth + 2 * TexBorder;
226 const int h = TexHeight + 2 * TexBorder;
227 char s[1000];
228
229 glClear(GL_COLOR_BUFFER_BIT);
230
231 glRasterPos2i(10, 80);
232 sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder);
233 PrintString(s);
234
235 glRasterPos2i(10, 65);
236 sprintf(s, "Format[f]: %s Type: %s IntFormat: %s",
237 FormatStr(FormatTable[Format].Format),
238 TypeStr( FormatTable[Format].Type),
239 FormatStr(FormatTable[Format].IntFormat));
240 PrintString(s);
241
242 glRasterPos2i(10, 50);
243 sprintf(s, "Pixel Scale&Bias[p]: %s TexSubImage[s]: %s",
244 ScaleAndBias ? "Yes" : "No",
245 SubImage ? "Yes" : "No");
246 PrintString(s);
247
248 if (Mode == 0) {
249 glRasterPos2i(200, 10);
250 sprintf(s, "...Measuring...");
251 PrintString(s);
252 glutSwapBuffers();
253 glutPostRedisplay();
254 Mode++;
255 }
256 else if (Mode == 1) {
257 MeasureDownloadRate();
258 glutPostRedisplay();
259 Mode++;
260 }
261 else {
262 /* show results */
263 glRasterPos2i(10, 10);
264 sprintf(s, "Download rate: %g Mtexels/second %g MB/second",
265 DownloadRate / 1000000.0,
266 DownloadRate * BytesPerTexel(Format) / 1000000.0);
267 PrintString(s);
268 {
269 GLint r, g, b, a, l, i;
270 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
271 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
272 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
273 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
274 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
275 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
276 sprintf(s, "TexelBits: R=%d G=%d B=%d A=%d L=%d I=%d", r, g, b, a, l, i);
277 glRasterPos2i(10, 25);
278 PrintString(s);
279 }
280
281 glutSwapBuffers();
282 }
283 }
284
285
286 static void
287 Reshape(int width, int height)
288 {
289 glViewport( 0, 0, width, height );
290 glMatrixMode( GL_PROJECTION );
291 glLoadIdentity();
292 glOrtho(0, width, 0, height, -1, 1);
293 glMatrixMode( GL_MODELVIEW );
294 glLoadIdentity();
295 }
296
297
298
299 static void
300 Key(unsigned char key, int x, int y)
301 {
302 (void) x;
303 (void) y;
304 switch (key) {
305 case ' ':
306 Mode = 0;
307 break;
308 case 'b':
309 /* toggle border */
310 TexBorder = 1 - TexBorder;
311 Mode = 0;
312 break;
313 case 'f':
314 /* change format */
315 Format = (Format + 1) % NUM_FORMATS;
316 Mode = 0;
317 break;
318 case 'p':
319 /* toggle border */
320 ScaleAndBias = !ScaleAndBias;
321 Mode = 0;
322 break;
323 case 's':
324 SubImage = !SubImage;
325 Mode = 0;
326 break;
327 case 27:
328 exit(0);
329 break;
330 }
331 glutPostRedisplay();
332 }
333
334
335 static void
336 SpecialKey(int key, int x, int y)
337 {
338 (void) x;
339 (void) y;
340 switch (key) {
341 case GLUT_KEY_UP:
342 if (TexHeight < MaxSize)
343 TexHeight *= 2;
344 break;
345 case GLUT_KEY_DOWN:
346 if (TexHeight > 1)
347 TexHeight /= 2;
348 break;
349 case GLUT_KEY_LEFT:
350 if (TexWidth > 1)
351 TexWidth /= 2;
352 break;
353 case GLUT_KEY_RIGHT:
354 if (TexWidth < MaxSize)
355 TexWidth *= 2;
356 break;
357 }
358 Mode = 0;
359 glutPostRedisplay();
360 }
361
362
363 static void
364 Init(void)
365 {
366 printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR));
367 printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION));
368 printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER));
369 }
370
371
372 int
373 main(int argc, char *argv[])
374 {
375 glutInit( &argc, argv );
376 glutInitWindowPosition( 0, 0 );
377 glutInitWindowSize( 600, 100 );
378 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
379 glutCreateWindow(argv[0]);
380 glutReshapeFunc( Reshape );
381 glutKeyboardFunc( Key );
382 glutSpecialFunc( SpecialKey );
383 glutDisplayFunc( Display );
384 Init();
385 glutMainLoop();
386 return 0;
387 }