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 glGetTextureSubImage() with most texture types.
28 #include "piglit-util-gl.h"
30 PIGLIT_GL_TEST_CONFIG_BEGIN
31 config
.supports_gl_compat_version
= 20;
32 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
|
33 PIGLIT_GL_VISUAL_DOUBLE
;
34 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
35 PIGLIT_GL_TEST_CONFIG_END
38 /* XXX this could potentially be a piglit utility function */
40 minify(GLenum target
, int level
, int width
, int height
, int depth
,
41 int *mip_width
, int *mip_height
, int *mip_depth
)
47 if (width
>> level
== 0)
49 *mip_width
= width
>> level
;
53 case GL_TEXTURE_1D_ARRAY
:
55 if (width
>> level
== 0)
57 *mip_width
= width
>> level
;
63 if (width
>> level
== 0 && height
>> level
== 0)
65 *mip_width
= MAX2(1, width
>> level
);
66 *mip_height
= MAX2(1, height
>> level
);
69 case GL_TEXTURE_2D_ARRAY
:
70 case GL_TEXTURE_CUBE_MAP
:
71 case GL_TEXTURE_CUBE_MAP_ARRAY
:
72 if (width
>> level
== 0 && height
>> level
== 0)
74 *mip_width
= MAX2(1, width
>> level
);
75 *mip_height
= MAX2(1, height
>> level
);
79 if (width
>> level
== 0 &&
80 height
>> level
== 0 &&
83 *mip_width
= MAX2(1, width
>> level
);
84 *mip_height
= MAX2(1, height
>> level
);
85 *mip_depth
= MAX2(1, depth
>> level
);
87 case GL_TEXTURE_RECTANGLE
:
102 test_getsubimage(GLenum target
,
103 GLsizei width
, GLsizei height
, GLsizei depth
,
106 const GLint bufSize
= width
* height
* depth
* 4 * sizeof(GLubyte
);
107 GLubyte
*texData
= malloc(bufSize
);
108 GLubyte
*refData
= malloc(bufSize
);
109 GLubyte
*testData
= malloc(bufSize
);
113 GLsizei mip_width
, mip_height
, mip_depth
;
115 printf("Testing %s %s %d x %d x %d\n",
116 piglit_get_gl_enum_name(target
),
117 piglit_get_gl_enum_name(intFormat
),
118 width
, height
, depth
);
120 /* initial texture data */
121 for (i
= 0; i
< width
* height
* depth
* 4; i
++) {
122 texData
[i
] = i
& 0xff;
125 glGenTextures(1, &tex
);
126 glBindTexture(target
, tex
);
132 /* make mipmapped texture */
133 for (level
= 0; ; level
++) {
134 if (!minify(target
, level
, width
, height
, depth
,
135 &mip_width
, &mip_height
, &mip_depth
)) {
141 glTexImage1D(GL_TEXTURE_1D
, level
, intFormat
,
143 GL_RGBA
, GL_UNSIGNED_BYTE
, texData
);
146 case GL_TEXTURE_RECTANGLE
:
147 case GL_TEXTURE_1D_ARRAY
:
148 glTexImage2D(target
, level
, intFormat
,
149 mip_width
, mip_height
, 0,
150 GL_RGBA
, GL_UNSIGNED_BYTE
, texData
);
153 case GL_TEXTURE_2D_ARRAY
:
154 case GL_TEXTURE_CUBE_MAP_ARRAY
:
155 glTexImage3D(target
, level
, intFormat
,
156 mip_width
, mip_height
, mip_depth
, 0,
157 GL_RGBA
, GL_UNSIGNED_BYTE
, texData
);
159 case GL_TEXTURE_CUBE_MAP
:
160 /* specify dimensions and format for all faces to make texture cube complete,
161 but specify data for only the +Y face as it is the only one read back */
162 for (i
= 0; i
< 6; i
++) {
163 GLubyte
*faceData
= i
== 2 ? texData
: NULL
;
164 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X
+ i
,
166 mip_width
, mip_height
, 0,
167 GL_RGBA
, GL_UNSIGNED_BYTE
,
174 /* compare glGetTexImage() vs. glGetTextureSubImage() */
175 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
181 for (level
= 0; ; level
++) {
182 GLint x0
, y0
, z0
, x1
, y1
, z1
, w0
, h0
, w1
, h1
, d0
, d1
;
184 if (!minify(target
, level
, width
, height
, depth
,
185 &mip_width
, &mip_height
, &mip_depth
)) {
189 /* compute pos/size of sub-regions */
193 x1
= MAX2(1, mip_width
/ 3);
194 y1
= MAX2(1, mip_height
/ 3);
195 z1
= MAX2(1, mip_depth
/ 3);
196 if (intFormat
== GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
) {
197 /* x1, y1 must be a multiple of 4 */
202 /* Note that any of these widths, heights, depths can be zero
203 * but that's legal and should work fine.
208 h1
= mip_height
- y1
;
212 memset(refData
, 0, bufSize
);
213 memset(testData
, 0, bufSize
);
218 * Get whole image (the reference)
220 glGetTexImage(GL_TEXTURE_1D
, level
,
221 GL_RGBA
, GL_UNSIGNED_BYTE
, refData
);
224 * Now get two sub-regions which should be equivalent
225 * to the whole reference image.
229 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
230 glGetTextureSubImage(tex
, level
,
232 GL_RGBA
, GL_UNSIGNED_BYTE
,
235 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
236 glGetTextureSubImage(tex
, level
,
238 GL_RGBA
, GL_UNSIGNED_BYTE
,
242 glPixelStorei(GL_PACK_SKIP_PIXELS
, 0);
244 /* now compare the images */
245 bytes
= mip_width
* 4;
246 if (memcmp(refData
, testData
, bytes
)) {
247 printf("Failure for GL_TEXTURE_1D:\n");
252 case GL_TEXTURE_1D_ARRAY
:
254 case GL_TEXTURE_RECTANGLE
:
255 case GL_TEXTURE_CUBE_MAP
:
256 glPixelStorei(GL_PACK_SKIP_PIXELS
, 0);
257 glPixelStorei(GL_PACK_ROW_LENGTH
, mip_width
);
259 if (target
== GL_TEXTURE_CUBE_MAP
) {
260 /* only get +Y face */
261 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
262 level
, GL_RGBA
, GL_UNSIGNED_BYTE
,
264 z0
= 2; /* positive Y face */
267 /* Get whole texture */
268 glGetTexImage(target
, level
,
269 GL_RGBA
, GL_UNSIGNED_BYTE
,
275 * Now get four sub-regions which should be equivalent
276 * to the whole reference image.
280 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
281 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
282 glGetTextureSubImage(tex
, level
,
283 x0
, y0
, z0
, w0
, h0
, 1,
284 GL_RGBA
, GL_UNSIGNED_BYTE
,
287 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
288 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
289 glGetTextureSubImage(tex
, level
,
290 x1
, y0
, z0
, w1
, h0
, 1,
291 GL_RGBA
, GL_UNSIGNED_BYTE
,
295 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
296 glPixelStorei(GL_PACK_SKIP_ROWS
, y1
);
297 glGetTextureSubImage(tex
, level
,
298 x0
, y1
, z0
, w0
, h1
, 1,
299 GL_RGBA
, GL_UNSIGNED_BYTE
,
303 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
304 glPixelStorei(GL_PACK_SKIP_ROWS
, y1
);
305 glGetTextureSubImage(tex
, level
,
306 x1
, y1
, z0
, w1
, h1
, 1,
307 GL_RGBA
, GL_UNSIGNED_BYTE
,
311 glPixelStorei(GL_PACK_SKIP_PIXELS
, 0);
312 glPixelStorei(GL_PACK_SKIP_ROWS
, 0);
314 /* now compare the images */
315 bytes
= mip_width
* mip_height
* 4;
316 if (memcmp(refData
, testData
, bytes
)) {
317 printf("Failure for %s\n",
318 piglit_get_gl_enum_name(target
));
325 case GL_TEXTURE_2D_ARRAY
:
326 case GL_TEXTURE_CUBE_MAP_ARRAY
:
327 glPixelStorei(GL_PACK_ROW_LENGTH
, mip_width
);
328 glPixelStorei(GL_PACK_IMAGE_HEIGHT
, mip_height
);
331 * Get whole image (the reference)
333 glGetTexImage(target
, level
,
334 GL_RGBA
, GL_UNSIGNED_BYTE
, refData
);
337 * Now get four sub-regions which should be equivalent
338 * to the whole reference image.
341 /* front-left block */
342 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
343 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
344 glPixelStorei(GL_PACK_SKIP_IMAGES
, z0
);
345 glGetTextureSubImage(tex
, level
,
346 x0
, y0
, z0
, w0
, h0
+h1
, d0
,
347 GL_RGBA
, GL_UNSIGNED_BYTE
,
349 /* front-right block */
350 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
351 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
352 glPixelStorei(GL_PACK_SKIP_IMAGES
, z0
);
353 glGetTextureSubImage(tex
, level
,
354 x1
, y0
, 0, w1
, h0
+h1
, d0
,
355 GL_RGBA
, GL_UNSIGNED_BYTE
,
358 /* back-left block */
359 glPixelStorei(GL_PACK_SKIP_PIXELS
, x0
);
360 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
361 glPixelStorei(GL_PACK_SKIP_IMAGES
, z1
);
362 glGetTextureSubImage(tex
, level
,
363 x0
, y0
, z1
, w0
, h0
+h1
, d1
,
364 GL_RGBA
, GL_UNSIGNED_BYTE
,
367 /* back-right block */
368 glPixelStorei(GL_PACK_SKIP_PIXELS
, x1
);
369 glPixelStorei(GL_PACK_SKIP_ROWS
, y0
);
370 glPixelStorei(GL_PACK_SKIP_IMAGES
, z1
);
371 glGetTextureSubImage(tex
, level
,
372 x1
, y0
, z1
, w1
, h0
+h1
, d1
,
373 GL_RGBA
, GL_UNSIGNED_BYTE
,
377 glPixelStorei(GL_PACK_SKIP_PIXELS
, 0);
378 glPixelStorei(GL_PACK_SKIP_ROWS
, 0);
379 glPixelStorei(GL_PACK_SKIP_IMAGES
, 0);
381 /* now compare the images */
382 bytes
= mip_width
* mip_height
* mip_depth
* 4;
383 if (memcmp(refData
, testData
, bytes
)) {
384 printf("Failure for %s\n",
385 piglit_get_gl_enum_name(target
));
392 /* Should be no GL errors */
393 if (!piglit_check_gl_error(GL_NO_ERROR
)) {
407 piglit_init(int argc
, char **argv
)
411 piglit_require_extension("GL_ARB_get_texture_sub_image");
413 /* Test assorted targets, sizes (including NPOT) and internal formats */
414 pass
= test_getsubimage(GL_TEXTURE_1D
, 64, 1, 1, GL_RGB
) && pass
;
416 pass
= test_getsubimage(GL_TEXTURE_2D
, 256, 128, 1, GL_RGBA
) && pass
;
418 pass
= test_getsubimage(GL_TEXTURE_2D
, 30, 40, 1, GL_ALPHA
) && pass
;
420 pass
= test_getsubimage(GL_TEXTURE_3D
, 8, 4, 16, GL_RGBA
) && pass
;
422 pass
= test_getsubimage(GL_TEXTURE_RECTANGLE
, 16, 8, 1, GL_RGB
) && pass
;
424 pass
= test_getsubimage(GL_TEXTURE_CUBE_MAP
, 32, 32, 1, GL_RGB
) && pass
;
426 if (piglit_is_extension_supported("GL_EXT_texture_array")) {
427 pass
= test_getsubimage(GL_TEXTURE_1D_ARRAY
, 64, 9, 1, GL_ALPHA
)
429 pass
= test_getsubimage(GL_TEXTURE_2D_ARRAY
, 32, 32, 9, GL_RGBA
)
433 if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array")) {
434 pass
= test_getsubimage(GL_TEXTURE_CUBE_MAP_ARRAY
,
435 8, 8, 6, GL_RGBA
) && pass
;
436 pass
= test_getsubimage(GL_TEXTURE_CUBE_MAP_ARRAY
,
437 32, 32, 18, GL_ALPHA
) && pass
;
440 if (piglit_is_extension_supported("GL_EXT_texture_compression_s3tc")) {
441 pass
= test_getsubimage(GL_TEXTURE_2D
, 128, 128, 1,
442 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
)
446 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);