getteximage-depth: new test to create/readback depth textures

Submitted by Dave Airlie on Nov. 3, 2015, 12:24 a.m.

Details

Message ID 1446510296-13635-1-git-send-email-airlied@gmail.com
State New
Headers show
Series "getteximage-depth: new test to create/readback depth textures" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Dave Airlie Nov. 3, 2015, 12:24 a.m.
From: Dave Airlie <airlied@redhat.com>

for every supported target for all the depth/stencil formats
this creates a texture, and then uses glGetTexImage
to read it back.
---
 tests/texturing/CMakeLists.gl.txt   |   1 +
 tests/texturing/getteximage-depth.c | 628 ++++++++++++++++++++++++++++++++++++
 2 files changed, 629 insertions(+)
 create mode 100644 tests/texturing/getteximage-depth.c

Patch hide | download patch | download mbox

diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
index 68afa16..704ea6d 100644
--- a/tests/texturing/CMakeLists.gl.txt
+++ b/tests/texturing/CMakeLists.gl.txt
@@ -34,6 +34,7 @@  piglit_add_executable (getteximage-formats getteximage-formats.c)
 piglit_add_executable (getteximage-simple getteximage-simple.c)
 piglit_add_executable (getteximage-luminance getteximage-luminance.c)
 piglit_add_executable (getteximage-targets getteximage-targets.c)
+piglit_add_executable (getteximage-depth getteximage-depth.c)
 piglit_add_executable (incomplete-texture incomplete-texture.c)
 piglit_add_executable (generatemipmap-cubemap generatemipmap-cubemap.c)
 piglit_add_executable (fragment-and-vertex-texturing fragment-and-vertex-texturing.c)
