[Piglit] [PATCH] ARB_texture_view: Add test for rendering with texture view.

Jon Ashburn jon at lunarg.com
Tue Oct 15 01:01:17 CEST 2013


Tests GL_ARB_texture_view  rendering and lifetime of views.
Rendering includes using various targets, layers  and levels.
Lifetime tests are combined with various formats and tex image data reads.

Tested on Nvidia Quadro 600; all subtests  pass.
---
 tests/all.tests                               |   1 +
 tests/spec/arb_texture_view/CMakeLists.gl.txt |   1 +
 tests/spec/arb_texture_view/rendering.c       | 758 ++++++++++++++++++++++++++
 3 files changed, 760 insertions(+)
 create mode 100644 tests/spec/arb_texture_view/rendering.c

diff --git a/tests/all.tests b/tests/all.tests
index b21d0a3..df04274 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1472,6 +1472,7 @@ arb_texture_view = Group()
 spec['ARB_texture_view'] = arb_texture_view
 arb_texture_view['params'] = plain_test('arb_texture_view-params')
 arb_texture_view['queries'] = plain_test('arb_texture_view-queries')
+arb_texture_view['rendering'] = plain_test('arb_texture_view-rendering')
 
 tdfx_texture_compression_fxt1 = Group()
 spec['3DFX_texture_compression_FXT1'] = tdfx_texture_compression_fxt1
diff --git a/tests/spec/arb_texture_view/CMakeLists.gl.txt b/tests/spec/arb_texture_view/CMakeLists.gl.txt
index 94ddfb4..6fbd441 100644
--- a/tests/spec/arb_texture_view/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_view/CMakeLists.gl.txt
@@ -11,5 +11,6 @@ link_libraries(
 
 piglit_add_executable(arb_texture_view-params params.c)
 piglit_add_executable(arb_texture_view-queries queries.c)
+piglit_add_executable(arb_texture_view-rendering rendering.c)
 
 # vim: ft=cmake:
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