filltest.cpp revision e0f1cff1fac644bd585e6d9ff1a3297338ef0013
1e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams/*
2e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * Copyright (C) 2007 The Android Open Source Project
3e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams *
4e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * you may not use this file except in compliance with the License.
6e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * You may obtain a copy of the License at
7e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams *
8e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams *
10e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * Unless required by applicable law or agreed to in writing, software
11e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * See the License for the specific language governing permissions and
14e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams * limitations under the License.
15e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams */
16e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
17e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <stdlib.h>
18e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <stdio.h>
19e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <time.h>
20e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <sched.h>
21e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <sys/resource.h>
22a5c381fd51deb4bdd8fea3141ad00925f2e2cfb6Andy McFadden#include <string.h>
23e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
24e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <GLES2/gl2.h>
25e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <GLES2/gl2ext.h>
26e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <utils/Timers.h>
27e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams#include <EGL/egl.h>
28e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
29e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
30e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsusing namespace android;
31e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
32e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic void checkGlError(const char* op) {
33e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    for (GLint error = glGetError(); error; error
34e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            = glGetError()) {
35e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
36e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
37e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
38e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
39e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason SamsGLuint loadShader(GLenum shaderType, const char* pSource) {
40e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    GLuint shader = glCreateShader(shaderType);
41e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (shader) {
42e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glShaderSource(shader, 1, &pSource, NULL);
43e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glCompileShader(shader);
44e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        GLint compiled = 0;
45e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
46e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        if (!compiled) {
47e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            GLint infoLen = 0;
48e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
49e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            if (infoLen) {
50e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                char* buf = (char*) malloc(infoLen);
51e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                if (buf) {
52e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
53e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    fprintf(stderr, "Could not compile shader %d:\n%s\n",
54e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                            shaderType, buf);
55e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    free(buf);
56e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                }
57e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                glDeleteShader(shader);
58e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                shader = 0;
59e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            }
60e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
61e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
62e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return shader;
63e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
64e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
65e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsenum {
66e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    A_POS,
67e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    A_COLOR,
68e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    A_TEX0,
69e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    A_TEX1
70e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams};
71e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
72e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason SamsGLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
73e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
74e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (!vertexShader) {
75e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        return 0;
76e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
77e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
78e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
79e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (!pixelShader) {
80e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        return 0;
81e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
82e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
83e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    GLuint program = glCreateProgram();
84e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (program) {
85e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glAttachShader(program, vertexShader);
86e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        checkGlError("glAttachShader v");
87e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glAttachShader(program, pixelShader);
88e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        checkGlError("glAttachShader p");
89e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
90e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glBindAttribLocation(program, A_POS, "a_pos");
91e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glBindAttribLocation(program, A_COLOR, "a_color");
92e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glBindAttribLocation(program, A_TEX0, "a_tex0");
93e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glBindAttribLocation(program, A_TEX1, "a_tex1");
94e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glLinkProgram(program);
95e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        GLint linkStatus = GL_FALSE;
96e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
97e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        if (linkStatus != GL_TRUE) {
98e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            GLint bufLength = 0;
99e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
100e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            if (bufLength) {
101e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                char* buf = (char*) malloc(bufLength);
102e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                if (buf) {
103e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    glGetProgramInfoLog(program, bufLength, NULL, buf);
104e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    printf("Could not link program:\n%s\n", buf);
105e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                    free(buf);
106e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                }
107e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            }
108e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            glDeleteProgram(program);
109e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            program = 0;
110e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
111e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
112e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    checkGlError("createProgram");
113e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glUseProgram(program);
114e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return program;
115e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
116e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
117e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsuint64_t getTime() {
118e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    struct timespec t;
119e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    clock_gettime(CLOCK_MONOTONIC, &t);
120e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000);
121e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
122e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
123e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsuint64_t gTime;
124e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsvoid startTimer() {
125e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    gTime = getTime();
126e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
127e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
128e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsvoid endTimer(const char *str, int w, int h, double dc, int count) {
129e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    uint64_t t2 = getTime();
130e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    double delta = ((double)(t2 - gTime)) / 1000000000;
131e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    double pixels = dc * (w * h) * count;
132e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    double mpps = pixels / delta / 1000000;
133e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    double dc60 = pixels / delta / (w * h) / 60;
134e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
135e0f1cff1fac644bd585e6d9ff1a3297338ef0013Jason Sams    printf("%s, %f, %f\n", str, mpps, dc60);
136e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
137e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
138e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic const char gVertexShader[] =
139e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "attribute vec4 a_pos;\n"
140e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "attribute vec4 a_color;\n"
141e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "attribute vec2 a_tex0;\n"
142e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "attribute vec2 a_tex1;\n"
143e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec4 v_color;\n"
144e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec2 v_tex0;\n"
145e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec2 v_tex1;\n"
146e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
147e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "void main() {\n"
148e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "    v_color = a_color;\n"
149e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "    v_tex0 = a_tex0;\n"
150e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "    v_tex1 = a_tex1;\n"
151e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "    gl_Position = a_pos;\n"
152e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "}\n";
153e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
154e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic const char gShaderPrefix[] =
155e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "precision mediump float;\n"
156e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform vec4 u_color;\n"
157e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform vec4 u_0;\n"
158e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform vec4 u_1;\n"
159e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform vec4 u_2;\n"
160e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform vec4 u_3;\n"
161e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec4 v_color;\n"
162e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec2 v_tex0;\n"
163e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "varying vec2 v_tex1;\n"
164e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform sampler2D u_tex0;\n"
165e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "uniform sampler2D u_tex1;\n"
166e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "void main() {\n";
167e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
168e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic const char gShaderPostfix[] =
169e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "  gl_FragColor = c;\n"
170e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    "}\n";
171e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
172e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
173e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic char * append(char *d, const char *s) {
174e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    size_t len = strlen(s);
175e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    memcpy(d, s, len);
176e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return d + len;
177e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
178e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
179e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic char * genShader(
180e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    bool useVarColor,
181e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    int texCount,
182e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    bool modulateFirstTex,
183e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    int extraMath)
184e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams{
185e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    char *str = (char *)calloc(16 * 1024, 1);
186e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    char *tmp = append(str, gShaderPrefix);
187e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
188e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (modulateFirstTex || !texCount) {
189e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        if (useVarColor) {
190e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            tmp = append(tmp, "  vec4 c = v_color;\n");
191e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        } else {
192e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            tmp = append(tmp, "  vec4 c = u_color;\n");
193e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
194e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    } else {
195e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  vec4 c = texture2D(u_tex0, v_tex0);\n");
196e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
197e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
198e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (modulateFirstTex && texCount) {
199e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= texture2D(u_tex0, v_tex0);\n");
200e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
201e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (texCount > 1) {
202e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= texture2D(u_tex1, v_tex1);\n");
203e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
204e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
205e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (extraMath > 0) {
206e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= u_0;\n");
207e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
208e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (extraMath > 1) {
209e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= u_1;\n");
210e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
211e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (extraMath > 2) {
212e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= u_2;\n");
213e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
214e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (extraMath > 3) {
215e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        tmp = append(tmp, "  c *= u_3;\n");
216e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
217e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
218e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
219e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    tmp = append(tmp, gShaderPostfix);
220e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    tmp[0] = 0;
221e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
222e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    //printf("%s", str);
223e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return str;
224e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
225e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
226e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic void setupVA() {
227e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    static const float vtx[] = {
228e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        -2.0f,-1.0f,
229e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams         1.0f,-1.0f,
230e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        -2.0f, 1.0f,
231e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams         1.0f, 1.0f };
232e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    static const float color[] = {
233e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,0.0f,1.0f,1.0f,
234e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        0.0f,0.0f,1.0f,1.0f,
235e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,1.0f,0.0f,1.0f,
236e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,1.0f,1.0f,1.0f };
237e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    static const float tex0[] = {
238e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        0.0f,0.0f,
239e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,0.0f,
240e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,1.0f,
241e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        0.0f,1.0f };
242e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    static const float tex1[] = {
243e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,0.0f,
244e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        1.0f,1.0f,
245e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        0.0f,1.0f,
246e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        0.0f,0.0f };
247e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
248e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glEnableVertexAttribArray(A_POS);
249e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glEnableVertexAttribArray(A_COLOR);
250e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glEnableVertexAttribArray(A_TEX0);
251e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glEnableVertexAttribArray(A_TEX1);
252e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
253e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx);
254e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color);
255e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0);
256e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1);
257e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
258e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
259e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams//////////////////////////
260e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
261e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsvoid ptSwap();
262e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
263e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic void doLoop(uint32_t w, uint32_t h, const char *str) {
264e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
265e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
266e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    ptSwap();
267e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glFinish();
268e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
269e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    startTimer();
270e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
271e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    for (int ct=0; ct < 100; ct++) {
272e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
273e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
274e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    ptSwap();
275e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glFinish();
276e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    endTimer(str, w, h, 1, 100);
277e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
278e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
279e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsstatic void doSingleTest(uint32_t w, uint32_t h,
280e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                         bool useVarColor,
281e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                         int texCount,
282e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                         bool modulateFirstTex,
283e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                         int extraMath,
284e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                         int tex0, int tex1) {
285e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    char *pgmTxt = genShader(useVarColor, texCount, modulateFirstTex, extraMath);
286e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    int pgm = createProgram(gVertexShader, pgmTxt);
287e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (!pgm) {
288e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        printf("error running test\n");
289e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        return;
290e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
291e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    int loc = glGetUniformLocation(pgm, "u_tex0");
292e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    //printf("loc = %i \n", loc);
293e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform1i(loc, 0);
294e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_tex1");
295e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform1i(loc, 1);
296e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
297e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_color");
298e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
299e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
300e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_0");
301e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform4f(loc, 1.f, 0.4f, 0.6f, 0.8f);
302e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
303e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_1");
304e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform4f(loc, 0.7f, 0.8f, 0.6f, 0.8f);
305e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
306e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_2");
307e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform4f(loc, 0.9f, 0.6f, 0.7f, 1.0f);
308e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
309e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    loc = glGetUniformLocation(pgm, "u_3");
310e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    if (loc >= 0) glUniform4f(loc, 0.88f, 0.2f, 0.4f, 0.2f);
311e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
312e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glActiveTexture(GL_TEXTURE0);
313e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glBindTexture(GL_TEXTURE_2D, tex0);
314e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glActiveTexture(GL_TEXTURE1);
315e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glBindTexture(GL_TEXTURE_2D, tex1);
316e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glActiveTexture(GL_TEXTURE0);
317e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
318e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    char str2[1024];
319e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
320e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glBlendFunc(GL_ONE, GL_ONE);
321e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glDisable(GL_BLEND);
322e0f1cff1fac644bd585e6d9ff1a3297338ef0013Jason Sams    sprintf(str2, "%i, %i, %i, %i, %i, 0",
323e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            useVarColor, texCount, modulateFirstTex, extraMath, tex0);
324e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    doLoop(w, h, str2);
325e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
326e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glEnable(GL_BLEND);
327e0f1cff1fac644bd585e6d9ff1a3297338ef0013Jason Sams    sprintf(str2, "%i, %i, %i, %i, %i, 1",
328e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            useVarColor, texCount, modulateFirstTex, extraMath, tex0);
329e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    doLoop(w, h, str2);
330e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
331e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
332e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsvoid genTextures() {
333e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    uint32_t *m = (uint32_t *)malloc(1024*1024*4);
334e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    for (int y=0; y < 1024; y++){
335e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        for (int x=0; x < 1024; x++){
336e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            m[y*1024 + x] = 0xff0000ff | ((x & 0xff) << 8) | (y << 16);
337e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
338e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
339e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glBindTexture(GL_TEXTURE_2D, 1);
340e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
341e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
342e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
343e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
344e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
345e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
346e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    for (int y=0; y < 16; y++){
347e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        for (int x=0; x < 16; x++){
348e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            m[y*16 + x] = 0xff0000ff | (x<<12) | (y<<20);
349e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
350e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
351e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glBindTexture(GL_TEXTURE_2D, 2);
352e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m);
353e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
354e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
355e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
356e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
357e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
358e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
359e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
360e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Samsbool doTest(uint32_t w, uint32_t h) {
361e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    setupVA();
362e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    genTextures();
363e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
364e0f1cff1fac644bd585e6d9ff1a3297338ef0013Jason Sams    printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n");
365e0f1cff1fac644bd585e6d9ff1a3297338ef0013Jason Sams
366e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    for (int texCount = 0; texCount < 3; texCount++) {
367e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        for (int extraMath = 0; extraMath < 5; extraMath++) {
368e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
369e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            doSingleTest(w, h, false, texCount, false, extraMath, 1, 1);
370e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            doSingleTest(w, h, true, texCount, false, extraMath, 1, 1);
371e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            if (texCount) {
372e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, false, texCount, true, extraMath, 1, 1);
373e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, true, texCount, true, extraMath, 1, 1);
374e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
375e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, false, texCount, false, extraMath, 2, 2);
376e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, true, texCount, false, extraMath, 2, 2);
377e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, false, texCount, true, extraMath, 2, 2);
378e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams                doSingleTest(w, h, true, texCount, true, extraMath, 2, 2);
379e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams            }
380e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams        }
381e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    }
382e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams
383e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    exit(0);
384e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams    return true;
385e448dd1a4f01da5d9d0ab813c2d5939bcba85ccbJason Sams}
386