errors.c - test error detection
get.c - test glGetTextureSubImage
getcompressed.c - test glGetCompressedTextureSubImage
cubemap.c - extra tests for getting cubemap images
---
 tests/all.py                                       |   7 +
 tests/spec/CMakeLists.txt                          |   1 +
 .../arb_get_texture_sub_image/CMakeLists.gl.txt    |  17 +
 .../spec/arb_get_texture_sub_image/CMakeLists.txt  |   1 +
 tests/spec/arb_get_texture_sub_image/cubemap.c     | 203 ++++++++++
 tests/spec/arb_get_texture_sub_image/errors.c      | 208 ++++++++++
 tests/spec/arb_get_texture_sub_image/get.c         | 435 +++++++++++++++++++++
 .../spec/arb_get_texture_sub_image/getcompressed.c | 337 ++++++++++++++++
 8 files changed, 1209 insertions(+)
 create mode 100644 tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
 create mode 100644 tests/spec/arb_get_texture_sub_image/CMakeLists.txt
 create mode 100644 tests/spec/arb_get_texture_sub_image/cubemap.c
 create mode 100644 tests/spec/arb_get_texture_sub_image/errors.c
 create mode 100644 tests/spec/arb_get_texture_sub_image/get.c
 create mode 100644 tests/spec/arb_get_texture_sub_image/getcompressed.c

diff --git a/tests/all.py b/tests/all.py
index f2e1765..1872df2 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -2501,6 +2501,13 @@ with profile.group_manager(
         'GL_DEPTH32F_STENCIL8', 0)
 
 with profile.group_manager(
+        PiglitGLTest, grouptools.join('spec', 'arb_get_texture_sub_image')) as 
g:
+    g(['arb_get_texture_sub_image-cubemap'])
+    g(['arb_get_texture_sub_image-errors'])
+    g(['arb_get_texture_sub_image-get'])
+    g(['arb_get_texture_sub_image-getcompressed'])
+
+with profile.group_manager(
         PiglitGLTest,
         grouptools.join('spec', 'arb_texture_env_crossbar')) as g:
     g(['crossbar'], run_concurrent=False)
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index b0973ac..1421afa 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -23,6 +23,7 @@ add_subdirectory (arb_framebuffer_object)
 add_subdirectory (arb_framebuffer_srgb)
 add_subdirectory (arb_geometry_shader4)
 add_subdirectory (arb_get_program_binary)
+add_subdirectory (arb_get_texture_sub_image)
 add_subdirectory (arb_gpu_shader5)
 add_subdirectory (arb_gpu_shader_fp64)
 add_subdirectory (arb_instanced_arrays)
