[Piglit] [PATCH 5/7] ARB_texture_view: Test for rendering various targets in texture view

Jon Ashburn jon at lunarg.com
Thu Oct 24 23:49:00 CEST 2013


Tests GL_ARB_texture_view rendering with various texture targets.
Creates texture maps with different solid colors for each level or layer
reads the framebuffer to ensure the rendered color is correct.

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/common.c           | 109 +++++++++-
 tests/spec/arb_texture_view/common.h           |  19 +-
 tests/spec/arb_texture_view/rendering_target.c | 269 +++++++++++++++++++++++++
 5 files changed, 396 insertions(+), 3 deletions(-)
 create mode 100644 tests/spec/arb_texture_view/rendering_target.c

diff --git a/tests/all.tests b/tests/all.tests
index 8784e24..5941eb2 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1476,6 +1476,7 @@ arb_texture_view['params'] = concurrent_test('arb_texture_view-params')
 arb_texture_view['formats'] = concurrent_test('arb_texture_view-formats')
 arb_texture_view['targets'] = concurrent_test('arb_texture_view-targets')
 arb_texture_view['queries'] = concurrent_test('arb_texture_view-queries')
+arb_texture_view['rendering-target'] = concurrent_test('arb_texture_view-rendering-target')
 
 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 6945a05..6b69bb1 100644
--- a/tests/spec/arb_texture_view/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_view/CMakeLists.gl.txt
@@ -14,5 +14,6 @@ piglit_add_executable(arb_texture_view-params params.c)
 piglit_add_executable(arb_texture_view-formats formats.c common.c)
 piglit_add_executable(arb_texture_view-targets targets.c common.c)
 piglit_add_executable(arb_texture_view-queries queries.c)
+piglit_add_executable(arb_texture_view-rendering-target rendering_target.c common.c)
 
 # vim: ft=cmake:
diff --git a/tests/spec/arb_texture_view/common.c b/tests/spec/arb_texture_view/common.c
index f8ecb9e..acbcfad 100644
--- a/tests/spec/arb_texture_view/common.c
+++ b/tests/spec/arb_texture_view/common.c
@@ -36,7 +36,46 @@
  * the variable parameters.
  */
 
-unsigned int update_valid_arrays(GLenum *valid, GLenum *invalid,
+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 pixel depending upon bytes
+ */
+GLubyte *
+create_solid_image(GLint w, GLint h, GLint d, const unsigned int bytes,
+		   const unsigned int 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;
+}
+
+unsigned int
+update_valid_arrays(GLenum *valid, GLenum *invalid,
 			 unsigned int numInvalid, ... )
 {
 	va_list args;
@@ -58,3 +97,71 @@ unsigned int update_valid_arrays(GLenum *valid, GLenum *invalid,
 	va_end(args);
 	return num;
 }
+
+/**
+ * Draw a textured line  from x, y to x+w, y+h. Use tex coordinates 0.0 to 1.0
+ */
+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.
+ */
+void
+draw_3d_depth_fixed(float x, float y, float w, float h, float depth)
+{
+	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+	glBegin(GL_QUADS);
+
+	glTexCoord3f(0, 0, depth);
+	glVertex2f(x, y);
+
+	glTexCoord3f(1, 0, depth);
+	glVertex2f(x + w, y);
+
+	glTexCoord3f(1, 1, depth);
+	glVertex2f(x + w, y + h);
+
+	glTexCoord3f(0, 1, depth);
+	glVertex2f(x, y + h);
+
+	glEnd();
+}
+
+/**
+ *  Draw a textured quad, sampling only the given depth  of the 3D texture.
+ *  Use shader pipeline.
+ */
+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);
+}
diff --git a/tests/spec/arb_texture_view/common.h b/tests/spec/arb_texture_view/common.h
index 1ffcaea..2a0ecfa 100644
--- a/tests/spec/arb_texture_view/common.h
+++ b/tests/spec/arb_texture_view/common.h
@@ -22,7 +22,22 @@
  *
  * Author: Jon Ashburn <jon at lunarg.com>
  */
+#include "piglit-util-gl-common.h"
 
+GLubyte *
+create_solid_image(GLint w, GLint h, GLint d, const unsigned int bytes,
+		   const unsigned int idx);
 
