[Piglit] [PATCH piglit 7/6] Add a test for all of the modes of the two half-float formats of BPTC

Neil Roberts neil at linux.intel.com
Thu Jul 31 07:00:44 PDT 2014


The test creates a texture with a block for each of the possible modes
of the half-float formats of BPTC and then retrieves it as a
half-float texture via glGetTexImage. This should test that the
decompressor works correctly with all possible code paths. It doesn't
test rendering the texture because that is a bit more tricky to do
accurately as it is not possible to create a half-float render target.

The data is generated randomly with an external program which also
generated the expected results. There are expected results for both
the signed and unsigned formats.
---
 tests/all.py                       |    1 +
 tests/texturing/CMakeLists.gl.txt  |    1 +
 tests/texturing/bptc-float-modes.c | 1009 ++++++++++++++++++++++++++++++++++++
 3 files changed, 1011 insertions(+)
 create mode 100644 tests/texturing/bptc-float-modes.c

diff --git a/tests/all.py b/tests/all.py
index 27eee50..2d00684 100644
--- a/tests/all.py
+++ b/tests/all.py
@@ -2294,6 +2294,7 @@ arb_texture_compression_bptc = {}
 spec['ARB_texture_compression_bptc'] = arb_texture_compression_bptc
 arb_texture_compression_bptc['invalid formats'] = concurrent_test('arb_texture_compression-invalid-formats bptc')
 add_concurrent_test(arb_texture_compression_bptc, 'bptc-modes')
+add_concurrent_test(arb_texture_compression_bptc, 'bptc-float-modes')
 add_fbo_generatemipmap_extension(arb_texture_compression_bptc, 'GL_ARB_texture_compression_bptc-unorm', 'fbo-generatemipmap-formats')
 add_fbo_generatemipmap_extension(arb_texture_compression_bptc, 'GL_ARB_texture_compression_bptc-float', 'fbo-generatemipmap-formats')
 add_texwrap_format_tests(arb_texture_compression_bptc, 'GL_ARB_texture_compression_bptc')
diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
index cd1bc11..bb88dec 100644
--- a/tests/texturing/CMakeLists.gl.txt
+++ b/tests/texturing/CMakeLists.gl.txt
@@ -14,6 +14,7 @@ piglit_add_executable (1-1-linear-texture 1-1-linear-texture.c)
 piglit_add_executable (array-depth-roundtrip array-depth-roundtrip.c)
 piglit_add_executable (array-texture array-texture.c)
 piglit_add_executable (bptc-modes bptc-modes.c)
+piglit_add_executable (bptc-float-modes bptc-float-modes.c)
 piglit_add_executable (compressedteximage compressedteximage.c)
 piglit_add_executable (copytexsubimage copytexsubimage.c)
 piglit_add_executable (copyteximage copyteximage.c)
