ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / arb_direct_state_access / getcompressedtextureimage.c
blob4206a47144c4f9019650dd20366a50497241ae71
1 /*
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
14 * Software.
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
22 * IN THE SOFTWARE.
25 /**
26 * @file getcompressedtextureimage.c
28 #include "piglit-util-gl.h"
29 #include "dsa-utils.h"
31 PIGLIT_GL_TEST_CONFIG_BEGIN
33 config.window_width = 216;
34 config.supports_gl_compat_version = 20;
35 config.supports_gl_core_version = 31;
37 config.window_visual = PIGLIT_GL_VISUAL_RGBA |
38 PIGLIT_GL_VISUAL_DOUBLE;
39 config.khr_no_error_support = PIGLIT_NO_ERRORS;
41 PIGLIT_GL_TEST_CONFIG_END
43 #define IMAGE_WIDTH 32
44 #define IMAGE_HEIGHT 32
45 #define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT * 4)
46 #define DISPLAY_GAP 4
48 static void
49 show_image(GLubyte *data, int num_layers, const char *title)
51 GLuint name;
52 int i;
53 char junk[50];
54 GLuint prog = 0;
56 if (!piglit_automatic) {
57 prog = dsa_create_program(GL_TEXTURE_2D);
58 glUseProgram(prog);
59 dsa_set_xform(prog, piglit_width, piglit_height);
61 /* Create the texture handle. */
62 glCreateTextures(GL_TEXTURE_2D, 1, &name);
63 glTextureStorage2D(name, 1, GL_RGBA8, IMAGE_WIDTH,
64 IMAGE_HEIGHT);
65 glTextureParameteri(name, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
66 glTextureParameteri(name, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
67 glBindTextureUnit(0, name);
69 /* Draw the layers, separated by some space */
70 glClear(GL_COLOR_BUFFER_BIT);
71 for (i = 0; i < num_layers; ++i) {
72 int x = (IMAGE_WIDTH + DISPLAY_GAP) * (i % 6);
73 int y = (IMAGE_HEIGHT + DISPLAY_GAP) * (i / 6);
74 glTextureSubImage2D(name, 0, 0, 0,
75 IMAGE_WIDTH, IMAGE_HEIGHT,
76 GL_RGBA, GL_UNSIGNED_BYTE,
77 data + i * IMAGE_SIZE);
78 piglit_draw_rect_tex(x, y, IMAGE_WIDTH, IMAGE_HEIGHT,
79 0, 0, 1, 1);
82 /* Make the title. */
83 printf("****** %s ******\n", title);
85 piglit_present_results();
87 /* Pause. */
88 printf("Enter any char to continue.\n>>>>>>");
89 (void) scanf("%s", junk);
90 printf("\n");
92 glDeleteTextures(1, &name);
93 glUseProgram(0);
94 glDeleteProgram(prog);
98 static GLubyte *
99 make_layer_data(int num_layers)
101 int z;
102 GLubyte *layer_data =
103 malloc(num_layers * IMAGE_SIZE * sizeof(GLubyte));
104 GLubyte *data = piglit_rgbw_image_ubyte(IMAGE_WIDTH,
105 IMAGE_HEIGHT, true);
107 for (z = 0; z < num_layers; z++) {
108 memcpy(layer_data + IMAGE_SIZE * z, data, IMAGE_SIZE);
111 free(data);
113 /* Show the first layer of the completed layer data. */
114 show_image(layer_data, num_layers, "Test Data");
116 return layer_data;
119 static bool
120 compare_layer(int layer, int num_elements, int tolerance,
121 GLubyte *data, GLubyte *expected)
123 int i;
125 for (i = 0; i < num_elements; ++i) {
126 if (abs((int)data[i] - (int)expected[i]) > tolerance) {
127 printf("GetCompressedTextureImage() returns incorrect"
128 " data in byte %i for layer %i\n",
129 i, layer);
130 printf(" corresponding to (%i,%i), channel %i\n",
131 (i / 4) / IMAGE_WIDTH, (i / 4) % IMAGE_HEIGHT,
132 i % 4);
133 printf(" expected: %i\n", expected[i]);
134 printf(" got: %i\n", data[i]);
135 return false;
138 return true;
141 static enum piglit_result
142 getTexImage(bool doPBO, GLenum target, GLubyte *data,
143 GLenum internalformat, int tolerance)
145 int i;
146 int num_layers=1, num_faces=1, layer_size;
147 GLubyte *data2 = NULL;
148 GLubyte *dataGet;
149 GLuint packPBO;
150 bool pass = true;
151 GLuint name;
152 GLint compressed;
153 GLint comp_size;
155 /* Upload the data. These are all targets that can be compressed
156 * according to _mesa_target_can_be_compressed.
158 switch (target) {
159 case GL_TEXTURE_2D:
160 glCreateTextures(target, 1, &name);
161 glTextureStorage2D(name, 1, internalformat, IMAGE_WIDTH,
162 IMAGE_HEIGHT);
163 glTextureSubImage2D(name, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
164 GL_RGBA, GL_UNSIGNED_BYTE, data);
165 layer_size = IMAGE_SIZE;
166 break;
168 case GL_TEXTURE_CUBE_MAP:
169 num_faces = 6;
170 glCreateTextures(target, 1, &name);
171 if (!piglit_khr_no_error) {
172 /* This is invalid. You must use 2D storage call for
173 * cube.
175 glTextureStorage3D(name, 1, internalformat,
176 IMAGE_WIDTH, IMAGE_HEIGHT,
177 num_faces);
178 pass &= piglit_check_gl_error(GL_INVALID_OPERATION);
180 glTextureStorage2D(name, 1, internalformat,
181 IMAGE_WIDTH, IMAGE_HEIGHT);
182 /* This is legal. */
183 glTextureSubImage3D(name, 0, 0, 0, 0, IMAGE_WIDTH,
184 IMAGE_HEIGHT, num_faces, GL_RGBA,
185 GL_UNSIGNED_BYTE, data);
186 layer_size = IMAGE_SIZE;
187 break;
189 case GL_TEXTURE_2D_ARRAY:
190 num_layers = 7; /* Fall through. */
191 case GL_TEXTURE_CUBE_MAP_ARRAY:
192 num_layers = 6 * 3;
193 glCreateTextures(target, 1, &name);
194 glTextureStorage3D(name, 1, internalformat, IMAGE_WIDTH,
195 IMAGE_HEIGHT, num_layers);
196 glTextureSubImage3D(name, 0, 0, 0, 0,
197 IMAGE_WIDTH, IMAGE_HEIGHT, num_layers,
198 GL_RGBA, GL_UNSIGNED_BYTE, data);
199 layer_size = IMAGE_SIZE;
200 break;
202 default:
203 puts("Invalid texture target.");
204 return PIGLIT_FAIL;
207 /* Make sure the driver has compressed the image. */
208 glGetTextureLevelParameteriv(name, 0, GL_TEXTURE_COMPRESSED,
209 &compressed);
210 printf("\tIs the texture compressed? %s.\n",
211 compressed ? "yes" : "no");
213 glGetTextureLevelParameteriv(name, 0,
214 GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
215 &comp_size);
216 /* Section 8.11 (Texture Queries) of the OpenGL 4.5 Core Profile spec
217 * says:
219 * "For GetTextureLevelParameter* only, texture may also be a cube
220 * map texture object. In this case the query is always performed
221 * for face zero (the TEXTURE_CUBE_MAP_POSITIVE_X face), since
222 * there is no way to specify another face."
224 if (target == GL_TEXTURE_CUBE_MAP)
225 comp_size *= num_faces;
226 printf("\tThe size of the texture in bytes is %d.\n", comp_size);
228 /* Show the uncompressed data. */
229 show_image(data, num_layers * num_faces, "Data Before Compression");
232 /* Setup the PBO or data array to read into from
233 * glGetCompressedTextureImage
235 if (doPBO) {
236 glGenBuffers(1, &packPBO);
237 glBindBuffer(GL_PIXEL_PACK_BUFFER, packPBO);
238 /* Make the buffer big enough to hold uncompressed data. */
239 glBufferData(GL_PIXEL_PACK_BUFFER, layer_size * num_faces *
240 num_layers * sizeof(GLubyte),
241 NULL, GL_STREAM_READ);
242 } else {
243 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
244 data2 = malloc(layer_size * num_faces * num_layers *
245 sizeof(GLubyte));
246 memset(data2, 123, layer_size * num_faces * num_layers *
247 sizeof(GLubyte));
249 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
250 assert(num_layers * num_faces * layer_size <= 18 * IMAGE_SIZE);
253 /* Download the compressed texture image. */
254 if (doPBO)
255 glGetCompressedTextureImage(name, 0, comp_size, NULL);
256 else
257 glGetCompressedTextureImage(name, 0, comp_size, data2);
258 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
260 if (doPBO)
261 dataGet = (GLubyte *) glMapBufferRange(
262 GL_PIXEL_PACK_BUFFER, 0,
263 comp_size,
264 GL_MAP_READ_BIT);
265 else
266 dataGet = data2;
268 /* Re-upload the texture in compressed form. */
269 switch (target) {
270 case GL_TEXTURE_2D:
271 glCompressedTextureSubImage2D(name, 0, 0, 0,
272 IMAGE_WIDTH, IMAGE_HEIGHT,
273 internalformat, comp_size,
274 dataGet);
275 break;
277 case GL_TEXTURE_CUBE_MAP:
278 glCompressedTextureSubImage3D(name, 0, 0, 0, 0,
279 IMAGE_WIDTH, IMAGE_HEIGHT,
280 num_faces,
281 internalformat, comp_size,
282 dataGet);
283 break;
285 case GL_TEXTURE_2D_ARRAY:
286 case GL_TEXTURE_CUBE_MAP_ARRAY:
287 glCompressedTextureSubImage3D(name, 0, 0, 0, 0,
288 IMAGE_WIDTH, IMAGE_HEIGHT,
289 num_layers,
290 internalformat, comp_size,
291 dataGet);
292 break;
296 /* Get the uncompressed version for comparison. */
297 if (doPBO) {
298 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
299 glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
300 layer_size * num_layers * num_faces * sizeof(GLubyte),
301 NULL);
303 else {
304 glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
305 layer_size * num_layers * num_faces * sizeof(GLubyte),
306 data2);
308 pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
309 if (doPBO)
310 dataGet = (GLubyte *) glMapBufferRange(
311 GL_PIXEL_PACK_BUFFER, 0,
312 layer_size * num_layers *
313 num_faces * sizeof(GLubyte),
314 GL_MAP_READ_BIT);
315 else
316 dataGet = data2;
318 /* Examine the image after pulling it off the graphics card. */
319 show_image(dataGet, num_layers * num_faces, "Data After Compression");
321 /* Do the comparison */
322 for (i = 0; i < num_faces * num_layers; i++) {
323 pass = compare_layer(i, layer_size, tolerance, dataGet,
324 data + (i * layer_size)) && pass;
325 dataGet += layer_size;
328 if (doPBO) {
329 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
330 glDeleteBuffers(1, &packPBO);
333 glDeleteTextures(1, &name);
334 free(data2);
336 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
339 struct target_and_mask {
340 GLenum target;
341 bool mask;
344 static struct target_and_mask targets[] = {
345 {GL_TEXTURE_2D, 1},
346 {GL_TEXTURE_CUBE_MAP, 1},
347 {GL_TEXTURE_2D_ARRAY, 1},
348 {GL_TEXTURE_CUBE_MAP_ARRAY, 1},
351 static void
352 clear_target_mask(GLenum target)
354 int i;
355 for (i = 0; i < ARRAY_SIZE(targets); ++i) {
356 if (targets[i].target == target) {
357 targets[i].mask = 0;
362 void
363 piglit_init(int argc, char **argv)
365 piglit_require_extension("GL_ARB_direct_state_access");
366 piglit_require_extension("GL_ARB_texture_storage");
368 if (!piglit_is_extension_supported("GL_EXT_texture_array"))
369 clear_target_mask(GL_TEXTURE_2D_ARRAY);
370 if (!piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
371 clear_target_mask(GL_TEXTURE_CUBE_MAP_ARRAY);
373 glClearColor(0.5, 0.5, 0.5, 1);
376 enum piglit_result
377 piglit_display(void)
379 int i;
380 GLenum internalformat = GL_COMPRESSED_RGBA_FXT1_3DFX;
381 int tolerance = 8;
382 GLubyte *data;
383 enum piglit_result subtest;
384 enum piglit_result result = PIGLIT_PASS;
386 piglit_require_extension("GL_3DFX_texture_compression_FXT1");
388 data = make_layer_data(18);
390 for (i = 0; i < ARRAY_SIZE(targets); ++i) {
391 if (!targets[i].mask)
392 continue;
394 printf("Testing %s into PBO\n",
395 piglit_get_gl_enum_name(targets[i].target));
396 subtest = getTexImage(true, targets[i].target, data,
397 internalformat, tolerance);
398 piglit_report_subtest_result(subtest, "getTexImage %s PBO",
399 piglit_get_gl_enum_name(
400 targets[i].target));
401 if (subtest == PIGLIT_FAIL)
402 result = PIGLIT_FAIL;
404 printf("\n"); /* Separate tests with some white space. */
406 printf("Testing %s into client array\n",
407 piglit_get_gl_enum_name(targets[i].target));
408 subtest = getTexImage(false, targets[i].target, data,
409 internalformat, tolerance);
410 piglit_report_subtest_result(subtest, "getTexImage %s",
411 piglit_get_gl_enum_name(
412 targets[i].target));
413 if (subtest == PIGLIT_FAIL)
414 result = PIGLIT_FAIL;
416 printf("\n\n"); /* Separate targets with some white space. */
418 if (!piglit_check_gl_error(GL_NO_ERROR))
419 result = PIGLIT_FAIL;
422 /* 1D targets can't be compressed in Mesa right now, but here is a
423 * trivial test for the entry point.
425 glCompressedTextureSubImage1D(250, 0, 0, 60,
426 internalformat, 60*4*8,
427 NULL);
429 if (!piglit_khr_no_error) {
430 /* Bad texture */
431 if (!piglit_check_gl_error(GL_INVALID_OPERATION))
432 subtest = PIGLIT_FAIL;
433 else
434 subtest = PIGLIT_PASS;
435 piglit_report_subtest_result(subtest, "Compressed Texture"
436 " Sub Image 1D");
437 if (subtest == PIGLIT_FAIL)
438 result = PIGLIT_FAIL;
441 free(data);
443 return result;