-unsigned int update_valid_arrays(GLenum *valid, GLenum *invalid,
-			 unsigned int numInvalid, ... );
+unsigned int
+update_valid_arrays(GLenum *valid, GLenum *invalid, unsigned int numInvalid,
+		    ... );
+void
+draw_line(float x, float y, float w, float h);
+
+void
+draw_3d_depth_fixed(float x, float y, float w, float h, int depth);
+
+void
+draw_3d_depth(float x, float y, float w, float h, int depth);
+
+extern GLubyte Colors[][8];
diff --git a/tests/spec/arb_texture_view/rendering_target.c b/tests/spec/arb_texture_view/rendering_target.c
new file mode 100644
index 0000000..dc39890
--- /dev/null
+++ b/tests/spec/arb_texture_view/rendering_target.c
@@ -0,0 +1,269 @@
+/*
+ * 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 with various texture targets.
+ * Creates texture maps with different  solid colors for each level or layer
+ * reads the framebuffer to ensure the rendered color is correct.
+ */
+
+#include "piglit-util-gl-common.h"
+#include "common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 20;
+	config.supports_gl_core_version = 31;
+	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-target";
+static int tex_loc_2Darray, tex_loc_1D;
+static int prog2Darray, prog1D;
+
+/**
+ * Simple views  of textures; test rendering with various texture view targets
+ */
+static bool
+test_render_with_targets(GLenum target)
+{
+	GLuint tex, newTex;
+	GLint width = 128, height = 64, depth = 4, levels = 8;
+	GLint l;
+	bool pass = true;
+
+	glUseProgram(0);
+	glGenTextures(1, &tex);
+	glBindTexture(target, tex);
+
+	switch (target) {
+	case GL_TEXTURE_1D:
+		glTexStorage1D(target, levels, GL_RGBA8, width);
+		height = 1;
+		depth = 1;
+		break;
+	case GL_TEXTURE_2D:
+		glTexStorage2D(target, levels, GL_RGBA8, width, height);
+		depth = 1;
+		break;
+	case GL_TEXTURE_3D:
+	case GL_TEXTURE_2D_ARRAY:
+		glTexStorage3D(target, levels, GL_RGBA8, width, height, depth);
+		break;
+	default:
+		/* only handle subset of legal targets */
+		assert(!"Illegal target for test_render_with_targets()\n");
+		break;
+	}
+
+	/* 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) {
+			switch(target) {
+			case GL_TEXTURE_1D:
+				glTexSubImage1D(GL_TEXTURE_1D, l, 0, width,
+						GL_RGBA, GL_UNSIGNED_BYTE, buf);
+				break;
+			case GL_TEXTURE_2D:
+				glTexSubImage2D(GL_TEXTURE_2D, l, 0, 0, width,
+						height, GL_RGBA,
+						GL_UNSIGNED_BYTE, buf);
+				break;
+			case GL_TEXTURE_3D:
+			case GL_TEXTURE_2D_ARRAY:
+				glTexSubImage3D(target, l, 0, 0, 0, width,
+						height, depth, GL_RGBA,
+						GL_UNSIGNED_BYTE, buf);
+				break;
+			}
+			free(buf);
+		} else {
+			assert(!"create_solid_image() failed\n");
+		}
+
+		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: Found gl errors prior to testing glTextureView\n",
+				   TestName);
+		glDeleteTextures(1, &tex);
+
+		return false;
+	}
+
+	/* create view of texture and bind it to target */
+	glGenTextures(1, &newTex);
+	glTextureView(newTex, target, tex,  GL_RGBA8, 0, levels, 0, 1);
+	glDeleteTextures(1, &tex);
+	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+	glActiveTexture(GL_TEXTURE0);
+	glBindTexture(target, newTex);
+
+
+	/* 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);
+
+		switch (target) {
+		case GL_TEXTURE_1D:
+			glUseProgram(prog1D);
+			glUniform1i(tex_loc_1D, 0);
+			draw_line(-1.0, -1.0, 2.0, 2.0);
+			break;
+		case 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);
+			break;
+		case GL_TEXTURE_2D_ARRAY:
+			glUseProgram(prog2Darray);
+			glUniform1i(tex_loc_2Darray, 0);
+			draw_3d_depth(-1.0, -1.0, 2.0, 2.0, l);
+			break;
+		case GL_TEXTURE_3D:
+			glEnable(target);
+			draw_3d_depth_fixed(-1.0, -1.0, 2.0, 2.0, (float) l);
+			glDisable(target);
+			break;
+		}
+
+		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("for level=%d, target=%s, expected color=%f %f %f\n",
+			   l, piglit_get_gl_enum_name(target), expected[0],
+				   expected[1], expected[2]);
+		sleep(1);
+#endif
+
+		if (!p) {
+			printf("%s: wrong color for mipmap level %d\n",
+			       TestName, l);
+			pass = false;
+		}
+	}
+	glDeleteTextures(1, &newTex);
+
+	return pass;
+}
+
+#define X(f, desc)					     	\
+	do {							\
+		const bool subtest_pass = (f);			\
+		piglit_report_subtest_result(subtest_pass	\
+					     ? PIGLIT_PASS : PIGLIT_FAIL, \
+					     (desc));		\
+		pass = pass && subtest_pass;			\
+	} while (0)
+
+enum piglit_result
+piglit_display(void)
+{
+	bool pass = true;
+	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
+	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	static char *vsCode;
+	static char *fsCode;
+
+	piglit_require_extension("GL_ARB_texture_storage");
+	piglit_require_extension("GL_ARB_texture_view");
+	piglit_require_extension("GL_EXT_texture_array");
+
+	/* setup shaders and program object for 2DArray rendering */
+	asprintf(&vsCode,
+		 "void main()\n"
+		 "{\n"
+		 "    gl_Position = gl_Vertex;\n"
+		 "    gl_TexCoord[0] = gl_MultiTexCoord0;\n"
+		 "}\n");
+	asprintf(&fsCode,
+		 "#extension GL_EXT_texture_array : enable\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");
+
+	prog2Darray = piglit_build_simple_program(vsCode, fsCode);
+	free(fsCode);
+	tex_loc_2Darray = glGetUniformLocation(prog2Darray, "tex");
+
+	/* setup shaders and program object for 1D rendering */
+	asprintf(&fsCode,
+		 "#extension GL_EXT_texture_array : enable\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");
+	prog1D = piglit_build_simple_program(vsCode, fsCode);
+	free(fsCode);
+	free(vsCode);
+
+	tex_loc_1D = glGetUniformLocation(prog1D, "tex");
+}
-- 
1.8.1.2



More information about the Piglit mailing list