[Piglit] [PATCH piglit] Add a test case for all of the modes of BPTC texture compression
Ilia Mirkin
imirkin at alum.mit.edu
Tue Jul 22 18:54:19 PDT 2014
On Tue, Jul 22, 2014 at 2:56 PM, Neil Roberts <neil at linux.intel.com> wrote:
> This creates a compressed texture with a block for each of 8 modes of
> BPTC compression. The texture is then both rendered and read back via
> glGetTexImage and compared with the expected values.
I may be misunderstanding, but it seems like this test only tests the
RGBA_UNORM format. How hard would it be to test all 4 formats? If it's
a pain to do so in the way you're doing here, you could have a more
basic test that just ensures that a texture that was compressed by the
library can be used for texturing (and returns the data you'd expect
it to).
[Sorry, I'm not qualified to review this test, just thinking about it
from a "what would be good to have for me to be confident in the
driver's impl".]
-ilia
> ---
> tests/all.py | 4 +
> tests/texturing/CMakeLists.gl.txt | 1 +
> tests/texturing/bptc-modes.c | 699 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 704 insertions(+)
> create mode 100644 tests/texturing/bptc-modes.c
>
> diff --git a/tests/all.py b/tests/all.py
> index 71e05d3..22f20fe 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -2840,6 +2840,10 @@ add_fbo_generatemipmap_extension(ati_texture_compression_3dc, 'GL_ATI_texture_co
> add_texwrap_format_tests(ati_texture_compression_3dc, 'GL_ATI_texture_compression_3dc')
> ati_texture_compression_3dc['invalid formats'] = concurrent_test('arb_texture_compression-invalid-formats 3dc')
>
> +arb_texture_compression_bptc = {}
> +spec['ARB_texture_compression_bptc'] = arb_texture_compression_bptc
> +add_concurrent_test(arb_texture_compression_bptc, 'bptc-modes')
> +
> ext_packed_float = {}
> spec['EXT_packed_float'] = ext_packed_float
> add_fbo_formats_tests('spec/EXT_packed_float', 'GL_EXT_packed_float')
> diff --git a/tests/texturing/CMakeLists.gl.txt b/tests/texturing/CMakeLists.gl.txt
> index b121163..cd1bc11 100644
> --- a/tests/texturing/CMakeLists.gl.txt
> +++ b/tests/texturing/CMakeLists.gl.txt
> @@ -13,6 +13,7 @@ link_libraries (
> 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 (compressedteximage compressedteximage.c)
> piglit_add_executable (copytexsubimage copytexsubimage.c)
> piglit_add_executable (copyteximage copyteximage.c)
> diff --git a/tests/texturing/bptc-modes.c b/tests/texturing/bptc-modes.c
> new file mode 100644
> index 0000000..0df092c
> --- /dev/null
> +++ b/tests/texturing/bptc-modes.c
> @@ -0,0 +1,699 @@
> +/*
> + * 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 BPTC-compressed textures that with a block for each of the
> + * possible 8 modes. The texture is both rendered and 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 64
> +
> +struct bptc_mode {
> + int n_subsets;
> + int n_partition_bits;
> + bool has_rotation_bits;
> + bool has_index_selection_bit;
> + int n_color_bits;
> + int n_alpha_bits;
> + bool has_endpoint_pbits;
> + bool has_shared_pbits;
> + int n_index_bits;
> + int n_secondary_index_bits;
> +};
> +
> +static const struct bptc_mode
> +bptc_modes[] = {
> + /* 0 */ { 3, 4, false, false, 4, 0, true, false, 3, 0 },
> + /* 1 */ { 2, 6, false, false, 6, 0, false, true, 3, 0 },
> + /* 2 */ { 3, 6, false, false, 5, 0, false, false, 2, 0 },
> + /* 3 */ { 2, 6, false, false, 7, 0, true, false, 2, 0 },
> + /* 4 */ { 1, 0, true, true, 5, 6, false, false, 2, 3 },
> + /* 5 */ { 1, 0, true, false, 7, 8, false, false, 2, 2 },
> + /* 6 */ { 1, 0, false, false, 7, 7, true, false, 4, 0 },
> + /* 7 */ { 2, 6, false, false, 5, 5, true, false, 2, 0 }
> +};
> +
> +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,
> + 0xf,0xf,0x6,0x8,0x2,0x8,0xf,0xf,0x2,0x8,0x2,0x2,0x2,0xf,0xf,0x6,
> + 0x6,0x2,0x6,0x8,0xf,0xf,0x2,0x2,0xf,0xf,0xf,0xf,0xf,0x2,0x2,0xf
> + },
> +
> + /* Anchor index values for the second subset of three-subset partitioning */
> + {
> + 0x3,0x3,0xf,0xf,0x8,0x3,0xf,0xf,0x8,0x8,0x6,0x6,0x6,0x5,0x3,0x3,
> + 0x3,0x3,0x8,0xf,0x3,0x3,0x6,0xa,0x5,0x8,0x8,0x6,0x8,0x5,0xf,0xf,
> + 0x8,0xf,0x3,0x5,0x6,0xa,0x8,0xf,0xf,0x3,0xf,0x5,0xf,0xf,0xf,0xf,
> + 0x3,0xf,0x5,0x5,0x5,0x8,0x5,0xa,0x5,0xa,0x8,0xd,0xf,0xc,0x3,0x3
> + },
> +
> + /* Anchor index values for the third subset of three-subset
> + * partitioning
> + */
> + {
> + 0xf,0x8,0x8,0x3,0xf,0xf,0x3,0x8,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x8,
> + 0xf,0x8,0xf,0x3,0xf,0x8,0xf,0x8,0x3,0xf,0x6,0xa,0xf,0xf,0xa,0x8,
> + 0xf,0x3,0xf,0xa,0xa,0x8,0x9,0xa,0x6,0xf,0x8,0xf,0x3,0x6,0x6,0x8,
> + 0xf,0x3,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x3,0xf,0xf,0x8
> + }
> +};
> +
> +struct bptc_block {
> + int mode;
> + int partition;
> + int rotation;
> + int index_selection;
> + uint8_t endpoints[2 * 3][4];
> + uint8_t pbits[3 * 2];
> + uint8_t primary_indices[BLOCK_SIZE * BLOCK_SIZE];
> + uint8_t secondary_indices[BLOCK_SIZE * BLOCK_SIZE];
> + uint8_t expected_values[BLOCK_SIZE * BLOCK_SIZE * 4];
> +};
> +
> +static const struct bptc_block
> +bptc_blocks[] = {
> + {
> + 0, /* mode */
> + 2, /* partition */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #000000ff #ffffffff */
> + { 0x0, 0x0, 0x0, 0x0 }, { 0xf, 0xf, 0xf, 0x0 },
> + /* #100010ff #ef08efff */
> + { 0x1, 0x0, 0x1, 0x0 }, { 0xe, 0x0, 0xe, 0x0 },
> + /* #001010ff #08dedeff */
> + { 0x0, 0x1, 0x1, 0x0 }, { 0x0, 0xd, 0xd, 0x0 }
> + },
> + /* pbits */
> + { 0, 1, 0, 1, 0, 1 },
> + /* primary indices */
> + {
> + 0x0, 0x2, 0x4, 0x7, /* subsets 0(a) 0 0 0 */
> + 0x0, 0x0, 0x7, 0x7, /* subsets 2 0 0 1 */
> + 0x0, 0x7, 0x0, 0x7, /* subsets 2(a) 2 1 1 */
> + 0x4, 0x2, 0x4, 0x2 /* subsets 2 2 1 1(a) */
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x00, 0x00, 0x00, 0xff, 0x48, 0x48, 0x48, 0xff,
> + 0x93, 0x93, 0x93, 0xff, 0xff, 0xff, 0xff, 0xff,
> + 0x00, 0x10, 0x10, 0xff, 0x00, 0x00, 0x00, 0xff,
> + 0xff, 0xff, 0xff, 0xff, 0xef, 0x08, 0xef, 0xff,
> + 0x00, 0x10, 0x10, 0xff, 0x08, 0xde, 0xde, 0xff,
> + 0x10, 0x00, 0x10, 0xff, 0xef, 0x08, 0xef, 0xff,
> + 0x05, 0x87, 0x87, 0xff, 0x02, 0x4a, 0x4a, 0xff,
> + 0x91, 0x05, 0x91, 0xff, 0x4f, 0x02, 0x4f, 0xff
> + },
> + },
> + {
> + 1, /* mode */
> + 63, /* partition */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #000000ff #fdfdfdff */
> + { 0x00, 0x00, 0x00, 0x00 }, { 0x3f, 0x3f, 0x3f, 0x00 },
> + /* #060206ff #bb02bbff */
> + { 0x01, 0x00, 0x01, 0x00 }, { 0x2e, 0x00, 0x2e, 0x00 },
> + },
> + /* pbits */
> + { 0, 1 },
> + /* primary indices */
> + {
> + 0x0, 0x2, 0x4, 0x7, /* subsets 0(a) 1 0 0 */
> + 0x0, 0x0, 0x7, 0x7, /* subsets 0 1 0 0 */
> + 0x0, 0x7, 0x0, 0x7, /* subsets 0 1 1 1 */
> + 0x4, 0x2, 0x4, 0x2 /* subsets 0 1 1 1(a) */
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x00, 0x00, 0x00, 0xff, 0x39, 0x02, 0x39, 0xff,
> + 0x92, 0x92, 0x92, 0xff, 0xfd, 0xfd, 0xfd, 0xff,
> + 0x00, 0x00, 0x00, 0xff, 0x06, 0x02, 0x06, 0xff,
> + 0xfd, 0xfd, 0xfd, 0xff, 0xfd, 0xfd, 0xfd, 0xff,
> + 0x00, 0x00, 0x00, 0xff, 0xbb, 0x02, 0xbb, 0xff,
> + 0x06, 0x02, 0x06, 0xff, 0xbb, 0x02, 0xbb, 0xff,
> + 0x92, 0x92, 0x92, 0xff, 0x39, 0x02, 0x39, 0xff,
> + 0x6f, 0x02, 0x6f, 0xff, 0x39, 0x02, 0x39, 0xff,
> + },
> + },
> + {
> + 2, /* mode */
> + 52, /* partition */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #000000ff #ffffffff */
> + { 0x00, 0x00, 0x00, 0x00 }, { 0x1f, 0x1f, 0x1f, 0x00 },
> + /* #080008ff #730073ff */
> + { 0x01, 0x00, 0x01, 0x00 }, { 0x0e, 0x00, 0x0e, 0x00 },
> + /* #008484ff #006b6bff */
> + { 0x00, 0x10, 0x10, 0x00 }, { 0x00, 0x0d, 0x0d, 0x00 }
> + },
> + /* pbits */
> + { },
> + /* primary indices */
> + {
> + 0x0, 0x0, 0x1, 0x2, /* subsets 0(a) 2 2 2 */
> + 0x1, 0x0, 0x1, 0x2, /* subsets 0 1(a) 1 1 */
> + 0x2, 0x3, 0x0, 0x0, /* subsets 0 1 1 1 */
> + 0x3, 0x3, 0x0, 0x0 /* subsets 0 2 2 2(a) */
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x00, 0x00, 0x00, 0xff, 0x00, 0x84, 0x84, 0xff,
> + 0x00, 0x7c, 0x7c, 0xff, 0x00, 0x73, 0x73, 0xff,
> + 0x54, 0x54, 0x54, 0xff, 0x08, 0x00, 0x08, 0xff,
> + 0x2b, 0x00, 0x2b, 0xff, 0x50, 0x00, 0x50, 0xff,
> + 0xab, 0xab, 0xab, 0xff, 0x73, 0x00, 0x73, 0xff,
> + 0x08, 0x00, 0x08, 0xff, 0x08, 0x00, 0x08, 0xff,
> + 0xff, 0xff, 0xff, 0xff, 0x00, 0x6b, 0x6b, 0xff,
> + 0x00, 0x84, 0x84, 0xff, 0x00, 0x84, 0x84, 0xff,
> + },
> + },
> + {
> + 3, /* mode */
> + 1, /* partition */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #000000ff #ffffffff */
> + { 0x00, 0x00, 0x00, 0x00 }, { 0x7f, 0x7f, 0x7f, 0x00 },
> + /* #840084ff #e101e1ff */
> + { 0x42, 0x00, 0x42, 0x00 }, { 0x70, 0x00, 0x70, 0x00 },
> + },
> + /* pbits */
> + { 0, 1, 0, 1 },
> + /* primary indices */
> + {
> + 0x0, 0x0, 0x0, 0x3, /* subsets 0(a) 0 0 1 */
> + 0x1, 0x1, 0x1, 0x2, /* subsets 0 0 0 1 */
> + 0x2, 0x2, 0x2, 0x1, /* subsets 0 0 0 1 */
> + 0x3, 0x3, 0x3, 0x0 /* subsets 0 0 0 1(a) */
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
> + 0x00, 0x00, 0x00, 0xff, 0xe1, 0x01, 0xe1, 0xff,
> + 0x54, 0x54, 0x54, 0xff, 0x54, 0x54, 0x54, 0xff,
> + 0x54, 0x54, 0x54, 0xff, 0xc2, 0x01, 0xc2, 0xff,
> + 0xab, 0xab, 0xab, 0xff, 0xab, 0xab, 0xab, 0xff,
> + 0xab, 0xab, 0xab, 0xff, 0xa3, 0x00, 0xa3, 0xff,
> + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
> + 0xff, 0xff, 0xff, 0xff, 0x84, 0x00, 0x84, 0xff,
> + },
> + },
> + {
> + 4, /* mode */
> + 0, /* partition (not used) */
> + 1, /* rotation */
> + 1, /* index selection */
> + /* endpoints */
> + {
> + /* #007bff41 #ff7b00ff */
> + { 0x00, 0x0f, 0x1f, 0x10 }, { 0x1f, 0x0f, 0x00, 0x3f },
> + },
> + /* pbits */
> + { },
> + /* primary indices */
> + {
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3
> + },
> + /* secondary indices */
> + {
> + 0x0, 0x1, 0x2, 0x3,
> + 0x4, 0x5, 0x6, 0x7,
> + 0x0, 0x1, 0x2, 0x3,
> + 0x4, 0x5, 0x6, 0x7
> + },
> + /* expected results */
> + {
> + 0x41, 0x7b, 0xff, 0x00, 0x7f, 0x7b, 0xdb, 0x24,
> + 0xc1, 0x7b, 0xb7, 0x48, 0xff, 0x7b, 0x93, 0x6c,
> + 0x41, 0x7b, 0x6c, 0x93, 0x7f, 0x7b, 0x48, 0xb7,
> + 0xc1, 0x7b, 0x24, 0xdb, 0xff, 0x7b, 0x00, 0xff,
> + 0x41, 0x7b, 0xff, 0x00, 0x7f, 0x7b, 0xdb, 0x24,
> + 0xc1, 0x7b, 0xb7, 0x48, 0xff, 0x7b, 0x93, 0x6c,
> + 0x41, 0x7b, 0x6c, 0x93, 0x7f, 0x7b, 0x48, 0xb7,
> + 0xc1, 0x7b, 0x24, 0xdb, 0xff, 0x7b, 0x00, 0xff,
> + },
> + },
> + {
> + 5, /* mode */
> + 0, /* partition (not used) */
> + 3, /* rotation */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #0081ff10 #ff8100ff */
> + { 0x00, 0x40, 0x7f, 0x10 }, { 0x7f, 0x40, 0x00, 0xff },
> + },
> + /* pbits */
> + { },
> + /* primary indices */
> + {
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3,
> + 0x0, 0x1, 0x2, 0x3
> + },
> + /* secondary indices */
> + {
> + 0x0, 0x0, 0x0, 0x0,
> + 0x1, 0x1, 0x1, 0x1,
> + 0x2, 0x2, 0x2, 0x2,
> + 0x3, 0x3, 0x3, 0x3
> + },
> + /* expected results */
> + {
> + 0x00, 0x81, 0x10, 0xff, 0x54, 0x81, 0x10, 0xab,
> + 0xab, 0x81, 0x10, 0x54, 0xff, 0x81, 0x10, 0x00,
> + 0x00, 0x81, 0x5e, 0xff, 0x54, 0x81, 0x5e, 0xab,
> + 0xab, 0x81, 0x5e, 0x54, 0xff, 0x81, 0x5e, 0x00,
> + 0x00, 0x81, 0xb1, 0xff, 0x54, 0x81, 0xb1, 0xab,
> + 0xab, 0x81, 0xb1, 0x54, 0xff, 0x81, 0xb1, 0x00,
> + 0x00, 0x81, 0xff, 0xff, 0x54, 0x81, 0xff, 0xab,
> + 0xab, 0x81, 0xff, 0x54, 0xff, 0x81, 0xff, 0x00,
> + },
> + },
> + {
> + 6, /* mode */
> + 0, /* partition (not used) */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #0181ff21 #fe8000fe */
> + { 0x00, 0x40, 0x7f, 0x10 }, { 0x7f, 0x40, 0x00, 0x7f },
> + },
> + /* pbits */
> + { 1, 0 },
> + /* primary indices */
> + {
> + 0x0, 0x1, 0x2, 0x3,
> + 0x4, 0x5, 0x6, 0x7,
> + 0x8, 0x9, 0xa, 0xb,
> + 0xc, 0xd, 0xe, 0xf
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x01, 0x81, 0xff, 0x21, 0x11, 0x81, 0xef, 0x2f,
> + 0x25, 0x81, 0xdb, 0x40, 0x34, 0x81, 0xcb, 0x4e,
> + 0x44, 0x81, 0xbb, 0x5c, 0x54, 0x81, 0xab, 0x6a,
> + 0x68, 0x81, 0x97, 0x7b, 0x78, 0x81, 0x87, 0x89,
> + 0x87, 0x80, 0x78, 0x96, 0x97, 0x80, 0x68, 0xa4,
> + 0xab, 0x80, 0x54, 0xb5, 0xbb, 0x80, 0x44, 0xc3,
> + 0xcb, 0x80, 0x34, 0xd1, 0xda, 0x80, 0x24, 0xdf,
> + 0xee, 0x80, 0x10, 0xf0, 0xfe, 0x80, 0x00, 0xfe,
> + },
> + },
> + {
> + 7, /* mode */
> + 8, /* partition */
> + 0, /* rotation (not used) */
> + 0, /* index selection (not used) */
> + /* endpoints */
> + {
> + /* #00000000 #ffffffff */
> + { 0x00, 0x00, 0x00, 0x00 }, { 0x1f, 0x1f, 0x1f, 0x1f },
> + /* #040c141c #fbf3ebe3 */
> + { 0x00, 0x01, 0x02, 0x03 }, { 0x1f, 0x1e, 0x1d, 0x1c },
> + },
> + /* pbits */
> + { 0, 1, 1, 0 },
> + /* primary indices */
> + {
> + 0x0, 0x1, 0x2, 0x3, /* subsets 0(a) 0 0 0 */
> + 0x0, 0x1, 0x2, 0x3, /* subsets 0 0 0 0 */
> + 0x0, 0x1, 0x2, 0x3, /* subsets 0 0 0 1 */
> + 0x0, 0x1, 0x1, 0x0 /* subsets 0 0 1 1(a) */
> + },
> + /* secondary indices */
> + { },
> + /* expected results */
> + {
> + 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x54, 0x54,
> + 0xab, 0xab, 0xab, 0xab, 0xff, 0xff, 0xff, 0xff,
> + 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x54, 0x54,
> + 0xab, 0xab, 0xab, 0xab, 0xff, 0xff, 0xff, 0xff,
> + 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x54, 0x54,
> + 0xab, 0xab, 0xab, 0xab, 0xfb, 0xf3, 0xeb, 0xe3,
> + 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x54, 0x54,
> + 0x55, 0x58, 0x5b, 0x5d, 0x04, 0x0c, 0x14, 0x1c,
> + },
> + },
> +};
> +
> +#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 void
> +write_component(uint8_t *out,
> + int *offset,
> + const struct bptc_block *block,
> + int component, int subset, int endpoint)
> +{
> + write_bits(out, offset,
> + block->endpoints[subset * 2 + endpoint][component],
> + bptc_modes[block->mode].n_color_bits);
> +}
> +
> +static bool
> +is_anchor(const struct bptc_block *block,
> + int texel)
> +{
> + if (texel == 0)
> + return true;
> +
> + switch (bptc_modes[block->mode].n_subsets) {
> + case 1:
> + return false;
> + case 2:
> + return anchor_indices[0][block->partition] == texel;
> + case 3:
> + return (anchor_indices[1][block->partition] == texel ||
> + anchor_indices[2][block->partition] == texel);
> + default:
> + assert(false);
> + return false;
> + }
> +}
> +
> +static void
> +make_block(const struct bptc_block *block,
> + uint8_t *out)
> +{
> + const struct bptc_mode *mode = bptc_modes + block->mode;
> + int offset = 0;
> + int component;
> + int subset;
> + int endpoint;
> + int n_bits;
> + int i;
> +
> + memset(out, 0, BLOCK_SIZE * BLOCK_SIZE);
> +
> + write_bits(out, &offset, 1 << block->mode, block->mode + 1);
> +
> + write_bits(out, &offset, block->partition, mode->n_partition_bits);
> +
> + write_bits(out, &offset, block->rotation,
> + mode->has_rotation_bits ? 2 : 0);
> +
> + write_bits(out, &offset, block->index_selection,
> + mode->has_index_selection_bit);
> +
> + for (component = 0; component < 3; component++) {
> + for (subset = 0; subset < mode->n_subsets; subset++) {
> + for (endpoint = 0; endpoint < 2; endpoint++) {
> + write_component(out, &offset, block,
> + component, subset, endpoint);
> + }
> + }
> + }
> +
> + for (subset = 0; subset < mode->n_subsets; subset++) {
> + for (endpoint = 0; endpoint < 2; endpoint++) {
> + write_bits(out, &offset,
> + block->endpoints[subset * 2 + endpoint][3],
> + mode->n_alpha_bits);
> + }
> + }
> +
> + for (subset = 0; subset < mode->n_subsets; subset++) {
> + for (endpoint = 0; endpoint < 2; endpoint++) {
> + write_bits(out, &offset,
> + block->pbits[subset * 2 + endpoint],
> + mode->has_endpoint_pbits);
> + }
> + }
> +
> + for (subset = 0; subset < mode->n_subsets; subset++) {
> + write_bits(out, &offset,
> + block->pbits[subset],
> + mode->has_shared_pbits);
> + }
> +
> + for (i = 0; i < BLOCK_SIZE * BLOCK_SIZE; i++) {
> + n_bits = mode->n_index_bits;
> +
> + if (is_anchor(block, i))
> + n_bits--;
> +
> + write_bits(out, &offset, block->primary_indices[i], n_bits);
> + }
> +
> + if (mode->n_secondary_index_bits) {
> + for (i = 0; i < BLOCK_SIZE * BLOCK_SIZE; i++) {
> + n_bits = mode->n_secondary_index_bits;
> +
> + if (is_anchor(block, i))
> + n_bits--;
> +
> + write_bits(out, &offset,
> + block->secondary_indices[i], n_bits);
> + }
> + }
> +
> + assert(offset == BLOCK_BYTES * 8);
> +}
> +
> +static GLuint
> +make_tex(void)
> +{
> + 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 */
> + GL_COMPRESSED_RGBA_BPTC_UNORM_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 uint8_t *expected,
> + const uint8_t *observed,
> + int observed_rowstride)
> +{
> + int y, x;
> +
> + for (y = 0; y < BLOCK_SIZE; y++) {
> + for (x = 0; x < BLOCK_SIZE; x++) {
> + if (memcmp(expected, observed, 4)) {
> + printf("Unexpected color at %i,%i:\n"
> + " expected %02x%02x%02x%02x\n"
> + " observed %02x%02x%02x%02x\n",
> + x, y,
> + expected[0], expected[1],
> + expected[2], expected[3],
> + observed[0], observed[1],
> + observed[2], observed[3]);
> + return false;
> + }
> + expected += 4;
> + observed += 4;
> + }
> +
> + observed += observed_rowstride - 4 * BLOCK_SIZE;
> + }
> +
> + return true;
> +}
> +
> +static void
> +render_texture(uint8_t *render_data,
> + uint8_t *get_data)
> +{
> + GLuint tex;
> +
> + tex = make_tex();
> +
> + glBindTexture(GL_TEXTURE_2D, tex);
> + glEnable(GL_TEXTURE_2D);
> +
> + piglit_draw_rect_tex(0, 0, 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);
> + glReadPixels(0, 0, BLOCK_SIZE * 2, BLOCK_SIZE * N_BLOCKS / 2,
> + GL_RGBA, GL_UNSIGNED_BYTE, render_data);
> +
> + glGetTexImage(GL_TEXTURE_2D,
> + 0, /* level */
> + GL_RGBA,
> + GL_UNSIGNED_BYTE,
> + get_data);
> +
> + glBindTexture(GL_TEXTURE_2D, 0);
> + glDeleteTextures(1, &tex);
> +}
> +
> +static GLboolean
> +check_block(const struct bptc_block *block,
> + const uint8_t *render_data,
> + const uint8_t *get_data)
> +{
> + GLboolean overall_result = GL_TRUE;
> + GLboolean pass;
> +
> + printf("mode %i, partition %i, rotation %i, index %i\n",
> + block->mode,
> + block->partition,
> + block->rotation,
> + block->index_selection);
> +
> + pass = compare_results(block->expected_values,
> + render_data,
> + BLOCK_SIZE * 2 * 4);
> + printf("render: %s\n", pass ? "pass" : "fail");
> +
> + overall_result &= pass;
> +
> + pass = compare_results(block->expected_values,
> + get_data,
> + BLOCK_SIZE * 2 * 4);
> + printf("glGetTexImage: %s\n", pass ? "pass" : "fail");
> +
> + overall_result &= pass;
> +
> + return overall_result;
> +}
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> + GLboolean pass = GL_TRUE;
> + uint8_t render_data[BLOCK_SIZE * BLOCK_SIZE * N_BLOCKS * 4];
> + uint8_t get_data[BLOCK_SIZE * BLOCK_SIZE * N_BLOCKS * 4];
> + int offset;
> + int i;
> +
> + glClearColor(0, 0, 0, 0);
> + glClear(GL_COLOR_BUFFER_BIT);
> +
> + render_texture(render_data, get_data);
> +
> + for (i = 0; i < N_BLOCKS; i++) {
> + offset = (i % 2 * BLOCK_SIZE * 4 +
> + i / 2 * BLOCK_SIZE * BLOCK_SIZE * 2 * 4);
> + pass &= check_block(bptc_blocks + i,
> + render_data + offset,
> + get_data + offset);
> + }
> +
> + 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);
> + }
> +
> + piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
> +}
> --
> 1.9.3
>
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit
More information about the Piglit
mailing list