[Piglit] [PATCH] ARB_texture_view: Add test suite

Jon Ashburn jon at lunarg.com
Mon Oct 14 23:31:39 CEST 2013


---
 tests/all.tests                               |   6 +
 tests/spec/arb_texture_view/CMakeLists.gl.txt |   4 +-
 tests/spec/arb_texture_view/params.c          | 643 ++++++++++++++++++++++
 tests/spec/arb_texture_view/queries.c         | 198 +++++++
 tests/spec/arb_texture_view/rendering.c       | 758 ++++++++++++++++++++++++++
 5 files changed, 1608 insertions(+), 1 deletion(-)
 create mode 100644 tests/spec/arb_texture_view/params.c
 create mode 100644 tests/spec/arb_texture_view/queries.c
 create mode 100644 tests/spec/arb_texture_view/rendering.c

diff --git a/tests/all.tests b/tests/all.tests
index f38d3d8..2204b09 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1404,6 +1404,12 @@ spec['ARB_texture_storage_multisample'] = arb_texture_storage_multisample
 arb_texture_storage_multisample['tex-storage'] = concurrent_test('arb_texture_storage_multisample-tex-storage')
 arb_texture_storage_multisample['tex-param'] = concurrent_test('arb_texture_storage_multisample-tex-param')
 
+arb_texture_view = Group()
+spec['ARB_texture_view'] = arb_texture_view
+arb_texture_view['rendering'] = plain_test('arb_texture_view-rendering')
+arb_texture_view['params'] = plain_test('arb_texture_view-params')
+arb_texture_view['queries'] = plain_test('arb_texture_view-queries')
+
 tdfx_texture_compression_fxt1 = Group()
 spec['3DFX_texture_compression_FXT1'] = tdfx_texture_compression_fxt1
 add_concurrent_test(tdfx_texture_compression_fxt1, 'compressedteximage GL_COMPRESSED_RGB_FXT1_3DFX')
diff --git a/tests/spec/arb_texture_view/CMakeLists.gl.txt b/tests/spec/arb_texture_view/CMakeLists.gl.txt
index c400759..293ef72 100644
--- a/tests/spec/arb_texture_view/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_view/CMakeLists.gl.txt
@@ -9,6 +9,8 @@ link_libraries(
 	${OPENGL_glu_LIBRARY}
 	)
 