diff --git a/tests/texturing/getteximage-depth.c b/tests/texturing/getteximage-depth.c
new file mode 100644
index 0000000..71311bc
--- /dev/null
+++ b/tests/texturing/getteximage-depth.c
@@ -0,0 +1,628 @@ 
+/*
+ * Copyright (c) 2015 Red Hat
+ *
+ * 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 getteximage-depth
+ *
+ * Test glGetTexImage for depth/stencil format/target combinations in a roundtrip.
+ * i.e. don't draw the textures, just create and readback.
+ * this was due to a bug in mesa's handling of 1D array depth textures.
+ */
+
+#include "piglit-util-gl.h"
+#include "../fbo/fbo-formats.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
+
+enum piglit_result
+piglit_display(void)
+{
+	/* UNREACHABLE */
+	return PIGLIT_FAIL;
+}
+
+#define IMAGE_WIDTH 32
+#define IMAGE_HEIGHT 32
+
+static GLenum target_list[] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,  GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY };
+
+static int test_target_bitmap;
+
+static int get_test_height(GLenum target)
+{
+	switch (target) {
+	case GL_TEXTURE_1D:
+	case GL_TEXTURE_1D_ARRAY:
+		return 1;
+	default:
+		return IMAGE_HEIGHT;
+	}
+}
+
+static int get_test_depth(GLenum target)
+{
+	switch (target) {
+	case GL_TEXTURE_3D:
+		return 16;
+	case GL_TEXTURE_1D_ARRAY:
+	case GL_TEXTURE_2D_ARRAY:
+		return 7;
+	case GL_TEXTURE_CUBE_MAP_ARRAY:
+		return 12;
+	case GL_TEXTURE_CUBE_MAP:
+		return 6;
+	default:
+		return 1;
+	}
+}
+
+static float get_depth_value(int w, int x)
+{
+	if (w == 1)
+		return 1.0;
+	else
+		return (float)(x) / (w - 1);
+}
+
+static int get_stencil_value(int w, int x)
+{
+	if (w == 1)
+		return 255;
+	else
+		return (x * 255) / (w - 1);
+}
+
+static GLuint
+get_depth_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)
+{
+	void *data;
+	float *f = NULL;
+	unsigned int  *i = NULL;
+	int size, x, y, level, layer;
+	GLuint tex;
+	GLuint extra = 0;
+	GLenum datatype, dataformat;
+	int mul = 1;
+
+	glGenTextures(1, &tex);
+	glBindTexture(target, tex);
+	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	if (mip) {
+		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+				GL_LINEAR);
+		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+				GL_LINEAR_MIPMAP_NEAREST);
+	} else {
+		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+				GL_NEAREST);
+		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+				GL_NEAREST);
+	}
+	if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+		mul = 2;
+	}
+	extra = d * sizeof(GLfloat) * mul;
+
+	data = calloc(1, w * h * sizeof(GLfloat) * mul + extra);
+
+	if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
+	    format->internalformat == GL_DEPTH24_STENCIL8_EXT) {
+		dataformat = GL_DEPTH_STENCIL_EXT;
+		datatype = GL_UNSIGNED_INT_24_8_EXT;
+		i = data;
+	} else if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+		dataformat = GL_DEPTH_STENCIL;
+		datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+		f = data;
+	} else {
+		dataformat = GL_DEPTH_COMPONENT;
+		datatype = GL_FLOAT;
+		f = data;
+	}
+
+	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+		for (y = 0; y < h; y++) {
+			for (x = 0; x < w; x++) {
+				float val = get_depth_value(w, x);
+
+				if (f)
+					f[(y * w + x)*mul] = val;
+				else
+					i[y * w + x] = 0xffffff00 * val;
+			}
+		}
+
+		for (x = 0; x < d; x++) {
+			float val = get_depth_value(w, x % w);
+
+			if (f)
+				f[(h * w + x)*mul] = val;
+			else
+				i[h * w + x] = 0xffffff00 * val;
+		}
+
+		switch (target) {
+		case GL_TEXTURE_1D:
+			glTexImage1D(target, level,
+				     format->internalformat,
+				     w, 0,
+				     dataformat, datatype, data);
+			break;
+		case GL_TEXTURE_2D:
+		case GL_TEXTURE_RECTANGLE:
+			glTexImage2D(target, level,
+				     format->internalformat,
+				     w, h, 0,
+				     dataformat, datatype, data);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			assert(d == 6);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer * 4 * mul;
+				glTexImage2D(cube_face_targets[layer],
+					     level, format->internalformat,
+					     w, h, 0,
+					     dataformat, datatype, ptr);
+			}
+			break;
+		case GL_TEXTURE_1D_ARRAY:
+			glTexImage2D(target, level,
+				     format->internalformat,
+				     w, d, 0,
+				     dataformat, datatype, NULL);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer * (4 * mul);
+				glTexSubImage2D(target, level,
+						0, layer, w, 1,
+						dataformat, datatype, ptr);
+			}
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+		case GL_TEXTURE_CUBE_MAP_ARRAY:
+			glTexImage3D(target, level,
+				     format->internalformat,
+				     w, h, d, 0,
+				     dataformat, datatype, NULL);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer * (4 * mul);
+				glTexSubImage3D(target, level,
+						0, 0, layer, w, h, 1,
+						dataformat, datatype, ptr);
+			}
+			break;
+
+		default:
+			assert(0);
+		}
+
+		if (!mip)
+			break;
+
+		if (w > 1)
+			w >>= 1;
+		if (target != GL_TEXTURE_1D &&
+		    target != GL_TEXTURE_1D_ARRAY &&
+		    h > 1)
+			h >>= 1;
+	}
+	free(data);
+	return tex;
+}
+
+static GLuint
+get_stencil_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)
+{
+	void *data;
+	unsigned char *u;
+	int size, x, y, level, layer;
+	GLuint tex;
+	GLenum datatype, dataformat;
+
+	glGenTextures(1, &tex);
+	glBindTexture(target, tex);
+	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+	if (mip) {
+		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+				GL_LINEAR);
+		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+				GL_LINEAR_MIPMAP_NEAREST);
+	} else {
+		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
+				GL_NEAREST);
+		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
+				GL_NEAREST);
+	}
+	data = malloc(w * h * sizeof(GLubyte) + d * sizeof(GLubyte));
+
+	dataformat = GL_STENCIL_INDEX;
+	datatype = GL_UNSIGNED_BYTE;
+	u = data;
+	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+		for (y = 0; y < h; y++) {
+			for (x = 0; x < w; x++) {
+				GLuint val = get_stencil_value(w, x);
+
+				u[y * w + x] = val;
+			}
+		}
+
+		for (x = 0; x < d; x++) {
+			GLuint val = get_stencil_value(w, x % w);
+			u[h * w + x] = val;
+		}
+
+		switch (target) {
+		case GL_TEXTURE_1D:
+			glTexImage1D(target, level,
+				     format->internalformat,
+				     w, 0,
+				     dataformat, datatype, data);
+			break;
+
+		case GL_TEXTURE_2D:
+		case GL_TEXTURE_RECTANGLE:
+			glTexImage2D(target, level,
+				     format->internalformat,
+				     w, h, 0,
+				     dataformat, datatype, data);
+			break;
+		case GL_TEXTURE_CUBE_MAP:
+			assert(d == 6);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer;
+				glTexImage2D(cube_face_targets[layer],
+					     level, format->internalformat,
+					     w, h, 0,
+					     dataformat, datatype, ptr);
+			}
+			break;
+		case GL_TEXTURE_1D_ARRAY:
+			glTexImage2D(target, level,
+				     format->internalformat,
+				     w, d, 0,
+				     dataformat, datatype, NULL);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer;
+				glTexSubImage2D(target, level,
+						0, layer, w, 1,
+						dataformat, datatype, ptr);
+			}
+			break;
+		case GL_TEXTURE_CUBE_MAP_ARRAY:
+		case GL_TEXTURE_2D_ARRAY:
+			glTexImage3D(target, level,
+				     format->internalformat,
+				     w, h, d, 0,
+				     dataformat, datatype, NULL);
+			for (layer = 0; layer < d; layer++) {
+				char *ptr = data;
+				ptr += layer;
+				glTexSubImage3D(target, level,
+						0, 0, layer, w, h, 1,
+						dataformat, datatype, ptr);
+			}
+			break;
+
+		default:
+			assert(0);
+		}
+
+		if (!mip)
+			break;
+
+		if (w > 1)
+			w >>= 1;
+		if (target != GL_TEXTURE_1D &&
+		    target != GL_TEXTURE_1D_ARRAY &&
+		    h > 1)
+			h >>= 1;
+	}
+	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+	free(data);
+	return tex;
+}
+
+static bool
+verify_depth_data(const struct format_desc *format, GLenum target,
+		  int w, int h, int d, GLboolean mip)
+{
+	int x, y, layer, level;
+	GLfloat *f;
+	unsigned *i = NULL;
+	int size;
+	GLenum datatype = format->base_internal_format;
+	GLenum dataformat;
+	int layer_size;
+	int mul = 1;
+	void *data, *ptr;
+	if (format->internalformat == GL_DEPTH32F_STENCIL8) {
+		dataformat = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+		mul = 2;
+	}
+	else if (format->base_internal_format == GL_DEPTH_STENCIL)
+		dataformat = GL_UNSIGNED_INT_24_8_EXT;
+	else
+		dataformat = GL_FLOAT;
+
+	ptr = calloc(mul * 4, w * h * d);
+	if (!ptr)
+		return false;
+
+	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+		data = ptr;
+		layer_size = w * h * 4 * mul;
+
+		if (target == GL_TEXTURE_CUBE_MAP) {
+			int idx;
+			for (idx = 0; idx < 6; idx++)
+				glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
+					      (char *)data + layer_size * idx);
+		} else
+			glGetTexImage(target, level, datatype, dataformat,
+				      data);
+
+		for (layer = 0; layer < d; layer++) {
+			f = data;
+			if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
+			    format->internalformat == GL_DEPTH24_STENCIL8_EXT)
+				i = data;
+
+			for (y = 0; y < h; y++) {
+				for (x = 0; x < w; x++) {
+					int offset = (x + layer) % w;
+					float exp_val = get_depth_value(w, offset);
+					float got_val;
+
+					if (i)
+						got_val = (float)(i[y * w + x] >> 8) / (float)0xffffff;
+					else
+						got_val = f[(y * w + x) * mul];
+					if (fabs(got_val - exp_val) >= 1e-4) {
+						fprintf(stderr, "mismatch at %d %d %d %d %g vs %g: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
+						if (0){
+							uint32_t *myptr = data;
+							int myx;
+							for (myx = 0; myx < w * h; myx++){
+								fprintf(stderr, "%08x ", myptr[myx]);
+							}
+							fprintf(stderr, "\n");
+						}
+						free(ptr);
+						return false;
+					}
+				}
+			}
+			data = (char *)data + layer_size;
+		}
+
+		if (!mip)
+			break;
+		if (w > 1)
+			w >>= 1;
+		if (target != GL_TEXTURE_1D &&
+		    target != GL_TEXTURE_1D_ARRAY &&
+		    h > 1)
+			h >>= 1;
+	}
+	free(ptr);
+	return true;
+}
+
+static bool
+verify_stencil_data(const struct format_desc *format,
+		    GLenum target, int w, int h, int d, GLboolean mip)
+{
+	int x, y, layer, level, size;
+	GLubyte *ub;
+	GLenum datatype = format->base_internal_format;
+	GLenum dataformat = GL_UNSIGNED_BYTE;
+	void *data, *ptr;
+	int layer_size;
+
+	ptr = calloc(1, w * h * d);
+	if (!ptr)
+		return false;
+
+	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
+		data = ptr;
+		layer_size = w * h;
+		glPixelStorei(GL_PACK_ALIGNMENT, 1);
+		if (target == GL_TEXTURE_CUBE_MAP) {
+			int idx;
+			for (idx = 0; idx < 6; idx++)
+				glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
+					      (char *)data + layer_size * idx);
+		} else
+			glGetTexImage(target, level, datatype, dataformat,
+				      data);
+		glPixelStorei(GL_PACK_ALIGNMENT, 4);
+		for (layer = 0; layer < d; layer++) {
+			ub = data;
+
+			for (y = 0; y < h; y++) {
+				for (x = 0; x < w; x++) {
+					int offset = (x + layer) % w;
+					GLubyte got_val;
+					GLubyte exp_val = get_stencil_value(w, offset);
+
+					got_val = ub[y * w + x];
+					if (exp_val != got_val) {
+						fprintf(stderr, "mismatch at %d %d %d %d %d vs %d: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
+						free(ptr);
+						return false;
+					}
+				}
+			}
+			data = (char *)data + layer_size;
+		}
+
+		if (!mip)
+			break;
+		if (w > 1)
+			w >>= 1;
+		if (target != GL_TEXTURE_1D &&
+		    target != GL_TEXTURE_1D_ARRAY &&
+		    h > 1)
+			h >>= 1;
+	}
+	free(ptr);
+	return true;
+}
+
+bool test_depth_format(GLenum target, const struct format_desc *format)
+{
+	GLuint tex;
+	int height, num_layers;
+	bool ret;
+
+	/* 3D depth textures don't occur */
+	if (target == GL_TEXTURE_3D)
+		return true;
+
+	height = get_test_height(target);
+	num_layers = get_test_depth(target);
+
+	tex = get_depth_texture(format, target, IMAGE_WIDTH, height, num_layers,
+				target == GL_TEXTURE_RECTANGLE ? false : true);
+
+	ret = verify_depth_data(format, target, IMAGE_WIDTH, height, num_layers,
+				target == GL_TEXTURE_RECTANGLE ? false : true);
+
+	piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
+				     "%s-%s",
+				     piglit_get_gl_enum_name(target),
+				     piglit_get_gl_enum_name(format->internalformat));
+	glDeleteTextures(1, &tex);
+	return ret;
+}
+
+bool test_stencil_format(GLenum target, const struct format_desc *format)
+{
+	GLuint tex;
+	int height, num_layers;
+	bool ret;
+	/* 3D depth textures don't occur */
+	if (target == GL_TEXTURE_3D)
+		return true;
+
+	height = get_test_height(target);
+	num_layers = get_test_depth(target);
+
+	tex = get_stencil_texture(format, target, IMAGE_WIDTH, height, num_layers,
+				  target == GL_TEXTURE_RECTANGLE ? false : true);
+
+	ret = verify_stencil_data(format, target, IMAGE_WIDTH, height, num_layers,
+				  target == GL_TEXTURE_RECTANGLE ? false : true);
+	piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
+				     "%s-%s",
+				     piglit_get_gl_enum_name(target),
+				     piglit_get_gl_enum_name(format->internalformat));
+	glDeleteTextures(1, &tex);
+	return ret;
+}
+
+bool test_target_format(GLenum target, const struct format_desc *format)
+{
+	if (format->base_internal_format == GL_DEPTH_COMPONENT ||
+	    format->base_internal_format == GL_DEPTH_STENCIL) {
+		return test_depth_format(target, format);
+	} else if (format->base_internal_format == GL_STENCIL_INDEX) {
+		return test_stencil_format(target, format);
+	}
+	return true;
+}
+
+bool test_target(GLenum target)
+{
+	int fmt_idx;
+	int set_idx;
+	int ext_idx;
+	bool do_test_set;
+	bool result = true, ret;
+
+	for (set_idx = 0; set_idx < ARRAY_SIZE(test_sets); set_idx++) {
+		do_test_set = true;
+		for (ext_idx = 0; ext_idx < 3; ext_idx++) {
+			if (test_sets[set_idx].ext[ext_idx])
+				if (!piglit_is_extension_supported(test_sets[set_idx].ext[ext_idx])) {
+					do_test_set = false;
+					break;
+				}
+		}
+		if (!do_test_set)
+			continue;
+
+		for (fmt_idx = 0; fmt_idx < test_sets[set_idx].num_formats; fmt_idx++) {
+			ret = test_target_format(target, &test_sets[set_idx].format[fmt_idx]);
+			if (ret == false)
+				result = false;
+		}
+	}
+	return result;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	int i;
+	enum piglit_result status = PIGLIT_PASS;
+	bool ret;
+
+	for (i = 0; i < 3; i++)
+		test_target_bitmap |= (1 << i);
+	if (piglit_is_extension_supported("GL_ARB_texture_rectangle"))
+		test_target_bitmap |= (1 << 3);
+	if (piglit_is_extension_supported("GL_ARB_texture_cube_map"))
+		test_target_bitmap |= (1 << 4);
+	if (piglit_is_extension_supported("GL_EXT_texture_array"))
+		test_target_bitmap |= (1 << 5) | (1 << 6);
+	if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
+		test_target_bitmap |= (1 << 7);
+
+	for (i = 0; i < ARRAY_SIZE(target_list); i++) {
+		if (!(test_target_bitmap & (1 << i)))
+			continue;
+
+		ret = test_target(target_list[i]);
+		if (ret == false)
+			status = PIGLIT_FAIL;
+	}
+
+	piglit_report_result(status);
+	(void)fbo_formats_display;
+}

Comments

