[Piglit] [PATCH] Add test to verify glBlitFramebuffer with non matching parameters in multisample FBOs

Anuj Phogat anuj.phogat at gmail.com
Fri May 11 18:36:58 PDT 2012


This test verifies if glBlitFramebuffer() throws expected GL errors with
multisample framebuffers.

V2: Test is rewritten to utilize the functionality defined in common.cpp
    and to match the testing pattern of other blitting tests written by
    Paul Berry. Command line options are provided to choose sample count
    and color/depth/stencil buffers for testing.

With src, dst fbo depth_stencil formats: GL_DEPTH32F_STENCIL8 and
GL_DEPTH_STENCIL, test_blit_ms_ms_non_matching_formats fails with
stencil buffer on mesa master. But it passes for depth buffer.

test_blit_ms_ms_non_matching_formats fails for depth and stencil on AMD
catalyst.

Mesa's behavior for depth buffer looks correct to me as both formats are
 different. I'm not sure about stencil buffer.

Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
Note: This patch require:
[Patch]: ext_framebuffer_multisample: Add color, depth and stencil format
variables in Fbo class

 tests/all.tests                                    |    7 +
 .../ext_framebuffer_multisample/CMakeLists.gl.txt  |    1 +
 .../non-matching-blit.cpp                          |  290 ++++++++++++++++++++
 3 files changed, 298 insertions(+), 0 deletions(-)
 create mode 100644 tests/spec/ext_framebuffer_multisample/non-matching-blit.cpp

diff --git a/tests/all.tests b/tests/all.tests
index da50ee0..fbaf981 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1318,6 +1318,13 @@ for num_samples in (2, 4, 8, 16, 32):
                         test_name)
                 ext_framebuffer_multisample[test_name] = PlainExecTest(executable)
 
+for num_samples in (2, 4, 8, 16, 32):
+        for buffer_type in ('color', 'depth', 'stencil'):
+                test_name = ' ' .join(['non-matching-blit', str(num_samples), buffer_type])
+                executable = 'ext_framebuffer_multisample-{0} -auto'.format(
+                        test_name)
+                ext_framebuffer_multisample[test_name] = PlainExecTest(executable)
+
 ext_framebuffer_object = Group()
 spec['EXT_framebuffer_object'] = ext_framebuffer_object
 add_fbo_stencil_tests(ext_framebuffer_object, 'GL_STENCIL_INDEX1')