diff --git a/tests/texturing/bptc-float-modes.c b/tests/texturing/bptc-float-modes.c
new file mode 100644
index 0000000..f16de19
--- /dev/null
+++ b/tests/texturing/bptc-float-modes.c
@@ -0,0 +1,1009 @@
+/*
+ * Copyright © 2014 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.
+ *
+ * Authors:
+ *    Neil Roberts <neil at linux.intel.com>
+ *
+ */
+
+/** @file bptc-modes.c
+ *
+ * Tests a BPTC-compressed half-float texture with a block for each of
+ * the possible 14 modes. The texture is retrieved with glGetTexImage
+ * and verified that it has the expected values.
+ */
+
+#include "piglit-util-gl.h"
+
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+	config.supports_gl_compat_version = 10;
+
+	config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+#define BLOCK_SIZE 4
+#define BLOCK_BYTES 16
+#define N_PARTITIONS 32
+
+struct bptc_float_bitfield {
+   int8_t endpoint;
+   uint8_t component;
+   uint8_t offset;
+   uint8_t n_bits;
+   bool reverse;
+};
+
+struct bptc_float_mode {
+   int n_partition_bits;
+   int n_index_bits;
+   struct bptc_float_bitfield bitfields[24];
+};
+
+static const struct bptc_float_mode
+bptc_float_modes[] = {
+   /* 00 */
+   { 5, 3,
+     { { 2, 1, 4, 1, false }, { 2, 2, 4, 1, false }, { 3, 2, 4, 1, false },
+       { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false },
+       { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false },
+       { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false },
+       { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false },
+       { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 01 */
+   { 5, 3,
+     { { 2, 1, 5, 1, false }, { 3, 1, 4, 1, false }, { 3, 1, 5, 1, false },
+       { 0, 0, 0, 7, false }, { 3, 2, 0, 1, false }, { 3, 2, 1, 1, false },
+       { 2, 2, 4, 1, false }, { 0, 1, 0, 7, false }, { 2, 2, 5, 1, false },
+       { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, { 0, 2, 0, 7, false },
+       { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false },
+       { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false },
+       { 2, 0, 0, 6, false },
+       { 3, 0, 0, 6, false },
+       { -1 } }
+   },
+   /* 00010 */
+   { 5, 3,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 5, false }, { 0, 0, 10, 1, false }, { 2, 1, 0, 4, false },
+       { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, { 3, 2, 0, 1, false },
+       { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false },
+       { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false },
+       { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 00011 */
+   { 0, 4,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 10, false }, { 1, 1, 0, 10, false }, { 1, 2, 0, 10, false },
+       { -1 } }
+   },
+   /* 00110 */
+   { 5, 3,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 3, 1, 4, 1, false },
+       { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, { 0, 1, 10, 1, false },
+       { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false },
+       { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false },
+       { 3, 2, 0, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false },
+       { 2, 1, 4, 1, false }, { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 00111 */
+   { 0, 4,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 9, false }, { 0, 0, 10, 1, false }, { 1, 1, 0, 9, false },
+       { 0, 1, 10, 1, false }, { 1, 2, 0, 9, false }, { 0, 2, 10, 1, false },
+       { -1 } }
+   },
+   /* 01010 */
+   { 5, 3,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 2, 2, 4, 1, false },
+       { 2, 1, 0, 4, false }, { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false },
+       { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false },
+       { 0, 2, 10, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false },
+       { 3, 2, 1, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false },
+       { 3, 2, 4, 1, false }, { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 01011 */
+   { 0, 4,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 8, false }, { 0, 0, 10, 2, true }, { 1, 1, 0, 8, false },
+       { 0, 1, 10, 2, true }, { 1, 2, 0, 8, false }, { 0, 2, 10, 2, true },
+       { -1 } }
+   },
+   /* 01110 */
+   { 5, 3,
+     { { 0, 0, 0, 9, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 9, false },
+       { 2, 1, 4, 1, false }, { 0, 2, 0, 9, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false },
+       { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false },
+       { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false },
+       { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false },
+       { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 01111 */
+   { 0, 4,
+     { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false },
+       { 1, 0, 0, 4, false }, { 0, 0, 10, 6, true }, { 1, 1, 0, 4, false },
+       { 0, 1, 10, 6, true }, { 1, 2, 0, 4, false }, { 0, 2, 10, 6, true },
+       { -1 } }
+   },
+   /* 10010 */
+   { 5, 3,
+     { { 0, 0, 0, 8, false }, { 3, 1, 4, 1, false }, { 2, 2, 4, 1, false },
+       { 0, 1, 0, 8, false }, { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false },
+       { 0, 2, 0, 8, false }, { 3, 2, 3, 1, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false },
+       { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false },
+       { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 6, false },
+       { 3, 0, 0, 6, false },
+       { -1 } }
+   },
+   /* 10011 */
+   { /* reserved */ },
+   /* 10110 */
+   { 5, 3,
+     { { 0, 0, 0, 8, false }, { 3, 2, 0, 1, false }, { 2, 2, 4, 1, false },
+       { 0, 1, 0, 8, false }, { 2, 1, 5, 1, false }, { 2, 1, 4, 1, false },
+       { 0, 2, 0, 8, false }, { 3, 1, 5, 1, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false },
+       { 1, 1, 0, 6, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false },
+       { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false },
+       { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 10111 */
+   { /* reserved */ },
+   /* 11010 */
+   { 5, 3,
+     { { 0, 0, 0, 8, false }, { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false },
+       { 0, 1, 0, 8, false }, { 2, 2, 5, 1, false }, { 2, 1, 4, 1, false },
+       { 0, 2, 0, 8, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false },
+       { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false },
+       { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false },
+       { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false },
+       { -1 } }
+   },
+   /* 11011 */
+   { /* reserved */ },
+   /* 11110 */
+   { 5, 3,
+     { { 0, 0, 0, 6, false }, { 3, 1, 4, 1, false }, { 3, 2, 0, 1, false },
+       { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 6, false },
+       { 2, 1, 5, 1, false }, { 2, 2, 5, 1, false }, { 3, 2, 2, 1, false },
+       { 2, 1, 4, 1, false }, { 0, 2, 0, 6, false }, { 3, 1, 5, 1, false },
+       { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false },
+       { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false },
+       { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false },
+       { 2, 0, 0, 6, false }, { 3, 0, 0, 6, false },
+       { -1 } }
+   },
+   /* 11111 */
+   { /* reserved */ },
+};
+
+static const uint8_t
+anchor_indices[N_PARTITIONS] = {
+	/* Anchor index values for the second subset of two-subset
+	 * partitioning */
+	0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,
+	0xf,0x2,0x8,0x2,0x2,0x8,0x8,0xf,0x2,0x8,0x2,0x2,0x8,0x8,0x2,0x2
+};
+
+struct bptc_block {
+	int mode;
+	int partition;
+	uint16_t endpoints[2 * 2][3];
+	uint8_t indices[BLOCK_SIZE * BLOCK_SIZE];
+	GLhalfNV signed_expected_values[BLOCK_SIZE * BLOCK_SIZE * 3];
+	GLhalfNV unsigned_expected_values[BLOCK_SIZE * BLOCK_SIZE * 3];
+};
+
+static const struct bptc_block
+bptc_blocks[] = {
+	{
+		0, /* mode */
+		0, /* partition */
+		{
+			 { 0x0167, 0x03c6, 0x0069 },
+			 { 0x0013, 0x0011, 0x001f },
+			 { 0x000a, 0x000c, 0x0009 },
+			 { 0x000d, 0x001a, 0x000b }
+		},
+		{
+			0x2, 0x3, 0x3, 0x6, /* subsets 0(a) 0    1    1    */
+			0x4, 0x2, 0x4, 0x0, /* subsets 0    0    1    1    */
+			0x3, 0x0, 0x7, 0x5, /* subsets 0    0    1    1    */
+			0x6, 0x2, 0x6, 0x3  /* subsets 0    0    1    1(a) */
+		},
+		{
+			0x562e, 0x8f30, 0x197b, 0x55bc, 0x8fb3, 0x1972,
+			0x59cb, 0x8d19, 0x1bef, 0x5a1c, 0x8f02, 0x1c25,
+			0x553f, 0x9044, 0x1969, 0x562e, 0x8f30, 0x197b,
+			0x59e8, 0x8dc8, 0x1c02, 0x597d, 0x8b43, 0x1bbb,
+			0x55bc, 0x8fb3, 0x1972, 0x5711, 0x8e2b, 0x198d,
+			0x5a37, 0x8f9f, 0x1c37, 0x5a02, 0x8e65, 0x1c14,
+			0x545c, 0x914a, 0x1957, 0x562e, 0x8f30, 0x197b,
+			0x5a1c, 0x8f02, 0x1c25, 0x59cb, 0x8d19, 0x1bef
+		},
+		{
+			0x2b17, 0x7486, 0x0cbd, 0x2ade, 0x7445, 0x0cb9,
+			0x2ce5, 0x7592, 0x0df7, 0x2d0e, 0x749d, 0x0e12,
+			0x2a9f, 0x73fc, 0x0cb4, 0x2b17, 0x7486, 0x0cbd,
+			0x2cf4, 0x753a, 0x0e01, 0x2cbe, 0x767d, 0x0ddd,
+			0x2ade, 0x7445, 0x0cb9, 0x2b88, 0x7509, 0x0cc6,
+			0x2d1b, 0x744f, 0x0e1b, 0x2d01, 0x74ec, 0x0e0a,
+			0x2a2e, 0x7379, 0x0cab, 0x2b17, 0x7486, 0x0cbd,
+			0x2d0e, 0x749d, 0x0e12, 0x2ce5, 0x7592, 0x0df7
+		}
+	},
+	{
+		1, /* mode */
+		1, /* partition */
+		{
+			 { 0x0033, 0x001f, 0x0049 },
+			 { 0x001a, 0x0026, 0x0032 },
+			 { 0x000d, 0x0037, 0x0031 },
+			 { 0x0018, 0x0023, 0x001a }
+		},
+		{
+			0x1, 0x5, 0x5, 0x7, /* subsets 0(a) 0    0    1    */
+			0x0, 0x1, 0x6, 0x4, /* subsets 0    0    0    1    */
+			0x3, 0x2, 0x5, 0x6, /* subsets 0    0    0    1    */
+			0x3, 0x4, 0x4, 0x1  /* subsets 0    0    0    1(a) */
+		},
+		{
+			0x47b7, 0x35f2, 0xcc32, 0xaba7, 0x18d3, 0x349d,
+			0xaba7, 0x18d3, 0x349d, 0xe7a8, 0x04d8, 0xb928,
+			0x63c8, 0x3d08, 0xeb88, 0x47b7, 0x35f2, 0xcc32,
+			0xc7b7, 0x11bd, 0x53f2, 0xf03d, 0x1531, 0x0ec6,
+			0x0f97, 0x27c7, 0x8d88, 0x2ba7, 0x2edd, 0xacdd,
+			0xaba7, 0x18d3, 0x349d, 0xea84, 0x0a4b, 0xa12e,
+			0x0f97, 0x27c7, 0x8d88, 0x8f97, 0x1fe8, 0x1548,
+			0x8f97, 0x1fe8, 0x1548, 0xf922, 0x2625, 0x595e
+		},
+		{
+			0x356e, 0x1af9, 0x454b, 0x43fe, 0x0c69, 0x3d74,
+			0x43fe, 0x0c69, 0x3d74, 0x4924, 0x026c, 0x6064,
+			0x31e4, 0x1e84, 0x4734, 0x356e, 0x1af9, 0x454b,
+			0x4789, 0x08de, 0x3b8c, 0x44a5, 0x0a98, 0x4fa2,
+			0x3c84, 0x13e3, 0x417b, 0x38f9, 0x176e, 0x4363,
+			0x43fe, 0x0c69, 0x3d74, 0x47a4, 0x0525, 0x5ace,
+			0x3c84, 0x13e3, 0x417b, 0x4073, 0x0ff4, 0x3f5c,
+			0x4073, 0x0ff4, 0x3f5c, 0x3ffb, 0x1312, 0x3e41
+		}
+	},
+	{
+		2, /* mode */
+		2, /* partition */
+		{
+			 { 0x040e, 0x0582, 0x0074 },
+			 { 0x0001, 0x0001, 0x000d },
+			 { 0x001c, 0x0007, 0x0000 },
+			 { 0x0009, 0x000e, 0x0001 }
+		},
+		{
+			0x1, 0x1, 0x4, 0x7, /* subsets 0(a) 1    1    1    */
+			0x6, 0x1, 0x6, 0x7, /* subsets 0    1    1    1    */
+			0x2, 0x4, 0x3, 0x6, /* subsets 0    1    1    1    */
+			0x7, 0x0, 0x4, 0x2  /* subsets 0    1    1    1(a) */
+		},
+		{
+			0xfa58, 0xcd4c, 0x0e0e, 0xfaa0, 0xcc9f, 0x0e20,
+			0xf9f0, 0xcd19, 0x0e2d, 0xf946, 0xcd8f, 0x0e3a,
+			0xfa42, 0xcd36, 0x0dcc, 0xfaa0, 0xcc9f, 0x0e20,
+			0xf97e, 0xcd67, 0x0e36, 0xf946, 0xcd8f, 0x0e3a,
+			0xfa54, 0xcd48, 0x0e01, 0xf9f0, 0xcd19, 0x0e2d,
+			0xfa2f, 0xcced, 0x0e29, 0xf97e, 0xcd67, 0x0e36,
+			0xfa3e, 0xcd32, 0x0dbe, 0xfad9, 0xcc78, 0x0e1b,
+			0xf9f0, 0xcd19, 0x0e2d, 0xfa68, 0xccc6, 0x0e24
+		},
+		{
+			0x3ee3, 0x5569, 0x0707, 0x3ebf, 0x55bf, 0x0710,
+			0x3f17, 0x5582, 0x0716, 0x3f6c, 0x5547, 0x071d,
+			0x3eee, 0x5574, 0x06e6, 0x3ebf, 0x55bf, 0x0710,
+			0x3f50, 0x555b, 0x071b, 0x3f6c, 0x5547, 0x071d,
+			0x3ee5, 0x556b, 0x0700, 0x3f17, 0x5582, 0x0716,
+			0x3ef8, 0x5598, 0x0714, 0x3f50, 0x555b, 0x071b,
+			0x3ef0, 0x5576, 0x06df, 0x3ea2, 0x55d3, 0x070d,
+			0x3f17, 0x5582, 0x0716, 0x3edb, 0x55ac, 0x0712
+		}
+	},
+	{
+		3, /* mode */
+		0, /* partition (not used) */
+		{
+			 { 0x02ec, 0x00b0, 0x003b },
+			 { 0x02fb, 0x0232, 0x00af }
+		},
+		{
+			0x4, 0x4, 0xc, 0x8, /* subsets 0(a) 0    0    0    */
+			0xb, 0xc, 0x2, 0xa, /* subsets 0    0    0    0    */
+			0xe, 0x3, 0xb, 0xa, /* subsets 0    0    0    0    */
+			0xa, 0xa, 0xb, 0x9  /* subsets 0    0    0    0    */
+		},
+		{
+			0xc1ff, 0x01a3, 0x15df, 0xc1ff, 0x01a3, 0x15df,
+			0xc011, 0xd093, 0x24cc, 0xc108, 0xa778, 0x1d55,
+			0xc04c, 0xc6e7, 0x230a, 0xc011, 0xd093, 0x24cc,
+			0xc274, 0x14fb, 0x125c, 0xc086, 0xbd3b, 0x2149,
+			0xbf8f, 0xe656, 0x28bf, 0xc23a, 0x0b4f, 0x141d,
+			0xc04c, 0xc6e7, 0x230a, 0xc086, 0xbd3b, 0x2149,
+			0xc086, 0xbd3b, 0x2149, 0xc086, 0xbd3b, 0x2149,
+			0xc04c, 0xc6e7, 0x230a, 0xc0ce, 0xb124, 0x1f17
+		},
+		{
+			0x5b1f, 0x21c9, 0x0aef, 0x5b1f, 0x21c9, 0x0aef,
+			0x5c16, 0x3a9e, 0x1266, 0x5b9a, 0x2e34, 0x0eaa,
+			0x5bf8, 0x37b3, 0x1185, 0x5c16, 0x3a9e, 0x1266,
+			0x5ae4, 0x1bf2, 0x092e, 0x5bdb, 0x34c7, 0x10a4,
+			0x5c57, 0x4131, 0x145f, 0x5b01, 0x1ede, 0x0a0e,
+			0x5bf8, 0x37b3, 0x1185, 0x5bdb, 0x34c7, 0x10a4,
+			0x5bdb, 0x34c7, 0x10a4, 0x5bdb, 0x34c7, 0x10a4,
+			0x5bf8, 0x37b3, 0x1185, 0x5bb7, 0x3120, 0x0f8b
+		}
+	},
+	{
+		6, /* mode */
+		3, /* partition */
+		{
+			 { 0x05d1, 0x07e6, 0x0005 },
+			 { 0x000c, 0x001c, 0x0004 },
+			 { 0x0005, 0x0018, 0x000e },
+			 { 0x0001, 0x0009, 0x0009 }
+		},
+		{
+			0x0, 0x3, 0x0, 0x1, /* subsets 0(a) 0    0    1    */
+			0x7, 0x5, 0x1, 0x3, /* subsets 0    0    1    1    */
+			0x1, 0x3, 0x5, 0x7, /* subsets 0    0    1    1    */
+			0x7, 0x0, 0x1, 0x1  /* subsets 0    1    1    1(a) */
+		},
+		{
+			0xc3c0, 0x8335, 0x00aa, 0xc3f4, 0x8369, 0x00de,
+			0xc3c0, 0x8335, 0x00aa, 0xc336, 0x83e2, 0x0052,
+			0xc43c, 0x83b1, 0x0126, 0xc419, 0x838e, 0x0103,
+			0xc336, 0x83e2, 0x0052, 0xc359, 0x834e, 0x001e,
+			0xc3d1, 0x8346, 0x00bb, 0xc3f4, 0x8369, 0x00de,
+			0xc37e, 0x82b2, 0x8019, 0xc3a1, 0x821e, 0x804d,
+			0xc43c, 0x83b1, 0x0126, 0xc325, 0x842d, 0x006c,
+			0xc336, 0x83e2, 0x0052, 0xc336, 0x83e2, 0x0052
+		},
+		{
+			0x5a2f, 0x7a74, 0x0055, 0x5a15, 0x7a5a, 0x006f,
+			0x5a2f, 0x7a74, 0x0055, 0x5a74, 0x7a1e, 0x119b,
+			0x59f1, 0x7a36, 0x0093, 0x5a02, 0x7a48, 0x0081,
+			0x5a74, 0x7a1e, 0x119b, 0x5a62, 0x7a68, 0x3465,
+			0x5a26, 0x7a6c, 0x005d, 0x5a15, 0x7a5a, 0x006f,
+			0x5a50, 0x7ab6, 0x591e, 0x5a3e, 0x7b00, 0x7be8,
+			0x59f1, 0x7a36, 0x0093, 0x5a7c, 0x79f8, 0x0036,
+			0x5a74, 0x7a1e, 0x119b, 0x5a74, 0x7a1e, 0x119b
+		}
+	},
+	{
+		7, /* mode */
+		0, /* partition (not used) */
+		{
+			 { 0x023a, 0x02e5, 0x07ca },
+			 { 0x000b, 0x00cb, 0x01d0 }
+		},
+		{
+			0x0, 0x7, 0x4, 0xd, /* subsets 0(a) 0    0    0    */
+			0xf, 0x3, 0xe, 0x8, /* subsets 0    0    0    0    */
+			0xc, 0xb, 0x4, 0x5, /* subsets 0    0    0    0    */
+			0x4, 0x3, 0xa, 0x5  /* subsets 0    0    0    0    */
+		},
+		{
+			0x4515, 0x59ca, 0x8699, 0x45b5, 0x6550, 0x8953,
+			0x4570, 0x6052, 0x8824, 0x463b, 0x6eeb, 0x8b98,
+			0x466a, 0x725f, 0x8c69, 0x455b, 0x5ec9, 0x87c7,
+			0x4655, 0x70d6, 0x8c0c, 0x45ca, 0x66d9, 0x89b0,
+			0x4625, 0x6d61, 0x8b3b, 0x4610, 0x6bd8, 0x8ade,
+			0x4570, 0x6052, 0x8824, 0x4585, 0x61db, 0x8881,
+			0x4570, 0x6052, 0x8824, 0x455b, 0x5ec9, 0x87c7,
+			0x45fb, 0x6a4f, 0x8a81, 0x4585, 0x61db, 0x8881
+		},
+		{
+			0x228a, 0x2ce5, 0x78c2, 0x22da, 0x32a8, 0x7766,
+			0x22b8, 0x3029, 0x77fd, 0x231d, 0x3775, 0x7643,
+			0x2335, 0x392f, 0x75da, 0x22ad, 0x2f64, 0x782b,
+			0x232a, 0x386b, 0x7609, 0x22e5, 0x336c, 0x7737,
+			0x2312, 0x36b0, 0x7671, 0x2308, 0x35ec, 0x76a0,
+			0x22b8, 0x3029, 0x77fd, 0x22c2, 0x30ed, 0x77ce,
+			0x22b8, 0x3029, 0x77fd, 0x22ad, 0x2f64, 0x782b,
+			0x22fd, 0x3527, 0x76ce, 0x22c2, 0x30ed, 0x77ce
+		}
+	},
+	{
+		10, /* mode */
+		4, /* partition */
+		{
+			 { 0x015e, 0x034b, 0x0379 },
+			 { 0x0003, 0x000b, 0x0010 },
+			 { 0x0004, 0x0004, 0x0011 },
+			 { 0x000e, 0x0009, 0x001c }
+		},
+		{
+			0x2, 0x4, 0x4, 0x2, /* subsets 0(a) 0    0    0    */
+			0x3, 0x0, 0x7, 0x3, /* subsets 0    0    0    1    */
+			0x3, 0x5, 0x3, 0x0, /* subsets 0    0    0    1    */
+			0x0, 0x7, 0x5, 0x0  /* subsets 0    0    1    1(a) */
+		},
+		{
+			0x2a8b, 0x65f8, 0x6b2b, 0x2aa7, 0x65cb, 0x6a97,
+			0x2aa7, 0x65cb, 0x6a97, 0x2a8b, 0x65f8, 0x6b2b,
+			0x2a99, 0x65e3, 0x6ae5, 0x2a71, 0x6624, 0x6bb6,
+			0x2ace, 0x6589, 0x69c6, 0x2a9f, 0x6611, 0x6a75,
+			0x2a99, 0x65e3, 0x6ae5, 0x2ab4, 0x65b5, 0x6a52,
+			0x2a99, 0x65e3, 0x6ae5, 0x2aed, 0x66a0, 0x69e5,
+			0x2a71, 0x6624, 0x6bb6, 0x2ace, 0x6589, 0x69c6,
+			0x2a67, 0x65ab, 0x6ada, 0x2aed, 0x66a0, 0x69e5
+		},
+		{
+			0x1545, 0x32fc, 0x3595, 0x1553, 0x32e5, 0x354b,
+			0x1553, 0x32e5, 0x354b, 0x1545, 0x32fc, 0x3595,
+			0x154c, 0x32f1, 0x3572, 0x1538, 0x3312, 0x35db,
+			0x1567, 0x32c4, 0x34e3, 0x154f, 0x3308, 0x353a,
+			0x154c, 0x32f1, 0x3572, 0x155a, 0x32da, 0x3529,
+			0x154c, 0x32f1, 0x3572, 0x1576, 0x3350, 0x34f2,
+			0x1538, 0x3312, 0x35db, 0x1567, 0x32c4, 0x34e3,
+			0x1533, 0x32d5, 0x356d, 0x1576, 0x3350, 0x34f2
+		}
+	},
+	{
+		11, /* mode */
+		0, /* partition (not used) */
+		{
+			 { 0x0fbb, 0x016f, 0x0422 },
+			 { 0x0019, 0x00ba, 0x009b }
+		},
+		{
+			0x5, 0x5, 0xb, 0x1, /* subsets 0(a) 0    0    0    */
+			0xa, 0xc, 0xf, 0x3, /* subsets 0    0    0    0    */
+			0x8, 0x9, 0x8, 0x4, /* subsets 0    0    0    0    */
+			0xb, 0x3, 0x5, 0xa  /* subsets 0    0    0    0    */
+		},
+		{
+			0x83b6, 0x14dc, 0x3e15, 0x83b6, 0x14dc, 0x3e15,
+			0x8318, 0x1323, 0x3b98, 0x841d, 0x15fc, 0x3fb4,
+			0x8330, 0x1367, 0x3bfa, 0x8300, 0x12e0, 0x3b37,
+			0x82b1, 0x1203, 0x39f9, 0x83e6, 0x1564, 0x3ed9,
+			0x8366, 0x13ff, 0x3cd7, 0x834e, 0x13bc, 0x3c75,
+			0x8366, 0x13ff, 0x3cd7, 0x83ce, 0x1520, 0x3e77,
+			0x8318, 0x1323, 0x3b98, 0x83e6, 0x1564, 0x3ed9,
+			0x83b6, 0x14dc, 0x3e15, 0x8330, 0x1367, 0x3bfa
+		},
+		{
+			0x7a2c, 0x0a6e, 0x1f0a, 0x7a2c, 0x0a6e, 0x1f0a,
+			0x7a7b, 0x0991, 0x1dcc, 0x79f9, 0x0afe, 0x1fda,
+			0x7a6f, 0x09b3, 0x1dfd, 0x7a87, 0x0970, 0x1d9b,
+			0x7aae, 0x0901, 0x1cfc, 0x7a14, 0x0ab2, 0x1f6c,
+			0x7a54, 0x09ff, 0x1e6b, 0x7a60, 0x09de, 0x1e3a,
+			0x7a54, 0x09ff, 0x1e6b, 0x7a20, 0x0a90, 0x1f3b,
+			0x7a7b, 0x0991, 0x1dcc, 0x7a14, 0x0ab2, 0x1f6c,
+			0x7a2c, 0x0a6e, 0x1f0a, 0x7a6f, 0x09b3, 0x1dfd
+		}
+	},
+	{
+		14, /* mode */
+		5, /* partition */
+		{
+			 { 0x014e, 0x01e8, 0x0098 },
+			 { 0x0012, 0x0018, 0x0000 },
+			 { 0x0019, 0x000d, 0x001d },
+			 { 0x0014, 0x001c, 0x001f }
+		},
+		{
+			0x2, 0x7, 0x2, 0x3, /* subsets 0(a) 0    1    1    */
+			0x4, 0x5, 0x4, 0x6, /* subsets 0    1    1    1    */
+			0x1, 0x3, 0x2, 0x2, /* subsets 0    1    1    1    */
+			0x5, 0x2, 0x6, 0x0  /* subsets 1    1    1    1(a) */
+		},
+		{
+			0xd85e, 0x8cf5, 0x49de, 0xdd3e, 0x8fbe, 0x49de,
+			0xda88, 0x87e2, 0x48af, 0xdadf, 0x890b, 0x48d2,
+			0xda61, 0x8e1b, 0x49de, 0xdb97, 0x8b7d, 0x491c,
+			0xdb40, 0x8a54, 0x48f9, 0xdbee, 0x8ca5, 0x493f,
+			0xd76a, 0x8c69, 0x49de, 0xdadf, 0x890b, 0x48d2,
+			0xda88, 0x87e2, 0x48af, 0xda88, 0x87e2, 0x48af,
+			0xdb97, 0x8b7d, 0x491c, 0xda88, 0x87e2, 0x48af,
+			0xdbee, 0x8ca5, 0x493f, 0xd9da, 0x8592, 0x486a
+		},
+		{
+			0x500e, 0x75c3, 0x24ef, 0x4d9f, 0x745f, 0x24ef,
+			0x4ef9, 0x784c, 0x2457, 0x4ece, 0x77b8, 0x2469,
+			0x4f0d, 0x7530, 0x24ef, 0x4e72, 0x767f, 0x248e,
+			0x4e9d, 0x7713, 0x247c, 0x4e46, 0x75eb, 0x249f,
+			0x5088, 0x7609, 0x24ef, 0x4ece, 0x77b8, 0x2469,
+			0x4ef9, 0x784c, 0x2457, 0x4ef9, 0x784c, 0x2457,
+			0x4e72, 0x767f, 0x248e, 0x4ef9, 0x784c, 0x2457,
+			0x4e46, 0x75eb, 0x249f, 0x4f51, 0x7975, 0x2435
+		}
+	},
+	{
+		15, /* mode */
+		0, /* partition (not used) */
+		{
+			 { 0x21b5, 0xe373, 0x173b },
+			 { 0x0004, 0x000c, 0x0003 }
+		},
+		{
+			0x6, 0x4, 0x3, 0xf, /* subsets 0(a) 0    0    0    */
+			0x2, 0x0, 0x4, 0xe, /* subsets 0    0    0    0    */
+			0xf, 0x2, 0x5, 0x9, /* subsets 0    0    0    0    */
+			0xd, 0x2, 0xe, 0x9  /* subsets 0    0    0    0    */
+		},
+		{
+			0x20a9, 0x9baa, 0x1682, 0x20a8, 0x9ba9, 0x1682,
+			0x20a8, 0x9ba9, 0x1682, 0x20ab, 0x9bac, 0x1684,
+			0x20a8, 0x9ba9, 0x1681, 0x20a7, 0x9ba8, 0x1681,
+			0x20a8, 0x9ba9, 0x1682, 0x20ab, 0x9bac, 0x1684,
+			0x20ab, 0x9bac, 0x1684, 0x20a8, 0x9ba9, 0x1681,
+			0x20a8, 0x9ba9, 0x1682, 0x20a9, 0x9baa, 0x1683,
+			0x20aa, 0x9bab, 0x1684, 0x20a8, 0x9ba9, 0x1681,
+			0x20ab, 0x9bac, 0x1684, 0x20a9, 0x9baa, 0x1683
+		},
+		{
+			0x1054, 0x6e2a, 0x0b41, 0x1054, 0x6e2b, 0x0b41,
+			0x1054, 0x6e2b, 0x0b41, 0x1055, 0x6e29, 0x0b42,
+			0x1054, 0x6e2b, 0x0b40, 0x1053, 0x6e2b, 0x0b40,
+			0x1054, 0x6e2b, 0x0b41, 0x1055, 0x6e29, 0x0b42,
+			0x1055, 0x6e29, 0x0b42, 0x1054, 0x6e2b, 0x0b40,
+			0x1054, 0x6e2b, 0x0b41, 0x1054, 0x6e2a, 0x0b41,
+			0x1055, 0x6e2a, 0x0b42, 0x1054, 0x6e2b, 0x0b40,
+			0x1055, 0x6e29, 0x0b42, 0x1054, 0x6e2a, 0x0b41
+		}
+	},
+	{
+		18, /* mode */
+		6, /* partition */
+		{
+			 { 0x0008, 0x0070, 0x00d4 },
+			 { 0x0032, 0x000a, 0x0009 },
+			 { 0x0014, 0x0008, 0x001a },
+			 { 0x000a, 0x001c, 0x0015 }
+		},
+		{
+			0x2, 0x0, 0x0, 0x4, /* subsets 0(a) 0    0    1    */
+			0x4, 0x3, 0x3, 0x6, /* subsets 0    0    1    1    */
+			0x4, 0x7, 0x5, 0x3, /* subsets 0    1    1    1    */
+			0x1, 0x2, 0x5, 0x2  /* subsets 1    1    1    1(a) */
+		},
+		{
+			0x0425, 0x6fb5, 0xa8a8, 0x083c, 0x6cfc, 0xab1c,
+			0x083c, 0x6cfc, 0xab1c, 0x1602, 0x6e03, 0xb3b8,
+			0x802a, 0x7295, 0xa611, 0x021a, 0x7112, 0xa76e,
+			0x1785, 0x6fd4, 0xb2f7, 0x1348, 0x6abe, 0xb515,
+			0x802a, 0x7295, 0xa611, 0x11ec, 0x691c, 0xb5c4,
+			0x14a5, 0x6c61, 0xb467, 0x1785, 0x6fd4, 0xb2f7,
+			0x1a3f, 0x7319, 0xb19a, 0x18e2, 0x7177, 0xb248,
+			0x14a5, 0x6c61, 0xb467, 0x18e2, 0x7177, 0xb248
+		},
+		{
+			0x2515, 0x37da, 0x6827, 0x041e, 0x367e, 0x66ee,
+			0x041e, 0x367e, 0x66ee, 0x0b01, 0x3701, 0x629f,
+			0x47e2, 0x394a, 0x6973, 0x3591, 0x3889, 0x68c4,
+			0x0bc2, 0x37ea, 0x6300, 0x09a4, 0x355f, 0x61f1,
+			0x47e2, 0x394a, 0x6973, 0x08f6, 0x348e, 0x619a,
+			0x0a52, 0x3630, 0x6248, 0x0bc2, 0x37ea, 0x6300,
+			0x0d1f, 0x398c, 0x63ae, 0x0c71, 0x38bb, 0x6357,
+			0x0a52, 0x3630, 0x6248, 0x0c71, 0x38bb, 0x6357
+		}
+	},
+	{
+		22, /* mode */
+		7, /* partition */
+		{
+			 { 0x00c4, 0x0033, 0x00af },
+			 { 0x000d, 0x0023, 0x0004 },
+			 { 0x001f, 0x002d, 0x000d },
+			 { 0x0014, 0x0036, 0x0007 }
+		},
+		{
+			0x2, 0x2, 0x4, 0x4, /* subsets 0(a) 0    0    0    */
+			0x2, 0x4, 0x0, 0x6, /* subsets 0    0    0    1    */
+			0x0, 0x3, 0x5, 0x4, /* subsets 0    0    1    1    */
+			0x3, 0x2, 0x7, 0x0  /* subsets 0    1    1    1(a) */
+		},
+		{
+			0xb711, 0x29fd, 0xcddd, 0xb711, 0x29fd, 0xcddd,
+			0xb354, 0x21a6, 0xccb6, 0xb354, 0x21a6, 0xccb6,
+			0xb711, 0x29fd, 0xcddd, 0xb354, 0x21a6, 0xccb6,
+			0xba9c, 0x31e4, 0xcef4, 0xc4bc, 0x26fa, 0xc75a,
+			0xba9c, 0x31e4, 0xcef4, 0xb54b, 0x2609, 0xcd51,
+			0xc33c, 0x25c0, 0xc689, 0xc1bd, 0x2486, 0xc5b8,
+			0xb54b, 0x2609, 0xcd51, 0xbe93, 0x21ef, 0xc3fe,
+			0xc63c, 0x2834, 0xc82c, 0xbb94, 0x1f7c, 0xc25c
+		},
+		{
+			0x60f3, 0x14fe, 0x558d, 0x60f3, 0x14fe, 0x558d,
+			0x62d1, 0x10d3, 0x5620, 0x62d1, 0x10d3, 0x5620,
+			0x60f3, 0x14fe, 0x558d, 0x62d1, 0x10d3, 0x5620,
+			0x5f2e, 0x18f2, 0x5502, 0x5a1d, 0x137d, 0x58ce,
+			0x5f2e, 0x18f2, 0x5502, 0x61d6, 0x1304, 0x55d3,
+			0x5add, 0x12e0, 0x5937, 0x5b9d, 0x1243, 0x599f,
+			0x61d6, 0x1304, 0x55d3, 0x5d32, 0x10f7, 0x5a7c,
+			0x595e, 0x141a, 0x5866, 0x5eb2, 0x0fbe, 0x5b4e
+		}
+	},
+	{
+		26, /* mode */
+		8, /* partition */
+		{
+			 { 0x00f4, 0x00ec, 0x000b },
+			 { 0x0019, 0x0000, 0x003a },
+			 { 0x0006, 0x0003, 0x003e },
+			 { 0x0005, 0x0011, 0x002c }
+		},
+		{
+			0x1, 0x7, 0x3, 0x7, /* subsets 0(a) 0    0    0    */
+			0x1, 0x0, 0x3, 0x3, /* subsets 0    0    0    0    */
+			0x4, 0x3, 0x1, 0x4, /* subsets 0    0    0    1    */
+			0x7, 0x6, 0x0, 0x2  /* subsets 0    0    1    1(a) */
+		},
+		{
+			0x8d10, 0x93dc, 0x0a52, 0x92e4, 0x93dc, 0x0554,
+			0x8ef8, 0x93dc, 0x08b0, 0x92e4, 0x93dc, 0x0554,
+			0x8d10, 0x93dc, 0x0a52, 0x8c1c, 0x93dc, 0x0b24,
+			0x8ef8, 0x93dc, 0x08b0, 0x8ef8, 0x93dc, 0x08b0,
+			0x9007, 0x93dc, 0x07c7, 0x8ef8, 0x93dc, 0x08b0,
+			0x8d10, 0x93dc, 0x0a52, 0x86db, 0x9b08, 0x8170,
+			0x92e4, 0x93dc, 0x0554, 0x91ef, 0x93dc, 0x0625,
+			0x864c, 0x90f4, 0x0934, 0x8691, 0x95db, 0x0406
+		},
+		{
+			0x75f3, 0x728e, 0x0529, 0x730a, 0x728e, 0x02aa,
+			0x74ff, 0x728e, 0x0458, 0x730a, 0x728e, 0x02aa,
+			0x75f3, 0x728e, 0x0529, 0x766e, 0x728e, 0x0592,
+			0x74ff, 0x728e, 0x0458, 0x74ff, 0x728e, 0x0458,
+			0x7478, 0x728e, 0x03e3, 0x74ff, 0x728e, 0x0458,
+			0x75f3, 0x728e, 0x0529, 0x790e, 0x6ef7, 0x473f,
+			0x730a, 0x728e, 0x02aa, 0x7384, 0x728e, 0x0312,
+			0x7956, 0x7402, 0x049a, 0x7933, 0x718e, 0x2506
+		}
+	},
+	{
+		30, /* mode */
+		9, /* partition */
+		{
+			 { 0x0010, 0x0028, 0x0036 },
+			 { 0x0005, 0x0014, 0x0001 },
+			 { 0x003e, 0x0034, 0x003c },
+			 { 0x0004, 0x0038, 0x003a }
+		},
+		{
+			0x1, 0x1, 0x6, 0x3, /* subsets 0(a) 0    1    1    */
+			0x0, 0x2, 0x2, 0x1, /* subsets 0    1    1    1    */
+			0x2, 0x6, 0x4, 0x6, /* subsets 1    1    1    1    */
+			0x1, 0x5, 0x3, 0x0  /* subsets 1    1    1    1(a) */
+		},
+		{
+			0x39f1, 0xc66a, 0xa226, 0x39f1, 0xc66a, 0xa226,
+			0x0d9f, 0xa31e, 0x9819, 0x01c1, 0xa9e6, 0x94b5,
+			0x3ff0, 0xdef0, 0xa8b0, 0x820f, 0xac14, 0x939e,
+			0x820f, 0xac14, 0x939e, 0x85df, 0xae42, 0x9287,
+			0x820f, 0xac14, 0x939e, 0x0d9f, 0xa31e, 0x9819,
+			0x05fe, 0xa77a, 0x95eb, 0x0d9f, 0xa31e, 0x9819,
+			0x85df, 0xae42, 0x9287, 0x09cf, 0xa54c, 0x9702,
+			0x01c1, 0xa9e6, 0x94b5, 0x89b0, 0xb070, 0x9170
+		},
+		{
+			0x1cf8, 0x4905, 0x5b27, 0x1cf8, 0x4905, 0x5b27,
+			0x1885, 0x6c61, 0x71e3, 0x49af, 0x68fd, 0x7395,
+			0x1ff8, 0x4e78, 0x6998, 0x597d, 0x67e6, 0x7421,
+			0x597d, 0x67e6, 0x7421, 0x694a, 0x66cf, 0x74ac,
+			0x597d, 0x67e6, 0x7421, 0x1885, 0x6c61, 0x71e3,
+			0x3820, 0x6a33, 0x72fa, 0x1885, 0x6c61, 0x71e3,
+			0x694a, 0x66cf, 0x74ac, 0x2853, 0x6b4a, 0x726f,
+			0x49af, 0x68fd, 0x7395, 0x7918, 0x65b8, 0x7538
+		}
+	}
+};
+
+#define N_BLOCKS ARRAY_SIZE(bptc_blocks)
+
+static void
+write_bits(uint8_t *out,
+	   int *offset,
+	   int value,
+	   int n_bits)
+{
+	int bit_index = *offset % 8;
+	int byte_index = *offset / 8;
+	int n_bits_in_byte = MIN2(n_bits, 8 - bit_index);
+
+	*offset += n_bits;
+
+	while (n_bits > 0) {
+		out[byte_index] |= ((value & ((1 << n_bits_in_byte) - 1)) <<
+				    bit_index);
+
+		n_bits -= n_bits_in_byte;
+		value >>= n_bits_in_byte;
+		byte_index++;
+		bit_index = 0;
+		n_bits_in_byte = MIN2(n_bits, 8);
+	}
+}
+
+static bool
+is_anchor(const struct bptc_float_mode *mode,
+	  int partition_num,
+	  int texel)
+{
+	if (texel == 0)
+		return true;
+
+	return (mode->n_partition_bits > 0 &&
+		anchor_indices[partition_num] == texel);
+}
+
+static uint16_t
+extract_bitfield(const struct bptc_block *block,
+		 const struct bptc_float_bitfield *bitfield)
+{
+	uint16_t value, tmp;
+	int i;
+
+	value = ((block->endpoints[bitfield->endpoint][bitfield->component] >>
+		  bitfield->offset) &
+		 ((1 << bitfield->n_bits) - 1));
+
+	if (bitfield->reverse) {
+		tmp = 0;
+		for (i = 0; i < bitfield->n_bits; i++) {
+			tmp <<= 1;
+			if (value & 1)
+				tmp |= 1;
+			value >>= 1;
+		}
+		return tmp;
+	} else {
+		return value;
+	}
+}
+
+static void
+make_block(const struct bptc_block *block,
+	   uint8_t *out)
+{
+	const struct bptc_float_mode *mode;
+	const struct bptc_float_bitfield *bitfield;
+	int offset = 0;
+	int n_bits;
+	uint16_t value;
+	int i;
+
+	if (block->mode >= 2) {
+		mode = (bptc_float_modes +
+			(((block->mode >> 1) & 0xe) | (block->mode & 1))) + 2;
+	} else {
+		mode = bptc_float_modes + (block->mode & 1);
+	}
+
+	memset(out, 0, BLOCK_SIZE * BLOCK_SIZE);
+
+	if (block->mode < 2)
+		write_bits(out, &offset, block->mode, 2);
+	else
+		write_bits(out, &offset, block->mode, 5);
+
+	for (bitfield = mode->bitfields; bitfield->endpoint != -1; bitfield++) {
+		value = extract_bitfield(block, bitfield);
+		write_bits(out, &offset, value, bitfield->n_bits);
+	}
+
+	write_bits(out, &offset, block->partition, mode->n_partition_bits);
+
+	for (i = 0; i < BLOCK_SIZE * BLOCK_SIZE; i++) {
+		n_bits = mode->n_index_bits;
+
+		if (is_anchor(mode, block->partition, i))
+			n_bits--;
+
+		write_bits(out, &offset, block->indices[i], n_bits);
+	}
+
+	assert(offset == BLOCK_BYTES * 8);
+}
+
+static GLuint
+make_tex(bool is_signed)
+{
+	GLuint tex;
+	uint8_t data[BLOCK_BYTES * N_BLOCKS];
+	int i;
+
+	glGenTextures(1, &tex);
+	glBindTexture(GL_TEXTURE_2D, tex);
+
+	for (i = 0; i < N_BLOCKS; i++)
+		make_block(bptc_blocks + i, data + i * BLOCK_BYTES);
+
+	glCompressedTexImage2D(GL_TEXTURE_2D,
+			       0, /* level */
+			       is_signed ?
+			       GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB :
+			       GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB,
+			       BLOCK_SIZE * 2, BLOCK_SIZE * N_BLOCKS / 2,
+			       0, /* border */
+			       sizeof data,
+			       data);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	return tex;
+}
+
+static bool
+compare_results(const GLhalfNV *expected,
+		const GLhalfNV *observed,
+		int observed_rowstride)
+{
+	int y, x, p;
+
+	for (y = 0; y < BLOCK_SIZE; y++) {
+		for (x = 0; x < BLOCK_SIZE; x++) {
+			for (p = 0; p < 3; p++) {
+				if (expected[p] != observed[p]) {
+					printf("Unexpected color at %i,%i:\n"
+					       "  Expected: %04x %04x %04x\n"
+					       "  Observed: %04x %04x %04x\n",
+					       x, y,
+					       expected[0],
+					       expected[1],
+					       expected[2],
+					       observed[0],
+					       observed[1],
+					       observed[2]);
+					return false;
+				}
+			}
+			expected += 3;
+			observed += 3;
+		}
+
+		observed += ((observed_rowstride -
+			     3 * BLOCK_SIZE * sizeof (float)) /
+			     sizeof (float));
+	}
+
+	return true;
+}
+
+static GLboolean
+check_block(const struct bptc_block *block,
+	    const GLhalfNV *get_data,
+	    bool is_signed)
+{
+	GLboolean pass;
+
+	printf("mode %i, partition %i\n",
+	       block->mode,
+	       block->partition);
+
+	pass = compare_results(is_signed ?
+			       block->signed_expected_values :
+			       block->unsigned_expected_values,
+			       get_data,
+			       BLOCK_SIZE * 2 * 3 * sizeof (float));
+	printf("glGetTexImage: %s\n", pass ? "pass" : "fail");
+
+	return pass;
+}
+
+static void
+render_texture(GLhalfNV *get_data,
+	       int x, int y,
+	       bool is_signed)
+{
+	GLuint tex;
+
+	tex = make_tex(is_signed);
+
+	glBindTexture(GL_TEXTURE_2D, tex);
+	glEnable(GL_TEXTURE_2D);
+
+	piglit_draw_rect_tex(x, y,
+			     BLOCK_SIZE * 2, BLOCK_SIZE * N_BLOCKS / 2,
+			     0.0f, 0.0f, 1.0f, 1.0f);
+
+	glDisable(GL_TEXTURE_2D);
+
+	glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+	glGetTexImage(GL_TEXTURE_2D,
+		      0, /* level */
+		      GL_RGB,
+		      GL_HALF_FLOAT,
+		      get_data);
+
+	glBindTexture(GL_TEXTURE_2D, 0);
+	glDeleteTextures(1, &tex);
+}
+
+enum piglit_result
+piglit_display(void)
+{
+	GLboolean pass = GL_TRUE;
+	GLhalfNV get_data[N_BLOCKS * BLOCK_SIZE * BLOCK_SIZE * 3];
+	int offset;
+	int is_signed;
+	int i;
+
+	glClearColor(0, 0, 0, 0);
+	glClear(GL_COLOR_BUFFER_BIT);
+
+	for (is_signed = 0; is_signed < 2; is_signed++) {
+		if (is_signed)
+			printf("Signed texture:\n");
+		else
+			printf("Unsigned texture:\n");
+
+		memset(get_data, 0, sizeof get_data);
+
+		render_texture(get_data,
+			       is_signed * BLOCK_SIZE * 2, 0, /* x/y offset */
+			       is_signed);
+
+		for (i = 0; i < N_BLOCKS; i++) {
+			offset = (i % 2 * BLOCK_SIZE * 3 +
+				  i / 2 * BLOCK_SIZE * BLOCK_SIZE * 2 * 3);
+			pass &= check_block(bptc_blocks + i,
+					    get_data + offset,
+					    is_signed);
+		}
+	}
+
+	piglit_present_results();
+
+	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	if (piglit_get_gl_version() < 42 &&
+	    !piglit_is_extension_supported("GL_ARB_texture_compression_bptc")) {
+		printf("OpenGL 4.2 or GL_ARB_texture_compression_bptc "
+		       "is required.\n");
+		piglit_report_result(PIGLIT_SKIP);
+	}
+
+	if (piglit_get_gl_version() < 30 &&
+	    !piglit_is_extension_supported("GL_ARB_half_float_pixel")) {
+		printf("OpenGL 3.0 or GL_ARB_half_float_pixel is required.\n");
+		piglit_report_result(PIGLIT_SKIP);
+	}
+
+	piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
+}
-- 
1.9.3



More information about the Piglit mailing list