blob: deb13abcafbc1e65e1dcd3080de75b3830522076 [file] [log] [blame]
Brian Paul7d69e9e2000-03-29 15:47:48 +00001/* $Id: texdown.c,v 1.2 2000/03/29 15:47:48 brianp Exp $ */
Brian Paul215ff222000-01-28 16:25:44 +00002
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;
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
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,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000156 FormatTable[Format].Format,
157 FormatTable[Format].Type, texImage);
Brian Paul215ff222000-01-28 16:25:44 +0000158 }
159 else {
Brian Paul7d69e9e2000-03-29 15:47:48 +0000160 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);
Brian Paul215ff222000-01-28 16:25:44 +0000177 }
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 */
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 ' ':
306 break;
307 case 'b':
308 /* toggle border */
309 TexBorder = 1 - TexBorder;
310 Mode = 0;
311 break;
312 case 'f':
313 /* change format */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000314 Format = (Format + 1) % NUM_FORMATS;
Brian Paul215ff222000-01-28 16:25:44 +0000315 Mode = 0;
316 break;
317 case 'p':
318 /* toggle border */
319 ScaleAndBias = !ScaleAndBias;
320 Mode = 0;
321 break;
322 case 's':
323 SubImage = !SubImage;
324 Mode = 0;
325 break;
Brian Paul215ff222000-01-28 16:25:44 +0000326 case 27:
327 exit(0);
328 break;
329 }
330 glutPostRedisplay();
331}
332
333
334static void
335SpecialKey(int key, int x, int y)
336{
337 (void) x;
338 (void) y;
339 switch (key) {
340 case GLUT_KEY_UP:
341 if (TexHeight < MaxSize)
342 TexHeight *= 2;
343 break;
344 case GLUT_KEY_DOWN:
345 if (TexHeight > 1)
346 TexHeight /= 2;
347 break;
348 case GLUT_KEY_LEFT:
349 if (TexWidth > 1)
350 TexWidth /= 2;
351 break;
352 case GLUT_KEY_RIGHT:
353 if (TexWidth < MaxSize)
354 TexWidth *= 2;
355 break;
356 }
357 Mode = 0;
358 glutPostRedisplay();
359}
360
361
362static void
363Init(void)
364{
365 printf("GL_VENDOR = %s\n", (const char *) glGetString(GL_VENDOR));
366 printf("GL_VERSION = %s\n", (const char *) glGetString(GL_VERSION));
367 printf("GL_RENDERER = %s\n", (const char *) glGetString(GL_RENDERER));
368}
369
370
371int
372main(int argc, char *argv[])
373{
374 glutInit( &argc, argv );
375 glutInitWindowPosition( 0, 0 );
376 glutInitWindowSize( 600, 100 );
377 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
378 glutCreateWindow(argv[0]);
379 glutReshapeFunc( Reshape );
380 glutKeyboardFunc( Key );
381 glutSpecialFunc( SpecialKey );
382 glutDisplayFunc( Display );
383 Init();
384 glutMainLoop();
385 return 0;
386}