[Piglit] [PATCH] fbo: add test for multiple draw buffer combinations including GL_NONE

Christoph Bumiller christoph.bumiller at speed.at
Sat Apr 20 05:54:38 PDT 2013


From: Christoph Bumiller <e0425955 at student.tuwien.ac.at>

Passes on NV blob (except segfault on doing glBlitFramebuffer when
glReadBuffer is GL_NONE), and fails horribly with st/mesa for obvious
reasons.
---
 tests/all.tests              |    1 +
 tests/fbo/CMakeLists.gl.txt  |    1 +
 tests/fbo/fbo-draw-buffers.c |  252 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 254 insertions(+), 0 deletions(-)
 create mode 100644 tests/fbo/fbo-draw-buffers.c

diff --git a/tests/all.tests b/tests/all.tests
index 495de59..f8dea51 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1049,6 +1049,7 @@ for format in ('rgba', 'depth', 'stencil'):
 add_plain_test(arb_framebuffer_object, 'fbo-alpha')
 add_plain_test(arb_framebuffer_object, 'fbo-blit-stretch')
 add_plain_test(arb_framebuffer_object, 'fbo-deriv')
+add_plain_test(arb_framebuffer_object, 'fbo-draw-buffers')
 add_plain_test(arb_framebuffer_object, 'fbo-luminance-alpha')
 add_plain_test(arb_framebuffer_object, 'fbo-getframebufferattachmentparameter-01')
 add_plain_test(arb_framebuffer_object, 'fbo-gl_pointcoord')
diff --git a/tests/fbo/CMakeLists.gl.txt b/tests/fbo/CMakeLists.gl.txt
index cf2a268..0723662 100644
--- a/tests/fbo/CMakeLists.gl.txt
+++ b/tests/fbo/CMakeLists.gl.txt
@@ -93,5 +93,6 @@ piglit_add_executable (fbo-copyteximage-simple fbo-copyteximage-simple.c)
 piglit_add_executable (fbo-cubemap fbo-cubemap.c)
 piglit_add_executable (fbo-scissor-bitmap fbo-scissor-bitmap.c)
 piglit_add_executable (fbo-viewport fbo-viewport.c)
+piglit_add_executable (fbo-draw-buffers fbo-draw-buffers.c)
 
 # vim: ft=cmake:
