blob: d56884f379af7b6bbc83c08d15347a934cd1eba5 [file] [log] [blame]
Gareth Hughesdde2da62001-02-07 03:04:58 +00001/* $Id: texdown.c,v 1.4 2001/02/07 03:04:58 gareth Exp $ */
Brian Paul215ff222000-01-28 16:25:44 +00002
3/*
4 * Copyright (C) 1999 Brian Paul All Rights Reserved.
Gareth Hughesdde2da62001-02-07 03:04:58 +00005 *
Brian Paul215ff222000-01-28 16:25:44 +00006 * 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:
Gareth Hughesdde2da62001-02-07 03:04:58 +000012 *
Brian Paul215ff222000-01-28 16:25:44 +000013 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
Gareth Hughesdde2da62001-02-07 03:04:58 +000015 *
Brian Paul215ff222000-01-28 16:25:44 +000016 * 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;
Brian Paul215ff222000-01-28 16:25:44 +000044static GLboolean ScaleAndBias = GL_FALSE;
45static GLboolean SubImage = GL_FALSE;
46static GLdouble DownloadRate = 0.0; /* texels/sec */
47
48static GLuint Mode = 0;
49
50
Brian Paul7d69e9e2000-03-29 15:47:48 +000051#define NUM_FORMATS 4
52struct FormatRec {
53 GLenum Format;
54 GLenum Type;
55 GLenum IntFormat;
56 GLint TexelSize;
57};
58
59
60static 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};
67static GLint Format;
68
69
Brian Paul215ff222000-01-28 16:25:44 +000070static int
Brian Paul7d69e9e2000-03-29 15:47:48 +000071BytesPerTexel(GLint format)
Brian Paul215ff222000-01-28 16:25:44 +000072{
Brian Paul7d69e9e2000-03-29 15:47:48 +000073 return FormatTable[format].TexelSize;
Brian Paul215ff222000-01-28 16:25:44 +000074}
75
76
77static const char *
78FormatStr(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
91static const char *
92TypeStr(GLenum type)
93{
94 switch (type) {
95 case GL_UNSIGNED_BYTE:
Brian Paul7d69e9e2000-03-29 15:47:48 +000096 return "GL_UNSIGNED_BYTE";
Brian Paul215ff222000-01-28 16:25:44 +000097 case GL_UNSIGNED_SHORT:
Brian Paul7d69e9e2000-03-29 15:47:48 +000098 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";
Brian Paul215ff222000-01-28 16:25:44 +0000103 default:
104 return "";
105 }
106}
107
108
109static void
110MeasureDownloadRate(void)
111{
112 const int w = TexWidth + 2 * TexBorder;
113 const int h = TexHeight + 2 * TexBorder;
Brian Paul7d69e9e2000-03-29 15:47:48 +0000114 const int bytes = w * h * BytesPerTexel(Format);
Brian Paul215ff222000-01-28 16:25:44 +0000115 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
Gareth Hughesdde2da62001-02-07 03:04:58 +0000151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
153 glEnable(GL_TEXTURE_2D);
154
Brian Paul215ff222000-01-28 16:25:44 +0000155 count = 0;
156 t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
157 do {
158 if (SubImage && count > 0) {
159 glTexSubImage2D(GL_TEXTURE_2D, 0, -TexBorder, -TexBorder, w, h,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000160 FormatTable[Format].Format,
161 FormatTable[Format].Type, texImage);
Brian Paul215ff222000-01-28 16:25:44 +0000162 }
163 else {
Brian Paul7d69e9e2000-03-29 15:47:48 +0000164 glTexImage2D(GL_TEXTURE_2D, 0,
165 FormatTable[Format].IntFormat, w, h, TexBorder,
166 FormatTable[Format].Format,
167 FormatTable[Format].Type, texImage);
168 }
169
Gareth Hughesdde2da62001-02-07 03:04:58 +0000170 /* draw a tiny polygon to force texture into texram */
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();
Brian Paul215ff222000-01-28 16:25:44 +0000176
177 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
178 time = t1 - t0;
179 count++;
180 } while (time < 3.0);
181
Gareth Hughesdde2da62001-02-07 03:04:58 +0000182 glDisable(GL_TEXTURE_2D);
183
Brian Paul215ff222000-01-28 16:25:44 +0000184 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 */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000190 glGetTexImage(GL_TEXTURE_2D, 0,
191 FormatTable[Format].Format,
192 FormatTable[Format].Type, getImage);
Brian Paul215ff222000-01-28 16:25:44 +0000193 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
212static void
213PrintString(const char *s)
214{
215 while (*s) {
216 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
217 s++;
218 }
219}
220
221
222static void
223Display(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
Brian Paul7d69e9e2000-03-29 15:47:48 +0000231 glRasterPos2i(10, 80);
Brian Paul215ff222000-01-28 16:25:44 +0000232 sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder);
233 PrintString(s);
234
Brian Paul7d69e9e2000-03-29 15:47:48 +0000235 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));
Brian Paul215ff222000-01-28 16:25:44 +0000240 PrintString(s);
241
Brian Paul7d69e9e2000-03-29 15:47:48 +0000242 glRasterPos2i(10, 50);
Brian Paul215ff222000-01-28 16:25:44 +0000243 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,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000266 DownloadRate * BytesPerTexel(Format) / 1000000.0);
Brian Paul215ff222000-01-28 16:25:44 +0000267 PrintString(s);
Brian Paul7d69e9e2000-03-29 15:47:48 +0000268 {
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
Brian Paul215ff222000-01-28 16:25:44 +0000281 glutSwapBuffers();
282 }
283}
284
285
286static void
287Reshape(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
Brian Paul215ff222000-01-28 16:25:44 +0000298
299static void
300Key(unsigned char key, int x, int y)
301{
302 (void) x;
303 (void) y;
304 switch (key) {
305 case ' ':
Brian Paul8fd9fcb2000-03-29 18:02:52 +0000306 Mode = 0;
Brian Paul215ff222000-01-28 16:25:44 +0000307 break;
308 case 'b':
309 /* toggle border */
310 TexBorder = 1 - TexBorder;
311 Mode = 0;
312 break;
313 case 'f':
314 /* change format */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000315 Format = (Format + 1) % NUM_FORMATS;
Brian Paul215ff222000-01-28 16:25:44 +0000316 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;
Brian Paul215ff222000-01-28 16:25:44 +0000327 case 27:
328 exit(0);
329 break;
330 }
331 glutPostRedisplay();
332}
333
334
335static void
336SpecialKey(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
363static void
364Init(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
372int
373main(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}