2 * Copyright © 2009 Intel Corporation
3 * Copyright © 2019 Advanced Micro Devices, Inc.
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
25 * Eric Anholt <eric@anholt.net>
26 * Andrew Wesie <awesie@gmail.com>
27 * Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
31 /** @file pbo-getteximage.c
33 * Tests that using a PBO as the unpack buffer for glTexImage and
34 * glTextureSubImage works correctly.
35 * (pbo-teximage.c used as reference)
38 #include "piglit-util-gl.h"
40 PIGLIT_GL_TEST_CONFIG_BEGIN
41 config
.supports_gl_compat_version
= 10;
42 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
43 PIGLIT_GL_TEST_CONFIG_END
45 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
48 probe(int x
, int y
, int z
, float *expected
, float *observed
)
50 if (expected
[0] != observed
[0] ||
51 expected
[1] != observed
[1] || expected
[2] != observed
[2]) {
52 printf("Probe color at (%i,%i,%i)\n", x
, y
, z
);
53 printf(" Expected: b = %f g = %f r = %f a = %f\n",
54 expected
[0], expected
[1], expected
[2], expected
[3]);
55 printf(" Observed: b = %f g = %f r = %f a = %f\n",
56 observed
[0], observed
[1], observed
[2], observed
[3]);
67 int width
, height
, depth
;
72 probe_all(struct desc
*tex
, struct desc
*pbo
)
75 for (int x
= 0; x
< pbo
->width
; ++x
)
76 for (int y
= 0; y
< pbo
->height
; ++y
)
77 for (int z
= 0; z
< pbo
->depth
; ++z
) {
78 int idx_in_tex
= (x
+ tex
->x
) +
79 tex
->width
* (y
+ tex
->y
) +
80 tex
->width
* tex
->height
* (z
+ tex
->z
);
81 int idx_in_pbo
= x
+ pbo
->width
* y
+
82 pbo
->width
* pbo
->height
* z
;
83 pass
&= probe(x
, y
, z
,
84 tex
->pixels
+ 4 * idx_in_tex
,
85 pbo
->pixels
+ 4 * idx_in_pbo
);
92 test_getteximage(GLenum target
, int width
, int height
, int depth
,
98 glGenTextures(1, &tex
);
99 glBindTexture(target
, tex
);
100 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
101 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
103 if (target
== GL_TEXTURE_CUBE_MAP
) {
104 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X
, 0, GL_RGBA
,
105 width
, height
, 0, GL_RGBA
, GL_FLOAT
, pixels
);
106 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X
, 0, GL_RGBA
,
107 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
108 pixels
+ 4 * 2 * 2 * 1);
109 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y
, 0, GL_RGBA
,
110 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
111 pixels
+ 4 * 2 * 2 * 2);
112 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
, 0, GL_RGBA
,
113 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
114 pixels
+ 4 * 2 * 2 * 3);
115 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z
, 0, GL_RGBA
,
116 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
117 pixels
+ 4 * 2 * 2 * 4);
118 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
, 0, GL_RGBA
,
119 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
120 pixels
+ 4 * 2 * 2 * 5);
123 glTexImage3D(target
, 0, GL_RGBA
, width
, height
, depth
, 0,
124 GL_RGBA
, GL_FLOAT
, pixels
);
126 glTexImage2D(target
, 0, GL_RGBA
, width
, height
, 0, GL_RGBA
,
130 glTexImage1D(target
, 0, GL_RGBA
, width
, 0, GL_RGBA
, GL_FLOAT
,
136 glGenBuffersARB(1, &pbo
);
137 glBindBufferARB(GL_PIXEL_PACK_BUFFER
, pbo
);
138 glBufferDataARB(GL_PIXEL_PACK_BUFFER
,
139 4 * width
* height
* depth
* sizeof(float), NULL
,
141 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
143 struct desc tex_info
= {
145 width
, height
, depth
,
149 struct desc pbo_info
= {
151 width
, height
, depth
,
154 if (target
== GL_TEXTURE_CUBE_MAP
) {
155 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X
, 0, GL_RGBA
,
156 GL_FLOAT
, BUFFER_OFFSET(0));
157 glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X
, 0, GL_RGBA
,
159 BUFFER_OFFSET(sizeof(float) * 4 * 2 * 2 * 1));
160 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y
, 0, GL_RGBA
,
162 BUFFER_OFFSET(sizeof(float) * 4 * 2 * 2 * 2));
163 glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
, 0, GL_RGBA
,
165 BUFFER_OFFSET(sizeof(float) * 4 * 2 * 2 * 3));
166 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z
, 0, GL_RGBA
,
168 BUFFER_OFFSET(sizeof(float) * 4 * 2 * 2 * 4));
169 glGetTexImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
, 0, GL_RGBA
,
171 BUFFER_OFFSET(sizeof(float) * 4 * 2 * 2 * 5));
173 pbo_info
.pixels
= glMapBufferARB(GL_PIXEL_PACK_BUFFER
,
175 pass
= probe_all(&tex_info
, &pbo_info
);
176 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER
);
178 glGetTexImage(target
, 0, GL_RGBA
, GL_FLOAT
, 0);
180 pbo_info
.pixels
= glMapBufferARB(GL_PIXEL_PACK_BUFFER
,
182 pass
= probe_all(&tex_info
, &pbo_info
);
183 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER
);
186 glBindBufferARB(GL_PIXEL_PACK_BUFFER
, 0);
188 glDeleteBuffersARB(1, &pbo
);
189 glDeleteTextures(1, &tex
);
194 test_gettexturesubimage(GLenum target
, int width
, int height
, int depth
,
197 int xoffset
, yoffset
, zoffset
;
201 glGenTextures(1, &tex
);
202 glBindTexture(target
, tex
);
203 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
204 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
206 if (target
== GL_TEXTURE_CUBE_MAP
) {
207 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X
, 0, GL_RGBA
,
208 width
, height
, 0, GL_RGBA
, GL_FLOAT
, pixels
);
209 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X
, 0, GL_RGBA
,
210 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
211 pixels
+ 4 * 2 * 2 * 1);
212 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y
, 0, GL_RGBA
,
213 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
214 pixels
+ 4 * 2 * 2 * 2);
215 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
, 0, GL_RGBA
,
216 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
217 pixels
+ 4 * 2 * 2 * 3);
218 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z
, 0, GL_RGBA
,
219 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
220 pixels
+ 4 * 2 * 2 * 4);
221 glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
, 0, GL_RGBA
,
222 width
, height
, 0, GL_RGBA
, GL_FLOAT
,
223 pixels
+ 4 * 2 * 2 * 5);
226 glTexImage3D(target
, 0, GL_RGBA
, width
, height
, depth
, 0,
227 GL_RGBA
, GL_FLOAT
, pixels
);
229 glTexImage2D(target
, 0, GL_RGBA
, width
, height
, 0, GL_RGBA
,
233 glTexImage1D(target
, 0, GL_RGBA
, width
, 0, GL_RGBA
, GL_FLOAT
,
240 yoffset
= 1 % height
;
243 struct desc tex_info
= {
244 xoffset
, yoffset
, zoffset
,
245 width
, height
, depth
,
249 struct desc pbo_info
= {
256 glGenBuffersARB(1, &pbo
);
257 glBindBufferARB(GL_PIXEL_PACK_BUFFER
, pbo
);
258 glBufferDataARB(GL_PIXEL_PACK_BUFFER
,
259 4 * width
* height
* depth
* sizeof(float), NULL
,
261 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
263 glGetTextureSubImage(tex
, 0, xoffset
, yoffset
, zoffset
,
264 pbo_info
.width
, pbo_info
.height
, pbo_info
.depth
,
266 4 * width
* height
* depth
* sizeof(float), 0);
268 pbo_info
.pixels
= glMapBufferARB(GL_PIXEL_PACK_BUFFER
,
270 pass
= probe_all(&tex_info
, &pbo_info
);
271 glUnmapBufferARB(GL_PIXEL_PACK_BUFFER
);
273 glBindBufferARB(GL_PIXEL_PACK_BUFFER
, 0);
275 glDeleteBuffersARB(1, &pbo
);
276 glDeleteTextures(1, &tex
);
281 piglit_init(int argc
, char **argv
)
284 float pixels
[4 * (2 * 2 * 12)];
285 unsigned int x
, y
, z
;
287 piglit_require_extension("GL_ARB_pixel_buffer_object");
288 piglit_require_extension("GL_ARB_get_texture_sub_image");
290 /* Init pixels with content */
291 for (x
= 0; x
< 2; ++x
)
292 for (y
= 0; y
< 2; ++y
)
293 for (z
= 0; z
< 12; ++z
) {
294 pixels
[4 * (x
+ 2 * y
+ 2 * 2 * z
)] = x
% 2;
295 pixels
[4 * (x
+ 2 * y
+ 2 * 2 * z
) + 1] =
297 pixels
[4 * (x
+ 2 * y
+ 2 * 2 * z
) + 2] =
299 pixels
[4 * (x
+ 2 * y
+ 2 * 2 * z
) + 3] =
303 pass
&= test_getteximage(GL_TEXTURE_1D
, 2, 0, 0, pixels
);
304 pass
&= test_getteximage(GL_TEXTURE_1D_ARRAY
, 2, 2, 0, pixels
);
305 pass
&= test_getteximage(GL_TEXTURE_2D
, 2, 2, 0, pixels
);
306 pass
&= test_getteximage(GL_TEXTURE_2D_ARRAY
, 2, 2, 2, pixels
);
307 pass
&= test_getteximage(GL_TEXTURE_3D
, 2, 2, 2, pixels
);
308 pass
&= test_getteximage(GL_TEXTURE_CUBE_MAP
, 2, 2, 0, pixels
);
309 if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
310 pass
&= test_getteximage(GL_TEXTURE_CUBE_MAP_ARRAY
, 2, 2, 12, pixels
);
312 pass
&= test_gettexturesubimage(GL_TEXTURE_1D
, 2, 0, 0, pixels
);
313 pass
&= test_gettexturesubimage(GL_TEXTURE_1D_ARRAY
, 2, 2, 0, pixels
);
314 pass
&= test_gettexturesubimage(GL_TEXTURE_2D
, 2, 2, 0, pixels
);
315 pass
&= test_gettexturesubimage(GL_TEXTURE_2D_ARRAY
, 2, 2, 2, pixels
);
316 pass
&= test_gettexturesubimage(GL_TEXTURE_3D
, 2, 2, 2, pixels
);
317 pass
&= test_gettexturesubimage(GL_TEXTURE_CUBE_MAP
, 2, 2, 0, pixels
);
319 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);