Add more structure constructor tests.
[piglit/hramrach.git] / tests / glean / tchgperf.cpp
blobb943f53d5f3a2a28411ee01c9d385102c984670c
1 // BEGIN_COPYRIGHT -*- glean -*-
2 //
3 // Copyright (C) 1999 Allen Akin All Rights Reserved.
4 //
5 // Permission is hereby granted, free of charge, to any person
6 // obtaining a copy of this software and associated documentation
7 // files (the "Software"), to deal in the Software without
8 // restriction, including without limitation the rights to use,
9 // copy, modify, merge, publish, distribute, sublicense, and/or
10 // sell copies of the Software, and to permit persons to whom the
11 // Software is furnished to do so, subject to the following
12 // conditions:
13 //
14 // The above copyright notice and this permission notice shall be
15 // included in all copies or substantial portions of the
16 // Software.
17 //
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 // KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 // WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ALLEN AKIN BE
22 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 // AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 // DEALINGS IN THE SOFTWARE.
26 //
27 // END_COPYRIGHT
29 // tchgperf.cpp: Some basic tests of attribute-change performance.
31 #include "tchgperf.h"
32 #include <algorithm>
33 #include "rand.h"
34 #include "image.h"
35 #include "timer.h"
36 #include "geomutil.h"
38 #if 0
39 #ifdef __UNIX__
40 #include <unistd.h>
41 #endif
43 #include <iostream>
44 #include <fstream>
45 #include "dsconfig.h"
46 #include "dsfilt.h"
47 #include "dsurf.h"
48 #include "winsys.h"
49 #include "environ.h"
50 #include "rc.h"
51 #include "glutils.h"
52 #include "timer.h"
53 #include "tchgperf.h"
54 #include "misc.h"
55 #endif
57 namespace {
59 GLEAN::Image redImage(64, 64, GL_RGB, GL_UNSIGNED_BYTE, 1.0, 0.0, 0.0, 0.0);
60 GLuint redTex;
61 GLEAN::Image greenImage(64, 64, GL_RGB, GL_UNSIGNED_BYTE, 0.0, 1.0, 0.0, 0.0);
62 GLuint greenTex;
64 int nPoints;
65 float* vertices;
66 float* texCoords;
68 void
69 noBindDraw() {
70 int rowSize = 2 * nPoints;
71 for (int y = 0; y < nPoints - 1; ++y) {
72 float* t0 = texCoords + y * rowSize;
73 float* v0 = vertices + y * rowSize;
74 for (int x = 0; x < nPoints - 1; ++x) {
75 float* t1 = t0 + rowSize;
76 float* t2 = t1 + 2;
77 float* t3 = t0 + 2;
78 float* v1 = v0 + rowSize;
79 float* v2 = v1 + 2;
80 float* v3 = v0 + 2;
82 glBegin(GL_TRIANGLES);
83 glTexCoord2fv(t0);
84 glVertex2fv(v0);
85 glTexCoord2fv(t1);
86 glVertex2fv(v1);
87 glTexCoord2fv(t2);
88 glVertex2fv(v2);
89 glEnd();
90 glBegin(GL_TRIANGLES);
91 glTexCoord2fv(t2);
92 glVertex2fv(v2);
93 glTexCoord2fv(t3);
94 glVertex2fv(v3);
95 glTexCoord2fv(t0);
96 glVertex2fv(v0);
97 glEnd();
99 t0 += 2;
100 v0 += 2;
103 } // noBindDraw
105 void
106 bindDraw() {
107 int rowSize = 2 * nPoints;
108 for (int y = 0; y < nPoints - 1; ++y) {
109 float* v0 = vertices + y * rowSize;
110 float* t0 = texCoords + y * rowSize;
111 for (int x = 0; x < nPoints - 1; ++x) {
112 float* t1 = t0 + rowSize;
113 float* t2 = t1 + 2;
114 float* t3 = t0 + 2;
115 float* v1 = v0 + rowSize;
116 float* v2 = v1 + 2;
117 float* v3 = v0 + 2;
119 glBindTexture(GL_TEXTURE_2D, redTex);
120 glBegin(GL_TRIANGLES);
121 glTexCoord2fv(t0);
122 glVertex2fv(v0);
123 glTexCoord2fv(t1);
124 glVertex2fv(v1);
125 glTexCoord2fv(t2);
126 glVertex2fv(v2);
127 glEnd();
129 glBindTexture(GL_TEXTURE_2D, greenTex);
130 glBegin(GL_TRIANGLES);
131 glTexCoord2fv(t2);
132 glVertex2fv(v2);
133 glTexCoord2fv(t3);
134 glVertex2fv(v3);
135 glTexCoord2fv(t0);
136 glVertex2fv(v0);
137 glEnd();
139 t0 += 2;
140 v0 += 2;
143 } // BindDraw
145 class BindDrawTimer: public GLEAN::Timer {
146 virtual void op() { bindDraw(); }
147 virtual void preop() { glFinish(); }
148 virtual void postop() { glFinish(); }
151 class NoBindDrawTimer: public GLEAN::Timer {
152 virtual void op() { noBindDraw(); }
153 virtual void preop() { glFinish(); }
154 virtual void postop() { glFinish(); }
157 void
158 logStats(GLEAN::TexBindPerfResult& r, GLEAN::Environment* env) {
159 env->log << "\tApproximate texture binding time = " << r.bindTime
160 << " microseconds.\n\tRange of valid measurements = ["
161 << r.lowerBound << ", " << r.upperBound << "]\n";
162 } // logStats
164 } // anonymous namespace
166 namespace GLEAN {
168 ///////////////////////////////////////////////////////////////////////////////
169 // runOne: Run a single test case
170 ///////////////////////////////////////////////////////////////////////////////
172 void
173 TexBindPerf::runOne(TexBindPerfResult& r, Window& w) {
174 glGenTextures(1, &redTex);
175 glBindTexture(GL_TEXTURE_2D, redTex);
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
180 redImage.makeMipmaps(GL_RGB);
182 glGenTextures(1, &greenTex);
183 glBindTexture(GL_TEXTURE_2D, greenTex);
184 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
185 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
186 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
187 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
188 greenImage.makeMipmaps(GL_RGB);
190 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
192 GLUtils::useScreenCoords(drawingSize + 2, drawingSize + 2);
193 glEnable(GL_DEPTH_TEST);
194 glDepthFunc(GL_LEQUAL);
195 glEnable(GL_TEXTURE_2D);
196 glColor4f(1.0, 1.0, 1.0, 1.0);
198 nPoints = drawingSize / 2; // Yields 1-pixel triangles.
200 RandomDouble vRand(142857);
201 RandomMesh2D v(1.0, drawingSize, nPoints, 1.0, drawingSize, nPoints,
202 vRand);
203 vertices = v(0, 0);
205 RandomDouble tRand(314159);
206 RandomMesh2D t(0.0, 1.0, nPoints, 0.0, 1.0, nPoints, tRand);
207 texCoords = t(0, 0);
209 int nTris = (nPoints - 1) * (nPoints - 1) / 2;
211 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
213 BindDrawTimer bindDrawTimer;
214 NoBindDrawTimer noBindDrawTimer;
216 bindDrawTimer.calibrate();
217 noBindDrawTimer.calibrate();
219 vector<float> measurements;
220 for (int i = 0; i < 5; ++i) {
221 env->quiesce();
222 double tBind = bindDrawTimer.time();
223 w.swap(); // So the user can see something happening.
225 env->quiesce();
226 double tNoBind = noBindDrawTimer.time();
227 w.swap();
229 double bindTime = 1E6 * (tBind - tNoBind) / nTris;
230 if (bindTime < 0.0) {
231 // This can happen if the system isn't quiescent;
232 // some process sneaks in and takes wall-clock time
233 // when ``noBindDraw'' is running. Just flush it
234 // and try again. (Note: You really shouldn't be
235 // running timing tests on a system where other
236 // processes are active!)
237 --i;
238 continue;
241 measurements.push_back(bindTime);
244 sort(measurements.begin(), measurements.end());
245 r.bindTime = (measurements[1]+measurements[2]+measurements[3]) / 3.0;
246 r.lowerBound = measurements[1];
247 r.upperBound = measurements[3];
248 r.pass = true;
249 } // TexBindPerf::runOne
251 ///////////////////////////////////////////////////////////////////////////////
252 // logOne: Log a single test case
253 ///////////////////////////////////////////////////////////////////////////////
254 void
255 TexBindPerf::logOne(TexBindPerfResult& r) {
256 logPassFail(r);
257 logConcise(r);
258 logStats(r, env);
259 } // TexBindPerf::logOne
261 ///////////////////////////////////////////////////////////////////////////////
262 // compareOne: Compare results for a single test case
263 ///////////////////////////////////////////////////////////////////////////////
264 void
265 TexBindPerf::compareOne(TexBindPerfResult& oldR, TexBindPerfResult& newR) {
266 if (newR.bindTime < oldR.lowerBound) {
267 int percent = static_cast<int>(
268 100.0 * (oldR.bindTime - newR.bindTime) / newR.bindTime
269 + 0.5);
270 env->log << name << ": DIFF "
271 << newR.config->conciseDescription() << '\n'
272 << '\t' << env->options.db2Name << " may be "
273 << percent << "% faster.\n";
274 } else if (newR.bindTime > oldR.upperBound) {
275 int percent = static_cast<int>(
276 100.0 * (newR.bindTime - oldR.bindTime) / oldR.bindTime
277 + 0.5);
278 env->log << name << ": DIFF "
279 << oldR.config->conciseDescription() << '\n'
280 << '\t' << env->options.db1Name << " may be "
281 << percent << "% faster.\n";
282 } else {
283 if (env->options.verbosity)
284 env->log << name << ": SAME "
285 << newR.config->conciseDescription()
286 << "\n\t"
287 << env->options.db2Name
288 << " test time falls within the "
289 << "valid measurement range of "
290 << env->options.db1Name
291 << " test time.\n";
293 if (env->options.verbosity) {
294 env->log << env->options.db1Name << ':';
295 logStats(oldR, env);
296 env->log << env->options.db2Name << ':';
297 logStats(newR, env);
299 } // TexBindPerf::compareOne
301 ///////////////////////////////////////////////////////////////////////////////
302 // The test object itself:
303 ///////////////////////////////////////////////////////////////////////////////
304 TexBindPerf texBindPerfTest("texBindPerf", "window, rgb, z",
306 "This test makes a rough estimate of the cost of a glBindTexture()\n"
307 "operation, expressed in microseconds.\n"
308 "\n"
309 "Since the apparent cost of a texture bind is dependent on many\n"
310 "factors (including the fraction of the texture map that's actually\n"
311 "used for drawing, on machines that cache textures; texture map\n"
312 "size; texel format; etc.), a general-purpose test can only estimate\n"
313 "it. In this test we do so by drawing random triangles of very\n"
314 "small size, and reporting simple statistics concerning the cost.\n");
317 } // namespace GLEAN