[Piglit] =?y?q?=5BPATCH=5D=20Add=20test=20to=20verify=20glBlitFramebuffer=20with=20non=20matching=20parameters=20in=20multisample=20FBOs?=

anuj.phogat at gmail.com anuj.phogat at gmail.com
Fri Jun 1 18:16:31 PDT 2012


From: Anuj Phogat <anuj.phogat at gmail.com>

This test verifies if glBlitFramebuffer() throws expected GL errors with
multisample framebuffers and no blitting occurs in case of error.

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.

V3: Made few changes to avoid manifesting same depth/stencil buffer twice.
    This was causing the test to fail.

Signed-off-by: Anuj Phogat <anuj.phogat at gmail.com>
---
This patch requires following patch sent on 05/11/2012:
"[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                          |  316 ++++++++++++++++++++
 3 files changed, 324 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 93716a8..0ca0fe4 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1356,6 +1356,13 @@ for num_samples in (2, 4, 8, 16, 32):
                         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)
+
+for num_samples in (2, 4, 8, 16, 32):
 	test_name = ' ' .join(['line-smooth', str(num_samples)])
 	executable = 'ext_framebuffer_multisample-{0} -auto'.format(
 	        test_name)
diff --git a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
index 155190f..aea8bd7 100644
--- a/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
+++ b/tests/spec/ext_framebuffer_multisample/CMakeLists.gl.txt
@@ -19,6 +19,7 @@ piglit_add_executable (ext_framebuffer_multisample-negative-copyteximage negativ
 piglit_add_executable (ext_framebuffer_multisample-negative-max-samples negative-max-samples.c)
 piglit_add_executable (ext_framebuffer_multisample-negative-mismatched-samples negative-mismatched-samples.c)
 piglit_add_executable (ext_framebuffer_multisample-negative-readpixels negative-readpixels.c)
+piglit_add_executable (ext_framebuffer_multisample-non-matching-blit common.cpp non-matching-blit.cpp)
 piglit_add_executable (ext_framebuffer_multisample-point-smooth common.cpp point-smooth.cpp)
 piglit_add_executable (ext_framebuffer_multisample-polygon-smooth common.cpp polygon-smooth.cpp)
 piglit_add_executable (ext_framebuffer_multisample-renderbuffer-samples renderbuffer-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..528329d
--- /dev/null
+++ b/tests/spec/ext_framebuffer_multisample/non-matching-blit.cpp
@@ -0,0 +1,316 @@
+/*
+ * 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 test pattern in to
+ * them, do blitting operation and then compare test image with the reference
+ * image.
+ *
+ * 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
+ *
+ * No blitting should happen in all the above cases and the driver should
+ * report GL_INVALID_OPERATION.
+ *
+ * Left half of default framebuffer draws test image.
+ * Right half of default framebuffer draws reference image.
+ *
+ * Author: Anuj Phogat <anuj.phogat at gmail.com>
+ */
+
+#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, dst_fbo, resolve_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 GLenum depth_stencil_formats[] = {
+	GL_DEPTH32F_STENCIL8};
+
+void blit_fbo_to_fbo(Fbo *src, struct Fbo *dst, float scale)
+{
+	glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src->handle);
+	glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst->handle);
+
+	glBlitFramebufferEXT(0, 0, src->width * scale, src->height * scale,
+			     0, 0, dst->width, dst->height,
+			     buffer_to_test, GL_NEAREST);
+}
+
+void blit_fbo_to_default(Fbo *src, int x_offset, int y_offset)
+{
+	glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src->handle);
+	glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+
+	/* In case of multisample FBO, glBlitFramebufferEXT invokes the
+	 * multisample to single sample resolution for each pixel */
+	glBlitFramebufferEXT(0, 0, src->width, src->height,
+			     x_offset, y_offset,
+			     pattern_width + x_offset,
+			     pattern_height + y_offset,
+			     GL_COLOR_BUFFER_BIT, GL_NEAREST);
+}
+
+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 manifest is required, blit dst_fbo first in to resolve_fbo and
+	 * then manifest the image in resolve_fbo, followed by blitting to
+	 * default framebuffer. This is used as a reference image. Here
+	 * resolve_fbo is required to avoid manifest same depth/stencil
+	 * buffer (in dst_fbo) twice in this test.
+	 */
+	if (manifest_program) {
+		blit_fbo_to_fbo(&dst_fbo, &resolve_fbo, 1.0);
+
+		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo.handle);
+		resolve_fbo.set_viewport();
+		manifest_program->run();
+
+		blit_fbo_to_default(&resolve_fbo, pattern_width, 0);
+	}
+	else
+		blit_fbo_to_default(&dst_fbo, pattern_width, 0);
+
+	/* 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.
+	 */
+	blit_fbo_to_fbo(&src_fbo, &dst_fbo, scale);
+
+	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();
+
+	blit_fbo_to_default(&dst_fbo, 0, 0);
+
+	/* 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 / 2);
+	dst_fbo.set_samples(num_samples);
+	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:
+		array_size = ARRAY_SIZE(depth_stencil_formats);
+		break;
+	}
+
+	for(i = 0; i < array_size; i++) {
+
+		switch(buffer_to_test) {
+		case GL_COLOR_BUFFER_BIT:
+			if ((color_formats[i] == GL_RED ||
+			     color_formats[i] == GL_RG) &&
+			    piglit_is_extension_supported("ARB_texture_rg"))
+				src_fbo.color_format = color_formats[i];
+			else
+				continue;
+			break;
+		case GL_DEPTH_BUFFER_BIT:
+			src_fbo.depth_stencil_format = depth_stencil_formats[i];
+			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 */);
+	resolve_fbo.init(0, pattern_width, pattern_height,
+		      true /* combine_depth_stencil */,
+		      false /* attach_texture */);
+}
+
+enum piglit_result
+piglit_display()
+{
+	bool pass = true, nm_samples = true, nm_size = true, nm_formats = true;
+
+	initialize_fbo();
+	/* Blit multisample-to-multisample with non-matching sample count */
+	nm_samples = test_blit_ms_ms_non_matching_samples();
+	if(!nm_samples && !piglit_automatic)
+		printf("test_blit_ms_ms_non_matching_samples failed\n");
+
+	initialize_fbo();
+	/* Blit multisample-to-multisample with non-matching buffer size */
+	nm_size = test_blit_ms_ms_non_matching_buffer_size();
+	if(!nm_size && !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 &&
+	      piglit_is_extension_supported("ARB_depth_buffer_float"))) {
+
+		initialize_fbo();
+		/* Blit multisample-to-multisample with non-matching format */
+		nm_formats = test_blit_ms_ms_non_matching_formats();
+		if(!nm_formats && !piglit_automatic)
+			printf("test_blit_ms_ms_non_matching_formats failed\n");
+	}
+
+	if (!piglit_automatic)
+		piglit_present_results();
+
+	pass = nm_samples && nm_size && nm_formats;
+	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);
+
+	/* 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