1 /*
2 * Copyright (c) 2010 VMware, Inc.
3 *
4 * Permission is hereby , free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 *
24 * Test GL_EXT_texture_array and GL_MESA_texture_array.
25 * Note that the Mesa extension works with fixed-function fragment
26 * processing whereas the EXT version only works with shaders.
27 *
28 * Author: Brian Paul
29 */
30
31
32 #include "piglit-util-gl.h"
33
34 PIGLIT_GL_TEST_CONFIG_BEGIN
35
36 config.supports_gl_compat_version = 10;
37
38 config.window_width = 700;
39 config.window_height = 400;
40 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGB;
41 config.khr_no_error_support = PIGLIT_NO_ERRORS;
42
43 PIGLIT_GL_TEST_CONFIG_END
44
45 int height = 100, ybase = 0;
46
47 static const char *prog = "array-texture";
48
49 static GLboolean have_MESA_texture_array;
50
51 static GLuint array_tex_1d;
52 static GLuint array_tex_2d;
53
54 /*
55 * We'll set each texture slice to a different solid color.
56 * XXX a better test would vary the color within each slice too.
57 */
58 #define NUM_COLORS 7
59
60 static GLfloat colors[NUM_COLORS][3] = {
61 {1.0, 0.0, 0.0},
62 {0.0, 1.0, 0.0},
63 {0.0, 0.0, 1.0},
64 {0.0, 0.0, 1.0},
65 {0.0, 1.0, 0.0},
66 {1.0, 1.0, 0.0},
67 {1.0, 1.0, 1.0}
68 };
69
70
71 static const char *frag_shader_2d_array_text =
72 "#extension GL_EXT_texture_array : enable \n"
73 "uniform sampler2DArray tex; \n"
74 "void main() \n"
75 "{ \n"
76 " gl_FragColor = texture2DArray(tex, gl_TexCoord[0].xyz); \n"
77 "} \n";
78
79 static GLuint frag_shader_2d_array;
80 static GLuint program_2d_array;
81
82
83 static const char *frag_shader_1d_array_text =
84 "#extension GL_EXT_texture_array : enable \n"
85 "uniform sampler1DArray tex; \n"
86 "void main() \n"
87 "{ \n"
88 " gl_FragColor = texture1DArray(tex, gl_TexCoord[0].xy); \n"
89 "} \n";
90
91 static GLuint frag_shader_1d_array;
92 static GLuint program_1d_array;
93
94
95
96 /* debug aid */
97 static void
check_error(int line)98 check_error(int line)
99 {
100 GLenum err = glGetError();
101 if (err) {
102 printf("%s: GL error 0x%x at line %d\n", prog, err, line);
103 }
104 }
105
106
107 static GLuint
make_2d_array_texture(void)108 make_2d_array_texture(void)
109 {
110 GLfloat img[NUM_COLORS][64][32][4];
111 GLuint tex;
112 int i, j, k;
113
114 for (i = 0; i < NUM_COLORS; i++) {
115 for (j = 0; j < 64; j++) {
116 for (k = 0; k < 32; k++) {
117 img[i][j][k][0] = colors[i][0];
118 img[i][j][k][1] = colors[i][1];
119 img[i][j][k][2] = colors[i][2];
120 img[i][j][k][3] = 1.0;
121 }
122 }
123 }
124
125 glGenTextures(1, &tex);
126
127 glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, tex);
128 check_error(__LINE__);
129
130 glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA,
131 32, 64, NUM_COLORS, /* w, h, d */
132 0, /* border */
133 GL_RGBA, GL_FLOAT, img);
134
135 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
136 glTexParameteri(GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
137 check_error(__LINE__);
138
139 return tex;
140 }
141
142
143 static GLuint
make_1d_array_texture(void)144 make_1d_array_texture(void)
145 {
146 GLfloat img[NUM_COLORS][16][4];
147 GLuint tex;
148 int i, j;
149
150 for (i = 0; i < NUM_COLORS; i++) {
151 for (j = 0; j < 16; j++) {
152 img[i][j][0] = colors[i][0];
153 img[i][j][1] = colors[i][1];
154 img[i][j][2] = colors[i][2];
155 img[i][j][3] = 1.0;
156 }
157 }
158
159 glGenTextures(1, &tex);
160
161 glBindTexture(GL_TEXTURE_1D_ARRAY_EXT, tex);
162 check_error(__LINE__);
163
164 glTexImage2D(GL_TEXTURE_1D_ARRAY_EXT, 0, GL_RGBA,
165 16, NUM_COLORS, /* w, depth */
166 0, /* border */
167 GL_RGBA, GL_FLOAT, img);
168
169 glTexParameteri(GL_TEXTURE_1D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
170 glTexParameteri(GL_TEXTURE_1D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
171 check_error(__LINE__);
172
173 return tex;
174 }
175
176
177 static GLboolean
test_2d_array_texture(GLuint tex)178 test_2d_array_texture(GLuint tex)
179 {
180 GLboolean pass, ret = GL_TRUE;
181 int i;
182 float width = piglit_width / NUM_COLORS;
183 float x = 0.0;
184
185 glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, tex);
186 /* render each image in the array, check its color */
187 for (i = 0; i < NUM_COLORS; i++) {
188 GLfloat r = (GLfloat) i;
189
190 glBegin(GL_POLYGON);
191 glTexCoord3f(0, 0, r); glVertex2f(x, ybase);
192 glTexCoord3f(1, 0, r); glVertex2f(x + width, ybase);
193 glTexCoord3f(1, 1, r); glVertex2f(x + width, ybase + height);
194 glTexCoord3f(0, 1, r); glVertex2f(x, ybase + height);
195 glEnd();
196
197 pass = piglit_probe_pixel_rgb(x + (width / 2), ybase + (height / 2),
198 colors[i]);
199
200 x += width;
201 if (!pass) {
202 printf("%s: failed for 2D image/slice %d\n", prog, i);
203 }
204
205 ret &= pass;
206 }
207
208 glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
209
210 return ret;
211 }
212
213
214 static GLboolean
test_1d_array_texture(GLuint tex)215 test_1d_array_texture(GLuint tex)
216 {
217 GLboolean pass, ret = GL_TRUE;
218 int i;
219 float width = piglit_width / NUM_COLORS;
220 float x = 0.0;
221
222 glBindTexture(GL_TEXTURE_1D_ARRAY_EXT, tex);
223
224 /* render each image in the array, check its color */
225 for (i = 0; i < NUM_COLORS; i++) {
226 GLfloat r = (GLfloat) i;
227
228 glBegin(GL_POLYGON);
229 glTexCoord2f(0, r); glVertex2f(x, ybase);
230 glTexCoord2f(1, r); glVertex2f(x + width, ybase);
231 glTexCoord2f(1, r); glVertex2f(x + width, ybase + height);
232 glTexCoord2f(0, r); glVertex2f(x, ybase + height);
233 glEnd();
234
235 glFinish();
236
237 pass = piglit_probe_pixel_rgb(x + (width / 2), ybase + (height / 2),
238 colors[i]);
239
240 x += width;
241
242 if (!pass) {
243 printf("%s: failed for 1D image/slice %d\n", prog, i);
244 }
245
246 ret &= pass;
247 }
248
249 glBindTexture(GL_TEXTURE_1D_ARRAY_EXT, 0);
250
251 return ret;
252 }
253
254
255 enum piglit_result
piglit_display(void)256 piglit_display(void)
257 {
258 GLboolean pass = GL_TRUE;
259 GLint loc;
260
261 if (!frag_shader_2d_array) {
262 printf("%s: failed to compile 2D fragment shader.\n", prog);
263 return PIGLIT_FAIL;
264 }
265
266 if (!program_2d_array) {
267 printf("%s: failed to link 2D shader program.\n", prog);
268 return PIGLIT_FAIL;
269 }
270
271 if (!frag_shader_1d_array) {
272 printf("%s: failed to compile 1D fragment shader.\n", prog);
273 return PIGLIT_FAIL;
274 }
275
276 if (!program_1d_array) {
277 printf("%s: failed to link 1D shader program.\n", prog);
278 return PIGLIT_FAIL;
279 }
280
281
282 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
283
284 ybase = 0;
285 /*
286 * Test 2d array texture with fragment shader
287 */
288 {
289 glClear(GL_COLOR_BUFFER_BIT);
290 glUseProgram(program_2d_array);
291 loc = glGetUniformLocation(program_2d_array, "tex");
292 glUniform1i(loc, 0); /* texture unit p */
293 pass &= test_2d_array_texture(array_tex_2d);
294 glUseProgram(0);
295 }
296
297 ybase = 100;
298 /*
299 * Test 2d array texture with fixed function
300 */
301 if (have_MESA_texture_array) {
302 glEnable(GL_TEXTURE_2D_ARRAY_EXT);
303 check_error(__LINE__);
304 pass &= test_2d_array_texture(array_tex_2d);
305 glDisable(GL_TEXTURE_2D_ARRAY_EXT);
306 check_error(__LINE__);
307 }
308
309 ybase = 200;
310 /*
311 * Test 1d array texture with fragment shader
312 */
313 {
314 glUseProgram(program_1d_array);
315 loc = glGetUniformLocation(program_1d_array, "tex");
316 glUniform1i(loc, 0); /* texture unit p */
317 pass &= test_1d_array_texture(array_tex_1d);
318 glUseProgram(0);
319 }
320
321 ybase = 300;
322 /*
323 * Test 1d array texture with fixed function
324 */
325 if (have_MESA_texture_array) {
326 glEnable(GL_TEXTURE_1D_ARRAY_EXT);
327 check_error(__LINE__);
328 pass &= test_1d_array_texture(array_tex_1d);
329 glDisable(GL_TEXTURE_1D_ARRAY_EXT);
330 check_error(__LINE__);
331 }
332
333 piglit_present_results();
334 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
335 }
336
337
338 void
piglit_init(int argc,char ** argv)339 piglit_init(int argc, char **argv)
340 {
341 piglit_require_extension("GL_EXT_texture_array");
342
343 have_MESA_texture_array = piglit_is_extension_supported("GL_MESA_texture_array");
344
345 /* Make shader programs */
346 frag_shader_2d_array =
347 piglit_compile_shader_text(GL_FRAGMENT_SHADER,
348 frag_shader_2d_array_text);
349 check_error(__LINE__);
350
351 program_2d_array = piglit_link_simple_program(0, frag_shader_2d_array);
352 check_error(__LINE__);
353
354 frag_shader_1d_array =
355 piglit_compile_shader_text(GL_FRAGMENT_SHADER,
356 frag_shader_1d_array_text);
357 check_error(__LINE__);
358
359 program_1d_array = piglit_link_simple_program(0, frag_shader_1d_array);
360 check_error(__LINE__);
361
362 /* make array textures */
363 array_tex_2d = make_2d_array_texture();
364 array_tex_1d = make_1d_array_texture();
365 }
366