blob: 1e78b7d6cba945e37abbb210d4d8d46d109128a4 [file] [log] [blame]
Alexey Marinichev592b8622010-02-04 15:20:10 -08001// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Alexey Marinichev6294a392010-03-02 16:53:36 -08005#include <fcntl.h>
Alexey Marinichev592b8622010-02-04 15:20:10 -08006#include <stdio.h>
7#include <stdlib.h>
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -08008#include <string.h>
Alexey Marinichev6294a392010-03-02 16:53:36 -08009#include <sys/mman.h>
Alexey Marinichev592b8622010-02-04 15:20:10 -080010
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -080011#include "base/logging.h"
12
Alexey Marinichev592b8622010-02-04 15:20:10 -080013#include "main.h"
Alexey Marinichev96e28692010-02-18 16:59:59 -080014#include "shaders.h"
Alexey Marinichev3c199732010-03-11 10:33:35 -080015#include "utils.h"
Alexey Marinichev6294a392010-03-02 16:53:36 -080016#include "yuv2rgb.h"
Alexey Marinichev592b8622010-02-04 15:20:10 -080017
18
Darin Petkovdd314962010-02-18 16:21:29 -080019const int enabled_tests_max = 8;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -080020const char *enabled_tests[enabled_tests_max+1] = {NULL};
21int seconds_to_run = 0;
22
Alexey Marinicheva991f2b2010-03-11 09:59:51 -080023// Runs Bench on a test function f and prints out results. Bench function
24// returns the slope and bias of a linear model relating the argument passed to
25// f and time it took f to run. Normally the argument of f is assumed to be
26// number of iterations an operation is executed.
27//
28// coefficient is multiplied (if inverse is false) or divided (if inverse is
29// true) by the slope and the result is printed.
30//
31// The test will not run if enabled_tests is nonempty and no string in
32// enabled_tests is contained in name.
33//
34// Examples:
35// coefficient = width * height (measured in pixels), inverse = true
36// returns the throughput in megapixels per second;
37//
38// coefficient = 1, inverse = false
39// returns number of operations per second.
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -080040void RunTest(BenchFunc f, const char *name, float coefficient, bool inverse) {
Alexey Marinichev592b8622010-02-04 15:20:10 -080041 float slope;
42 int64_t bias;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -080043
44 if (enabled_tests[0]) {
45 bool found = false;
46 for (const char **e = enabled_tests; *e; e++)
47 if (strstr(name, *e)) {
48 found = true;
49 break;
50 }
51 if (!found)
52 return;
53 }
54
Alexey Marinichevc24aa232010-02-24 18:15:54 -080055 GLenum err = glGetError();
56 if (err != 0) {
57 printf("# %s failed, glGetError returned 0x%x.\n", name, err);
58 // float() in python will happily parse Nan.
59 printf("%s: Nan\n", name);
60 } else {
Alexey Marinichev8919b6e2010-03-04 16:21:02 -080061 if (Bench(f, &slope, &bias)) {
Alexey Marinicheve5b107a2010-03-10 17:51:04 -080062 printf("%s: %g\n", name, coefficient * (inverse ? 1.f / slope : slope));
Alexey Marinichev8919b6e2010-03-04 16:21:02 -080063 } else {
64 printf("# %s is too slow, returning zero.\n", name);
65 printf("%s: 0\n", name);
66 }
Alexey Marinichevc24aa232010-02-24 18:15:54 -080067 }
Alexey Marinichev592b8622010-02-04 15:20:10 -080068}
69
70static int arg1 = 0;
Alexey Marinichev592b8622010-02-04 15:20:10 -080071
Alexey Marinichev592b8622010-02-04 15:20:10 -080072void SwapTestFunc(int iter) {
73 for (int i = 0 ; i < iter; ++i) {
74 SwapBuffers();
75 }
76}
77
78void SwapTest() {
Alexey Marinicheve5b107a2010-03-10 17:51:04 -080079 RunTest(SwapTestFunc, "us_swap_swap", 1.f, false);
Alexey Marinichev592b8622010-02-04 15:20:10 -080080}
81
Alexey Marinichev592b8622010-02-04 15:20:10 -080082void ClearTestFunc(int iter) {
83 GLbitfield mask = arg1;
84 glClear(mask);
85 glFlush(); // Kick GPU as soon as possible
86 for (int i = 0 ; i < iter-1; ++i) {
87 glClear(mask);
88 }
89}
90
91
92void ClearTest() {
93 arg1 = GL_COLOR_BUFFER_BIT;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -080094 RunTest(ClearTestFunc, "mpixels_sec_clear_color", g_width * g_height, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -080095
96 arg1 = GL_DEPTH_BUFFER_BIT;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -080097 RunTest(ClearTestFunc, "mpixels_sec_clear_depth", g_width * g_height, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -080098
99 arg1 = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800100 RunTest(ClearTestFunc, "mpixels_sec_clear_colordepth",
101 g_width * g_height, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800102
103 arg1 = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800104 RunTest(ClearTestFunc, "mpixels_sec_clear_depthstencil",
105 g_width * g_height, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800106
107 arg1 = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800108 RunTest(ClearTestFunc, "mpixels_sec_clear_colordepthstencil",
109 g_width * g_height, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800110}
111
112
113GLuint SetupVBO(GLenum target, GLsizeiptr size, const GLvoid *data) {
114 GLuint buf = ~0;
115 glGenBuffers(1, &buf);
116 glBindBuffer(target, buf);
117 glBufferData(target, size, data, GL_STATIC_DRAW);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700118 CHECK(!glGetError());
119 return buf;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800120}
121
122
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800123GLuint SetupTexture(GLsizei size_log2) {
124 GLsizei size = 1 << size_log2;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800125 GLuint name = ~0;
126 glGenTextures(1, &name);
127 glBindTexture(GL_TEXTURE_2D, name);
128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
130
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800131 unsigned char *pixels = new unsigned char[size * size * 4];
Alexey Marinichev592b8622010-02-04 15:20:10 -0800132 if (!pixels)
133 return 0;
134
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800135 for (GLint level = 0; size > 0; level++, size /= 2) {
136 unsigned char *p = pixels;
137 for (int i = 0; i < size; i++) {
138 for (int j = 0; j < size; j++) {
139 *p++ = level %3 != 0 ? (i ^ j) << level : 0;
140 *p++ = level %3 != 1 ? (i ^ j) << level : 0;
141 *p++ = level %3 != 2 ? (i ^ j) << level : 0;
142 *p++ = 255;
143 }
Alexey Marinichev592b8622010-02-04 15:20:10 -0800144 }
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800145 if (size == 1) {
146 unsigned char *p = pixels;
147 *p++ = 255;
148 *p++ = 255;
149 *p++ = 255;
150 *p++ = 255;
151 }
152 glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size, size, 0,
153 GL_RGBA, GL_UNSIGNED_BYTE, pixels);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800154 }
Alexey Marinichev592b8622010-02-04 15:20:10 -0800155 delete[] pixels;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800156 return name;
157}
158
159
Alexey Marinichev96e28692010-02-18 16:59:59 -0800160static void DrawArraysTestFunc(int iter);
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800161static void FillRateTestNormal(const char *name, float coeff=1.f);
162static void FillRateTestBlendDepth(const char *name);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800163
164void FillRateTest() {
165 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
166 glDisable(GL_DEPTH_TEST);
167 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
168
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800169 GLfloat buffer_vertex[8] = {
Alexey Marinichev592b8622010-02-04 15:20:10 -0800170 -1.f, -1.f,
171 1.f, -1.f,
172 -1.f, 1.f,
173 1.f, 1.f,
174 };
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800175 GLfloat buffer_texture[8] = {
176 0.f, 0.f,
177 1.f, 0.f,
178 0.f, 1.f,
179 1.f, 1.f,
180 };
Alexey Marinichev592b8622010-02-04 15:20:10 -0800181 glEnableClientState(GL_VERTEX_ARRAY);
182
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800183 GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER,
184 sizeof(buffer_vertex), buffer_vertex);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700185 glVertexPointer(2, GL_FLOAT, 0, 0);
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800186
187 GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER,
188 sizeof(buffer_texture), buffer_texture);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700189 glTexCoordPointer(2, GL_FLOAT, 0, 0);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800190
191 glColor4f(1.f, 0.f, 0.f, 1.f);
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800192 FillRateTestNormal("fill_solid");
193 FillRateTestBlendDepth("fill_solid");
Alexey Marinichev592b8622010-02-04 15:20:10 -0800194
195 glColor4f(1.f, 1.f, 1.f, 1.f);
196 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
197 glEnable(GL_TEXTURE_2D);
198
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800199 GLuint texture = SetupTexture(9);
200 FillRateTestNormal("fill_tex_nearest");
Alexey Marinichev592b8622010-02-04 15:20:10 -0800201
202 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
203 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800204 FillRateTestNormal("fill_tex_bilinear");
Alexey Marinichev592b8622010-02-04 15:20:10 -0800205
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800206 // lod = 0.5
207 glScalef(0.7071f, 0.7071f, 1.f);
208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
209 GL_LINEAR_MIPMAP_NEAREST);
210 FillRateTestNormal("fill_tex_trilinear_nearest_05", 0.7071f * 0.7071f);
211
212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
213 GL_LINEAR_MIPMAP_LINEAR);
214 FillRateTestNormal("fill_tex_trilinear_linear_05", 0.7071f * 0.7071f);
215
216 // lod = 0.4
217 glLoadIdentity();
218 glScalef(0.758f, 0.758f, 1.f);
219 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
220 GL_LINEAR_MIPMAP_LINEAR);
221 FillRateTestNormal("fill_tex_trilinear_linear_04", 0.758f * 0.758f);
222
223 // lod = 0.1
224 glLoadIdentity();
225 glScalef(0.933f, 0.933f, 1.f);
226 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
227 GL_LINEAR_MIPMAP_LINEAR);
228 FillRateTestNormal("fill_tex_trilinear_linear_01", 0.933f * 0.933f);
229
230 glDeleteBuffers(1, &vbo_vertex);
231 glDeleteBuffers(1, &vbo_texture);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800232 glDeleteTextures(1, &texture);
233}
234
235
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800236static void FillRateTestNormal(const char *name, float coeff) {
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800237 const int buffer_len = 64;
238 char buffer[buffer_len];
239 snprintf(buffer, buffer_len, "mpixels_sec_%s", name);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800240 RunTest(DrawArraysTestFunc, buffer, coeff * g_width * g_height, true);
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800241}
Alexey Marinichev592b8622010-02-04 15:20:10 -0800242
Alexey Marinichevd4a0f072010-02-09 17:50:12 -0800243static void FillRateTestBlendDepth(const char *name) {
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800244 const int buffer_len = 64;
245 char buffer[buffer_len];
246
Alexey Marinichev6d014842010-02-10 19:21:39 -0800247 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
248 glEnable(GL_BLEND);
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800249 snprintf(buffer, buffer_len, "mpixels_sec_%s_blended", name);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800250 RunTest(DrawArraysTestFunc, buffer, g_width * g_height, true);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800251 glDisable(GL_BLEND);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800252
Alexey Marinichev6d014842010-02-10 19:21:39 -0800253 glEnable(GL_DEPTH_TEST);
254 glDepthFunc(GL_NOTEQUAL);
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800255 snprintf(buffer, buffer_len, "mpixels_sec_%s_depth_neq", name);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800256 RunTest(DrawArraysTestFunc, buffer, g_width * g_height, true);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800257 glDepthFunc(GL_NEVER);
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800258 snprintf(buffer, buffer_len, "mpixels_sec_%s_depth_never", name);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800259 RunTest(DrawArraysTestFunc, buffer, g_width * g_height, true);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800260 glDisable(GL_DEPTH_TEST);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800261}
262
263
Alexey Marinichev96e28692010-02-18 16:59:59 -0800264static void DrawArraysTestFunc(int iter) {
Alexey Marinichev592b8622010-02-04 15:20:10 -0800265 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
266 glFlush();
267 for (int i = 0; i < iter-1; ++i) {
268 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
269 }
270}
271
272
Alexey Marinichev96e28692010-02-18 16:59:59 -0800273static void DrawElementsTestFunc(int iter) {
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700274 glDrawElements(GL_TRIANGLES, arg1, GL_UNSIGNED_INT, 0);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800275 glFlush();
276 for (int i = 0 ; i < iter-1; ++i) {
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700277 glDrawElements(GL_TRIANGLES, arg1, GL_UNSIGNED_INT, 0);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800278 }
279}
280
Alexey Marinichev6d014842010-02-10 19:21:39 -0800281// Generates a tautological lattice.
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800282static void CreateLattice(GLfloat **vertices, GLsizeiptr *size,
283 GLfloat size_x, GLfloat size_y,
Alexey Marinichev6d014842010-02-10 19:21:39 -0800284 int width, int height)
285{
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800286 GLfloat *vptr = *vertices = new GLfloat[2 * (width + 1) * (height + 1)];
Alexey Marinichev6d014842010-02-10 19:21:39 -0800287 for (int j = 0; j <= height; j++) {
288 for (int i = 0; i <= width; i++) {
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800289 *vptr++ = i * size_x;
290 *vptr++ = j * size_y;
Alexey Marinichev6d014842010-02-10 19:21:39 -0800291 }
292 }
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800293 *size = (vptr - *vertices) * sizeof(GLfloat);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800294}
295
Alexey Marinichev592b8622010-02-04 15:20:10 -0800296// Generates a mesh of 2*width*height triangles. The ratio of front facing to
297// back facing triangles is culled_ratio/RAND_MAX. Returns the number of
298// vertices in the mesh.
Alexey Marinichev6d014842010-02-10 19:21:39 -0800299static int CreateMesh(GLuint **indices, GLsizeiptr *size,
Alexey Marinichev592b8622010-02-04 15:20:10 -0800300 int width, int height, int culled_ratio) {
301 srand(0);
302
Alexey Marinichev6d014842010-02-10 19:21:39 -0800303 GLuint *iptr = *indices = new GLuint[2 * 3 * (width * height)];
Alexey Marinichev592b8622010-02-04 15:20:10 -0800304 const int swath_height = 4;
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800305
306 CHECK(width % swath_height == 0 && height % swath_height == 0);
307
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800308 for (int j = 0; j < height; j += swath_height) {
Alexey Marinichev592b8622010-02-04 15:20:10 -0800309 for (int i = 0; i < width; i++) {
310 for (int j2 = 0; j2 < swath_height; j2++) {
Alexey Marinichev6d014842010-02-10 19:21:39 -0800311 GLuint first = (j + j2) * (width + 1) + i;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800312 GLuint second = first + 1;
Alexey Marinichev6d014842010-02-10 19:21:39 -0800313 GLuint third = first + (width + 1);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800314 GLuint fourth = third + 1;
315
316 bool flag = rand() < culled_ratio;
317 *iptr++ = first;
318 *iptr++ = flag ? second : third;
319 *iptr++ = flag ? third : second;
320
321 *iptr++ = fourth;
322 *iptr++ = flag ? third : second;
323 *iptr++ = flag ? second : third;
324 }
325 }
326 }
Alexey Marinichev6d014842010-02-10 19:21:39 -0800327 *size = (iptr - *indices) * sizeof(GLuint);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800328
Alexey Marinichev6d014842010-02-10 19:21:39 -0800329 return iptr - *indices;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800330}
331
332void TriangleSetupTest() {
333 glViewport(-g_width, -g_height, g_width*2, g_height*2);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800334
335 // Larger meshes make this test too slow for devices that do 1 mtri/sec.
336 GLint width = 64;
337 GLint height = 64;
338
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800339 GLfloat *vertices = NULL;
Alexey Marinichev6d014842010-02-10 19:21:39 -0800340 GLsizeiptr vertex_buffer_size = 0;
Alexey Marinichevbf88d1f2010-02-12 12:49:16 -0800341 CreateLattice(&vertices, &vertex_buffer_size, 1.f / g_width, 1.f / g_height,
342 width, height);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800343 GLuint vertex_buffer = SetupVBO(GL_ARRAY_BUFFER,
344 vertex_buffer_size, vertices);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700345 glVertexPointer(2, GL_FLOAT, 0, 0);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800346 glEnableClientState(GL_VERTEX_ARRAY);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800347
348 GLuint *indices = NULL;
349 GLuint index_buffer = 0;
350 GLsizeiptr index_buffer_size = 0;
351
Alexey Marinichev6d014842010-02-10 19:21:39 -0800352 {
353 arg1 = CreateMesh(&indices, &index_buffer_size, width, height, 0);
354
Alexey Marinichev6d014842010-02-10 19:21:39 -0800355 index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
356 index_buffer_size, indices);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800357 RunTest(DrawElementsTestFunc, "mtri_sec_triangle_setup", arg1 / 3, true);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800358 glEnable(GL_CULL_FACE);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800359 RunTest(DrawElementsTestFunc, "mtri_sec_triangle_setup_all_culled",
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800360 arg1 / 3, true);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800361 glDisable(GL_CULL_FACE);
Alexey Marinichev6d014842010-02-10 19:21:39 -0800362
Alexey Marinichev6d014842010-02-10 19:21:39 -0800363 glDeleteBuffers(1, &index_buffer);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800364 delete[] indices;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800365 }
366
Alexey Marinichev6d014842010-02-10 19:21:39 -0800367 {
368 glColor4f(0.f, 1.f, 1.f, 1.f);
369 arg1 = CreateMesh(&indices, &index_buffer_size, width, height,
370 RAND_MAX / 2);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800371
Alexey Marinichev6d014842010-02-10 19:21:39 -0800372 index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
373 index_buffer_size, indices);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800374 glEnable(GL_CULL_FACE);
375 RunTest(DrawElementsTestFunc, "mtri_sec_triangle_setup_half_culled",
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800376 arg1 / 3, true);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800377
Alexey Marinichev6d014842010-02-10 19:21:39 -0800378 glDeleteBuffers(1, &index_buffer);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800379 delete[] indices;
Alexey Marinichev6d014842010-02-10 19:21:39 -0800380 }
Alexey Marinichev592b8622010-02-04 15:20:10 -0800381
Alexey Marinichev6d014842010-02-10 19:21:39 -0800382 glDeleteBuffers(1, &vertex_buffer);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800383 delete[] vertices;
Alexey Marinichev592b8622010-02-04 15:20:10 -0800384}
385
386
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800387void AttributeFetchShaderTest() {
Alexey Marinichev96e28692010-02-18 16:59:59 -0800388 GLint width = 64;
389 GLint height = 64;
390
391 glViewport(-g_width, -g_height, g_width*2, g_height*2);
392
393 GLfloat *vertices = NULL;
394 GLsizeiptr vertex_buffer_size = 0;
395 CreateLattice(&vertices, &vertex_buffer_size, 1.f / g_width, 1.f / g_height,
396 width, height);
397 GLuint vertex_buffer = SetupVBO(GL_ARRAY_BUFFER,
398 vertex_buffer_size, vertices);
399
400 GLuint *indices = NULL;
401 GLuint index_buffer = 0;
402 GLsizeiptr index_buffer_size = 0;
403
404 // Everything will be back-face culled.
405 arg1 = CreateMesh(&indices, &index_buffer_size, width, height, 0);
406 index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
407 index_buffer_size, indices);
408
409 glEnable(GL_CULL_FACE);
410
411 GLuint vertex_buffers[8];
412 for (GLuint i = 0; i < sizeof(vertex_buffers)/sizeof(vertex_buffers[0]); i++)
413 vertex_buffers[i] = vertex_buffer;
414
415 ShaderProgram program = AttributeFetchShaderProgram(1, vertex_buffers);
416 RunTest(DrawElementsTestFunc,
417 "mvtx_sec_attribute_fetch_shader", arg1, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800418 glDeleteProgram(program);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800419
Alexey Marinichev9b818772010-02-23 12:07:48 -0800420 program = AttributeFetchShaderProgram(2, vertex_buffers);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800421 RunTest(DrawElementsTestFunc,
422 "mvtx_sec_attribute_fetch_shader_2_attr", arg1, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800423 glDeleteProgram(program);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800424
Alexey Marinichev9b818772010-02-23 12:07:48 -0800425 program = AttributeFetchShaderProgram(4, vertex_buffers);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800426 RunTest(DrawElementsTestFunc,
427 "mvtx_sec_attribute_fetch_shader_4_attr", arg1, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800428 glDeleteProgram(program);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800429
Alexey Marinichev9b818772010-02-23 12:07:48 -0800430 program = AttributeFetchShaderProgram(8, vertex_buffers);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800431 RunTest(DrawElementsTestFunc,
432 "mvtx_sec_attribute_fetch_shader_8_attr", arg1, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800433 glDeleteProgram(program);
Alexey Marinichev96e28692010-02-18 16:59:59 -0800434
435 glDeleteBuffers(1, &index_buffer);
436 delete[] indices;
437
438 glDeleteBuffers(1, &vertex_buffer);
439 delete[] vertices;
440}
441
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800442
Alexey Marinichevc24aa232010-02-24 18:15:54 -0800443void VaryingsAndDdxyShaderTest() {
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800444 glViewport(-g_width, -g_height, g_width*2, g_height*2);
445
446 const int c = 4;
447 GLfloat *vertices = NULL;
448 GLsizeiptr vertex_buffer_size = 0;
449 CreateLattice(&vertices, &vertex_buffer_size, 1.f / c, 1.f / c, c, c);
450 GLuint vertex_buffer = SetupVBO(GL_ARRAY_BUFFER,
451 vertex_buffer_size, vertices);
452
453 GLuint *indices = NULL;
454 GLuint index_buffer = 0;
455 GLsizeiptr index_buffer_size = 0;
456
457 arg1 = CreateMesh(&indices, &index_buffer_size, c, c, 0);
458 index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
459 index_buffer_size, indices);
460
461 ShaderProgram program = VaryingsShaderProgram(1, vertex_buffer);
462 RunTest(DrawElementsTestFunc,
463 "mpixels_sec_varyings_shader_1", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800464 glDeleteProgram(program);
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800465
466 program = VaryingsShaderProgram(2, vertex_buffer);
467 RunTest(DrawElementsTestFunc,
468 "mpixels_sec_varyings_shader_2", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800469 glDeleteProgram(program);
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800470
471 program = VaryingsShaderProgram(4, vertex_buffer);
472 RunTest(DrawElementsTestFunc,
473 "mpixels_sec_varyings_shader_4", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800474 glDeleteProgram(program);
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800475
476 program = VaryingsShaderProgram(8, vertex_buffer);
477 RunTest(DrawElementsTestFunc,
478 "mpixels_sec_varyings_shader_8", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800479 glDeleteProgram(program);
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800480
Alexey Marinichevc24aa232010-02-24 18:15:54 -0800481 program = DdxDdyShaderProgram(true, vertex_buffer);
482 RunTest(DrawElementsTestFunc,
483 "mpixels_sec_ddx_shader", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800484 glDeleteProgram(program);
Alexey Marinichevc24aa232010-02-24 18:15:54 -0800485
486 program = DdxDdyShaderProgram(false, vertex_buffer);
487 RunTest(DrawElementsTestFunc,
488 "mpixels_sec_ddy_shader", g_width * g_height, true);
Alexey Marinichev3c199732010-03-11 10:33:35 -0800489 glDeleteProgram(program);
Alexey Marinichevc24aa232010-02-24 18:15:54 -0800490
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800491 glDeleteBuffers(1, &index_buffer);
492 delete[] indices;
493
494 glDeleteBuffers(1, &vertex_buffer);
495 delete[] vertices;
496}
497
Alexey Marinichev8919b6e2010-03-04 16:21:02 -0800498
499void YuvToRgbShaderTestHelper(int type, const char *name) {
Alexey Marinichev6294a392010-03-02 16:53:36 -0800500 size_t size = 0;
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800501 GLuint texture[2];
Alexey Marinichev6294a392010-03-02 16:53:36 -0800502 ShaderProgram program = 0;
503 GLuint vertex_buffer = 0;
504 GLfloat vertices[8] = {
505 0.f, 0.f,
506 1.f, 0.f,
Alexey Marinicheve5b107a2010-03-10 17:51:04 -0800507 0.f, 1.f,
508 1.f, 1.f,
Alexey Marinichev6294a392010-03-02 16:53:36 -0800509 };
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800510 char evenodd[2] = {0, 255};
Alexey Marinicheve5b107a2010-03-10 17:51:04 -0800511 const int pixel_height = YUV2RGB_HEIGHT * 2 / 3;
Alexey Marinichev6294a392010-03-02 16:53:36 -0800512
513 char *pixels = static_cast<char *>(MmapFile(YUV2RGB_NAME, &size));
514 if (!pixels) {
515 printf("# Could not open image file: %s\n", YUV2RGB_NAME);
516 goto done;
517 }
518 if (size != YUV2RGB_SIZE) {
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800519 printf("# Image file of wrong size, got %d, expected %d\n",
520 static_cast<int>(size), YUV2RGB_SIZE);
Alexey Marinichev6294a392010-03-02 16:53:36 -0800521 goto done;
522 }
523
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800524 glGenTextures(2, texture);
525 glActiveTexture(GL_TEXTURE0);
526 glBindTexture(GL_TEXTURE_2D, texture[0]);
Alexey Marinichev6294a392010-03-02 16:53:36 -0800527 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
528 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
529 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, YUV2RGB_WIDTH, YUV2RGB_HEIGHT,
530 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels);
531
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800532 glActiveTexture(GL_TEXTURE1);
533 glBindTexture(GL_TEXTURE_2D, texture[1]);
534 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
535 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
536 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 1,
537 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, evenodd);
538
Alexey Marinicheve5b107a2010-03-10 17:51:04 -0800539 glViewport(-YUV2RGB_WIDTH, -pixel_height, YUV2RGB_WIDTH*2, pixel_height * 2);
Alexey Marinichev6294a392010-03-02 16:53:36 -0800540 vertex_buffer = SetupVBO(GL_ARRAY_BUFFER, sizeof(vertices), vertices);
541
Alexey Marinichev8919b6e2010-03-04 16:21:02 -0800542 program = YuvToRgbShaderProgram(type, vertex_buffer,
Alexey Marinicheve5b107a2010-03-10 17:51:04 -0800543 YUV2RGB_WIDTH, pixel_height);
544
545 if (program) {
546 float coeff = 1.f *
547 (YUV2RGB_WIDTH < g_width ?
548 static_cast<float>(YUV2RGB_WIDTH) / g_width : 1.f) *
549 (pixel_height < g_height ?
550 static_cast<float>(pixel_height) / g_height : 1.f);
551 FillRateTestNormal(name, coeff);
552 } else {
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800553 printf("# Could not set up YUV shader.\n");
Alexey Marinicheve5b107a2010-03-10 17:51:04 -0800554 }
Alexey Marinichev6294a392010-03-02 16:53:36 -0800555
556done:
Alexey Marinichev3c199732010-03-11 10:33:35 -0800557 glDeleteProgram(program);
Alexey Marinichev6dfea312010-03-03 14:53:12 -0800558 glDeleteTextures(2, texture);
559 glDeleteBuffers(1, &vertex_buffer);
Alexey Marinichev6294a392010-03-02 16:53:36 -0800560 munmap(pixels, size);
561}
562
Alexey Marinichev8919b6e2010-03-04 16:21:02 -0800563void YuvToRgbShaderTest1() {
564 YuvToRgbShaderTestHelper(1, "yuv_shader_1");
565}
566
567void YuvToRgbShaderTest2() {
568 YuvToRgbShaderTestHelper(2, "yuv_shader_2");
569}
570
Matthew Papakipos1efe8bb2010-03-24 13:57:49 -0700571static GLuint compositing_textures[5];
572static uint32_t texture_base[WINDOW_HEIGHT*WINDOW_WIDTH];
573static uint32_t texture_update[WINDOW_HEIGHT*WINDOW_WIDTH];
574static ShaderProgram compositing_background_program = 0;
575static ShaderProgram compositing_foreground_program = 0;
576
577void InitBaseTexture() {
578 for (int y = 0; y < WINDOW_HEIGHT; y++) {
579 for (int x = 0; x < WINDOW_WIDTH; x++) {
580 // This color is gray, half alpha.
581 texture_base[y*WINDOW_WIDTH+x] = 0x80808080;
582 }
583 }
584}
585
586// UpdateTexture simulates Chrome updating tab contents.
587// We cause a bunch of read and write cpu memory bandwidth.
588// It's a very rough approximation.
589void UpdateTexture() {
590 memcpy(texture_update, texture_base, sizeof(texture_base));
591}
592
593void LoadTexture() {
594 // Use GL_RGBA for compatibility with GLES2.0.
595 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
596 WINDOW_WIDTH, WINDOW_HEIGHT, 0,
597 GL_RGBA, GL_UNSIGNED_BYTE, texture_update);
598}
599
600// Test how fast we can do full-screen compositing of images
601// continuously updated from the CPU.
602// This tests both GPU compositing performance and also
603// CPU -> GPU data transfer speed.
604// It is a basic perf test to make sure we have enough performance
605// to run a compositing window manager.
606void CompositingTestFunc(int iter) {
607 for (int i = 0 ; i < iter; ++i) {
608 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
609
610 // Draw the background
611 glDisable(GL_BLEND);
612 glDisable(GL_DEPTH_TEST);
613 // We have to blend three textures, but we use multi-texture for this
614 // blending, not fb blend, to avoid the external memory traffic
615 glActiveTexture(GL_TEXTURE0);
616 glBindTexture(GL_TEXTURE_2D, compositing_textures[0]);
617 glActiveTexture(GL_TEXTURE1);
618 glBindTexture(GL_TEXTURE_2D, compositing_textures[1]);
619 glActiveTexture(GL_TEXTURE2);
620 glBindTexture(GL_TEXTURE_2D, compositing_textures[2]);
621 // Set up the texture coordinate arrays
622 glClientActiveTexture(GL_TEXTURE0);
623 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
624 glClientActiveTexture(GL_TEXTURE1);
625 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
626 glClientActiveTexture(GL_TEXTURE2);
627 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
628 // Use the right shader
629 glUseProgram(compositing_background_program);
630 // Draw the quad
631 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
632
633 // Set up one texture coordinate array
634 glClientActiveTexture(GL_TEXTURE0);
635 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
636 glClientActiveTexture(GL_TEXTURE1);
637 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
638 glClientActiveTexture(GL_TEXTURE2);
639 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
640 // Use the right shader
641 glUseProgram(compositing_foreground_program);
642
643 // Compositing is blending, so we shall blend.
644 glEnable(GL_BLEND);
645 // Depth test is on for window occlusion
646 glEnable(GL_DEPTH_TEST);
647
648 // Draw window number one
649 // This update acts like a chrome webkit sw rendering update.
650 glActiveTexture(GL_TEXTURE0);
651 glBindTexture(GL_TEXTURE_2D, compositing_textures[3]);
652 UpdateTexture();
653 // TODO(papakipos): this LoadTexture is likely doing more CPU memory copies
654 // than we would like.
655 LoadTexture();
656 // TODO(papakipos): add color interpolation here, and modulate
657 // texture against it.
658 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
659
660 // Draw window number two
661 // This is a static window, so we don't update it.
662 glActiveTexture(GL_TEXTURE0);
663 glBindTexture(GL_TEXTURE_2D, compositing_textures[4]);
664 // TODO(papakipos): add color interpolation here, and modulate
665 // texture against it.
666 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
667 }
668}
669
670void InitializeCompositing() {
671 InitBaseTexture();
672
673 glClearColor(0.f, 0.f, 0.f, 0.f);
674 glDisable(GL_DEPTH_TEST);
675 glDisable(GL_BLEND);
676 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
677 glDepthFunc(GL_LEQUAL);
678
679 glGenTextures(5, compositing_textures);
680 glActiveTexture(GL_TEXTURE0);
681 for (int i = 0; i < 5; i++) {
682 glBindTexture(GL_TEXTURE_2D, compositing_textures[i]);
683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
684 GL_LINEAR);
685 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
686 GL_LINEAR);
687 }
688
689 glColor4f(1.f, 1.f, 1.f, 1.f);
690
691 // Set up the vertex arrays for drawing textured quads later on.
692 glEnableClientState(GL_VERTEX_ARRAY);
693 GLfloat buffer_vertex[8] = {
694 -1.f, -1.f,
695 1.f, -1.f,
696 -1.f, 1.f,
697 1.f, 1.f,
698 };
699 GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER,
700 sizeof(buffer_vertex), buffer_vertex);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700701 glVertexPointer(2, GL_FLOAT, 0, 0);
Matthew Papakipos1efe8bb2010-03-24 13:57:49 -0700702
703 GLfloat buffer_texture[8] = {
704 0.f, 0.f,
705 1.f, 0.f,
706 0.f, 1.f,
707 1.f, 1.f,
708 };
709 GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER,
710 sizeof(buffer_texture), buffer_texture);
711 for (int i = 0; i < 3; i++) {
712 glClientActiveTexture(GL_TEXTURE0 + i);
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700713 glTexCoordPointer(2, GL_FLOAT, 0, 0);
Matthew Papakipos1efe8bb2010-03-24 13:57:49 -0700714 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
715 }
716
717 // Set up the static background textures.
718 UpdateTexture();
719 UpdateTexture();
720 UpdateTexture();
721 // Load these textures into bound texture ids and keep using them
722 // from there to avoid having to reload this texture every frame
723 glActiveTexture(GL_TEXTURE0);
724 glBindTexture(GL_TEXTURE_2D, compositing_textures[0]);
725 LoadTexture();
726 glActiveTexture(GL_TEXTURE1);
727 glBindTexture(GL_TEXTURE_2D, compositing_textures[1]);
728 LoadTexture();
729 glActiveTexture(GL_TEXTURE2);
730 glBindTexture(GL_TEXTURE_2D, compositing_textures[2]);
731 LoadTexture();
732
733 glActiveTexture(GL_TEXTURE0);
734 glBindTexture(GL_TEXTURE_2D, compositing_textures[3]);
735 UpdateTexture();
736 LoadTexture();
737
738 glActiveTexture(GL_TEXTURE0);
739 glBindTexture(GL_TEXTURE_2D, compositing_textures[4]);
740 UpdateTexture();
741 LoadTexture();
742
743 // Set up vertex & fragment shaders.
744 compositing_background_program =
745 TripleTextureBlendShaderProgram(vbo_vertex,
746 vbo_texture, vbo_texture, vbo_texture);
747 compositing_foreground_program =
748 BasicTextureShaderProgram(vbo_vertex, vbo_texture);
749 if ((!compositing_background_program) ||
750 (!compositing_foreground_program)) {
751 printf("# Could not set up compositing shader.\n");
752 }
753
Matthew Papakiposef4f4632010-03-25 16:45:42 -0700754 glVertexPointer(2, GL_FLOAT, 0, 0);
Matthew Papakipos1efe8bb2010-03-24 13:57:49 -0700755}
756
757void TeardownCompositing() {
758 glDeleteProgram(compositing_background_program);
759 glDeleteProgram(compositing_foreground_program);
760}
761
762// Notes on the window manager compositing test:
763// Depth
764// Depth complexity = 3: background, active window, static window
765// Background: may be a tex-blend of three images (2.5d effect)
766// The windows -- at most two, fullscreen
767// Depth test is on, passing most of the time.
768// A lot of texture min-filtering -- not modelled
769// One of the two windows is getting live browser frame updates -- not mod
770// The live window runs at x/2 and y/2 size -- not modelled
771// The two windows are modulated by color interpolation to get gradient
772static float screen_scale_factor = (1e6f*
773 (WINDOW_WIDTH*WINDOW_HEIGHT)/
774 (1280.f*768));
775
776void WindowManagerCompositingTest() {
777 InitializeCompositing();
778 RunTest(CompositingTestFunc, "1280x768_fps_compositing",
779 screen_scale_factor, true);
780 TeardownCompositing();
781}
782
783void NoFillWindowManagerCompositingTest() {
784 glScissor(0, 0, 1, 1);
785 glEnable(GL_SCISSOR_TEST);
786 InitializeCompositing();
787 RunTest(CompositingTestFunc, "1280x768_fps_no_fill_compositing",
788 screen_scale_factor, true);
789 TeardownCompositing();
790}
Alexey Marinichev6294a392010-03-02 16:53:36 -0800791
Alexey Marinichev3c199732010-03-11 10:33:35 -0800792// TODO: get resources file from a command line option or something.
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800793// TODO: use proper command line parsing library.
794static void ParseArgs(int argc, char *argv[]) {
795 const char **enabled_tests_ptr = enabled_tests;
796 bool test_name_arg = false;
797 bool duration_arg = false;
798 for (int i = 0; i < argc; i++) {
799 if (test_name_arg) {
800 test_name_arg = false;
801 *enabled_tests_ptr++ = argv[i];
802 if (enabled_tests_ptr - enabled_tests >= enabled_tests_max)
803 break;
804 } else if (duration_arg) {
805 duration_arg = false;
806 seconds_to_run = atoi(argv[i]);
807 } else if (strcmp("-t", argv[i]) == 0) {
808 test_name_arg = true;
809 } else if (strcmp("-d", argv[i]) == 0) {
810 duration_arg = true;
811 }
812 }
813 *enabled_tests_ptr++ = NULL;
814}
815
816
Alexey Marinichev592b8622010-02-04 15:20:10 -0800817int main(int argc, char *argv[]) {
Antoine Labourec7eb532010-03-12 11:01:34 -0800818 SetBasePathFromArgv0(argv[0], "src");
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800819 ParseArgs(argc, argv);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800820 if (!Init()) {
821 printf("# Failed to initialize.\n");
822 return 1;
823 }
824
825 void (*test[])() = {
826 SwapTest,
827 ClearTest,
828 FillRateTest,
829 TriangleSetupTest,
Alexey Marinichevaf0b26d2010-02-24 13:03:13 -0800830 AttributeFetchShaderTest,
Alexey Marinichevc24aa232010-02-24 18:15:54 -0800831 VaryingsAndDdxyShaderTest,
Alexey Marinichev8919b6e2010-03-04 16:21:02 -0800832 YuvToRgbShaderTest1,
833 YuvToRgbShaderTest2,
Matthew Papakipos1efe8bb2010-03-24 13:57:49 -0700834 NoFillWindowManagerCompositingTest,
835 WindowManagerCompositingTest,
Alexey Marinichev592b8622010-02-04 15:20:10 -0800836 };
837
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800838 uint64_t done = GetUTime() + 1000000ULL * seconds_to_run;
839 do {
840 for (unsigned int i = 0; i < sizeof(test) / sizeof(*test); i++) {
841 InitContext();
842 test[i]();
Alexey Marinichev9b818772010-02-23 12:07:48 -0800843 GLenum err = glGetError();
844 if (err != 0)
Alexey Marinichev8919b6e2010-03-04 16:21:02 -0800845 printf("# glGetError returned non-zero: 0x%x\n", err);
Alexey Marinichev19b5a5d2010-02-18 11:37:26 -0800846 DestroyContext();
847 }
848 } while (GetUTime() < done);
Alexey Marinichev592b8622010-02-04 15:20:10 -0800849
850 return 0;
851}