diff --git a/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt 
b/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
new file mode 100644
index 0000000..2194f8c
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/CMakeLists.gl.txt
@@ -0,0 +1,17 @@
+include_directories(
+       ${GLEXT_INCLUDE_DIR}
+       ${OPENGL_INCLUDE_PATH}
+)
+
+link_libraries (
+       piglitutil_${piglit_target_api}
+       ${OPENGL_gl_LIBRARY}
+       ${OPENGL_glu_LIBRARY}
+)
+
+piglit_add_executable (arb_get_texture_sub_image-cubemap cubemap.c)
+piglit_add_executable (arb_get_texture_sub_image-errors errors.c)
+piglit_add_executable (arb_get_texture_sub_image-get get.c)
+piglit_add_executable (arb_get_texture_sub_image-getcompressed getcompressed.c)
+
+# vim: ft=cmake:
diff --git a/tests/spec/arb_get_texture_sub_image/CMakeLists.txt 
b/tests/spec/arb_get_texture_sub_image/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/arb_get_texture_sub_image/cubemap.c 
b/tests/spec/arb_get_texture_sub_image/cubemap.c
new file mode 100644
index 0000000..b11e74c
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/cubemap.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2015 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Test glGetTextureSubImage with cube maps.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+       config.supports_gl_compat_version = 20;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+static void
+memset_series(unsigned *buffer, unsigned baseValue, unsigned size)
+{
+       unsigned i;
+       for (i = 0; i < size; i++)
+               buffer[i] = baseValue + i;
+}
+
+
+static bool
+compare_series(const unsigned *buffer, unsigned baseValue, unsigned size)
+{
+       unsigned i;
+       for (i = 0; i < size; i++) {
+               if (buffer[i] != baseValue + i) {
+                       printf("Expected 0x%08x found 0x%08x\n",
+                              baseValue + i, buffer[i]);
+                       return false;
+               }
+
+       }
+       return true;
+}
+
+
+static bool
+test_cube_map(void)
+{
+       GLuint tex;
+       GLuint buffer[8*8];
+       GLuint results[6*8*8];
+       int level, face, imgStart;
+
+       /* setup 8x8 mipmapped cube texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
+       glTexStorage2D(GL_TEXTURE_CUBE_MAP, 4, GL_RGBA8, 8, 8);
+
+       for (level = 0; level < 4; level++) {
+               for (face = 0; face < 6; face++) {
+                       memset_series(buffer, face*10000+level*100,
+                                     sizeof(buffer)/4);
+                       glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
+                                       level, 0, 0, 8 >> level, 8 >> level,
+                                       GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                       buffer);
+               }
+       }
+
+       /* test getting all six faces */
+       for (level = 0; level < 4; level++) {
+               /* get all six faces */
+               memset(results, 0, sizeof(results));
+               glGetTextureSubImage(tex, level,
+                                    0, 0, 0,  /* offset */
+                                    8 >> level, 8 >> level, 6, /* size */
+                                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                    sizeof(results), results);
+
+               /* check results */
+               imgStart = 0;
+               for (face = 0; face < 6; face++) {
+                       GLuint expected = face * 10000 + level * 100;
+                       int numTexels = (8 >> level) * (8 >> level);
+                       if (!compare_series(results + imgStart, expected,
+                                           numTexels)) {
+                               printf("Incorrect cubemap texel at "
+                                      "level %u, face %u\n",
+                                      level, face);
+                               return false;
+                       }
+                       imgStart += numTexels;
+               }
+       }
+
+       /* Test getting face sub images (skip last 1x1 mipmap level)
+        * using four glGetTextureSubImage calls, one per quadrant.
+        * Note that each call retrieves the quadrant for all six faces
+        * at once.
+        */
+       for (level = 0; level < 3; level++) {
+               const int w = 4 >> level, h = 4 >> level;
+               int x, y;
+
+               memset(results, 0, sizeof(results));
+
+               glPixelStorei(GL_PACK_ROW_LENGTH, w * 2);
+               glPixelStorei(GL_PACK_IMAGE_HEIGHT, h * 2);
+
+               /* lower-left */
+               x = y = 0;
+               glPixelStorei(GL_PACK_SKIP_PIXELS, x);
+               glPixelStorei(GL_PACK_SKIP_ROWS, y);
+               glGetTextureSubImage(tex, level,
+                                    x, y, 0,
+                                    w, h, 6,
+                                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                    sizeof(results), results);
+
+               /* lower-right */
+               x = w;
+               y = 0;
+               glPixelStorei(GL_PACK_SKIP_PIXELS, x);
+               glPixelStorei(GL_PACK_SKIP_ROWS, y);
+               glGetTextureSubImage(tex, level,
+                                    x, y, 0,
+                                    w, h, 6,
+                                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                    sizeof(results), results);
+
+               /* upper-left */
+               x = 0;
+               y = h;
+               glPixelStorei(GL_PACK_SKIP_PIXELS, x);
+               glPixelStorei(GL_PACK_SKIP_ROWS, y);
+               glGetTextureSubImage(tex, level,
+                                    x, y, 0,
+                                    w, h, 6,
+                                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                    sizeof(results), results);
+
+               /* upper-right */
+               x = w;
+               y = h;
+               glPixelStorei(GL_PACK_SKIP_PIXELS, x);
+               glPixelStorei(GL_PACK_SKIP_ROWS, y);
+               glGetTextureSubImage(tex, level,
+                                    x, y, 0,
+                                    w, h, 6,
+                                    GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
+                                    sizeof(results), results);
+
+               /* check results */
+               imgStart = 0;
+               for (face = 0; face < 6; face++) {
+                       GLuint expected = face * 10000 + level * 100;
+                       int numTexels = (8 >> level) * (8 >> level);
+                       if (!compare_series(results + imgStart, expected,
+                                           numTexels)) {
+                               printf("Incorrect cubemap texel at "
+                                      "level %u, face %u\n",
+                                      level, face);
+                               return false;
+                       }
+                       imgStart += numTexels;
+               }
+       }
+
+       return true;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass;
+
+       pass = test_cube_map();
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_get_texture_sub_image");
+}
diff --git a/tests/spec/arb_get_texture_sub_image/errors.c 
b/tests/spec/arb_get_texture_sub_image/errors.c
new file mode 100644
index 0000000..8bdbb90
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/errors.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright 2015 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Test glGetTextureSubImage and glGetCompressedTextureSubImage error checking.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+       config.supports_gl_compat_version = 20;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+static bool
+test_texture_id(void)
+{
+       GLubyte buffer[8*8*4];
+       GLuint tex = 42;
+       bool pass = true;
+
+       /* Test get with bad texture ID */
+       glGetTextureSubImage(tex, 0,
+                            0, 0, 0, /* offset */
+                            8, 8, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test compressed get with bad texture ID */
+       glGetCompressedTextureSubImage(tex, 0,
+                                      0, 0, 0, /* offset */
+                                      8, 8, 1, /* size */
+                                      sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test get with undefined texture */
+       glGenTextures(1, &tex);
+       glGetTextureSubImage(tex, 0,
+                            0, 0, 0, /* offset */
+                            8, 8, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test compressed get with undefined texture */
+       glGetCompressedTextureSubImage(tex, 0,
+                                      0, 0, 0, /* offset */
+                                      8, 8, 1, /* size */
+                                      sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       glDeleteTextures(1, &tex);
+
+       return pass;
+}
+
+
+static bool
+test_buffer_size(void)
+{
+       GLubyte buffer[8*8*4];
+       GLubyte quadrant_buffer[4*4*4];
+       GLuint tex = 42;
+       bool pass = true;
+
+       /* setup 8x8 texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 8, 8);
+
+       /* Test too small of dest buffer */
+       glGetTextureSubImage(tex, 0,
+                            0, 0, 0, /* offset */
+                            8, 8, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer) - 1, buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test with pixel unpack params, sufficient buffer size */
+       glPixelStorei(GL_PACK_SKIP_ROWS, 4);
+       glPixelStorei(GL_PACK_SKIP_PIXELS, 4);
+       glPixelStorei(GL_PACK_ROW_LENGTH, 8);
+       glGetTextureSubImage(tex, 0,
+                            4, 4, 0, /* offset */
+                            4, 4, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_NO_ERROR))
+               pass = false;
+
+       /* Test with pixel unpack params, insufficient buffer size */
+       glGetTextureSubImage(tex, 0,
+                            4, 4, 0, /* offset */
+                            4, 4, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer) - 1, buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test getting a quadrant, sufficent buffer size */
+       glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+       glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+       glGetTextureSubImage(tex, 0,
+                            4, 4, 0, /* offset */
+                            4, 4, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(quadrant_buffer), quadrant_buffer);
+       if (!piglit_check_gl_error(GL_NO_ERROR))
+               pass = false;
+
+       /* Test getting a quadrant, insufficent buffer size */
+       glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+       glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+       glGetTextureSubImage(tex, 0,
+                            4, 4, 0, /* offset */
+                            4, 4, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(quadrant_buffer) - 1, quadrant_buffer);
+       if (!piglit_check_gl_error(GL_INVALID_OPERATION))
+               pass = false;
+
+       /* Test getting invalid level */
+       glGetTextureSubImage(tex, 99,
+                            0, 0, 0, /* offset */
+                            1, 1, 1, /* size */
+                            GL_RGBA, GL_UNSIGNED_BYTE,
+                            sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_VALUE))
+               pass = false;
+
+       glDeleteTextures(1, &tex);
+
+       return pass;
+}
+
+
+static bool
+test_invalid_values(void)
+{
+       GLubyte buffer[8*8*4];
+       GLuint tex = 42;
+       bool pass = true;
+
+       /* setup 8x8 texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexStorage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 8, 8);
+
+       /* Test bad format/type */
+       glGetTextureSubImage(tex, 0,
+                            0, 0, 0, /* offset */
+                            8, 8, 1, /* size */
+                            GL_RGBA, GL_DEPTH_FUNC,  /* bad enum */
+                            sizeof(buffer), buffer);
+       if (!piglit_check_gl_error(GL_INVALID_ENUM))
+               pass = false;
+
+       return pass;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass;
+
+       pass = test_texture_id();
+       pass = test_buffer_size() && pass;
+       pass = test_invalid_values() && pass;
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_get_texture_sub_image");
+}
diff --git a/tests/spec/arb_get_texture_sub_image/get.c 
b/tests/spec/arb_get_texture_sub_image/get.c
new file mode 100644
index 0000000..fa0a2e5
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/get.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2015 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Test glGetTextureSubImage() with most texture types.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+       config.supports_gl_compat_version = 20;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA |
+                              PIGLIT_GL_VISUAL_DOUBLE;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+/* XXX this could potentially be a piglit utility function */
+static bool
+minify(GLenum target, int level, int width, int height, int depth,
+       int *mip_width, int *mip_height, int *mip_depth)
+{
+       switch (target) {
+       case GL_TEXTURE_1D:
+               assert(height == 1);
+               assert(depth == 1);
+               if (width >> level == 0)
+                       return false;
+               *mip_width = width >> level;
+               *mip_height = 1;
+               *mip_depth = 1;
+               return true;
+       case GL_TEXTURE_1D_ARRAY:
+               assert(depth == 1);
+               if (width >> level == 0)
+                       return false;
+               *mip_width = width >> level;
+               *mip_height = height;
+               *mip_depth = 1;
+               return true;
+       case GL_TEXTURE_2D:
+               assert(depth == 1);
+               if (width >> level == 0 && height >> level == 0)
+                       return false;
+               *mip_width = MAX2(1, width >> level);
+               *mip_height = MAX2(1, height >> level);
+               *mip_depth = 1;
+               return true;
+       case GL_TEXTURE_2D_ARRAY:
+               if (width >> level == 0 && height >> level == 0)
+                       return false;
+               *mip_width = MAX2(1, width >> level);
+               *mip_height = MAX2(1, height >> level);
+               *mip_depth = depth;
+               return true;
+       case GL_TEXTURE_3D:
+               if (width >> level == 0 &&
+                   height >> level == 0 &&
+                   depth >> level == 0)
+                       return false;
+               *mip_width = MAX2(1, width >> level);
+               *mip_height = MAX2(1, height >> level);
+               *mip_depth = MAX2(1, depth >> level);
+               return true;
+       case GL_TEXTURE_RECTANGLE:
+               assert(depth == 1);
+               if (level > 0)
+                       return false;
+               *mip_width = width;
+               *mip_height = height;
+               *mip_depth = 1;
+               return true;
+       default:
+               return false;
+       }
+}
+
+
+static bool
+test_getsubimage(GLenum target,
+                GLsizei width, GLsizei height, GLsizei depth,
+                GLenum intFormat)
+{
+       const GLint bufSize = width * height * depth * 4 * sizeof(GLubyte);
+       GLubyte *texData = malloc(bufSize);
+       GLubyte *refData = malloc(bufSize);
+       GLubyte *testData = malloc(bufSize);
+       GLuint tex;
+       int i, level, bytes;
+       bool pass = true;
+       GLsizei mip_width, mip_height, mip_depth;
+
+       printf("Testing %s %s %d x %d x %d\n",
+              piglit_get_gl_enum_name(target),
+              piglit_get_gl_enum_name(intFormat),
+              width, height, depth);
+
+       /* initial texture data */
+       for (i = 0; i < width * height * depth * 4; i++) {
+               texData[i] = i & 0xff;
+       }
+
+       glGenTextures(1, &tex);
+       glBindTexture(target, tex);
+
+       mip_width = width;
+       mip_height = height;
+       mip_depth = depth;
+
+       /* make mipmapped texture */
+       for (level = 0; ; level++) {
+               if (!minify(target, level, width, height, depth,
+                           &mip_width, &mip_height, &mip_depth)) {
+                       break;
+               }
+
+               switch (target) {
+               case GL_TEXTURE_1D:
+                       glTexImage1D(GL_TEXTURE_1D, level, intFormat,
+                                    mip_width, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, texData);
+                       break;
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_RECTANGLE:
+               case GL_TEXTURE_1D_ARRAY:
+                       glTexImage2D(target, level, intFormat,
+                                    mip_width, mip_height, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, texData);
+                       break;
+               case GL_TEXTURE_3D:
+               case GL_TEXTURE_2D_ARRAY:
+                       glTexImage3D(target, level, intFormat,
+                                    mip_width, mip_height, mip_depth, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, texData);
+                       break;
+               case GL_TEXTURE_CUBE_MAP:
+                       /* only tests positive Y face */
+                       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, level,
+                                    intFormat, mip_width, mip_height, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, texData);
+                       break;
+               }
+       }
+
+       /* compare glGetTexImage() vs. glGetTextureSubImage() */
+       glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+       mip_width = width;
+       mip_height = height;
+       mip_depth = depth;
+
+       for (level = 0; ; level++) {
+               GLint x0, y0, z0, x1, y1, z1, w0, h0, w1, h1, d0, d1;
+
+               if (!minify(target, level, width, height, depth,
+                           &mip_width, &mip_height, &mip_depth)) {
+                       break;
+               }
+
+               /* compute pos/size of sub-regions */
+               x0 = 0;
+               y0 = 0;
+               z0 = 0;
+               x1 = MAX2(1, mip_width / 3);
+               y1 = MAX2(1, mip_height / 3);
+               z1 = MAX2(1, mip_depth / 3);
+               if (intFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) {
+                       /* x1, y1 must be a multipe of 4 */
+                       x1 &= ~0x3;
+                       y1 &= ~0x3;
+               }
+
+                /* Note that any of these widths, heights, depths can be zero
+                 * but that's legal and should work fine.
+                 */
+               w0 = x1 - x0;
+               w1 = mip_width - x1;
+               h0 = y1 - y0;
+               h1 = mip_height - y1;
+               d0 = z1 - z0;
+               d1 = mip_depth - z1;
+
+               memset(refData, 0, bufSize);
+               memset(testData, 0, bufSize);
+
+               switch (target) {
+               case GL_TEXTURE_1D:
+                       /*
+                        * Get whole image (the reference)
+                        */
+                       glGetTexImage(GL_TEXTURE_1D, level,
+                                     GL_RGBA, GL_UNSIGNED_BYTE, refData);
+
+                       /*
+                        * Now get two sub-regions which should be equivalent
+                        * to the whole reference image.
+                        */
+
+                       /* left part */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+                       glGetTextureSubImage(tex, level,
+                                            x0, 0, 0, w0, 1, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+                       /* right part */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+                       glGetTextureSubImage(tex, level,
+                                            x1, 0, 0, w1, 1, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* defaults */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+
+                       /* now compare the images */
+                       bytes = mip_width * 4;
+                       if (memcmp(refData, testData, bytes)) {
+                               printf("Failure for GL_TEXTURE_1D:\n");
+                               pass = false;
+                       }
+                       break;
+
+               case GL_TEXTURE_1D_ARRAY:
+               case GL_TEXTURE_2D:
+               case GL_TEXTURE_RECTANGLE:
+               case GL_TEXTURE_CUBE_MAP:
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+                       glPixelStorei(GL_PACK_ROW_LENGTH, mip_width);
+
+                       /*
+                        * Get whole image (the reference)
+                        */
+                       if (target == GL_TEXTURE_CUBE_MAP) {
+                               glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+                                              level, GL_RGBA, GL_UNSIGNED_BYTE,
+                                              refData);
+                               z0 = 2; /* positive Y face */
+                       }
+                       else {
+                               glGetTexImage(target, level,
+                                             GL_RGBA, GL_UNSIGNED_BYTE,
+                                              refData);
+                               z0 = 0;
+                       }
+
+                       /*
+                        * Now get four sub-regions which should be equivalent
+                        * to the whole reference image.
+                        */
+
+                       /* lower-left */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glGetTextureSubImage(tex, level,
+                                            x0, y0, z0, w0, h0, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+                       /* lower-right */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glGetTextureSubImage(tex, level,
+                                            x1, y0, z0, w1, h0, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* upper-left */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y1);
+                       glGetTextureSubImage(tex, level,
+                                            x0, y1, z0, w0, h1, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* upper-right */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y1);
+                       glGetTextureSubImage(tex, level,
+                                            x1, y1, z0, w1, h1, 1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* defaults */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+
+                       /* now compare the images */
+                       bytes = mip_width * mip_height * 4;
+                       if (memcmp(refData, testData, bytes)) {
+                               printf("Failure for %s\n",
+                                      piglit_get_gl_enum_name(target));
+                               pass = false;
+                       }
+
+                       break;
+
+               case GL_TEXTURE_3D:
+               case GL_TEXTURE_2D_ARRAY:
+                       glPixelStorei(GL_PACK_ROW_LENGTH, mip_width);
+                       glPixelStorei(GL_PACK_IMAGE_HEIGHT, mip_height);
+
+                       /*
+                        * Get whole image (the reference)
+                        */
+                       glGetTexImage(target, level,
+                                     GL_RGBA, GL_UNSIGNED_BYTE, refData);
+
+                       /*
+                        * Now get four sub-regions which should be equivalent
+                        * to the whole reference image.
+                        */
+
+                       /* front-left block */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glPixelStorei(GL_PACK_SKIP_IMAGES, z0);
+                       glGetTextureSubImage(tex, level,
+                                            x0, y0, z0, w0, h0+h1, d0,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+                       /* front-right block */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glPixelStorei(GL_PACK_SKIP_IMAGES, z0);
+                       glGetTextureSubImage(tex, level,
+                                            x1, y0, 0, w1, h0+h1, d0,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* back-left block */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glPixelStorei(GL_PACK_SKIP_IMAGES, z1);
+                       glGetTextureSubImage(tex, level,
+                                            x0, y0, z1, w0, h0+h1, d1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* back-right block */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+                       glPixelStorei(GL_PACK_SKIP_IMAGES, z1);
+                       glGetTextureSubImage(tex, level,
+                                            x1, y0, z1, w1, h0+h1, d1,
+                                            GL_RGBA, GL_UNSIGNED_BYTE,
+                                            bufSize, testData);
+
+                       /* defaults */
+                       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+                       glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+                       glPixelStorei(GL_PACK_SKIP_IMAGES, 0);
+
+                       /* now compare the images */
+                       bytes = mip_width * mip_height * mip_depth * 4;
+                       if (memcmp(refData, testData, bytes)) {
+                               printf("Failure for %s\n",
+                                      piglit_get_gl_enum_name(target));
+                               pass = false;
+                       }
+
+                       break;
+               }
+
+               /* Should be no GL errors */
+               if (!piglit_check_gl_error(GL_NO_ERROR)) {
+                       pass = false;
+               }
+       }
+
+       free(texData);
+       free(refData);
+       free(testData);
+
+       return pass;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+
+       /* Test assorted targets, sizes (including NPOT) and internal formats */
+       pass = test_getsubimage(GL_TEXTURE_1D, 64, 1, 1, GL_RGB) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 256, 128, 1, GL_RGBA) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 30, 40, 1, GL_ALPHA) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_3D, 8, 4, 16, GL_RGBA) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_RECTANGLE, 16, 8, 1, GL_RGB) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_CUBE_MAP, 32, 32, 1, GL_RGB) && pass;
+
+       if (piglit_is_extension_supported("GL_EXT_texture_array")) {
+               pass = test_getsubimage(GL_TEXTURE_1D_ARRAY, 64, 9, 1, GL_ALPHA)
+                       && pass;
+               pass = test_getsubimage(GL_TEXTURE_2D_ARRAY, 32, 32, 9, GL_RGBA)
+                       && pass;
+       }
+
+       if (piglit_is_extension_supported("GL_EXT_texture_compression_s3tc")) {
+               pass = test_getsubimage(GL_TEXTURE_2D, 128, 128, 1,
+                                       GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+                       && pass;
+       }
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_get_texture_sub_image");
+}
diff --git a/tests/spec/arb_get_texture_sub_image/getcompressed.c 
b/tests/spec/arb_get_texture_sub_image/getcompressed.c
new file mode 100644
index 0000000..26cecc1
--- /dev/null
+++ b/tests/spec/arb_get_texture_sub_image/getcompressed.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2015 VMware, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * Test glGetCompressedTextureSubImage() with 2D, 2D array, cubemap, and
+ * cubemap array textures.
+ */
+
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+       config.supports_gl_compat_version = 20;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA;
+PIGLIT_GL_TEST_CONFIG_END
+
+
+static bool
+test_getsubimage(GLenum target,
+                GLsizei width, GLsizei height, GLsizei numSlices,
+                GLenum intFormat)
+{
+       const GLint bufSize = width * height * 4 * sizeof(GLubyte);
+       GLubyte *texData;
+       GLubyte *refData = malloc(6 * bufSize); /* 6 for cubemaps */
+       GLubyte *testData = malloc(6 * bufSize); /* 6 for cubemaps */
+       GLuint tex;
+       int i, slice, compressedSize, compSize;
+       int blockWidth, blockHeight, blockSize;
+       bool pass = true;
+       const int level = 0;
+       int x0, y0, x1, y1, w0, h0, w1, h1;
+
+       printf("Testing %s %s %d x %d\n",
+              piglit_get_gl_enum_name(target),
+              piglit_get_gl_enum_name(intFormat),
+              width, height);
+
+       /* For all S3TC formats */
+       blockWidth = blockHeight = 4;
+       if (intFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+           intFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) {
+               blockSize = 8;
+       }
+       else {
+               assert(intFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
+                      intFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
+               blockSize = 16;
+       }
+
+       /* Size must be multiple of block dims */
+       assert(width % blockWidth == 0);
+       assert(height % blockHeight == 0);
+
+       compressedSize = (width / blockWidth) * (height / blockHeight)
+               * blockSize;
+       if (0) {
+               printf("byte per block row: %d\n",
+                      (width / blockWidth) * blockSize);
+               printf("compressed image size = %d\n", compressedSize);
+       }
+
+       /* initial texture data */
+       texData = malloc(compressedSize);
+       for (i = 0; i < compressedSize; i++) {
+               texData[i] = (i+10) & 0xff;
+       }
+
+       glGenTextures(1, &tex);
+       glBindTexture(target, tex);
+
+       /* Define texture image */
+       if (target == GL_TEXTURE_CUBE_MAP) {
+               for (slice = 0; slice < 6; slice++) {
+                       glCompressedTexImage2D(
+                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
+                               level, intFormat, width, height, 0,
+                               compressedSize, texData);
+               }
+               glGetTexLevelParameteriv(GL_TEXTURE_CUBE_MAP_POSITIVE_X, level,
+                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
+                                        &compSize);
+               assert(numSlices == 6);
+       }
+       else if (target == GL_TEXTURE_CUBE_MAP_ARRAY) {
+               assert(numSlices % 6 == 0);
+               glCompressedTexImage3D(target, level, intFormat,
+                                      width, height, numSlices, 0,
+                                      compressedSize * numSlices, NULL);
+               for (slice = 0; slice < numSlices; slice++) {
+                       glCompressedTexSubImage3D(target, level,
+                                                 0, 0, slice,
+                                                 width, height, 1,
+                                                 intFormat,
+                                                 compressedSize, texData);
+               }
+               glGetTexLevelParameteriv(target, level,
+                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
+                                        &compSize);
+               compSize /= numSlices;
+       }
+       else if (target == GL_TEXTURE_2D_ARRAY) {
+               glCompressedTexImage3D(target, level, intFormat,
+                                      width, height, numSlices, 0,
+                                      compressedSize * numSlices, NULL);
+               for (slice = 0; slice < numSlices; slice++) {
+                       glCompressedTexSubImage3D(target, level,
+                                                 0, 0, slice,
+                                                 width, height, 1,
+                                                 intFormat,
+                                                 compressedSize, texData);
+               }
+               glGetTexLevelParameteriv(target, level,
+                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
+                                        &compSize);
+               compSize /= numSlices;
+       }
+       else {
+               assert(target == GL_TEXTURE_2D);
+               glCompressedTexImage2D(target, level, intFormat,
+                                      width, height, 0,
+                                      compressedSize, texData);
+               glGetTexLevelParameteriv(target, level,
+                                        GL_TEXTURE_COMPRESSED_IMAGE_SIZE,
+                                        &compSize);
+               assert(numSlices == 1);
+       }
+
+       assert(compSize == compressedSize);
+
+       /* Should be no GL errors */
+       if (!piglit_check_gl_error(GL_NO_ERROR)) {
+               pass = false;
+       }
+
+       refData = calloc(1, numSlices * compressedSize);
+       testData = calloc(1, numSlices * compressedSize);
+
+       /* compute pos/size of sub-regions */
+       x0 = 0;
+       y0 = 0;
+       x1 = width / 4;  /* quarter width */
+       y1 = height / 2;  /* half height */
+
+       /* Position must be multiple of block dims */
+       assert(x1 % blockWidth == 0);
+       assert(y1 % blockHeight == 0);
+
+       w0 = x1 - x0;
+       w1 = width - x1;
+       h0 = y1 - y0;
+       h1 = height - y1;
+
+       /* Sizes must be multiple of block dims */
+       assert(w0 % blockWidth == 0);
+       assert(w1 % blockWidth == 0);
+       assert(h0 % blockHeight == 0);
+       assert(h1 % blockHeight == 0);
+
+       glPixelStorei(GL_PACK_ALIGNMENT, 1);
+       glPixelStorei(GL_PACK_ROW_LENGTH, width);
+       glPixelStorei(GL_PACK_IMAGE_HEIGHT, height);
+       glPixelStorei(GL_PACK_COMPRESSED_BLOCK_WIDTH, blockWidth);
+       glPixelStorei(GL_PACK_COMPRESSED_BLOCK_HEIGHT, blockHeight);
+       glPixelStorei(GL_PACK_COMPRESSED_BLOCK_SIZE, blockSize);
+
+       /* Should be no GL errors */
+       if (!piglit_check_gl_error(GL_NO_ERROR)) {
+               pass = false;
+       }
+
+       /*
+        * Get whole compressed image (the reference)
+        */
+       if (target == GL_TEXTURE_CUBE_MAP) {
+               for (slice = 0; slice < 6; slice++) {
+                       glGetCompressedTexImage(
+                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + slice,
+                               level,
+                               refData + slice * compressedSize);
+               }
+       }
+       else {
+               glGetCompressedTexImage(target, level, refData);
+       }
+
+       if (!piglit_check_gl_error(GL_NO_ERROR)) {
+               pass = false;
+       }
+
+       /*
+        * Now get four sub-regions which should be equivalent
+        * to the whole reference image.
+        */
+
+       /* lower-left */
+       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+       glGetCompressedTextureSubImage(tex, level,
+                                      x0, y0, 0, w0, h0, numSlices,
+                                      numSlices * compressedSize, testData);
+
+       /* lower-right */
+       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+       glPixelStorei(GL_PACK_SKIP_ROWS, y0);
+       glGetCompressedTextureSubImage(tex, level,
+                                      x1, y0, 0, w1, h0, numSlices,
+                                      numSlices * compressedSize, testData);
+
+       /* upper-left */
+       glPixelStorei(GL_PACK_SKIP_PIXELS, x0);
+       glPixelStorei(GL_PACK_SKIP_ROWS, y1);
+       glGetCompressedTextureSubImage(tex, level,
+                                      x0, y1, 0, w0, h1, numSlices,
+                                      numSlices * compressedSize, testData);
+
+       /* upper-right */
+       glPixelStorei(GL_PACK_SKIP_PIXELS, x1);
+       glPixelStorei(GL_PACK_SKIP_ROWS, y1);
+       glGetCompressedTextureSubImage(tex, level,
+                                      x1, y1, 0, w1, h1, numSlices,
+                                      numSlices * compressedSize, testData);
+
+       /* defaults */
+       glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+       glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+
+       /* Should be no GL errors */
+       if (!piglit_check_gl_error(GL_NO_ERROR)) {
+               pass = false;
+       }
+
+       /* now compare the images */
+       for (slice = 0; slice < numSlices; slice++) {
+               int sliceStart = slice * compressedSize;
+               if (memcmp(refData + sliceStart,
+                          testData + sliceStart,
+                          compressedSize)) {
+                       int i;
+                       for (i = 0; i < compressedSize; i++) {
+                               if (refData[sliceStart + i] !=
+                                   testData[sliceStart + i]) {
+                                       printf("fail in slice/face %d at offset 
%d\n",
+                                              slice, i);
+                                       printf("expected %d, found %d\n",
+                                              refData[sliceStart + i],
+                                              testData[sliceStart + i]);
+                                       break;
+                               }
+                       }
+                       printf("Failure for %s %s\n",
+                              piglit_get_gl_enum_name(target),
+                              piglit_get_gl_enum_name(intFormat));
+                       pass = false;
+               }
+       }
+
+       free(texData);
+       free(refData);
+       free(testData);
+
+       glDeleteTextures(1, &tex);
+
+       return pass;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 256, 128, 1,
+                               GL_COMPRESSED_RGB_S3TC_DXT1_EXT) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 80, 40, 1,
+                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 32, 32, 1,
+                               GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) && pass;
+
+       pass = test_getsubimage(GL_TEXTURE_2D, 32, 32, 1,
+                               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) && pass;
+
+       /* NOTE: texture rectangle not supported with S3TC */
+
+       pass = test_getsubimage(GL_TEXTURE_CUBE_MAP, 16, 16, 6,
+                               GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) && pass;
+
+       if (piglit_is_extension_supported("GL_EXT_texture_array")) {
+               pass = test_getsubimage(GL_TEXTURE_2D_ARRAY, 16, 32, 10,
+                                       GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+                       && pass;
+
+               pass = test_getsubimage(GL_TEXTURE_2D_ARRAY, 32, 16, 1,
+                                       GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
+                       && pass;
+       }
+
+       if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array")) {
+               pass = test_getsubimage(GL_TEXTURE_CUBE_MAP_ARRAY, 16, 16, 18,
+                                       GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
+                       && pass;
+       }
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_get_texture_sub_image");
+       piglit_require_extension("GL_ARB_compressed_texture_pixel_storage");
+       piglit_require_extension("GL_EXT_texture_compression_s3tc");
+       piglit_require_extension("GL_ARB_texture_non_power_of_two");
+}
-- 
1.9.1

_______________________________________________
Piglit mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to