On Mon, Nov 2, 2015 at 7:24 PM, Dave Airlie <airlied@gmail.com> wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> for every supported target for all the depth/stencil formats
> this creates a texture, and then uses glGetTexImage
> to read it back.
> ---
>  tests/texturing/CMakeLists.gl.txt   |   1 +
>  tests/texturing/getteximage-depth.c | 628 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 629 insertions(+)
>  create mode 100644 tests/texturing/getteximage-depth.c
>
> diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
> index 68afa16..704ea6d 100644
> --- a/tests/texturing/CMakeLists.gl.txt
> +++ b/tests/texturing/CMakeLists.gl.txt
> @@ -34,6 +34,7 @@ piglit_add_executable (getteximage-formats getteximage-formats.c)
>  piglit_add_executable (getteximage-simple getteximage-simple.c)
>  piglit_add_executable (getteximage-luminance getteximage-luminance.c)
>  piglit_add_executable (getteximage-targets getteximage-targets.c)
> +piglit_add_executable (getteximage-depth getteximage-depth.c)
>  piglit_add_executable (incomplete-texture incomplete-texture.c)
>  piglit_add_executable (generatemipmap-cubemap generatemipmap-cubemap.c)
>  piglit_add_executable (fragment-and-vertex-texturing fragment-and-vertex-texturing.c)
> diff --git a/tests/texturing/getteximage-depth.c b/tests/texturing/getteximage-depth.c
> new file mode 100644
> index 0000000..71311bc
> --- /dev/null
> +++ b/tests/texturing/getteximage-depth.c
> @@ -0,0 +1,628 @@
> +/*
> + * Copyright (c) 2015 Red Hat
> + *
> + * 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 getteximage-depth
> + *
> + * Test glGetTexImage for depth/stencil format/target combinations in a roundtrip.
> + * i.e. don't draw the textures, just create and readback.
> + * this was due to a bug in mesa's handling of 1D array depth textures.
> + */
> +
> +#include "piglit-util-gl.h"
> +#include "../fbo/fbo-formats.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
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       /* UNREACHABLE */
> +       return PIGLIT_FAIL;
> +}
> +
> +#define IMAGE_WIDTH 32
> +#define IMAGE_HEIGHT 32
> +
> +static GLenum target_list[] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,  GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY };
> +
> +static int test_target_bitmap;
> +
> +static int get_test_height(GLenum target)
> +{
> +       switch (target) {
> +       case GL_TEXTURE_1D:
> +       case GL_TEXTURE_1D_ARRAY:
> +               return 1;
> +       default:
> +               return IMAGE_HEIGHT;
> +       }
> +}
> +
> +static int get_test_depth(GLenum target)
> +{
> +       switch (target) {
> +       case GL_TEXTURE_3D:
> +               return 16;
> +       case GL_TEXTURE_1D_ARRAY:
> +       case GL_TEXTURE_2D_ARRAY:
> +               return 7;
> +       case GL_TEXTURE_CUBE_MAP_ARRAY:
> +               return 12;
> +       case GL_TEXTURE_CUBE_MAP:
> +               return 6;
> +       default:
> +               return 1;
> +       }
> +}
> +
> +static float get_depth_value(int w, int x)
> +{
> +       if (w == 1)
> +               return 1.0;
> +       else
> +               return (float)(x) / (w - 1);
> +}
> +
> +static int get_stencil_value(int w, int x)
> +{
> +       if (w == 1)
> +               return 255;
> +       else
> +               return (x * 255) / (w - 1);
> +}
> +
> +static GLuint
> +get_depth_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +       void *data;
> +       float *f = NULL;
> +       unsigned int  *i = NULL;
> +       int size, x, y, level, layer;
> +       GLuint tex;
> +       GLuint extra = 0;
> +       GLenum datatype, dataformat;
> +       int mul = 1;
> +
> +       glGenTextures(1, &tex);
> +       glBindTexture(target, tex);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +       if (mip) {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_LINEAR);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_LINEAR_MIPMAP_NEAREST);
> +       } else {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_NEAREST);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_NEAREST);
> +       }
> +       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               mul = 2;
> +       }
> +       extra = d * sizeof(GLfloat) * mul;
> +
> +       data = calloc(1, w * h * sizeof(GLfloat) * mul + extra);
> +
> +       if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
> +           format->internalformat == GL_DEPTH24_STENCIL8_EXT) {
> +               dataformat = GL_DEPTH_STENCIL_EXT;
> +               datatype = GL_UNSIGNED_INT_24_8_EXT;
> +               i = data;
> +       } else if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               dataformat = GL_DEPTH_STENCIL;
> +               datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +               f = data;
> +       } else {
> +               dataformat = GL_DEPTH_COMPONENT;
> +               datatype = GL_FLOAT;
> +               f = data;
> +       }
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +               for (y = 0; y < h; y++) {
> +                       for (x = 0; x < w; x++) {
> +                               float val = get_depth_value(w, x);
> +
> +                               if (f)
> +                                       f[(y * w + x)*mul] = val;
> +                               else
> +                                       i[y * w + x] = 0xffffff00 * val;
> +                       }
> +               }
> +
> +               for (x = 0; x < d; x++) {
> +                       float val = get_depth_value(w, x % w);
> +
> +                       if (f)
> +                               f[(h * w + x)*mul] = val;
> +                       else
> +                               i[h * w + x] = 0xffffff00 * val;
> +               }
> +
> +               switch (target) {
> +               case GL_TEXTURE_1D:
> +                       glTexImage1D(target, level,
> +                                    format->internalformat,
> +                                    w, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_2D:
> +               case GL_TEXTURE_RECTANGLE:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, h, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP:
> +                       assert(d == 6);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * 4 * mul;
> +                               glTexImage2D(cube_face_targets[layer],
> +                                            level, format->internalformat,
> +                                            w, h, 0,
> +                                            dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_1D_ARRAY:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * (4 * mul);
> +                               glTexSubImage2D(target, level,
> +                                               0, layer, w, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_2D_ARRAY:
> +               case GL_TEXTURE_CUBE_MAP_ARRAY:
> +                       glTexImage3D(target, level,
> +                                    format->internalformat,
> +                                    w, h, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * (4 * mul);
> +                               glTexSubImage3D(target, level,
> +                                               0, 0, layer, w, h, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +
> +               default:
> +                       assert(0);
> +               }
> +
> +               if (!mip)
> +                       break;
> +
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(data);
> +       return tex;
> +}
> +
> +static GLuint
> +get_stencil_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +       void *data;
> +       unsigned char *u;
> +       int size, x, y, level, layer;
> +       GLuint tex;
> +       GLenum datatype, dataformat;
> +
> +       glGenTextures(1, &tex);
> +       glBindTexture(target, tex);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +       if (mip) {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_LINEAR);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_LINEAR_MIPMAP_NEAREST);
> +       } else {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_NEAREST);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_NEAREST);
> +       }
> +       data = malloc(w * h * sizeof(GLubyte) + d * sizeof(GLubyte));
> +
> +       dataformat = GL_STENCIL_INDEX;
> +       datatype = GL_UNSIGNED_BYTE;
> +       u = data;
> +       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +               for (y = 0; y < h; y++) {
> +                       for (x = 0; x < w; x++) {
> +                               GLuint val = get_stencil_value(w, x);
> +
> +                               u[y * w + x] = val;
> +                       }
> +               }
> +
> +               for (x = 0; x < d; x++) {
> +                       GLuint val = get_stencil_value(w, x % w);
> +                       u[h * w + x] = val;
> +               }
> +
> +               switch (target) {
> +               case GL_TEXTURE_1D:
> +                       glTexImage1D(target, level,
> +                                    format->internalformat,
> +                                    w, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +
> +               case GL_TEXTURE_2D:
> +               case GL_TEXTURE_RECTANGLE:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, h, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP:
> +                       assert(d == 6);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexImage2D(cube_face_targets[layer],
> +                                            level, format->internalformat,
> +                                            w, h, 0,
> +                                            dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_1D_ARRAY:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexSubImage2D(target, level,
> +                                               0, layer, w, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP_ARRAY:
> +               case GL_TEXTURE_2D_ARRAY:
> +                       glTexImage3D(target, level,
> +                                    format->internalformat,
> +                                    w, h, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexSubImage3D(target, level,
> +                                               0, 0, layer, w, h, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +
> +               default:
> +                       assert(0);
> +               }
> +
> +               if (!mip)
> +                       break;
> +
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
> +       free(data);
> +       return tex;
> +}
> +
> +static bool
> +verify_depth_data(const struct format_desc *format, GLenum target,
> +                 int w, int h, int d, GLboolean mip)
> +{
> +       int x, y, layer, level;
> +       GLfloat *f;
> +       unsigned *i = NULL;
> +       int size;
> +       GLenum datatype = format->base_internal_format;
> +       GLenum dataformat;
> +       int layer_size;
> +       int mul = 1;
> +       void *data, *ptr;
> +       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               dataformat = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +               mul = 2;
> +       }
> +       else if (format->base_internal_format == GL_DEPTH_STENCIL)
> +               dataformat = GL_UNSIGNED_INT_24_8_EXT;
> +       else
> +               dataformat = GL_FLOAT;
> +
> +       ptr = calloc(mul * 4, w * h * d);
> +       if (!ptr)
> +               return false;
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +               data = ptr;
> +               layer_size = w * h * 4 * mul;
> +
> +               if (target == GL_TEXTURE_CUBE_MAP) {
> +                       int idx;
> +                       for (idx = 0; idx < 6; idx++)
> +                               glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
> +                                             (char *)data + layer_size * idx);
> +               } else
> +                       glGetTexImage(target, level, datatype, dataformat,
> +                                     data);
> +
> +               for (layer = 0; layer < d; layer++) {
> +                       f = data;
> +                       if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
> +                           format->internalformat == GL_DEPTH24_STENCIL8_EXT)
> +                               i = data;
> +
> +                       for (y = 0; y < h; y++) {
> +                               for (x = 0; x < w; x++) {
> +                                       int offset = (x + layer) % w;
> +                                       float exp_val = get_depth_value(w, offset);
> +                                       float got_val;
> +
> +                                       if (i)
> +                                               got_val = (float)(i[y * w + x] >> 8) / (float)0xffffff;
> +                                       else
> +                                               got_val = f[(y * w + x) * mul];
> +                                       if (fabs(got_val - exp_val) >= 1e-4) {
> +                                               fprintf(stderr, "mismatch at %d %d %d %d %g vs %g: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
> +                                               if (0){
> +                                                       uint32_t *myptr = data;
> +                                                       int myx;
> +                                                       for (myx = 0; myx < w * h; myx++){
> +                                                               fprintf(stderr, "%08x ", myptr[myx]);
> +                                                       }
> +                                                       fprintf(stderr, "\n");
> +                                               }
> +                                               free(ptr);
> +                                               return false;
> +                                       }
> +                               }
> +                       }
> +                       data = (char *)data + layer_size;
> +               }
> +
> +               if (!mip)
> +                       break;
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(ptr);
> +       return true;
> +}
> +
> +static bool
> +verify_stencil_data(const struct format_desc *format,
> +                   GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +       int x, y, layer, level, size;
> +       GLubyte *ub;
> +       GLenum datatype = format->base_internal_format;
> +       GLenum dataformat = GL_UNSIGNED_BYTE;
> +       void *data, *ptr;
> +       int layer_size;
> +
> +       ptr = calloc(1, w * h * d);
> +       if (!ptr)
> +               return false;
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +               data = ptr;
> +               layer_size = w * h;
> +               glPixelStorei(GL_PACK_ALIGNMENT, 1);
> +               if (target == GL_TEXTURE_CUBE_MAP) {
> +                       int idx;
> +                       for (idx = 0; idx < 6; idx++)
> +                               glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
> +                                             (char *)data + layer_size * idx);
> +               } else
> +                       glGetTexImage(target, level, datatype, dataformat,
> +                                     data);
> +               glPixelStorei(GL_PACK_ALIGNMENT, 4);
> +               for (layer = 0; layer < d; layer++) {
> +                       ub = data;
> +
> +                       for (y = 0; y < h; y++) {
> +                               for (x = 0; x < w; x++) {
> +                                       int offset = (x + layer) % w;
> +                                       GLubyte got_val;
> +                                       GLubyte exp_val = get_stencil_value(w, offset);
> +
> +                                       got_val = ub[y * w + x];
> +                                       if (exp_val != got_val) {
> +                                               fprintf(stderr, "mismatch at %d %d %d %d %d vs %d: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
> +                                               free(ptr);
> +                                               return false;
> +                                       }
> +                               }
> +                       }
> +                       data = (char *)data + layer_size;
> +               }
> +
> +               if (!mip)
> +                       break;
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(ptr);
> +       return true;
> +}
> +
> +bool test_depth_format(GLenum target, const struct format_desc *format)
> +{
> +       GLuint tex;
> +       int height, num_layers;
> +       bool ret;
> +
> +       /* 3D depth textures don't occur */
> +       if (target == GL_TEXTURE_3D)
> +               return true;
> +
> +       height = get_test_height(target);
> +       num_layers = get_test_depth(target);
> +
> +       tex = get_depth_texture(format, target, IMAGE_WIDTH, height, num_layers,
> +                               target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +       ret = verify_depth_data(format, target, IMAGE_WIDTH, height, num_layers,
> +                               target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +                                    "%s-%s",
> +                                    piglit_get_gl_enum_name(target),
> +                                    piglit_get_gl_enum_name(format->internalformat));
> +       glDeleteTextures(1, &tex);
> +       return ret;
> +}
> +
> +bool test_stencil_format(GLenum target, const struct format_desc *format)
> +{
> +       GLuint tex;
> +       int height, num_layers;
> +       bool ret;
> +       /* 3D depth textures don't occur */
> +       if (target == GL_TEXTURE_3D)
> +               return true;
> +
> +       height = get_test_height(target);
> +       num_layers = get_test_depth(target);
> +
> +       tex = get_stencil_texture(format, target, IMAGE_WIDTH, height, num_layers,
> +                                 target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +       ret = verify_stencil_data(format, target, IMAGE_WIDTH, height, num_layers,
> +                                 target == GL_TEXTURE_RECTANGLE ? false : true);
> +       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +                                    "%s-%s",
> +                                    piglit_get_gl_enum_name(target),
> +                                    piglit_get_gl_enum_name(format->internalformat));
> +       glDeleteTextures(1, &tex);
> +       return ret;
> +}
> +
> +bool test_target_format(GLenum target, const struct format_desc *format)
> +{
> +       if (format->base_internal_format == GL_DEPTH_COMPONENT ||
> +           format->base_internal_format == GL_DEPTH_STENCIL) {
> +               return test_depth_format(target, format);
> +       } else if (format->base_internal_format == GL_STENCIL_INDEX) {
> +               return test_stencil_format(target, format);
> +       }
> +       return true;
> +}
> +
> +bool test_target(GLenum target)
> +{
> +       int fmt_idx;
> +       int set_idx;
> +       int ext_idx;
> +       bool do_test_set;
> +       bool result = true, ret;
> +
> +       for (set_idx = 0; set_idx < ARRAY_SIZE(test_sets); set_idx++) {
> +               do_test_set = true;
> +               for (ext_idx = 0; ext_idx < 3; ext_idx++) {
> +                       if (test_sets[set_idx].ext[ext_idx])
> +                               if (!piglit_is_extension_supported(test_sets[set_idx].ext[ext_idx])) {
> +                                       do_test_set = false;
> +                                       break;
> +                               }
> +               }
> +               if (!do_test_set)
> +                       continue;
> +
> +               for (fmt_idx = 0; fmt_idx < test_sets[set_idx].num_formats; fmt_idx++) {
> +                       ret = test_target_format(target, &test_sets[set_idx].format[fmt_idx]);
> +                       if (ret == false)
> +                               result = false;
> +               }
> +       }
> +       return result;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +       int i;
> +       enum piglit_result status = PIGLIT_PASS;
> +       bool ret;
> +

piglit_require_extension("GL_ARB_depth_texture")

> +       for (i = 0; i < 3; i++)
> +               test_target_bitmap |= (1 << i);
> +       if (piglit_is_extension_supported("GL_ARB_texture_rectangle"))
> +               test_target_bitmap |= (1 << 3);
> +       if (piglit_is_extension_supported("GL_ARB_texture_cube_map"))
> +               test_target_bitmap |= (1 << 4);
> +       if (piglit_is_extension_supported("GL_EXT_texture_array"))
> +               test_target_bitmap |= (1 << 5) | (1 << 6);
> +       if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
> +               test_target_bitmap |= (1 << 7);
> +
> +       for (i = 0; i < ARRAY_SIZE(target_list); i++) {
> +               if (!(test_target_bitmap & (1 << i)))
> +                       continue;
> +
> +               ret = test_target(target_list[i]);
> +               if (ret == false)
> +                       status = PIGLIT_FAIL;
> +       }
> +
> +       piglit_report_result(status);
> +       (void)fbo_formats_display;
> +}
> --
> 2.4.3
>
> _______________________________________________
> Piglit mailing list
> Piglit@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
Add to all.py?
On Nov 2, 2015 4:25 PM, "Dave Airlie" <airlied@gmail.com> wrote:

> From: Dave Airlie <airlied@redhat.com>
>
> for every supported target for all the depth/stencil formats
> this creates a texture, and then uses glGetTexImage
> to read it back.
> ---
>  tests/texturing/CMakeLists.gl.txt   |   1 +
>  tests/texturing/getteximage-depth.c | 628
> ++++++++++++++++++++++++++++++++++++
>  2 files changed, 629 insertions(+)
>  create mode 100644 tests/texturing/getteximage-depth.c
>
> diff --git a/tests/texturing/CMakeLists.gl.txt
> b/tests/texturing/CMakeLists.gl.txt
> index 68afa16..704ea6d 100644
> --- a/tests/texturing/CMakeLists.gl.txt
> +++ b/tests/texturing/CMakeLists.gl.txt
> @@ -34,6 +34,7 @@ piglit_add_executable (getteximage-formats
> getteximage-formats.c)
>  piglit_add_executable (getteximage-simple getteximage-simple.c)
>  piglit_add_executable (getteximage-luminance getteximage-luminance.c)
>  piglit_add_executable (getteximage-targets getteximage-targets.c)
> +piglit_add_executable (getteximage-depth getteximage-depth.c)
>  piglit_add_executable (incomplete-texture incomplete-texture.c)
>  piglit_add_executable (generatemipmap-cubemap generatemipmap-cubemap.c)
>  piglit_add_executable (fragment-and-vertex-texturing
> fragment-and-vertex-texturing.c)
> diff --git a/tests/texturing/getteximage-depth.c
> b/tests/texturing/getteximage-depth.c
> new file mode 100644
> index 0000000..71311bc
> --- /dev/null
> +++ b/tests/texturing/getteximage-depth.c
> @@ -0,0 +1,628 @@
> +/*
> + * Copyright (c) 2015 Red Hat
> + *
> + * 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 getteximage-depth
> + *
> + * Test glGetTexImage for depth/stencil format/target combinations in a
> roundtrip.
> + * i.e. don't draw the textures, just create and readback.
> + * this was due to a bug in mesa's handling of 1D array depth textures.
> + */
> +
> +#include "piglit-util-gl.h"
> +#include "../fbo/fbo-formats.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
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +       /* UNREACHABLE */
> +       return PIGLIT_FAIL;
> +}
> +
> +#define IMAGE_WIDTH 32
> +#define IMAGE_HEIGHT 32
> +
> +static GLenum target_list[] = { GL_TEXTURE_1D, GL_TEXTURE_2D,
> GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,
> GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY };
> +
> +static int test_target_bitmap;
> +
> +static int get_test_height(GLenum target)
> +{
> +       switch (target) {
> +       case GL_TEXTURE_1D:
> +       case GL_TEXTURE_1D_ARRAY:
> +               return 1;
> +       default:
> +               return IMAGE_HEIGHT;
> +       }
> +}
> +
> +static int get_test_depth(GLenum target)
> +{
> +       switch (target) {
> +       case GL_TEXTURE_3D:
> +               return 16;
> +       case GL_TEXTURE_1D_ARRAY:
> +       case GL_TEXTURE_2D_ARRAY:
> +               return 7;
> +       case GL_TEXTURE_CUBE_MAP_ARRAY:
> +               return 12;
> +       case GL_TEXTURE_CUBE_MAP:
> +               return 6;
> +       default:
> +               return 1;
> +       }
> +}
> +
> +static float get_depth_value(int w, int x)
> +{
> +       if (w == 1)
> +               return 1.0;
> +       else
> +               return (float)(x) / (w - 1);
> +}
> +
> +static int get_stencil_value(int w, int x)
> +{
> +       if (w == 1)
> +               return 255;
> +       else
> +               return (x * 255) / (w - 1);
> +}
> +
> +static GLuint
> +get_depth_texture(const struct format_desc *format, GLenum target, int w,
> int h, int d, GLboolean mip)
> +{
> +       void *data;
> +       float *f = NULL;
> +       unsigned int  *i = NULL;
> +       int size, x, y, level, layer;
> +       GLuint tex;
> +       GLuint extra = 0;
> +       GLenum datatype, dataformat;
> +       int mul = 1;
> +
> +       glGenTextures(1, &tex);
> +       glBindTexture(target, tex);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +       if (mip) {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_LINEAR);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_LINEAR_MIPMAP_NEAREST);
> +       } else {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_NEAREST);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_NEAREST);
> +       }
> +       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               mul = 2;
> +       }
> +       extra = d * sizeof(GLfloat) * mul;
> +
> +       data = calloc(1, w * h * sizeof(GLfloat) * mul + extra);
> +
> +       if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
> +           format->internalformat == GL_DEPTH24_STENCIL8_EXT) {
> +               dataformat = GL_DEPTH_STENCIL_EXT;
> +               datatype = GL_UNSIGNED_INT_24_8_EXT;
> +               i = data;
> +       } else if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               dataformat = GL_DEPTH_STENCIL;
> +               datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +               f = data;
> +       } else {
> +               dataformat = GL_DEPTH_COMPONENT;
> +               datatype = GL_FLOAT;
> +               f = data;
> +       }
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>=
> 1) {
> +               for (y = 0; y < h; y++) {
> +                       for (x = 0; x < w; x++) {
> +                               float val = get_depth_value(w, x);
> +
> +                               if (f)
> +                                       f[(y * w + x)*mul] = val;
> +                               else
> +                                       i[y * w + x] = 0xffffff00 * val;
> +                       }
> +               }
> +
> +               for (x = 0; x < d; x++) {
> +                       float val = get_depth_value(w, x % w);
> +
> +                       if (f)
> +                               f[(h * w + x)*mul] = val;
> +                       else
> +                               i[h * w + x] = 0xffffff00 * val;
> +               }
> +
> +               switch (target) {
> +               case GL_TEXTURE_1D:
> +                       glTexImage1D(target, level,
> +                                    format->internalformat,
> +                                    w, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_2D:
> +               case GL_TEXTURE_RECTANGLE:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, h, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP:
> +                       assert(d == 6);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * 4 * mul;
> +                               glTexImage2D(cube_face_targets[layer],
> +                                            level, format->internalformat,
> +                                            w, h, 0,
> +                                            dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_1D_ARRAY:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * (4 * mul);
> +                               glTexSubImage2D(target, level,
> +                                               0, layer, w, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_2D_ARRAY:
> +               case GL_TEXTURE_CUBE_MAP_ARRAY:
> +                       glTexImage3D(target, level,
> +                                    format->internalformat,
> +                                    w, h, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer * (4 * mul);
> +                               glTexSubImage3D(target, level,
> +                                               0, 0, layer, w, h, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +
> +               default:
> +                       assert(0);
> +               }
> +
> +               if (!mip)
> +                       break;
> +
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(data);
> +       return tex;
> +}
> +
> +static GLuint
> +get_stencil_texture(const struct format_desc *format, GLenum target, int
> w, int h, int d, GLboolean mip)
> +{
> +       void *data;
> +       unsigned char *u;
> +       int size, x, y, level, layer;
> +       GLuint tex;
> +       GLenum datatype, dataformat;
> +
> +       glGenTextures(1, &tex);
> +       glBindTexture(target, tex);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +       glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +       if (mip) {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_LINEAR);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_LINEAR_MIPMAP_NEAREST);
> +       } else {
> +               glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +                               GL_NEAREST);
> +               glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +                               GL_NEAREST);
> +       }
> +       data = malloc(w * h * sizeof(GLubyte) + d * sizeof(GLubyte));
> +
> +       dataformat = GL_STENCIL_INDEX;
> +       datatype = GL_UNSIGNED_BYTE;
> +       u = data;
> +       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>=
> 1) {
> +               for (y = 0; y < h; y++) {
> +                       for (x = 0; x < w; x++) {
> +                               GLuint val = get_stencil_value(w, x);
> +
> +                               u[y * w + x] = val;
> +                       }
> +               }
> +
> +               for (x = 0; x < d; x++) {
> +                       GLuint val = get_stencil_value(w, x % w);
> +                       u[h * w + x] = val;
> +               }
> +
> +               switch (target) {
> +               case GL_TEXTURE_1D:
> +                       glTexImage1D(target, level,
> +                                    format->internalformat,
> +                                    w, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +
> +               case GL_TEXTURE_2D:
> +               case GL_TEXTURE_RECTANGLE:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, h, 0,
> +                                    dataformat, datatype, data);
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP:
> +                       assert(d == 6);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexImage2D(cube_face_targets[layer],
> +                                            level, format->internalformat,
> +                                            w, h, 0,
> +                                            dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_1D_ARRAY:
> +                       glTexImage2D(target, level,
> +                                    format->internalformat,
> +                                    w, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexSubImage2D(target, level,
> +                                               0, layer, w, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +               case GL_TEXTURE_CUBE_MAP_ARRAY:
> +               case GL_TEXTURE_2D_ARRAY:
> +                       glTexImage3D(target, level,
> +                                    format->internalformat,
> +                                    w, h, d, 0,
> +                                    dataformat, datatype, NULL);
> +                       for (layer = 0; layer < d; layer++) {
> +                               char *ptr = data;
> +                               ptr += layer;
> +                               glTexSubImage3D(target, level,
> +                                               0, 0, layer, w, h, 1,
> +                                               dataformat, datatype, ptr);
> +                       }
> +                       break;
> +
> +               default:
> +                       assert(0);
> +               }
> +
> +               if (!mip)
> +                       break;
> +
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
> +       free(data);
> +       return tex;
> +}
> +
> +static bool
> +verify_depth_data(const struct format_desc *format, GLenum target,
> +                 int w, int h, int d, GLboolean mip)
> +{
> +       int x, y, layer, level;
> +       GLfloat *f;
> +       unsigned *i = NULL;
> +       int size;
> +       GLenum datatype = format->base_internal_format;
> +       GLenum dataformat;
> +       int layer_size;
> +       int mul = 1;
> +       void *data, *ptr;
> +       if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +               dataformat = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +               mul = 2;
> +       }
> +       else if (format->base_internal_format == GL_DEPTH_STENCIL)
> +               dataformat = GL_UNSIGNED_INT_24_8_EXT;
> +       else
> +               dataformat = GL_FLOAT;
> +
> +       ptr = calloc(mul * 4, w * h * d);
> +       if (!ptr)
> +               return false;
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>=
> 1) {
> +               data = ptr;
> +               layer_size = w * h * 4 * mul;
> +
> +               if (target == GL_TEXTURE_CUBE_MAP) {
> +                       int idx;
> +                       for (idx = 0; idx < 6; idx++)
> +                               glGetTexImage(cube_face_targets[idx],
> level, datatype, dataformat,
> +                                             (char *)data + layer_size *
> idx);
> +               } else
> +                       glGetTexImage(target, level, datatype, dataformat,
> +                                     data);
> +
> +               for (layer = 0; layer < d; layer++) {
> +                       f = data;
> +                       if (format->internalformat == GL_DEPTH_STENCIL_EXT
> ||
> +                           format->internalformat ==
> GL_DEPTH24_STENCIL8_EXT)
> +                               i = data;
> +
> +                       for (y = 0; y < h; y++) {
> +                               for (x = 0; x < w; x++) {
> +                                       int offset = (x + layer) % w;
> +                                       float exp_val = get_depth_value(w,
> offset);
> +                                       float got_val;
> +
> +                                       if (i)
> +                                               got_val = (float)(i[y * w
> + x] >> 8) / (float)0xffffff;
> +                                       else
> +                                               got_val = f[(y * w + x) *
> mul];
> +                                       if (fabs(got_val - exp_val) >=
> 1e-4) {
> +                                               fprintf(stderr, "mismatch
> at %d %d %d %d %g vs %g: %d %dx%d\n", level, x, y, layer, got_val, exp_val,
> layer_size, w, h);
> +                                               if (0){
> +                                                       uint32_t *myptr =
> data;
> +                                                       int myx;
> +                                                       for (myx = 0; myx
> < w * h; myx++){
> +
>  fprintf(stderr, "%08x ", myptr[myx]);
> +                                                       }
> +                                                       fprintf(stderr,
> "\n");
> +                                               }
> +                                               free(ptr);
> +                                               return false;
> +                                       }
> +                               }
> +                       }
> +                       data = (char *)data + layer_size;
> +               }
> +
> +               if (!mip)
> +                       break;
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(ptr);
> +       return true;
> +}
> +
> +static bool
> +verify_stencil_data(const struct format_desc *format,
> +                   GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +       int x, y, layer, level, size;
> +       GLubyte *ub;
> +       GLenum datatype = format->base_internal_format;
> +       GLenum dataformat = GL_UNSIGNED_BYTE;
> +       void *data, *ptr;
> +       int layer_size;
> +
> +       ptr = calloc(1, w * h * d);
> +       if (!ptr)
> +               return false;
> +
> +       for (level = 0, size = w > h ? w : h; size > 0; level++, size >>=
> 1) {
> +               data = ptr;
> +               layer_size = w * h;
> +               glPixelStorei(GL_PACK_ALIGNMENT, 1);
> +               if (target == GL_TEXTURE_CUBE_MAP) {
> +                       int idx;
> +                       for (idx = 0; idx < 6; idx++)
> +                               glGetTexImage(cube_face_targets[idx],
> level, datatype, dataformat,
> +                                             (char *)data + layer_size *
> idx);
> +               } else
> +                       glGetTexImage(target, level, datatype, dataformat,
> +                                     data);
> +               glPixelStorei(GL_PACK_ALIGNMENT, 4);
> +               for (layer = 0; layer < d; layer++) {
> +                       ub = data;
> +
> +                       for (y = 0; y < h; y++) {
> +                               for (x = 0; x < w; x++) {
> +                                       int offset = (x + layer) % w;
> +                                       GLubyte got_val;
> +                                       GLubyte exp_val =
> get_stencil_value(w, offset);
> +
> +                                       got_val = ub[y * w + x];
> +                                       if (exp_val != got_val) {
> +                                               fprintf(stderr, "mismatch
> at %d %d %d %d %d vs %d: %d %dx%d\n", level, x, y, layer, got_val, exp_val,
> layer_size, w, h);
> +                                               free(ptr);
> +                                               return false;
> +                                       }
> +                               }
> +                       }
> +                       data = (char *)data + layer_size;
> +               }
> +
> +               if (!mip)
> +                       break;
> +               if (w > 1)
> +                       w >>= 1;
> +               if (target != GL_TEXTURE_1D &&
> +                   target != GL_TEXTURE_1D_ARRAY &&
> +                   h > 1)
> +                       h >>= 1;
> +       }
> +       free(ptr);
> +       return true;
> +}
> +
> +bool test_depth_format(GLenum target, const struct format_desc *format)
> +{
> +       GLuint tex;
> +       int height, num_layers;
> +       bool ret;
> +
> +       /* 3D depth textures don't occur */
> +       if (target == GL_TEXTURE_3D)
> +               return true;
> +
> +       height = get_test_height(target);
> +       num_layers = get_test_depth(target);
> +
> +       tex = get_depth_texture(format, target, IMAGE_WIDTH, height,
> num_layers,
> +                               target == GL_TEXTURE_RECTANGLE ? false :
> true);
> +
> +       ret = verify_depth_data(format, target, IMAGE_WIDTH, height,
> num_layers,
> +                               target == GL_TEXTURE_RECTANGLE ? false :
> true);
> +
> +       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +                                    "%s-%s",
> +                                    piglit_get_gl_enum_name(target),
> +
> piglit_get_gl_enum_name(format->internalformat));
> +       glDeleteTextures(1, &tex);
> +       return ret;
> +}
> +
> +bool test_stencil_format(GLenum target, const struct format_desc *format)
> +{
> +       GLuint tex;
> +       int height, num_layers;
> +       bool ret;
> +       /* 3D depth textures don't occur */
> +       if (target == GL_TEXTURE_3D)
> +               return true;
> +
> +       height = get_test_height(target);
> +       num_layers = get_test_depth(target);
> +
> +       tex = get_stencil_texture(format, target, IMAGE_WIDTH, height,
> num_layers,
> +                                 target == GL_TEXTURE_RECTANGLE ? false :
> true);
> +
> +       ret = verify_stencil_data(format, target, IMAGE_WIDTH, height,
> num_layers,
> +                                 target == GL_TEXTURE_RECTANGLE ? false :
> true);
> +       piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +                                    "%s-%s",
> +                                    piglit_get_gl_enum_name(target),
> +
> piglit_get_gl_enum_name(format->internalformat));
> +       glDeleteTextures(1, &tex);
> +       return ret;
> +}
> +
> +bool test_target_format(GLenum target, const struct format_desc *format)
> +{
> +       if (format->base_internal_format == GL_DEPTH_COMPONENT ||
> +           format->base_internal_format == GL_DEPTH_STENCIL) {
> +               return test_depth_format(target, format);
> +       } else if (format->base_internal_format == GL_STENCIL_INDEX) {
> +               return test_stencil_format(target, format);
> +       }
> +       return true;
> +}
> +
> +bool test_target(GLenum target)
> +{
> +       int fmt_idx;
> +       int set_idx;
> +       int ext_idx;
> +       bool do_test_set;
> +       bool result = true, ret;
> +
> +       for (set_idx = 0; set_idx < ARRAY_SIZE(test_sets); set_idx++) {
> +               do_test_set = true;
> +               for (ext_idx = 0; ext_idx < 3; ext_idx++) {
> +                       if (test_sets[set_idx].ext[ext_idx])
> +                               if
> (!piglit_is_extension_supported(test_sets[set_idx].ext[ext_idx])) {
> +                                       do_test_set = false;
> +                                       break;
> +                               }
> +               }
> +               if (!do_test_set)
> +                       continue;
> +
> +               for (fmt_idx = 0; fmt_idx <
> test_sets[set_idx].num_formats; fmt_idx++) {
> +                       ret = test_target_format(target,
> &test_sets[set_idx].format[fmt_idx]);
> +                       if (ret == false)
> +                               result = false;
> +               }
> +       }
> +       return result;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +       int i;
> +       enum piglit_result status = PIGLIT_PASS;
> +       bool ret;
> +
> +       for (i = 0; i < 3; i++)
> +               test_target_bitmap |= (1 << i);
> +       if (piglit_is_extension_supported("GL_ARB_texture_rectangle"))
> +               test_target_bitmap |= (1 << 3);
> +       if (piglit_is_extension_supported("GL_ARB_texture_cube_map"))
> +               test_target_bitmap |= (1 << 4);
> +       if (piglit_is_extension_supported("GL_EXT_texture_array"))
> +               test_target_bitmap |= (1 << 5) | (1 << 6);
> +       if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
> +               test_target_bitmap |= (1 << 7);
> +
> +       for (i = 0; i < ARRAY_SIZE(target_list); i++) {
> +               if (!(test_target_bitmap & (1 << i)))
> +                       continue;
> +
> +               ret = test_target(target_list[i]);
> +               if (ret == false)
> +                       status = PIGLIT_FAIL;
> +       }
> +
> +       piglit_report_result(status);
> +       (void)fbo_formats_display;
> +}
> --
> 2.4.3
>
> _______________________________________________
> Piglit mailing list
> Piglit@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
>
On 11/02/2015 05:24 PM, Dave Airlie wrote:
> From: Dave Airlie <airlied@redhat.com>
>
> for every supported target for all the depth/stencil formats
> this creates a texture, and then uses glGetTexImage
> to read it back.
> ---
>   tests/texturing/CMakeLists.gl.txt   |   1 +
>   tests/texturing/getteximage-depth.c | 628 ++++++++++++++++++++++++++++++++++++
>   2 files changed, 629 insertions(+)
>   create mode 100644 tests/texturing/getteximage-depth.c
>
> diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
> index 68afa16..704ea6d 100644
> --- a/tests/texturing/CMakeLists.gl.txt
> +++ b/tests/texturing/CMakeLists.gl.txt
> @@ -34,6 +34,7 @@ piglit_add_executable (getteximage-formats getteximage-formats.c)
>   piglit_add_executable (getteximage-simple getteximage-simple.c)
>   piglit_add_executable (getteximage-luminance getteximage-luminance.c)
>   piglit_add_executable (getteximage-targets getteximage-targets.c)
> +piglit_add_executable (getteximage-depth getteximage-depth.c)
>   piglit_add_executable (incomplete-texture incomplete-texture.c)
>   piglit_add_executable (generatemipmap-cubemap generatemipmap-cubemap.c)
>   piglit_add_executable (fragment-and-vertex-texturing fragment-and-vertex-texturing.c)
> diff --git a/tests/texturing/getteximage-depth.c b/tests/texturing/getteximage-depth.c
> new file mode 100644
> index 0000000..71311bc
> --- /dev/null
> +++ b/tests/texturing/getteximage-depth.c
> @@ -0,0 +1,628 @@
> +/*
> + * Copyright (c) 2015 Red Hat
> + *
> + * 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 getteximage-depth
> + *
> + * Test glGetTexImage for depth/stencil format/target combinations in a roundtrip.
> + * i.e. don't draw the textures, just create and readback.
> + * this was due to a bug in mesa's handling of 1D array depth textures.
> + */
> +
> +#include "piglit-util-gl.h"
> +#include "../fbo/fbo-formats.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
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> +	/* UNREACHABLE */
> +	return PIGLIT_FAIL;
> +}
> +
> +#define IMAGE_WIDTH 32
> +#define IMAGE_HEIGHT 32
> +
> +static GLenum target_list[] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP,  GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY };

