summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2012-03-07 17:07:09 -0800
committerEric Anholt <eric@anholt.net>2012-03-28 10:43:15 -0700
commit677fc97e17d6e686b7c9693cee027a899b05aa38 (patch)
tree3643a8ca084cfb4346f8c31e8ebbf857a21f5197
parentdbd6e5377b5b31151c3b5a53a4be6b082547d40a (diff)
GL_ARB_texture_buffer_object/formats: Add a test for all the format options.tbo
-rw-r--r--tests/all.tests4
-rw-r--r--tests/spec/arb_texture_buffer_object/CMakeLists.gl.txt1
-rw-r--r--tests/spec/arb_texture_buffer_object/formats.c689
3 files changed, 694 insertions, 0 deletions
diff --git a/tests/all.tests b/tests/all.tests
index 1a9172648..71220301b 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 572ae2def..fd71ff706 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 000000000..8835cb6df
--- /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();
+}