2 * Copyright 2015 VMware, Inc.
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
25 * Test glGetCompressedTextureSubImage() with 2D, 2D array, cubemap, and
26 * cubemap array textures.
30 #include "piglit-util-gl.h"
32 PIGLIT_GL_TEST_CONFIG_BEGIN
33 config
.supports_gl_compat_version
= 20;
34 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
;
35 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
36 PIGLIT_GL_TEST_CONFIG_END
40 test_getsubimage(GLenum target
,
41 GLsizei width
, GLsizei height
, GLsizei numSlices
,
48 int i
, slice
, compressedSize
, compSize
;
49 int blockWidth
, blockHeight
, blockSize
;
52 int x0
, y0
, x1
, y1
, w0
, h0
, w1
, h1
;
54 printf("Testing %s %s %d x %d\n",
55 piglit_get_gl_enum_name(target
),
56 piglit_get_gl_enum_name(intFormat
),
59 /* For all S3TC formats */
60 blockWidth
= blockHeight
= 4;
61 if (intFormat
== GL_COMPRESSED_RGB_S3TC_DXT1_EXT
||
62 intFormat
== GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
) {
66 assert(intFormat
== GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
||
67 intFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
);
71 /* Size must be multiple of block dims */
72 assert(width
% blockWidth
== 0);
73 assert(height
% blockHeight
== 0);
75 compressedSize
= (width
/ blockWidth
) * (height
/ blockHeight
)
78 printf("byte per block row: %d\n",
79 (width
/ blockWidth
) * blockSize
);
80 printf("compressed image size = %d\n", compressedSize
);
83 /* initial texture data */
84 texData
= malloc(compressedSize
);
85 for (i
= 0; i
< compressedSize
; i
++) {
86 texData
[i
] = (i
+10) & 0xff;
89 glGenTextures(1, &tex
);
90 glBindTexture(target
, tex
);
92 /* Define texture image */
93 if (target
== GL_TEXTURE_CUBE_MAP
) {
94 for (slice
= 0; slice
< 6; slice
++) {
95 glCompressedTexImage2D(
96 GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ slice
,
97 level
, intFormat
, width
, height
, 0,
98 compressedSize
, texData
);
100 glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X
, level
,
101 GL_TEXTURE_COMPRESSED_IMAGE_SIZE
,
103 assert(numSlices
== 6);
105 else if (target
== GL_TEXTURE_CUBE_MAP_ARRAY
) {
106 assert(numSlices
% 6 == 0);
107 glCompressedTexImage3D(target
, level
, intFormat
,
108 width
, height
, numSlices
, 0,
109 compressedSize
* numSlices
, NULL
);
110 for (slice
= 0; slice
< numSlices
; slice
++) {
111 glCompressedTexSubImage3D(target
, level
,
115 compressedSize
, texData
);
117 glGetTexLevelParameteriv(target
, level
,
118 GL_TEXTURE_COMPRESSED_IMAGE_SIZE
,
120 compSize
/= numSlices
;
122 else if (target
== GL_TEXTURE_2D_ARRAY
) {
123 glCompressedTexImage3D(target
, level
, intFormat
,
124 width
, height
, numSlices
, 0,
125 compressedSize
* numSlices
, NULL
);
126 for (slice
= 0; slice
< numSlices
; slice
++) {
127 glCompressedTexSubImage3D(target
, level
,
131 compressedSize
, texData
);
133 glGetTexLevelParameteriv(target
, level
,
134 GL_TEXTURE_COMPRESSED_IMAGE_SIZE
,
136 compSize
/= numSlices
;
139 assert(target
== GL_TEXTURE_2D
);
140 glCompressedTexImage2D(target
, level
, intFormat
,
142 compressedSize
, texData
);
143 glGetTexLevelParameteriv(target
, level
,
144 GL_TEXTURE_COMPRESSED_IMAGE_SIZE
,
146 assert(numSlices
== 1);
149 assert(compSize
== compressedSize
);
151 /* Should be no GL errors */
152 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
156 refData
= calloc(1, numSlices
* compressedSize
);
157 testData
= calloc(1, numSlices
* compressedSize
);
159 /* compute pos/size of sub-regions */
162 x1
= width
/ 4; /* quarter width */
163 y1
= height
/ 2; /* half height */
165 /* Position must be multiple of block dims */
166 assert(x1
% blockWidth
== 0);
167 assert(y1
% blockHeight
== 0);
174 /* Sizes must be multiple of block dims */
175 assert(w0
% blockWidth
== 0);
176 assert(w1
% blockWidth
== 0);
177 assert(h0
% blockHeight
== 0);
178 assert(h1
% blockHeight
== 0);
180 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
181 glPixelStorei(GL_PACK_ROW_LENGTH
, width
);
182 glPixelStorei(GL_PACK_IMAGE_HEIGHT
, height
);
183 glPixelStorei(GL_PACK_COMPRESSED_BLOCK_WIDTH
, blockWidth
);
184 glPixelStorei(GL_PACK_COMPRESSED_BLOCK_HEIGHT
, blockHeight
);
185 glPixelStorei(GL_PACK_COMPRESSED_BLOCK_SIZE
, blockSize
);
187 /* Should be no GL errors */
188 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
193 * Get whole compressed image (the reference)
195 if (target
== GL_TEXTURE_CUBE_MAP
) {
196 for (slice
= 0; slice
< 6; slice
++) {
197 glGetCompressedTexImage(
198 GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ slice
,
200 refData
+ slice
* compressedSize
);
204 glGetCompressedTexImage(target
, level
, refData
);
207 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
212 * Now get four sub-regions which should be equivalent
213 * to the whole reference image.
217 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
218 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
219 glGetCompressedTextureSubImage(tex
, level
,
220 x0
, y0
, 0, w0
, h0
, numSlices
,
221 numSlices
* compressedSize
, testData
);
224 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
225 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
226 glGetCompressedTextureSubImage(tex
, level
,
227 x1
, y0
, 0, w1
, h0
, numSlices
,
228 numSlices
* compressedSize
, testData
);
231 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
232 glPixelStorei(GL_PACK_SKIP_ROWS
, y1
);
233 glGetCompressedTextureSubImage(tex
, level
,
234 x0
, y1
, 0, w0
, h1
, numSlices
,
235 numSlices
* compressedSize
, testData
);
238 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
239 glPixelStorei(GL_PACK_SKIP_ROWS
, y1
);
240 glGetCompressedTextureSubImage(tex
, level
,
241 x1
, y1
, 0, w1
, h1
, numSlices
,
242 numSlices
* compressedSize
, testData
);
245 glPixelStorei(GL_PACK_SKIP_PIXELS
, 0);
246 glPixelStorei(GL_PACK_SKIP_ROWS
, 0);
248 /* Should be no GL errors */
249 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
253 /* now compare the images */
254 for (slice
= 0; slice
< numSlices
; slice
++) {
255 int sliceStart
= slice
* compressedSize
;
256 if (memcmp(refData
+ sliceStart
,
257 testData
+ sliceStart
,
260 for (i
= 0; i
< compressedSize
; i
++) {
261 if (refData
[sliceStart
+ i
] !=
262 testData
[sliceStart
+ i
]) {
263 printf("fail in slice/face %d at offset %d\n",
265 printf("expected %d, found %d\n",
266 refData
[sliceStart
+ i
],
267 testData
[sliceStart
+ i
]);
271 printf("Failure for %s %s\n",
272 piglit_get_gl_enum_name(target
),
273 piglit_get_gl_enum_name(intFormat
));
282 glDeleteTextures(1, &tex
);
289 piglit_init(int argc
, char **argv
)
293 piglit_require_extension("GL_ARB_get_texture_sub_image");
294 piglit_require_extension("GL_ARB_compressed_texture_pixel_storage");
296 if (!piglit_is_extension_supported("GL_EXT_texture_compression_s3tc") &&
297 !(piglit_is_extension_supported("GL_EXT_texture_compression_dxt1") &&
298 piglit_is_extension_supported("GL_ANGLE_texture_compression_dxt3") &&
299 piglit_is_extension_supported("GL_ANGLE_texture_compression_dxt5"))) {
300 printf("Test requires either GL_EXT_texture_compression_s3tc "
301 "or GL_EXT_texture_compression_dxt1, "
302 "GL_ANGLE_texture_compression_dxt3, and "
303 "GL_ANGLE_texture_compression_dxt5\n");
304 piglit_report_result(PIGLIT_SKIP
);
307 pass
= test_getsubimage(GL_TEXTURE_2D
, 256, 128, 1,
308 GL_COMPRESSED_RGB_S3TC_DXT1_EXT
) && pass
;
310 pass
= test_getsubimage(GL_TEXTURE_2D
, 80, 40, 1,
311 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
) && pass
;
313 pass
= test_getsubimage(GL_TEXTURE_2D
, 32, 32, 1,
314 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
) && pass
;
316 pass
= test_getsubimage(GL_TEXTURE_2D
, 32, 32, 1,
317 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
) && pass
;
319 /* NOTE: texture rectangle not supported with S3TC */
321 pass
= test_getsubimage(GL_TEXTURE_CUBE_MAP
, 16, 16, 6,
322 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
) && pass
;
324 if (piglit_is_extension_supported("GL_EXT_texture_array")) {
325 pass
= test_getsubimage(GL_TEXTURE_2D_ARRAY
, 16, 32, 10,
326 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)
329 pass
= test_getsubimage(GL_TEXTURE_2D_ARRAY
, 32, 16, 1,
330 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)
334 if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array")) {
335 pass
= test_getsubimage(GL_TEXTURE_CUBE_MAP_ARRAY
, 16, 16, 18,
336 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
)
340 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);