2 * Copyright © 2008-2009 Intel Corporation
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
24 * Eric Anholt <eric@anholt.net>
28 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
34 config
.supports_gl_compat_version
= 10;
36 config
.window_width
= (64*6+PAD
*9)*2;
37 config
.window_height
= 400;
38 config
.window_visual
= PIGLIT_GL_VISUAL_DOUBLE
| PIGLIT_GL_VISUAL_RGB
;
39 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
41 PIGLIT_GL_TEST_CONFIG_END
46 static GLfloat colors
[][3] = {
57 set_face_image(GLenum internalformat
, int level
, GLenum face
, int size
, int color
)
59 GLfloat
*color1
= colors
[color
];
60 GLfloat
*color2
= colors
[(color
+ 1) % ARRAY_SIZE(colors
)];
65 tex
= malloc(size
* size
* 3 * sizeof(GLfloat
));
67 /* Set the texture for this face to one corner being color2 and the
68 * rest color1. If the texture is 1x1, then it's all color1.
70 for (y
= 0; y
< size
; y
++) {
71 for (x
= 0; x
< size
; x
++) {
72 GLfloat
*chosen_color
;
74 if (y
>= (size
/ 2) || x
>= (size
/ 2))
75 chosen_color
= color1
;
77 chosen_color
= color2
;
79 tex
[(y
* size
+ x
) * 3 + 0] = chosen_color
[0];
80 tex
[(y
* size
+ x
) * 3 + 1] = chosen_color
[1];
81 tex
[(y
* size
+ x
) * 3 + 2] = chosen_color
[2];
86 glGenBuffers(1, &buffer
);
87 glBindBuffer(GL_PIXEL_UNPACK_BUFFER
, buffer
);
88 glBufferData(GL_PIXEL_UNPACK_BUFFER
, size
* size
* 3 * sizeof(GLfloat
),
92 glTexImage2D(face
, level
, internalformat
, size
, size
, 0, GL_RGB
, GL_FLOAT
,
93 use_pbo
? NULL
: tex
);
96 glDeleteBuffers(1, &buffer
);
102 * Tests that the mipmap drawn at (x,y)-(x+size,y+size) has the majority color,
103 * with color+1 in bottom left.
106 test_results(int x
, int y
, int size
, int level
, int face
, GLboolean mipmapped
,
109 GLfloat
*color1
= colors
[color
];
110 GLfloat
*color2
= colors
[(color
+ 1) % ARRAY_SIZE(colors
)];
111 GLboolean pass
= GL_TRUE
;
112 int x1
= x
+ size
/ 4, x2
= x
+ size
* 3 / 4;
113 int y1
= y
+ size
/ 4, y2
= y
+ size
* 3 / 4;
116 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y1
, color1
);
118 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y1
, color2
);
119 pass
= pass
&& piglit_probe_pixel_rgb(x2
, y1
, color1
);
120 pass
= pass
&& piglit_probe_pixel_rgb(x2
, y2
, color1
);
121 pass
= pass
&& piglit_probe_pixel_rgb(x1
, y2
, color1
);
125 int base_size
= size
* (1 << level
);
126 printf("Cube map failed at size %dx%d, level %d (%dx%d), face %s%s\n",
127 base_size
, base_size
, level
, size
, size
,
128 cube_face_names
[face
],
129 mipmapped
? ", mipmapped" : "");
136 draw_at_size(GLenum internalformat
, int size
, int x_offset
, int y_offset
, GLboolean mipmapped
)
138 GLfloat row_y
= PAD
+ y_offset
;
140 int color
= 0, level
= 0;
142 GLboolean pass
= GL_TRUE
;
144 /* Create the texture. */
145 glGenTextures(1, &texname
);
146 glBindTexture(GL_TEXTURE_CUBE_MAP_ARB
, texname
);
148 /* For each face drawing, we want to only see that face's contents at
152 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,
153 GL_TEXTURE_MIN_FILTER
,
154 GL_NEAREST_MIPMAP_NEAREST
);
156 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,
157 GL_TEXTURE_MIN_FILTER
,
160 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,
161 GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
162 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,
163 GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
164 glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB
,
165 GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
167 /* Fill in faces on each level */
168 for (dim
= size
; dim
> 0; dim
/= 2) {
169 for (face
= 0; face
< 6; face
++) {
170 set_face_image(internalformat
, level
, cube_face_targets
[face
],
172 color
= (color
+ 1) % ARRAY_SIZE(colors
);
180 glEnable(GL_TEXTURE_CUBE_MAP_ARB
);
184 for (dim
= size
; dim
> 0; dim
/= 2) {
185 GLfloat row_x
= PAD
+ x_offset
;
187 for (face
= 0; face
< 6; face
++) {
188 GLfloat base_x
= row_x
+ face
* (max_size
+ PAD
);
189 GLfloat base_y
= row_y
;
193 glTexCoord3fv(cube_face_texcoords
[face
][0]);
194 glVertex2f(base_x
, base_y
);
196 glTexCoord3fv(cube_face_texcoords
[face
][1]);
197 glVertex2f(base_x
+ dim
, base_y
);
199 glTexCoord3fv(cube_face_texcoords
[face
][2]);
200 glVertex2f(base_x
+ dim
, base_y
+ dim
);
202 glTexCoord3fv(cube_face_texcoords
[face
][3]);
203 glVertex2f(base_x
, base_y
+ dim
);
208 pass
= test_results(base_x
, base_y
,
214 color
= (color
+ 1) % ARRAY_SIZE(colors
);
224 glDeleteTextures(1, &texname
);
230 test_format(GLenum internalformat
)
234 int i
= 0, y_offset
= 0;
237 /* Clear background to gray */
238 glClearColor(0.5, 0.5, 0.5, 1.0);
239 glClear(GL_COLOR_BUFFER_BIT
);
241 /* First, do each size from MAX_SIZExMAX_SIZE to 1x1 as a
242 * single texture level.
245 for (dim
= max_size
; dim
> 0; dim
/= 2) {
246 pass
= draw_at_size(internalformat
, dim
, 0, y_offset
, GL_FALSE
) && pass
;
247 y_offset
+= dim
+ PAD
;
250 /* Next, do each size with mipmaps from MAX_SIZExMAX_SIZE
254 for (dim
= max_size
; dim
> 0; dim
/= 2) {
255 int x_offset
= (i
% 2 == 1) ? 0 : piglit_width
/ 2;
257 row_dim
= (row_dim
< dim
) ? dim
: row_dim
;
259 pass
&= draw_at_size(internalformat
, dim
, x_offset
, y_offset
, GL_TRUE
);
261 y_offset
+= row_dim
* 2 + (ffs(dim
) + 3) * PAD
;
273 static const GLenum internalformats
[] = {
277 GLboolean pass
= GL_TRUE
;
280 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
282 for (i
= 0; i
< ARRAY_SIZE(internalformats
); ++i
)
283 pass
= test_format(internalformats
[i
]) && pass
;
285 piglit_present_results();
287 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
291 piglit_init(int argc
, char **argv
)
295 piglit_require_extension("GL_ARB_texture_cube_map");
299 for (i
= 1; i
< argc
; i
++) {
300 if (strcmp(argv
[i
], "npot") == 0) {
301 piglit_require_extension("GL_ARB_texture_non_power_of_two");
303 } else if (strcmp(argv
[i
], "pbo") == 0) {
304 piglit_require_extension("GL_ARB_pixel_buffer_object");