2 * Copyright © 2012 Marek Olšák <maraeo@gmail.com>
3 * Copyright © 2014 Intel Corporation
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 * @file gettextureimage-targets.c
29 #include "piglit-util-gl.h"
31 PIGLIT_GL_TEST_CONFIG_BEGIN
33 config
.supports_gl_compat_version
= 20;
34 config
.supports_gl_core_version
= 31;
36 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
|
37 PIGLIT_GL_VISUAL_DOUBLE
;
38 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
40 PIGLIT_GL_TEST_CONFIG_END
42 #define IMAGE_WIDTH 32
43 #define IMAGE_HEIGHT 32
44 #define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT * 4)
47 init_layer_data(GLubyte
*layer_data
, int num_layers
)
51 for (z
= 0; z
< num_layers
; z
++) {
52 GLubyte
*data
= layer_data
+ IMAGE_SIZE
* z
;
54 for (x
= 0; x
< IMAGE_WIDTH
; x
+= 4) {
55 for (y
= 0; y
< IMAGE_HEIGHT
; y
+= 4) {
56 int r
= (x
+ 1) * 255 / (IMAGE_WIDTH
- 1);
57 int g
= (y
+ 1) * 255 / (IMAGE_HEIGHT
- 1);
58 int b
= (z
+ 1) * 255 / (num_layers
- 1);
61 /* each 4x4 block constains only one color (for S3TC) */
62 for (i
= 0; i
< 4; i
++) {
63 for (j
= 0; j
< 4; j
++) {
64 data
[((y
+ j
) * IMAGE_WIDTH
+ x
66 data
[((y
+ j
) * IMAGE_WIDTH
+ x
68 data
[((y
+ j
) * IMAGE_WIDTH
+ x
70 data
[((y
+ j
) * IMAGE_WIDTH
+ x
80 compare_layer(int layer
, int num_elements
, int tolerance
,
81 GLubyte
*data
, GLubyte
*expected
)
85 for (i
= 0; i
< num_elements
; ++i
) {
86 if (abs((int)data
[i
] - (int)expected
[i
]) > tolerance
) {
87 printf("GetTextureImage() returns incorrect data in byte %i for layer %i\n",
89 printf(" corresponding to (%i,%i), channel %i\n",
90 (i
/ 4) / IMAGE_WIDTH
, (i
/ 4) % IMAGE_HEIGHT
, i
% 4);
91 printf(" expected: %i\n", expected
[i
]);
92 printf(" got: %i\n", data
[i
]);
100 getTexImage(bool doPBO
, GLenum target
, GLubyte data
[][IMAGE_SIZE
],
101 GLenum internalformat
, int tolerance
)
104 int num_layers
=1, num_faces
=1, layer_size
;
105 GLubyte data2
[18][IMAGE_SIZE
];
113 glCreateTextures(target
, 1, &name
);
114 glTextureStorage1D(name
, 1, internalformat
, IMAGE_WIDTH
);
115 glTextureSubImage1D(name
, 0, 0, IMAGE_WIDTH
, GL_RGBA
,
116 GL_UNSIGNED_BYTE
, data
);
117 layer_size
= IMAGE_WIDTH
* 4;
121 case GL_TEXTURE_RECTANGLE
:
122 glCreateTextures(target
, 1, &name
);
123 glTextureStorage2D(name
, 1, internalformat
, IMAGE_WIDTH
,
125 glTextureSubImage2D(name
, 0, 0, 0, IMAGE_WIDTH
, IMAGE_HEIGHT
,
126 GL_RGBA
, GL_UNSIGNED_BYTE
, data
);
127 layer_size
= IMAGE_SIZE
;
130 case GL_TEXTURE_CUBE_MAP
:
132 glCreateTextures(target
, 1, &name
);
133 /* This is invalid. You must use 2D storage call for cube. */
134 if (!piglit_khr_no_error
) {
135 glTextureStorage3D(name
, 1, internalformat
,
136 IMAGE_WIDTH
, IMAGE_HEIGHT
,
138 pass
= piglit_check_gl_error(GL_INVALID_OPERATION
) && pass
;
141 glTextureStorage2D(name
, 1, internalformat
,
142 IMAGE_WIDTH
, IMAGE_HEIGHT
);
143 glTextureSubImage3D(name
, 0, 0, 0, 0, IMAGE_WIDTH
,
144 IMAGE_HEIGHT
, num_faces
, GL_RGBA
,
145 GL_UNSIGNED_BYTE
, data
);
146 layer_size
= IMAGE_SIZE
;
149 case GL_TEXTURE_1D_ARRAY
:
151 glCreateTextures(target
, 1, &name
);
152 // test as a single layer 2D image
153 glTextureStorage2D(name
, 1, internalformat
, IMAGE_WIDTH
,
155 glTextureSubImage2D(name
, 0, 0, 0, IMAGE_WIDTH
, num_layers
,
156 GL_RGBA
, GL_UNSIGNED_BYTE
, data
);
157 layer_size
= IMAGE_WIDTH
* 4 * num_layers
;
162 num_layers
= 16; /* Fall through. */
163 case GL_TEXTURE_2D_ARRAY
:
164 num_layers
= 7; /* Fall through. */
165 case GL_TEXTURE_CUBE_MAP_ARRAY
:
167 glCreateTextures(target
, 1, &name
);
168 glTextureStorage3D(name
, 1, internalformat
, IMAGE_WIDTH
,
169 IMAGE_HEIGHT
, num_layers
);
170 glTextureSubImage3D(name
, 0, 0, 0, 0,
171 IMAGE_WIDTH
, IMAGE_HEIGHT
, num_layers
,
172 GL_RGBA
, GL_UNSIGNED_BYTE
, data
);
173 layer_size
= IMAGE_SIZE
;
177 puts("Invalid texture target.");
182 /* Setup the PBO or data array to read into from glGetTextureImage */
184 glGenBuffers(1, &packPBO
);
185 glBindBuffer(GL_PIXEL_PACK_BUFFER
, packPBO
);
186 glBufferData(GL_PIXEL_PACK_BUFFER
,
187 layer_size
* num_faces
* num_layers
,
188 NULL
, GL_STREAM_READ
);
190 glBindBuffer(GL_PIXEL_PACK_BUFFER
, 0);
191 memset(data2
, 123, sizeof(data2
));
193 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
194 assert(num_layers
* num_faces
* layer_size
<= sizeof(data2
));
197 glGetTextureImage(name
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
,
198 layer_size
* num_faces
* num_layers
, NULL
);
200 glGetTextureImage(name
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
,
201 layer_size
* num_faces
* num_layers
, data2
);
203 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
206 dataGet
= (GLubyte
*) glMapBufferRange(
207 GL_PIXEL_PACK_BUFFER
, 0,
208 layer_size
* num_layers
*
214 for (i
= 0; i
< num_faces
* num_layers
; i
++) {
215 pass
= compare_layer(i
, layer_size
, tolerance
, dataGet
,
217 dataGet
+= layer_size
;
221 glUnmapBuffer(GL_PIXEL_PACK_BUFFER
);
222 glDeleteBuffers(1, &packPBO
);
225 glDeleteTextures(1, &name
);
230 struct target_and_mask
{
235 static struct target_and_mask targets
[] = {
239 {GL_TEXTURE_RECTANGLE
, 1},
240 {GL_TEXTURE_CUBE_MAP
, 1},
241 {GL_TEXTURE_1D_ARRAY
, 1},
242 {GL_TEXTURE_2D_ARRAY
, 1},
243 {GL_TEXTURE_CUBE_MAP_ARRAY
, 1},
247 clear_target_mask(GLenum target
)
250 for (i
= 0; i
< ARRAY_SIZE(targets
); ++i
) {
251 if (targets
[i
].target
== target
) {
258 piglit_init(int argc
, char **argv
)
260 piglit_require_extension("GL_ARB_direct_state_access");
261 piglit_require_extension("GL_ARB_texture_storage");
263 if (!piglit_is_extension_supported("GL_ARB_texture_rectangle"))
264 clear_target_mask(GL_TEXTURE_RECTANGLE
);
265 if (!piglit_is_extension_supported("GL_EXT_texture_array")) {
266 clear_target_mask(GL_TEXTURE_1D_ARRAY
);
267 clear_target_mask(GL_TEXTURE_2D_ARRAY
);
269 if (!piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
270 clear_target_mask(GL_TEXTURE_CUBE_MAP_ARRAY
);
278 GLenum internalformat
= GL_RGBA8
;
280 GLubyte data
[18][IMAGE_SIZE
];
282 init_layer_data(data
[0], 18);
284 for (i
= 0; i
< ARRAY_SIZE(targets
); ++i
) {
285 if (!targets
[i
].mask
)
288 printf("Testing %s into PBO\n",
289 piglit_get_gl_enum_name(targets
[i
].target
));
290 pass
= getTexImage(true, targets
[i
].target
, data
,
291 internalformat
, tolerance
)
294 printf("Testing %s into client array\n",
295 piglit_get_gl_enum_name(targets
[i
].target
));
296 pass
= getTexImage(false, targets
[i
].target
, data
,
297 internalformat
, tolerance
)
300 pass
= piglit_check_gl_error(GL_NO_ERROR
) && pass
;
303 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;