[Piglit] [PATCH piglit] Add a test case for all of the modes of BPTC texture compression

Marek Olšák maraeo at gmail.com
Wed Jul 23 10:01:37 PDT 2014


Adding a new test for BPTC might be useful if want to test a feature
that isn't covered by other tests, because there already is a test
infrastructure for testing all OpenGL formats and it's just a matter
of adding BPTC support to existing tests. Mostly, just adding the new
formats to appropriate tables is enough. It would be a couple lines of
code and the feature coverage would be huge. The tests are:

1) All tests that include fbo-formats.h, however, only
fbo-generatemipmap-formats can be used to test compressed textures. It
reads the table from fbo-formats.h.
2) texwrap.c - there are tables at the beginning of the file.
3) compressedteximage.c - this one is simple and tests texture uploads
and downloads (not decompression though)
4) For glGetTexImage, you can fork rgtc-teximage-01.c
5) You might also need to update invalid-formats.c. I don't know the
test very well, but it looks useful.

Also, see the "ext_texture_compression_rgtc" section in all.py. The
new bptc section should look similar.

Marek


On Tue, Jul 22, 2014 at 8: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.
> ---
>  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