2 * Measure glTexSubImage and glCopyTexSubImage speed
12 #include <glad/glad.h>
13 #include "glut_wrap.h"
15 static GLint WinWidth
= 1024, WinHeight
= 512;
16 static GLint TexWidth
= 512, TexHeight
= 512;
18 static GLuint TexObj
= 1;
20 static GLenum IntFormat
= GL_RGBA8
;
21 static GLenum ReadFormat
= GL_RGBA
; /* for glReadPixels */
23 static GLboolean DrawQuad
= GL_TRUE
;
27 * draw teapot image, size TexWidth by TexHeight
34 glViewport(0, 0, TexWidth
, TexHeight
);
35 glScissor(0, 0, TexWidth
, TexHeight
);
36 glEnable(GL_SCISSOR_TEST
);
38 glClearColor(0.5, 0.5, 0.5, 0.0);
39 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
41 ar
= (float) TexWidth
/ TexHeight
;
43 glMatrixMode(GL_PROJECTION
);
45 glFrustum(-ar
, ar
, -1.0, 1.0, 5.0, 25.0);
46 glMatrixMode(GL_MODELVIEW
);
48 glEnable(GL_LIGHTING
);
50 glEnable(GL_DEPTH_TEST
);
53 glRotatef(45, 1, 0, 0);
54 glRotatef(45, 0, 1, 0);
58 glDisable(GL_DEPTH_TEST
);
59 glDisable(GL_LIGHTING
);
61 glDisable(GL_SCISSOR_TEST
);
63 glViewport(0, 0, WinWidth
, WinHeight
);
69 * Do glCopyTexSubImage2D call (update texture with framebuffer data)
70 * If doSubRect is true, do the copy in four pieces instead of all at once.
73 DoCopyTex(GLboolean doSubRect
)
76 /* copy in four parts */
77 int w
= TexWidth
/ 2, h
= TexHeight
/ 2;
81 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y0
, x0
, y0
, w
, h
);
82 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y0
, x1
, y0
, w
, h
);
83 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y1
, x0
, y1
, w
, h
);
84 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y1
, x1
, y1
, w
, h
);
87 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y0
, x1
, y1
, w
, h
);
88 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y0
, x0
, y1
, w
, h
);
89 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y1
, x1
, y0
, w
, h
);
90 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y1
, x0
, y0
, w
, h
);
94 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0, 0, 0, 0, 0, TexWidth
, TexHeight
);
100 * Do glTexSubImage2D (update texture w/ user data)
101 * If doSubRect, do update in four pieces, else all at once.
104 SubTex(GLboolean doSubRect
, const GLubyte
*image
)
108 int w
= TexWidth
/ 2, h
= TexHeight
/ 2;
111 glPixelStorei(GL_UNPACK_ROW_LENGTH
, TexWidth
);
112 glPixelStorei(GL_UNPACK_ALIGNMENT
, 1);
114 glPixelStorei(GL_UNPACK_SKIP_ROWS
, y0
);
115 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, x0
);
116 glTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y0
, w
, h
,
117 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
119 glPixelStorei(GL_UNPACK_SKIP_ROWS
, y0
);
120 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, x1
);
121 glTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y0
, w
, h
,
122 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
124 glPixelStorei(GL_UNPACK_SKIP_ROWS
, y1
);
125 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, x0
);
126 glTexSubImage2D(GL_TEXTURE_2D
, 0, x0
, y1
, w
, h
,
127 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
129 glPixelStorei(GL_UNPACK_SKIP_ROWS
, y1
);
130 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, x1
);
131 glTexSubImage2D(GL_TEXTURE_2D
, 0, x1
, y1
, w
, h
,
132 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
136 glTexSubImage2D(GL_TEXTURE_2D
, 0, 0, 0, TexWidth
, TexHeight
,
137 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
143 * Measure gl[Copy]TexSubImage rate.
144 * This actually also includes time to render a quad and SwapBuffers.
147 RunTest(GLboolean copyTex
, GLboolean doSubRect
)
151 float copyRate
, mbRate
;
155 GLubyte
*image
= NULL
;
157 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_RED_SIZE
, &r
);
158 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_GREEN_SIZE
, &g
);
159 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_BLUE_SIZE
, &b
);
160 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_ALPHA_SIZE
, &a
);
161 bpp
= (r
+ g
+ b
+ a
) / 8;
164 /* read image from frame buffer */
165 image
= (GLubyte
*) malloc(TexWidth
* TexHeight
* bpp
);
166 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
167 glReadPixels(0, 0, TexWidth
, TexHeight
,
168 ReadFormat
, GL_UNSIGNED_BYTE
, image
);
171 glEnable(GL_TEXTURE_2D
);
172 glViewport(WinWidth
/ 2, 0, WinWidth
/ 2, WinHeight
);
174 t0
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
178 /* Framebuffer -> Texture */
179 DoCopyTex(doSubRect
);
181 /* Main Mem -> Texture */
182 SubTex(doSubRect
, image
);
185 /* draw textured quad */
188 glRotatef(rot
, 0, 0, 1);
189 glTranslatef(1, 0, 0);
191 glTexCoord2f(0, 0); glVertex2f(-1, -1);
192 glTexCoord2f(1, 0); glVertex2f( 1, -1);
193 glTexCoord2f(1, 1); glVertex2f( 1, 1);
194 glTexCoord2f(0, 1); glVertex2f(-1, 1);
202 t1
= glutGet(GLUT_ELAPSED_TIME
) / 1000.0;
206 } while (t1
- t0
< 5.0);
208 glDisable(GL_TEXTURE_2D
);
222 copyRate
= iters
/ (t1
- t0
);
223 mbRate
= w
* h
* bpp
* copyRate
/ (1024 * 1024);
226 printf("glCopyTexSubImage: %d x %d, %d Bpp:\n", w
, h
, bpp
);
228 printf("glTexSubImage: %d x %d, %d Bpp:\n", w
, h
, bpp
);
229 printf(" %d calls in %.2f = %.2f calls/sec, %.2f MB/s\n",
230 iters
, t1
-t0
, copyRate
, mbRate
);
237 glClearColor(0.2, 0.2, 0.8, 0);
238 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
245 RunTest(GL_FALSE
, GL_FALSE
);
246 RunTest(GL_FALSE
, GL_TRUE
);
247 RunTest(GL_TRUE
, GL_FALSE
);
248 RunTest(GL_TRUE
, GL_TRUE
);
258 Reshape(int width
, int height
)
260 glViewport(0, 0, width
, height
);
261 glMatrixMode(GL_PROJECTION
);
263 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
264 glMatrixMode(GL_MODELVIEW
);
266 glTranslatef(0.0, 0.0, -15.0);
271 Key(unsigned char key
, int x
, int y
)
285 SpecialKey(int key
, int x
, int y
)
306 /* create initial, empty teximage */
307 glBindTexture(GL_TEXTURE_2D
, TexObj
);
308 glTexImage2D(GL_TEXTURE_2D
, 0, IntFormat
, TexWidth
, TexHeight
, 0,
309 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
310 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
311 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
312 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
318 ParseArgs(int argc
, char *argv
[])
321 for (i
= 1; i
< argc
; i
++) {
322 if (strcmp(argv
[i
], "-nodraw") == 0)
329 main(int argc
, char *argv
[])
331 GLint mode
= GLUT_RGB
| GLUT_ALPHA
| GLUT_DOUBLE
| GLUT_DEPTH
;
332 glutInit(&argc
, argv
);
334 ParseArgs(argc
, argv
);
336 glutInitWindowPosition(0, 0);
337 glutInitWindowSize(WinWidth
, WinHeight
);
338 glutInitDisplayMode(mode
);
339 glutCreateWindow(argv
[0]);
341 glutReshapeFunc(Reshape
);
342 glutKeyboardFunc(Key
);
343 glutSpecialFunc(SpecialKey
);
344 glutDisplayFunc(Draw
);
346 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));