2 * Copyright © 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 * Chris Lord <chris@openedhand.com>
25 * Eric Anholt <eric@anholt.net>
29 /** @file s3tc-teximage.c
31 * Tests that a full S3TC-compressed mipmap tree can be created and
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 #ifdef PIGLIT_USE_OPENGL
40 config
.supports_gl_compat_version
= 11;
41 #else // PIGLIT_USE_OPENGL_ES2
42 config
.supports_gl_es_version
= 20;
45 config
.window_width
= 500;
46 config
.window_height
= 600;
47 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
48 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
50 PIGLIT_GL_TEST_CONFIG_END
54 const float red
[4] = {1.0, 0.0, 0.0, 1.0};
55 const float green
[4] = {0.0, 1.0, 0.0, 1.0};
56 const float blue
[4] = {0.0, 0.0, 1.0, 1.0};
57 const float white
[4] = {1.0, 1.0, 1.0, 1.0};
59 #ifdef PIGLIT_USE_OPENGL_ES2
61 const char *vs_source
=
63 "attribute vec4 piglit_vertex;\n"
64 "attribute vec2 piglit_texcoord;\n"
65 "varying mediump vec2 tex_coord;\n"
66 "uniform mat4 proj;\n"
70 " gl_Position = proj * piglit_vertex;\n"
71 " tex_coord = piglit_texcoord;\n"
74 const char *fs_source
=
76 "varying mediump vec2 tex_coord;\n"
77 "uniform sampler2D tex;\n"
81 " gl_FragColor = texture2D(tex, tex_coord);\n"
84 #include "piglit-matrix.h"
91 display_mipmaps(int start_x
, int start_y
)
95 #ifdef PIGLIT_USE_OPENGL
96 glEnable(GL_TEXTURE_2D
);
99 /* Display all the mipmap levels */
100 for (i
= SIZE
; i
> 0; i
/= 2) {
101 piglit_draw_rect_tex(start_x
, start_y
, i
, i
,
102 0.0f
, 0.0f
, 1.0f
, 1.0f
);
108 create_texture(GLenum format
)
111 int size
, x
, y
, level
;
114 glGenTextures(1, &tex
);
115 glBindTexture(GL_TEXTURE_2D
, tex
);
116 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
117 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
118 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
119 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
120 GL_LINEAR_MIPMAP_NEAREST
);
121 data
= malloc(SIZE
* SIZE
* 4 * sizeof(GLfloat
));
123 for (level
= 0, size
= SIZE
; size
> 0; level
++, size
>>= 1) {
124 for (y
= 0; y
< size
; y
++) {
125 for (x
= 0; x
< size
; x
++) {
134 else if (x
< size
/ 2 && y
< size
/ 2)
136 else if (y
< size
/ 2)
138 else if (x
< size
/ 2)
143 memcpy(data
+ (y
* size
+ x
) * 4, color
,
148 /* Create empty texture */
149 glTexImage2D(GL_TEXTURE_2D
, level
, format
,
151 GL_RGBA
, GL_FLOAT
, NULL
);
153 glPixelStorei(GL_UNPACK_ROW_LENGTH
, size
);
155 /* Fill in sub regions of texture */
157 glTexSubImage2D(GL_TEXTURE_2D
, level
,
159 GL_RGBA
, GL_FLOAT
, data
);
162 float *greens
= data
+ size
/ 2 * 4;
163 float *blues
= reds
+ (size
/ 2) * size
* 4;
164 float *whites
= blues
+ size
/ 2 * 4;
166 glTexSubImage2D(GL_TEXTURE_2D
, level
,
169 GL_RGBA
, GL_FLOAT
, reds
);
170 glTexSubImage2D(GL_TEXTURE_2D
, level
,
173 GL_RGBA
, GL_FLOAT
, greens
);
174 glTexSubImage2D(GL_TEXTURE_2D
, level
,
177 GL_RGBA
, GL_FLOAT
, blues
);
178 glTexSubImage2D(GL_TEXTURE_2D
, level
,
181 GL_RGBA
, GL_FLOAT
, whites
);
189 check_resulting_mipmaps(int x
, int y
)
191 GLboolean pass
= GL_TRUE
;
194 for (size
= SIZE
; size
> 0; size
/= 2) {
196 pass
= pass
&& piglit_probe_pixel_rgb(x
+ 2, y
+ 2,
199 pass
= pass
&& piglit_probe_pixel_rgb(x
+ 1, y
+ 1,
202 pass
= pass
&& piglit_probe_pixel_rgb(x
, y
,
205 pass
= pass
&& piglit_probe_pixel_rgb(x
+ size
/ 4,
208 pass
= pass
&& piglit_probe_pixel_rgb(x
+ size
* 3 / 4,
211 pass
= pass
&& piglit_probe_pixel_rgb(x
+ size
/ 4,
214 pass
= pass
&& piglit_probe_pixel_rgb(x
+ size
* 3 / 4,
228 GLboolean pass
= GL_TRUE
;
230 glClearColor(0, 0, 0, 0);
231 glClear(GL_COLOR_BUFFER_BIT
);
233 tex
= create_texture(GL_COMPRESSED_RGB_S3TC_DXT1_EXT
);
234 display_mipmaps(10, 10 + (10 + SIZE
) * 0);
235 glDeleteTextures(1, &tex
);
236 tex
= create_texture(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
);
237 display_mipmaps(10, 10 + (10 + SIZE
) * 1);
238 glDeleteTextures(1, &tex
);
239 tex
= create_texture(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
);
240 display_mipmaps(10, 10 + (10 + SIZE
) * 2);
241 glDeleteTextures(1, &tex
);
242 tex
= create_texture(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
);
243 display_mipmaps(10, 10 + (10 + SIZE
) * 3);
244 glDeleteTextures(1, &tex
);
246 pass
= pass
&& check_resulting_mipmaps(10, 10 + (10 + SIZE
) * 0);
247 pass
= pass
&& check_resulting_mipmaps(10, 10 + (10 + SIZE
) * 1);
248 pass
= pass
&& check_resulting_mipmaps(10, 10 + (10 + SIZE
) * 2);
249 pass
= pass
&& check_resulting_mipmaps(10, 10 + (10 + SIZE
) * 3);
251 piglit_present_results();
253 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
257 piglit_init(int argc
, char **argv
)
259 piglit_require_extension("GL_EXT_texture_compression_s3tc");
261 #ifdef PIGLIT_USE_OPENGL
263 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
265 #else // PIGLIT_USE_OPENGL_ES2
267 tex_program
= piglit_build_simple_program(vs_source
, fs_source
);
268 glUseProgram(tex_program
);
269 GLint proj_loc
= glGetUniformLocation(tex_program
, "proj");
270 piglit_ortho_uniform(proj_loc
, piglit_width
, piglit_height
);