blob: 9f4f50869175c8afbf3f613f019dac8b543e096d [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 +000050#define NUM_FORMATS 4
51struct FormatRec {
52 GLenum Format;
53 GLenum Type;
54 GLenum IntFormat;
55 GLint TexelSize;
56};
57
58
59static const struct FormatRec FormatTable[NUM_FORMATS] = {
60 /* Format Type IntFormat TexelSize */
61 { 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 },
65};
66static GLint Format;
67
68
Brian Paul215ff222000-01-28 16:25:44 +000069static int
Brian Paul7d69e9e2000-03-29 15:47:48 +000070BytesPerTexel(GLint format)
Brian Paul215ff222000-01-28 16:25:44 +000071{
Brian Paul7d69e9e2000-03-29 15:47:48 +000072 return FormatTable[format].TexelSize;
Brian Paul215ff222000-01-28 16:25:44 +000073}
74
75
76static const char *
77FormatStr(GLenum format)
78{
79 switch (format) {
80 case GL_RGB:
81 return "GL_RGB";
82 case GL_RGBA:
83 return "GL_RGBA";
84 default:
85 return "";
86 }
87}
88
89
90static const char *
91TypeStr(GLenum type)
92{
93 switch (type) {
94 case GL_UNSIGNED_BYTE:
Brian Paul7d69e9e2000-03-29 15:47:48 +000095 return "GL_UNSIGNED_BYTE";
Brian Paul215ff222000-01-28 16:25:44 +000096 case GL_UNSIGNED_SHORT:
Brian Paul7d69e9e2000-03-29 15:47:48 +000097 return "GL_UNSIGNED_SHORT";
98 case GL_UNSIGNED_SHORT_5_6_5:
99 return "GL_UNSIGNED_SHORT_5_6_5";
100 case GL_UNSIGNED_SHORT_5_6_5_REV:
101 return "GL_UNSIGNED_SHORT_5_6_5_REV";
Brian Paul215ff222000-01-28 16:25:44 +0000102 default:
103 return "";
104 }
105}
106
107
108static void
109MeasureDownloadRate(void)
110{
111 const int w = TexWidth + 2 * TexBorder;
112 const int h = TexHeight + 2 * TexBorder;
Brian Paul7d69e9e2000-03-29 15:47:48 +0000113 const int bytes = w * h * BytesPerTexel(Format);
Brian Paul215ff222000-01-28 16:25:44 +0000114 GLubyte *texImage, *getImage;
115 GLdouble t0, t1, time;
116 int count;
117 int i;
118
119 texImage = (GLubyte *) malloc(bytes);
120 getImage = (GLubyte *) malloc(bytes);
121 if (!texImage || !getImage) {
122 DownloadRate = 0.0;
123 return;
124 }
125
126 for (i = 0; i < bytes; i++) {
127 texImage[i] = i & 0xff;
128 }
129
130 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
131 glPixelStorei(GL_PACK_ALIGNMENT, 1);
132
133 if (ScaleAndBias) {
134 glPixelTransferf(GL_RED_SCALE, 0.5);
135 glPixelTransferf(GL_GREEN_SCALE, 0.5);
136 glPixelTransferf(GL_BLUE_SCALE, 0.5);
137 glPixelTransferf(GL_RED_BIAS, 0.5);
138 glPixelTransferf(GL_GREEN_BIAS, 0.5);
139 glPixelTransferf(GL_BLUE_BIAS, 0.5);
140 }
141 else {
142 glPixelTransferf(GL_RED_SCALE, 1.0);
143 glPixelTransferf(GL_GREEN_SCALE, 1.0);
144 glPixelTransferf(GL_BLUE_SCALE, 1.0);
145 glPixelTransferf(GL_RED_BIAS, 0.0);
146 glPixelTransferf(GL_GREEN_BIAS, 0.0);
147 glPixelTransferf(GL_BLUE_BIAS, 0.0);
148 }
149
Gareth Hughesdde2da62001-02-07 03:04:58 +0000150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
152 glEnable(GL_TEXTURE_2D);
153
Brian Paul215ff222000-01-28 16:25:44 +0000154 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,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000159 FormatTable[Format].Format,
160 FormatTable[Format].Type, texImage);
Brian Paul215ff222000-01-28 16:25:44 +0000161 }
162 else {
Brian Paul7d69e9e2000-03-29 15:47:48 +0000163 glTexImage2D(GL_TEXTURE_2D, 0,
164 FormatTable[Format].IntFormat, w, h, TexBorder,
165 FormatTable[Format].Format,
166 FormatTable[Format].Type, texImage);
167 }
168
Gareth Hughesdde2da62001-02-07 03:04:58 +0000169 /* draw a tiny polygon to force texture into texram */
170 glBegin(GL_TRIANGLES);
171 glTexCoord2f(0, 0); glVertex2f(1, 1);
172 glTexCoord2f(1, 0); glVertex2f(3, 1);
173 glTexCoord2f(0.5, 1); glVertex2f(2, 3);
174 glEnd();
Brian Paul215ff222000-01-28 16:25:44 +0000175
176 t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
177 time = t1 - t0;
178 count++;
179 } while (time < 3.0);
180
Gareth Hughesdde2da62001-02-07 03:04:58 +0000181 glDisable(GL_TEXTURE_2D);
182
Brian Paul215ff222000-01-28 16:25:44 +0000183 printf("w*h=%d count=%d time=%f\n", w*h, count, time);
184 DownloadRate = w * h * count / time;
185
186#if 0
187 if (!ScaleAndBias) {
188 /* verify texture readback */
Brian Paul7d69e9e2000-03-29 15:47:48 +0000189 glGetTexImage(GL_TEXTURE_2D, 0,
190 FormatTable[Format].Format,
191 FormatTable[Format].Type, getImage);
Brian Paul215ff222000-01-28 16:25:44 +0000192 for (i = 0; i < w * h; i++) {
193 if (texImage[i] != getImage[i]) {
194 printf("[%d] %d != %d\n", i, texImage[i], getImage[i]);
195 }
196 }
197 }
198#endif
199
200 free(texImage);
201 free(getImage);
202
203 {
204 GLint err = glGetError();
205 if (err)
206 printf("GL error %d\n", err);
207 }
208}
209
210
211static void
212PrintString(const char *s)
213{
214 while (*s) {
215 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
216 s++;
217 }
218}
219
220
221static void
222Display(void)
223{
224 const int w = TexWidth + 2 * TexBorder;
225 const int h = TexHeight + 2 * TexBorder;
226 char s[1000];
227
228 glClear(GL_COLOR_BUFFER_BIT);
229
Brian Paul7d69e9e2000-03-29 15:47:48 +0000230 glRasterPos2i(10, 80);
Brian Paul215ff222000-01-28 16:25:44 +0000231 sprintf(s, "Texture size[cursor]: %d x %d Border[b]: %d", w, h, TexBorder);
232 PrintString(s);
233
Brian Paul7d69e9e2000-03-29 15:47:48 +0000234 glRasterPos2i(10, 65);
235 sprintf(s, "Format[f]: %s Type: %s IntFormat: %s",
236 FormatStr(FormatTable[Format].Format),
237 TypeStr( FormatTable[Format].Type),
238 FormatStr(FormatTable[Format].IntFormat));
Brian Paul215ff222000-01-28 16:25:44 +0000239 PrintString(s);
240
Brian Paul7d69e9e2000-03-29 15:47:48 +0000241 glRasterPos2i(10, 50);
Brian Paul215ff222000-01-28 16:25:44 +0000242 sprintf(s, "Pixel Scale&Bias[p]: %s TexSubImage[s]: %s",
243 ScaleAndBias ? "Yes" : "No",
244 SubImage ? "Yes" : "No");
245 PrintString(s);
246
247 if (Mode == 0) {
248 glRasterPos2i(200, 10);
249 sprintf(s, "...Measuring...");
250 PrintString(s);
251 glutSwapBuffers();
252 glutPostRedisplay();
253 Mode++;
254 }
255 else if (Mode == 1) {
256 MeasureDownloadRate();
257 glutPostRedisplay();
258 Mode++;
259 }
260 else {
261 /* show results */
262 glRasterPos2i(10, 10);
263 sprintf(s, "Download rate: %g Mtexels/second %g MB/second",
264 DownloadRate / 1000000.0,
Brian Paul7d69e9e2000-03-29 15:47:48 +0000265 DownloadRate * BytesPerTexel(Format) / 1000000.0);
Brian Paul215ff222000-01-28 16:25:44 +0000266 PrintString(s);
Brian Paul7d69e9e2000-03-29 15:47:48 +0000267 {
268 GLint r, g, b, a, l, i;
269 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
270 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
271 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
272 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
273 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
274 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
275 sprintf(s, "TexelBits: R=%d G=%d B=%d A=%d L=%d I=%d", r, g, b, a, l, i);
276 glRasterPos2i(10, 25);
277 PrintString(s);
278 }
279
Brian Paul215ff222000-01-28 16:25:44 +0000280 glutSwapBuffers();
281 }
282}
283
284
285static void
286Reshape(int width, int height)
287{
288 glViewport( 0, 0, width, height );
289 glMatrixMode( GL_PROJECTION );
290 glLoadIdentity();
291 glOrtho(0, width, 0, height, -1, 1);
292 glMatrixMode( GL_MODELVIEW );
293 glLoadIdentity();
294}
295
296
Brian Paul215ff222000-01-28 16:25:44 +0000297
298static void
299Key(unsigned char key, int x, int y)
300{
301 (void) x;
302 (void) y;
303 switch (key) {
304 case ' ':
Brian Paul8fd9fcb2000-03-29 18:02:52 +0000305 Mode = 0;
Brian Paul215ff222000-01-28 16:25:44 +0000306 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}