[Piglit] [PATCH] arb_texture_multisample: add new texelFetch() test

Brian Paul brianp at vmware.com
Tue Jul 8 16:17:09 PDT 2014


A simple test to check that using texelFetch() to get individual
samples from a MSAA texture really works.

v2: rename "fetch texel" -> "texel fetch".
---
 tests/all.py                                       |    3 +
 .../spec/arb_texture_multisample/CMakeLists.gl.txt |    1 +
 tests/spec/arb_texture_multisample/texelfetch.c    |  315 ++++++++++++++++++++
 3 files changed, 319 insertions(+)
 create mode 100644 tests/spec/arb_texture_multisample/texelfetch.c

diff --git a/tests/all.py b/tests/all.py
index 7ce90d8..dba3115 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -1382,6 +1382,9 @@ add_concurrent_test(arb_texture_multisample, 'texelFetch fs sampler2DMSArray 4 9
 add_concurrent_test(arb_texture_multisample, 'texelFetch fs sampler2DMSArray 4 98x129x1-98x129x9')
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-texstate')
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-errors')
+add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-texelfetch 2')
+add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-texelfetch 4')
+add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-texelfetch 8')
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-sample-mask')
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-sample-mask-value')
 add_concurrent_test(arb_texture_multisample, 'arb_texture_multisample-sample-mask-execution')
diff --git a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
index 0f00e72..fbb3f5c 100644
--- a/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_multisample/CMakeLists.gl.txt
@@ -13,6 +13,7 @@ link_libraries (
 piglit_add_executable (arb_texture_multisample-minmax minmax.c)
 piglit_add_executable (arb_texture_multisample-errors errors.c)
 piglit_add_executable (arb_texture_multisample-fb-completeness fb-completeness.c)
+piglit_add_executable (arb_texture_multisample-texelfetch texelfetch.c)
 piglit_add_executable (arb_texture_multisample-texstate texstate.c)
 piglit_add_executable (arb_texture_multisample-sample-mask sample-mask.c)
 piglit_add_executable (arb_texture_multisample-sample-mask-value sample-mask-value.c)
diff --git a/tests/spec/arb_texture_multisample/texelfetch.c b/tests/spec/arb_texture_multisample/texelfetch.c
new file mode 100644
index 0000000..ed93f7a
--- /dev/null
+++ b/tests/spec/arb_texture_multisample/texelfetch.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2014 VMware, 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.
+ */
+
+/* File: texelfetch.c
+ *
+ * Tests that texelFetch() really gets samples from different sample positions.
+ * First, we draw a triangle into a MSAA texture/FBO.
+ * Then, for each sample location, we draw a texture quad, using texelFetch()
+ * to grab a particular sample.  We read back the colors to a temporary image.
+ * Finally, we check that the colors in the temp images are different for at
+ * least some of the pixels/samples.
+ *
+ * Brian Paul
+ * July 2014
+ */
+
+
+#include "piglit-util-gl-common.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+    config.supports_gl_compat_version = 30;
+    config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+/* Debug helpers */
+#define MSAA 1
+#define DEBUG_WITH_BLIT 0
+#define DISPLAY_AVERAGE 0
+
+#define MAX_SAMPLES 32
+
+static const char *vs_src_draw =
+	"#version 130 \n"
+	"in vec4 pos;\n"
+	"void main() { \n"
+	"   gl_Position = pos; \n"
+	"} \n";
+
+static const char *fs_src_draw =
+	"#version 130 \n"
+	"out vec4 frag_color; \n"
+	"void main() { \n"
+	"   frag_color = vec4(0.9, 0.8, 0, 1); \n"
+	"} \n";
+
+static const char *vs_src_readback =
+	"#version 130 \n"
+	"in vec4 pos; \n"
+	"in vec2 coord_vs;\n"
+	"out vec2 coord_fs;\n"
+	"void main() { \n"
+	"   gl_Position = pos; \n"
+	"   coord_fs = coord_vs; \n"
+	"} \n";
+
+static const char *fs_src_readback =
+	"#version 130 \n"
+	"#extension GL_ARB_texture_multisample : require\n"
+#if MSAA
+	"uniform sampler2DMS tex; \n"
+#else
+	"uniform sampler2D tex; \n"
+#endif
+	"uniform int samplePos; \n"
+	"in vec2 coord_fs; \n"
+	"out vec4 frag_color; \n"
+	"void main() { \n"
+#if MSAA
+	"   frag_color = texelFetch(tex, ivec2(coord_fs), samplePos); \n"
+#else
+	"   frag_color = texture2D(tex, coord_fs / 31.0); \n"
+#endif
+	"} \n";
+
+static GLuint tex;
+static GLuint fbo;
+static GLuint readback_prog, draw_prog;
+static GLint sample_pos_uniform;
+static GLint draw_pos_attr, readback_pos_attr, readback_texcoord_attr;
+static int num_samples = 0;
+
+
+enum piglit_result
+piglit_display(void)
+{
+	static const GLfloat tri_verts[3][2] = {
+		{ -0.8, -1 },
+		{ 0.8, -0.9 },
+		{ 0.1, 1}
+	};
+	static const GLfloat quad_verts[4][2] = {
+		{ -1, -1 },
+		{  1, -1 },
+		{  1,  1 },
+		{ -1,  1 }
+	};
+	static const GLfloat quad_texcoords[4][2] = {
+		{ 0, 0 },
+		{ 31, 0 },
+		{ 31, 31 },
+		{ 0, 31 }
+	};
+	unsigned i, j, num_diffs;
+	GLfloat *images[MAX_SAMPLES], *average;
+
+	for (i = 0; i < num_samples; i++) {
+		images[i] = malloc(32 * 32 * 4 * sizeof(GLfloat));
+	}
+	average = malloc(32 * 32 * 4 * sizeof(GLfloat));
+
+	glViewport(0, 0, 32, 32);
+
+	/* Draw triangle into MSAA texture */
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+	glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
+	glClear(GL_COLOR_BUFFER_BIT);
+	piglit_check_gl_error(GL_NO_ERROR);
+
+	glUseProgram(draw_prog);
+	glVertexAttribPointer(draw_pos_attr, 2, GL_FLOAT,
+			      GL_FALSE, 0, tri_verts);
+	glEnableVertexAttribArray(draw_pos_attr);
+	glDrawArrays(GL_TRIANGLES, 0, 3);
+	glDisableVertexAttribArray(draw_pos_attr);
+
+	piglit_check_gl_error(GL_NO_ERROR);
+
+	/* Read back samples:
+	 * Draw textured quad into main framebuffer using texture samples
+	 * from the MSAA texture.  Then use glReadPixels to get the samples.
+	 */
+	glBindFramebuffer(GL_FRAMEBUFFER, 0);
+	glClearColor(0.25, 0.25, 0.25, 0);
+	glClear(GL_COLOR_BUFFER_BIT);
+	glUseProgram(readback_prog);
+
+#if DEBUG_WITH_BLIT
+	/* Blit from MSAA texture/FBO to window */
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+	glBlitFramebuffer(0, 0, 31, 31,
+			  0, 0, 31, 31,
+			  GL_COLOR_BUFFER_BIT, GL_NEAREST);
+#else
+	for (i = 0; i < num_samples; i++) {
+		/* fetch the i-th sample */
+		glUniform1i(sample_pos_uniform, i);
+
+		glVertexAttribPointer(readback_pos_attr, 2, GL_FLOAT,
+				      GL_FALSE, 0, quad_verts);
+		glVertexAttribPointer(readback_texcoord_attr, 2, GL_FLOAT,
+				      GL_FALSE, 0, quad_texcoords);
+		glEnableVertexAttribArray(readback_pos_attr);
+		glEnableVertexAttribArray(readback_texcoord_attr);
+		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+		glDisableVertexAttribArray(readback_pos_attr);
+		glDisableVertexAttribArray(readback_texcoord_attr);
+
+		glReadPixels(0, 0, 32, 32, GL_RGBA, GL_FLOAT, images[i]);
+	}
+#endif
+
+	piglit_check_gl_error(GL_NO_ERROR);
+
+	/* compare sample images.
+	 * There should be some differences.
+	 */
+	num_diffs = 0;
+	for (j = 0; j < 32 * 32; j++) {
+		for (i = 1; i < num_samples; i++) {
+			/* compare samples at [j] */
+			if (images[i][j*4+0] != images[0][j*4+0]) {
+				num_diffs++;
+				if (0)
+				printf("diff at pixel %u: sample[%u]=%g vs"
+				       " sample[%d]=%g\n",
+				       j,
+				       i, images[i][j*4+0],
+				       0, images[0][j*4+0]);
+			}
+		}
+	}
+
+	if (num_diffs == 0) {
+		fprintf(stderr,
+			"There was no difference among the %d samples\n",
+			num_samples);
+		fflush(stderr);
+	}
+
+#if DISPLAY_AVERAGE
+	/* "Resolve" the msaa image by computing the average of the samples. */
+	for (j = 0; j < 32 * 32 * 4; j++) {
+		float sum = 0.0f;
+		for (i = 0; i < num_samples; i++) {
+			sum += images[i][j];
+		}
+		average[j] = sum / num_samples;
+	}
+
+	glUseProgram(0);
+	glDrawPixels(32, 32, GL_RGBA, GL_FLOAT, average);
+#endif
+
+	piglit_present_results();
+
+	/* clean up */
+	for (i = 0; i < num_samples; i++) {
+		free(images[i]);
+	}
+	free(average);
+
+	return num_diffs ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+void
+piglit_init(int argc, char **argv)
+{
+	GLuint max_samples;
+	GLint tex_uniform;
+
+#if MSAA
+	piglit_require_extension("GL_ARB_texture_multisample");
+#endif
+
+	if (argc < 2) {
+		fprintf(stderr, "%s <sample_count>\n", argv[0]);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+#if MSAA
+	num_samples = strtoul(argv[1], NULL, 0);
+	glGetIntegerv(GL_MAX_SAMPLES, (GLint *)&max_samples);
+	if (num_samples > max_samples)
+		piglit_report_result(PIGLIT_SKIP);
+#else
+	num_samples = 1;
+#endif
+
+	assert(num_samples <= MAX_SAMPLES);
+
+	piglit_check_gl_error(GL_NO_ERROR);
+
+	/* create MSAA tex and fbo */
+	glGenTextures(1, &tex);
+#if MSAA
+	glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex);
+	glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, num_samples,
+				GL_RGBA8,
+				32, 32, GL_TRUE);
+#else
+	glBindTexture(GL_TEXTURE_2D, tex);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 
+		     32, 32, 0,
+		     GL_RGBA, GL_FLOAT, NULL);
+#endif
+
+	glGenFramebuffers(1, &fbo);
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+	glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+#if MSAA
+			       GL_TEXTURE_2D_MULTISAMPLE,
+#else
+			       GL_TEXTURE_2D,
+#endif
+			       tex, 0);
+	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+	assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) ==
+	       GL_FRAMEBUFFER_COMPLETE);
+
+	/* create sample readback shader */
+	readback_prog = piglit_build_simple_program(vs_src_readback,
+						    fs_src_readback);
+	glUseProgram(readback_prog);
+	tex_uniform = glGetUniformLocation(readback_prog, "tex");
+	glUniform1i(tex_uniform, 0); /* unit 0 */
+	sample_pos_uniform = glGetUniformLocation(readback_prog, "samplePos");
+	readback_pos_attr = glGetAttribLocation(readback_prog, "pos");
+	readback_texcoord_attr = glGetAttribLocation(readback_prog, "coord_vs");
+
+	/* create triangle drawing shader */
+	draw_prog = piglit_build_simple_program(vs_src_draw, fs_src_draw);
+	glUseProgram(draw_prog);
+	draw_pos_attr = glGetAttribLocation(draw_prog, "pos");
+
+	if (!piglit_check_gl_error(GL_NO_ERROR))
+		piglit_report_result(PIGLIT_FAIL);
+
+	glEnable(GL_MULTISAMPLE);
+}
-- 
1.7.10.4



More information about the Piglit mailing list