-piglit_add_executable(arb_texture_view-texture-immutable-levels texture-immutable-levels.c)
+piglit_add_executable(arb_texture_view-rendering rendering.c)
+piglit_add_executable(arb_texture_view-params params.c)
+piglit_add_executable(arb_texture_view-queries queries.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/arb_texture_view/params.c b/tests/spec/arb_texture_view/params.c
new file mode 100644
index 0000000..2714dd4
--- /dev/null
+++ b/tests/spec/arb_texture_view/params.c
@@ -0,0 +1,643 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view  and validity of input parameters.
+ * Use both valid and invalid parameters.
+ *
+ */
+
+#include "piglit-util-gl-common.h"
+#include <stdarg.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
+
+static const char *TestName = "arb_texture_view-params";
+
+
+void update_valid_arrays(GLenum *valid, GLenum *invalid, unsigned int num_invalid,
+						 unsigned int num_valid, ... )
+{
+	va_list args;
+	GLenum val;
+	unsigned int i,j;
+
+	va_start(args, num_valid);
+	for (i = 0; i < num_valid; i++) {
+		val = va_arg(args, GLenum);
+		valid[i] = val;
+		// remove the valid enum from the invalid array
+		for (j= 0; j < num_invalid; j++) {
+			if (invalid[j] == val)
+					invalid[j] = 0;
+		}
+	}
+	va_end(args);
+}
+
+/**
+ * Do error-check tests for texture targets
+ */
+static enum piglit_result
+test_target_errors(GLenum target)
+{
+	GLint width = 64, height = 14, depth = 8;
+	const GLsizei levels = 1;
+	GLuint tex;
+	GLenum legal_targets[4];
+	unsigned int num_targets, i;
+	GLenum illegal_targets[] = {
+		// skip multisample
+		GL_TEXTURE_1D,
+		GL_TEXTURE_2D,
+		GL_TEXTURE_3D,
+		GL_TEXTURE_CUBE_MAP,
+		GL_TEXTURE_RECTANGLE,
+		GL_TEXTURE_1D_ARRAY,
+		GL_TEXTURE_2D_ARRAY,
+		GL_TEXTURE_CUBE_MAP_ARRAY,
+	};
+
+	// skip 2d_multisample  targets for now
+	assert(target == GL_TEXTURE_1D ||
+		   target == GL_TEXTURE_2D ||
+		   target == GL_TEXTURE_3D ||
+		   target == GL_TEXTURE_CUBE_MAP ||
+		   target == GL_TEXTURE_RECTANGLE ||
+		   target == GL_TEXTURE_1D_ARRAY ||
+		   target == GL_TEXTURE_2D_ARRAY ||
+		   target == GL_TEXTURE_CUBE_MAP_ARRAY);
+
+	glGenTextures(1, &tex);   // orig tex
+	glBindTexture(target, tex);
+
+	switch (target) {
+	case GL_TEXTURE_1D:
+		glTexStorage1D(target, levels, GL_RGBA8, width);
+		num_targets = 2;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY);
+		break;
+	case GL_TEXTURE_1D_ARRAY:
+		glTexStorage2D(target, levels*2, GL_RGBA8, width, height);
+		num_targets = 2;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_1D, GL_TEXTURE_1D_ARRAY);
+		break;
+	case GL_TEXTURE_2D:
+		glTexStorage2D(target, levels, GL_RGBA8, width, height);
+		num_targets = 2;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY);
+		break;
+	case  GL_TEXTURE_RECTANGLE:
+		glTexStorage2D(target, levels, GL_RGBA8, width, height);
+		num_targets = 1;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_RECTANGLE);
+		break;
+	case GL_TEXTURE_CUBE_MAP:
+		width = height;
+		glTexStorage2D(target, levels, GL_RGBA8, width, height);
+		num_targets = 4;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
+							GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
+		break;
+	case GL_TEXTURE_3D:
+		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
+		num_targets = 1;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets, GL_TEXTURE_3D);
+		break;
+	case GL_TEXTURE_CUBE_MAP_ARRAY:
+	case GL_TEXTURE_2D_ARRAY:
+		height = width;
+		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth*6);
+		num_targets = 4;
+		update_valid_arrays(legal_targets, illegal_targets,
+					ARRAY_SIZE(illegal_targets), num_targets,
+							GL_TEXTURE_CUBE_MAP, GL_TEXTURE_2D,
+							GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_ARRAY);
+		break;
+	}
+
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDeleteTextures(1, &tex);
+
+		return PIGLIT_SKIP;
+	}
+
+	// ensure TextureView of legal targets  works
+	for (i = 0; i < num_targets; i++) {
+		GLenum tar = legal_targets[i];
+		GLuint new_tex, layers=1;
+		glGenTextures(1, &new_tex);
+		if (tar == GL_TEXTURE_CUBE_MAP)
+			layers = 6;
+		else if (tar == GL_TEXTURE_CUBE_MAP_ARRAY)
+			layers = 12;
+		glTextureView(new_tex, tar, tex,  GL_RG16, 0, levels, 0, layers);
+		glDeleteTextures(1, &new_tex);
+		if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			glDeleteTextures(1, &tex);
+			return PIGLIT_FAIL;
+		}
+	}
+
+	// ensure TextureView  of illegal targets returns an error
+	for (i = 0; i < ARRAY_SIZE(illegal_targets); i++) {
+		GLenum tar = illegal_targets[i];
+		GLuint new_tex, layers=1;
+		if (illegal_targets[i] == 0)
+				continue;
+		glGenTextures(1, &new_tex);
+		if (tar == GL_TEXTURE_CUBE_MAP)
+			layers = 6;
+		else if (tar == GL_TEXTURE_CUBE_MAP_ARRAY)
+			layers = 12;
+		glTextureView(new_tex, tar, tex,  GL_RG16, 0, levels, 0, layers);
+		if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+			glDeleteTextures(1, &new_tex);
+			glDeleteTextures(1, &tex);
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &new_tex);
+	}
+	glDeleteTextures(1, &tex);
+
+	return PIGLIT_PASS;
+}
+
+
+/**
+ * Do error-check tests for misc glTextureView parameters
+ */
+static enum piglit_result test_param_errors()
+{
+	GLuint tex[2] = {0, 0};
+	GLint level, layer, i;
+	unsigned char * ptr;
+
+	// invalid original texture param (origtexture)
+	glGenTextures(2, tex);
+	glBindTexture(GL_TEXTURE_3D, tex[0]);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDeleteTextures(2, tex);
+		return PIGLIT_SKIP;
+	}
+	glTextureView(tex[1], GL_TEXTURE_3D, tex[0], GL_R8, 0, 1, 0, 1);
+	if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, &tex[1]);
+	glTexStorage3D(GL_TEXTURE_3D,2, GL_RGBA32F, 16, 16, 8);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(1, tex);
+		return PIGLIT_SKIP;
+	}
+	glGenTextures(1, &tex[1]);
+	glTextureView(tex[1], GL_TEXTURE_3D, 0, GL_RGBA32UI, 0, 1, 0, 1);
+	if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, &tex[1]);
+
+	// invalid  texture param
+	glTextureView(0, GL_TEXTURE_3D, tex[0], GL_RGBA32I, 0, 1, 0 ,1);
+	if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+		glDeleteTextures(1, tex);
+		return PIGLIT_FAIL;
+	}
+	glGenTextures(1, &tex[1]);
+	glBindTexture(GL_TEXTURE_3D, tex[1]);
+	glTextureView(tex[1], GL_TEXTURE_3D, tex[0],GL_RGBA32F, 0, 1, 0, 1);
+	if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(2, tex);
+
+	glGenTextures(1, tex);
+	glBindTexture(GL_TEXTURE_3D, tex[0]);
+	glTexStorage3D(GL_TEXTURE_3D, 3, GL_RG16F, 16, 16, 8);
+	glTextureView(~tex[0],GL_TEXTURE_3D, tex[0], GL_RGBA8, 0,1,0,1);
+	if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+		glDeleteTextures(1, &tex[0]);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, tex);
+
+	// orig texture not immutable
+	ptr = (unsigned char *) malloc(32 * 32 * 4 * 6);
+	if (ptr == NULL)
+		return PIGLIT_SKIP;
+	glGenTextures(2, tex);
+	glBindTexture(GL_TEXTURE_3D, tex[0]);
+	glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16, 32, 32, 4, 0, GL_RGB,
+		     GL_SHORT, ptr);
+	glTexImage3D(GL_TEXTURE_3D, 1, GL_RGB16, 16, 16, 2, 0, GL_RGB,
+		     GL_SHORT, ptr);
+	free(ptr);
+	glTextureView(tex[1], GL_TEXTURE_3D, tex[0], GL_RGBA32F, 0,1,0,1);
+	if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(2, tex);
+
+	// invalid layer param
+	glGenTextures(2, tex);
+	glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+	glTexStorage2D(GL_TEXTURE_1D_ARRAY, 7, GL_RGB16I, 64, 4);
+	glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16UI, 0, 7, 4,
+		      2);
+	if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, &tex[1]);
+	glGenTextures(1, &tex[1]);
+	glTextureView(tex[1],GL_TEXTURE_1D, tex[0], GL_RGB16I, 1, 5, 0, 4);
+	if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, &tex[1]);
+
+	// invalid level param
+	glGenTextures(1, &tex[1]);
+	glTextureView(tex[1],GL_TEXTURE_1D, tex[0], GL_RGB16UI, 7, 5, 1, 1);
+	if (piglit_check_gl_error(GL_INVALID_VALUE) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(1, &tex[1]);
+
+	// numlevels clamping, minlevel range over legal values
+	for (i = 0; i < 7; i++) {
+		glGenTextures(1, &tex[1]);
+		glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16F,
+			      i, 8-i, 0, 5);
+		if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glBindTexture(GL_TEXTURE_1D_ARRAY, tex[1]);
+		glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_MIN_LEVEL,
+							&level);
+		if (level != i) {
+			printf("failed at min_level=%d, queried view_min_level=%d\n",
+					   i, level);
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_NUM_LEVELS,
+							&level);
+		if (level != (7-i)) {
+			printf("failed at min_level=%d, queried view_num_level=%d\n",
+					   i, level);
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &tex[1]);
+		glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+	}
+
+	// numlayers clamping, minlayers range over legal values
+	for (i = 0; i < 4; i++) {
+		glGenTextures(1, &tex[1]);
+		glTextureView(tex[1],GL_TEXTURE_1D_ARRAY, tex[0], GL_RGB16I,
+			      0, 7, i, 5-i);
+		if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glBindTexture(GL_TEXTURE_1D_ARRAY, tex[1]);
+		glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_MIN_LAYER,
+							&layer);
+		if (layer != i) {
+			printf("failed at min_layer=%d, queried view_min_layer=%d\n",
+					   i, layer);
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glGetTexParameteriv(GL_TEXTURE_1D_ARRAY, GL_TEXTURE_VIEW_NUM_LAYERS,
+							&layer);
+		if (layer != (4-i)) {
+			printf("failed at min_layer=%d, queried view_num_layer=%d\n",
+					   i, layer);
+			glDeleteTextures(2, tex);
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &tex[1]);
+		glBindTexture(GL_TEXTURE_1D_ARRAY, tex[0]);
+	}
+
+	glDeleteTextures(2, tex);
+	return PIGLIT_PASS;
+
+}
+
+/**
+ * Do error-check tests for texture targets
+ */
+static enum piglit_result
+test_format_errors(GLenum format_class)
+{
+	GLint width = 16, height = 16;
+	const GLsizei levels = 5;
+	GLenum target = GL_TEXTURE_CUBE_MAP;
+	GLuint tex;
+	GLenum legal_formats[17];
+	unsigned int num_formats, i;
+	GLenum illegal_formats[] = {
+		//skip compressed sized formats
+		//128 bit
+		GL_RGBA32F,
+		GL_RGBA32UI,
+		GL_RGBA32I,
+		// 96 bit
+		GL_RGB32F,
+		GL_RGB32UI,
+		GL_RGB32I,
+		// 64 bit
+		GL_RGBA16F,
+		GL_RG32F,
+		GL_RGBA16UI,
+		GL_RG32UI,
+		GL_RGBA16I,
+		GL_RG32I,
+		GL_RGBA16,
+		GL_RGBA16_SNORM,
+		//48 bit
+		GL_RGB16,
+		GL_RGB16_SNORM,
+		GL_RGB16F,
+		GL_RGB16UI,
+		GL_RGB16I,
+		//32 bits
+		GL_RG16F,
+		GL_R11F_G11F_B10F,
+		GL_R32F,
+		GL_RGB10_A2UI,
+		GL_RGBA8UI,
+		GL_RG16UI,
+		GL_R32UI,
+		GL_RGBA8I,
+		GL_RG16I,
+		GL_R32I,
+		GL_RGB10_A2,
+		GL_RGBA8,
+		GL_RG16,
+		GL_RGBA8_SNORM,
+		GL_RG16_SNORM,
+		GL_SRGB8_ALPHA8,
+		GL_RGB9_E5,
+		//24 bits
+		GL_RGB8,
+		GL_RGB8_SNORM,
+		GL_SRGB8,
+		GL_RGB8UI,
+		GL_RGB8I,
+		//16 bits
+		GL_R16F,
+		GL_RG8UI,
+		GL_R16UI,
+		GL_RG8I,
+		GL_R16I,
+		GL_RG8,
+		GL_R16,
+		GL_RG8_SNORM,
+		GL_R16_SNORM,
+		//8 bits
+		GL_R8UI,
+		GL_R8I,
+		GL_R8,
+		GL_R8_SNORM,
+		// a sampling of unsized formats
+		GL_ALPHA,
+		GL_LUMINANCE,
+		GL_LUMINANCE_ALPHA,
+		GL_INTENSITY,
+		GL_RGB,
+		GL_RGBA,
+		GL_DEPTH_COMPONENT,
+		GL_COMPRESSED_ALPHA,
+		GL_COMPRESSED_LUMINANCE_ALPHA,
+		GL_COMPRESSED_LUMINANCE,
+		GL_COMPRESSED_INTENSITY,
+		GL_COMPRESSED_RGB,
+		GL_COMPRESSED_RGBA,
+		GL_COMPRESSED_RGBA,
+		GL_COMPRESSED_SRGB,
+		GL_COMPRESSED_SRGB_ALPHA,
+		GL_COMPRESSED_SLUMINANCE,
+		GL_COMPRESSED_SLUMINANCE_ALPHA,
+	};
+
+	// skip compressed internal formats for now including extensions
+	assert(format_class == GL_VIEW_CLASS_128_BITS ||
+	       format_class == GL_VIEW_CLASS_96_BITS ||
+	       format_class == GL_VIEW_CLASS_64_BITS ||
+	       format_class == GL_VIEW_CLASS_48_BITS ||
+	       format_class == GL_VIEW_CLASS_32_BITS ||
+	       format_class == GL_VIEW_CLASS_24_BITS ||
+	       format_class == GL_VIEW_CLASS_16_BITS ||
+	       format_class == GL_VIEW_CLASS_8_BITS);
+
+	glGenTextures(1, &tex);   // orig tex
+	glBindTexture(target, tex);
+
+	switch (format_class) {
+	case GL_VIEW_CLASS_128_BITS:
+		glTexStorage2D(target, levels, GL_RGBA32F, width, height);
+		num_formats = 3;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+							GL_RGBA32F, GL_RGBA32UI, GL_RGBA32I);
+		break;
+	case GL_VIEW_CLASS_96_BITS:
+		glTexStorage2D(target, levels, GL_RGB32F, width, height);
+		num_formats = 3;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+							GL_RGB32F, GL_RGB32UI, GL_RGB32I);
+		break;
+	case GL_VIEW_CLASS_64_BITS:
+		glTexStorage2D(target, levels, GL_RGBA16F, width, height);
+		num_formats = 8;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+							GL_RGBA16F, GL_RG32F, GL_RGBA16UI, GL_RG32UI,
+							GL_RGBA16I, GL_RG32I, GL_RGBA16, GL_RGBA16_SNORM);
+		break;
+	case GL_VIEW_CLASS_48_BITS:
+		glTexStorage2D(target, levels, GL_RGB16, width, height);
+		num_formats = 5;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+					GL_RGB16, GL_RGB16_SNORM, GL_RGB16F, GL_RGB16UI, GL_RGB16I);
+		break;
+	case GL_VIEW_CLASS_32_BITS:
+		glTexStorage2D(target, levels, GL_RG16F, width, height);
+		num_formats = 17;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+					GL_RG16F, GL_R11F_G11F_B10F, GL_R32F, GL_RGB10_A2UI,
+					GL_RGBA8UI, GL_RG16UI, GL_R32UI, GL_RGBA8I, GL_RG16I,
+					GL_R32I, GL_RGB10_A2, GL_RGBA8, GL_RG16, GL_RGBA8_SNORM,
+					GL_RG16_SNORM, GL_SRGB8_ALPHA8, GL_RGB9_E5);
+		break;
+	case GL_VIEW_CLASS_24_BITS:
+		glTexStorage2D(target, levels, GL_RGB8, width, height);
+		num_formats = 5;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+					GL_RGB8, GL_RGB8_SNORM, GL_SRGB8, GL_RGB8UI, GL_RGB8I);
+		break;
+	case GL_VIEW_CLASS_16_BITS:
+		glTexStorage2D(target, levels, GL_R16F, width, height);
+		num_formats = 9;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+					GL_R16F, GL_RG8UI, GL_R16UI, GL_RG8I, GL_R16I, GL_RG8,
+					GL_R16, GL_RG8_SNORM, GL_R16_SNORM);
+		break;
+	case GL_VIEW_CLASS_8_BITS:
+		glTexStorage2D(target, levels, GL_R8I, width, height);
+		num_formats = 4;
+		update_valid_arrays(legal_formats, illegal_formats,
+					ARRAY_SIZE(illegal_formats), num_formats,
+							GL_R8UI, GL_R8I, GL_R8, GL_R8_SNORM);
+		break;
+	}
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDeleteTextures(1, &tex);
+		return PIGLIT_SKIP;
+	}
+
+	// ensure TextureView of legal formats  works
+	for (i = 0; i < num_formats; i++) {
+		GLenum format;
+		GLuint new_tex, layers=6;
+		format = legal_formats[i];
+		glGenTextures(1, &new_tex);
+		glTextureView(new_tex, target, tex,  format, 0, levels, 0, layers);
+		glDeleteTextures(1, &new_tex);
+		if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			glDeleteTextures(1, &tex);
+			return PIGLIT_FAIL;
+		}
+	}
+
+	// ensure TextureView  of illegal formats returns an error
+	for (i = 0; i < ARRAY_SIZE(illegal_formats); i++) {
+		GLenum format;
+		GLuint new_tex, layers=6;
+		format = illegal_formats[i];
+		if (format == 0)
+				continue;
+		glGenTextures(1, &new_tex);
+		glTextureView(new_tex, target, tex, format, 0, levels, 0, layers);
+		if (piglit_check_gl_error(GL_INVALID_OPERATION) == GL_FALSE) {
+			glDeleteTextures(1, &new_tex);
+			glDeleteTextures(1, &tex);
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &new_tex);
+	}
+
+	glDeleteTextures(1, &tex);
+
+	return PIGLIT_PASS;
+}
+
+
+enum piglit_result
+piglit_display(void)
+{
+	enum piglit_result pass = PIGLIT_PASS;
+	enum piglit_result tmp;
+#define X(f, n) tmp = (f); pass = tmp != PIGLIT_PASS ? PIGLIT_FAIL : pass; piglit_report_subtest_result(tmp, (n))
+	X(test_target_errors(GL_TEXTURE_1D), "1D tex target validity");
+	X(test_target_errors(GL_TEXTURE_2D), "2D tex target validity");
+	X(test_target_errors(GL_TEXTURE_3D), "3D tex target validity");
+	X(test_target_errors(GL_TEXTURE_CUBE_MAP), "Cubemap tex target validity");
+	X(test_target_errors(GL_TEXTURE_RECTANGLE), "Rectangle tex target validity");
+	X(test_target_errors(GL_TEXTURE_1D_ARRAY), "1D Array tex target validity");
+	X(test_target_errors(GL_TEXTURE_2D_ARRAY), "2D Array tex target validity");
+	X(test_target_errors(GL_TEXTURE_CUBE_MAP_ARRAY),
+		"Cubemap Array tex target validity");
+	X(test_param_errors(), "Param texture/level/layer validity");
+	X(test_format_errors(GL_VIEW_CLASS_128_BITS), "Format 128 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_96_BITS), "Format 96 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_64_BITS), "Format 64 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_48_BITS), "Format 48 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_32_BITS), "Format 32 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_24_BITS), "Format 24 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_16_BITS), "Format 16 bits validity");
+	X(test_format_errors(GL_VIEW_CLASS_8_BITS), "Format 8 bits validity");
+#undef X
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+		return PIGLIT_FAIL;
+	return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_extension("GL_ARB_texture_storage");
+	piglit_require_extension("GL_ARB_texture_view");
+	piglit_require_extension("GL_EXT_texture_integer");
+	piglit_require_extension("GL_ARB_texture_float");
+	piglit_require_extension("GL_ARB_texture_cube_map_array");
+	piglit_require_extension("GL_EXT_texture_array");
+	piglit_require_extension("GL_ARB_texture_rectangle");
+	piglit_require_extension("GL_EXT_texture3D");
+	piglit_reset_gl_error();
+}
diff --git a/tests/spec/arb_texture_view/queries.c b/tests/spec/arb_texture_view/queries.c
new file mode 100644
index 0000000..e4bb084
--- /dev/null
+++ b/tests/spec/arb_texture_view/queries.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view  queries of new state added by this extension
+ *
+ */
+
+#include "piglit-util-gl-common.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)
+{
+	GLuint tex[2], view_tex, l;
+	GLint param;
+
+	glGenTextures(2, tex);
+
+	// test the view causes immutable_format to be set
+	glBindTexture(GL_TEXTURE_2D, tex[0]);
+	glTexStorage2D(GL_TEXTURE_2D, 6, GL_R32F, 16, 32);
+	glTextureView(tex[1], GL_TEXTURE_2D, tex[0], GL_RG16F, 0, 1, 0, 1);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glBindTexture(GL_TEXTURE_2D, tex[1]);
+	glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_FORMAT, &param);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+
+	if (param != GL_TRUE) {
+		printf("bad query of immutable_format\n");
+		glDeleteTextures(2, tex);
+		return PIGLIT_FAIL;
+	}
+	glDeleteTextures(2,tex);
+
+	// test min_levels are additive
+	// test immutable_levels  get set correctly
+	// note: see params test for more min/num  level/layer query testing
+	glGenTextures(2,tex);
+	glBindTexture(GL_TEXTURE_CUBE_MAP, tex[0]);
+	glTexStorage2D(GL_TEXTURE_CUBE_MAP, 7, GL_R32F, 64, 64);
+	glTextureView(tex[1], GL_TEXTURE_CUBE_MAP, tex[0], GL_RG16I, 2, 4, 0, 6);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(2,tex);
+		return PIGLIT_FAIL;
+	}
+	glBindTexture(GL_TEXTURE_CUBE_MAP, tex[1]);
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+						&param);
+	if (param != 7) {
+		glDeleteTextures(2, tex);
+		printf("bad query of immutable_levels, expected 7 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	for (l = 0; l < 3; l++) {
+		glGenTextures(1, &view_tex);
+		glTextureView(view_tex, GL_TEXTURE_CUBE_MAP, tex[1], GL_RG16F, l, 4,
+					  0, 6);
+		glBindTexture(GL_TEXTURE_CUBE_MAP, view_tex);
+		glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LEVEL,
+							&param);
+		if (param != (2 + l)) {
+			glDeleteTextures(2, tex);
+			glDeleteTextures(1, &view_tex);
+			printf("bad query of view_min_level expected %u got %u\n", 2+l,
+				   param);
+			return PIGLIT_FAIL;
+		}
+		glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+							&param);
+		glDeleteTextures(1, &view_tex);
+		if (param != 7) {
+			glDeleteTextures(2, tex);
+			printf("query of immutable_levels not tracking orig, expected 7 got %u\n", param);
+			return PIGLIT_FAIL;
+		}
+	}
+	glDeleteTextures(2, tex);
+
+	// make sure default intial state is correct
+	// view_tex which is bound to GL_TEXTURE_CUBE_MAP is deleted
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LEVEL,
+							&param);
+	if (param != 0) {
+		printf("bad default of min_level, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_NUM_LEVELS,
+							&param);
+	if (param != 0) {
+		printf("bad default of num_levels, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_MIN_LAYER,
+							&param);
+	if (param != 0) {
+		printf("bad default of min_layer, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_VIEW_NUM_LAYERS,
+							&param);
+	if (param != 0) {
+		printf("bad default of num_layers, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_FORMAT,
+							&param);
+	if (param != 0) {
+		printf("bad default of immutable_format, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+	glGetTexParameteriv(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_IMMUTABLE_LEVELS,
+							&param);
+	if (param != 0) {
+		printf("bad default of immutable_levels, expected 0 got %u\n", param);
+		return PIGLIT_FAIL;
+	}
+
+	// test min_layers are additive
+	glGenTextures(2, tex);
+	glBindTexture(GL_TEXTURE_2D_ARRAY, tex[0]);
+	glTexStorage3D(GL_TEXTURE_2D_ARRAY, 7, GL_RG16F, 64, 64, 8);
+	glTextureView(tex[1], GL_TEXTURE_2D_ARRAY, tex[0], GL_RG16I, 0, 3, 1, 8);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(2,tex);
+		return PIGLIT_FAIL;
+	}
+	for (l = 0; l < 4; l++) {
+		glGenTextures(1, &view_tex);
+		glTextureView(view_tex, GL_TEXTURE_2D_ARRAY, tex[1], GL_RG16UI, 0, 4,
+					  l, 7);
+		glBindTexture(GL_TEXTURE_2D_ARRAY, view_tex);
+		glGetTexParameteriv(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_VIEW_MIN_LAYER,
+							&param);
+		if (param != (1 + l)) {
+			glDeleteTextures(2, tex);
+			glDeleteTextures(1, &view_tex);
+			printf("bad query of view_min_layer expected %u got %u\n", 1+l,
+				   param);
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &view_tex);
+	}
+	glDeleteTextures(2, tex);
+
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+		return PIGLIT_FAIL;
+
+	return PIGLIT_PASS;
+
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+
+	piglit_require_extension("GL_ARB_texture_storage");
+	piglit_require_extension("GL_ARB_texture_view");
+	piglit_reset_gl_error();
+}
diff --git a/tests/spec/arb_texture_view/rendering.c b/tests/spec/arb_texture_view/rendering.c
new file mode 100644
index 0000000..2674c67
--- /dev/null
+++ b/tests/spec/arb_texture_view/rendering.c
@@ -0,0 +1,758 @@
+/*
+ * Copyright © 2013 LunarG, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Author: Jon Ashburn <jon at lunarg.com>
+ */
+
+/**
+ * Tests GL_ARB_texture_view  rendering and lifetime of views
+ * Rendering includes with various targets, layers  and levels.
+ * Lifetime tests are combined with various formats and tex image data reads.
+ */
+#include <unistd.h>
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+	config.window_width = 128;
+	config.window_height = 128;
+
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char *TestName = "arb_texture_view-rendering";
+static int tex_loc_2Darray, tex_loc_1D;
+static int prog2Darray, prog1D;
+
+/* Formats. */
+
+struct format_desc {
+	const char  *name;
+	GLenum      internalfmt;
+	GLenum		storagefmt;
+	GLenum		imagefmt;
+	GLenum		imagetype;
+	GLenum		getfmt;
+	GLenum		gettype;
+	int         red, green, blue, alpha;
+};
+
+#define FORMAT(f) #f, f
+static const struct format_desc format_list[] = {
+		{FORMAT(GL_RGBA8UI), GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, 8, 8, 8, 8},
+		{FORMAT(GL_RGBA8I), GL_RGBA8I, GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA_INTEGER, GL_BYTE, 8, 8, 8, 8},
+		{FORMAT(GL_RGB16I), GL_RGB16, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB_INTEGER, GL_SHORT, 16, 16, 16, 0},
+		{FORMAT(GL_RGB16F), GL_RGB16, GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, GL_HALF_FLOAT, 16, 16, 16, 0},
+		{FORMAT(GL_R16UI), GL_R16, GL_RED, GL_UNSIGNED_BYTE, GL_RED_INTEGER, GL_SHORT, 16, 0, 0, 0},
+		{FORMAT(GL_R16F), GL_R16, GL_RED, GL_UNSIGNED_BYTE, GL_RED, GL_HALF_FLOAT, 16, 0, 0, 0},
+};
+#undef FORMAT
+
+
+static GLubyte Colors[][8] = {
+		{127,	0,   0, 255,  0, 10, 20,  0},
+		{  0, 127,   0, 255,  0,  0, 80, 90},
+		{  0,	0, 127, 255, 25,  0,  0, 60},
+		{  0, 127, 127, 255, 15, 15,  0,  0},
+		{127,	0, 127, 255,  0,  2, 50,  0},
+		{127, 127,   0, 255, 80, 10, 70, 20},
+		{255,	0,   0, 255, 60,  0, 40, 30},
+		{  0, 255,   0, 255, 50, 20,  2, 40},
+		{  0,	0, 255, 255, 40,  0,  1,  0},
+		{  0, 255, 255, 255, 30,  5,  3,  8},
+		{255,	0, 255, 255, 20, 18,  4,  7},
+		{255, 255,	0, 255,  10, 24, 77, 67},
+		{255, 255, 255, 255,  5,  33, 88, 44}
+};
+
+/**
+ * Create a single-color image. Up to 64 bits  per color depending upon bytes
+ */
+static GLubyte *
+create_solid_image(GLint w, GLint h, GLint d, const uint bytes, const uint idx)
+{
+	GLubyte *buf = (GLubyte *) malloc(w * h * d * bytes);
+	int i,j;
+
+	if (buf == NULL || idx > (sizeof(Colors) / bytes - 1)) {
+			free(buf);
+			return NULL;
+	}
+	for (i = 0; i < w * h * d; i++) {
+			for (j = 0; j < bytes; j++) {
+					buf[i*bytes+j] = Colors[idx][j];
+			}
+	}
+	return buf;
+}
+
+static void
+draw_line(float x, float y, float w, float h)
+{
+	GLfloat vertices[6] =  {x, y, 0.0,
+							x+w, y+h, 0.0};
+	GLuint elements[4] = {0, 1};
+
+	GLfloat texcoords[2] = {0.0, 1.0};
+
+
+	glVertexPointer(3, GL_FLOAT, 0, vertices);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+	glTexCoordPointer(1, GL_FLOAT, 0, texcoords);
+	glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, elements);
+}
+
+/**
+ *  Draw a textured quad, sampling only the given depth  of the 3D texture.
+ *  Use fixed function pipeline.
+ */
+static void
+draw_3d_depth_fixed(float x, float y, float w, float h, int depth)
+{
+	float depth_coord = (float)depth;
+
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+	glBegin(GL_QUADS);
+
+	glTexCoord3f(0, 0, depth_coord);
+	glVertex2f(x, y);
+
+	glTexCoord3f(1, 0, depth_coord);
+	glVertex2f(x + w, y);
+
+	glTexCoord3f(1, 1, depth_coord);
+	glVertex2f(x + w, y + h);
+
+	glTexCoord3f(0, 1, depth_coord);
+	glVertex2f(x, y + h);
+
+	glEnd();
+}
+
+static void
+draw_3d_depth(float x, float y, float w, float h, int depth)
+{
+	GLfloat d = (GLfloat) depth;
+	GLfloat vertices[12] =  {x, y, 0.0,
+							 x+w, y, 0.0,
+							 x+w, y+h, 0.0,
+							 x, y+h, 0.0};
+	GLuint elements[4] = {0, 1, 2, 3};
+
+	GLfloat texcoords[12] = {0.0, 0.0, d,
+							 1.0, 0.0, d,
+							 1.0, 1.0, d,
+							 0.0, 1.0, d};
+
+	glVertexPointer(3, GL_FLOAT, 0, vertices);
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+	glTexCoordPointer(3, GL_FLOAT, 0, texcoords);
+	glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, elements);
+}
+
+/**
+ * Simple views  of textures; test rendering with various texture view targets
+ */
+static enum piglit_result
+test_render_with_targets(GLenum target)
+{
+	GLuint tex, new_tex;
+	GLint width = 128, height = 64, depth = 4, levels = 8;
+	GLint l;
+
+	//only handle subset of legal targets
+	assert(target == GL_TEXTURE_1D ||
+	       target == GL_TEXTURE_2D ||
+	       target == GL_TEXTURE_2D_ARRAY ||
+	       target == GL_TEXTURE_3D);
+
+	glUseProgram(0);
+	glGenTextures(1, &tex);
+	glBindTexture(target, tex);
+
+	if (target == GL_TEXTURE_1D) {
+		glTexStorage1D(target, levels, GL_RGBA8, width);
+		height = 1;
+		depth = 1;
+	}
+	else if (target == GL_TEXTURE_2D) {
+		glTexStorage2D(target, levels, GL_RGBA8, width, height);
+		depth = 1;
+	}
+	else if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) {
+		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
+	}
+
+	/* load each mipmap with a different color texture */
+	for (l = 0; l < levels; l++) {
+			GLubyte *buf = create_solid_image(width, height, depth, 4, l);
+
+		if (buf != NULL) {
+			if (target == GL_TEXTURE_1D) {
+				glTexSubImage1D(GL_TEXTURE_1D, l, 0, width, GL_RGBA,
+								GL_UNSIGNED_BYTE, buf);
+			}
+			else if (target == GL_TEXTURE_2D) {
+				glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width, height,
+										GL_RGBA, GL_UNSIGNED_BYTE, buf);
+			}
+			else if (target == GL_TEXTURE_3D || target == GL_TEXTURE_2D_ARRAY) {
+				glTexSubImage3D(target, l, 0, 0, 0, width, height, depth,
+										GL_RGBA, GL_UNSIGNED_BYTE, buf);
+			}
+			free(buf);
+		}
+
+		if (width > 1)
+			width /= 2;
+		if (height > 1)
+			height /= 2;
+		if (depth > 1)
+			depth /= 2;
+	}
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDeleteTextures(1, &tex);
+
+		return PIGLIT_SKIP;
+	}
+
+	// create view of texture and bind it to target
+	glGenTextures(1, &new_tex);
+	glTextureView(new_tex, target, tex,  GL_RGBA8, 0, levels, 0, 1);
+	glDeleteTextures(1, &tex);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(1, &new_tex);
+		return PIGLIT_FAIL;
+	}
+	glActiveTexture(GL_TEXTURE0);
+	glBindTexture(target, new_tex);
+
+
+	/* draw a quad/line using each texture mipmap level */
+	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	for (l = 0; l < levels; l++) {
+		GLfloat expected[3];
+		int p;
+
+		glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, l);
+		glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, l);
+
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		if (target == GL_TEXTURE_1D) {
+				glUseProgram(prog1D);
+				glUniform1i(tex_loc_1D, 0);
+				draw_line(-1.0, -1.0, 2.0, 2.0);
+		}
+		else if (target == GL_TEXTURE_2D) {
+			glEnable(target);
+			piglit_draw_rect_tex(-1.0, -1.0, 2.0, 2.0, 0.0, 0.0, 1.0, 1.0);
+			glDisable(target);
+		} else if (target == GL_TEXTURE_2D_ARRAY) {
+			glUseProgram(prog2Darray);
+			glUniform1i(tex_loc_2Darray, 0);
+			draw_3d_depth(-1.0, -1.0, 2.0, 2.0, l);
+
+		} else if (target == GL_TEXTURE_3D) {
+			glEnable(target);
+			draw_3d_depth_fixed(-1.0, -1.0, 2.0, 2.0, l);
+			glDisable(target);
+		}
+
+		expected[0] = Colors[l][0] / 255.0;
+		expected[1] = Colors[l][1] / 255.0;
+		expected[2] = Colors[l][2] / 255.0;
+
+		p = piglit_probe_pixel_rgb(piglit_width/2, piglit_height/2, expected);
+
+		piglit_present_results();
+
+		if (0) {  //debug
+			printf("%s for level=%d, target=%s, expected color=%f %f %f\n",
+				   __func__, l, piglit_get_gl_enum_name(target), expected[0],
+				   expected[1], expected[2]);
+			sleep(1);
+		}
+
+		if (!p) {
+			printf("%s: wrong color for mipmap level %d\n", TestName, l);
+			glDeleteTextures(1, &new_tex);
+
+			return PIGLIT_FAIL;
+		}
+	}
+	glDeleteTextures(1, &new_tex);
+
+	return PIGLIT_PASS;
+}
+
+
+/**
+ * Views  with varying minimum  and number of levels, 2D only
+ */
+static enum piglit_result
+test_render_levels()
+{
+	GLuint tex, new_tex;
+	GLint width = 4096, height = 4096, levels =13;
+	GLuint num_levels[] = {3,2,2,1};
+	GLint l;
+	int expected_level;
+	GLfloat expected[3];
+	int p;
+
+	glUseProgram(0);
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, width, height);
+	glEnable(GL_TEXTURE_2D);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+	/* load each mipmap with a different color texture */
+	for (l = 0; l < levels; l++) {
+			GLubyte *buf = create_solid_image(width, height, 1, 4, l);
+
+		if (buf != NULL) {
+			glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width, height,
+										GL_RGBA, GL_UNSIGNED_BYTE, buf);
+			free(buf);
+		}
+
+		if (width > 1)
+			width /= 2;
+		if (height > 1)
+			height /= 2;
+	}
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDisable(GL_TEXTURE_2D);
+		glDeleteTextures(1, &tex);
+
+		return PIGLIT_SKIP;
+	}
+
+	// create view of texture with restricted levels and draw quad
+	// using smallest mip level in the view range which varies every loop
+	for (l = 0; l < ARRAY_SIZE(num_levels); l++) {
+		glGenTextures(1, &new_tex);
+		glTextureView(new_tex, GL_TEXTURE_2D, tex,  GL_RGBA8, l, num_levels[l], 0, 1);
+		glBindTexture(GL_TEXTURE_2D, new_tex);
+		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels-1);
+
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		piglit_draw_rect_tex(-1.0, -1.0, 2.0/(float) (l+2), 2.0/ (float) (l+2),
+							 0.0, 0.0, 1.0, 1.0);
+
+		expected_level = l + num_levels[l] - 1;
+		expected[0] = Colors[expected_level][0] / 255.0;
+		expected[1] = Colors[expected_level][1] / 255.0;
+		expected[2] = Colors[expected_level][2] / 255.0;
+
+		p = piglit_probe_pixel_rgb(piglit_width/(2*(l+3)), piglit_height/(2*(l+3)), expected);
+
+		piglit_present_results();
+
+		if (0) {  //debug
+			GLint param;
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, &param);
+			printf("%s for view min level=%d base_level=%d expected color=%f %f %f\n",
+				   __func__, l, param, expected[0], expected[1], expected[2]);
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &param);
+			printf("max_level=%d\n", param);
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_MIN_LEVEL, &param);
+			printf("view min_level=%d\n", param);
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_VIEW_NUM_LEVELS, &param);
+			printf("view num_level=%d\n", param);
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_IMMUTABLE_LEVELS, &param);
+			printf("immutable levels=%d\n", param);
+			glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, &param);
+			printf("view max_lod=%d\n", param);
+			sleep(1);
+		}
+
+		if (!p) {
+			printf("%s: wrong color for view min level %d, expected_level %d\n",
+				   TestName, l, expected_level);
+			glDisable(GL_TEXTURE_2D);
+			glDeleteTextures(1, &new_tex);
+			glDeleteTextures(1, &tex);
+
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &new_tex);
+	}
+
+	glDisable(GL_TEXTURE_2D);
+	glDeleteTextures(1, &tex);
+	return PIGLIT_PASS;
+}
+
+/**
+ * Views  with varying minimum  and number of layers 2D_ARRAY only
+ */
+
+static enum piglit_result
+test_render_layers()
+{
+	GLuint tex, new_tex;
+	GLint width = 16, height = 16, layers = 8;
+	GLint l;
+	GLint num_layers[] = {7, 1, 2, 2};
+	int expected_layer;
+	GLfloat expected[3];
+	int p;
+
+	glUseProgram(prog2Darray);
+	glUniform1i(tex_loc_2Darray, 0);
+
+	glGenTextures(1, &tex);
+	glActiveTexture(GL_TEXTURE0);
+	glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
+
+	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
+	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 0);
+	glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, width, height, layers);
+
+	/* load each array layer with a different color texture */
+	for (l = 0; l < layers; l++) {
+			GLubyte *buf = create_solid_image(width, height, 1, 4, l);
+
+		if (buf != NULL) {
+				glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, l, width, height, 1,
+										GL_RGBA, GL_UNSIGNED_BYTE, buf);
+			free(buf);
+		}
+
+	}
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		printf("%s:%s Found gl errors prior to testing glTextureView\n",
+				   TestName, __func__);
+		glDeleteTextures(1, &tex);
+		return PIGLIT_SKIP;
+	}
+
+	// create view of texture with restricted layers and draw quad
+	// using a single layer in the view range which varies every loop
+	for (l = 0; l < ARRAY_SIZE(num_layers); l++) {
+		glGenTextures(1, &new_tex);
+		glTextureView(new_tex, GL_TEXTURE_2D_ARRAY, tex,  GL_RGBA8, 0, 1, l, num_layers[l]);
+
+		glActiveTexture(GL_TEXTURE0);
+		glBindTexture(GL_TEXTURE_2D_ARRAY, new_tex);
+
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		expected_layer = l + num_layers[l] - 1;
+		draw_3d_depth(-1.0, -1.0, 2.0, 2.0, expected_layer);
+
+		expected[0] = Colors[expected_layer][0] / 255.0;
+		expected[1] = Colors[expected_layer][1] / 255.0;
+		expected[2] = Colors[expected_layer][2] / 255.0;
+
+		p = piglit_probe_pixel_rgb(piglit_width/2, piglit_height/2, expected);
+
+		piglit_present_results();
+
+		if (0) {  //debug
+			printf("%s for view min layer=%d expected_layer=%d expected color=%f %f %f\n",
+				   __func__, l, expected_layer, expected[0], expected[1], expected[2]);
+			sleep(1);
+		}
+
+		if (!p) {
+			printf("%s: wrong color for view min layer %d, expected_layer %d\n",
+				   TestName, l, expected_layer);
+			glDeleteTextures(1, &new_tex);
+			glDeleteTextures(1, &tex);
+
+			return PIGLIT_FAIL;
+		}
+		glDeleteTextures(1, &new_tex);
+	}
+
+	glDeleteTextures(1, &tex);
+	return PIGLIT_PASS;
+}
+
+/**
+ * Views with data format changes. 1D textures only.
+ * Also uses multiple simultaneous views with different lifetimes and check results
+ * via glGetTexImage().
+ */
+
+static int
+compare_buffers(unsigned char * buf0, unsigned char *buf1, GLint w)
+{
+	int i;
+	for (i = 0; i < w; i++) {
+		if (buf0[i] != buf1[i]) {
+			printf("mismatched texels at index (%d)\n", i);
+			printf("  Buffer0: %u\n", buf0[i]);
+			printf("  Buffer1: %u\n", buf1[i]);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+static enum piglit_result
+test_format_lifetime(struct format_desc desc0, struct format_desc desc1)
+{
+	GLuint tex, view_tex[3];
+	GLint width = 32, w, levels = 6;
+	GLint l;
+	int bytes;
+	unsigned char *buffer0, *buffer1;
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_1D, tex);
+	glTexStorage1D(GL_TEXTURE_1D, levels, desc0.storagefmt, width);
+	glGenTextures(3, view_tex);
+	glTextureView(view_tex[0], GL_TEXTURE_1D, tex,  desc0.internalfmt, 0,
+				  levels, 0, 1);
+	glTextureView(view_tex[1], GL_TEXTURE_1D, view_tex[0], desc1.internalfmt, 0,
+				  levels, 0, 1);
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(1, &tex);
+		glDeleteTextures(3, view_tex);
+		return PIGLIT_FAIL;
+	}
+
+	/* load each mipmap with a different color texture */
+	w = width;
+	bytes = (desc0.red + desc0.green + desc0.blue + desc0.alpha) / 8;
+	for (l = 0; l < levels; l++) {
+		GLubyte *buf = create_solid_image(width, 1, 1, bytes, l);
+
+		if (buf != NULL) {
+			glTexSubImage1D(GL_TEXTURE_1D, l, 0, w, desc0.imagefmt,
+							desc0.imagetype, buf);
+			free(buf);
+		}
+
+		if (w > 1)
+			w /= 2;
+	}
+
+	if (0) {  // debug
+		printf("%s:fmt0=%s, fmt1=%s, strgfmt0=%s, gettype0=%s\n",__func__,
+			   piglit_get_gl_enum_name(desc0.internalfmt),
+			   piglit_get_gl_enum_name(desc1.internalfmt),
+			   piglit_get_gl_enum_name(desc0.storagefmt),
+			   piglit_get_gl_enum_name(desc0.gettype));
+		printf("bytes=%d, width=%d, view_tex[0]=%d, [1]=%d, [2]=%d\n",bytes,width,
+			   view_tex[0], view_tex[1], view_tex[2]);
+
+	}
+
+	glDeleteTextures(1, &tex);
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(3, view_tex);
+		return PIGLIT_FAIL;
+	}
+
+	/* compare view0 all level texels bytes to view1 texels bytes */
+	buffer0 = malloc(width * bytes);
+	buffer1 = malloc(width * bytes);
+	w = width;
+	for (l = 0; l < levels; l++) {
+		glBindTexture(GL_TEXTURE_1D, view_tex[0]);
+		glGetTexImage(GL_TEXTURE_1D, l, desc0.getfmt, desc0.gettype, buffer0);
+
+		glBindTexture(GL_TEXTURE_1D, view_tex[1]);
+		glGetTexImage(GL_TEXTURE_1D, l, desc1.getfmt, desc1.gettype, buffer1);
+		if (compare_buffers(buffer0, buffer1, w)) {
+			piglit_check_gl_error(GL_NO_ERROR);
+			printf("level %d  texel mismatch view 0 and view1, width=%d\n", l, w);
+			free(buffer0);
+			free(buffer1);
+			glDeleteTextures(3, view_tex);
+
+			return PIGLIT_FAIL;
+
+		}
+
+		if (w > 1)
+			w /= 2;
+	}
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+		glDeleteTextures(3, view_tex);
+		return PIGLIT_FAIL;
+	}
+
+	/* compare view1 base level texels to view2 after view0 and view1 deleted */
+	glBindTexture(GL_TEXTURE_1D, view_tex[1]);
+	glGetTexImage(GL_TEXTURE_1D, 0, desc1.getfmt, desc1.gettype, buffer1);
+
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			printf("gl error after glGetTexImage\n");
+	}
+
+	glTextureView(view_tex[2], GL_TEXTURE_1D, view_tex[0], desc0.internalfmt,
+				0, 1, 0, 1);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			printf("gl error after glTextureView[2]n");
+	}
+	glDeleteTextures(2, view_tex);
+	glBindTexture(GL_TEXTURE_1D, view_tex[2]);
+	glGetTexImage(GL_TEXTURE_1D, 0, desc0.getfmt, desc0.gettype, buffer0);
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE) {
+			printf("gl error after glGetTexI\n");
+	}
+
+	if (compare_buffers(buffer0, buffer1, width)) {
+			free(buffer0);
+			free(buffer1);
+			glDeleteTextures(1, &view_tex[2]);
+
+			return PIGLIT_FAIL;
+	}
+
+	free(buffer0);
+	free(buffer1);
+	glDeleteTextures(1, &view_tex[2]);
+
+	return PIGLIT_PASS;
+
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	enum piglit_result pass = PIGLIT_PASS;
+	enum piglit_result tmp;
+#define X(f, n) tmp = (f); pass = tmp != PIGLIT_PASS ? PIGLIT_FAIL : pass; piglit_report_subtest_result(tmp, (n))
+	X(test_format_lifetime(format_list[0], format_list[1]), "view compare 32 bit formats");
+	X(test_format_lifetime(format_list[2], format_list[3]), "view compare 48 bit formats");
+	X(test_format_lifetime(format_list[4], format_list[5]), "view compare 16 bit formats");
+	X(test_render_layers(), "2D layers rendering");
+	X(test_render_levels(), "2D levels rendering");
+	X(test_render_with_targets(GL_TEXTURE_1D), "1D view rendering");
+	X(test_render_with_targets(GL_TEXTURE_2D), "2D view rendering");
+	X(test_render_with_targets(GL_TEXTURE_3D), "3D view rendering");
+	X(test_render_with_targets(GL_TEXTURE_2D_ARRAY), "2D Array view rendering");
+#undef X
+	if (piglit_check_gl_error(GL_NO_ERROR) == GL_FALSE)
+		return PIGLIT_FAIL;
+	return pass;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	int vs, fs;
+	static char *vs_code;
+	static char *fs_code;
+	char *shader_version = "";
+	char *extension_fs = "#extension GL_EXT_texture_array : enable";
+	char *extension_vs = "";
+
+	piglit_require_extension("GL_ARB_texture_storage");
+	piglit_require_extension("GL_ARB_texture_view");
+	piglit_require_extension("GL_EXT_texture_integer");
+	piglit_require_extension("GL_EXT_texture_array");
+	piglit_require_extension("GL_EXT_texture3D");
+	piglit_reset_gl_error();
+
+    // setup shaders and program object for 2DArray rendering
+	asprintf(&vs_code,
+		 "%s\n%s\n"
+		 "void main()\n"
+		 "{\n"
+		 "    gl_Position = gl_Vertex;\n"
+		 "    gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+		 "}\n",
+		 shader_version, extension_vs);
+	asprintf(&fs_code,
+		 "%s\n%s\n"
+		 "uniform sampler2DArray tex;\n"
+		 "void main()\n"
+		 "{\n"
+		 "   vec4 color  = texture2DArray(tex, gl_TexCoord[0].xyz);\n"
+		 "   gl_FragColor = vec4(color.xyz, 1.0);\n"
+		 "}\n",
+		 shader_version, extension_fs);
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_code);
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+
+	free(fs_code);
+	free(vs_code);
+	if (!vs || !fs)
+		piglit_report_result(PIGLIT_FAIL);
+
+	prog2Darray = glCreateProgram();
+	glAttachShader(prog2Darray, vs);
+	glAttachShader(prog2Darray, fs);
+	glLinkProgram(prog2Darray);
+	if (!piglit_link_check_status(prog2Darray))
+		piglit_report_result(PIGLIT_FAIL);
+
+	tex_loc_2Darray = glGetUniformLocation(prog2Darray, "tex");
+
+    // setup shaders and program object for 1D rendering
+	asprintf(&fs_code,
+		 "%s\n%s\n"
+		 "uniform sampler1D tex;\n"
+		 "void main()\n"
+		 "{\n"
+		 "   vec4 color  = texture1D(tex, gl_TexCoord[0].x);\n"
+		 "   gl_FragColor = vec4(color.xyz, 1.0);\n"
+		 "}\n",
+		 shader_version, extension_fs);
+
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_code);
+	free(fs_code);
+
+	prog1D = glCreateProgram();
+	glAttachShader(prog1D, vs);
+	glAttachShader(prog1D, fs);
+	glLinkProgram(prog1D);
+	if (!piglit_link_check_status(prog1D))
+		piglit_report_result(PIGLIT_FAIL);
+
+	tex_loc_1D = glGetUniformLocation(prog1D, "tex");
+}
-- 
1.8.1.2



More information about the Piglit mailing list