Can you wrap that line, maybe one target per line?  Could be const too.


> +
> +static int test_target_bitmap;
> +
> +static int get_test_height(GLenum target)
> +{
> +	switch (target) {
> +	case GL_TEXTURE_1D:
> +	case GL_TEXTURE_1D_ARRAY:
> +		return 1;
> +	default:
> +		return IMAGE_HEIGHT;
> +	}
> +}
> +
> +static int get_test_depth(GLenum target)
> +{
> +	switch (target) {
> +	case GL_TEXTURE_3D:
> +		return 16;
> +	case GL_TEXTURE_1D_ARRAY:
> +	case GL_TEXTURE_2D_ARRAY:
> +		return 7;
> +	case GL_TEXTURE_CUBE_MAP_ARRAY:
> +		return 12;
> +	case GL_TEXTURE_CUBE_MAP:
> +		return 6;
> +	default:
> +		return 1;
> +	}
> +}
> +
> +static float get_depth_value(int w, int x)
> +{
> +	if (w == 1)
> +		return 1.0;
> +	else
> +		return (float)(x) / (w - 1);
> +}
> +
> +static int get_stencil_value(int w, int x)
> +{
> +	if (w == 1)
> +		return 255;
> +	else
> +		return (x * 255) / (w - 1);
> +}
> +
> +static GLuint
> +get_depth_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)

