[Piglit] [PATCH 2/2] GL_ARB_texture_buffer_object/formats: Add a test for all the format options.

Eric Anholt eric at anholt.net
Wed Mar 28 10:50:51 PDT 2012


---
 tests/all.tests                                    |    4 +
 .../arb_texture_buffer_object/CMakeLists.gl.txt    |    1 +
 tests/spec/arb_texture_buffer_object/formats.c     |  689 ++++++++++++++++++++
 3 files changed, 694 insertions(+), 0 deletions(-)
 create mode 100644 tests/spec/arb_texture_buffer_object/formats.c

diff --git a/tests/all.tests b/tests/all.tests
index 1a91726..7122030 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -1136,6 +1136,10 @@ add_plain_test(arb_explicit_attrib_location, 'glsl-explicit-location-05')
 arb_texture_buffer_object = Group()
 spec['ARB_texture_buffer_object'] = arb_texture_buffer_object
 arb_texture_buffer_object['dlist'] = concurrent_test('arb_texture_buffer_object-dlist')
+arb_texture_buffer_object['formats (FS, 3.1 core)'] = concurrent_test('arb_texture_buffer_object-formats fs core')
+arb_texture_buffer_object['formats (VS, 3.1 core)'] = concurrent_test('arb_texture_buffer_object-formats vs core')
+arb_texture_buffer_object['formats (FS, ARB)'] = concurrent_test('arb_texture_buffer_object-formats fs arb')
+arb_texture_buffer_object['formats (VS, ARB)'] = concurrent_test('arb_texture_buffer_object-formats vs arb')
 arb_texture_buffer_object['get'] = concurrent_test('arb_texture_buffer_object-get')
 arb_texture_buffer_object['minmax'] = concurrent_test('arb_texture_buffer_object-minmax')
 arb_texture_buffer_object['negative-bad-bo'] = concurrent_test('arb_texture_buffer_object-negative-bad-bo')
diff --git a/tests/spec/arb_texture_buffer_object/CMakeLists.gl.txt b/tests/spec/arb_texture_buffer_object/CMakeLists.gl.txt
index 572ae2d..fd71ff7 100644
--- a/tests/spec/arb_texture_buffer_object/CMakeLists.gl.txt
+++ b/tests/spec/arb_texture_buffer_object/CMakeLists.gl.txt
@@ -13,6 +13,7 @@ link_libraries (
 )
 
 piglit_add_executable (arb_texture_buffer_object-dlist dlist.c)
+piglit_add_executable (arb_texture_buffer_object-formats formats.c)
 piglit_add_executable (arb_texture_buffer_object-get get.c)
 piglit_add_executable (arb_texture_buffer_object-minmax minmax.c)
 piglit_add_executable (arb_texture_buffer_object-negative-bad-bo negative-bad-bo.c)
