---
 tests/all.py                                       |   6 +
 .../spec/arb_direct_state_access/CMakeLists.gl.txt |   5 +
 tests/spec/arb_direct_state_access/get-textures.c  | 114 +++++
 .../gettextureimage-formats.c                      | 559 +++++++++++++++++++++
 .../gettextureimage-luminance.c                    | 260 ++++++++++
 .../gettextureimage-simple.c                       |  86 ++++
 .../gettextureimage-targets.c                      | 305 +++++++++++
 7 files changed, 1335 insertions(+)
 create mode 100644 tests/spec/arb_direct_state_access/get-textures.c
 create mode 100644 tests/spec/arb_direct_state_access/gettextureimage-formats.c
 create mode 100644 
tests/spec/arb_direct_state_access/gettextureimage-luminance.c
 create mode 100644 tests/spec/arb_direct_state_access/gettextureimage-simple.c
 create mode 100644 tests/spec/arb_direct_state_access/gettextureimage-targets.c

diff --git a/tests/all.py b/tests/all.py
index 48ec09f..8dfb5ac 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -4316,6 +4316,12 @@ spec['ARB_direct_state_access']['texunits'] = 
PiglitGLTest('arb_direct_state_acc
 spec['ARB_direct_state_access']['texture-params'] = 
PiglitGLTest('arb_direct_state_access-texture-params', run_concurrent=True)
 spec['ARB_direct_state_access']['copytexturesubimage'] = 
PiglitGLTest('arb_direct_state_access-copytexturesubimage', run_concurrent=True)
 spec['ARB_direct_state_access']['texture-errors'] = 
PiglitGLTest('arb_direct_state_access-texture-errors', run_concurrent=True)
+spec['ARB_direct_state_access']['get-textures'] = 
PiglitGLTest('arb_direct_state_access-get-textures', run_concurrent=True)
+spec['ARB_direct_state_access']['gettextureimage-formats'] = 
PiglitGLTest('arb_direct_state_access-gettextureimage-formats', 
run_concurrent=True)
+spec['ARB_direct_state_access']['gettextureimage-luminance'] = 
PiglitGLTest('arb_direct_state_access-gettextureimage-luminance', 
run_concurrent=True)
+spec['ARB_direct_state_access']['gettextureimage-simple'] = 
PiglitGLTest('arb_direct_state_access-gettextureimage-simple', 
run_concurrent=True)
+spec['ARB_direct_state_access']['gettextureimage-targets'] = 
PiglitGLTest('arb_direct_state_access-gettextureimage-targets', 
run_concurrent=True)
+
 
 profile.tests['hiz'] = hiz
 profile.tests['fast_color_clear'] = fast_color_clear
diff --git a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt 
b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
index 4f8f49f..d5a496e 100644
--- a/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
+++ b/tests/spec/arb_direct_state_access/CMakeLists.gl.txt
@@ -18,4 +18,9 @@ piglit_add_executable (arb_direct_state_access-texunits 
texunits.c)
 piglit_add_executable (arb_direct_state_access-texture-params texture-params.c)
 piglit_add_executable (arb_direct_state_access-copytexturesubimage 
copytexturesubimage.c)
 piglit_add_executable (arb_direct_state_access-texture-errors texture-errors.c)
+piglit_add_executable (arb_direct_state_access-get-textures get-textures.c)
+piglit_add_executable (arb_direct_state_access-gettextureimage-formats 
gettextureimage-formats.c)
+piglit_add_executable (arb_direct_state_access-gettextureimage-luminance 
gettextureimage-luminance.c)
+piglit_add_executable (arb_direct_state_access-gettextureimage-simple 
gettextureimage-simple.c)
+piglit_add_executable (arb_direct_state_access-gettextureimage-targets 
gettextureimage-targets.c)
 # vim: ft=cmake:
diff --git a/tests/spec/arb_direct_state_access/get-textures.c 
b/tests/spec/arb_direct_state_access/get-textures.c
new file mode 100644
index 0000000..95d5bc4
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/get-textures.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2014 Intel Corporation
+ *
+ * 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.
+ */
+
+/** @file get-textures.c
+ *
+ * Tests glGetTextureImage to see if it behaves in the expected way,
+ * throwing the correct errors, etc.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 13;
+
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA | 
+               PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_direct_state_access");
+}
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+       GLuint name;
+       GLubyte *data = malloc(50 * 50 * 6 * 4 * sizeof(GLubyte));
+       GLubyte *image = malloc(50 * 50 * 4 * sizeof(GLubyte));
+
+       /* Throw some invalid inputs at glGetTextureImage. */
+
+       /* Non-gen-ed name */
+       glGetTextureImage(3, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data);
+       pass &= piglit_check_gl_error(GL_INVALID_OPERATION);
+
+       /* Unsupported target. */
+       glGenTextures(1, &name);
+       glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X, name);
+       glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data);
+       pass &= piglit_check_gl_error(GL_INVALID_ENUM);
+       glDeleteTextures(1, &name);
+
+       /* Unsupported dsa target for non-dsa version. */
+       glGetTexImage(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                    data);
+       pass &= piglit_check_gl_error(GL_INVALID_ENUM);
+
+       /* No Storage
+        *
+        * The spec doesn't say what should happen in this case.  This is
+        * addressed by Khronos Bug 13223.
+        */
+       glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name);
+       glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data);
+       pass &= piglit_check_gl_error(GL_INVALID_OPERATION);
+       glDeleteTextures(1, &name);
+
+       /* Insufficient storage
+        *
+        * The spec doesn't say what should happen in this case.  This is
+        * addressed by Khronos Bug 13223.
+        */
+       glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name);
+       glBindTexture(GL_TEXTURE_CUBE_MAP, name);
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,
+                    GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0,
+                    GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0,
+                    GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+       /* Note: GL_TEXTURE_CUBE_MAP_NEGATIVE_Y not set */
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0,
+                    GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+       glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0,
+                    GL_RGBA8, 50, 50, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+       glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0, data);
+       pass &= piglit_check_gl_error(GL_INVALID_OPERATION);
+       glDeleteTextures(1, &name);
+
+       /* Trivial, but should work. */
+       glCreateTextures(GL_TEXTURE_CUBE_MAP, 1, &name);
+       glTextureStorage2D(name, 1, GL_RGBA8, 50, 50);
+       glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                         50 * 50 * 6 * 4, data);
+       pass &= piglit_check_gl_error(GL_NO_ERROR);
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
diff --git a/tests/spec/arb_direct_state_access/gettextureimage-formats.c 
b/tests/spec/arb_direct_state_access/gettextureimage-formats.c
new file mode 100644
index 0000000..a22d235
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/gettextureimage-formats.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2011 VMware, Inc.
+ * Copyright (c) 2014 Intel Corporation.
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+
+/**
+ * @file gettextureimage-formats.c
+ *
+ * Test glGetTexImage with a variety of formats.
+ * Brian Paul
+ * Sep 2011
+ *
+ * Adapted for testing glGetTextureImage in ARB_direct_state_access by
+ * Laura Ekstrand <la...@jlekstrand.net>, November 2014.
+ */
+
+
+#include "piglit-util-gl.h"
+#include "../fbo/fbo-formats.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 10;
+
+       config.window_width = 600;
+       config.window_height = 200;
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "gettextureimage-formats";
+
+static const GLfloat clearColor[4] = { 0.4, 0.4, 0.4, 0.0 };
+static GLuint texture_id;
+static GLboolean init_by_rendering;
+
+#define TEX_SIZE 128
+
+#define DO_BLEND 1
+
+
+/**
+ * Make a simple texture image where red increases from left to right,
+ * green increases from bottom to top, blue stays constant (50%) and
+ * the alpha channel is a checkerboard pattern.
+ * \return GL_TRUE for success, GL_FALSE if unsupported format
+ */
+static GLboolean
+make_texture_image(GLenum intFormat, GLubyte upperRightTexel[4])
+{
+       GLubyte tex[TEX_SIZE][TEX_SIZE][4];
+       int i, j;
+       GLuint fb, status;
+
+       for (i = 0; i < TEX_SIZE; i++) {
+               for (j = 0; j < TEX_SIZE; j++) {
+                       tex[i][j][0] = j * 255 / TEX_SIZE;
+                       tex[i][j][1] = i * 255 / TEX_SIZE;
+                       tex[i][j][2] = 128;
+                       if (((i >> 4) ^ (j >> 4)) & 1)
+                               tex[i][j][3] = 255;  /* opaque */
+                       else
+                               tex[i][j][3] = 125;     /* transparent */
+               }
+       }
+
+       memcpy(upperRightTexel, tex[TEX_SIZE-1][TEX_SIZE-1], 4);
+
+       if (init_by_rendering) {
+               /* Initialize the mipmap levels. */
+               for (i = TEX_SIZE, j = 0; i; i >>= 1, j++) {
+                       glTexImage2D(GL_TEXTURE_2D, j, intFormat, i, i, 0,
+                                    GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+               }
+
+               /* Initialize the texture with glDrawPixels. */
+               glGenFramebuffers(1, &fb);
+               glBindFramebuffer(GL_FRAMEBUFFER, fb);
+               glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                      GL_TEXTURE_2D, texture_id, 0);
+               status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+               if (status != GL_FRAMEBUFFER_COMPLETE) {
+                       glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 
piglit_winsys_fbo);
+                       glDeleteFramebuffers(1, &fb);
+                       return GL_FALSE;
+               }
+
+               glViewport(0, 0, TEX_SIZE, TEX_SIZE);
+
+               glWindowPos2iARB(0, 0);
+               glDrawPixels(TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, 
tex);
+               glGenerateMipmap(GL_TEXTURE_2D);
+
+               glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
+               glDeleteFramebuffers(1, &fb);
+               glViewport(0, 0, piglit_width, piglit_height);
+       }
+       else {
+               glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
+               glTexImage2D(GL_TEXTURE_2D, 0, intFormat, TEX_SIZE, TEX_SIZE, 0,
+                            GL_RGBA, GL_UNSIGNED_BYTE, tex);
+       }
+
+       return glGetError() == GL_NO_ERROR;
+}
+
+static GLfloat
+ubyte_to_float(GLubyte b, GLint bits)
+{
+       if (bits <= 8) {
+               GLint b2 = b >> (8 - bits);
+               GLint max = 255 >> (8 - bits);
+               return b2 / (float) max;
+       }
+       else {
+               return b / 255.0;
+       }
+}
+
+
+
+static GLfloat
+bits_to_tolerance(GLint bits, GLboolean compressed)
+{
+       GLfloat t;
+
+       if (bits == 0) {
+               return 0.25;
+       }
+       else if (bits == 1) {
+               return 0.5;
+       }
+       else if (bits > 8) {
+               /* The original texture was specified as GLubyte and we
+                * assume that the window/surface is 8-bits/channel.
+                */
+               t = 4.0 / 255;
+       }
+       else {
+               t = 4.0 / (1 << (bits - 1));
+       }
+
+       if (compressed) {
+               /* Use a fudge factor.  The queries for GL_TEXTURE_RED/
+                * GREEN/BLUE/ALPHA_SIZE don't return well-defined values for
+                * compressed formats so using them is unreliable.  This is
+                * pretty loose, but good enough to catch some Mesa bugs during
+                * development.
+                */
+               t = 0.3;
+       }
+       return t;
+}
+
+
+static void
+compute_expected_color(const struct format_desc *fmt,
+                      const GLubyte upperRightTexel[4],
+                      GLfloat expected[4], GLfloat tolerance[4])
+{
+       GLfloat texel[4];
+       GLint compressed;
+       int bits[4];
+
+       bits[0] = bits[1] = bits[2] = bits[3] = 0;
+
+       /* Handle special cases first */
+       if (fmt->internalformat == GL_R11F_G11F_B10F_EXT) {
+               bits[0] = bits[1] = bits[2] = 8;
+               bits[3] = 0;
+               texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
+               texel[1] = ubyte_to_float(upperRightTexel[1], bits[1]);
+               texel[2] = ubyte_to_float(upperRightTexel[2], bits[2]);
+               texel[3] = 1.0;
+               compressed = GL_FALSE;
+       }
+       else {
+               GLint r, g, b, a, l, i;
+               GLenum baseFormat = 0;
+
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, 
&r);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_GREEN_SIZE, &g);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_BLUE_SIZE, &b);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_ALPHA_SIZE, &a);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_LUMINANCE_SIZE, &l);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_INTENSITY_SIZE, &i);
+               glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, 
GL_TEXTURE_COMPRESSED, &compressed);
+
+               if (0)
+                       printf("r=%d g=%d b=%d a=%d l=%d i=%d\n", r, g, b, a, 
l, i);
+
+               if (i > 0) {
+                       baseFormat = GL_INTENSITY;
+                       bits[0] = i;
+                       bits[1] = 0;
+                       bits[2] = 0;
+                       bits[3] = i;
+                       texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
+                       texel[1] = 0.0;
+                       texel[2] = 0.0;
+                       texel[3] = ubyte_to_float(upperRightTexel[0], bits[3]);
+               }
+               else if (a > 0) {
+                       if (l > 0) {
+                               baseFormat = GL_LUMINANCE_ALPHA;
+                               bits[0] = l;
+                               bits[1] = 0;
+                               bits[2] = 0;
+                               bits[3] = a;
+                               texel[0] = ubyte_to_float(upperRightTexel[0], 
bits[0]);
+                               texel[1] = 0.0;
+                               texel[2] = 0.0;
+                               texel[3] = ubyte_to_float(upperRightTexel[3], 
bits[3]);
+                       }
+                       else if (r > 0 && g > 0 && b > 0) {
+                               baseFormat = GL_RGBA;
+                               bits[0] = r;
+                               bits[1] = g;
+                               bits[2] = b;
+                               bits[3] = a;
+                               texel[0] = ubyte_to_float(upperRightTexel[0], 
bits[0]);
+                               texel[1] = ubyte_to_float(upperRightTexel[1], 
bits[1]);
+                               texel[2] = ubyte_to_float(upperRightTexel[2], 
bits[2]);
+                               texel[3] = ubyte_to_float(upperRightTexel[3], 
bits[3]);
+                       }
+                       else if (r == 0 && g == 0 && b == 0) {
+                               baseFormat = GL_ALPHA;
+                               bits[0] = 0;
+                               bits[1] = 0;
+                               bits[2] = 0;
+                               bits[3] = a;
+                               texel[0] = 0.0;
+                               texel[1] = 0.0;
+                               texel[2] = 0.0;
+                               texel[3] = ubyte_to_float(upperRightTexel[3], 
bits[3]);
+                       }
+                       else {
+                               baseFormat = 0;  /* ??? */
+                               texel[0] = 0.0;
+                               texel[1] = 0.0;
+                               texel[2] = 0.0;
+                               texel[3] = 0.0;
+                       }
+               }
+               else if (l > 0) {
+                       baseFormat = GL_LUMINANCE;
+                       bits[0] = l;
+                       bits[1] = 0;
+                       bits[2] = 0;
+                       bits[3] = 0;
+                       texel[0] = ubyte_to_float(upperRightTexel[0], bits[0]);
+                       texel[1] = 0.0;
+                       texel[2] = 0.0;
+                       texel[3] = 1.0;
+               }
+               else if (r > 0) {
+                       if (g > 0) {
+                               if (b > 0) {
+                                       baseFormat = GL_RGB;
+                                       bits[0] = r;
+                                       bits[1] = g;
+                                       bits[2] = b;
+                                       bits[3] = 0;
+                                       texel[0] = 
ubyte_to_float(upperRightTexel[0], bits[0]);
+                                       texel[1] = 
ubyte_to_float(upperRightTexel[1], bits[1]);
+                                       texel[2] = 
ubyte_to_float(upperRightTexel[2], bits[2]);
+                                       texel[3] = 1.0;
+                               }
+                               else {
+                                       baseFormat = GL_RG;
+                                       bits[0] = r;
+                                       bits[1] = g;
+                                       bits[2] = 0;
+                                       bits[3] = 0;
+                                       texel[0] = 
ubyte_to_float(upperRightTexel[0], bits[0]);
+                                       texel[1] = 
ubyte_to_float(upperRightTexel[1], bits[1]);
+                                       texel[2] = 0.0;
+                                       texel[3] = 1.0;
+                               }
+                       }
+                       else {
+                               baseFormat = GL_RED;
+                               bits[0] = r;
+                               bits[1] = 0;
+                               bits[2] = 0;
+                               bits[3] = 0;
+                               texel[0] = ubyte_to_float(upperRightTexel[0], 
bits[0]);
+                               texel[1] = 0.0;
+                               texel[2] = 0.0;
+                               texel[3] = 1.0;
+                       }
+               } else {
+                       assert(!"Unexpected texture component sizes");
+                       texel[0] = 0.0;
+                       texel[1] = 0.0;
+                       texel[2] = 0.0;
+                       texel[3] = 0.0;
+               }
+
+               (void) baseFormat;  /* not used, at this time */
+       }
+
+       /* compute texel color blended with background color */
+#if DO_BLEND
+       expected[0] = texel[0] * texel[3] + clearColor[0] * (1.0 - texel[3]);
+       expected[1] = texel[1] * texel[3] + clearColor[1] * (1.0 - texel[3]);
+       expected[2] = texel[2] * texel[3] + clearColor[2] * (1.0 - texel[3]);
+       expected[3] = texel[3] * texel[3] + clearColor[3] * (1.0 - texel[3]);
+#else
+        expected[0] = texel[0];
+        expected[1] = texel[1];
+        expected[2] = texel[2];
+        expected[3] = texel[3];
+#endif
+
+       assert(expected[0] == expected[0]);
+
+       tolerance[0] = bits_to_tolerance(bits[0], compressed);
+       tolerance[1] = bits_to_tolerance(bits[1], compressed);
+       tolerance[2] = bits_to_tolerance(bits[2], compressed);
+       tolerance[3] = bits_to_tolerance(bits[3], compressed);
+}
+
+
+static GLboolean
+colors_equal(const GLfloat expected[4], const GLfloat pix[4],
+            GLfloat tolerance[4])
+{
+       if (fabsf(expected[0] - pix[0]) > tolerance[0] ||
+                fabsf(expected[1] - pix[1]) > tolerance[1] ||
+                fabsf(expected[2] - pix[2]) > tolerance[2] ||
+                fabsf(expected[3] - pix[3]) > tolerance[3]) {
+               return GL_FALSE;
+       }
+       return GL_TRUE;
+}
+
+
+static GLboolean
+test_format(const struct test_desc *test,
+           const struct format_desc *fmt)
+{
+       int x, y;
+       int w = TEX_SIZE, h = TEX_SIZE;
+       GLfloat readback[TEX_SIZE][TEX_SIZE][4];
+       GLubyte upperRightTexel[4];
+       int level;
+       GLfloat expected[4], pix[4], tolerance[4];
+       GLboolean pass = GL_TRUE;
+
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       /* The RGBA_DXT1 formats seem to expose a Mesa/libtxc_dxtn bug.
+        * Just skip them for now.  Testing the other compressed formats
+        * is good enough.
+        */
+       if (fmt->internalformat != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT &&
+           fmt->internalformat != GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) {
+               /* init texture image */
+               if (!make_texture_image(fmt->internalformat, upperRightTexel))
+                       return GL_TRUE; /* unsupported = OK */
+
+               x = 10;
+               y = 40;
+
+               compute_expected_color(fmt, upperRightTexel, expected, 
tolerance);
+
+               /* Draw with the texture */
+               glEnable(GL_TEXTURE_2D);
+#if DO_BLEND
+               glEnable(GL_BLEND);
+#endif
+               piglit_draw_rect_tex(x, y, w, h,  0.0, 0.0, 1.0, 1.0);
+               glDisable(GL_TEXTURE_2D);
+               glDisable(GL_BLEND);
+
+               x += TEX_SIZE + 20;
+
+               level = 0;
+               while (w > 0) {
+                       /* Get the texture image */
+                       assert(!glIsEnabled(GL_TEXTURE_2D));
+                       glGetTextureImage(texture_id, level, GL_RGBA,
+                                         GL_FLOAT, sizeof(readback),
+                                         readback);
+
+                       assert(!glIsEnabled(GL_TEXTURE_2D));
+                       /* Draw the texture image */
+                       glWindowPos2iARB(x, y);
+#if DO_BLEND
+                       glEnable(GL_BLEND);
+#endif
+                       assert(!glIsEnabled(GL_TEXTURE_2D));
+                       glDrawPixels(w, h, GL_RGBA, GL_FLOAT, readback);
+                       glDisable(GL_BLEND);
+
+                       assert(!glIsEnabled(GL_TEXTURE_2D));
+
+                       if (level <= 2) {
+                               GLint rx = x + w-1;
+                               GLint ry = y + h-1;
+                               glReadPixels(rx, ry, 1, 1, GL_RGBA, GL_FLOAT, 
pix);
+                               if (!colors_equal(expected, pix, tolerance)) {
+                                       printf("%s failure: format: %s, level 
%d at pixel(%d, %d)\n",
+                                                        TestName, fmt->name, 
level, rx, ry);
+                                       printf(" Expected (%f, %f, %f, %f)\n",
+                                                        expected[0], 
expected[1], expected[2], expected[3]);
+                                       printf("         Found (%f, %f, %f, 
%f)\n",
+                                                        pix[0], pix[1], 
pix[2], pix[3]);
+                                       printf("Tolerance (%f, %f, %f, %f)\n",
+                                                        tolerance[0], 
tolerance[1], tolerance[2], tolerance[3]);
+                                       pass = GL_FALSE;
+                               }
+                       }
+
+                       x += w + 20;
+                       w /= 2;
+                       h /= 2;
+                       level++;
+               }
+
+       }
+
+       piglit_present_results();
+
+       return pass;
+}
+
+
+/**
+ * Is the given set of formats supported?
+ * This checks if required extensions are present and if this piglit test
+ * can actually grok the formats.
+ */
+static GLboolean
+supported_format_set(const struct test_desc *set)
+{
+       if (!supported(set))
+               return GL_FALSE;
+
+       if (set->format == ext_texture_integer ||
+                set->format == ext_packed_depth_stencil ||
+                set->format == arb_texture_rg_int ||
+                set->format == arb_depth_texture ||
+                set->format == arb_depth_buffer_float) {
+               /*
+                * texture_integer requires a fragment shader, different
+                * glTexImage calls.  Depth/stencil formats not implemented.
+                */
+               return GL_FALSE;
+       }
+
+       return GL_TRUE;
+}
+
+
+static GLboolean
+test_all_formats(void)
+{
+       GLboolean pass = GL_TRUE;
+       int i, j;
+
+       for (i = 0; i < ARRAY_SIZE(test_sets); i++) {
+               const struct test_desc *set = &test_sets[i];
+               if (supported_format_set(set)) {
+                       for (j = 0; j < set->num_formats; j++) {
+                               if (!test_format(set, &set->format[j])) {
+                                       pass = GL_FALSE;
+                               }
+                       }
+               }
+       }
+
+       return pass;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       GLboolean pass;
+
+       piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+
+       if (piglit_automatic) {
+               pass = test_all_formats();
+       }
+       else {
+               const struct test_desc *set = &test_sets[test_index];
+               if (supported_format_set(set)) {
+                       pass = test_format(set, &set->format[format_index]);
+               }
+               else {
+                       /* unsupported format - not a failure */
+                       pass = GL_TRUE;
+                       glClear(GL_COLOR_BUFFER_BIT);
+                       piglit_present_results();
+               }
+       }
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       int i;
+
+       piglit_require_extension("GL_ARB_direct_state_access");
+
+       if ((piglit_get_gl_version() < 14) && 
!piglit_is_extension_supported("GL_ARB_window_pos")) {
+               printf("Requires GL 1.4 or GL_ARB_window_pos");
+               piglit_report_result(PIGLIT_SKIP);
+       }
+
+       fbo_formats_init(1, argv, !piglit_automatic);
+       (void) fbo_formats_display;
+
+       for (i = 1; i < argc; i++) {
+               if (strcmp(argv[i], "init-by-rendering") == 0) {
+                       init_by_rendering = GL_TRUE;
+                       puts("The textures will be initialized by rendering "
+                            "to them using glDrawPixels.");
+                       break;
+               }
+       }
+
+       glGenTextures(1, &texture_id);
+       glBindTexture(GL_TEXTURE_2D, texture_id);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+       glClearColor(clearColor[0], clearColor[1], clearColor[2], 
clearColor[3]);
+}
diff --git a/tests/spec/arb_direct_state_access/gettextureimage-luminance.c 
b/tests/spec/arb_direct_state_access/gettextureimage-luminance.c
new file mode 100644
index 0000000..3add1d7
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/gettextureimage-luminance.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2012 VMware, Inc.
+ * Copyright (c) 2014 Intel Corporation
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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
+ * NON-INFRINGEMENT.  IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
+ * 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 glGetTexImage for luminance formats.
+ * Brian Paul
+ * 8 Mar 2012
+ *
+ * Adapted for testing glGetTextureImage in ARB_direct_state_access by
+ * Laura Ekstrand <la...@jlekstrand.net>, November 2014.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 10;
+
+       config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "gettextureimage-luminance";
+static float tolerance = 3.0 / 255.0;
+
+
+static bool
+rgba_equal(const float *c1, const float *c2)
+{
+       return ((fabs(c1[0] - c2[0]) < tolerance) &&
+               (fabs(c1[1] - c2[1]) < tolerance) &&
+               (fabs(c1[2] - c2[2]) < tolerance) &&
+               (fabs(c1[3] - c2[3]) < tolerance));
+}
+
+
+static bool
+lum_equal(const float *l1, const float *l2)
+{
+       return fabs(*l1 - *l2) < tolerance;
+}
+
+
+/*
+ * Test reading back a luminance texture as luminance and RGBA.
+ */
+static bool
+test_luminance(void)
+{
+       static const GLfloat lumImage[2*2] = { 0.25, 0.25, 0.25, 0.25 };
+       static const GLfloat rgbaImage[4] = { 0.25, 0.0, 0.0, 1.0 };
+       GLuint tex;
+       GLfloat test[2*2*4];
+
+       /* create 2x2 GL_LUMINANCE texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0,
+                    GL_LUMINANCE, GL_FLOAT, lumImage);
+
+       /* Get and check luminance image */
+       glGetTextureImage(tex, 0, GL_LUMINANCE, GL_FLOAT, sizeof(test), test);
+       if (!lum_equal(lumImage, test)) {
+               printf("%s: glGetTextureImage(GL_LUMINANCE as"
+                      " GL_LUMINANCE) failed\n", TestName);
+               printf("  Expected %g  Found %g\n", lumImage[0], test[0]);
+               return false;
+       }
+
+       /* Get and check rgba image */
+       glGetTextureImage(tex, 0, GL_RGBA, GL_FLOAT, sizeof(test), &test);
+       if (!rgba_equal(rgbaImage, test)) {
+               printf("%s: glGetTextureImage(GL_LUMINANCE as"
+                      " GL_RGBA) failed\n", TestName);
+               printf("  Expected %g, %g, %g, %g  Found %g, %g, %g, %g\n",
+                      rgbaImage[0], rgbaImage[1], rgbaImage[2], rgbaImage[3],
+                      test[0], test[1], test[2], test[3]);
+               return false;
+       }
+
+       return true;
+}
+
+
+/*
+ * Test reading back an RGBA texture as luminance.
+ */
+static bool
+test_rgba(void)
+{
+       static const GLfloat rgbaImage[4] = { 0.5, 0.25, 0.125, 1.0 };
+       static const GLfloat lumImage[1] = { 0.5 };
+       GLuint tex;
+       GLfloat test[2*2*4];
+
+       /* create 1x1 GL_RGBA texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
+                    GL_RGBA, GL_FLOAT, rgbaImage);
+
+       /* Get and check luminance image */
+       glGetTextureImage(tex, 0, GL_LUMINANCE, GL_FLOAT, sizeof(test), test);
+       if (!lum_equal(lumImage, test)) {
+               printf("%s: glGetTextureImage(GL_RGBA as"
+                      " GL_LUMINANCE) failed\n", TestName);
+               printf("  Expected %g  Found %g\n", lumImage[0], test[0]);
+               return false;
+       }
+
+       return true;
+}
+
+
+/*
+ * Test reading back a luminance texture via FBO + glReadPixels as RGBA.
+ */
+static bool
+test_fbo_readpixels_lum_as_rgba(void)
+{
+       static const GLfloat lumImage[2*2] = { 0.25, 0.25, 0.25, 0.25 };
+       static const GLfloat rgbaImage[4] = { 0.25, 0.0, 0.0, 1.0 };
+       GLuint tex, fbo;
+       GLfloat test[2*2*4];
+       GLenum status;
+
+       if (!piglit_is_extension_supported("GL_ARB_framebuffer_object"))
+               return true;
+
+       /* create 2x2 GL_LUMINANCE texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 2, 2, 0,
+                    GL_LUMINANCE, GL_FLOAT, lumImage);
+
+       /* create an FBO to wrap the texture so we can read it back
+        * with glReadPixels
+        */
+       glGenFramebuffers(1, &fbo);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
+                              GL_TEXTURE_2D, tex, 0);
+
+       status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+               /* can't test glReadPixels from a luminance fbo/texture */
+               if (!piglit_automatic) {
+                       printf("Skipping FBO ReadPixels test\n");
+               }
+               return true;
+       }
+
+       /* get rgba image (only red should have the lum value) */
+       glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, test);
+       if (!rgba_equal(rgbaImage, test)) {
+               printf("%s: glReadPixels(GL_LUMINANCE as GL_RGBA) failed\n",
+                      TestName);
+               printf("  Expected %g, %g, %g, %g  Found %g, %g, %g, %g\n",
+                      rgbaImage[0], rgbaImage[1], rgbaImage[2], rgbaImage[3],
+                      test[0], test[1], test[2], test[3]);
+               return false;
+       }
+
+       return true;
+}
+
+
+/*
+ * Test reading back an RGBA texture via FBO + glReadPixels as luminance.
+ */
+static bool
+test_fbo_readpixels_rgba_as_lum(void)
+{
+       static const GLfloat rgbaImage[4] = { 0.5, 0.25, 0.125, 1.0 };
+       static const GLfloat lumImage[1] = { 0.5 + 0.25 + 0.125 };
+       GLuint tex, fbo;
+       GLfloat test[1];
+       GLenum status;
+
+       if (!piglit_is_extension_supported("GL_ARB_framebuffer_object"))
+               return true;
+
+       /* create 1x1 GL_RGBA texture */
+       glGenTextures(1, &tex);
+       glBindTexture(GL_TEXTURE_2D, tex);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
+                    GL_RGBA, GL_FLOAT, rgbaImage);
+
+       /* create an FBO to wrap the texture so we can read it back
+        * with glReadPixels
+        */
+       glGenFramebuffers(1, &fbo);
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT,
+                              GL_TEXTURE_2D, tex, 0);
+
+       status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
+       if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+               /* something failed with FBO setup, ignore it */
+               if (!piglit_automatic) {
+                       printf("Skipping FBO ReadPixels test\n");
+               }
+               return true;
+       }
+
+       /* get luminance image, should be sum of RGB values */
+       glReadPixels(0, 0, 1, 1, GL_LUMINANCE, GL_FLOAT, test);
+       if (!lum_equal(lumImage, test)) {
+               printf("%s: glReadPixels(GL_RGBA as GL_LUMINANCE) failed\n",
+                      TestName);
+               printf("  Expected %g  Found %g\n", lumImage[0], test[0]);
+               return false;
+       }
+
+       return true;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+       bool pass = true;
+
+       pass = test_luminance() && pass;
+       pass = test_rgba() && pass;
+       pass = test_fbo_readpixels_lum_as_rgba() && pass;
+       pass = test_fbo_readpixels_rgba_as_lum() && pass;
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_direct_state_access");
+       piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
+}
diff --git a/tests/spec/arb_direct_state_access/gettextureimage-simple.c 
b/tests/spec/arb_direct_state_access/gettextureimage-simple.c
new file mode 100644
index 0000000..081caaa
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/gettextureimage-simple.c
@@ -0,0 +1,86 @@
+/**
+ * @file gettextureimage-simple.c
+ *
+ * Extremely basic test to check whether image data can be retrieved.
+ *
+ * Note that the texture is used in a full frame of rendering before
+ * the readback, to ensure that buffer manager related code for uploading
+ * texture images is executed before the readback.
+ *
+ * This used to crash for R300+bufmgr.
+ *
+ * Adapted for testing glGetTextureImage in ARB_direct_state_access by
+ * Laura Ekstrand <la...@jlekstrand.net>, November 2014.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 10;
+
+       config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static GLubyte data[4096]; /* 64*16*4 */
+static GLuint name; /* texture name */
+
+static int test_getteximage(void)
+{
+       GLubyte compare[4096];
+       int i;
+
+       glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                         sizeof(compare), compare);
+
+       for(i = 0; i < 4096; ++i) {
+               if (data[i] != compare[i]) {
+                       printf("GetTextureImage() returns incorrect data in 
byte %i\n", i);
+                       printf("    corresponding to (%i,%i) channel %i\n", i / 
64, (i / 4) % 16, i % 4);
+                       printf("    expected: %i\n", data[i]);
+                       printf("    got: %i\n", compare[i]);
+                       return 0;
+               }
+       }
+
+       return 1;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+       int pass;
+
+       glClearColor(0.0, 0.0, 0.0, 1.0);
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+       glEnable(GL_TEXTURE_2D);
+       glBindTextureUnit(0, name);
+       piglit_draw_rect_tex(0, 0, 1, 1, 0, 0, 1, 1);
+
+       piglit_present_results();
+
+       pass = test_getteximage();
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       int i;
+       piglit_require_extension("GL_ARB_direct_state_access");
+
+       for(i = 0; i < 4096; ++i)
+               data[i] = rand() & 0xff;
+
+       glCreateTextures(GL_TEXTURE_2D, 1, &name);
+       glTextureParameteri(name, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       glTextureParameteri(name, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTextureStorage2D(name, 1, GL_RGBA8, 64, 16);
+       glTextureSubImage2D(name, 0, 0, 0, 64, 16, GL_RGBA, GL_UNSIGNED_BYTE,
+                           data);
+
+       piglit_gen_ortho_projection(0.0, 1.0, 0.0, 1.0, -2.0, 6.0, GL_FALSE);
+}
diff --git a/tests/spec/arb_direct_state_access/gettextureimage-targets.c 
b/tests/spec/arb_direct_state_access/gettextureimage-targets.c
new file mode 100644
index 0000000..b827a12
--- /dev/null
+++ b/tests/spec/arb_direct_state_access/gettextureimage-targets.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright © 2012 Marek Olšák <mar...@gmail.com>
+ * Copyright © 2014 Intel Corporation
+ *
+ * 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.
+ */
+
+/**
+ * @file gettextureimage-targets.c
+ *
+ * Adapted for testing glGetTextureImage in ARB_direct_state_access by
+ * Laura Ekstrand <la...@jlekstrand.net>, November 2014.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+       config.supports_gl_compat_version = 10;
+
+       config.window_visual = PIGLIT_GL_VISUAL_RGBA |
+                              PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define IMAGE_WIDTH 32
+#define IMAGE_HEIGHT 32
+#define IMAGE_SIZE (IMAGE_WIDTH * IMAGE_HEIGHT * 4)
+
+static void
+init_layer_data(GLubyte *layer_data, int num_layers)
+{
+       int x, y, z, i, j;
+
+       for (z = 0; z < num_layers; z++) {
+               GLubyte *data = layer_data + IMAGE_SIZE * z;
+
+               for (x = 0; x < IMAGE_WIDTH; x += 4) {
+                       for (y = 0; y < IMAGE_HEIGHT; y += 4) {
+                               int r = (x + 1) * 255 / (IMAGE_WIDTH - 1);
+                               int g = (y + 1) * 255 / (IMAGE_HEIGHT - 1);
+                               int b = (z + 1) * 255 / (num_layers - 1);
+                               int a = x ^ y ^ z;
+
+                               /* each 4x4 block constains only one color (for 
S3TC) */
+                               for (i = 0; i < 4; i++) {
+                                       for (j = 0; j < 4; j++) {
+                                               data[((y + j) * IMAGE_WIDTH + x
+                                                     + i) * 4 + 0] = r;
+                                               data[((y + j) * IMAGE_WIDTH + x
+                                                     + i) * 4 + 1] = g;
+                                               data[((y + j) * IMAGE_WIDTH + x
+                                                     + i) * 4 + 2] = b;
+                                               data[((y + j) * IMAGE_WIDTH + x
+                                                     + i) * 4 + 3] = a;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+static bool
+compare_layer(int layer, int num_elements, int tolerance,
+                         GLubyte *data, GLubyte *expected)
+{
+       int i;
+
+       for (i = 0; i < num_elements; ++i) {
+               if (abs((int)data[i] - (int)expected[i]) > tolerance) {
+                       printf("GetTextureImage() returns incorrect data in 
byte %i for layer %i\n",
+                              i, layer);
+                       printf("    corresponding to (%i,%i), channel %i\n",
+                              (i / 4) / IMAGE_WIDTH, (i / 4) % IMAGE_HEIGHT, i 
% 4);
+                       printf("    expected: %i\n", expected[i]);
+                       printf("    got: %i\n", data[i]);
+                       return false;
+               }
+       }
+       return true;
+}
+
+static bool
+getTexImage(bool doPBO, GLenum target, GLubyte data[][IMAGE_SIZE],
+           GLenum internalformat, int tolerance)
+{
+       int i;
+       int num_layers=1, num_faces=1, layer_size;
+       GLubyte data2[18][IMAGE_SIZE];
+       GLubyte *dataGet;
+       GLuint packPBO;
+       bool pass = true;
+       GLuint name;
+
+       switch (target) {
+       case GL_TEXTURE_1D:
+               glCreateTextures(target, 1, &name);
+               glTextureStorage1D(name, 1, internalformat, IMAGE_WIDTH);
+               glTextureSubImage1D(name, 0, 0, IMAGE_WIDTH, GL_RGBA,
+                                   GL_UNSIGNED_BYTE, data);
+               layer_size = IMAGE_WIDTH * 4;
+               break;
+
+       case GL_TEXTURE_2D:
+       case GL_TEXTURE_RECTANGLE:
+               glCreateTextures(target, 1, &name);
+               glTextureStorage2D(name, 1, internalformat, IMAGE_WIDTH,
+                                  IMAGE_HEIGHT);
+               glTextureSubImage2D(name, 0, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, data);
+               layer_size = IMAGE_SIZE;
+               break;
+
+       case GL_TEXTURE_CUBE_MAP:
+               num_faces = 6;
+               glCreateTextures(target, 1, &name);
+               /* This is invalid. You must use 2D storage call for cube. */
+               glTextureStorage3D(name, 1, internalformat,
+                                  IMAGE_WIDTH, IMAGE_HEIGHT, num_faces);
+               pass &= piglit_check_gl_error(GL_INVALID_ENUM);
+               glTextureStorage2D(name, 1, internalformat,
+                                  IMAGE_WIDTH, IMAGE_HEIGHT);
+               /* This is legal. */
+               glTextureSubImage3D(name, 0, 0, 0, 0, IMAGE_WIDTH,
+                                   IMAGE_HEIGHT, num_faces, GL_RGBA,
+                                   GL_UNSIGNED_BYTE, data);
+               layer_size = IMAGE_SIZE;
+               break;
+
+       case GL_TEXTURE_1D_ARRAY:
+               num_layers = 7;
+               glCreateTextures(target, 1, &name);
+               // test as a single layer 2D image
+               glTextureStorage2D(name, 1, internalformat, IMAGE_WIDTH,
+                                  num_layers);
+               glTextureSubImage2D(name, 0, 0, 0, IMAGE_WIDTH, num_layers,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, data);
+               layer_size = IMAGE_WIDTH * 4 * num_layers;
+               num_layers = 1;
+               break;
+
+       case GL_TEXTURE_3D:
+               num_layers = 16; /* Fall through. */
+       case GL_TEXTURE_2D_ARRAY:
+               num_layers = 7; /* Fall through. */
+       case GL_TEXTURE_CUBE_MAP_ARRAY:
+               num_layers = 6 * 3;
+               glCreateTextures(target, 1, &name);
+               glTextureStorage3D(name, 1, internalformat, IMAGE_WIDTH,
+                                  IMAGE_HEIGHT, num_layers);
+               glTextureSubImage3D(name, 0, 0, 0, 0,
+                                   IMAGE_WIDTH, IMAGE_HEIGHT, num_layers,
+                                   GL_RGBA, GL_UNSIGNED_BYTE, data);
+               layer_size = IMAGE_SIZE;
+               break;
+
+       default:
+               puts("Invalid texture target.");
+               return false;
+
+       }
+
+       /* Setup the PBO or data array to read into from glGetTextureImage */
+       if (doPBO) {
+               glGenBuffers(1, &packPBO);
+               glBindBuffer(GL_PIXEL_PACK_BUFFER, packPBO);
+               glBufferData(GL_PIXEL_PACK_BUFFER,
+                                    layer_size * num_faces * num_layers,
+                                    NULL, GL_STREAM_READ);
+       } else {
+               glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+               memset(data2, 123, sizeof(data2));
+       }
+       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+       assert(num_layers * num_faces * layer_size <= sizeof(data2));
+
+       if (doPBO) {
+               glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                       layer_size * num_faces * num_layers, NULL);
+       }
+       else {
+               glGetTextureImage(name, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                       layer_size * num_faces * num_layers, data2);
+       }
+       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+
+       if (doPBO)
+               dataGet = (GLubyte *) glMapBufferRange(
+                                              GL_PIXEL_PACK_BUFFER, 0,
+                                              layer_size * num_layers *
+                                              num_faces,
+                                              GL_MAP_READ_BIT);
+       else
+               dataGet = data2[0];
+
+       for (i = 0; i < num_faces * num_layers; i++) {
+               pass = compare_layer(i, layer_size, tolerance, dataGet,
+                                    data[i]) && pass;
+               dataGet += layer_size;
+       }
+
+       if (doPBO) {
+               glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
+               glDeleteBuffers(1, &packPBO);
+       }
+
+       glDeleteTextures(1, &name);
+
+       return pass;
+}
+
+struct target_and_mask {
+       GLenum target;
+       bool mask;
+};
+
+static struct target_and_mask targets[] = {
+       {GL_TEXTURE_1D, 1},
+       {GL_TEXTURE_2D, 1},
+       {GL_TEXTURE_3D, 1},
+       {GL_TEXTURE_RECTANGLE, 1},
+       {GL_TEXTURE_CUBE_MAP, 1},
+       {GL_TEXTURE_1D_ARRAY, 1},
+       {GL_TEXTURE_2D_ARRAY, 1},
+       {GL_TEXTURE_CUBE_MAP_ARRAY, 1},
+};
+
+static void
+clear_target_mask(GLenum target)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(targets); ++i) {
+               if (targets[i].target == target) {
+                       targets[i].mask = 0;
+               }
+       }
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+       piglit_require_extension("GL_ARB_direct_state_access");
+
+       if (piglit_get_gl_version() < 12)
+               clear_target_mask(GL_TEXTURE_3D);
+       if (!piglit_is_extension_supported("GL_ARB_texture_rectangle"))
+               clear_target_mask(GL_TEXTURE_RECTANGLE);
+       if (!piglit_is_extension_supported("GL_ARB_texture_cube_map"))
+               clear_target_mask(GL_TEXTURE_CUBE_MAP);
+       if (!piglit_is_extension_supported("GL_EXT_texture_array")) {
+               clear_target_mask(GL_TEXTURE_1D_ARRAY);
+               clear_target_mask(GL_TEXTURE_2D_ARRAY);
+       }
+       if (!piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
+               clear_target_mask(GL_TEXTURE_CUBE_MAP_ARRAY);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+       int i;
+       bool pass = true;
+       GLenum internalformat = GL_RGBA8;
+       int tolerance = 0;
+       GLubyte data[18][IMAGE_SIZE];
+
+       init_layer_data(data[0], 18);
+
+       for (i = 0; i < ARRAY_SIZE(targets); ++i) {
+               if (!targets[i].mask)
+                       continue;
+
+               printf("Testing %s into PBO\n", 
+                       piglit_get_gl_enum_name(targets[i].target));
+               pass &= getTexImage(true, targets[i].target, data,
+                                   internalformat, tolerance);
+
+               printf("Testing %s into client array\n",
+                       piglit_get_gl_enum_name(targets[i].target));
+               pass &= getTexImage(false, targets[i].target, data, 
+                                   internalformat, tolerance);
+
+               pass &= piglit_check_gl_error(GL_NO_ERROR);
+       }
+
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
-- 
2.1.0

_______________________________________________
Piglit mailing list
Piglit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/piglit

Reply via email to