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 <[email protected]> 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 <[email protected]> > + * > + */ > + > +/** @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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/piglit _______________________________________________ Piglit mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/piglit