diff --git a/tests/spec/arb_texture_buffer_object/formats.c b/tests/spec/arb_texture_buffer_object/formats.c
new file mode 100644
index 0000000..8835cb6
--- /dev/null
+++ b/tests/spec/arb_texture_buffer_object/formats.c
@@ -0,0 +1,689 @@
+/* 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 minmax.c
+ *
+ * Test for the minimum maximum value in the GL_ARB_texture_buffer_object spec.
+ */
+
+#define _GNU_SOURCE
+#include "piglit-util.h"
+
+int piglit_width = 200;
+int piglit_height = 500;
+int piglit_window_mode = GLUT_DOUBLE | GLUT_RGB | GLUT_ALPHA;
+
+enum channels {
+	A,
+	L,
+	LA,
+	I,
+	R,
+	RG,
+	RGBA,
+};
+
+static const struct format {
+	GLenum format;
+	GLenum type;
+	int components;
+	bool norm;
+	enum channels channels;
+} formats[] = {
+	{ GL_ALPHA8,                     GL_UNSIGNED_BYTE,  1,        true,     A },
+	{ GL_ALPHA16,                    GL_UNSIGNED_SHORT, 1,        true,     A },
+	{ GL_ALPHA16F_ARB,               GL_HALF_FLOAT,     1,        false,    A },
+	{ GL_ALPHA32F_ARB,               GL_FLOAT,          1,        false,    A },
+	{ GL_ALPHA8I_EXT,                GL_BYTE,           1,        false,    A },
+	{ GL_ALPHA16I_EXT,               GL_SHORT,          1,        false,    A },
+	{ GL_ALPHA32I_EXT,               GL_INT,            1,        false,    A },
+	{ GL_ALPHA8UI_EXT,               GL_UNSIGNED_BYTE,  1,        false,    A },
+	{ GL_ALPHA16UI_EXT,              GL_UNSIGNED_SHORT, 1,        false,    A },
+	{ GL_ALPHA32UI_EXT,              GL_UNSIGNED_INT,   1,        false,    A },
+
+	{ GL_LUMINANCE8,                 GL_UNSIGNED_BYTE,  1,        true,     L },
+	{ GL_LUMINANCE16,                GL_UNSIGNED_SHORT, 1,        true,     L },
+	{ GL_LUMINANCE16F_ARB,           GL_HALF_FLOAT,     1,        false,    L },
+	{ GL_LUMINANCE32F_ARB,           GL_FLOAT,          1,        false,    L },
+	{ GL_LUMINANCE8I_EXT,            GL_BYTE ,          1,        false,    L },
+	{ GL_LUMINANCE16I_EXT,           GL_SHORT,          1,        false,    L },
+	{ GL_LUMINANCE32I_EXT,           GL_INT  ,          1,        false,    L },
+	{ GL_LUMINANCE8UI_EXT,           GL_UNSIGNED_BYTE,  1,        false,    L },
+	{ GL_LUMINANCE16UI_EXT,          GL_UNSIGNED_SHORT, 1,        false,    L },
+	{ GL_LUMINANCE32UI_EXT,          GL_UNSIGNED_INT,   1,        false,    L },
+
+	{ GL_LUMINANCE8_ALPHA8,          GL_UNSIGNED_BYTE,  2,        true,     LA },
+	{ GL_LUMINANCE16_ALPHA16,        GL_UNSIGNED_SHORT, 2,        true,     LA },
+	{ GL_LUMINANCE_ALPHA16F_ARB,     GL_HALF_FLOAT,     2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA32F_ARB,     GL_FLOAT,          2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA8I_EXT,      GL_BYTE,           2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA16I_EXT,     GL_SHORT,          2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA32I_EXT,     GL_INT,            2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA8UI_EXT,     GL_UNSIGNED_BYTE,  2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA16UI_EXT,    GL_UNSIGNED_SHORT, 2,        false,    LA },
+	{ GL_LUMINANCE_ALPHA32UI_EXT,    GL_UNSIGNED_INT,   2,        false,    LA },
+
+	{ GL_INTENSITY8,                 GL_UNSIGNED_BYTE,  1,        true,     I },
+	{ GL_INTENSITY16,                GL_UNSIGNED_SHORT, 1,        true,     I },
+	{ GL_INTENSITY16F_ARB,           GL_HALF_FLOAT,     1,        false,    I },
+	{ GL_INTENSITY32F_ARB,           GL_FLOAT,          1,        false,    I },
+	{ GL_INTENSITY8I_EXT,            GL_BYTE,           1,        false,    I },
+	{ GL_INTENSITY16I_EXT,           GL_SHORT,          1,        false,    I },
+	{ GL_INTENSITY32I_EXT,           GL_INT,            1,        false,    I },
+	{ GL_INTENSITY8UI_EXT,           GL_UNSIGNED_BYTE,  1,        false,    I },
+	{ GL_INTENSITY16UI_EXT,          GL_UNSIGNED_SHORT, 1,        false,    I },
+	{ GL_INTENSITY32UI_EXT,          GL_UNSIGNED_INT,   1,        false,    I },
+
+	{ GL_RGBA8,                      GL_UNSIGNED_BYTE,  4,        true,     RGBA },
+	{ GL_RGBA16,                     GL_UNSIGNED_SHORT, 4,        true,     RGBA },
+	{ GL_RGBA16F,                    GL_HALF_FLOAT,     4,        false,    RGBA },
+	{ GL_RGBA32F,                    GL_FLOAT,          4,        false,    RGBA },
+	{ GL_RGBA8I_EXT,                 GL_BYTE,           4,        false,    RGBA },
+	{ GL_RGBA16I_EXT,                GL_SHORT,          4,        false,    RGBA },
+	{ GL_RGBA32I_EXT,                GL_INT,            4,        false,    RGBA },
+	{ GL_RGBA8UI_EXT,                GL_UNSIGNED_BYTE,  4,        false,    RGBA },
+	{ GL_RGBA16UI_EXT,               GL_UNSIGNED_SHORT, 4,        false,    RGBA },
+	{ GL_RGBA32UI_EXT,               GL_UNSIGNED_INT,   4,        false,    RGBA },
+
+	/* These don't appear in the GL_ARB_texture_buffer_object or
+	 * GL_ARB_texture_rg specs, but they do appear in the GL 3.1
+	 * specification's table for buffer texture formats.  We
+	 * assume that the intent was for RG to be included even in
+	 * ARB_tbo + ARB_texture_rg
+	 */
+	{ GL_R8,                         GL_UNSIGNED_BYTE,  1,        true,     R },
+	{ GL_R16,                        GL_UNSIGNED_SHORT, 1,        true,     R },
+	{ GL_R16F,                       GL_HALF_FLOAT,     1,        false,    R },
+	{ GL_R32F,                       GL_FLOAT,          1,        false,    R },
+	{ GL_R8I,                        GL_BYTE,           1,        false,    R },
+	{ GL_R16I,                       GL_SHORT,          1,        false,    R },
+	{ GL_R32I,                       GL_INT,            1,        false,    R },
+	{ GL_R8UI,                       GL_UNSIGNED_BYTE,  1,        false,    R },
+	{ GL_R16UI,                      GL_UNSIGNED_SHORT, 1,        false,    R },
+	{ GL_R32UI,                      GL_UNSIGNED_INT,   1,        false,    R },
+
+	{ GL_RG8,                        GL_UNSIGNED_BYTE,  2,        true,     RG },
+	{ GL_RG16,                       GL_UNSIGNED_SHORT, 2,        true,     RG },
+	{ GL_RG16F,                      GL_HALF_FLOAT,     2,        false,    RG },
+	{ GL_RG32F,                      GL_FLOAT,          2,        false,    RG },
+	{ GL_RG8I,                       GL_BYTE,           2,        false,    RG },
+	{ GL_RG16I,                      GL_SHORT,          2,        false,    RG },
+	{ GL_RG32I,                      GL_INT,            2,        false,    RG },
+	{ GL_RG8UI,                      GL_UNSIGNED_BYTE,  2,        false,    RG },
+	{ GL_RG16UI,                     GL_UNSIGNED_SHORT, 2,        false,    RG },
+	{ GL_RG32UI,                     GL_UNSIGNED_INT,   2,        false,    RG },
+};
+
+bool test_vs;
+bool test_arb;
+
+struct program {
+	GLuint prog;
+	int pos_location;
+	int expected_location;
+	int vertex_location;
+};
+
+struct program prog_f;
+struct program prog_i;
+struct program prog_u;
+
+static int y_index;
+
+static uint8_t uint8_data[] = {
+	0x00, 0x01, 0x02, 0x03,
+	0x10, 0x20, 0x30, 0x40,
+	0x60, 0x90, 0xa0, 0xff,
+};
+
+static uint16_t uint16_data[] = {
+	0x0000, 0x0001, 0x0002, 0x0003,
+	0x4000, 0x8000, 0xc000, 0xffff,
+};
+
+static uint32_t uint32_data[] = {
+	0x00000000, 0x00000001, 0x00000002, 0x00000003,
+	0x40000000, 0x80000000, 0xc0000000, 0xffffffff,
+};
+
+static float float_data[] = {
+	 0.0,  0.25, 0.5,  0.75,
+	 1.0,  2.0,  3.0,  4.0,
+	-1.0, -2.0, -3.0, -4.0,
+};
+
+static float
+transform_x(float x)
+{
+	return -1.0 + 2.0 * x / piglit_width;
+}
+
+static float
+transform_y(float y)
+{
+	return -1.0 + 2.0 * y / piglit_height;
+}
+
+static bool
+get_expected_f(const struct format *format, int sample, float *expected)
+{
+	float chans[4];
+	int i;
+
+	for (i = 0; i < format->components; i++) {
+		int comp = sample * format->components + i;
+
+		switch (format->type) {
+		case GL_FLOAT:
+			chans[i] = float_data[comp];
+			break;
+		case GL_HALF_FLOAT:
+			chans[i] = float_data[comp];
+			break;
+		case GL_UNSIGNED_BYTE:
+			chans[i] = uint8_data[comp] / 255.0;
+			break;
+		case GL_UNSIGNED_SHORT:
+			chans[i] = uint16_data[comp] / 65535.0;
+			break;
+		default:
+			printf("line %d, bad type: %s\n", __LINE__,
+			       piglit_get_gl_enum_name(format->type));
+			memset(expected, 0, 16);
+			return false;
+		}
+	}
+
+	switch (format->channels) {
+	case RGBA:
+		expected[0] = chans[0];
+		expected[1] = chans[1];
+		expected[2] = chans[2];
+		expected[3] = chans[3];
+		break;
+
+	case RG:
+		expected[0] = chans[0];
+		expected[1] = chans[1];
+		expected[2] = 0.0;
+		expected[3] = 1.0;
+		break;
+
+	case R:
+		expected[0] = chans[0];
+		expected[1] = 0.0;
+		expected[2] = 0.0;
+		expected[3] = 1.0;
+		break;
+
+	case A:
+		expected[0] = 0.0;
+		expected[1] = 0.0;
+		expected[2] = 0.0;
+		expected[3] = chans[0];
+		break;
+
+	case L:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = 1.0;
+		break;
+
+	case LA:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = chans[1];
+		break;
+
+	case I:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = chans[0];
+		break;
+	}
+
+	return true;
+}
+
+static bool
+get_expected_i(const struct format *format, int sample, uint32_t *expected)
+{
+	uint32_t chans[4];
+	int i;
+
+	for (i = 0; i < format->components; i++) {
+		int comp = sample * format->components + i;
+
+		switch (format->type) {
+		case GL_BYTE:
+			chans[i] = ((int8_t *)uint8_data)[comp];
+			break;
+		case GL_UNSIGNED_BYTE:
+			chans[i] = uint8_data[comp];
+			break;
+		case GL_SHORT:
+			chans[i] = ((int16_t *)uint16_data)[comp];
+			break;
+		case GL_UNSIGNED_SHORT:
+			chans[i] = uint16_data[comp];
+			break;
+		case GL_INT:
+		case GL_UNSIGNED_INT:
+			chans[i] = uint32_data[comp];
+			break;
+		default:
+			printf("line %d, bad type: %s\n", __LINE__,
+			       piglit_get_gl_enum_name(format->type));
+			memset(expected, 0, 16);
+			return false;
+		}
+	}
+
+	switch (format->channels) {
+	case RGBA:
+		expected[0] = chans[0];
+		expected[1] = chans[1];
+		expected[2] = chans[2];
+		expected[3] = chans[3];
+		break;
+
+	case RG:
+		expected[0] = chans[0];
+		expected[1] = chans[1];
+		expected[2] = 0.0;
+		expected[3] = 1.0;
+		break;
+
+	case R:
+		expected[0] = chans[0];
+		expected[1] = 0.0;
+		expected[2] = 0.0;
+		expected[3] = 1.0;
+		break;
+
+	case A:
+		expected[0] = 0.0;
+		expected[1] = 0.0;
+		expected[2] = 0.0;
+		expected[3] = chans[0];
+		break;
+
+	case L:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = 1.0;
+		break;
+
+	case LA:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = chans[1];
+		break;
+
+	case I:
+		expected[0] = chans[0];
+		expected[1] = chans[0];
+		expected[2] = chans[0];
+		expected[3] = chans[0];
+		break;
+	}
+
+	return true;
+}
+
+enum piglit_result
+test_format(int format_index)
+{
+	const struct format *format = &formats[format_index];
+	GLuint tex, bo;
+	bool is_rg = (format->channels == R ||
+		      format->channels == RG);
+	bool is_arb = (format->channels == I ||
+		       format->channels == L ||
+		       format->channels == LA ||
+		       format->channels == A);
+	bool pass = true;
+	int data_components, num_samples;
+	int i;
+	bool returns_float = (format->norm ||
+			      format->type == GL_FLOAT ||
+			      format->type == GL_HALF_FLOAT);
+	bool returns_int = (!format->norm &&
+			    (format->type == GL_BYTE ||
+			     format->type == GL_SHORT ||
+			     format->type == GL_INT));
+	bool returns_uint = (!format->norm &&
+			     (format->type == GL_UNSIGNED_BYTE ||
+			      format->type == GL_UNSIGNED_SHORT ||
+			      format->type == GL_UNSIGNED_INT));
+	struct program *prog;
+
+	if (returns_float)
+		prog = &prog_f;
+	else if (returns_int)
+		prog = &prog_i;
+	else
+		prog = &prog_u;
+
+	glUseProgram(prog->prog);
+
+	if (test_arb != is_arb)
+		return PIGLIT_SKIP;
+
+	/* These didn't exist in the extension before being promoted to
+	 * GL 3.1.
+	 */
+	if (is_rg && piglit_get_gl_version() < 31)
+		return PIGLIT_SKIP;
+
+	printf("Testing %s\n", piglit_get_gl_enum_name(format->format));
+
+	glGenBuffers(1, &bo);
+	glBindBuffer(GL_TEXTURE_BUFFER, bo);
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_BUFFER, tex);
+
+	glTexBuffer(GL_TEXTURE_BUFFER, format->format, bo);
+
+	switch (format->type) {
+	case GL_BYTE:
+	case GL_UNSIGNED_BYTE:
+		glBufferData(GL_TEXTURE_BUFFER, sizeof(uint8_data), uint8_data,
+			     GL_STATIC_READ);
+		data_components = ARRAY_SIZE(uint8_data);
+		break;
+
+	case GL_SHORT:
+	case GL_UNSIGNED_SHORT:
+		glBufferData(GL_TEXTURE_BUFFER, sizeof(uint16_data),
+			     uint16_data, GL_STATIC_READ);
+		data_components = ARRAY_SIZE(uint16_data);
+		break;
+
+	case GL_INT:
+	case GL_UNSIGNED_INT:
+		glBufferData(GL_TEXTURE_BUFFER, sizeof(uint32_data),
+			     uint32_data, GL_STATIC_READ);
+		data_components = ARRAY_SIZE(uint32_data);
+		break;
+
+	case GL_FLOAT:
+		glBufferData(GL_TEXTURE_BUFFER, sizeof(float_data), float_data,
+			     GL_STATIC_READ);
+		data_components = ARRAY_SIZE(float_data);
+		break;
+
+	case GL_HALF_FLOAT: {
+		unsigned short hf_data[ARRAY_SIZE(float_data)];
+		for (i = 0; i < ARRAY_SIZE(float_data); i++) {
+			hf_data[i] = piglit_half_from_float(float_data[i]);
+		}
+		glBufferData(GL_TEXTURE_BUFFER, sizeof(hf_data), hf_data,
+			     GL_STATIC_READ);
+		data_components = ARRAY_SIZE(float_data);
+
+		break;
+	}
+
+	default:
+		printf("line %d, bad type: %s\n", __LINE__,
+		       piglit_get_gl_enum_name(format->type));
+		return PIGLIT_SKIP;
+	}
+
+	num_samples = data_components / format->components;
+
+	for (i = 0; i < num_samples; i++) {
+		float x1 = 5 + i * 10;
+		float x2 = 10 + i * 10;
+		float y1 = piglit_height - (5 + y_index * 10);
+		float y2 = piglit_height - (10 + y_index * 10);
+		GLfloat verts[8] = {
+			transform_x(x1), transform_y(y1),
+			transform_x(x2), transform_y(y1),
+			transform_x(x2), transform_y(y2),
+			transform_x(x1), transform_y(y2),
+		};
+		float expected_f[4];
+		uint32_t expected_i[4];
+		const float green[4] = {0, 1, 0, 0};
+
+		if (returns_float) {
+			if (!get_expected_f(format, i, expected_f))
+				return PIGLIT_SKIP;
+			glUniform4fv(prog->expected_location, 1, expected_f);
+		} else {
+			if (!get_expected_i(format, i, expected_i))
+				return PIGLIT_SKIP;
+			if (returns_uint) {
+				glUniform4uiv(prog->expected_location, 1,
+					      expected_i);
+			} else {
+				glUniform4iv(prog->expected_location, 1,
+					     (int *)expected_i);
+			}
+		}
+
+		glUniform1i(prog->pos_location, i);
+
+		glVertexAttribPointer(prog->vertex_location, 2, GL_FLOAT,
+				      GL_FALSE, 0, &verts);
+		glEnableVertexAttribArray(prog->vertex_location);
+
+		glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+		if (pass &&
+		    !piglit_probe_rect_rgba(x1, y2,
+					    x2 - x1, y1 - y2, green)) {
+			if (returns_int) {
+				printf("     Texel: %d %d %d %d\n",
+				       expected_i[0], expected_i[1],
+				       expected_i[2], expected_i[3]);
+			} else if (returns_uint) {
+				printf("     Texel: %u %u %u %u\n",
+				       expected_i[0], expected_i[1],
+				       expected_i[2], expected_i[3]);
+			} else {
+				printf("     Texel: %f %f %f %f\n",
+				       expected_f[0], expected_f[1],
+				       expected_f[2], expected_f[3]);
+			}
+			pass = false;
+		}
+	}
+
+	glDeleteBuffers(1, &bo);
+	glDeleteTextures(1, &tex);
+
+	y_index++;
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	enum piglit_result result = PIGLIT_SKIP;
+	int i;
+
+	glClearColor(0.5, 0.5, 0.5, 0.5);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	y_index = 0;
+
+	for (i = 0; i < ARRAY_SIZE(formats); i++) {
+		piglit_merge_result(&result, test_format(i));
+	}
+
+	piglit_present_results();
+
+	return result;
+}
+
+static char *vs_vert_source =
+	"#version 140\n"
+	"in vec4 vertex;\n"
+	"out vec4 color;\n"
+	"uniform %ssamplerBuffer s;\n"
+	"uniform int pos;\n"
+	"uniform %svec4 expected;"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vertex;\n"
+	"\n"
+	"	%svec4 result = texelFetch(s, pos);\n"
+	"	%svec4 delta = result - expected;\n"
+	"	bvec4 fail = greaterThanEqual(abs(delta), %s);\n"
+	"	if (any(fail)) {\n"
+	"		color = 0.25 + 0.5 * vec4(fail);\n"
+	"	} else {\n"
+	"		color = vec4(0.0, 1.0, 0.0, 0.0);\n"
+	"	}\n"
+	"}\n";
+
+static char *fs_vert_source =
+	"#version 140\n"
+	"in vec4 color;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_FragColor = color;\n"
+	"}\n";
+
+
+static char *vs_frag_source =
+	"#version 140\n"
+	"in vec4 vertex;\n"
+	"void main()\n"
+	"{\n"
+	"	gl_Position = vertex;\n"
+	"}\n";
+
+static char *fs_frag_source =
+	"#version 140\n"
+	"uniform %ssamplerBuffer s;\n"
+	"uniform int pos;\n"
+	"uniform %svec4 expected;"
+	"void main()\n"
+	"{\n"
+	"	%svec4 result = texelFetch(s, pos);\n"
+	"	%svec4 delta = result - expected;\n"
+	"	bvec4 fail = greaterThanEqual(abs(delta), %s);\n"
+	"	if (any(fail)) {\n"
+	"		gl_FragColor = 0.25 + 0.5 * vec4(fail);\n"
+	"	} else {\n"
+	"		gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);\n"
+	"	}\n"
+	"}\n";
+
+static void
+create_program(struct program *program, const char *type)
+{
+	char *fs_source, *vs_source;
+	GLuint vs, fs, prog;
+	char *threshold;
+
+	if (strcmp(type, "") == 0)
+		threshold = "vec4(0.02)";
+	else
+		threshold = "ivec4(1)";
+
+	if (test_vs) {
+		asprintf(&vs_source, vs_vert_source, type, type, type, type,
+			 threshold);
+		fs_source = fs_vert_source;
+	} else {
+		vs_source = vs_frag_source;
+		asprintf(&fs_source, fs_frag_source, type, type, type, type,
+			 threshold);
+	}
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);
+	if (!vs) {
+		printf("VS source:\n%s\n", vs_source);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);
+	if (!fs) {
+		printf("FS source:\n%s\n", fs_source);
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	prog = piglit_link_simple_program(vs, fs);
+	if (!prog)
+		piglit_report_result(PIGLIT_FAIL);
+
+	program->prog = prog;
+        program->pos_location = piglit_GetUniformLocation(prog, "pos");
+        program->expected_location = piglit_GetUniformLocation(prog,
+							       "expected");
+	program->vertex_location = glGetAttribLocation(prog, "vertex");
+}
+
+static void
+init_programs()
+{
+	create_program(&prog_f, "");
+	create_program(&prog_i, "i");
+	create_program(&prog_u, "u");
+}
+
+static void
+usage(const char *name)
+{
+	printf("usage: %s <fs | vs> <core | arb>\n", name);
+	piglit_report_result(PIGLIT_FAIL);
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	piglit_require_GLSL_version(140);
+
+	if (argc != 3)
+		usage(argv[0]);
+
+	test_vs = strcmp(argv[1], "vs") == 0;
+	if (!test_vs && strcmp(argv[1], "fs") != 0)
+		usage(argv[0]);
+
+	test_arb = strcmp(argv[2], "arb") == 0;
+	if (!test_arb && strcmp(argv[2], "core") != 0)
+		usage(argv[0]);
+
+	piglit_require_extension("GL_EXT_texture_integer");
+	piglit_require_extension("GL_ARB_texture_rg");
+
+	if (test_arb) {
+		piglit_require_extension("GL_ARB_texture_buffer_object");
+	} else {
+		if (piglit_get_gl_version() < 31)
+			piglit_require_extension("GL_ARB_texture_buffer_object");
+	}
+
+	init_programs();
+}
-- 
1.7.9.1



More information about the Piglit mailing list