How about create_depth_texture()?  From the function name, it thought 
the code was going to get/read depth texture data.

Can you wrap to 78 columns?

Could use 'bool' instead of GLboolean.


> +{
> +	void *data;
> +	float *f = NULL;
> +	unsigned int  *i = NULL;
> +	int size, x, y, level, layer;
> +	GLuint tex;
> +	GLuint extra = 0;
> +	GLenum datatype, dataformat;
> +	int mul = 1;
> +
> +	glGenTextures(1, &tex);
> +	glBindTexture(target, tex);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +	if (mip) {
> +		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +				GL_LINEAR);
> +		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +				GL_LINEAR_MIPMAP_NEAREST);
> +	} else {
> +		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +				GL_NEAREST);
> +		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +				GL_NEAREST);
> +	}

I don't think you have to make any glTexParameter calls since there's no 
rendering/sampling in this test.


> +	if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +		mul = 2;
> +	}
> +	extra = d * sizeof(GLfloat) * mul;
> +
> +	data = calloc(1, w * h * sizeof(GLfloat) * mul + extra);
> +
> +	if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
> +	    format->internalformat == GL_DEPTH24_STENCIL8_EXT) {
> +		dataformat = GL_DEPTH_STENCIL_EXT;
> +		datatype = GL_UNSIGNED_INT_24_8_EXT;
> +		i = data;
> +	} else if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +		dataformat = GL_DEPTH_STENCIL;
> +		datatype = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +		f = data;
> +	} else {
> +		dataformat = GL_DEPTH_COMPONENT;
> +		datatype = GL_FLOAT;
> +		f = data;
> +	}
> +
> +	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +		for (y = 0; y < h; y++) {
> +			for (x = 0; x < w; x++) {
> +				float val = get_depth_value(w, x);
> +
> +				if (f)
> +					f[(y * w + x)*mul] = val;
> +				else
> +					i[y * w + x] = 0xffffff00 * val;
> +			}
> +		}
> +
> +		for (x = 0; x < d; x++) {
> +			float val = get_depth_value(w, x % w);
> +
> +			if (f)
> +				f[(h * w + x)*mul] = val;
> +			else
> +				i[h * w + x] = 0xffffff00 * val;
> +		}
> +
> +		switch (target) {
> +		case GL_TEXTURE_1D:
> +			glTexImage1D(target, level,
> +				     format->internalformat,
> +				     w, 0,
> +				     dataformat, datatype, data);
> +			break;
> +		case GL_TEXTURE_2D:
> +		case GL_TEXTURE_RECTANGLE:
> +			glTexImage2D(target, level,
> +				     format->internalformat,
> +				     w, h, 0,
> +				     dataformat, datatype, data);
> +			break;
> +		case GL_TEXTURE_CUBE_MAP:
> +			assert(d == 6);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer * 4 * mul;
> +				glTexImage2D(cube_face_targets[layer],
> +					     level, format->internalformat,
> +					     w, h, 0,
> +					     dataformat, datatype, ptr);
> +			}
> +			break;
> +		case GL_TEXTURE_1D_ARRAY:
> +			glTexImage2D(target, level,
> +				     format->internalformat,
> +				     w, d, 0,
> +				     dataformat, datatype, NULL);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer * (4 * mul);
> +				glTexSubImage2D(target, level,
> +						0, layer, w, 1,
> +						dataformat, datatype, ptr);
> +			}
> +			break;
> +		case GL_TEXTURE_2D_ARRAY:
> +		case GL_TEXTURE_CUBE_MAP_ARRAY:
> +			glTexImage3D(target, level,
> +				     format->internalformat,
> +				     w, h, d, 0,
> +				     dataformat, datatype, NULL);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer * (4 * mul);
> +				glTexSubImage3D(target, level,
> +						0, 0, layer, w, h, 1,
> +						dataformat, datatype, ptr);
> +			}
> +			break;
> +
> +		default:
> +			assert(0);
> +		}
> +
> +		if (!mip)
> +			break;
> +
> +		if (w > 1)
> +			w >>= 1;
> +		if (target != GL_TEXTURE_1D &&
> +		    target != GL_TEXTURE_1D_ARRAY &&
> +		    h > 1)
> +			h >>= 1;
> +	}
> +	free(data);
> +	return tex;
> +}
> +
> +static GLuint
> +get_stencil_texture(const struct format_desc *format, GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +	void *data;
> +	unsigned char *u;
> +	int size, x, y, level, layer;
> +	GLuint tex;
> +	GLenum datatype, dataformat;
> +
> +	glGenTextures(1, &tex);
> +	glBindTexture(target, tex);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
> +	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
> +	if (mip) {
> +		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +				GL_LINEAR);
> +		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +				GL_LINEAR_MIPMAP_NEAREST);
> +	} else {
> +		glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
> +				GL_NEAREST);
> +		glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
> +				GL_NEAREST);
> +	}
> +	data = malloc(w * h * sizeof(GLubyte) + d * sizeof(GLubyte));
> +
> +	dataformat = GL_STENCIL_INDEX;
> +	datatype = GL_UNSIGNED_BYTE;
> +	u = data;
> +	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
> +	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +		for (y = 0; y < h; y++) {
> +			for (x = 0; x < w; x++) {
> +				GLuint val = get_stencil_value(w, x);
> +
> +				u[y * w + x] = val;
> +			}
> +		}
> +
> +		for (x = 0; x < d; x++) {
> +			GLuint val = get_stencil_value(w, x % w);
> +			u[h * w + x] = val;
> +		}
> +
> +		switch (target) {
> +		case GL_TEXTURE_1D:
> +			glTexImage1D(target, level,
> +				     format->internalformat,
> +				     w, 0,
> +				     dataformat, datatype, data);
> +			break;
> +
> +		case GL_TEXTURE_2D:
> +		case GL_TEXTURE_RECTANGLE:
> +			glTexImage2D(target, level,
> +				     format->internalformat,
> +				     w, h, 0,
> +				     dataformat, datatype, data);
> +			break;
> +		case GL_TEXTURE_CUBE_MAP:
> +			assert(d == 6);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer;
> +				glTexImage2D(cube_face_targets[layer],
> +					     level, format->internalformat,
> +					     w, h, 0,
> +					     dataformat, datatype, ptr);
> +			}
> +			break;
> +		case GL_TEXTURE_1D_ARRAY:
> +			glTexImage2D(target, level,
> +				     format->internalformat,
> +				     w, d, 0,
> +				     dataformat, datatype, NULL);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer;
> +				glTexSubImage2D(target, level,
> +						0, layer, w, 1,
> +						dataformat, datatype, ptr);
> +			}
> +			break;
> +		case GL_TEXTURE_CUBE_MAP_ARRAY:
> +		case GL_TEXTURE_2D_ARRAY:
> +			glTexImage3D(target, level,
> +				     format->internalformat,
> +				     w, h, d, 0,
> +				     dataformat, datatype, NULL);
> +			for (layer = 0; layer < d; layer++) {
> +				char *ptr = data;
> +				ptr += layer;
> +				glTexSubImage3D(target, level,
> +						0, 0, layer, w, h, 1,
> +						dataformat, datatype, ptr);
> +			}
> +			break;
> +
> +		default:
> +			assert(0);
> +		}
> +
> +		if (!mip)
> +			break;
> +
> +		if (w > 1)
> +			w >>= 1;
> +		if (target != GL_TEXTURE_1D &&
> +		    target != GL_TEXTURE_1D_ARRAY &&
> +		    h > 1)
> +			h >>= 1;
> +	}
> +	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
> +	free(data);
> +	return tex;
> +}
> +
> +static bool
> +verify_depth_data(const struct format_desc *format, GLenum target,
> +		  int w, int h, int d, GLboolean mip)
> +{
> +	int x, y, layer, level;
> +	GLfloat *f;
> +	unsigned *i = NULL;
> +	int size;
> +	GLenum datatype = format->base_internal_format;
> +	GLenum dataformat;
> +	int layer_size;
> +	int mul = 1;
> +	void *data, *ptr;
> +	if (format->internalformat == GL_DEPTH32F_STENCIL8) {
> +		dataformat = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
> +		mul = 2;
> +	}
> +	else if (format->base_internal_format == GL_DEPTH_STENCIL)
> +		dataformat = GL_UNSIGNED_INT_24_8_EXT;
> +	else
> +		dataformat = GL_FLOAT;
> +
> +	ptr = calloc(mul * 4, w * h * d);
> +	if (!ptr)
> +		return false;
> +
> +	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +		data = ptr;
> +		layer_size = w * h * 4 * mul;
> +
> +		if (target == GL_TEXTURE_CUBE_MAP) {
> +			int idx;
> +			for (idx = 0; idx < 6; idx++)
> +				glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
> +					      (char *)data + layer_size * idx);
> +		} else
> +			glGetTexImage(target, level, datatype, dataformat,
> +				      data);
> +
> +		for (layer = 0; layer < d; layer++) {
> +			f = data;
> +			if (format->internalformat == GL_DEPTH_STENCIL_EXT ||
> +			    format->internalformat == GL_DEPTH24_STENCIL8_EXT)
> +				i = data;
> +
> +			for (y = 0; y < h; y++) {
> +				for (x = 0; x < w; x++) {
> +					int offset = (x + layer) % w;
> +					float exp_val = get_depth_value(w, offset);
> +					float got_val;
> +
> +					if (i)
> +						got_val = (float)(i[y * w + x] >> 8) / (float)0xffffff;
> +					else
> +						got_val = f[(y * w + x) * mul];
> +					if (fabs(got_val - exp_val) >= 1e-4) {
> +						fprintf(stderr, "mismatch at %d %d %d %d %g vs %g: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
> +						if (0){
> +							uint32_t *myptr = data;
> +							int myx;
> +							for (myx = 0; myx < w * h; myx++){
> +								fprintf(stderr, "%08x ", myptr[myx]);
> +							}
> +							fprintf(stderr, "\n");
> +						}
> +						free(ptr);
> +						return false;
> +					}
> +				}
> +			}
> +			data = (char *)data + layer_size;
> +		}
> +
> +		if (!mip)
> +			break;
> +		if (w > 1)
> +			w >>= 1;
> +		if (target != GL_TEXTURE_1D &&
> +		    target != GL_TEXTURE_1D_ARRAY &&
> +		    h > 1)
> +			h >>= 1;
> +	}
> +	free(ptr);
> +	return true;
> +}
> +
> +static bool
> +verify_stencil_data(const struct format_desc *format,
> +		    GLenum target, int w, int h, int d, GLboolean mip)
> +{
> +	int x, y, layer, level, size;
> +	GLubyte *ub;
> +	GLenum datatype = format->base_internal_format;
> +	GLenum dataformat = GL_UNSIGNED_BYTE;
> +	void *data, *ptr;
> +	int layer_size;
> +
> +	ptr = calloc(1, w * h * d);
> +	if (!ptr)
> +		return false;
> +
> +	for (level = 0, size = w > h ? w : h; size > 0; level++, size >>= 1) {
> +		data = ptr;
> +		layer_size = w * h;
> +		glPixelStorei(GL_PACK_ALIGNMENT, 1);
> +		if (target == GL_TEXTURE_CUBE_MAP) {
> +			int idx;
> +			for (idx = 0; idx < 6; idx++)
> +				glGetTexImage(cube_face_targets[idx], level, datatype, dataformat,
> +					      (char *)data + layer_size * idx);
> +		} else
> +			glGetTexImage(target, level, datatype, dataformat,
> +				      data);
> +		glPixelStorei(GL_PACK_ALIGNMENT, 4);
> +		for (layer = 0; layer < d; layer++) {
> +			ub = data;
> +
> +			for (y = 0; y < h; y++) {
> +				for (x = 0; x < w; x++) {
> +					int offset = (x + layer) % w;
> +					GLubyte got_val;
> +					GLubyte exp_val = get_stencil_value(w, offset);
> +
> +					got_val = ub[y * w + x];
> +					if (exp_val != got_val) {
> +						fprintf(stderr, "mismatch at %d %d %d %d %d vs %d: %d %dx%d\n", level, x, y, layer, got_val, exp_val, layer_size, w, h);
> +						free(ptr);
> +						return false;
> +					}
> +				}
> +			}
> +			data = (char *)data + layer_size;
> +		}
> +
> +		if (!mip)
> +			break;
> +		if (w > 1)
> +			w >>= 1;
> +		if (target != GL_TEXTURE_1D &&
> +		    target != GL_TEXTURE_1D_ARRAY &&
> +		    h > 1)
> +			h >>= 1;
> +	}
> +	free(ptr);
> +	return true;
> +}
> +
> +bool test_depth_format(GLenum target, const struct format_desc *format)