diff --git a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
index 475237c..a72a381 100644
--- a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
+++ b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
@@ -15,6 +15,7 @@ piglit_add_executable (ext_framebuffer_multisample-accuracy common.cpp accuracy.
 piglit_add_executable (ext_framebuffer_multisample-dlist dlist.c)
 piglit_add_executable (ext_framebuffer_multisample-minmax minmax.c)
 piglit_add_executable (ext_framebuffer_multisample-multisample-blit common.cpp multisample-blit.cpp)
+piglit_add_executable (ext_framebuffer_multisample-multisample-non-matching-blit common.cpp non-matching-blit.cpp)
 piglit_add_executable (ext_framebuffer_multisample-negative-copypixels negative-copypixels.c)
 piglit_add_executable (ext_framebuffer_multisample-negative-copyteximage negative-copyteximage.c)
 piglit_add_executable (ext_framebuffer_multisample-negative-max-samples negative-max-samples.c)
diff --git a/tests/spec/ext_framebuffer_multisample/non-matching-blit.cpp b/tests/spec/ext_framebuffer_multisample/non-matching-blit.cpp
new file mode 100644
index 0000000..51d0087
--- /dev/null
+++ b/tests/spec/ext_framebuffer_multisample/non-matching-blit.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright © 2012 Intel Corporation
+ *
+ * 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 non-matching-blit.cpp
+ *
+ * This test verifies if glBlitFramebuffer() throws expected GL errors with
+ * multisample framebuffers.
+ *
+ * We generate FBOs with specified sample count, draw a pattern in to them,
+ * do blitting operation and then probe color buffer to verify against
+ * expected values.
+ *
+ * Tests following cases:
+ * - Blit multisample-to-multisample with non-matching sample count
+ * - Blit multisample-to-multisample with non-matching format
+ * - Blit multisample-to-multisample non-matching buffer size
+ *
+ * Left half of default framebuffer draws test image.
+ * Right half of default framebuffer draws reference image.
+ */
+
+#include "common.h"
+
+int piglit_width = 512; int piglit_height = 256;
+int piglit_window_mode =
+	GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH | GLUT_STENCIL;
+
+const int pattern_width = 256; const int pattern_height = 256;
+int num_samples;
+
+Fbo src_fbo;
+Fbo dst_fbo;
+TestPattern *test_pattern = NULL;
+ManifestProgram *manifest_program = NULL;
+GLbitfield buffer_to_test;
+
+static GLenum color_formats[] = {
+	GL_RED,
+	GL_RG,
+	GL_RGB,
+	GL_ALPHA,
+	};
+
+static bool
+test_blit_ms_ms(GLfloat scale)
+{
+	bool pass = true;
+
+	/* Clear default buffer */
+	glClear(buffer_to_test);
+
+	/* Draw the test pattern in dst_fbo. */
+	float proj[4][4] = {
+		{ 1, 0, 0, 0 },
+		{ 0, 1, 0, 0 },
+		{ 0, 0, 1, 0 },
+		{ 0, 0, 0, 1 }
+	};
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo.handle);
+	dst_fbo.set_viewport();
+	test_pattern->draw(proj);
+
+	/* If required manifest the image in dst_fbo and then blit
+	 * it to default framebuffer. This is the reference image.
+	 */
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo.handle);
+	dst_fbo.set_viewport();
+	if (manifest_program)
+		manifest_program->run();
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, dst_fbo.handle);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+	glBlitFramebuffer(0, 0, pattern_width, pattern_height,
+			  pattern_width, 0, 2*pattern_width, pattern_height,
+			  GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+	/* Clear the src_fbo to a default color/depth/stencil value */
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, src_fbo.handle);
+	src_fbo.set_viewport();
+	glClear(buffer_to_test);
+
+	/* Blit from src_fbo to dst_fbo. scale variable is used to change
+	 * the buffer size used for blitting.
+	 */
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, src_fbo.handle);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo.handle);
+	glBlitFramebuffer(0, 0, pattern_width * scale, pattern_height * scale,
+			  0, 0, pattern_width, pattern_height,
+			  buffer_to_test, GL_NEAREST);
+
+	pass = piglit_check_gl_error(GL_INVALID_OPERATION) && pass;
+
+	/* Manifest dst_fbo again in to a color image and blit from dst_fbo
+	 * to the left half of the window system framebuffer.  This is the
+	 * test image.
+	 */
+
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst_fbo.handle);
+	dst_fbo.set_viewport();
+	if (manifest_program)
+		manifest_program->run();
+
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, dst_fbo.handle);
+	glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+	glBlitFramebuffer(0, 0, pattern_width, pattern_height,
+			  0, 0, pattern_width, pattern_height,
+			  GL_COLOR_BUFFER_BIT, GL_NEAREST);
+
+	/* Check that the left and right halves of the screen match.
+	 * If they don't, that means blitting operation modified
+	 * dst_fbo.
+	 */
+	glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+	pass = piglit_probe_rect_halves_equal_rgba(0, 0, piglit_width,
+						   piglit_height) && pass;
+
+	return pass;
+}
+
+
+static bool
+test_blit_ms_ms_non_matching_samples(void)
+{
+	src_fbo.set_samples(num_samples);
+	dst_fbo.set_samples(num_samples / 2);
+	return test_blit_ms_ms(1.0);
+
+}
+
+static bool
+test_blit_ms_ms_non_matching_buffer_size(void)
+{
+	return test_blit_ms_ms(0.5);
+}
+
+static bool
+test_blit_ms_ms_non_matching_formats(void)
+{
+	GLuint i, array_size;
+	bool pass = true;
+
+	switch(buffer_to_test) {
+	case GL_COLOR_BUFFER_BIT:
+		array_size = ARRAY_SIZE(color_formats);
+		break;
+	case GL_DEPTH_BUFFER_BIT:
+	case GL_STENCIL_BUFFER_BIT:
+		array_size = 1;
+		break;
+	}
+
+	for(i = 0; i < array_size; i++) {
+
+		switch(buffer_to_test) {
+		case GL_COLOR_BUFFER_BIT:
+			src_fbo.color_format = color_formats[i];
+			break;
+		case GL_DEPTH_BUFFER_BIT:
+		case GL_STENCIL_BUFFER_BIT:
+			src_fbo.depth_stencil_format = GL_DEPTH32F_STENCIL8;
+			break;
+		}
+
+		src_fbo.set_samples(num_samples);
+		pass = test_blit_ms_ms(1.0) && pass;
+	}
+	return pass;
+}
+
+void
+initialize_fbo(void)
+{
+	src_fbo.init(num_samples, pattern_width, pattern_height,
+		     true /* combine_depth_stencil */,
+		     false /* attach_texture */);
+	dst_fbo.init(num_samples, pattern_width, pattern_height,
+		     true /* combine_depth_stencil */,
+		     false /* attach_texture */);
+}
+
+enum piglit_result
+piglit_display()
+{
+	bool pass = true, pass0 = true, pass1 = true, pass2 = true;
+
+	initialize_fbo();
+	/* Blit multisample-to-multisample with non-matching sample count */
+	pass0 = test_blit_ms_ms_non_matching_samples()
+	       && pass0;
+	if(!pass0 && !piglit_automatic)
+		printf("test_blit_ms_ms_non_matching_samples failed\n");
+
+	initialize_fbo();
+	/* Blit multisample-to-multisample with non-matching buffer size */
+	pass1 = test_blit_ms_ms_non_matching_buffer_size()
+	       && pass1;
+	if(!pass1 && !piglit_automatic)
+		printf("test_blit_ms_ms_non_matching_buffer_size failed\n");
+
+	if (buffer_to_test == GL_COLOR_BUFFER_BIT ||
+	    ((buffer_to_test == GL_DEPTH_BUFFER_BIT ||
+	      buffer_to_test == GL_STENCIL_BUFFER_BIT) &&
+	      piglit_is_extension_supported("ARB_depth_buffer_float"))) {
+
+		initialize_fbo();
+		/* Blit multisample-to-multisample with non-matching format */
+		pass2 = test_blit_ms_ms_non_matching_formats()
+		       && pass2;
+		if(!pass2 && !piglit_automatic)
+			printf("test_blit_ms_ms_non_matching_formats failed\n");
+	}
+
+	if (!piglit_automatic)
+		piglit_present_results();
+
+	pass = pass0 && pass1 && pass2;
+	return (pass ? PIGLIT_PASS : PIGLIT_FAIL);
+}
+
+void
+print_usage_and_exit(char *prog_name)
+{
+	printf("Usage: %s <num_samples> <buffer_type>\n"
+	       "  where <buffer_type> is one of:\n"
+	       "    color\n"
+	       "    stencil\n"
+	       "    depth\n",
+	       prog_name);
+	piglit_report_result(PIGLIT_FAIL);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	if (argc < 3)
+		print_usage_and_exit(argv[0]);
+	{
+		char *endptr = NULL;
+		num_samples = strtol(argv[1], &endptr, 0);
+		if (endptr != argv[1] + strlen(argv[1]))
+			print_usage_and_exit(argv[0]);
+	}
+
+	piglit_require_gl_version(30);
+	piglit_require_GLSL_version(130);
+
+	/* Skip the test if num_samples > GL_MAX_SAMPLES */
+	GLint max_samples;
+	glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
+	if (num_samples > max_samples)
+		piglit_report_result(PIGLIT_SKIP);
+
+	if (strcmp(argv[2], "color") == 0) {
+		test_pattern = new Triangles();
+		buffer_to_test = GL_COLOR_BUFFER_BIT;
+	} else if (strcmp(argv[2], "depth") == 0) {
+		test_pattern = new DepthSunburst();
+		manifest_program = new ManifestDepth();
+		buffer_to_test = GL_DEPTH_BUFFER_BIT;
+	} else if (strcmp(argv[2], "stencil") == 0) {
+		test_pattern = new StencilSunburst();
+		manifest_program = new ManifestStencil();
+		buffer_to_test = GL_STENCIL_BUFFER_BIT;
+	} else {
+		print_usage_and_exit(argv[0]);
+	}
+	test_pattern->compile();
+	if (manifest_program)
+		manifest_program->compile();
+}
-- 
1.7.7.6



More information about the Piglit mailing list