progs/egl: Move demos a level deeper.
[mesa.git] / progs / perf / copytex.c
1 /*
2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
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.
20 */
21
22 /**
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
26 * on-screen windows.
27 *
28 * Brian Paul
29 * 22 Sep 2009
30 */
31
32 #include <string.h>
33 #include "glmain.h"
34 #include "common.h"
35
36 int WinWidth = 100, WinHeight = 100;
37
38 static GLuint VBO, FBO, RBO, Tex;
39
40 const GLsizei MinSize = 16, MaxSize = 4096;
41 static GLsizei TexSize;
42
43 static const GLboolean DrawPoint = GL_TRUE;
44 static const GLboolean TexSubImage4 = GL_FALSE;
45
46 struct vertex
47 {
48 GLfloat x, y, s, t;
49 };
50
51 static const struct vertex vertices[1] = {
52 { 0.0, 0.0, 0.5, 0.5 },
53 };
54
55 #define VOFFSET(F) ((void *) offsetof(struct vertex, F))
56
57
58 /** Called from test harness/main */
59 void
60 PerfInit(void)
61 {
62 const GLenum filter = GL_LINEAR;
63 GLenum stat;
64
65 if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
66 perf_printf("copytex: GL_EXT_framebuffer_object not supported\n");
67 exit(0);
68 }
69
70 /* setup VBO */
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);
75
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);
80
81 /* setup texture */
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);
87
88 /* setup rbo */
89 glGenRenderbuffersEXT(1, &RBO);
90 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBO);
91 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, MaxSize, MaxSize);
92
93 /* setup fbo */
94 glGenFramebuffersEXT(1, &FBO);
95 glBindFramebufferEXT(GL_FRAMEBUFFER, FBO);
96 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
97 GL_COLOR_ATTACHMENT0_EXT,
98 GL_RENDERBUFFER_EXT, RBO);
99
100 stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
101 if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
102 perf_printf("fboswitch: Error: incomplete FBO!\n");
103 exit(1);
104 }
105
106 /* clear the FBO */
107 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
108 glViewport(0, 0, MaxSize, MaxSize);
109 glClear(GL_COLOR_BUFFER_BIT);
110 }
111
112
113 static void
114 CopyTexImage(unsigned count)
115 {
116 unsigned i;
117 for (i = 1; i < count; i++) {
118 /* draw something */
119 if (DrawPoint)
120 glDrawArrays(GL_POINTS, 0, 1);
121
122 /* copy whole texture */
123 glCopyTexImage2D(GL_TEXTURE_2D, 0,
124 GL_RGBA, 0, 0, TexSize, TexSize, 0);
125 }
126 glFinish();
127 }
128
129
130 static void
131 CopyTexSubImage(unsigned count)
132 {
133 unsigned i;
134 for (i = 1; i < count; i++) {
135 /* draw something */
136 if (DrawPoint)
137 glDrawArrays(GL_POINTS, 0, 1);
138
139 /* copy sub texture */
140 if (TexSubImage4) {
141 /* four sub-copies */
142 GLsizei half = TexSize / 2;
143 /* lower-left */
144 glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
145 0, 0, 0, 0, half, half);
146 /* lower-right */
147 glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
148 half, 0, half, 0, half, half);
149 /* upper-left */
150 glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
151 0, half, 0, half, half, half);
152 /* upper-right */
153 glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
154 half, half, half, half, half, half);
155 }
156 else {
157 /* one big copy */
158 glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
159 0, 0, 0, 0, TexSize, TexSize);
160 }
161 }
162 glFinish();
163 }
164
165
166 /** Called from test harness/main */
167 void
168 PerfNextRound(void)
169 {
170 }
171
172
173 /** Called from test harness/main */
174 void
175 PerfDraw(void)
176 {
177 double rate, mbPerSec;
178 GLint sub, maxTexSize;
179
180 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
181
182 /* loop over whole/sub tex copy */
183 for (sub = 0; sub < 2; sub++) {
184
185 /* loop over texture sizes */
186 for (TexSize = MinSize; TexSize <= MaxSize; TexSize *= 4) {
187
188 if (TexSize <= maxTexSize) {
189 GLint bytesPerImage = 4 * TexSize * TexSize;
190
191 if (sub == 0)
192 rate = PerfMeasureRate(CopyTexImage);
193 else {
194 /* setup empty dest texture */
195 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
196 TexSize, TexSize, 0,
197 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
198 rate = PerfMeasureRate(CopyTexSubImage);
199 }
200
201 mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
202 }
203 else {
204 rate = 0.0;
205 mbPerSec = 0.0;
206 }
207
208 perf_printf(" glCopyTex%sImage(%d x %d): %.1f copies/sec, %.1f Mpixels/sec\n",
209 (sub ? "Sub" : ""), TexSize, TexSize, rate, mbPerSec);
210 }
211 }
212
213 exit(0);
214 }