[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