1// SPDX-License-Identifier: Apache-2.0 2// ---------------------------------------------------------------------------- 3// Copyright 2023 Arm Limited 4// 5// Licensed under the Apache License, Version 2.0 (the "License"); you may not 6// use this file except in compliance with the License. You may obtain a copy 7// of the License at: 8// 9// http://www.apache.org/licenses/LICENSE-2.0 10// 11// Unless required by applicable law or agreed to in writing, software 12// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14// License for the specific language governing permissions and limitations 15// under the License. 16// ---------------------------------------------------------------------------- 17 18// astcenc doesn't use the top 8 integer bits directly for sRGB RGB components 19// or when using the decode_unorm8 decode mode. An alterantive is used which 20// allows a common code path to be used. This test program shows that the two 21// produce equivalent output once rounded to a decode_unorm8 output. 22 23// Compile with e.g. clang++ astcenc_u8_test_bench.cpp -o astcenc_u8_test_bench -mavx2 -mf16c 24 25#define ASTCENC_AVX 2 26#define ASTCENC_F16C 1 27#define ASTCENC_SSE 41 28 29#include "../Source/astcenc_mathlib.cpp" 30#include "../Source/astcenc_color_unquantize.cpp" 31#include "../Source/astcenc_decompress_symbolic.cpp" 32 33int main() 34{ 35 printf("Decode mode test bench\n"); 36 37 for (int ep0 = 0; ep0 < 256; ep0++) 38 { 39 for (int ep1 = 0; ep1 < 256; ep1++) 40 { 41 for (int wt1 = 0; wt1 < 65; wt1++) 42 { 43 // Validate linear data with decode_unorm8 mode 44 { 45 // Expand 8 bit to 16 bit 46 vint4 weights(wt1); 47 int ep0_v0 = ep0 * 257; 48 int ep1_v0 = ep1 * 257; 49 50 // Linear with decode_u8 handling 51 vmask4 decode_u8_v0(true, true, true, true); 52 vint4 ep0v0(ep0_v0, ep0_v0, ep0_v0, ep0_v0); 53 vint4 ep1v0(ep1_v0, ep1_v0, ep1_v0, ep1_v0); 54 55 // Linear without decode_u8 handling 56 vmask4 decode_u8_v1(false, false, false, false); 57 vint4 ep0v1(ep0_v0, ep0_v0, ep0_v0, ep0_v0); 58 vint4 ep1v1(ep1_v0, ep1_v0, ep1_v0, ep1_v0); 59 60 // Lerp both styles 61 vint4 colorv0 = lerp_color_int(decode_u8_v0, ep0v0, ep1v0, weights); 62 vint4 colorv1 = lerp_color_int(decode_u8_v1, ep0v1, ep1v1, weights); 63 64 // Validate top 8 integer bits match in both cases 65 // - Shows that astcenc-style U8 doesn't differ from Khronos-style U8 66 vint4 cs0 = lsr<8>(colorv0); 67 vint4 cs1 = lsr<8>(colorv1); 68 assert(cs0.lane<0>() == cs1.lane<0>()); 69 assert(cs0.lane<3>() == cs1.lane<3>()); 70 71 // Validate that astcenc output matches the top 8 integer bits 72 vfloat4 colorv0f = decode_texel(colorv0, vmask4(false)); 73 vint4 colorv0_out = float_to_int_rtn(colorv0f * 255.0f); 74 assert(colorv0_out.lane<0>() == cs0.lane<0>()); 75 } 76 77 // Validate sRGB data with decode_unorm8 mode 78 { 79 // Expand 8 bit to 16 bit 80 vint4 weights(wt1); 81 int ep0_v0s = (ep0 << 8) | 0x80; 82 int ep1_v0s = (ep1 << 8) | 0x80; 83 int ep0_v0 = ep0 * 257; 84 int ep1_v0 = ep1 * 257; 85 86 // sRGB RGB and linear A with decode_u8 handling 87 vmask4 decode_u8_v0(true, true, true, true); 88 vint4 ep0v0(ep0_v0s, ep0_v0s, ep0_v0s, ep0_v0); 89 vint4 ep1v0(ep1_v0s, ep1_v0s, ep1_v0s, ep1_v0); 90 91 // sRGB RGB and linear A without decode_u8 handling 92 vmask4 decode_u8_v1(false, false, false, false); 93 vint4 ep0v1(ep0_v0s, ep0_v0s, ep0_v0s, ep0_v0); 94 vint4 ep1v1(ep1_v0s, ep1_v0s, ep1_v0s, ep1_v0); 95 96 // Lerp both styles 97 vint4 colorv0 = lerp_color_int(decode_u8_v0, ep0v0, ep1v0, weights); 98 vint4 colorv1 = lerp_color_int(decode_u8_v1, ep0v1, ep1v1, weights); 99 100 // Validate top 8 integer bits match in both cases 101 // - Shows that astcenc-style U8 doesn't differ from Khronos-style U8 102 vint4 cs0 = lsr<8>(colorv0); 103 vint4 cs1 = lsr<8>(colorv1); 104 assert(cs0.lane<0>() == cs1.lane<0>()); 105 assert(cs0.lane<3>() == cs1.lane<3>()); 106 107 // Validate that astcenc output matches the top 8 integer bits 108 vfloat4 colorv0f = decode_texel(colorv0, vmask4(false)); 109 vint4 colorv0_out = float_to_int_rtn(colorv0f * 255.0f); 110 assert(colorv0_out.lane<0>() == cs0.lane<0>()); 111 } 112 } 113 } 114 } 115 116 return 0; 117} 118