diff --git a/tests/fbo/fbo-draw-buffers.c b/tests/fbo/fbo-draw-buffers.c
new file mode 100644
index 0000000..0c0e43a
--- /dev/null
+++ b/tests/fbo/fbo-draw-buffers.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright © 2013 The Piglit Project
+ *
+ * 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.
+ *
+ * Authors:
+ *    Christoph Bumiller
+ *
+ */
+
+/** @file fbo-draw-buffers
+ *
+ * Tests that various assignments of color attachments to draw buffer slots,
+ * and hence color outputs, notably including gaps (GL_NONE), works correctly.
+ */
+
+#include "piglit-util-gl-common.h"
+
+#define RB_WIDTH 128
+
+#define NUM_CBUFS_MAX 16
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+
+	config.window_width = RB_WIDTH;
+	config.window_height = RB_WIDTH;
+	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const GLfloat colors[NUM_CBUFS_MAX][4] = {
+	{ 0.0f, 0.0f, 0.0f, 0.0f },
+	{ 0.0f, 0.0f, 1.0f, 0.0f },
+	{ 0.0f, 1.0f, 0.0f, 0.0f },
+	{ 0.0f, 1.0f, 1.0f, 0.0f },
+	{ 1.0f, 0.0f, 0.0f, 0.0f },
+	{ 1.0f, 0.0f, 1.0f, 0.0f },
+	{ 1.0f, 1.0f, 0.0f, 0.0f },
+	{ 1.0f, 1.0f, 1.0f, 0.0f },
+	{ 0.0f, 0.0f, 0.0f, 1.0f },
+	{ 0.0f, 0.0f, 1.0f, 1.0f },
+	{ 0.0f, 1.0f, 0.0f, 1.0f },
+	{ 0.0f, 1.0f, 1.0f, 1.0f },
+	{ 1.0f, 0.0f, 0.0f, 1.0f },
+	{ 1.0f, 0.0f, 1.0f, 1.0f },
+	{ 1.0f, 1.0f, 0.0f, 1.0f },
+	{ 1.0f, 1.0f, 1.0f, 1.0f }
+};
+static const GLfloat grey1[4] = { 0.3f, 0.3f, 0.3f, 0.3f };
+static const GLfloat grey2[4] = { 0.7f, 0.7f, 0.7f, 0.7f };
+
+static GLint num_cbufs;
+static GLuint fbo;
+static GLuint rbo[NUM_CBUFS_MAX];
+static GLenum att[NUM_CBUFS_MAX];
+static GLuint prog;
+
+static void
+make_fbo()
+{
+	GLenum status;
+	int i;
+
+	glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &num_cbufs);
+	if (num_cbufs > NUM_CBUFS_MAX)
+		num_cbufs = NUM_CBUFS_MAX;
+
+	glGenFramebuffers(1, &fbo);
+	glGenRenderbuffers(num_cbufs, rbo);
+
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+	for (i = 0; i < num_cbufs; ++i) {
+		glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
+		glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8,
+				      RB_WIDTH, 1);
+
+		glFramebufferRenderbuffer(GL_FRAMEBUFFER,
+					  GL_COLOR_ATTACHMENT0 + i,
+					  GL_RENDERBUFFER, rbo[i]);
+	}
+
+	status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+	if (status != GL_FRAMEBUFFER_COMPLETE) {
+		fprintf(stderr, "fbo incomplete (status = 0x%04x)\n", status);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+}
+
+static void
+fbo_set_mask(unsigned int config)
+{
+	unsigned int mask = config & 0xff;
+	int i, c;
+
+	glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+
+	for (i = 0, c = 0; i < num_cbufs; ++i, c += (mask & 1), mask >>= 1) {
+		if (mask & 1)
+			att[i] = GL_COLOR_ATTACHMENT0 + c;
+		else
+			att[i] = GL_NONE;
+	}
+	glDrawBuffers(num_cbufs, att);
+
+	glViewport(0, 0, RB_WIDTH, 1);
+
+	glClearColor(grey2[0], grey2[1], grey2[2], grey2[3]);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	if (!piglit_check_gl_error(GL_NO_ERROR))
+		piglit_report_result(PIGLIT_FAIL);
+}
+
+
+static void draw_quad()
+{
+	const GLfloat quad[4][2] = {
+		{ -1.0f, -1.0f },
+		{ -1.0f, +1.0f },
+		{ +1.0f, +1.0f },
+		{ +1.0f, -1.0f }
+	};
+	glEnableClientState(GL_VERTEX_ARRAY);
+	glVertexPointer(2, GL_FLOAT, 0, quad);
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+	glDisableClientState(GL_VERTEX_ARRAY);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	const GLint h = RB_WIDTH / num_cbufs;
+
+	GLboolean pass = GL_TRUE;
+	int i;
+	unsigned int m;
+
+	for (m = 0x00; m <= 0xff && pass; ++m) {
+		fbo_set_mask(m);
+
+		draw_quad();
+
+		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+		glDrawBuffer(GL_BACK);
+
+		glClearColor(grey1[0], grey1[1], grey1[2], grey1[3]);
+		glClear(GL_COLOR_BUFFER_BIT);
+
+		for (i = 0; i < num_cbufs; ++i) {
+			GLint y = i * h;
+
+			glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
+			glReadBuffer(att[i]);
+			glBlitFramebuffer(0, 0, RB_WIDTH, 1,
+					  0, y, RB_WIDTH, y + h,
+					  GL_COLOR_BUFFER_BIT, GL_NEAREST);
+		}
+
+		glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+		glReadBuffer(GL_BACK);
+		for (i = 0; i < num_cbufs && pass; ++i)
+			pass = piglit_probe_pixel_rgba(RB_WIDTH / 2,
+						       i * h,
+						       att[i] == GL_NONE ?
+						       grey1 : colors[i]);
+		if (!pass) {
+			fprintf(stderr, "Failure with:\n");
+			for (i = 0; i < num_cbufs; ++i)
+				if (att[i] == GL_NONE)
+					fprintf(stderr, "GL_NONE\n");
+				else
+					fprintf(stderr,
+						"GL_COLOR_ATTACHMENT%i\n",
+						att[i] - GL_COLOR_ATTACHMENT0);
+		}
+	}
+
+	piglit_present_results();
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+
+static const char *vsSource = "#version 110 \n"
+        "void main() { \n"
+        "   gl_Position = gl_Vertex; \n"
+        "} \n";
+
+static const char fsSourceHead[] = "#version 110 \n"
+	"void main() { \n";
+static const char fsSourceTail[] =
+	"} \n";
+static const char fsSourceLine[] =
+	"   gl_FragData[%i] = vec4(%1.1f, %1.1f, %1.1f, %1.1f); \n";
+
+void
+piglit_init(int argc, char **argv)
+{
+	char *fsSource;
+	GLuint vs, fs;
+	int i;
+	int pos, len;
+
+	piglit_require_extension("GL_ARB_framebuffer_object");
+	piglit_require_extension("GL_EXT_framebuffer_blit");
+	piglit_require_GLSL_version(110);
+
+	make_fbo();
+
+	len = sizeof(fsSourceHead) +
+	      sizeof(fsSourceTail) +
+	      sizeof(fsSourceLine) * num_cbufs;
+
+	fsSource = malloc(len);
+
+	pos = snprintf(&fsSource[0], len, fsSourceHead);
+	for (i = 0; i < num_cbufs && pos < len; ++i)
+		pos += snprintf(&fsSource[pos], len - pos, fsSourceLine,
+				i,
+				colors[i][0], colors[i][1], colors[i][2],
+				colors[i][3]);
+	if (pos < len)
+		pos += snprintf(&fsSource[pos], len - pos, fsSourceTail);
+
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fsSource);
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vsSource);
+	prog = piglit_link_simple_program(vs, fs);
+
+	free(fsSource);
+
+	glUseProgram(prog);
+}
-- 
1.7.3.4



More information about the Piglit mailing list