blob: 79525a0395e849778ec806c13e32fdc7c7274022 [file] [log] [blame]
Brian Paul215ff222000-01-28 16:25:44 +00001
2/*
3 * Copyright (C) 1999 Brian Paul All Rights Reserved.
Gareth Hughesdde2da62001-02-07 03:04:58 +00004 *
Brian Paul215ff222000-01-28 16:25:44 +00005 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
Gareth Hughesdde2da62001-02-07 03:04:58 +000011 *
Brian Paul215ff222000-01-28 16:25:44 +000012 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
Gareth Hughesdde2da62001-02-07 03:04:58 +000014 *
Brian Paul215ff222000-01-28 16:25:44 +000015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23
24/*
25 * texdown
26 *
27 * Measure texture download speed.
28 * Use keyboard to change texture size, format, datatype, scale/bias,
29 * subimageload, etc.
30 *
31 * Brian Paul 28 January 2000
32 */
33
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <math.h>
38#include <GL/glut.h>
39
40
41static GLsizei MaxSize = 1024;
42static GLsizei TexWidth = 256, TexHeight = 256, TexBorder = 0;
Brian Paul215ff222000-01-28 16:25:44 +000043static GLboolean ScaleAndBias = GL_FALSE;
44static GLboolean SubImage = GL_FALSE;
45static GLdouble DownloadRate = 0.0; /* texels/sec */
46
47static GLuint Mode = 0;
48
49
Brian Paul7d69e9e2000-03-29 15:47:48 +000050struct FormatRec {
51 GLenum Format;
52 GLenum Type;
53 GLenum IntFormat;
54 GLint TexelSize;
55};
56
57
Keith Whitwell46d50d92005-03-22 13:32:35 +000058static const struct FormatRec FormatTable[] = {
Brian Paul7d69e9e2000-03-29 15:47:48 +000059 /* Format Type IntFormat TexelSize */
Keith Whitwell46d50d92005-03-22 13:32:35 +000060 { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, 4 },
Brian Paul7d69e9e2000-03-29 15:47:48 +000061 { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, 3 },
62 { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, 4 },
63 { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGB, 4 },
64 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, 2 },
Keith Whitwell46d50d92005-03-22 13:32:35 +000065 { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, 1 },
66 { GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, GL_LUMINANCE_ALPHA, 2 },
67 { GL_ALPHA, GL_UNSIGNED_BYTE, GL_ALPHA, 1 },
Brian Paul7d69e9e2000-03-29 15:47:48 +000068};
69static GLint Format;
70
Keith Whitwell46d50d92005-03-22 13:32:35 +000071#define NUM_FORMATS (sizeof(FormatTable)/sizeof(FormatTable[0]))
Brian Paul7d69e9e2000-03-29 15:47:48 +000072
Brian Paul215ff222000-01-28 16:25:44 +000073static int
Brian Paul7d69e9e2000-03-29 15:47:48 +000074BytesPerTexel(GLint format)
Brian Paul215ff222000-01-28 16:25:44 +000075{
Brian Paul7d69e9e2000-03-29 15:47:48 +000076 return FormatTable[format].TexelSize;
Brian Paul215ff222000-01-28 16:25:44 +000077}
78
79
80static const char *
81FormatStr(GLenum format)
82{
83 switch (format) {
84 case GL_RGB:
85 return "GL_RGB";
86 case GL_RGBA:
87 return "GL_RGBA";
Keith Whitwell46d50d92005-03-22 13:32:35 +000088 case GL_BGRA:
89 return "GL_BGRA";
90 case GL_LUMINANCE:
91 return "GL_LUMINANCE";
92 case GL_LUMINANCE_ALPHA:
93 return "GL_LUMINANCE_ALPHA";
94 case GL_ALPHA:
95 return "GL_ALPHA";
Brian Paul215ff222000-01-28 16:25:44 +000096 default:
97 return "";
98 }
99}
100
101
102static const char *
103TypeStr(GLenum type)
104{
105 switch (type) {
106 case GL_UNSIGNED_BYTE:
Brian Paul7d69e9e2000-03-29 15:47:48 +0000107 return "GL_UNSIGNED_BYTE";
Brian Paul215ff222000-01-28 16:25:44 +0000108 case GL_UNSIGNED_SHORT:
Brian Paul7d69e9e2000-03-29 15:47:48 +0000109 return "GL_UNSIGNED_SHORT";
110 case GL_UNSIGNED_SHORT_5_6_5:
111 return "GL_UNSIGNED_SHORT_5_6_5";
112 case GL_UNSIGNED_SHORT_5_6_5_REV:
113 return "GL_UNSIGNED_SHORT_5_6_5_REV";
Brian Paul215ff222000-01-28 16:25:44 +0000114 default:
115 return "";
116 }
117}
118
119
120static void
121MeasureDownloadRate(void)
122{
123 const int w = TexWidth + 2 * TexBorder;
124 const int h = TexHeight + 2 * TexBorder;
Brian Paul7d69e9e2000-03-29 15:47:48 +0000125 const int bytes = w * h * BytesPerTexel(Format);
Brian Paul215ff222000-01-28 16:25:44 +0000126 GLubyte *texImage, *getImage;
127 GLdouble t0, t1, time;
128 int count;
129 int i;
130
131 texImage = (GLubyte *) malloc(bytes);
132 getImage = (GLubyte *) malloc(bytes);
133 if (!texImage || !getImage) {
134 DownloadRate = 0.0;
135 return;
136 }
137
138 for (i = 0; i < bytes; i++) {
139 texImage[i] = i & 0xff;
140 }
141
142 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
143 glPixelStorei(GL_PACK_ALIGNMENT, 1);
144
145 if (ScaleAndBias) {
146 glPixelTransferf(GL_RED_SCALE, 0.5);
147 glPixelTransferf(GL_GREEN_SCALE, 0.5);
148 glPixelTransferf(GL_BLUE_SCALE, 0.5);
149 glPixelTransferf(GL_RED_BIAS, 0.5);
150 glPixelTransferf(GL_GREEN_BIAS, 0.5);
151 glPixelTransferf(GL_BLUE_BIAS, 0.5);
152 }
153 else {
154 glPixelTransferf(GL_RED_SCALE, 1.0);
155 glPixelTransferf(GL_GREEN_SCALE, 1.0);
156 glPixelTransferf(GL_BLUE_SCALE, 1.0);
157 glPixelTransferf(GL_RED_BIAS, 0.0);
158 glPixelTransferf(GL_GREEN_BIAS, 0.0);
159 glPixelTransferf(GL_BLUE_BIAS, 0.0);
160 }
161
Gareth Hughesdde2da62001-02-07 03:04:58 +0000162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
164 glEnable(GL_TEXTURE_2D);
165
Brian Paul215ff222000-01-28 16:25:44 +0000166 count = 0;
167 t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
168 do {
169 if (SubImage && count > 0) {
170 glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000171 FormatTable[Format].Format,
172 FormatTable[Format].Type, texImage);
Brian Paul215ff222000-01-28 16:25:44 +0000173 }
174 else {
Brian Paul7d69e9e2000-03-29 15:47:48 +0000175 glTexImage2D(GL_TEXTURE_2D, 0,
176 FormatTable[Format].IntFormat, w, h, TexBorder,
177 FormatTable[Format].Format,
178 FormatTable[Format].Type, texImage);
179 }
180
Gareth Hughesdde2da62001-02-07 03:04:58 +0000181 /* draw a tiny polygon to force texture into texram */
182 glBegin(GL_TRIANGLES);
183 glTexCoord2f(0, 0); glVertex2f(1, 1);
184 glTexCoord2f(1, 0); glVertex2f(3, 1);
185 glTexCoord2f(0.5, 1); glVertex2f(2, 3);
186 glEnd();
Brian Paul215ff222000-01-28 16:25:44 +0000187
188 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
189 time = t1 - t0;
190 count++;
191 } while (time < 3.0);
192
Gareth Hughesdde2da62001-02-07 03:04:58 +0000193 glDisable(GL_TEXTURE_2D);
194
Brian Paul215ff222000-01-28 16:25:44 +0000195 printf("w*h=%d count=%d time=%f\n", w*h, count, time);
196 DownloadRate = w * h * count / time;
197
198#if 0
199 if (!ScaleAndBias) {
200 /* verify texture readback */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000201 glGetTexImage(GL_TEXTURE_2D, 0,
202 FormatTable[Format].Format,
203 FormatTable[Format].Type, getImage);
Brian Paul215ff222000-01-28 16:25:44 +0000204 for (i = 0; i < w * h; i++) {
205 if (texImage[i] != getImage[i]) {
206 printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
207 }
208 }
209 }
210#endif
211
212 free(texImage);
213 free(getImage);
214
215 {
216 GLint err = glGetError();
217 if (err)
218 printf("GL error %d\n", err);
219 }
220}
221
222
223static void
224PrintString(const char *s)
225{
226 while (*s) {
227 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
228 s++;
229 }
230}
231
232
233static void
234Display(void)
235{
236 const int w = TexWidth + 2 * TexBorder;
237 const int h = TexHeight + 2 * TexBorder;
238 char s[1000];
239
240 glClear(GL_COLOR_BUFFER_BIT);
241
Brian Paul7d69e9e2000-03-29 15:47:48 +0000242 glRasterPos2i(10, 80);
Brian Paul215ff222000-01-28 16:25:44 +0000243 sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder);
244 PrintString(s);
245
Brian Paul7d69e9e2000-03-29 15:47:48 +0000246 glRasterPos2i(10, 65);
247 sprintf(s, "Format[f]: %s Type: %s IntFormat: %s",
248 FormatStr(FormatTable[Format].Format),
249 TypeStr( FormatTable[Format].Type),
250 FormatStr(FormatTable[Format].IntFormat));
Brian Paul215ff222000-01-28 16:25:44 +0000251 PrintString(s);
252
Brian Paul7d69e9e2000-03-29 15:47:48 +0000253 glRasterPos2i(10, 50);
Brian Paul215ff222000-01-28 16:25:44 +0000254 sprintf(s, "Pixel Scale&Bias[p]: %s TexSubImage[s]: %s",
255 ScaleAndBias ? "Yes" : "No",
256 SubImage ? "Yes" : "No");
257 PrintString(s);
258
259 if (Mode == 0) {
260 glRasterPos2i(200, 10);
261 sprintf(s, "...Measuring...");
262 PrintString(s);
263 glutSwapBuffers();
264 glutPostRedisplay();
265 Mode++;
266 }
267 else if (Mode == 1) {
268 MeasureDownloadRate();
269 glutPostRedisplay();
270 Mode++;
271 }
272 else {
273 /* show results */
274 glRasterPos2i(10, 10);
275 sprintf(s, "Download rate: %g Mtexels/second %g MB/second",
276 DownloadRate / 1000000.0,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000277 DownloadRate * BytesPerTexel(Format) / 1000000.0);
Brian Paul215ff222000-01-28 16:25:44 +0000278 PrintString(s);
Brian Paul7d69e9e2000-03-29 15:47:48 +0000279 {
280 GLint r, g, b, a, l, i;
281 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
282 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
283 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
284 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
285 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
286 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
287 sprintf(s, "TexelBits: R=%d G=%d B=%d A=%d L=%d I=%d", r, g, b, a, l, i);
288 glRasterPos2i(10, 25);
289 PrintString(s);
290 }
291
Brian Paul215ff222000-01-28 16:25:44 +0000292 glutSwapBuffers();
293 }
294}
295
296
297static void
298Reshape(int width, int height)
299{
300 glViewport( 0, 0, width, height );
301 glMatrixMode( GL_PROJECTION );
302 glLoadIdentity();
303 glOrtho(0, width, 0, height, -1, 1);
304 glMatrixMode( GL_MODELVIEW );
305 glLoadIdentity();
306}
307
308
Brian Paul215ff222000-01-28 16:25:44 +0000309
310static void
311Key(unsigned char key, int x, int y)
312{
313 (void) x;
314 (void) y;
315 switch (key) {
316 case ' ':
Brian Paul8fd9fcb2000-03-29 18:02:52 +0000317 Mode = 0;
Brian Paul215ff222000-01-28 16:25:44 +0000318 break;
319 case 'b':
320 /* toggle border */
321 TexBorder = 1 - TexBorder;
322 Mode = 0;
323 break;
324 case 'f':
325 /* change format */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000326 Format = (Format + 1) % NUM_FORMATS;
Brian Paul215ff222000-01-28 16:25:44 +0000327 Mode = 0;
328 break;
Keith Whitwell46d50d92005-03-22 13:32:35 +0000329 case 'F':
330 /* change format */
331 Format = (Format - 1) % NUM_FORMATS;
332 Mode = 0;
333 break;
Brian Paul215ff222000-01-28 16:25:44 +0000334 case 'p':
335 /* toggle border */
336 ScaleAndBias = !ScaleAndBias;
337 Mode = 0;
338 break;
339 case 's':
340 SubImage = !SubImage;
341 Mode = 0;
342 break;
Brian Paul215ff222000-01-28 16:25:44 +0000343 case 27:
344 exit(0);
345 break;
346 }
347 glutPostRedisplay();
348}
349
350
351static void
352SpecialKey(int key, int x, int y)
353{
354 (void) x;
355 (void) y;
356 switch (key) {
357 case GLUT_KEY_UP:
358 if (TexHeight < MaxSize)
359 TexHeight *= 2;
360 break;
361 case GLUT_KEY_DOWN:
362 if (TexHeight > 1)
363 TexHeight /= 2;
364 break;
365 case GLUT_KEY_LEFT:
366 if (TexWidth > 1)
367 TexWidth /= 2;
368 break;
369 case GLUT_KEY_RIGHT:
370 if (TexWidth < MaxSize)
371 TexWidth *= 2;
372 break;
373 }
374 Mode = 0;
375 glutPostRedisplay();
376}
377
378
379static void
380Init(void)
381{
382 printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR));
383 printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION));
384 printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER));
385}
386
387
388int
389main(int argc, char *argv[])
390{
391 glutInit( &argc, argv );
392 glutInitWindowPosition( 0, 0 );
393 glutInitWindowSize( 600, 100 );
394 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
395 glutCreateWindow(argv[0]);
396 glutReshapeFunc( Reshape );
397 glutKeyboardFunc( Key );
398 glutSpecialFunc( SpecialKey );
399 glutDisplayFunc( Display );
400 Init();
401 glutMainLoop();
402 return 0;
403}