2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * Measure glCopyTex[Sub]Image() rate.
24 * Create a large, off-screen framebuffer object for rendering and
25 * copying the texture data from it since we can't make really large
36 int WinWidth
= 100, WinHeight
= 100;
38 static GLuint VBO
, FBO
, RBO
, Tex
;
40 const GLsizei MinSize
= 16, MaxSize
= 4096;
41 static GLsizei TexSize
;
43 static const GLboolean DrawPoint
= GL_TRUE
;
44 static const GLboolean TexSubImage4
= GL_FALSE
;
51 static const struct vertex vertices
[1] = {
52 { 0.0, 0.0, 0.5, 0.5 },
55 #define VOFFSET(F) ((void *) offsetof(struct vertex, F))
58 /** Called from test harness/main */
62 const GLenum filter
= GL_LINEAR
;
65 if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
66 perf_printf("copytex: GL_EXT_framebuffer_object not supported\n");
71 glGenBuffersARB(1, &VBO
);
72 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, VBO
);
73 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, sizeof(vertices
),
74 vertices
, GL_STATIC_DRAW_ARB
);
76 glVertexPointer(2, GL_FLOAT
, sizeof(struct vertex
), VOFFSET(x
));
77 glTexCoordPointer(2, GL_FLOAT
, sizeof(struct vertex
), VOFFSET(s
));
78 glEnableClientState(GL_VERTEX_ARRAY
);
79 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
82 glGenTextures(1, &Tex
);
83 glBindTexture(GL_TEXTURE_2D
, Tex
);
84 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, filter
);
85 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, filter
);
86 glEnable(GL_TEXTURE_2D
);
89 glGenRenderbuffersEXT(1, &RBO
);
90 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT
, RBO
);
91 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT
, GL_RGBA
, MaxSize
, MaxSize
);
94 glGenFramebuffersEXT(1, &FBO
);
95 glBindFramebufferEXT(GL_FRAMEBUFFER
, FBO
);
96 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT
,
97 GL_COLOR_ATTACHMENT0_EXT
,
98 GL_RENDERBUFFER_EXT
, RBO
);
100 stat
= glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT
);
101 if (stat
!= GL_FRAMEBUFFER_COMPLETE_EXT
) {
102 perf_printf("fboswitch: Error: incomplete FBO!\n");
107 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT
);
108 glViewport(0, 0, MaxSize
, MaxSize
);
109 glClear(GL_COLOR_BUFFER_BIT
);
114 CopyTexImage(unsigned count
)
117 for (i
= 1; i
< count
; i
++) {
120 glDrawArrays(GL_POINTS
, 0, 1);
122 /* copy whole texture */
123 glCopyTexImage2D(GL_TEXTURE_2D
, 0,
124 GL_RGBA
, 0, 0, TexSize
, TexSize
, 0);
131 CopyTexSubImage(unsigned count
)
134 for (i
= 1; i
< count
; i
++) {
137 glDrawArrays(GL_POINTS
, 0, 1);
139 /* copy sub texture */
141 /* four sub-copies */
142 GLsizei half
= TexSize
/ 2;
144 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0,
145 0, 0, 0, 0, half
, half
);
147 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0,
148 half
, 0, half
, 0, half
, half
);
150 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0,
151 0, half
, 0, half
, half
, half
);
153 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0,
154 half
, half
, half
, half
, half
, half
);
158 glCopyTexSubImage2D(GL_TEXTURE_2D
, 0,
159 0, 0, 0, 0, TexSize
, TexSize
);
166 /** Called from test harness/main */
173 /** Called from test harness/main */
177 double rate
, mbPerSec
;
178 GLint sub
, maxTexSize
;
180 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxTexSize
);
182 /* loop over whole/sub tex copy */
183 for (sub
= 0; sub
< 2; sub
++) {
185 /* loop over texture sizes */
186 for (TexSize
= MinSize
; TexSize
<= MaxSize
; TexSize
*= 4) {
188 if (TexSize
<= maxTexSize
) {
189 GLint bytesPerImage
= 4 * TexSize
* TexSize
;
192 rate
= PerfMeasureRate(CopyTexImage
);
194 /* setup empty dest texture */
195 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
,
197 GL_RGBA
, GL_UNSIGNED_BYTE
, NULL
);
198 rate
= PerfMeasureRate(CopyTexSubImage
);
201 mbPerSec
= rate
* bytesPerImage
/ (1024.0 * 1024.0);
208 perf_printf(" glCopyTex%sImage(%d x %d): %.1f copies/sec, %.1f Mpixels/sec\n",
209 (sub
? "Sub" : ""), TexSize
, TexSize
, rate
, mbPerSec
);