fix the spelling in whole piglit
[piglit.git] / tests / spec / arb_get_texture_sub_image / get.c
bloba0ba906f7d9c6037ee6f62d1c8f8c99989916c46
1 /*
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
13 * Software.
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
21 * IN THE SOFTWARE.
24 /**
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 */
39 static bool
40 minify(GLenum target, int level, int width, int height, int depth,
41 int *mip_width, int *mip_height, int *mip_depth)
43 switch (target) {
44 case GL_TEXTURE_1D:
45 assert(height == 1);
46 assert(depth == 1);
47 if (width >> level == 0)
48 return false;
49 *mip_width = width >> level;
50 *mip_height = 1;
51 *mip_depth = 1;
52 return true;
53 case GL_TEXTURE_1D_ARRAY:
54 assert(depth == 1);
55 if (width >> level == 0)
56 return false;
57 *mip_width = width >> level;
58 *mip_height = height;
59 *mip_depth = 1;
60 return true;
61 case GL_TEXTURE_2D:
62 assert(depth == 1);
63 if (width >> level == 0 && height >> level == 0)
64 return false;
65 *mip_width = MAX2(1, width >> level);
66 *mip_height = MAX2(1, height >> level);
67 *mip_depth = 1;
68 return true;
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)
73 return false;
74 *mip_width = MAX2(1, width >> level);
75 *mip_height = MAX2(1, height >> level);
76 *mip_depth = depth;
77 return true;
78 case GL_TEXTURE_3D:
79 if (width >> level == 0 &&
80 height >> level == 0 &&
81 depth >> level == 0)
82 return false;
83 *mip_width = MAX2(1, width >> level);
84 *mip_height = MAX2(1, height >> level);
85 *mip_depth = MAX2(1, depth >> level);
86 return true;
87 case GL_TEXTURE_RECTANGLE:
88 assert(depth == 1);
89 if (level > 0)
90 return false;
91 *mip_width = width;
92 *mip_height = height;
93 *mip_depth = 1;
94 return true;
95 default:
96 return false;
101 static bool
102 test_getsubimage(GLenum target,
103 GLsizei width, GLsizei height, GLsizei depth,
104 GLenum intFormat)
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);
110 GLuint tex;
111 int i, level, bytes;
112 bool pass = true;
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);
128 mip_width = width;
129 mip_height = height;
130 mip_depth = depth;
132 /* make mipmapped texture */
133 for (level = 0; ; level++) {
134 if (!minify(target, level, width, height, depth,
135 &mip_width, &mip_height, &mip_depth)) {
136 break;
139 switch (target) {
140 case GL_TEXTURE_1D:
141 glTexImage1D(GL_TEXTURE_1D, level, intFormat,
142 mip_width, 0,
143 GL_RGBA, GL_UNSIGNED_BYTE, texData);
144 break;
145 case GL_TEXTURE_2D:
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);
151 break;
152 case GL_TEXTURE_3D:
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);
158 break;
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,
165 level, intFormat,
166 mip_width, mip_height, 0,
167 GL_RGBA, GL_UNSIGNED_BYTE,
168 faceData);
170 break;
174 /* compare glGetTexImage() vs. glGetTextureSubImage() */
175 glPixelStorei(GL_PACK_ALIGNMENT, 1);
177 mip_width = width;
178 mip_height = height;
179 mip_depth = depth;
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)) {
186 break;
189 /* compute pos/size of sub-regions */
190 x0 = 0;
191 y0 = 0;
192 z0 = 0;
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 */
198 x1 &= ~0x3;
199 y1 &= ~0x3;
202 /* Note that any of these widths, heights, depths can be zero
203 * but that's legal and should work fine.
205 w0 = x1 - x0;
206 w1 = mip_width - x1;
207 h0 = y1 - y0;
208 h1 = mip_height - y1;
209 d0 = z1 - z0;
210 d1 = mip_depth - z1;
212 memset(refData, 0, bufSize);
213 memset(testData, 0, bufSize);
215 switch (target) {
216 case GL_TEXTURE_1D:
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.
228 /* left part */
229 glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
230 glGetTextureSubImage(tex, level,
231 x0, 0, 0, w0, 1, 1,
232 GL_RGBA, GL_UNSIGNED_BYTE,
233 bufSize, testData);
234 /* right part */
235 glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
236 glGetTextureSubImage(tex, level,
237 x1, 0, 0, w1, 1, 1,
238 GL_RGBA, GL_UNSIGNED_BYTE,
239 bufSize, testData);
241 /* defaults */
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");
248 pass = false;
250 break;
252 case GL_TEXTURE_1D_ARRAY:
253 case GL_TEXTURE_2D:
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,
263 refData);
264 z0 = 2; /* positive Y face */
266 else {
267 /* Get whole texture */
268 glGetTexImage(target, level,
269 GL_RGBA, GL_UNSIGNED_BYTE,
270 refData);
271 z0 = 0;
275 * Now get four sub-regions which should be equivalent
276 * to the whole reference image.
279 /* lower-left */
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,
285 bufSize, testData);
286 /* lower-right */
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,
292 bufSize, testData);
294 /* upper-left */
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,
300 bufSize, testData);
302 /* upper-right */
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,
308 bufSize, testData);
310 /* defaults */
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));
319 pass = false;
322 break;
324 case GL_TEXTURE_3D:
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,
348 bufSize, testData);
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,
356 bufSize, testData);
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,
365 bufSize, testData);
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,
374 bufSize, testData);
376 /* defaults */
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));
386 pass = false;
389 break;
392 /* Should be no GL errors */
393 if (!piglit_check_gl_error(GL_NO_ERROR)) {
394 pass = false;
398 free(texData);
399 free(refData);
400 free(testData);
402 return pass;
406 void
407 piglit_init(int argc, char **argv)
409 bool pass = true;
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)
428 && pass;
429 pass = test_getsubimage(GL_TEXTURE_2D_ARRAY, 32, 32, 9, GL_RGBA)
430 && pass;
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)
443 && pass;
446 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
450 enum piglit_result
451 piglit_display(void)
453 /* never called */
454 return PIGLIT_PASS;