static bool
test_depth_format(...)

Same thing below.  There seems to be a mix of function declaration styles.


> +{
> +	GLuint tex;
> +	int height, num_layers;
> +	bool ret;
> +
> +	/* 3D depth textures don't occur */
> +	if (target == GL_TEXTURE_3D)
> +		return true;
> +
> +	height = get_test_height(target);
> +	num_layers = get_test_depth(target);
> +
> +	tex = get_depth_texture(format, target, IMAGE_WIDTH, height, num_layers,
> +				target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +	ret = verify_depth_data(format, target, IMAGE_WIDTH, height, num_layers,
> +				target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +	piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +				     "%s-%s",
> +				     piglit_get_gl_enum_name(target),
> +				     piglit_get_gl_enum_name(format->internalformat));
> +	glDeleteTextures(1, &tex);
> +	return ret;
> +}
> +
> +bool test_stencil_format(GLenum target, const struct format_desc *format)
> +{
> +	GLuint tex;
> +	int height, num_layers;
> +	bool ret;
> +	/* 3D depth textures don't occur */
> +	if (target == GL_TEXTURE_3D)
> +		return true;
> +
> +	height = get_test_height(target);
> +	num_layers = get_test_depth(target);
> +
> +	tex = get_stencil_texture(format, target, IMAGE_WIDTH, height, num_layers,
> +				  target == GL_TEXTURE_RECTANGLE ? false : true);
> +
> +	ret = verify_stencil_data(format, target, IMAGE_WIDTH, height, num_layers,
> +				  target == GL_TEXTURE_RECTANGLE ? false : true);
> +	piglit_report_subtest_result(ret ? PIGLIT_PASS : PIGLIT_FAIL,
> +				     "%s-%s",
> +				     piglit_get_gl_enum_name(target),
> +				     piglit_get_gl_enum_name(format->internalformat));
> +	glDeleteTextures(1, &tex);
> +	return ret;
> +}
> +
> +bool test_target_format(GLenum target, const struct format_desc *format)
> +{
> +	if (format->base_internal_format == GL_DEPTH_COMPONENT ||
> +	    format->base_internal_format == GL_DEPTH_STENCIL) {
> +		return test_depth_format(target, format);
> +	} else if (format->base_internal_format == GL_STENCIL_INDEX) {
> +		return test_stencil_format(target, format);
> +	}
> +	return true;
> +}
> +
> +bool test_target(GLenum target)
> +{
> +	int fmt_idx;
> +	int set_idx;
> +	int ext_idx;
> +	bool do_test_set;
> +	bool result = true, ret;
> +
> +	for (set_idx = 0; set_idx < ARRAY_SIZE(test_sets); set_idx++) {
> +		do_test_set = true;
> +		for (ext_idx = 0; ext_idx < 3; ext_idx++) {
> +			if (test_sets[set_idx].ext[ext_idx])
> +				if (!piglit_is_extension_supported(test_sets[set_idx].ext[ext_idx])) {
> +					do_test_set = false;
> +					break;
> +				}
> +		}
> +		if (!do_test_set)
> +			continue;
> +
> +		for (fmt_idx = 0; fmt_idx < test_sets[set_idx].num_formats; fmt_idx++) {
> +			ret = test_target_format(target, &test_sets[set_idx].format[fmt_idx]);
> +			if (ret == false)
> +				result = false;
> +		}
> +	}
> +	return result;
> +}
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> +	int i;
> +	enum piglit_result status = PIGLIT_PASS;
> +	bool ret;
> +
> +	for (i = 0; i < 3; i++)
> +		test_target_bitmap |= (1 << i);
> +	if (piglit_is_extension_supported("GL_ARB_texture_rectangle"))
> +		test_target_bitmap |= (1 << 3);
> +	if (piglit_is_extension_supported("GL_ARB_texture_cube_map"))
> +		test_target_bitmap |= (1 << 4);
> +	if (piglit_is_extension_supported("GL_EXT_texture_array"))
> +		test_target_bitmap |= (1 << 5) | (1 << 6);
> +	if (piglit_is_extension_supported("GL_ARB_texture_cube_map_array"))
> +		test_target_bitmap |= (1 << 7);
> +
> +	for (i = 0; i < ARRAY_SIZE(target_list); i++) {
> +		if (!(test_target_bitmap & (1 << i)))
> +			continue;
> +
> +		ret = test_target(target_list[i]);
> +		if (ret == false)
> +			status = PIGLIT_FAIL;
> +	}

The bitmap logic seems a little brittle.  How about something like this:

	for (i = 0; i < ARRAY_SIZE(target_list); i++) {

		switch (target_list[i]) {
		case GL_TEXTURE_1D_ARRAY:
		case GL_TEXTURE_2D_ARRAY:
			if (!piglit_is_extension_supported("GL_EXT_texture_array"))
				continue;
			break;
		...
		}

		ret = test_target(target_list[i]);
		...
	}


Thanks for writing this test though!

-Brian


> +
> +	piglit_report_result(status);
> +	(void)fbo_formats_display;
> +}
>
>
> piglit_require_extension("GL_ARB_depth_texture")

It's checked in the logic up above for the test sets.

In theory I was hoping to expand this test to cover non-depth/stencil cases,
but since they are mostly covered already I didn't expend the time right now.

But I'd like to get to it at some point.

Dave.