File: astcenc_u8_test_bench.cpp

package info (click to toggle)
astc-encoder 5.2.0%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 43,352 kB
  • sloc: ansic: 44,622; cpp: 24,142; python: 3,403; sh: 78; makefile: 24
file content (117 lines) | stat: -rw-r--r-- 5,185 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// SPDX-License-Identifier: Apache-2.0
// ----------------------------------------------------------------------------
// Copyright 2023 Arm Limited
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at:
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
// ----------------------------------------------------------------------------

// astcenc doesn't use the top 8 integer bits directly for sRGB RGB components
// or when using the decode_unorm8 decode mode. An alterantive is used which
// allows a common code path to be used. This test program shows that the two
// produce equivalent output once rounded to a decode_unorm8 output.

// Compile with e.g. clang++ astcenc_u8_test_bench.cpp -o astcenc_u8_test_bench -mavx2 -mf16c

#define ASTCENC_AVX 2
#define ASTCENC_F16C 1
#define ASTCENC_SSE 41

#include "../Source/astcenc_mathlib.cpp"
#include "../Source/astcenc_color_unquantize.cpp"
#include "../Source/astcenc_decompress_symbolic.cpp"

int main()
{
    printf("Decode mode test bench\n");

    for (int ep0 = 0; ep0 < 256; ep0++)
    {
        for (int ep1 = 0; ep1 < 256; ep1++)
        {
            for (int wt1 = 0; wt1 < 65; wt1++)
            {
                // Validate linear data with decode_unorm8 mode
                {
                    // Expand 8 bit to 16 bit
                    vint4 weights(wt1);
                    int ep0_v0 = ep0 * 257;
                    int ep1_v0 = ep1 * 257;

                    // Linear with decode_u8 handling
                    vmask4 decode_u8_v0(true, true, true, true);
                    vint4 ep0v0(ep0_v0, ep0_v0, ep0_v0, ep0_v0);
                    vint4 ep1v0(ep1_v0, ep1_v0, ep1_v0, ep1_v0);

                    // Linear without decode_u8 handling
                    vmask4 decode_u8_v1(false, false, false, false);
                    vint4 ep0v1(ep0_v0, ep0_v0, ep0_v0, ep0_v0);
                    vint4 ep1v1(ep1_v0, ep1_v0, ep1_v0, ep1_v0);

                    // Lerp both styles
                    vint4 colorv0 = lerp_color_int(decode_u8_v0, ep0v0, ep1v0, weights);
                    vint4 colorv1 = lerp_color_int(decode_u8_v1, ep0v1, ep1v1, weights);

                    // Validate top 8 integer bits match in both cases
                    //  - Shows that astcenc-style U8 doesn't differ from Khronos-style U8
                    vint4 cs0 = lsr<8>(colorv0);
                    vint4 cs1 = lsr<8>(colorv1);
                    assert(cs0.lane<0>() == cs1.lane<0>());
                    assert(cs0.lane<3>() == cs1.lane<3>());

                    // Validate that astcenc output matches the top 8 integer bits
                    vfloat4 colorv0f = decode_texel(colorv0, vmask4(false));
                    vint4 colorv0_out = float_to_int_rtn(colorv0f * 255.0f);
                    assert(colorv0_out.lane<0>() == cs0.lane<0>());
                }

                // Validate sRGB data with decode_unorm8 mode
                {
                    // Expand 8 bit to 16 bit
                    vint4 weights(wt1);
                    int ep0_v0s = (ep0 << 8) | 0x80;
                    int ep1_v0s = (ep1 << 8) | 0x80;
                    int ep0_v0 = ep0 * 257;
                    int ep1_v0 = ep1 * 257;

                    // sRGB RGB and linear A with decode_u8 handling
                    vmask4 decode_u8_v0(true, true, true, true);
                    vint4 ep0v0(ep0_v0s, ep0_v0s, ep0_v0s, ep0_v0);
                    vint4 ep1v0(ep1_v0s, ep1_v0s, ep1_v0s, ep1_v0);

                    // sRGB RGB and linear A without decode_u8 handling
                    vmask4 decode_u8_v1(false, false, false, false);
                    vint4 ep0v1(ep0_v0s, ep0_v0s, ep0_v0s, ep0_v0);
                    vint4 ep1v1(ep1_v0s, ep1_v0s, ep1_v0s, ep1_v0);

                    // Lerp both styles
                    vint4 colorv0 = lerp_color_int(decode_u8_v0, ep0v0, ep1v0, weights);
                    vint4 colorv1 = lerp_color_int(decode_u8_v1, ep0v1, ep1v1, weights);

                    // Validate top 8 integer bits match in both cases
                    //  - Shows that astcenc-style U8 doesn't differ from Khronos-style U8
                    vint4 cs0 = lsr<8>(colorv0);
                    vint4 cs1 = lsr<8>(colorv1);
                    assert(cs0.lane<0>() == cs1.lane<0>());
                    assert(cs0.lane<3>() == cs1.lane<3>());

                    // Validate that astcenc output matches the top 8 integer bits
                    vfloat4 colorv0f = decode_texel(colorv0, vmask4(false));
                    vint4 colorv0_out = float_to_int_rtn(colorv0f * 255.0f);
                    assert(colorv0_out.lane<0>() == cs0.lane<0>());
                }
            }
        }
    }

    return 0;
}