1677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
2677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Use of this source code is governed by a BSD-style license that can be
4677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * found in the LICENSE file.
5677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
6677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
7677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <GLES2/gl2.h>
8677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <GLES2/gl2ext.h>
9677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <EGL/egl.h>
10677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <EGL/eglext.h>
11677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <X11/Xlib.h>
12677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <X11/Xatom.h>
13677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <X11/Xutil.h>
14677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
15677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <stdlib.h>
16677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <unistd.h>
17677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <getopt.h>
18677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <stdio.h>
19677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <math.h>
20677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <sys/time.h>
21677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <string.h>
22677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <stdbool.h>
23677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#include <assert.h>
24677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
25677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define ALLOC_COUNT_MAX        256
26677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define ALLOC_SIZE_MAX         8000000
27677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define REALLOCS_COUNT         10000
28677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define PINNING_PERCENTAGE     0
29677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define DEFAULT_LOOP_COUNT     100
30677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define DEFAULT_CARVEOUT_AMT   80
31677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define SYS_ROOT               "/sys/devices/platform/tegra-nvmap/misc/nvmap"
32677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define WINDOW_WIDTH           1024
33677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define WINDOW_HEIGHT          768
34677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
35677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/* GART is 32mb, but is limited to 24mb per process */
36677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein#define GART_FILL_SIZE         24
37677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
38677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic int verbose = 0;
39677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic const char space[] = "************************************************";
40677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic GLuint vsObj, fsObj, programObj;
41677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic Display *x_display;
42677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic Window win;
43677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic EGLDisplay egl_display;
44677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic EGLContext egl_context;
45677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic EGLSurface egl_surface;
46677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
47677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinconst char vertex_src [] =
48677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein"                                               \
49677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinuniform mat4 transformMatrix;                   \
50677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinattribute vec4 position;                        \
51677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinattribute vec4 tcoord;                          \
52677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvarying vec2 st;                                \
53677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                                \
54677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid main()                                     \
55677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{                                               \
56677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein    gl_Position = transformMatrix * position;   \
57677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein    st = tcoord.st;                             \
58677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}                                               \
59677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein";
60677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
61677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinconst char fragment_src [] =
62677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein"                                               \
63677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinprecision highp float;                          \
64677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinuniform sampler2D tex;                          \
65677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvarying vec2 st;                                \
66677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                                \
67677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid main()                                     \
68677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{                                               \
69677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein    gl_FragColor = texture2D(tex, st);          \
70677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}                                               \
71677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein";
72677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
73677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic const GLfloat sVertData[] = {
74677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        -1, -1, 0, 1,
75677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        1, -1, 0, 1,
76677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        -1,  1, 0, 1,
77677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        1,  1, 0, 1
78677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein};
79677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
80677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
81677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function gets the available amount of carveout from sysfs.
82677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
83677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint GetCarveoutTotalSize(unsigned int *total)
84677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
85677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        FILE* f;
86677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        char buffer[256];
87677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
88677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        sprintf(buffer, "%s/heap-generic-0/total_size", SYS_ROOT);
89677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
90677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        f = fopen(buffer, "r");
91677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if(!f) {
92677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            printf("Failed to open %s", buffer);
93677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            return -1;
94677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
95677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
96677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        fscanf(f, "%d", total);
97677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        fclose(f);
98677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
99677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return 0;
100677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
101677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
102677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
103677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function gets the free amount of carveout from sysfs.
104677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
105677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint GetCarveoutFreeSize(unsigned int *free)
106677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
107677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        FILE* f;
108677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        char buffer[256];
109677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
110677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        sprintf(buffer, "%s/heap-generic-0/free_size", SYS_ROOT);
111677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
112677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /*
113677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * Make sure all previous rendering calls have completed so we
114677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * can query free carveout size
115677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         */
116677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glFinish();
117677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
118677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        f = fopen(buffer, "r");
119677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if(!f) {
120677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            printf("Failed to open %s", buffer);
121677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            return -1;
122677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
123677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
124677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        fscanf(f, "%d", free);
125677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        fclose(f);
126677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
127677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return 0;
128677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
129677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
130677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
131677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function creates an RGBA texture with a given width and height.
132677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Return value: handle to texture
133677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
134677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic GLuint CreateTexture(int width, int height, int number)
135677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
136677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        char *data = NULL;
137677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int x, y, bytesPerPixel;
138677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint tex;
139677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
140677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        assert(number == (number & 0xF));
141677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
142677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* There are 4 bytes per pixel for GL_RGBA & GL_UNSIGNED_BYTE */
143677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        bytesPerPixel = 4;
144677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
145677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        data = (char *)malloc((size_t)(width*height*bytesPerPixel));
146677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (!data)
147677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
148677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
149677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (x = 0; x < width; x++) {
150677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                for (y = 0 ; y < height; y++) {
151677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        int idx = (y*width + x)*bytesPerPixel;
152677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        data[idx] = (number * 0xF) & 0xFF;
153677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        data[idx+1] = (number * 0xF) & 0xFF;
154677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        data[idx+2] = 0xFF;
155677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        data[idx+3] = 0xFF;
156677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
157677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
158677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
159677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* create texture */
160677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glGenTextures(1, &tex);
161677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (glGetError() != GL_NO_ERROR)
162677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
163677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
164677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glActiveTexture(GL_TEXTURE0);
165677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (glGetError() != GL_NO_ERROR)
166677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
167677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
168677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glBindTexture(GL_TEXTURE_2D, tex);
169677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (glGetError() != GL_NO_ERROR)
170677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
171677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
172677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glTexImage2D(
173677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* target */            GL_TEXTURE_2D,
174677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* level */             0,
175677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* internalformat */    (GLint)GL_RGBA,
176677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* width */             width,
177677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* height */            height,
178677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* border */            0,
179677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* format */            GL_RGBA,
180677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* type */              GL_UNSIGNED_BYTE,
181677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* pixels */            data);
182677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
183677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
184677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
185677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
186677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        goto done;
187677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
188677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinfail:
189677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        tex = -1;
190677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleindone:
191677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        free(data);
192677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
193677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return tex;
194677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
195677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
196677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
197677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Fill in the result array with an identity matrix.
198677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
199677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic void LoadIdentity(GLfloat *result)
200677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
201677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        memset(result, 0x0, 16*4);
202677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[0] = 1;
203677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[5] = 1;
204677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[10] = 1;
205677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[15] = 1;
206677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
207677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
208677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
209677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Fill in the result array with a scaling matrix.
210677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
211677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic void Scale(GLfloat *result, GLfloat sx, GLfloat sy, GLfloat sz)
212677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
213677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[0] *= sx;
214677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[1] *= sx;
215677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[2] *= sx;
216677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[3] *= sx;
217677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
218677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[4] *= sy;
219677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[5] *= sy;
220677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[6] *= sy;
221677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[7] *= sy;
222677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
223677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[8] *= sz;
224677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[9] *= sz;
225677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[10] *= sz;
226677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[11] *= sz;
227677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
228677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
229677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
230677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Fill in the result array with a transformation matrix.
231677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
232677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic void Translate(GLfloat *result, GLfloat tx, GLfloat ty, GLfloat tz)
233677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
234677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[12] += (result[0] * tx + result[4] * ty + result[8] * tz);
235677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[13] += (result[1] * tx + result[5] * ty + result[9] * tz);
236677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[14] += (result[2] * tx + result[6] * ty + result[10] * tz);
237677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        result[15] += (result[3] * tx + result[7] * ty + result[11] * tz);
238677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
239677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
240677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
241677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function takes a given texture array and displays the textures in it.
242677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * All textures need to be the same size, width x height.
243677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
244677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint ShowTextures(GLuint *tex, int count, int width, int height)
245677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
246677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLint texSampler;
247677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLint transformMatrixUniform;
248677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLfloat vertSTData[8];
249677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int i;
250677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLfloat transformMatrix[16];
251677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int cols = (int)sqrtf(count);
252677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        struct timeval tv;
253677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int rnd;
254677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
255677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        gettimeofday(&tv, NULL);
256677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        rnd = tv.tv_sec * 1000;
257677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
258677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Texture coords */
259677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[0] = 0;
260677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[1] = 0;
261677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[2] = width;
262677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[3] = 0;
263677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[4] = 0;
264677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[5] = height;
265677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[6] = width;
266677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vertSTData[7] = height;
267677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
268677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, vertSTData);
269677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        texSampler = glGetUniformLocation(programObj, "tex");
270677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        transformMatrixUniform = glGetUniformLocation(programObj,
271677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                        "transformMatrix");
272677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glUniform1i(texSampler, 0);
273677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
274677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Draw texture rectangles */
275677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        LoadIdentity(transformMatrix);
276677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        Scale(transformMatrix, 4.0f/cols, 4.0f/cols, 4.0f/cols);
277677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        Translate(transformMatrix, -cols - 1.0f, cols - 1.0f, 0.0f);
278677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < count; i++) {
279677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            rnd = rnd * 69069 + 69069;
280677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            if(((rnd / 1217) & 255) > 128) {
281677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                Translate(transformMatrix, 2.0f, 0.0f, 0.0f);
282677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glUniformMatrix4fv(transformMatrixUniform, 1, GL_FALSE,
283677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                        transformMatrix);
284677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glBindTexture(GL_TEXTURE_2D, tex[i]);
285677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
286677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (((i+1) % cols) == 0) {
287677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                    Translate(transformMatrix, -2.0f*cols, -2.0f,
288677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                0.0f);
289677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
290677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            }
291677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
292677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
293677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Issue flush to ensure all gl commands are sent to processing */
294677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glFlush();
295677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
296677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return 0;
297677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
298677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
299677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
300677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function runs a single phase of the test.
301677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Return value: 0 on success
302677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
303677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint RunPhase(int phase, int phase_width, int phase_height, int texture_count,
304677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                int texture_size, GLuint *tex)
305677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
306677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int phase_size = texture_count * texture_size;
307677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int freeBefore, freeAfter;
308677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLenum errCode = GL_NO_ERROR;
309677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int brokeAt = 0;
310677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int displacement;
311677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int i;
312677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
313677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("%.*s\n", 48, space);
314677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("Phase %d: Allocating small %d (%dMB) [%dMB] textures\n",
315677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        phase, texture_count, texture_size,
316677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        texture_count * texture_size);
317677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("%.*s\n", 48, space);
318677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
319677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Create texture */
320677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("allocating textures.. (%d,%d)\n", phase_width, phase_height);
321677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GetCarveoutFreeSize(&freeBefore);
322677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < texture_count; i++) {
323677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                tex[i] = CreateTexture(phase_width - 1, phase_height - 1,
324677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                        (i % 16));
325677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
326677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (tex[i] < 0) {
327677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        printf("Failed to create texture.\n");
328677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        brokeAt = i;
329677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        goto done;
330677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
331677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
332677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                errCode = glGetError();
333677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (errCode != GL_NO_ERROR) {
334677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        printf("GL Error Occured : %d\n", errCode);
335677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        brokeAt = i;
336677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        goto done;
337677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
338677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
339677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
340677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GetCarveoutFreeSize(&freeAfter);
341677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Calculate difference in MB */
342677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        displacement = (freeBefore - freeAfter) / (1024 * 1024);
343677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
344677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (displacement < phase_size) {
345677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL to alloc required mem from carveout.\n");
346677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "Allocated %dMB instead of desired %dMB\n",
347677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        displacement, phase_size);
348677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                brokeAt = texture_count - 1;
349677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto done;
350677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
351677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
352677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose) {
353677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                unsigned int free;
354677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                GetCarveoutFreeSize(&free);
355677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("CarveOut free after phase %d allocation: %d\n",
356677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        phase, free);
357677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
358677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
359677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleindone:
360677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return brokeAt; /* brokeAt is 0 unless and error happened */
361677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
362677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
363677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
364677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function runs the actual test, drawing the texture rects.
365677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * Return value: 0 on success
366677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
367677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint RunTest(int carveout_percent)
368677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
369677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint phase1_tex[ALLOC_COUNT_MAX];
370677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint phase2_tex[ALLOC_COUNT_MAX / 4];
371677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint phase3_tex[ALLOC_COUNT_MAX / 8];
372677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int i;
373677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int allocCount = 0;
374677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int carveoutTotal;
375677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        unsigned int carveoutFree;
376677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int allocatedMemoryLimit;
377677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLenum errCode = GL_NO_ERROR;
378677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int phase = 0;
379677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int brokeAt = 0;
380677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
381677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if(GetCarveoutTotalSize(&carveoutTotal) ||
382677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein           GetCarveoutFreeSize(&carveoutFree)) {
383677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Failed to read carveout stats\n");
384677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
385677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
386677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
387677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("CarveOut total before cleanup: %d [%dMB]\n", carveoutTotal,
388677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                carveoutTotal / (1024*1024));
389677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("CarveOut free before cleanup: %d [%dMB]\n", carveoutFree,
390677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                carveoutFree / (1024*1024));
391677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
392677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Memory is in units of bytes */
393677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
394677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        allocatedMemoryLimit = (int)((carveoutFree / 100) * carveout_percent);
395677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        allocCount = allocatedMemoryLimit / 1048576; /* 1 mb */
396677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        allocCount = (allocCount / 4) * 4; /* always a multiple of 4. */
397677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
398677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        phase = 1;
399677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        errCode = RunPhase(phase, 512, 512, allocCount, 1, phase1_tex);
400677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (errCode) {
401677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                brokeAt = errCode;
402677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto cleanup_phase1;
403677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
404677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
405677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("freeing first 3 of every 4 textures from phase 1 [%dMB]\n",
406677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        (allocCount * 3 / 4) * 1);
407677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < allocCount; i++) {
408677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if ((i + 1) % 4 == 0) continue;
409677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glDeleteTextures(1, &phase1_tex[i]);
410677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
411677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
412677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /*
413677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * Make sure all previous rendering calls have completed so we
414677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * can query free carveout size
415677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         */
416677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glFinish();
417677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
418677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose) {
419677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                unsigned int free;
420677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                GetCarveoutFreeSize(&free);
421677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("CarveOut free after phase 1 freeing: %d\n", free);
422677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
423677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
424677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /*
425677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * prepare for phase 2
426677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * we free'd up 3/4 of the phase 1 handles, and then these will be
427677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * 4x as large, so the number will further shrink so 3/16
428677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         */
429677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        allocCount = (allocCount * 3) / 16;
430677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        phase = 2;
431677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        errCode = RunPhase(phase, 1024, 1024, allocCount, 4, phase2_tex);
432677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (errCode) {
433677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                brokeAt = errCode;
434677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto cleanup_phase2;
435677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
436677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
437677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("freeing every other texture from phase 2 [%dMB]\n",
438677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        (allocCount / 2) * 4 );
439677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < allocCount; i++) {
440677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (i % 2 != 0) continue;
441677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glDeleteTextures(1, &phase2_tex[i]);
442677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
443677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
444677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /*
445677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * Make sure all previous rendering calls have completed so we
446677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * can query free carveout size
447677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         */
448677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glFinish();
449677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
450677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose) {
451677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                unsigned int free;
452677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                GetCarveoutFreeSize(&free);
453677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("CarveOut free after phase 2 freeing: %d\n", free);
454677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
455677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
456677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /*
457677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * prepare for phase 3
458677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * we free'd up 1/2 of the phase 2 handles, and then these will be
459677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         * 2x as large, so the number will further shrink so 1/4
460677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein         */
461677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        allocCount = (allocCount / 4);
462677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        phase = 3;
463677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        errCode = RunPhase(phase, 2048, 1024, allocCount, 8, phase3_tex);
464677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (errCode) {
465677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                brokeAt = errCode;
466677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto cleanup_phase3;
467677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
468677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
469677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("%.*s\n", 48, space);
470677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("Test Complete \n");
471677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("%.*s\n", 48, space);
472677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
473677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleincleanup_phase3:
474677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("freeing last textures from phase 3\n");
475677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < (brokeAt ? brokeAt : allocCount); i++)
476677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glDeleteTextures(1, &phase3_tex[i]);
477677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
478677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleincleanup_phase2:
479677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("freeing last textures from phase 2\n");
480677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (phase == 2 && errCode != GL_NO_ERROR)
481677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                for (i = 0; i < (brokeAt ? brokeAt : allocCount); i++)
482677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        glDeleteTextures(1, &phase2_tex[i]);
483677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        else
484677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                for (i = 0; i < allocCount; i += 2)
485677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        glDeleteTextures(1, &phase2_tex[i]);
486677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
487677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleincleanup_phase1:
488677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("freeing last textures from phase 1\n");
489677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (phase == 1 && errCode != GL_NO_ERROR)
490677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                for (i = 0; i < (brokeAt ? brokeAt : allocCount); i++)
491677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        glDeleteTextures(1, &phase1_tex[i]);
492677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        else
493677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                for (i = 3; i < allocCount; i += 4)
494677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        glDeleteTextures(1, &phase1_tex[i]);
495677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
496677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return (errCode == GL_NO_ERROR ? 0 : -1);
497677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
498677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
499677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein/*
500677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein * This function prints the info log for a given shader (from handle).
501677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein */
502677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid PrintShaderInfoLog(GLuint shader)
503677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
504677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLint        length;
505677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
506677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
507677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
508677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (length) {
509677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                char buffer[length];
510677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glGetShaderInfoLog(shader, length, NULL, buffer);
511677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("shader info: %s\n", buffer);
512677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
513677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
514677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
515677ef98db2329cfeaea67101993f90800ae78e99Rhyland KleinGLuint LoadShader(const char *shader_src, GLenum type)
516677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
517677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint        shader = glCreateShader(type);
518677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLint         success;
519677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
520677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glShaderSource(shader, 1, &shader_src, NULL);
521677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glCompileShader(shader);
522677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
523677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (success != GL_TRUE) {
524677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAILED to compile shader. %d\n", success);
525677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return success;
526677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
527677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
528677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose)
529677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                PrintShaderInfoLog(shader);
530677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
531677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return shader;
532677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
533677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
534677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinstatic void InitGraphicsState()
535677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
536677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, sVertData);
537677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glEnableVertexAttribArray(0);
538677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glEnableVertexAttribArray(1);
539677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
540677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        vsObj = LoadShader(vertex_src, GL_VERTEX_SHADER);
541677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        fsObj = LoadShader(fragment_src, GL_FRAGMENT_SHADER);
542677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
543677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        programObj = glCreateProgram();
544677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glAttachShader(programObj, vsObj);
545677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glAttachShader(programObj, fsObj);
546677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glBindAttribLocation(programObj, 0, "position");
547677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glBindAttribLocation(programObj, 1, "tcoord");
548677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glLinkProgram(programObj);
549677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glUseProgram(programObj);
550677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
551677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* so that odd-sized RGB textures will work nicely */
552677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
553677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
554677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glDisable(GL_DEPTH_TEST);
555677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
556677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
557677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid CleanupX()
558677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
559677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        XDestroyWindow(x_display, win);
560677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        XCloseDisplay(x_display);
561677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
562677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
563677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid CleanupEgl()
564677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
565677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        eglDestroyContext(egl_display, egl_context);
566677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        eglDestroySurface(egl_display, egl_surface);
567677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        eglTerminate(egl_display);
568677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
569677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
570677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint XInitialize(int x, int y, int width, int height)
571677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
572677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        Window                         root;
573677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        XSetWindowAttributes         swa;
574677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        XSetWindowAttributes         xattr;
575677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        Atom                         atom;
576677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        XWMHints                     hints;
577677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int                             xres;
578677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
579677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        x_display = XOpenDisplay(NULL);
580677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (x_display == NULL) {
581677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Cannot connect to X server. Exiting...\n");
582677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
583677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
584677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
585677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        root = DefaultRootWindow(x_display);
586677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;
587677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
588677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose)
589677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Creating window at (%d,%d) with w=%d, h=%d\n",
590677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        x, y, width, height);
591677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
592677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        win = XCreateWindow(
593677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* connection to x server */      x_display,
594677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* parent window */               root,
595677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* x coord, top left corner */    x,
596677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* y coord, top left corner */    y,
597677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* width of window */             width,
598677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* height of window */            height,
599677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* border width */                0,
600677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* depth of window */             CopyFromParent,
601677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* window's class */              InputOutput,
602677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* visual type */                 CopyFromParent,
603677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* valid attribute mask */        CWEventMask,
604677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* attributes */                  &swa);
605677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (win == BadAlloc ||
606677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadColor ||
607677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadCursor ||
608677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadMatch ||
609677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadPixmap ||
610677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadValue ||
611677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            win == BadWindow) {
612677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAILED to create X window\n");
613677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
614677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
615677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
616677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        xattr.override_redirect = false;
617677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        xres = XChangeWindowAttributes(x_display, win, CWOverrideRedirect,
618677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                        &xattr);
619677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (xres == BadAccess ||
620677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadColor ||
621677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadCursor ||
622677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadMatch ||
623677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadPixmap ||
624677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadValue ||
625677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein            xres == BadWindow) {
626677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL changing X win attribs: %d\n", xres);
627677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
628677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
629677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
630677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        atom = XInternAtom(x_display, "_NET_WM_STATE_FULLSCREEN", true);
631677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
632677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        hints.input = true;
633677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        hints.flags = InputHint;
634677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        xres = XSetWMHints(x_display, win, &hints);
635677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (xres == BadAlloc || xres == BadWindow) {
636677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL setting X WM hints: %d\n", xres);
637677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
638677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
639677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
640677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        xres = XMapWindow(x_display, win);
641677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (xres == BadAlloc || xres == BadWindow ) {
642677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL mapping X window: %d\n", xres);
643677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
644677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
645677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
646677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        xres = XStoreName(x_display, win, "GLES2 Texture Test");
647677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (xres == BadAlloc || xres == BadWindow) {
648677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL storing X window name: %d\n", xres);
649677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto fail;
650677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
651677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
652677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return 0;
653677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
654677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinfail:
655677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        CleanupX();
656677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
657677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return -1;
658677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
659677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
660677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
661677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint EglInitialize()
662677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
663677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        EGLConfig        config;
664677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        EGLint                numConfig;
665677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
666677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        EGLint        attr[] = {
667677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_BUFFER_SIZE, 16,
668677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_RENDERABLE_TYPE,
669677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_OPENGL_ES2_BIT,
670677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_NONE
671677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        };
672677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
673677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        EGLint ctxattr[] = {
674677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_CONTEXT_CLIENT_VERSION, 2,
675677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                EGL_NONE
676677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        };
677677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
678677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        egl_display = eglGetDisplay((EGLNativeDisplayType)x_display);
679677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (egl_display == EGL_NO_DISPLAY) {
680677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed to obtain display. Exiting...\n");
681677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
682677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
683677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
684677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if ( !eglInitialize(egl_display, NULL, NULL)) {
685677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed to initialize. Exiting...\n");
686677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
687677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
688677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
689677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if ( !eglChooseConfig(egl_display, attr, &config, 1, &numConfig)) {
690677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed to choose config. Exiting...\n");
691677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
692677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
693677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
694677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (numConfig != 1) {
695677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed got %d > 1 Exiting...\n",
696677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        numConfig);
697677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
698677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
699677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
700677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        egl_surface = eglCreateWindowSurface(egl_display, config, win, NULL);
701677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (egl_surface == EGL_NO_SURFACE) {
702677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed create window surface. Exiting\n");
703677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
704677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
705677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
706677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        egl_context = eglCreateContext(egl_display, config, EGL_NO_CONTEXT,
707677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                        ctxattr);
708677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (egl_context == EGL_NO_CONTEXT) {
709677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed to create context. Exiting...\n");
710677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
711677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
712677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
713677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if ( !eglMakeCurrent(egl_display, egl_surface, egl_surface,
714677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                egl_context)) {
715677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "EGL failed make context current. Exiting\n");
716677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                return -1;
717677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
718677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
719677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return 0;
720677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
721677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
722677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinvoid PrintUsage()
723677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
724677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("--------------------------------------------\n");
725677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("nvmap_carveout_compactor [options]\n");
726677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("  -h | --help              - Show this help screen\n");
727677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("  -v | --verbose           - Enables verbose prints\n");
728677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("  -l | --loop_count        - # of times to loop [def: %d]\n",
729677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                DEFAULT_LOOP_COUNT);
730677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("  -c | --carveout_percent  - %% of free carveout [def : %d].\n",
731677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                DEFAULT_CARVEOUT_AMT);
732677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
733677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
734677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinint main(int argc, char *argv[])
735677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein{
736677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLuint fill_tex[GART_FILL_SIZE];
737677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int failure = 0;
738677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int failIndex = 0;
739677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int i;
740677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int loop_count = 1;
741677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int option_index = 0;
742677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        GLenum errCode;
743677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int x = 0, y = 0, width = WINDOW_WIDTH, height = WINDOW_HEIGHT;
744677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        int carveout_percent = 80; /* 80 percent of free carveout */
745677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
746677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        static struct option long_options[] = {
747677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                {"help",             no_argument,       0,        'h'},
748677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                {"verbose",          no_argument,       0,        'v'},
749677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                {"loop_count",       required_argument, 0,        'l'},
750677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                {"carveout_percent", required_argument, 0,        'c'},
751677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                {NULL,               0,                 NULL,     0}
752677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        };
753677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
754677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (!getenv("DISPLAY")) {
755677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "FAIL: DISPLAY env variable not set.\n");
756677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                failure = -1;
757677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto done;
758677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
759677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
760677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        while ((i = getopt_long(argc, argv, "hvl:c:", long_options,
761677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        &option_index)) != -1)
762677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                switch (i) {
763677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        case 'h':
764677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                PrintUsage();
765677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                return 0;
766677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        case 'v':
767677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                verbose = 1;
768677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                break;
769677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        case 'l':
770677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                loop_count = atoi(optarg);
771677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                break;
772677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        case 'c':
773677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                carveout_percent = atoi(optarg);
774677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                break;
775677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        case '?':
776677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                printf("unknown option `\\x%x`.\n", optopt);
777677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                return 1;
778677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        default:
779677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                goto done;
780677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
781677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
782677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        failure = XInitialize(x, y, width, height);
783677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (failure)
784677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto done;
785677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
786677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        failure = EglInitialize();
787677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (failure)
788677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto clean_x;
789677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
790677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        InitGraphicsState();
791677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
792677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glViewport(0, 0, width, height);
793677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        glClear(GL_COLOR_BUFFER_BIT);
794677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
795677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("Test started pid = %d.\n", getpid());
796677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (verbose) {
797677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Looping for %d iterations.\n", loop_count);
798677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Going to try to use %d%% of carveout during test.\n",
799677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        carveout_percent);
800677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
801677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
802677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* first need to allocate 24mb of textures to fill GART */
803677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        printf("allocating textures to fill GART.. (%d,%d)\n",
804677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                512, 512);
805677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
806677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* Each process gets 24mb of GART */
807677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < GART_FILL_SIZE; i++) {
808677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fill_tex[i] = CreateTexture(511, 511, (i % 16));
809677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
810677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                errCode = glGetError();
811677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (fill_tex[i] >= 0 && errCode == GL_NO_ERROR)
812677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        continue;
813677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
814677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                /* Some error occured when creating textures */
815677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Failed to create texture.\n");
816677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (errCode != GL_NO_ERROR)
817677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                               printf("GL Error Occured : %d\n", errCode);
818677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
819677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                failIndex = i;
820677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                failure = -1;
821677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                goto done;
822677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
823677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
824677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        ShowTextures(fill_tex, GART_FILL_SIZE, 512, 512);
825677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
826677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        /* predefined resolutions to account for size */
827677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
828677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for(i = 0; i < loop_count; i++) {
829677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                failure |= RunTest(carveout_percent);
830677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                eglSwapBuffers(egl_display, egl_surface);
831677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
832677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
833677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (!failure) {
834677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                errCode = glGetError();
835677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                if (errCode == GL_NO_ERROR)
836677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        failure = false;
837677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                else {
838677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        fprintf(stderr, "FAIL: GL Error Occured : %d\n",
839677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                                errCode);
840677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                        failure = 1;
841677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                }
842677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        }
843677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
844677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        CleanupEgl();
845677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleinclean_x:
846677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        CleanupX();
847677ef98db2329cfeaea67101993f90800ae78e99Rhyland Kleindone:
848677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
849677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        for (i = 0; i < (failIndex ? failIndex : GART_FILL_SIZE); i++)
850677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                glDeleteTextures(1, &fill_tex[i]);
851677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
852677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        if (!failure)
853677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                printf("Test completed [SUCCESS]: pid = %d\n", getpid());
854677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        else
855677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein                fprintf(stderr, "Test completed [FAIL]: pid = %d\n", getpid());
856677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
857677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein        return failure ? -1 : 0;
858677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein}
859677ef98db2329cfeaea67101993f90800ae78e99Rhyland Klein
860