blob: a381f3b65813ccda1d3c53e141d43bb2c32f13ef [file] [log] [blame]
Brian Paul215ff222000-01-28 16:25:44 +00001/* $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
42static GLsizei MaxSize = 1024;
43static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0;
44static GLenum TexFormat = GL_RGBA, TexType = GL_UNSIGNED_BYTE;
45static GLenum TexIntFormat = GL_RGBA;
46static GLboolean ScaleAndBias = GL_FALSE;
47static GLboolean SubImage = GL_FALSE;
48static GLdouble DownloadRate = 0.0; /* texels/sec */
49
50static GLuint Mode = 0;
51
52
53static int
54BytesPerTexel(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
84static const char *
85FormatStr(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
98static const char *
99TypeStr(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
112static void
113MeasureDownloadRate(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
197static void
198PrintString(const char *s)
199{
200 while (*s) {
201 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
202 s++;
203 }
204}
205
206
207static void
208Display(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
256static void
257Reshape(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
268static GLenum
269NextFormat(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
283static GLenum
284NextType(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
298static void
299Key(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
343static void
344SpecialKey(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
371static void
372Init(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
380int
381main(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}