2 * Copyright © 2012 Red Hat
4 * Permission is hereby granted, 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:
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
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
29 * arb_texture_cube_map_array-cubemap-lod
31 * This constructs a two layer mipmapped cube array, and tests
32 * setting an explicit lod to layer 3 and a lod bias of 3.0
33 * samples from the correct levels/layers, across both layers
37 #include "piglit-util-gl.h"
43 PIGLIT_GL_TEST_CONFIG_BEGIN
45 config
.supports_gl_compat_version
= 10;
47 config
.window_width
= (64 * 6 + PAD
* 9) * 2;
48 config
.window_height
= 200*NUM_LAYERS
;
49 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGB
;
50 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
52 PIGLIT_GL_TEST_CONFIG_END
56 static const GLfloat colors
[][3] = {
66 /* we need a larger size than the common code so just copy them in */
67 GLfloat a_cube_face_texcoords
[6][4][4];
69 void setup_texcoords(void)
72 for (i
= 0; i
< 6; i
++) {
73 for (j
= 0; j
< 4; j
++) {
74 memcpy(a_cube_face_texcoords
[i
][j
], cube_face_texcoords
[i
][j
], 3 * sizeof(GLfloat
));
79 static const char *frag_shader_biased
=
80 "#extension GL_ARB_texture_cube_map_array : enable\n"
81 "uniform samplerCubeArray tex; \n"
84 " gl_FragColor = texture(tex, gl_TexCoord[0], 3.0);\n"
87 static const char *frag_shader_explicit
=
88 "#extension GL_ARB_texture_cube_map_array : enable\n"
89 "uniform samplerCubeArray tex; \n"
92 " gl_FragColor = textureLod(tex, gl_TexCoord[0], 3.0);\n"
95 static GLuint frag_shader_cube_array_biased
;
96 static GLuint program_cube_array_biased
;
97 static GLuint frag_shader_cube_array_explicit
;
98 static GLuint program_cube_array_explicit
;
101 set_image(int level
, int size
, int *color
)
103 const GLfloat
*color1
;
104 const GLfloat
*color2
;
110 face_size
= size
* size
* 3;
111 tex
= malloc(NUM_LAYERS
* 6 * face_size
* sizeof(GLfloat
));
113 for (face
= 0; face
< NUM_LAYERS
* 6; face
++) {
115 *color
= (level
+ (face
/ 6)) % ARRAY_SIZE(colors
);
117 color1
= colors
[*color
];
118 color2
= colors
[(*color
+ 1) % ARRAY_SIZE(colors
)];
120 /* Set the texture for this face to one corner being color2 and the
121 * rest color1. If the texture is 1x1, then it's all color1.
123 for (y
= 0; y
< size
; y
++) {
124 for (x
= 0; x
< size
; x
++) {
125 const GLfloat
*chosen_color
;
127 if (y
>= (size
/ 2) || x
>= (size
/ 2))
128 chosen_color
= color1
;
130 chosen_color
= color2
;
132 tex
[(face
* face_size
) + (y
* size
+ x
) * 3 + 0] = chosen_color
[0];
133 tex
[(face
* face_size
) + (y
* size
+ x
) * 3 + 1] = chosen_color
[1];
134 tex
[(face
* face_size
) + (y
* size
+ x
) * 3 + 2] = chosen_color
[2];
138 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY
, level
, GL_RGB
, size
, size
, 6 * NUM_LAYERS
, 0, GL_RGB
, GL_FLOAT
, tex
);
144 * Tests that the mipmap drawn at (x,y)-(x+size,y+size) has the majority color,
145 * with color+1 in bottom left.
148 test_results(int x
, int y
, int size
, int level
, int face
, bool biased
,
149 int color
, int layer
, int maxlevel
)
151 const GLfloat
*color1
= colors
[color
];
152 const GLfloat
*color2
= colors
[(color
+ 1) % ARRAY_SIZE(colors
)];
154 int x1
= x
+ size
/ 4, x2
= x
+ size
* 3 / 4;
155 int y1
= y
+ size
/ 4, y2
= y
+ size
* 3 / 4;
157 if (level
>= maxlevel
)
161 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y1
, color1
);
163 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y1
, color2
);
164 pass
= pass
&& piglit_probe_pixel_rgb(x2
, y1
, color1
);
165 pass
= pass
&& piglit_probe_pixel_rgb(x2
, y2
, color1
);
166 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y2
, color1
);
170 int base_size
= size
* (1 << level
);
171 printf("Cube map failed at size %dx%d, level %d (%dx%d), face %s%s\n",
172 base_size
, base_size
, level
, size
, size
,
173 cube_face_names
[face
],
174 biased
? ", biased" : "");
181 draw_at_size(int size
, int x_offset
, int y_offset
,
184 GLfloat row_y
= PAD
+ y_offset
;
186 int color
= 0, level
= 0, maxlevel
, baselevel
= 3;
192 glUseProgram(program_cube_array_biased
);
193 loc
= glGetUniformLocation(program_cube_array_biased
, "tex");
195 glUseProgram(program_cube_array_explicit
);
196 loc
= glGetUniformLocation(program_cube_array_explicit
, "tex");
198 glUniform1i(loc
, 0); /* texture unit p */
200 /* Create the texture. */
201 glGenTextures(1, &texname
);
202 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY_ARB
, texname
);
204 /* For each face drawing, we want to only see that face's contents at
207 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY_ARB
,
208 GL_TEXTURE_MIN_FILTER
,
209 GL_NEAREST_MIPMAP_NEAREST
);
210 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY_ARB
,
211 GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
212 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY_ARB
,
213 GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
214 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY_ARB
,
215 GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
217 /* Fill in faces on each level */
218 for (dim
= size
; dim
> 0; dim
/= 2) {
219 set_image(level
, dim
, &color
);
223 if (maxlevel
>= ARRAY_SIZE(colors
))
224 maxlevel
= ARRAY_SIZE(colors
) - 1;
228 for (dim
= size
; dim
> 0; dim
/= 2) {
229 GLfloat row_x
= PAD
+ x_offset
;
233 for (face
= 0; face
< 6 * NUM_LAYERS
; face
++) {
234 GLint realface
= face
% 6;
235 GLint layer
= face
/ 6;
236 GLfloat base_x
= row_x
+ realface
* (max_size
+ PAD
);
237 GLfloat base_y
= row_y
+ (200 * layer
);
241 if (color
>= ARRAY_SIZE(colors
))
242 color
= ARRAY_SIZE(colors
) - 1;
244 color
%= ARRAY_SIZE(colors
);
248 a_cube_face_texcoords
[realface
][0][3] = layer
;
249 a_cube_face_texcoords
[realface
][1][3] = layer
;
250 a_cube_face_texcoords
[realface
][2][3] = layer
;
251 a_cube_face_texcoords
[realface
][3][3] = layer
;
253 glTexCoord4fv(a_cube_face_texcoords
[realface
][0]);
254 glVertex2f(base_x
, base_y
);
256 glTexCoord4fv(a_cube_face_texcoords
[realface
][1]);
257 glVertex2f(base_x
+ dim
, base_y
);
259 glTexCoord4fv(a_cube_face_texcoords
[realface
][2]);
260 glVertex2f(base_x
+ dim
, base_y
+ dim
);
262 glTexCoord4fv(a_cube_face_texcoords
[realface
][3]);
263 glVertex2f(base_x
, base_y
+ dim
);
268 pass
= test_results(base_x
, base_y
,
269 dim
, level
, realface
,
271 color
, layer
, maxlevel
) && pass
;
278 if (level
> maxlevel
)
282 glDeleteTextures(1, &texname
);
294 int i
= 0, y_offset
= 0;
298 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
300 /* Clear background to gray */
301 glClearColor(0.5, 0.5, 0.5, 1.0);
302 glClear(GL_COLOR_BUFFER_BIT
);
304 /* Next, do each size with mipmaps from MAX_SIZExMAX_SIZE
309 for (dim
= max_size
; dim
> max_size
/2; dim
/= 2) {
310 int x_offset
= (i
% 2 == 0) ? 0 : piglit_width
/ 2;
312 row_dim
= (row_dim
< dim
) ? dim
: row_dim
;
314 pass
&= draw_at_size(dim
, x_offset
, y_offset
, biased
);
316 y_offset
+= row_dim
* 2 + (ffs(dim
) + 3) * PAD
;
322 if (biased
== false) {
326 piglit_present_results();
328 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
332 piglit_init(int argc
, char **argv
)
336 piglit_require_extension("GL_ARB_texture_cube_map_array");
340 for (i
= 1; i
< argc
; i
++) {
341 if (strcmp(argv
[i
], "npot") == 0) {
342 piglit_require_extension("GL_ARB_texture_non_power_of_two");
348 frag_shader_cube_array_biased
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag_shader_biased
);
349 piglit_check_gl_error(GL_NO_ERROR
);
350 program_cube_array_biased
= piglit_link_simple_program(0, frag_shader_cube_array_biased
);
351 piglit_check_gl_error(GL_NO_ERROR
);
353 frag_shader_cube_array_explicit
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag_shader_explicit
);
354 piglit_check_gl_error(GL_NO_ERROR
);
355 program_cube_array_explicit
= piglit_link_simple_program(0, frag_shader_cube_array_explicit
);
356 piglit_check_gl_error(GL_NO_ERROR
);