1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * drawElements Quality Program Tester Core 3e5c31af7Sopenharmony_ci * ---------------------------------------- 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright 2016 The Android Open Source Project 6e5c31af7Sopenharmony_ci * 7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 10e5c31af7Sopenharmony_ci * 11e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 12e5c31af7Sopenharmony_ci * 13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 17e5c31af7Sopenharmony_ci * limitations under the License. 18e5c31af7Sopenharmony_ci * 19e5c31af7Sopenharmony_ci *//*! 20e5c31af7Sopenharmony_ci * \file 21e5c31af7Sopenharmony_ci * \brief ASTC Utilities. 22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 23e5c31af7Sopenharmony_ci 24e5c31af7Sopenharmony_ci#include "tcuAstcUtil.hpp" 25e5c31af7Sopenharmony_ci#include "deFloat16.h" 26e5c31af7Sopenharmony_ci#include "deRandom.hpp" 27e5c31af7Sopenharmony_ci#include "deMeta.hpp" 28e5c31af7Sopenharmony_ci 29e5c31af7Sopenharmony_ci#include <algorithm> 30e5c31af7Sopenharmony_ci 31e5c31af7Sopenharmony_cinamespace tcu 32e5c31af7Sopenharmony_ci{ 33e5c31af7Sopenharmony_cinamespace astc 34e5c31af7Sopenharmony_ci{ 35e5c31af7Sopenharmony_ci 36e5c31af7Sopenharmony_ciusing std::vector; 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_cinamespace 39e5c31af7Sopenharmony_ci{ 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci// Common utilities 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cienum 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_ci MAX_BLOCK_WIDTH = 12, 46e5c31af7Sopenharmony_ci MAX_BLOCK_HEIGHT = 12 47e5c31af7Sopenharmony_ci}; 48e5c31af7Sopenharmony_ci 49e5c31af7Sopenharmony_ciinline deUint32 getBit (deUint32 src, int ndx) 50e5c31af7Sopenharmony_ci{ 51e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(ndx, 0, 32)); 52e5c31af7Sopenharmony_ci return (src >> ndx) & 1; 53e5c31af7Sopenharmony_ci} 54e5c31af7Sopenharmony_ci 55e5c31af7Sopenharmony_ciinline deUint32 getBits (deUint32 src, int low, int high) 56e5c31af7Sopenharmony_ci{ 57e5c31af7Sopenharmony_ci const int numBits = (high-low) + 1; 58e5c31af7Sopenharmony_ci 59e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numBits, 1, 32)); 60e5c31af7Sopenharmony_ci 61e5c31af7Sopenharmony_ci if (numBits < 32) 62e5c31af7Sopenharmony_ci return (deUint32)((src >> low) & ((1u<<numBits)-1)); 63e5c31af7Sopenharmony_ci else 64e5c31af7Sopenharmony_ci return (deUint32)((src >> low) & 0xFFFFFFFFu); 65e5c31af7Sopenharmony_ci} 66e5c31af7Sopenharmony_ci 67e5c31af7Sopenharmony_ciinline bool isBitSet (deUint32 src, int ndx) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci return getBit(src, ndx) != 0; 70e5c31af7Sopenharmony_ci} 71e5c31af7Sopenharmony_ci 72e5c31af7Sopenharmony_ciinline deUint32 reverseBits (deUint32 src, int numBits) 73e5c31af7Sopenharmony_ci{ 74e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numBits, 0, 32)); 75e5c31af7Sopenharmony_ci deUint32 result = 0; 76e5c31af7Sopenharmony_ci for (int i = 0; i < numBits; i++) 77e5c31af7Sopenharmony_ci result |= ((src >> i) & 1) << (numBits-1-i); 78e5c31af7Sopenharmony_ci return result; 79e5c31af7Sopenharmony_ci} 80e5c31af7Sopenharmony_ci 81e5c31af7Sopenharmony_ciinline deUint32 bitReplicationScale (deUint32 src, int numSrcBits, int numDstBits) 82e5c31af7Sopenharmony_ci{ 83e5c31af7Sopenharmony_ci DE_ASSERT(numSrcBits <= numDstBits); 84e5c31af7Sopenharmony_ci DE_ASSERT((src & ((1<<numSrcBits)-1)) == src); 85e5c31af7Sopenharmony_ci deUint32 dst = 0; 86e5c31af7Sopenharmony_ci for (int shift = numDstBits-numSrcBits; shift > -numSrcBits; shift -= numSrcBits) 87e5c31af7Sopenharmony_ci dst |= shift >= 0 ? src << shift : src >> -shift; 88e5c31af7Sopenharmony_ci return dst; 89e5c31af7Sopenharmony_ci} 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ciinline deInt32 signExtend (deInt32 src, int numSrcBits) 92e5c31af7Sopenharmony_ci{ 93e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numSrcBits, 2, 31)); 94e5c31af7Sopenharmony_ci const bool negative = (src & (1 << (numSrcBits-1))) != 0; 95e5c31af7Sopenharmony_ci return src | (negative ? ~((1 << numSrcBits) - 1) : 0); 96e5c31af7Sopenharmony_ci} 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ciinline bool isFloat16InfOrNan (deFloat16 v) 99e5c31af7Sopenharmony_ci{ 100e5c31af7Sopenharmony_ci return getBits(v, 10, 14) == 31; 101e5c31af7Sopenharmony_ci} 102e5c31af7Sopenharmony_ci 103e5c31af7Sopenharmony_cienum ISEMode 104e5c31af7Sopenharmony_ci{ 105e5c31af7Sopenharmony_ci ISEMODE_TRIT = 0, 106e5c31af7Sopenharmony_ci ISEMODE_QUINT, 107e5c31af7Sopenharmony_ci ISEMODE_PLAIN_BIT, 108e5c31af7Sopenharmony_ci 109e5c31af7Sopenharmony_ci ISEMODE_LAST 110e5c31af7Sopenharmony_ci}; 111e5c31af7Sopenharmony_ci 112e5c31af7Sopenharmony_cistruct ISEParams 113e5c31af7Sopenharmony_ci{ 114e5c31af7Sopenharmony_ci ISEMode mode; 115e5c31af7Sopenharmony_ci int numBits; 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci ISEParams (ISEMode mode_, int numBits_) : mode(mode_), numBits(numBits_) {} 118e5c31af7Sopenharmony_ci}; 119e5c31af7Sopenharmony_ci 120e5c31af7Sopenharmony_ciinline int computeNumRequiredBits (const ISEParams& iseParams, int numValues) 121e5c31af7Sopenharmony_ci{ 122e5c31af7Sopenharmony_ci switch (iseParams.mode) 123e5c31af7Sopenharmony_ci { 124e5c31af7Sopenharmony_ci case ISEMODE_TRIT: return deDivRoundUp32(numValues*8, 5) + numValues*iseParams.numBits; 125e5c31af7Sopenharmony_ci case ISEMODE_QUINT: return deDivRoundUp32(numValues*7, 3) + numValues*iseParams.numBits; 126e5c31af7Sopenharmony_ci case ISEMODE_PLAIN_BIT: return numValues*iseParams.numBits; 127e5c31af7Sopenharmony_ci default: 128e5c31af7Sopenharmony_ci DE_ASSERT(false); 129e5c31af7Sopenharmony_ci return -1; 130e5c31af7Sopenharmony_ci } 131e5c31af7Sopenharmony_ci} 132e5c31af7Sopenharmony_ci 133e5c31af7Sopenharmony_ciISEParams computeMaximumRangeISEParams (int numAvailableBits, int numValuesInSequence) 134e5c31af7Sopenharmony_ci{ 135e5c31af7Sopenharmony_ci int curBitsForTritMode = 6; 136e5c31af7Sopenharmony_ci int curBitsForQuintMode = 5; 137e5c31af7Sopenharmony_ci int curBitsForPlainBitMode = 8; 138e5c31af7Sopenharmony_ci 139e5c31af7Sopenharmony_ci while (true) 140e5c31af7Sopenharmony_ci { 141e5c31af7Sopenharmony_ci DE_ASSERT(curBitsForTritMode > 0 || curBitsForQuintMode > 0 || curBitsForPlainBitMode > 0); 142e5c31af7Sopenharmony_ci 143e5c31af7Sopenharmony_ci const int tritRange = curBitsForTritMode > 0 ? (3 << curBitsForTritMode) - 1 : -1; 144e5c31af7Sopenharmony_ci const int quintRange = curBitsForQuintMode > 0 ? (5 << curBitsForQuintMode) - 1 : -1; 145e5c31af7Sopenharmony_ci const int plainBitRange = curBitsForPlainBitMode > 0 ? (1 << curBitsForPlainBitMode) - 1 : -1; 146e5c31af7Sopenharmony_ci const int maxRange = de::max(de::max(tritRange, quintRange), plainBitRange); 147e5c31af7Sopenharmony_ci 148e5c31af7Sopenharmony_ci if (maxRange == tritRange) 149e5c31af7Sopenharmony_ci { 150e5c31af7Sopenharmony_ci const ISEParams params(ISEMODE_TRIT, curBitsForTritMode); 151e5c31af7Sopenharmony_ci if (computeNumRequiredBits(params, numValuesInSequence) <= numAvailableBits) 152e5c31af7Sopenharmony_ci return ISEParams(ISEMODE_TRIT, curBitsForTritMode); 153e5c31af7Sopenharmony_ci curBitsForTritMode--; 154e5c31af7Sopenharmony_ci } 155e5c31af7Sopenharmony_ci else if (maxRange == quintRange) 156e5c31af7Sopenharmony_ci { 157e5c31af7Sopenharmony_ci const ISEParams params(ISEMODE_QUINT, curBitsForQuintMode); 158e5c31af7Sopenharmony_ci if (computeNumRequiredBits(params, numValuesInSequence) <= numAvailableBits) 159e5c31af7Sopenharmony_ci return ISEParams(ISEMODE_QUINT, curBitsForQuintMode); 160e5c31af7Sopenharmony_ci curBitsForQuintMode--; 161e5c31af7Sopenharmony_ci } 162e5c31af7Sopenharmony_ci else 163e5c31af7Sopenharmony_ci { 164e5c31af7Sopenharmony_ci const ISEParams params(ISEMODE_PLAIN_BIT, curBitsForPlainBitMode); 165e5c31af7Sopenharmony_ci DE_ASSERT(maxRange == plainBitRange); 166e5c31af7Sopenharmony_ci if (computeNumRequiredBits(params, numValuesInSequence) <= numAvailableBits) 167e5c31af7Sopenharmony_ci return ISEParams(ISEMODE_PLAIN_BIT, curBitsForPlainBitMode); 168e5c31af7Sopenharmony_ci curBitsForPlainBitMode--; 169e5c31af7Sopenharmony_ci } 170e5c31af7Sopenharmony_ci } 171e5c31af7Sopenharmony_ci} 172e5c31af7Sopenharmony_ci 173e5c31af7Sopenharmony_ciinline int computeNumColorEndpointValues (deUint32 endpointMode) 174e5c31af7Sopenharmony_ci{ 175e5c31af7Sopenharmony_ci DE_ASSERT(endpointMode < 16); 176e5c31af7Sopenharmony_ci return (endpointMode/4 + 1) * 2; 177e5c31af7Sopenharmony_ci} 178e5c31af7Sopenharmony_ci 179e5c31af7Sopenharmony_ci// Decompression utilities 180e5c31af7Sopenharmony_ci 181e5c31af7Sopenharmony_cienum DecompressResult 182e5c31af7Sopenharmony_ci{ 183e5c31af7Sopenharmony_ci DECOMPRESS_RESULT_VALID_BLOCK = 0, //!< Decompressed valid block 184e5c31af7Sopenharmony_ci DECOMPRESS_RESULT_ERROR, //!< Encountered error while decompressing, error color written 185e5c31af7Sopenharmony_ci 186e5c31af7Sopenharmony_ci DECOMPRESS_RESULT_LAST 187e5c31af7Sopenharmony_ci}; 188e5c31af7Sopenharmony_ci 189e5c31af7Sopenharmony_ci// A helper for getting bits from a 128-bit block. 190e5c31af7Sopenharmony_ciclass Block128 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ciprivate: 193e5c31af7Sopenharmony_ci typedef deUint64 Word; 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci enum 196e5c31af7Sopenharmony_ci { 197e5c31af7Sopenharmony_ci WORD_BYTES = sizeof(Word), 198e5c31af7Sopenharmony_ci WORD_BITS = 8*WORD_BYTES, 199e5c31af7Sopenharmony_ci NUM_WORDS = 128 / WORD_BITS 200e5c31af7Sopenharmony_ci }; 201e5c31af7Sopenharmony_ci 202e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(128 % WORD_BITS == 0); 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_cipublic: 205e5c31af7Sopenharmony_ci Block128 (const deUint8* src) 206e5c31af7Sopenharmony_ci { 207e5c31af7Sopenharmony_ci for (int wordNdx = 0; wordNdx < NUM_WORDS; wordNdx++) 208e5c31af7Sopenharmony_ci { 209e5c31af7Sopenharmony_ci m_words[wordNdx] = 0; 210e5c31af7Sopenharmony_ci for (int byteNdx = 0; byteNdx < WORD_BYTES; byteNdx++) 211e5c31af7Sopenharmony_ci m_words[wordNdx] |= (Word)src[wordNdx*WORD_BYTES + byteNdx] << (8*byteNdx); 212e5c31af7Sopenharmony_ci } 213e5c31af7Sopenharmony_ci } 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci deUint32 getBit (int ndx) const 216e5c31af7Sopenharmony_ci { 217e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(ndx, 0, 128)); 218e5c31af7Sopenharmony_ci return (m_words[ndx / WORD_BITS] >> (ndx % WORD_BITS)) & 1; 219e5c31af7Sopenharmony_ci } 220e5c31af7Sopenharmony_ci 221e5c31af7Sopenharmony_ci deUint32 getBits (int low, int high) const 222e5c31af7Sopenharmony_ci { 223e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(low, 0, 128)); 224e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(high, 0, 128)); 225e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(high-low+1, 0, 32)); 226e5c31af7Sopenharmony_ci 227e5c31af7Sopenharmony_ci if (high-low+1 == 0) 228e5c31af7Sopenharmony_ci return 0; 229e5c31af7Sopenharmony_ci 230e5c31af7Sopenharmony_ci const int word0Ndx = low / WORD_BITS; 231e5c31af7Sopenharmony_ci const int word1Ndx = high / WORD_BITS; 232e5c31af7Sopenharmony_ci 233e5c31af7Sopenharmony_ci // \note "foo << bar << 1" done instead of "foo << (bar+1)" to avoid overflow, i.e. shift amount being too big. 234e5c31af7Sopenharmony_ci 235e5c31af7Sopenharmony_ci if (word0Ndx == word1Ndx) 236e5c31af7Sopenharmony_ci return (deUint32)((m_words[word0Ndx] & ((((Word)1 << high%WORD_BITS << 1) - 1))) >> ((Word)low % WORD_BITS)); 237e5c31af7Sopenharmony_ci else 238e5c31af7Sopenharmony_ci { 239e5c31af7Sopenharmony_ci DE_ASSERT(word1Ndx == word0Ndx + 1); 240e5c31af7Sopenharmony_ci 241e5c31af7Sopenharmony_ci return (deUint32)(m_words[word0Ndx] >> (low%WORD_BITS)) | 242e5c31af7Sopenharmony_ci (deUint32)((m_words[word1Ndx] & (((Word)1 << high%WORD_BITS << 1) - 1)) << (high-low - high%WORD_BITS)); 243e5c31af7Sopenharmony_ci } 244e5c31af7Sopenharmony_ci } 245e5c31af7Sopenharmony_ci 246e5c31af7Sopenharmony_ci bool isBitSet (int ndx) const 247e5c31af7Sopenharmony_ci { 248e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(ndx, 0, 128)); 249e5c31af7Sopenharmony_ci return getBit(ndx) != 0; 250e5c31af7Sopenharmony_ci } 251e5c31af7Sopenharmony_ci 252e5c31af7Sopenharmony_ciprivate: 253e5c31af7Sopenharmony_ci Word m_words[NUM_WORDS]; 254e5c31af7Sopenharmony_ci}; 255e5c31af7Sopenharmony_ci 256e5c31af7Sopenharmony_ci// A helper for sequential access into a Block128. 257e5c31af7Sopenharmony_ciclass BitAccessStream 258e5c31af7Sopenharmony_ci{ 259e5c31af7Sopenharmony_cipublic: 260e5c31af7Sopenharmony_ci BitAccessStream (const Block128& src, int startNdxInSrc, int length, bool forward) 261e5c31af7Sopenharmony_ci : m_src (src) 262e5c31af7Sopenharmony_ci , m_startNdxInSrc (startNdxInSrc) 263e5c31af7Sopenharmony_ci , m_length (length) 264e5c31af7Sopenharmony_ci , m_forward (forward) 265e5c31af7Sopenharmony_ci , m_ndx (0) 266e5c31af7Sopenharmony_ci { 267e5c31af7Sopenharmony_ci } 268e5c31af7Sopenharmony_ci 269e5c31af7Sopenharmony_ci // Get the next num bits. Bits at positions greater than or equal to m_length are zeros. 270e5c31af7Sopenharmony_ci deUint32 getNext (int num) 271e5c31af7Sopenharmony_ci { 272e5c31af7Sopenharmony_ci if (num == 0 || m_ndx >= m_length) 273e5c31af7Sopenharmony_ci return 0; 274e5c31af7Sopenharmony_ci 275e5c31af7Sopenharmony_ci const int end = m_ndx + num; 276e5c31af7Sopenharmony_ci const int numBitsFromSrc = de::max(0, de::min(m_length, end) - m_ndx); 277e5c31af7Sopenharmony_ci const int low = m_ndx; 278e5c31af7Sopenharmony_ci const int high = m_ndx + numBitsFromSrc - 1; 279e5c31af7Sopenharmony_ci 280e5c31af7Sopenharmony_ci m_ndx += num; 281e5c31af7Sopenharmony_ci 282e5c31af7Sopenharmony_ci return m_forward ? m_src.getBits(m_startNdxInSrc + low, m_startNdxInSrc + high) 283e5c31af7Sopenharmony_ci : reverseBits(m_src.getBits(m_startNdxInSrc - high, m_startNdxInSrc - low), numBitsFromSrc); 284e5c31af7Sopenharmony_ci } 285e5c31af7Sopenharmony_ci 286e5c31af7Sopenharmony_ciprivate: 287e5c31af7Sopenharmony_ci const Block128& m_src; 288e5c31af7Sopenharmony_ci const int m_startNdxInSrc; 289e5c31af7Sopenharmony_ci const int m_length; 290e5c31af7Sopenharmony_ci const bool m_forward; 291e5c31af7Sopenharmony_ci 292e5c31af7Sopenharmony_ci int m_ndx; 293e5c31af7Sopenharmony_ci}; 294e5c31af7Sopenharmony_ci 295e5c31af7Sopenharmony_cistruct ISEDecodedResult 296e5c31af7Sopenharmony_ci{ 297e5c31af7Sopenharmony_ci deUint32 m; 298e5c31af7Sopenharmony_ci deUint32 tq; //!< Trit or quint value, depending on ISE mode. 299e5c31af7Sopenharmony_ci deUint32 v; 300e5c31af7Sopenharmony_ci}; 301e5c31af7Sopenharmony_ci 302e5c31af7Sopenharmony_ci// Data from an ASTC block's "block mode" part (i.e. bits [0,10]). 303e5c31af7Sopenharmony_cistruct ASTCBlockMode 304e5c31af7Sopenharmony_ci{ 305e5c31af7Sopenharmony_ci bool isError; 306e5c31af7Sopenharmony_ci // \note Following fields only relevant if !isError. 307e5c31af7Sopenharmony_ci bool isVoidExtent; 308e5c31af7Sopenharmony_ci // \note Following fields only relevant if !isVoidExtent. 309e5c31af7Sopenharmony_ci bool isDualPlane; 310e5c31af7Sopenharmony_ci int weightGridWidth; 311e5c31af7Sopenharmony_ci int weightGridHeight; 312e5c31af7Sopenharmony_ci ISEParams weightISEParams; 313e5c31af7Sopenharmony_ci 314e5c31af7Sopenharmony_ci ASTCBlockMode (void) 315e5c31af7Sopenharmony_ci : isError (true) 316e5c31af7Sopenharmony_ci , isVoidExtent (true) 317e5c31af7Sopenharmony_ci , isDualPlane (true) 318e5c31af7Sopenharmony_ci , weightGridWidth (-1) 319e5c31af7Sopenharmony_ci , weightGridHeight (-1) 320e5c31af7Sopenharmony_ci , weightISEParams (ISEMODE_LAST, -1) 321e5c31af7Sopenharmony_ci { 322e5c31af7Sopenharmony_ci } 323e5c31af7Sopenharmony_ci}; 324e5c31af7Sopenharmony_ci 325e5c31af7Sopenharmony_ciinline int computeNumWeights (const ASTCBlockMode& mode) 326e5c31af7Sopenharmony_ci{ 327e5c31af7Sopenharmony_ci return mode.weightGridWidth * mode.weightGridHeight * (mode.isDualPlane ? 2 : 1); 328e5c31af7Sopenharmony_ci} 329e5c31af7Sopenharmony_ci 330e5c31af7Sopenharmony_cistruct ColorEndpointPair 331e5c31af7Sopenharmony_ci{ 332e5c31af7Sopenharmony_ci UVec4 e0; 333e5c31af7Sopenharmony_ci UVec4 e1; 334e5c31af7Sopenharmony_ci}; 335e5c31af7Sopenharmony_ci 336e5c31af7Sopenharmony_cistruct TexelWeightPair 337e5c31af7Sopenharmony_ci{ 338e5c31af7Sopenharmony_ci deUint32 w[2]; 339e5c31af7Sopenharmony_ci}; 340e5c31af7Sopenharmony_ci 341e5c31af7Sopenharmony_ciASTCBlockMode getASTCBlockMode (deUint32 blockModeData) 342e5c31af7Sopenharmony_ci{ 343e5c31af7Sopenharmony_ci ASTCBlockMode blockMode; 344e5c31af7Sopenharmony_ci blockMode.isError = true; // \note Set to false later, if not error. 345e5c31af7Sopenharmony_ci 346e5c31af7Sopenharmony_ci blockMode.isVoidExtent = getBits(blockModeData, 0, 8) == 0x1fc; 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_ci if (!blockMode.isVoidExtent) 349e5c31af7Sopenharmony_ci { 350e5c31af7Sopenharmony_ci if ((getBits(blockModeData, 0, 1) == 0 && getBits(blockModeData, 6, 8) == 7) || getBits(blockModeData, 0, 3) == 0) 351e5c31af7Sopenharmony_ci return blockMode; // Invalid ("reserved"). 352e5c31af7Sopenharmony_ci 353e5c31af7Sopenharmony_ci deUint32 r = (deUint32)-1; // \note Set in the following branches. 354e5c31af7Sopenharmony_ci 355e5c31af7Sopenharmony_ci if (getBits(blockModeData, 0, 1) == 0) 356e5c31af7Sopenharmony_ci { 357e5c31af7Sopenharmony_ci const deUint32 r0 = getBit(blockModeData, 4); 358e5c31af7Sopenharmony_ci const deUint32 r1 = getBit(blockModeData, 2); 359e5c31af7Sopenharmony_ci const deUint32 r2 = getBit(blockModeData, 3); 360e5c31af7Sopenharmony_ci const deUint32 i78 = getBits(blockModeData, 7, 8); 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci r = (r2 << 2) | (r1 << 1) | (r0 << 0); 363e5c31af7Sopenharmony_ci 364e5c31af7Sopenharmony_ci if (i78 == 3) 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci const bool i5 = isBitSet(blockModeData, 5); 367e5c31af7Sopenharmony_ci blockMode.weightGridWidth = i5 ? 10 : 6; 368e5c31af7Sopenharmony_ci blockMode.weightGridHeight = i5 ? 6 : 10; 369e5c31af7Sopenharmony_ci } 370e5c31af7Sopenharmony_ci else 371e5c31af7Sopenharmony_ci { 372e5c31af7Sopenharmony_ci const deUint32 a = getBits(blockModeData, 5, 6); 373e5c31af7Sopenharmony_ci switch (i78) 374e5c31af7Sopenharmony_ci { 375e5c31af7Sopenharmony_ci case 0: blockMode.weightGridWidth = 12; blockMode.weightGridHeight = a + 2; break; 376e5c31af7Sopenharmony_ci case 1: blockMode.weightGridWidth = a + 2; blockMode.weightGridHeight = 12; break; 377e5c31af7Sopenharmony_ci case 2: blockMode.weightGridWidth = a + 6; blockMode.weightGridHeight = getBits(blockModeData, 9, 10) + 6; break; 378e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 379e5c31af7Sopenharmony_ci } 380e5c31af7Sopenharmony_ci } 381e5c31af7Sopenharmony_ci } 382e5c31af7Sopenharmony_ci else 383e5c31af7Sopenharmony_ci { 384e5c31af7Sopenharmony_ci const deUint32 r0 = getBit(blockModeData, 4); 385e5c31af7Sopenharmony_ci const deUint32 r1 = getBit(blockModeData, 0); 386e5c31af7Sopenharmony_ci const deUint32 r2 = getBit(blockModeData, 1); 387e5c31af7Sopenharmony_ci const deUint32 i23 = getBits(blockModeData, 2, 3); 388e5c31af7Sopenharmony_ci const deUint32 a = getBits(blockModeData, 5, 6); 389e5c31af7Sopenharmony_ci 390e5c31af7Sopenharmony_ci r = (r2 << 2) | (r1 << 1) | (r0 << 0); 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_ci if (i23 == 3) 393e5c31af7Sopenharmony_ci { 394e5c31af7Sopenharmony_ci const deUint32 b = getBit(blockModeData, 7); 395e5c31af7Sopenharmony_ci const bool i8 = isBitSet(blockModeData, 8); 396e5c31af7Sopenharmony_ci blockMode.weightGridWidth = i8 ? b+2 : a+2; 397e5c31af7Sopenharmony_ci blockMode.weightGridHeight = i8 ? a+2 : b+6; 398e5c31af7Sopenharmony_ci } 399e5c31af7Sopenharmony_ci else 400e5c31af7Sopenharmony_ci { 401e5c31af7Sopenharmony_ci const deUint32 b = getBits(blockModeData, 7, 8); 402e5c31af7Sopenharmony_ci 403e5c31af7Sopenharmony_ci switch (i23) 404e5c31af7Sopenharmony_ci { 405e5c31af7Sopenharmony_ci case 0: blockMode.weightGridWidth = b + 4; blockMode.weightGridHeight = a + 2; break; 406e5c31af7Sopenharmony_ci case 1: blockMode.weightGridWidth = b + 8; blockMode.weightGridHeight = a + 2; break; 407e5c31af7Sopenharmony_ci case 2: blockMode.weightGridWidth = a + 2; blockMode.weightGridHeight = b + 8; break; 408e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 409e5c31af7Sopenharmony_ci } 410e5c31af7Sopenharmony_ci } 411e5c31af7Sopenharmony_ci } 412e5c31af7Sopenharmony_ci 413e5c31af7Sopenharmony_ci const bool zeroDH = getBits(blockModeData, 0, 1) == 0 && getBits(blockModeData, 7, 8) == 2; 414e5c31af7Sopenharmony_ci const bool h = zeroDH ? 0 : isBitSet(blockModeData, 9); 415e5c31af7Sopenharmony_ci blockMode.isDualPlane = zeroDH ? 0 : isBitSet(blockModeData, 10); 416e5c31af7Sopenharmony_ci 417e5c31af7Sopenharmony_ci { 418e5c31af7Sopenharmony_ci ISEMode& m = blockMode.weightISEParams.mode; 419e5c31af7Sopenharmony_ci int& b = blockMode.weightISEParams.numBits; 420e5c31af7Sopenharmony_ci m = ISEMODE_PLAIN_BIT; 421e5c31af7Sopenharmony_ci b = 0; 422e5c31af7Sopenharmony_ci 423e5c31af7Sopenharmony_ci if (h) 424e5c31af7Sopenharmony_ci { 425e5c31af7Sopenharmony_ci switch (r) 426e5c31af7Sopenharmony_ci { 427e5c31af7Sopenharmony_ci case 2: m = ISEMODE_QUINT; b = 1; break; 428e5c31af7Sopenharmony_ci case 3: m = ISEMODE_TRIT; b = 2; break; 429e5c31af7Sopenharmony_ci case 4: b = 4; break; 430e5c31af7Sopenharmony_ci case 5: m = ISEMODE_QUINT; b = 2; break; 431e5c31af7Sopenharmony_ci case 6: m = ISEMODE_TRIT; b = 3; break; 432e5c31af7Sopenharmony_ci case 7: b = 5; break; 433e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 434e5c31af7Sopenharmony_ci } 435e5c31af7Sopenharmony_ci } 436e5c31af7Sopenharmony_ci else 437e5c31af7Sopenharmony_ci { 438e5c31af7Sopenharmony_ci switch (r) 439e5c31af7Sopenharmony_ci { 440e5c31af7Sopenharmony_ci case 2: b = 1; break; 441e5c31af7Sopenharmony_ci case 3: m = ISEMODE_TRIT; break; 442e5c31af7Sopenharmony_ci case 4: b = 2; break; 443e5c31af7Sopenharmony_ci case 5: m = ISEMODE_QUINT; break; 444e5c31af7Sopenharmony_ci case 6: m = ISEMODE_TRIT; b = 1; break; 445e5c31af7Sopenharmony_ci case 7: b = 3; break; 446e5c31af7Sopenharmony_ci default: DE_ASSERT(false); 447e5c31af7Sopenharmony_ci } 448e5c31af7Sopenharmony_ci } 449e5c31af7Sopenharmony_ci } 450e5c31af7Sopenharmony_ci } 451e5c31af7Sopenharmony_ci 452e5c31af7Sopenharmony_ci blockMode.isError = false; 453e5c31af7Sopenharmony_ci return blockMode; 454e5c31af7Sopenharmony_ci} 455e5c31af7Sopenharmony_ci 456e5c31af7Sopenharmony_ciinline void setASTCErrorColorBlock (void* dst, int blockWidth, int blockHeight, bool isSRGB) 457e5c31af7Sopenharmony_ci{ 458e5c31af7Sopenharmony_ci if (isSRGB) 459e5c31af7Sopenharmony_ci { 460e5c31af7Sopenharmony_ci deUint8* const dstU = (deUint8*)dst; 461e5c31af7Sopenharmony_ci 462e5c31af7Sopenharmony_ci for (int i = 0; i < blockWidth*blockHeight; i++) 463e5c31af7Sopenharmony_ci { 464e5c31af7Sopenharmony_ci dstU[4*i + 0] = 0xff; 465e5c31af7Sopenharmony_ci dstU[4*i + 1] = 0; 466e5c31af7Sopenharmony_ci dstU[4*i + 2] = 0xff; 467e5c31af7Sopenharmony_ci dstU[4*i + 3] = 0xff; 468e5c31af7Sopenharmony_ci } 469e5c31af7Sopenharmony_ci } 470e5c31af7Sopenharmony_ci else 471e5c31af7Sopenharmony_ci { 472e5c31af7Sopenharmony_ci float* const dstF = (float*)dst; 473e5c31af7Sopenharmony_ci 474e5c31af7Sopenharmony_ci for (int i = 0; i < blockWidth*blockHeight; i++) 475e5c31af7Sopenharmony_ci { 476e5c31af7Sopenharmony_ci dstF[4*i + 0] = 1.0f; 477e5c31af7Sopenharmony_ci dstF[4*i + 1] = 0.0f; 478e5c31af7Sopenharmony_ci dstF[4*i + 2] = 1.0f; 479e5c31af7Sopenharmony_ci dstF[4*i + 3] = 1.0f; 480e5c31af7Sopenharmony_ci } 481e5c31af7Sopenharmony_ci } 482e5c31af7Sopenharmony_ci} 483e5c31af7Sopenharmony_ci 484e5c31af7Sopenharmony_ciDecompressResult decodeVoidExtentBlock (void* dst, const Block128& blockData, int blockWidth, int blockHeight, bool isSRGB, bool isLDRMode) 485e5c31af7Sopenharmony_ci{ 486e5c31af7Sopenharmony_ci const deUint32 minSExtent = blockData.getBits(12, 24); 487e5c31af7Sopenharmony_ci const deUint32 maxSExtent = blockData.getBits(25, 37); 488e5c31af7Sopenharmony_ci const deUint32 minTExtent = blockData.getBits(38, 50); 489e5c31af7Sopenharmony_ci const deUint32 maxTExtent = blockData.getBits(51, 63); 490e5c31af7Sopenharmony_ci const bool allExtentsAllOnes = minSExtent == 0x1fff && maxSExtent == 0x1fff && minTExtent == 0x1fff && maxTExtent == 0x1fff; 491e5c31af7Sopenharmony_ci const bool isHDRBlock = blockData.isBitSet(9); 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci if ((isLDRMode && isHDRBlock) || (!allExtentsAllOnes && (minSExtent >= maxSExtent || minTExtent >= maxTExtent))) 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci setASTCErrorColorBlock(dst, blockWidth, blockHeight, isSRGB); 496e5c31af7Sopenharmony_ci return DECOMPRESS_RESULT_ERROR; 497e5c31af7Sopenharmony_ci } 498e5c31af7Sopenharmony_ci 499e5c31af7Sopenharmony_ci const deUint32 rgba[4] = 500e5c31af7Sopenharmony_ci { 501e5c31af7Sopenharmony_ci blockData.getBits(64, 79), 502e5c31af7Sopenharmony_ci blockData.getBits(80, 95), 503e5c31af7Sopenharmony_ci blockData.getBits(96, 111), 504e5c31af7Sopenharmony_ci blockData.getBits(112, 127) 505e5c31af7Sopenharmony_ci }; 506e5c31af7Sopenharmony_ci 507e5c31af7Sopenharmony_ci if (isSRGB) 508e5c31af7Sopenharmony_ci { 509e5c31af7Sopenharmony_ci deUint8* const dstU = (deUint8*)dst; 510e5c31af7Sopenharmony_ci for (int i = 0; i < blockWidth*blockHeight; i++) 511e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 512e5c31af7Sopenharmony_ci dstU[i*4 + c] = (deUint8)((rgba[c] & 0xff00) >> 8); 513e5c31af7Sopenharmony_ci } 514e5c31af7Sopenharmony_ci else 515e5c31af7Sopenharmony_ci { 516e5c31af7Sopenharmony_ci float* const dstF = (float*)dst; 517e5c31af7Sopenharmony_ci 518e5c31af7Sopenharmony_ci if (isHDRBlock) 519e5c31af7Sopenharmony_ci { 520e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 521e5c31af7Sopenharmony_ci { 522e5c31af7Sopenharmony_ci if (isFloat16InfOrNan((deFloat16)rgba[c])) 523e5c31af7Sopenharmony_ci throw InternalError("Infinity or NaN color component in HDR void extent block in ASTC texture (behavior undefined by ASTC specification)"); 524e5c31af7Sopenharmony_ci } 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci for (int i = 0; i < blockWidth*blockHeight; i++) 527e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 528e5c31af7Sopenharmony_ci dstF[i*4 + c] = deFloat16To32((deFloat16)rgba[c]); 529e5c31af7Sopenharmony_ci } 530e5c31af7Sopenharmony_ci else 531e5c31af7Sopenharmony_ci { 532e5c31af7Sopenharmony_ci for (int i = 0; i < blockWidth*blockHeight; i++) 533e5c31af7Sopenharmony_ci for (int c = 0; c < 4; c++) 534e5c31af7Sopenharmony_ci dstF[i*4 + c] = rgba[c] == 65535 ? 1.0f : (float)rgba[c] / 65536.0f; 535e5c31af7Sopenharmony_ci } 536e5c31af7Sopenharmony_ci } 537e5c31af7Sopenharmony_ci 538e5c31af7Sopenharmony_ci return DECOMPRESS_RESULT_VALID_BLOCK; 539e5c31af7Sopenharmony_ci} 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_civoid decodeColorEndpointModes (deUint32* endpointModesDst, const Block128& blockData, int numPartitions, int extraCemBitsStart) 542e5c31af7Sopenharmony_ci{ 543e5c31af7Sopenharmony_ci if (numPartitions == 1) 544e5c31af7Sopenharmony_ci endpointModesDst[0] = blockData.getBits(13, 16); 545e5c31af7Sopenharmony_ci else 546e5c31af7Sopenharmony_ci { 547e5c31af7Sopenharmony_ci const deUint32 highLevelSelector = blockData.getBits(23, 24); 548e5c31af7Sopenharmony_ci 549e5c31af7Sopenharmony_ci if (highLevelSelector == 0) 550e5c31af7Sopenharmony_ci { 551e5c31af7Sopenharmony_ci const deUint32 mode = blockData.getBits(25, 28); 552e5c31af7Sopenharmony_ci for (int i = 0; i < numPartitions; i++) 553e5c31af7Sopenharmony_ci endpointModesDst[i] = mode; 554e5c31af7Sopenharmony_ci } 555e5c31af7Sopenharmony_ci else 556e5c31af7Sopenharmony_ci { 557e5c31af7Sopenharmony_ci for (int partNdx = 0; partNdx < numPartitions; partNdx++) 558e5c31af7Sopenharmony_ci { 559e5c31af7Sopenharmony_ci const deUint32 cemClass = highLevelSelector - (blockData.isBitSet(25 + partNdx) ? 0 : 1); 560e5c31af7Sopenharmony_ci const deUint32 lowBit0Ndx = numPartitions + 2*partNdx; 561e5c31af7Sopenharmony_ci const deUint32 lowBit1Ndx = numPartitions + 2*partNdx + 1; 562e5c31af7Sopenharmony_ci const deUint32 lowBit0 = blockData.getBit(lowBit0Ndx < 4 ? 25+lowBit0Ndx : extraCemBitsStart+lowBit0Ndx-4); 563e5c31af7Sopenharmony_ci const deUint32 lowBit1 = blockData.getBit(lowBit1Ndx < 4 ? 25+lowBit1Ndx : extraCemBitsStart+lowBit1Ndx-4); 564e5c31af7Sopenharmony_ci 565e5c31af7Sopenharmony_ci endpointModesDst[partNdx] = (cemClass << 2) | (lowBit1 << 1) | lowBit0; 566e5c31af7Sopenharmony_ci } 567e5c31af7Sopenharmony_ci } 568e5c31af7Sopenharmony_ci } 569e5c31af7Sopenharmony_ci} 570e5c31af7Sopenharmony_ci 571e5c31af7Sopenharmony_ciint computeNumColorEndpointValues (const deUint32* endpointModes, int numPartitions) 572e5c31af7Sopenharmony_ci{ 573e5c31af7Sopenharmony_ci int result = 0; 574e5c31af7Sopenharmony_ci for (int i = 0; i < numPartitions; i++) 575e5c31af7Sopenharmony_ci result += computeNumColorEndpointValues(endpointModes[i]); 576e5c31af7Sopenharmony_ci return result; 577e5c31af7Sopenharmony_ci} 578e5c31af7Sopenharmony_ci 579e5c31af7Sopenharmony_civoid decodeISETritBlock (ISEDecodedResult* dst, int numValues, BitAccessStream& data, int numBits) 580e5c31af7Sopenharmony_ci{ 581e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numValues, 1, 5)); 582e5c31af7Sopenharmony_ci 583e5c31af7Sopenharmony_ci deUint32 m[5]; 584e5c31af7Sopenharmony_ci 585e5c31af7Sopenharmony_ci m[0] = data.getNext(numBits); 586e5c31af7Sopenharmony_ci deUint32 T01 = data.getNext(2); 587e5c31af7Sopenharmony_ci m[1] = data.getNext(numBits); 588e5c31af7Sopenharmony_ci deUint32 T23 = data.getNext(2); 589e5c31af7Sopenharmony_ci m[2] = data.getNext(numBits); 590e5c31af7Sopenharmony_ci deUint32 T4 = data.getNext(1); 591e5c31af7Sopenharmony_ci m[3] = data.getNext(numBits); 592e5c31af7Sopenharmony_ci deUint32 T56 = data.getNext(2); 593e5c31af7Sopenharmony_ci m[4] = data.getNext(numBits); 594e5c31af7Sopenharmony_ci deUint32 T7 = data.getNext(1); 595e5c31af7Sopenharmony_ci 596e5c31af7Sopenharmony_ci switch (numValues) 597e5c31af7Sopenharmony_ci { 598e5c31af7Sopenharmony_ci case 1: 599e5c31af7Sopenharmony_ci T23 = 0; 600e5c31af7Sopenharmony_ci // Fallthrough 601e5c31af7Sopenharmony_ci case 2: 602e5c31af7Sopenharmony_ci T4 = 0; 603e5c31af7Sopenharmony_ci // Fallthrough 604e5c31af7Sopenharmony_ci case 3: 605e5c31af7Sopenharmony_ci T56 = 0; 606e5c31af7Sopenharmony_ci // Fallthrough 607e5c31af7Sopenharmony_ci case 4: 608e5c31af7Sopenharmony_ci T7 = 0; 609e5c31af7Sopenharmony_ci // Fallthrough 610e5c31af7Sopenharmony_ci case 5: 611e5c31af7Sopenharmony_ci break; 612e5c31af7Sopenharmony_ci default: 613e5c31af7Sopenharmony_ci DE_ASSERT(false); 614e5c31af7Sopenharmony_ci } 615e5c31af7Sopenharmony_ci 616e5c31af7Sopenharmony_ci const deUint32 T = (T7 << 7) | (T56 << 5) | (T4 << 4) | (T23 << 2) | (T01 << 0); 617e5c31af7Sopenharmony_ci 618e5c31af7Sopenharmony_ci static const deUint32 tritsFromT[256][5] = 619e5c31af7Sopenharmony_ci { 620e5c31af7Sopenharmony_ci { 0,0,0,0,0 }, { 1,0,0,0,0 }, { 2,0,0,0,0 }, { 0,0,2,0,0 }, { 0,1,0,0,0 }, { 1,1,0,0,0 }, { 2,1,0,0,0 }, { 1,0,2,0,0 }, { 0,2,0,0,0 }, { 1,2,0,0,0 }, { 2,2,0,0,0 }, { 2,0,2,0,0 }, { 0,2,2,0,0 }, { 1,2,2,0,0 }, { 2,2,2,0,0 }, { 2,0,2,0,0 }, 621e5c31af7Sopenharmony_ci { 0,0,1,0,0 }, { 1,0,1,0,0 }, { 2,0,1,0,0 }, { 0,1,2,0,0 }, { 0,1,1,0,0 }, { 1,1,1,0,0 }, { 2,1,1,0,0 }, { 1,1,2,0,0 }, { 0,2,1,0,0 }, { 1,2,1,0,0 }, { 2,2,1,0,0 }, { 2,1,2,0,0 }, { 0,0,0,2,2 }, { 1,0,0,2,2 }, { 2,0,0,2,2 }, { 0,0,2,2,2 }, 622e5c31af7Sopenharmony_ci { 0,0,0,1,0 }, { 1,0,0,1,0 }, { 2,0,0,1,0 }, { 0,0,2,1,0 }, { 0,1,0,1,0 }, { 1,1,0,1,0 }, { 2,1,0,1,0 }, { 1,0,2,1,0 }, { 0,2,0,1,0 }, { 1,2,0,1,0 }, { 2,2,0,1,0 }, { 2,0,2,1,0 }, { 0,2,2,1,0 }, { 1,2,2,1,0 }, { 2,2,2,1,0 }, { 2,0,2,1,0 }, 623e5c31af7Sopenharmony_ci { 0,0,1,1,0 }, { 1,0,1,1,0 }, { 2,0,1,1,0 }, { 0,1,2,1,0 }, { 0,1,1,1,0 }, { 1,1,1,1,0 }, { 2,1,1,1,0 }, { 1,1,2,1,0 }, { 0,2,1,1,0 }, { 1,2,1,1,0 }, { 2,2,1,1,0 }, { 2,1,2,1,0 }, { 0,1,0,2,2 }, { 1,1,0,2,2 }, { 2,1,0,2,2 }, { 1,0,2,2,2 }, 624e5c31af7Sopenharmony_ci { 0,0,0,2,0 }, { 1,0,0,2,0 }, { 2,0,0,2,0 }, { 0,0,2,2,0 }, { 0,1,0,2,0 }, { 1,1,0,2,0 }, { 2,1,0,2,0 }, { 1,0,2,2,0 }, { 0,2,0,2,0 }, { 1,2,0,2,0 }, { 2,2,0,2,0 }, { 2,0,2,2,0 }, { 0,2,2,2,0 }, { 1,2,2,2,0 }, { 2,2,2,2,0 }, { 2,0,2,2,0 }, 625e5c31af7Sopenharmony_ci { 0,0,1,2,0 }, { 1,0,1,2,0 }, { 2,0,1,2,0 }, { 0,1,2,2,0 }, { 0,1,1,2,0 }, { 1,1,1,2,0 }, { 2,1,1,2,0 }, { 1,1,2,2,0 }, { 0,2,1,2,0 }, { 1,2,1,2,0 }, { 2,2,1,2,0 }, { 2,1,2,2,0 }, { 0,2,0,2,2 }, { 1,2,0,2,2 }, { 2,2,0,2,2 }, { 2,0,2,2,2 }, 626e5c31af7Sopenharmony_ci { 0,0,0,0,2 }, { 1,0,0,0,2 }, { 2,0,0,0,2 }, { 0,0,2,0,2 }, { 0,1,0,0,2 }, { 1,1,0,0,2 }, { 2,1,0,0,2 }, { 1,0,2,0,2 }, { 0,2,0,0,2 }, { 1,2,0,0,2 }, { 2,2,0,0,2 }, { 2,0,2,0,2 }, { 0,2,2,0,2 }, { 1,2,2,0,2 }, { 2,2,2,0,2 }, { 2,0,2,0,2 }, 627e5c31af7Sopenharmony_ci { 0,0,1,0,2 }, { 1,0,1,0,2 }, { 2,0,1,0,2 }, { 0,1,2,0,2 }, { 0,1,1,0,2 }, { 1,1,1,0,2 }, { 2,1,1,0,2 }, { 1,1,2,0,2 }, { 0,2,1,0,2 }, { 1,2,1,0,2 }, { 2,2,1,0,2 }, { 2,1,2,0,2 }, { 0,2,2,2,2 }, { 1,2,2,2,2 }, { 2,2,2,2,2 }, { 2,0,2,2,2 }, 628e5c31af7Sopenharmony_ci { 0,0,0,0,1 }, { 1,0,0,0,1 }, { 2,0,0,0,1 }, { 0,0,2,0,1 }, { 0,1,0,0,1 }, { 1,1,0,0,1 }, { 2,1,0,0,1 }, { 1,0,2,0,1 }, { 0,2,0,0,1 }, { 1,2,0,0,1 }, { 2,2,0,0,1 }, { 2,0,2,0,1 }, { 0,2,2,0,1 }, { 1,2,2,0,1 }, { 2,2,2,0,1 }, { 2,0,2,0,1 }, 629e5c31af7Sopenharmony_ci { 0,0,1,0,1 }, { 1,0,1,0,1 }, { 2,0,1,0,1 }, { 0,1,2,0,1 }, { 0,1,1,0,1 }, { 1,1,1,0,1 }, { 2,1,1,0,1 }, { 1,1,2,0,1 }, { 0,2,1,0,1 }, { 1,2,1,0,1 }, { 2,2,1,0,1 }, { 2,1,2,0,1 }, { 0,0,1,2,2 }, { 1,0,1,2,2 }, { 2,0,1,2,2 }, { 0,1,2,2,2 }, 630e5c31af7Sopenharmony_ci { 0,0,0,1,1 }, { 1,0,0,1,1 }, { 2,0,0,1,1 }, { 0,0,2,1,1 }, { 0,1,0,1,1 }, { 1,1,0,1,1 }, { 2,1,0,1,1 }, { 1,0,2,1,1 }, { 0,2,0,1,1 }, { 1,2,0,1,1 }, { 2,2,0,1,1 }, { 2,0,2,1,1 }, { 0,2,2,1,1 }, { 1,2,2,1,1 }, { 2,2,2,1,1 }, { 2,0,2,1,1 }, 631e5c31af7Sopenharmony_ci { 0,0,1,1,1 }, { 1,0,1,1,1 }, { 2,0,1,1,1 }, { 0,1,2,1,1 }, { 0,1,1,1,1 }, { 1,1,1,1,1 }, { 2,1,1,1,1 }, { 1,1,2,1,1 }, { 0,2,1,1,1 }, { 1,2,1,1,1 }, { 2,2,1,1,1 }, { 2,1,2,1,1 }, { 0,1,1,2,2 }, { 1,1,1,2,2 }, { 2,1,1,2,2 }, { 1,1,2,2,2 }, 632e5c31af7Sopenharmony_ci { 0,0,0,2,1 }, { 1,0,0,2,1 }, { 2,0,0,2,1 }, { 0,0,2,2,1 }, { 0,1,0,2,1 }, { 1,1,0,2,1 }, { 2,1,0,2,1 }, { 1,0,2,2,1 }, { 0,2,0,2,1 }, { 1,2,0,2,1 }, { 2,2,0,2,1 }, { 2,0,2,2,1 }, { 0,2,2,2,1 }, { 1,2,2,2,1 }, { 2,2,2,2,1 }, { 2,0,2,2,1 }, 633e5c31af7Sopenharmony_ci { 0,0,1,2,1 }, { 1,0,1,2,1 }, { 2,0,1,2,1 }, { 0,1,2,2,1 }, { 0,1,1,2,1 }, { 1,1,1,2,1 }, { 2,1,1,2,1 }, { 1,1,2,2,1 }, { 0,2,1,2,1 }, { 1,2,1,2,1 }, { 2,2,1,2,1 }, { 2,1,2,2,1 }, { 0,2,1,2,2 }, { 1,2,1,2,2 }, { 2,2,1,2,2 }, { 2,1,2,2,2 }, 634e5c31af7Sopenharmony_ci { 0,0,0,1,2 }, { 1,0,0,1,2 }, { 2,0,0,1,2 }, { 0,0,2,1,2 }, { 0,1,0,1,2 }, { 1,1,0,1,2 }, { 2,1,0,1,2 }, { 1,0,2,1,2 }, { 0,2,0,1,2 }, { 1,2,0,1,2 }, { 2,2,0,1,2 }, { 2,0,2,1,2 }, { 0,2,2,1,2 }, { 1,2,2,1,2 }, { 2,2,2,1,2 }, { 2,0,2,1,2 }, 635e5c31af7Sopenharmony_ci { 0,0,1,1,2 }, { 1,0,1,1,2 }, { 2,0,1,1,2 }, { 0,1,2,1,2 }, { 0,1,1,1,2 }, { 1,1,1,1,2 }, { 2,1,1,1,2 }, { 1,1,2,1,2 }, { 0,2,1,1,2 }, { 1,2,1,1,2 }, { 2,2,1,1,2 }, { 2,1,2,1,2 }, { 0,2,2,2,2 }, { 1,2,2,2,2 }, { 2,2,2,2,2 }, { 2,1,2,2,2 } 636e5c31af7Sopenharmony_ci }; 637e5c31af7Sopenharmony_ci 638e5c31af7Sopenharmony_ci const deUint32 (& trits)[5] = tritsFromT[T]; 639e5c31af7Sopenharmony_ci 640e5c31af7Sopenharmony_ci for (int i = 0; i < numValues; i++) 641e5c31af7Sopenharmony_ci { 642e5c31af7Sopenharmony_ci dst[i].m = m[i]; 643e5c31af7Sopenharmony_ci dst[i].tq = trits[i]; 644e5c31af7Sopenharmony_ci dst[i].v = (trits[i] << numBits) + m[i]; 645e5c31af7Sopenharmony_ci } 646e5c31af7Sopenharmony_ci} 647e5c31af7Sopenharmony_ci 648e5c31af7Sopenharmony_civoid decodeISEQuintBlock (ISEDecodedResult* dst, int numValues, BitAccessStream& data, int numBits) 649e5c31af7Sopenharmony_ci{ 650e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numValues, 1, 3)); 651e5c31af7Sopenharmony_ci 652e5c31af7Sopenharmony_ci deUint32 m[3]; 653e5c31af7Sopenharmony_ci 654e5c31af7Sopenharmony_ci m[0] = data.getNext(numBits); 655e5c31af7Sopenharmony_ci deUint32 Q012 = data.getNext(3); 656e5c31af7Sopenharmony_ci m[1] = data.getNext(numBits); 657e5c31af7Sopenharmony_ci deUint32 Q34 = data.getNext(2); 658e5c31af7Sopenharmony_ci m[2] = data.getNext(numBits); 659e5c31af7Sopenharmony_ci deUint32 Q56 = data.getNext(2); 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci switch (numValues) 662e5c31af7Sopenharmony_ci { 663e5c31af7Sopenharmony_ci case 1: 664e5c31af7Sopenharmony_ci Q34 = 0; 665e5c31af7Sopenharmony_ci // Fallthrough 666e5c31af7Sopenharmony_ci case 2: 667e5c31af7Sopenharmony_ci Q56 = 0; 668e5c31af7Sopenharmony_ci // Fallthrough 669e5c31af7Sopenharmony_ci case 3: 670e5c31af7Sopenharmony_ci break; 671e5c31af7Sopenharmony_ci default: 672e5c31af7Sopenharmony_ci DE_ASSERT(false); 673e5c31af7Sopenharmony_ci } 674e5c31af7Sopenharmony_ci 675e5c31af7Sopenharmony_ci const deUint32 Q = (Q56 << 5) | (Q34 << 3) | (Q012 << 0); 676e5c31af7Sopenharmony_ci 677e5c31af7Sopenharmony_ci static const deUint32 quintsFromQ[256][3] = 678e5c31af7Sopenharmony_ci { 679e5c31af7Sopenharmony_ci { 0,0,0 }, { 1,0,0 }, { 2,0,0 }, { 3,0,0 }, { 4,0,0 }, { 0,4,0 }, { 4,4,0 }, { 4,4,4 }, { 0,1,0 }, { 1,1,0 }, { 2,1,0 }, { 3,1,0 }, { 4,1,0 }, { 1,4,0 }, { 4,4,1 }, { 4,4,4 }, 680e5c31af7Sopenharmony_ci { 0,2,0 }, { 1,2,0 }, { 2,2,0 }, { 3,2,0 }, { 4,2,0 }, { 2,4,0 }, { 4,4,2 }, { 4,4,4 }, { 0,3,0 }, { 1,3,0 }, { 2,3,0 }, { 3,3,0 }, { 4,3,0 }, { 3,4,0 }, { 4,4,3 }, { 4,4,4 }, 681e5c31af7Sopenharmony_ci { 0,0,1 }, { 1,0,1 }, { 2,0,1 }, { 3,0,1 }, { 4,0,1 }, { 0,4,1 }, { 4,0,4 }, { 0,4,4 }, { 0,1,1 }, { 1,1,1 }, { 2,1,1 }, { 3,1,1 }, { 4,1,1 }, { 1,4,1 }, { 4,1,4 }, { 1,4,4 }, 682e5c31af7Sopenharmony_ci { 0,2,1 }, { 1,2,1 }, { 2,2,1 }, { 3,2,1 }, { 4,2,1 }, { 2,4,1 }, { 4,2,4 }, { 2,4,4 }, { 0,3,1 }, { 1,3,1 }, { 2,3,1 }, { 3,3,1 }, { 4,3,1 }, { 3,4,1 }, { 4,3,4 }, { 3,4,4 }, 683e5c31af7Sopenharmony_ci { 0,0,2 }, { 1,0,2 }, { 2,0,2 }, { 3,0,2 }, { 4,0,2 }, { 0,4,2 }, { 2,0,4 }, { 3,0,4 }, { 0,1,2 }, { 1,1,2 }, { 2,1,2 }, { 3,1,2 }, { 4,1,2 }, { 1,4,2 }, { 2,1,4 }, { 3,1,4 }, 684e5c31af7Sopenharmony_ci { 0,2,2 }, { 1,2,2 }, { 2,2,2 }, { 3,2,2 }, { 4,2,2 }, { 2,4,2 }, { 2,2,4 }, { 3,2,4 }, { 0,3,2 }, { 1,3,2 }, { 2,3,2 }, { 3,3,2 }, { 4,3,2 }, { 3,4,2 }, { 2,3,4 }, { 3,3,4 }, 685e5c31af7Sopenharmony_ci { 0,0,3 }, { 1,0,3 }, { 2,0,3 }, { 3,0,3 }, { 4,0,3 }, { 0,4,3 }, { 0,0,4 }, { 1,0,4 }, { 0,1,3 }, { 1,1,3 }, { 2,1,3 }, { 3,1,3 }, { 4,1,3 }, { 1,4,3 }, { 0,1,4 }, { 1,1,4 }, 686e5c31af7Sopenharmony_ci { 0,2,3 }, { 1,2,3 }, { 2,2,3 }, { 3,2,3 }, { 4,2,3 }, { 2,4,3 }, { 0,2,4 }, { 1,2,4 }, { 0,3,3 }, { 1,3,3 }, { 2,3,3 }, { 3,3,3 }, { 4,3,3 }, { 3,4,3 }, { 0,3,4 }, { 1,3,4 } 687e5c31af7Sopenharmony_ci }; 688e5c31af7Sopenharmony_ci 689e5c31af7Sopenharmony_ci const deUint32 (& quints)[3] = quintsFromQ[Q]; 690e5c31af7Sopenharmony_ci 691e5c31af7Sopenharmony_ci for (int i = 0; i < numValues; i++) 692e5c31af7Sopenharmony_ci { 693e5c31af7Sopenharmony_ci dst[i].m = m[i]; 694e5c31af7Sopenharmony_ci dst[i].tq = quints[i]; 695e5c31af7Sopenharmony_ci dst[i].v = (quints[i] << numBits) + m[i]; 696e5c31af7Sopenharmony_ci } 697e5c31af7Sopenharmony_ci} 698e5c31af7Sopenharmony_ci 699e5c31af7Sopenharmony_ciinline void decodeISEBitBlock (ISEDecodedResult* dst, BitAccessStream& data, int numBits) 700e5c31af7Sopenharmony_ci{ 701e5c31af7Sopenharmony_ci dst[0].m = data.getNext(numBits); 702e5c31af7Sopenharmony_ci dst[0].v = dst[0].m; 703e5c31af7Sopenharmony_ci} 704e5c31af7Sopenharmony_ci 705e5c31af7Sopenharmony_civoid decodeISE (ISEDecodedResult* dst, int numValues, BitAccessStream& data, const ISEParams& params) 706e5c31af7Sopenharmony_ci{ 707e5c31af7Sopenharmony_ci if (params.mode == ISEMODE_TRIT) 708e5c31af7Sopenharmony_ci { 709e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numValues, 5); 710e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 711e5c31af7Sopenharmony_ci { 712e5c31af7Sopenharmony_ci const int numValuesInBlock = blockNdx == numBlocks-1 ? numValues - 5*(numBlocks-1) : 5; 713e5c31af7Sopenharmony_ci decodeISETritBlock(&dst[5*blockNdx], numValuesInBlock, data, params.numBits); 714e5c31af7Sopenharmony_ci } 715e5c31af7Sopenharmony_ci } 716e5c31af7Sopenharmony_ci else if (params.mode == ISEMODE_QUINT) 717e5c31af7Sopenharmony_ci { 718e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numValues, 3); 719e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 720e5c31af7Sopenharmony_ci { 721e5c31af7Sopenharmony_ci const int numValuesInBlock = blockNdx == numBlocks-1 ? numValues - 3*(numBlocks-1) : 3; 722e5c31af7Sopenharmony_ci decodeISEQuintBlock(&dst[3*blockNdx], numValuesInBlock, data, params.numBits); 723e5c31af7Sopenharmony_ci } 724e5c31af7Sopenharmony_ci } 725e5c31af7Sopenharmony_ci else 726e5c31af7Sopenharmony_ci { 727e5c31af7Sopenharmony_ci DE_ASSERT(params.mode == ISEMODE_PLAIN_BIT); 728e5c31af7Sopenharmony_ci for (int i = 0; i < numValues; i++) 729e5c31af7Sopenharmony_ci decodeISEBitBlock(&dst[i], data, params.numBits); 730e5c31af7Sopenharmony_ci } 731e5c31af7Sopenharmony_ci} 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_civoid unquantizeColorEndpoints (deUint32* dst, const ISEDecodedResult* iseResults, int numEndpoints, const ISEParams& iseParams) 734e5c31af7Sopenharmony_ci{ 735e5c31af7Sopenharmony_ci if (iseParams.mode == ISEMODE_TRIT || iseParams.mode == ISEMODE_QUINT) 736e5c31af7Sopenharmony_ci { 737e5c31af7Sopenharmony_ci const int rangeCase = iseParams.numBits*2 - (iseParams.mode == ISEMODE_TRIT ? 2 : 1); 738e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(rangeCase, 0, 10)); 739e5c31af7Sopenharmony_ci static const deUint32 Ca[11] = { 204, 113, 93, 54, 44, 26, 22, 13, 11, 6, 5 }; 740e5c31af7Sopenharmony_ci const deUint32 C = Ca[rangeCase]; 741e5c31af7Sopenharmony_ci 742e5c31af7Sopenharmony_ci for (int endpointNdx = 0; endpointNdx < numEndpoints; endpointNdx++) 743e5c31af7Sopenharmony_ci { 744e5c31af7Sopenharmony_ci const deUint32 a = getBit(iseResults[endpointNdx].m, 0); 745e5c31af7Sopenharmony_ci const deUint32 b = getBit(iseResults[endpointNdx].m, 1); 746e5c31af7Sopenharmony_ci const deUint32 c = getBit(iseResults[endpointNdx].m, 2); 747e5c31af7Sopenharmony_ci const deUint32 d = getBit(iseResults[endpointNdx].m, 3); 748e5c31af7Sopenharmony_ci const deUint32 e = getBit(iseResults[endpointNdx].m, 4); 749e5c31af7Sopenharmony_ci const deUint32 f = getBit(iseResults[endpointNdx].m, 5); 750e5c31af7Sopenharmony_ci 751e5c31af7Sopenharmony_ci const deUint32 A = a == 0 ? 0 : (1<<9)-1; 752e5c31af7Sopenharmony_ci const deUint32 B = rangeCase == 0 ? 0 753e5c31af7Sopenharmony_ci : rangeCase == 1 ? 0 754e5c31af7Sopenharmony_ci : rangeCase == 2 ? (b << 8) | (b << 4) | (b << 2) | (b << 1) 755e5c31af7Sopenharmony_ci : rangeCase == 3 ? (b << 8) | (b << 3) | (b << 2) 756e5c31af7Sopenharmony_ci : rangeCase == 4 ? (c << 8) | (b << 7) | (c << 3) | (b << 2) | (c << 1) | (b << 0) 757e5c31af7Sopenharmony_ci : rangeCase == 5 ? (c << 8) | (b << 7) | (c << 2) | (b << 1) | (c << 0) 758e5c31af7Sopenharmony_ci : rangeCase == 6 ? (d << 8) | (c << 7) | (b << 6) | (d << 2) | (c << 1) | (b << 0) 759e5c31af7Sopenharmony_ci : rangeCase == 7 ? (d << 8) | (c << 7) | (b << 6) | (d << 1) | (c << 0) 760e5c31af7Sopenharmony_ci : rangeCase == 8 ? (e << 8) | (d << 7) | (c << 6) | (b << 5) | (e << 1) | (d << 0) 761e5c31af7Sopenharmony_ci : rangeCase == 9 ? (e << 8) | (d << 7) | (c << 6) | (b << 5) | (e << 0) 762e5c31af7Sopenharmony_ci : rangeCase == 10 ? (f << 8) | (e << 7) | (d << 6) | (c << 5) | (b << 4) | (f << 0) 763e5c31af7Sopenharmony_ci : (deUint32)-1; 764e5c31af7Sopenharmony_ci DE_ASSERT(B != (deUint32)-1); 765e5c31af7Sopenharmony_ci 766e5c31af7Sopenharmony_ci dst[endpointNdx] = (((iseResults[endpointNdx].tq*C + B) ^ A) >> 2) | (A & 0x80); 767e5c31af7Sopenharmony_ci } 768e5c31af7Sopenharmony_ci } 769e5c31af7Sopenharmony_ci else 770e5c31af7Sopenharmony_ci { 771e5c31af7Sopenharmony_ci DE_ASSERT(iseParams.mode == ISEMODE_PLAIN_BIT); 772e5c31af7Sopenharmony_ci 773e5c31af7Sopenharmony_ci for (int endpointNdx = 0; endpointNdx < numEndpoints; endpointNdx++) 774e5c31af7Sopenharmony_ci dst[endpointNdx] = bitReplicationScale(iseResults[endpointNdx].v, iseParams.numBits, 8); 775e5c31af7Sopenharmony_ci } 776e5c31af7Sopenharmony_ci} 777e5c31af7Sopenharmony_ci 778e5c31af7Sopenharmony_ciinline void bitTransferSigned (deInt32& a, deInt32& b) 779e5c31af7Sopenharmony_ci{ 780e5c31af7Sopenharmony_ci b >>= 1; 781e5c31af7Sopenharmony_ci b |= a & 0x80; 782e5c31af7Sopenharmony_ci a >>= 1; 783e5c31af7Sopenharmony_ci a &= 0x3f; 784e5c31af7Sopenharmony_ci if (isBitSet(a, 5)) 785e5c31af7Sopenharmony_ci a -= 0x40; 786e5c31af7Sopenharmony_ci} 787e5c31af7Sopenharmony_ci 788e5c31af7Sopenharmony_ciinline UVec4 clampedRGBA (const IVec4& rgba) 789e5c31af7Sopenharmony_ci{ 790e5c31af7Sopenharmony_ci return UVec4(de::clamp(rgba.x(), 0, 0xff), 791e5c31af7Sopenharmony_ci de::clamp(rgba.y(), 0, 0xff), 792e5c31af7Sopenharmony_ci de::clamp(rgba.z(), 0, 0xff), 793e5c31af7Sopenharmony_ci de::clamp(rgba.w(), 0, 0xff)); 794e5c31af7Sopenharmony_ci} 795e5c31af7Sopenharmony_ci 796e5c31af7Sopenharmony_ciinline IVec4 blueContract (int r, int g, int b, int a) 797e5c31af7Sopenharmony_ci{ 798e5c31af7Sopenharmony_ci return IVec4((r+b)>>1, (g+b)>>1, b, a); 799e5c31af7Sopenharmony_ci} 800e5c31af7Sopenharmony_ci 801e5c31af7Sopenharmony_ciinline bool isColorEndpointModeHDR (deUint32 mode) 802e5c31af7Sopenharmony_ci{ 803e5c31af7Sopenharmony_ci return mode == 2 || 804e5c31af7Sopenharmony_ci mode == 3 || 805e5c31af7Sopenharmony_ci mode == 7 || 806e5c31af7Sopenharmony_ci mode == 11 || 807e5c31af7Sopenharmony_ci mode == 14 || 808e5c31af7Sopenharmony_ci mode == 15; 809e5c31af7Sopenharmony_ci} 810e5c31af7Sopenharmony_ci 811e5c31af7Sopenharmony_civoid decodeHDREndpointMode7 (UVec4& e0, UVec4& e1, deUint32 v0, deUint32 v1, deUint32 v2, deUint32 v3) 812e5c31af7Sopenharmony_ci{ 813e5c31af7Sopenharmony_ci const deUint32 m10 = getBit(v1, 7) | (getBit(v2, 7) << 1); 814e5c31af7Sopenharmony_ci const deUint32 m23 = getBits(v0, 6, 7); 815e5c31af7Sopenharmony_ci const deUint32 majComp = m10 != 3 ? m10 816e5c31af7Sopenharmony_ci : m23 != 3 ? m23 817e5c31af7Sopenharmony_ci : 0; 818e5c31af7Sopenharmony_ci const deUint32 mode = m10 != 3 ? m23 819e5c31af7Sopenharmony_ci : m23 != 3 ? 4 820e5c31af7Sopenharmony_ci : 5; 821e5c31af7Sopenharmony_ci 822e5c31af7Sopenharmony_ci deInt32 red = (deInt32)getBits(v0, 0, 5); 823e5c31af7Sopenharmony_ci deInt32 green = (deInt32)getBits(v1, 0, 4); 824e5c31af7Sopenharmony_ci deInt32 blue = (deInt32)getBits(v2, 0, 4); 825e5c31af7Sopenharmony_ci deInt32 scale = (deInt32)getBits(v3, 0, 4); 826e5c31af7Sopenharmony_ci 827e5c31af7Sopenharmony_ci { 828e5c31af7Sopenharmony_ci#define SHOR(DST_VAR, SHIFT, BIT_VAR) (DST_VAR) |= (BIT_VAR) << (SHIFT) 829e5c31af7Sopenharmony_ci#define ASSIGN_X_BITS(V0,S0, V1,S1, V2,S2, V3,S3, V4,S4, V5,S5, V6,S6) do { SHOR(V0,S0,x0); SHOR(V1,S1,x1); SHOR(V2,S2,x2); SHOR(V3,S3,x3); SHOR(V4,S4,x4); SHOR(V5,S5,x5); SHOR(V6,S6,x6); } while (false) 830e5c31af7Sopenharmony_ci 831e5c31af7Sopenharmony_ci const deUint32 x0 = getBit(v1, 6); 832e5c31af7Sopenharmony_ci const deUint32 x1 = getBit(v1, 5); 833e5c31af7Sopenharmony_ci const deUint32 x2 = getBit(v2, 6); 834e5c31af7Sopenharmony_ci const deUint32 x3 = getBit(v2, 5); 835e5c31af7Sopenharmony_ci const deUint32 x4 = getBit(v3, 7); 836e5c31af7Sopenharmony_ci const deUint32 x5 = getBit(v3, 6); 837e5c31af7Sopenharmony_ci const deUint32 x6 = getBit(v3, 5); 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_ci deInt32& R = red; 840e5c31af7Sopenharmony_ci deInt32& G = green; 841e5c31af7Sopenharmony_ci deInt32& B = blue; 842e5c31af7Sopenharmony_ci deInt32& S = scale; 843e5c31af7Sopenharmony_ci 844e5c31af7Sopenharmony_ci switch (mode) 845e5c31af7Sopenharmony_ci { 846e5c31af7Sopenharmony_ci case 0: ASSIGN_X_BITS(R,9, R,8, R,7, R,10, R,6, S,6, S,5); break; 847e5c31af7Sopenharmony_ci case 1: ASSIGN_X_BITS(R,8, G,5, R,7, B,5, R,6, R,10, R,9); break; 848e5c31af7Sopenharmony_ci case 2: ASSIGN_X_BITS(R,9, R,8, R,7, R,6, S,7, S,6, S,5); break; 849e5c31af7Sopenharmony_ci case 3: ASSIGN_X_BITS(R,8, G,5, R,7, B,5, R,6, S,6, S,5); break; 850e5c31af7Sopenharmony_ci case 4: ASSIGN_X_BITS(G,6, G,5, B,6, B,5, R,6, R,7, S,5); break; 851e5c31af7Sopenharmony_ci case 5: ASSIGN_X_BITS(G,6, G,5, B,6, B,5, R,6, S,6, S,5); break; 852e5c31af7Sopenharmony_ci default: 853e5c31af7Sopenharmony_ci DE_ASSERT(false); 854e5c31af7Sopenharmony_ci } 855e5c31af7Sopenharmony_ci 856e5c31af7Sopenharmony_ci#undef ASSIGN_X_BITS 857e5c31af7Sopenharmony_ci#undef SHOR 858e5c31af7Sopenharmony_ci } 859e5c31af7Sopenharmony_ci 860e5c31af7Sopenharmony_ci static const int shiftAmounts[] = { 1, 1, 2, 3, 4, 5 }; 861e5c31af7Sopenharmony_ci DE_ASSERT(mode < DE_LENGTH_OF_ARRAY(shiftAmounts)); 862e5c31af7Sopenharmony_ci 863e5c31af7Sopenharmony_ci red <<= shiftAmounts[mode]; 864e5c31af7Sopenharmony_ci green <<= shiftAmounts[mode]; 865e5c31af7Sopenharmony_ci blue <<= shiftAmounts[mode]; 866e5c31af7Sopenharmony_ci scale <<= shiftAmounts[mode]; 867e5c31af7Sopenharmony_ci 868e5c31af7Sopenharmony_ci if (mode != 5) 869e5c31af7Sopenharmony_ci { 870e5c31af7Sopenharmony_ci green = red - green; 871e5c31af7Sopenharmony_ci blue = red - blue; 872e5c31af7Sopenharmony_ci } 873e5c31af7Sopenharmony_ci 874e5c31af7Sopenharmony_ci if (majComp == 1) 875e5c31af7Sopenharmony_ci std::swap(red, green); 876e5c31af7Sopenharmony_ci else if (majComp == 2) 877e5c31af7Sopenharmony_ci std::swap(red, blue); 878e5c31af7Sopenharmony_ci 879e5c31af7Sopenharmony_ci e0 = UVec4(de::clamp(red - scale, 0, 0xfff), 880e5c31af7Sopenharmony_ci de::clamp(green - scale, 0, 0xfff), 881e5c31af7Sopenharmony_ci de::clamp(blue - scale, 0, 0xfff), 882e5c31af7Sopenharmony_ci 0x780); 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci e1 = UVec4(de::clamp(red, 0, 0xfff), 885e5c31af7Sopenharmony_ci de::clamp(green, 0, 0xfff), 886e5c31af7Sopenharmony_ci de::clamp(blue, 0, 0xfff), 887e5c31af7Sopenharmony_ci 0x780); 888e5c31af7Sopenharmony_ci} 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_civoid decodeHDREndpointMode11 (UVec4& e0, UVec4& e1, deUint32 v0, deUint32 v1, deUint32 v2, deUint32 v3, deUint32 v4, deUint32 v5) 891e5c31af7Sopenharmony_ci{ 892e5c31af7Sopenharmony_ci const deUint32 major = (getBit(v5, 7) << 1) | getBit(v4, 7); 893e5c31af7Sopenharmony_ci 894e5c31af7Sopenharmony_ci if (major == 3) 895e5c31af7Sopenharmony_ci { 896e5c31af7Sopenharmony_ci e0 = UVec4(v0<<4, v2<<4, getBits(v4,0,6)<<5, 0x780); 897e5c31af7Sopenharmony_ci e1 = UVec4(v1<<4, v3<<4, getBits(v5,0,6)<<5, 0x780); 898e5c31af7Sopenharmony_ci } 899e5c31af7Sopenharmony_ci else 900e5c31af7Sopenharmony_ci { 901e5c31af7Sopenharmony_ci const deUint32 mode = (getBit(v3, 7) << 2) | (getBit(v2, 7) << 1) | getBit(v1, 7); 902e5c31af7Sopenharmony_ci 903e5c31af7Sopenharmony_ci deInt32 a = (deInt32)((getBit(v1, 6) << 8) | v0); 904e5c31af7Sopenharmony_ci deInt32 c = (deInt32)(getBits(v1, 0, 5)); 905e5c31af7Sopenharmony_ci deInt32 b0 = (deInt32)(getBits(v2, 0, 5)); 906e5c31af7Sopenharmony_ci deInt32 b1 = (deInt32)(getBits(v3, 0, 5)); 907e5c31af7Sopenharmony_ci deInt32 d0 = (deInt32)(getBits(v4, 0, 4)); 908e5c31af7Sopenharmony_ci deInt32 d1 = (deInt32)(getBits(v5, 0, 4)); 909e5c31af7Sopenharmony_ci 910e5c31af7Sopenharmony_ci { 911e5c31af7Sopenharmony_ci#define SHOR(DST_VAR, SHIFT, BIT_VAR) (DST_VAR) |= (BIT_VAR) << (SHIFT) 912e5c31af7Sopenharmony_ci#define ASSIGN_X_BITS(V0,S0, V1,S1, V2,S2, V3,S3, V4,S4, V5,S5) do { SHOR(V0,S0,x0); SHOR(V1,S1,x1); SHOR(V2,S2,x2); SHOR(V3,S3,x3); SHOR(V4,S4,x4); SHOR(V5,S5,x5); } while (false) 913e5c31af7Sopenharmony_ci 914e5c31af7Sopenharmony_ci const deUint32 x0 = getBit(v2, 6); 915e5c31af7Sopenharmony_ci const deUint32 x1 = getBit(v3, 6); 916e5c31af7Sopenharmony_ci const deUint32 x2 = getBit(v4, 6); 917e5c31af7Sopenharmony_ci const deUint32 x3 = getBit(v5, 6); 918e5c31af7Sopenharmony_ci const deUint32 x4 = getBit(v4, 5); 919e5c31af7Sopenharmony_ci const deUint32 x5 = getBit(v5, 5); 920e5c31af7Sopenharmony_ci 921e5c31af7Sopenharmony_ci switch (mode) 922e5c31af7Sopenharmony_ci { 923e5c31af7Sopenharmony_ci case 0: ASSIGN_X_BITS(b0,6, b1,6, d0,6, d1,6, d0,5, d1,5); break; 924e5c31af7Sopenharmony_ci case 1: ASSIGN_X_BITS(b0,6, b1,6, b0,7, b1,7, d0,5, d1,5); break; 925e5c31af7Sopenharmony_ci case 2: ASSIGN_X_BITS(a,9, c,6, d0,6, d1,6, d0,5, d1,5); break; 926e5c31af7Sopenharmony_ci case 3: ASSIGN_X_BITS(b0,6, b1,6, a,9, c,6, d0,5, d1,5); break; 927e5c31af7Sopenharmony_ci case 4: ASSIGN_X_BITS(b0,6, b1,6, b0,7, b1,7, a,9, a,10); break; 928e5c31af7Sopenharmony_ci case 5: ASSIGN_X_BITS(a,9, a,10, c,7, c,6, d0,5, d1,5); break; 929e5c31af7Sopenharmony_ci case 6: ASSIGN_X_BITS(b0,6, b1,6, a,11, c,6, a,9, a,10); break; 930e5c31af7Sopenharmony_ci case 7: ASSIGN_X_BITS(a,9, a,10, a,11, c,6, d0,5, d1,5); break; 931e5c31af7Sopenharmony_ci default: 932e5c31af7Sopenharmony_ci DE_ASSERT(false); 933e5c31af7Sopenharmony_ci } 934e5c31af7Sopenharmony_ci 935e5c31af7Sopenharmony_ci#undef ASSIGN_X_BITS 936e5c31af7Sopenharmony_ci#undef SHOR 937e5c31af7Sopenharmony_ci } 938e5c31af7Sopenharmony_ci 939e5c31af7Sopenharmony_ci static const int numDBits[] = { 7, 6, 7, 6, 5, 6, 5, 6 }; 940e5c31af7Sopenharmony_ci DE_ASSERT(mode < DE_LENGTH_OF_ARRAY(numDBits)); 941e5c31af7Sopenharmony_ci 942e5c31af7Sopenharmony_ci d0 = signExtend(d0, numDBits[mode]); 943e5c31af7Sopenharmony_ci d1 = signExtend(d1, numDBits[mode]); 944e5c31af7Sopenharmony_ci 945e5c31af7Sopenharmony_ci const int shiftAmount = (mode >> 1) ^ 3; 946e5c31af7Sopenharmony_ci a <<= shiftAmount; 947e5c31af7Sopenharmony_ci c <<= shiftAmount; 948e5c31af7Sopenharmony_ci b0 <<= shiftAmount; 949e5c31af7Sopenharmony_ci b1 <<= shiftAmount; 950e5c31af7Sopenharmony_ci d0 <<= shiftAmount; 951e5c31af7Sopenharmony_ci d1 <<= shiftAmount; 952e5c31af7Sopenharmony_ci 953e5c31af7Sopenharmony_ci e0 = UVec4(de::clamp(a-c, 0, 0xfff), 954e5c31af7Sopenharmony_ci de::clamp(a-b0-c-d0, 0, 0xfff), 955e5c31af7Sopenharmony_ci de::clamp(a-b1-c-d1, 0, 0xfff), 956e5c31af7Sopenharmony_ci 0x780); 957e5c31af7Sopenharmony_ci 958e5c31af7Sopenharmony_ci e1 = UVec4(de::clamp(a, 0, 0xfff), 959e5c31af7Sopenharmony_ci de::clamp(a-b0, 0, 0xfff), 960e5c31af7Sopenharmony_ci de::clamp(a-b1, 0, 0xfff), 961e5c31af7Sopenharmony_ci 0x780); 962e5c31af7Sopenharmony_ci 963e5c31af7Sopenharmony_ci if (major == 1) 964e5c31af7Sopenharmony_ci { 965e5c31af7Sopenharmony_ci std::swap(e0.x(), e0.y()); 966e5c31af7Sopenharmony_ci std::swap(e1.x(), e1.y()); 967e5c31af7Sopenharmony_ci } 968e5c31af7Sopenharmony_ci else if (major == 2) 969e5c31af7Sopenharmony_ci { 970e5c31af7Sopenharmony_ci std::swap(e0.x(), e0.z()); 971e5c31af7Sopenharmony_ci std::swap(e1.x(), e1.z()); 972e5c31af7Sopenharmony_ci } 973e5c31af7Sopenharmony_ci } 974e5c31af7Sopenharmony_ci} 975e5c31af7Sopenharmony_ci 976e5c31af7Sopenharmony_civoid decodeHDREndpointMode15(UVec4& e0, UVec4& e1, deUint32 v0, deUint32 v1, deUint32 v2, deUint32 v3, deUint32 v4, deUint32 v5, deUint32 v6In, deUint32 v7In) 977e5c31af7Sopenharmony_ci{ 978e5c31af7Sopenharmony_ci decodeHDREndpointMode11(e0, e1, v0, v1, v2, v3, v4, v5); 979e5c31af7Sopenharmony_ci 980e5c31af7Sopenharmony_ci const deUint32 mode = (getBit(v7In, 7) << 1) | getBit(v6In, 7); 981e5c31af7Sopenharmony_ci deInt32 v6 = (deInt32)getBits(v6In, 0, 6); 982e5c31af7Sopenharmony_ci deInt32 v7 = (deInt32)getBits(v7In, 0, 6); 983e5c31af7Sopenharmony_ci 984e5c31af7Sopenharmony_ci if (mode == 3) 985e5c31af7Sopenharmony_ci { 986e5c31af7Sopenharmony_ci e0.w() = v6 << 5; 987e5c31af7Sopenharmony_ci e1.w() = v7 << 5; 988e5c31af7Sopenharmony_ci } 989e5c31af7Sopenharmony_ci else 990e5c31af7Sopenharmony_ci { 991e5c31af7Sopenharmony_ci v6 |= (v7 << (mode+1)) & 0x780; 992e5c31af7Sopenharmony_ci v7 &= (0x3f >> mode); 993e5c31af7Sopenharmony_ci v7 ^= 0x20 >> mode; 994e5c31af7Sopenharmony_ci v7 -= 0x20 >> mode; 995e5c31af7Sopenharmony_ci v6 <<= 4-mode; 996e5c31af7Sopenharmony_ci v7 <<= 4-mode; 997e5c31af7Sopenharmony_ci 998e5c31af7Sopenharmony_ci v7 += v6; 999e5c31af7Sopenharmony_ci v7 = de::clamp(v7, 0, 0xfff); 1000e5c31af7Sopenharmony_ci e0.w() = v6; 1001e5c31af7Sopenharmony_ci e1.w() = v7; 1002e5c31af7Sopenharmony_ci } 1003e5c31af7Sopenharmony_ci} 1004e5c31af7Sopenharmony_ci 1005e5c31af7Sopenharmony_civoid decodeColorEndpoints (ColorEndpointPair* dst, const deUint32* unquantizedEndpoints, const deUint32* endpointModes, int numPartitions) 1006e5c31af7Sopenharmony_ci{ 1007e5c31af7Sopenharmony_ci int unquantizedNdx = 0; 1008e5c31af7Sopenharmony_ci 1009e5c31af7Sopenharmony_ci for (int partitionNdx = 0; partitionNdx < numPartitions; partitionNdx++) 1010e5c31af7Sopenharmony_ci { 1011e5c31af7Sopenharmony_ci const deUint32 endpointMode = endpointModes[partitionNdx]; 1012e5c31af7Sopenharmony_ci const deUint32* v = &unquantizedEndpoints[unquantizedNdx]; 1013e5c31af7Sopenharmony_ci UVec4& e0 = dst[partitionNdx].e0; 1014e5c31af7Sopenharmony_ci UVec4& e1 = dst[partitionNdx].e1; 1015e5c31af7Sopenharmony_ci 1016e5c31af7Sopenharmony_ci unquantizedNdx += computeNumColorEndpointValues(endpointMode); 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci switch (endpointMode) 1019e5c31af7Sopenharmony_ci { 1020e5c31af7Sopenharmony_ci case 0: 1021e5c31af7Sopenharmony_ci e0 = UVec4(v[0], v[0], v[0], 0xff); 1022e5c31af7Sopenharmony_ci e1 = UVec4(v[1], v[1], v[1], 0xff); 1023e5c31af7Sopenharmony_ci break; 1024e5c31af7Sopenharmony_ci 1025e5c31af7Sopenharmony_ci case 1: 1026e5c31af7Sopenharmony_ci { 1027e5c31af7Sopenharmony_ci const deUint32 L0 = (v[0] >> 2) | (getBits(v[1], 6, 7) << 6); 1028e5c31af7Sopenharmony_ci const deUint32 L1 = de::min(0xffu, L0 + getBits(v[1], 0, 5)); 1029e5c31af7Sopenharmony_ci e0 = UVec4(L0, L0, L0, 0xff); 1030e5c31af7Sopenharmony_ci e1 = UVec4(L1, L1, L1, 0xff); 1031e5c31af7Sopenharmony_ci break; 1032e5c31af7Sopenharmony_ci } 1033e5c31af7Sopenharmony_ci 1034e5c31af7Sopenharmony_ci case 2: 1035e5c31af7Sopenharmony_ci { 1036e5c31af7Sopenharmony_ci const deUint32 v1Gr = v[1] >= v[0]; 1037e5c31af7Sopenharmony_ci const deUint32 y0 = v1Gr ? v[0]<<4 : (v[1]<<4) + 8; 1038e5c31af7Sopenharmony_ci const deUint32 y1 = v1Gr ? v[1]<<4 : (v[0]<<4) - 8; 1039e5c31af7Sopenharmony_ci 1040e5c31af7Sopenharmony_ci e0 = UVec4(y0, y0, y0, 0x780); 1041e5c31af7Sopenharmony_ci e1 = UVec4(y1, y1, y1, 0x780); 1042e5c31af7Sopenharmony_ci break; 1043e5c31af7Sopenharmony_ci } 1044e5c31af7Sopenharmony_ci 1045e5c31af7Sopenharmony_ci case 3: 1046e5c31af7Sopenharmony_ci { 1047e5c31af7Sopenharmony_ci const bool m = isBitSet(v[0], 7); 1048e5c31af7Sopenharmony_ci const deUint32 y0 = m ? (getBits(v[1], 5, 7) << 9) | (getBits(v[0], 0, 6) << 2) 1049e5c31af7Sopenharmony_ci : (getBits(v[1], 4, 7) << 8) | (getBits(v[0], 0, 6) << 1); 1050e5c31af7Sopenharmony_ci const deUint32 d = m ? getBits(v[1], 0, 4) << 2 1051e5c31af7Sopenharmony_ci : getBits(v[1], 0, 3) << 1; 1052e5c31af7Sopenharmony_ci const deUint32 y1 = de::min(0xfffu, y0+d); 1053e5c31af7Sopenharmony_ci 1054e5c31af7Sopenharmony_ci e0 = UVec4(y0, y0, y0, 0x780); 1055e5c31af7Sopenharmony_ci e1 = UVec4(y1, y1, y1, 0x780); 1056e5c31af7Sopenharmony_ci break; 1057e5c31af7Sopenharmony_ci } 1058e5c31af7Sopenharmony_ci 1059e5c31af7Sopenharmony_ci case 4: 1060e5c31af7Sopenharmony_ci e0 = UVec4(v[0], v[0], v[0], v[2]); 1061e5c31af7Sopenharmony_ci e1 = UVec4(v[1], v[1], v[1], v[3]); 1062e5c31af7Sopenharmony_ci break; 1063e5c31af7Sopenharmony_ci 1064e5c31af7Sopenharmony_ci case 5: 1065e5c31af7Sopenharmony_ci { 1066e5c31af7Sopenharmony_ci deInt32 v0 = (deInt32)v[0]; 1067e5c31af7Sopenharmony_ci deInt32 v1 = (deInt32)v[1]; 1068e5c31af7Sopenharmony_ci deInt32 v2 = (deInt32)v[2]; 1069e5c31af7Sopenharmony_ci deInt32 v3 = (deInt32)v[3]; 1070e5c31af7Sopenharmony_ci bitTransferSigned(v1, v0); 1071e5c31af7Sopenharmony_ci bitTransferSigned(v3, v2); 1072e5c31af7Sopenharmony_ci 1073e5c31af7Sopenharmony_ci e0 = clampedRGBA(IVec4(v0, v0, v0, v2)); 1074e5c31af7Sopenharmony_ci e1 = clampedRGBA(IVec4(v0+v1, v0+v1, v0+v1, v2+v3)); 1075e5c31af7Sopenharmony_ci break; 1076e5c31af7Sopenharmony_ci } 1077e5c31af7Sopenharmony_ci 1078e5c31af7Sopenharmony_ci case 6: 1079e5c31af7Sopenharmony_ci e0 = UVec4((v[0]*v[3]) >> 8, (v[1]*v[3]) >> 8, (v[2]*v[3]) >> 8, 0xff); 1080e5c31af7Sopenharmony_ci e1 = UVec4(v[0], v[1], v[2], 0xff); 1081e5c31af7Sopenharmony_ci break; 1082e5c31af7Sopenharmony_ci 1083e5c31af7Sopenharmony_ci case 7: 1084e5c31af7Sopenharmony_ci decodeHDREndpointMode7(e0, e1, v[0], v[1], v[2], v[3]); 1085e5c31af7Sopenharmony_ci break; 1086e5c31af7Sopenharmony_ci 1087e5c31af7Sopenharmony_ci case 8: 1088e5c31af7Sopenharmony_ci if (v[1]+v[3]+v[5] >= v[0]+v[2]+v[4]) 1089e5c31af7Sopenharmony_ci { 1090e5c31af7Sopenharmony_ci e0 = UVec4(v[0], v[2], v[4], 0xff); 1091e5c31af7Sopenharmony_ci e1 = UVec4(v[1], v[3], v[5], 0xff); 1092e5c31af7Sopenharmony_ci } 1093e5c31af7Sopenharmony_ci else 1094e5c31af7Sopenharmony_ci { 1095e5c31af7Sopenharmony_ci e0 = blueContract(v[1], v[3], v[5], 0xff).asUint(); 1096e5c31af7Sopenharmony_ci e1 = blueContract(v[0], v[2], v[4], 0xff).asUint(); 1097e5c31af7Sopenharmony_ci } 1098e5c31af7Sopenharmony_ci break; 1099e5c31af7Sopenharmony_ci 1100e5c31af7Sopenharmony_ci case 9: 1101e5c31af7Sopenharmony_ci { 1102e5c31af7Sopenharmony_ci deInt32 v0 = (deInt32)v[0]; 1103e5c31af7Sopenharmony_ci deInt32 v1 = (deInt32)v[1]; 1104e5c31af7Sopenharmony_ci deInt32 v2 = (deInt32)v[2]; 1105e5c31af7Sopenharmony_ci deInt32 v3 = (deInt32)v[3]; 1106e5c31af7Sopenharmony_ci deInt32 v4 = (deInt32)v[4]; 1107e5c31af7Sopenharmony_ci deInt32 v5 = (deInt32)v[5]; 1108e5c31af7Sopenharmony_ci bitTransferSigned(v1, v0); 1109e5c31af7Sopenharmony_ci bitTransferSigned(v3, v2); 1110e5c31af7Sopenharmony_ci bitTransferSigned(v5, v4); 1111e5c31af7Sopenharmony_ci 1112e5c31af7Sopenharmony_ci if (v1+v3+v5 >= 0) 1113e5c31af7Sopenharmony_ci { 1114e5c31af7Sopenharmony_ci e0 = clampedRGBA(IVec4(v0, v2, v4, 0xff)); 1115e5c31af7Sopenharmony_ci e1 = clampedRGBA(IVec4(v0+v1, v2+v3, v4+v5, 0xff)); 1116e5c31af7Sopenharmony_ci } 1117e5c31af7Sopenharmony_ci else 1118e5c31af7Sopenharmony_ci { 1119e5c31af7Sopenharmony_ci e0 = clampedRGBA(blueContract(v0+v1, v2+v3, v4+v5, 0xff)); 1120e5c31af7Sopenharmony_ci e1 = clampedRGBA(blueContract(v0, v2, v4, 0xff)); 1121e5c31af7Sopenharmony_ci } 1122e5c31af7Sopenharmony_ci break; 1123e5c31af7Sopenharmony_ci } 1124e5c31af7Sopenharmony_ci 1125e5c31af7Sopenharmony_ci case 10: 1126e5c31af7Sopenharmony_ci e0 = UVec4((v[0]*v[3]) >> 8, (v[1]*v[3]) >> 8, (v[2]*v[3]) >> 8, v[4]); 1127e5c31af7Sopenharmony_ci e1 = UVec4(v[0], v[1], v[2], v[5]); 1128e5c31af7Sopenharmony_ci break; 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci case 11: 1131e5c31af7Sopenharmony_ci decodeHDREndpointMode11(e0, e1, v[0], v[1], v[2], v[3], v[4], v[5]); 1132e5c31af7Sopenharmony_ci break; 1133e5c31af7Sopenharmony_ci 1134e5c31af7Sopenharmony_ci case 12: 1135e5c31af7Sopenharmony_ci if (v[1]+v[3]+v[5] >= v[0]+v[2]+v[4]) 1136e5c31af7Sopenharmony_ci { 1137e5c31af7Sopenharmony_ci e0 = UVec4(v[0], v[2], v[4], v[6]); 1138e5c31af7Sopenharmony_ci e1 = UVec4(v[1], v[3], v[5], v[7]); 1139e5c31af7Sopenharmony_ci } 1140e5c31af7Sopenharmony_ci else 1141e5c31af7Sopenharmony_ci { 1142e5c31af7Sopenharmony_ci e0 = clampedRGBA(blueContract(v[1], v[3], v[5], v[7])); 1143e5c31af7Sopenharmony_ci e1 = clampedRGBA(blueContract(v[0], v[2], v[4], v[6])); 1144e5c31af7Sopenharmony_ci } 1145e5c31af7Sopenharmony_ci break; 1146e5c31af7Sopenharmony_ci 1147e5c31af7Sopenharmony_ci case 13: 1148e5c31af7Sopenharmony_ci { 1149e5c31af7Sopenharmony_ci deInt32 v0 = (deInt32)v[0]; 1150e5c31af7Sopenharmony_ci deInt32 v1 = (deInt32)v[1]; 1151e5c31af7Sopenharmony_ci deInt32 v2 = (deInt32)v[2]; 1152e5c31af7Sopenharmony_ci deInt32 v3 = (deInt32)v[3]; 1153e5c31af7Sopenharmony_ci deInt32 v4 = (deInt32)v[4]; 1154e5c31af7Sopenharmony_ci deInt32 v5 = (deInt32)v[5]; 1155e5c31af7Sopenharmony_ci deInt32 v6 = (deInt32)v[6]; 1156e5c31af7Sopenharmony_ci deInt32 v7 = (deInt32)v[7]; 1157e5c31af7Sopenharmony_ci bitTransferSigned(v1, v0); 1158e5c31af7Sopenharmony_ci bitTransferSigned(v3, v2); 1159e5c31af7Sopenharmony_ci bitTransferSigned(v5, v4); 1160e5c31af7Sopenharmony_ci bitTransferSigned(v7, v6); 1161e5c31af7Sopenharmony_ci 1162e5c31af7Sopenharmony_ci if (v1+v3+v5 >= 0) 1163e5c31af7Sopenharmony_ci { 1164e5c31af7Sopenharmony_ci e0 = clampedRGBA(IVec4(v0, v2, v4, v6)); 1165e5c31af7Sopenharmony_ci e1 = clampedRGBA(IVec4(v0+v1, v2+v3, v4+v5, v6+v7)); 1166e5c31af7Sopenharmony_ci } 1167e5c31af7Sopenharmony_ci else 1168e5c31af7Sopenharmony_ci { 1169e5c31af7Sopenharmony_ci e0 = clampedRGBA(blueContract(v0+v1, v2+v3, v4+v5, v6+v7)); 1170e5c31af7Sopenharmony_ci e1 = clampedRGBA(blueContract(v0, v2, v4, v6)); 1171e5c31af7Sopenharmony_ci } 1172e5c31af7Sopenharmony_ci 1173e5c31af7Sopenharmony_ci break; 1174e5c31af7Sopenharmony_ci } 1175e5c31af7Sopenharmony_ci 1176e5c31af7Sopenharmony_ci case 14: 1177e5c31af7Sopenharmony_ci decodeHDREndpointMode11(e0, e1, v[0], v[1], v[2], v[3], v[4], v[5]); 1178e5c31af7Sopenharmony_ci e0.w() = v[6]; 1179e5c31af7Sopenharmony_ci e1.w() = v[7]; 1180e5c31af7Sopenharmony_ci break; 1181e5c31af7Sopenharmony_ci 1182e5c31af7Sopenharmony_ci case 15: 1183e5c31af7Sopenharmony_ci decodeHDREndpointMode15(e0, e1, v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]); 1184e5c31af7Sopenharmony_ci break; 1185e5c31af7Sopenharmony_ci 1186e5c31af7Sopenharmony_ci default: 1187e5c31af7Sopenharmony_ci DE_ASSERT(false); 1188e5c31af7Sopenharmony_ci } 1189e5c31af7Sopenharmony_ci } 1190e5c31af7Sopenharmony_ci} 1191e5c31af7Sopenharmony_ci 1192e5c31af7Sopenharmony_civoid computeColorEndpoints (ColorEndpointPair* dst, const Block128& blockData, const deUint32* endpointModes, int numPartitions, int numColorEndpointValues, const ISEParams& iseParams, int numBitsAvailable) 1193e5c31af7Sopenharmony_ci{ 1194e5c31af7Sopenharmony_ci const int colorEndpointDataStart = numPartitions == 1 ? 17 : 29; 1195e5c31af7Sopenharmony_ci ISEDecodedResult colorEndpointData[18]; 1196e5c31af7Sopenharmony_ci 1197e5c31af7Sopenharmony_ci { 1198e5c31af7Sopenharmony_ci BitAccessStream dataStream(blockData, colorEndpointDataStart, numBitsAvailable, true); 1199e5c31af7Sopenharmony_ci decodeISE(&colorEndpointData[0], numColorEndpointValues, dataStream, iseParams); 1200e5c31af7Sopenharmony_ci } 1201e5c31af7Sopenharmony_ci 1202e5c31af7Sopenharmony_ci { 1203e5c31af7Sopenharmony_ci deUint32 unquantizedEndpoints[18]; 1204e5c31af7Sopenharmony_ci unquantizeColorEndpoints(&unquantizedEndpoints[0], &colorEndpointData[0], numColorEndpointValues, iseParams); 1205e5c31af7Sopenharmony_ci decodeColorEndpoints(dst, &unquantizedEndpoints[0], &endpointModes[0], numPartitions); 1206e5c31af7Sopenharmony_ci } 1207e5c31af7Sopenharmony_ci} 1208e5c31af7Sopenharmony_ci 1209e5c31af7Sopenharmony_civoid unquantizeWeights (deUint32 dst[64], const ISEDecodedResult* weightGrid, const ASTCBlockMode& blockMode) 1210e5c31af7Sopenharmony_ci{ 1211e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockMode); 1212e5c31af7Sopenharmony_ci const ISEParams& iseParams = blockMode.weightISEParams; 1213e5c31af7Sopenharmony_ci 1214e5c31af7Sopenharmony_ci if (iseParams.mode == ISEMODE_TRIT || iseParams.mode == ISEMODE_QUINT) 1215e5c31af7Sopenharmony_ci { 1216e5c31af7Sopenharmony_ci const int rangeCase = iseParams.numBits*2 + (iseParams.mode == ISEMODE_QUINT ? 1 : 0); 1217e5c31af7Sopenharmony_ci 1218e5c31af7Sopenharmony_ci if (rangeCase == 0 || rangeCase == 1) 1219e5c31af7Sopenharmony_ci { 1220e5c31af7Sopenharmony_ci static const deUint32 map0[3] = { 0, 32, 63 }; 1221e5c31af7Sopenharmony_ci static const deUint32 map1[5] = { 0, 16, 32, 47, 63 }; 1222e5c31af7Sopenharmony_ci const deUint32* const map = rangeCase == 0 ? &map0[0] : &map1[0]; 1223e5c31af7Sopenharmony_ci for (int i = 0; i < numWeights; i++) 1224e5c31af7Sopenharmony_ci { 1225e5c31af7Sopenharmony_ci DE_ASSERT(weightGrid[i].v < (rangeCase == 0 ? 3u : 5u)); 1226e5c31af7Sopenharmony_ci dst[i] = map[weightGrid[i].v]; 1227e5c31af7Sopenharmony_ci } 1228e5c31af7Sopenharmony_ci } 1229e5c31af7Sopenharmony_ci else 1230e5c31af7Sopenharmony_ci { 1231e5c31af7Sopenharmony_ci DE_ASSERT(rangeCase <= 6); 1232e5c31af7Sopenharmony_ci static const deUint32 Ca[5] = { 50, 28, 23, 13, 11 }; 1233e5c31af7Sopenharmony_ci const deUint32 C = Ca[rangeCase-2]; 1234e5c31af7Sopenharmony_ci 1235e5c31af7Sopenharmony_ci for (int weightNdx = 0; weightNdx < numWeights; weightNdx++) 1236e5c31af7Sopenharmony_ci { 1237e5c31af7Sopenharmony_ci const deUint32 a = getBit(weightGrid[weightNdx].m, 0); 1238e5c31af7Sopenharmony_ci const deUint32 b = getBit(weightGrid[weightNdx].m, 1); 1239e5c31af7Sopenharmony_ci const deUint32 c = getBit(weightGrid[weightNdx].m, 2); 1240e5c31af7Sopenharmony_ci 1241e5c31af7Sopenharmony_ci const deUint32 A = a == 0 ? 0 : (1<<7)-1; 1242e5c31af7Sopenharmony_ci const deUint32 B = rangeCase == 2 ? 0 1243e5c31af7Sopenharmony_ci : rangeCase == 3 ? 0 1244e5c31af7Sopenharmony_ci : rangeCase == 4 ? (b << 6) | (b << 2) | (b << 0) 1245e5c31af7Sopenharmony_ci : rangeCase == 5 ? (b << 6) | (b << 1) 1246e5c31af7Sopenharmony_ci : rangeCase == 6 ? (c << 6) | (b << 5) | (c << 1) | (b << 0) 1247e5c31af7Sopenharmony_ci : (deUint32)-1; 1248e5c31af7Sopenharmony_ci 1249e5c31af7Sopenharmony_ci dst[weightNdx] = (((weightGrid[weightNdx].tq*C + B) ^ A) >> 2) | (A & 0x20); 1250e5c31af7Sopenharmony_ci } 1251e5c31af7Sopenharmony_ci } 1252e5c31af7Sopenharmony_ci } 1253e5c31af7Sopenharmony_ci else 1254e5c31af7Sopenharmony_ci { 1255e5c31af7Sopenharmony_ci DE_ASSERT(iseParams.mode == ISEMODE_PLAIN_BIT); 1256e5c31af7Sopenharmony_ci 1257e5c31af7Sopenharmony_ci for (int weightNdx = 0; weightNdx < numWeights; weightNdx++) 1258e5c31af7Sopenharmony_ci dst[weightNdx] = bitReplicationScale(weightGrid[weightNdx].v, iseParams.numBits, 6); 1259e5c31af7Sopenharmony_ci } 1260e5c31af7Sopenharmony_ci 1261e5c31af7Sopenharmony_ci for (int weightNdx = 0; weightNdx < numWeights; weightNdx++) 1262e5c31af7Sopenharmony_ci dst[weightNdx] += dst[weightNdx] > 32 ? 1 : 0; 1263e5c31af7Sopenharmony_ci 1264e5c31af7Sopenharmony_ci // Initialize nonexistent weights to poison values 1265e5c31af7Sopenharmony_ci for (int weightNdx = numWeights; weightNdx < 64; weightNdx++) 1266e5c31af7Sopenharmony_ci dst[weightNdx] = ~0u; 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci} 1269e5c31af7Sopenharmony_ci 1270e5c31af7Sopenharmony_civoid interpolateWeights (TexelWeightPair* dst, const deUint32 (&unquantizedWeights) [64], int blockWidth, int blockHeight, const ASTCBlockMode& blockMode) 1271e5c31af7Sopenharmony_ci{ 1272e5c31af7Sopenharmony_ci const int numWeightsPerTexel = blockMode.isDualPlane ? 2 : 1; 1273e5c31af7Sopenharmony_ci const deUint32 scaleX = (1024 + blockWidth/2) / (blockWidth-1); 1274e5c31af7Sopenharmony_ci const deUint32 scaleY = (1024 + blockHeight/2) / (blockHeight-1); 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci DE_ASSERT(blockMode.weightGridWidth*blockMode.weightGridHeight*numWeightsPerTexel <= DE_LENGTH_OF_ARRAY(unquantizedWeights)); 1277e5c31af7Sopenharmony_ci 1278e5c31af7Sopenharmony_ci for (int texelY = 0; texelY < blockHeight; texelY++) 1279e5c31af7Sopenharmony_ci { 1280e5c31af7Sopenharmony_ci for (int texelX = 0; texelX < blockWidth; texelX++) 1281e5c31af7Sopenharmony_ci { 1282e5c31af7Sopenharmony_ci const deUint32 gX = (scaleX*texelX*(blockMode.weightGridWidth-1) + 32) >> 6; 1283e5c31af7Sopenharmony_ci const deUint32 gY = (scaleY*texelY*(blockMode.weightGridHeight-1) + 32) >> 6; 1284e5c31af7Sopenharmony_ci const deUint32 jX = gX >> 4; 1285e5c31af7Sopenharmony_ci const deUint32 jY = gY >> 4; 1286e5c31af7Sopenharmony_ci const deUint32 fX = gX & 0xf; 1287e5c31af7Sopenharmony_ci const deUint32 fY = gY & 0xf; 1288e5c31af7Sopenharmony_ci 1289e5c31af7Sopenharmony_ci const deUint32 w11 = (fX*fY + 8) >> 4; 1290e5c31af7Sopenharmony_ci const deUint32 w10 = fY - w11; 1291e5c31af7Sopenharmony_ci const deUint32 w01 = fX - w11; 1292e5c31af7Sopenharmony_ci const deUint32 w00 = 16 - fX - fY + w11; 1293e5c31af7Sopenharmony_ci 1294e5c31af7Sopenharmony_ci const deUint32 i00 = jY*blockMode.weightGridWidth + jX; 1295e5c31af7Sopenharmony_ci const deUint32 i01 = i00 + 1; 1296e5c31af7Sopenharmony_ci const deUint32 i10 = i00 + blockMode.weightGridWidth; 1297e5c31af7Sopenharmony_ci const deUint32 i11 = i00 + blockMode.weightGridWidth + 1; 1298e5c31af7Sopenharmony_ci 1299e5c31af7Sopenharmony_ci // These addresses can be out of bounds, but respective weights will be 0 then. 1300e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(i00, 0, blockMode.weightGridWidth*blockMode.weightGridHeight) || w00 == 0); 1301e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(i01, 0, blockMode.weightGridWidth*blockMode.weightGridHeight) || w01 == 0); 1302e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(i10, 0, blockMode.weightGridWidth*blockMode.weightGridHeight) || w10 == 0); 1303e5c31af7Sopenharmony_ci DE_ASSERT(deInBounds32(i11, 0, blockMode.weightGridWidth*blockMode.weightGridHeight) || w11 == 0); 1304e5c31af7Sopenharmony_ci 1305e5c31af7Sopenharmony_ci for (int texelWeightNdx = 0; texelWeightNdx < numWeightsPerTexel; texelWeightNdx++) 1306e5c31af7Sopenharmony_ci { 1307e5c31af7Sopenharmony_ci // & 0x3f clamps address to bounds of unquantizedWeights 1308e5c31af7Sopenharmony_ci const deUint32 p00 = unquantizedWeights[(i00 * numWeightsPerTexel + texelWeightNdx) & 0x3f]; 1309e5c31af7Sopenharmony_ci const deUint32 p01 = unquantizedWeights[(i01 * numWeightsPerTexel + texelWeightNdx) & 0x3f]; 1310e5c31af7Sopenharmony_ci const deUint32 p10 = unquantizedWeights[(i10 * numWeightsPerTexel + texelWeightNdx) & 0x3f]; 1311e5c31af7Sopenharmony_ci const deUint32 p11 = unquantizedWeights[(i11 * numWeightsPerTexel + texelWeightNdx) & 0x3f]; 1312e5c31af7Sopenharmony_ci 1313e5c31af7Sopenharmony_ci dst[texelY*blockWidth + texelX].w[texelWeightNdx] = (p00*w00 + p01*w01 + p10*w10 + p11*w11 + 8) >> 4; 1314e5c31af7Sopenharmony_ci } 1315e5c31af7Sopenharmony_ci } 1316e5c31af7Sopenharmony_ci } 1317e5c31af7Sopenharmony_ci} 1318e5c31af7Sopenharmony_ci 1319e5c31af7Sopenharmony_civoid computeTexelWeights (TexelWeightPair* dst, const Block128& blockData, int blockWidth, int blockHeight, const ASTCBlockMode& blockMode) 1320e5c31af7Sopenharmony_ci{ 1321e5c31af7Sopenharmony_ci ISEDecodedResult weightGrid[64]; 1322e5c31af7Sopenharmony_ci 1323e5c31af7Sopenharmony_ci { 1324e5c31af7Sopenharmony_ci BitAccessStream dataStream(blockData, 127, computeNumRequiredBits(blockMode.weightISEParams, computeNumWeights(blockMode)), false); 1325e5c31af7Sopenharmony_ci decodeISE(&weightGrid[0], computeNumWeights(blockMode), dataStream, blockMode.weightISEParams); 1326e5c31af7Sopenharmony_ci } 1327e5c31af7Sopenharmony_ci 1328e5c31af7Sopenharmony_ci { 1329e5c31af7Sopenharmony_ci deUint32 unquantizedWeights[64]; 1330e5c31af7Sopenharmony_ci unquantizeWeights(&unquantizedWeights[0], &weightGrid[0], blockMode); 1331e5c31af7Sopenharmony_ci interpolateWeights(dst, unquantizedWeights, blockWidth, blockHeight, blockMode); 1332e5c31af7Sopenharmony_ci } 1333e5c31af7Sopenharmony_ci} 1334e5c31af7Sopenharmony_ci 1335e5c31af7Sopenharmony_ciinline deUint32 hash52 (deUint32 v) 1336e5c31af7Sopenharmony_ci{ 1337e5c31af7Sopenharmony_ci deUint32 p = v; 1338e5c31af7Sopenharmony_ci p ^= p >> 15; p -= p << 17; p += p << 7; p += p << 4; 1339e5c31af7Sopenharmony_ci p ^= p >> 5; p += p << 16; p ^= p >> 7; p ^= p >> 3; 1340e5c31af7Sopenharmony_ci p ^= p << 6; p ^= p >> 17; 1341e5c31af7Sopenharmony_ci return p; 1342e5c31af7Sopenharmony_ci} 1343e5c31af7Sopenharmony_ci 1344e5c31af7Sopenharmony_ciint computeTexelPartition (deUint32 seedIn, deUint32 xIn, deUint32 yIn, deUint32 zIn, int numPartitions, bool smallBlock) 1345e5c31af7Sopenharmony_ci{ 1346e5c31af7Sopenharmony_ci DE_ASSERT(zIn == 0); 1347e5c31af7Sopenharmony_ci const deUint32 x = smallBlock ? xIn << 1 : xIn; 1348e5c31af7Sopenharmony_ci const deUint32 y = smallBlock ? yIn << 1 : yIn; 1349e5c31af7Sopenharmony_ci const deUint32 z = smallBlock ? zIn << 1 : zIn; 1350e5c31af7Sopenharmony_ci const deUint32 seed = seedIn + 1024*(numPartitions-1); 1351e5c31af7Sopenharmony_ci const deUint32 rnum = hash52(seed); 1352e5c31af7Sopenharmony_ci deUint8 seed1 = (deUint8)( rnum & 0xf); 1353e5c31af7Sopenharmony_ci deUint8 seed2 = (deUint8)((rnum >> 4) & 0xf); 1354e5c31af7Sopenharmony_ci deUint8 seed3 = (deUint8)((rnum >> 8) & 0xf); 1355e5c31af7Sopenharmony_ci deUint8 seed4 = (deUint8)((rnum >> 12) & 0xf); 1356e5c31af7Sopenharmony_ci deUint8 seed5 = (deUint8)((rnum >> 16) & 0xf); 1357e5c31af7Sopenharmony_ci deUint8 seed6 = (deUint8)((rnum >> 20) & 0xf); 1358e5c31af7Sopenharmony_ci deUint8 seed7 = (deUint8)((rnum >> 24) & 0xf); 1359e5c31af7Sopenharmony_ci deUint8 seed8 = (deUint8)((rnum >> 28) & 0xf); 1360e5c31af7Sopenharmony_ci deUint8 seed9 = (deUint8)((rnum >> 18) & 0xf); 1361e5c31af7Sopenharmony_ci deUint8 seed10 = (deUint8)((rnum >> 22) & 0xf); 1362e5c31af7Sopenharmony_ci deUint8 seed11 = (deUint8)((rnum >> 26) & 0xf); 1363e5c31af7Sopenharmony_ci deUint8 seed12 = (deUint8)(((rnum >> 30) | (rnum << 2)) & 0xf); 1364e5c31af7Sopenharmony_ci 1365e5c31af7Sopenharmony_ci seed1 = (deUint8)(seed1 * seed1 ); 1366e5c31af7Sopenharmony_ci seed2 = (deUint8)(seed2 * seed2 ); 1367e5c31af7Sopenharmony_ci seed3 = (deUint8)(seed3 * seed3 ); 1368e5c31af7Sopenharmony_ci seed4 = (deUint8)(seed4 * seed4 ); 1369e5c31af7Sopenharmony_ci seed5 = (deUint8)(seed5 * seed5 ); 1370e5c31af7Sopenharmony_ci seed6 = (deUint8)(seed6 * seed6 ); 1371e5c31af7Sopenharmony_ci seed7 = (deUint8)(seed7 * seed7 ); 1372e5c31af7Sopenharmony_ci seed8 = (deUint8)(seed8 * seed8 ); 1373e5c31af7Sopenharmony_ci seed9 = (deUint8)(seed9 * seed9 ); 1374e5c31af7Sopenharmony_ci seed10 = (deUint8)(seed10 * seed10); 1375e5c31af7Sopenharmony_ci seed11 = (deUint8)(seed11 * seed11); 1376e5c31af7Sopenharmony_ci seed12 = (deUint8)(seed12 * seed12); 1377e5c31af7Sopenharmony_ci 1378e5c31af7Sopenharmony_ci const int shA = (seed & 2) != 0 ? 4 : 5; 1379e5c31af7Sopenharmony_ci const int shB = numPartitions == 3 ? 6 : 5; 1380e5c31af7Sopenharmony_ci const int sh1 = (seed & 1) != 0 ? shA : shB; 1381e5c31af7Sopenharmony_ci const int sh2 = (seed & 1) != 0 ? shB : shA; 1382e5c31af7Sopenharmony_ci const int sh3 = (seed & 0x10) != 0 ? sh1 : sh2; 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci seed1 = (deUint8)(seed1 >> sh1); 1385e5c31af7Sopenharmony_ci seed2 = (deUint8)(seed2 >> sh2); 1386e5c31af7Sopenharmony_ci seed3 = (deUint8)(seed3 >> sh1); 1387e5c31af7Sopenharmony_ci seed4 = (deUint8)(seed4 >> sh2); 1388e5c31af7Sopenharmony_ci seed5 = (deUint8)(seed5 >> sh1); 1389e5c31af7Sopenharmony_ci seed6 = (deUint8)(seed6 >> sh2); 1390e5c31af7Sopenharmony_ci seed7 = (deUint8)(seed7 >> sh1); 1391e5c31af7Sopenharmony_ci seed8 = (deUint8)(seed8 >> sh2); 1392e5c31af7Sopenharmony_ci seed9 = (deUint8)(seed9 >> sh3); 1393e5c31af7Sopenharmony_ci seed10 = (deUint8)(seed10 >> sh3); 1394e5c31af7Sopenharmony_ci seed11 = (deUint8)(seed11 >> sh3); 1395e5c31af7Sopenharmony_ci seed12 = (deUint8)(seed12 >> sh3); 1396e5c31af7Sopenharmony_ci 1397e5c31af7Sopenharmony_ci const int a = 0x3f & (seed1*x + seed2*y + seed11*z + (rnum >> 14)); 1398e5c31af7Sopenharmony_ci const int b = 0x3f & (seed3*x + seed4*y + seed12*z + (rnum >> 10)); 1399e5c31af7Sopenharmony_ci const int c = numPartitions >= 3 ? 0x3f & (seed5*x + seed6*y + seed9*z + (rnum >> 6)) : 0; 1400e5c31af7Sopenharmony_ci const int d = numPartitions >= 4 ? 0x3f & (seed7*x + seed8*y + seed10*z + (rnum >> 2)) : 0; 1401e5c31af7Sopenharmony_ci 1402e5c31af7Sopenharmony_ci return a >= b && a >= c && a >= d ? 0 1403e5c31af7Sopenharmony_ci : b >= c && b >= d ? 1 1404e5c31af7Sopenharmony_ci : c >= d ? 2 1405e5c31af7Sopenharmony_ci : 3; 1406e5c31af7Sopenharmony_ci} 1407e5c31af7Sopenharmony_ci 1408e5c31af7Sopenharmony_ciDecompressResult setTexelColors (void* dst, ColorEndpointPair* colorEndpoints, TexelWeightPair* texelWeights, int ccs, deUint32 partitionIndexSeed, 1409e5c31af7Sopenharmony_ci int numPartitions, int blockWidth, int blockHeight, bool isSRGB, bool isLDRMode, const deUint32* colorEndpointModes) 1410e5c31af7Sopenharmony_ci{ 1411e5c31af7Sopenharmony_ci const bool smallBlock = blockWidth*blockHeight < 31; 1412e5c31af7Sopenharmony_ci DecompressResult result = DECOMPRESS_RESULT_VALID_BLOCK; 1413e5c31af7Sopenharmony_ci bool isHDREndpoint[4]; 1414e5c31af7Sopenharmony_ci 1415e5c31af7Sopenharmony_ci for (int i = 0; i < numPartitions; i++) 1416e5c31af7Sopenharmony_ci isHDREndpoint[i] = isColorEndpointModeHDR(colorEndpointModes[i]); 1417e5c31af7Sopenharmony_ci 1418e5c31af7Sopenharmony_ci for (int texelY = 0; texelY < blockHeight; texelY++) 1419e5c31af7Sopenharmony_ci for (int texelX = 0; texelX < blockWidth; texelX++) 1420e5c31af7Sopenharmony_ci { 1421e5c31af7Sopenharmony_ci const int texelNdx = texelY*blockWidth + texelX; 1422e5c31af7Sopenharmony_ci const int colorEndpointNdx = numPartitions == 1 ? 0 : computeTexelPartition(partitionIndexSeed, texelX, texelY, 0, numPartitions, smallBlock); 1423e5c31af7Sopenharmony_ci DE_ASSERT(colorEndpointNdx < numPartitions); 1424e5c31af7Sopenharmony_ci const UVec4& e0 = colorEndpoints[colorEndpointNdx].e0; 1425e5c31af7Sopenharmony_ci const UVec4& e1 = colorEndpoints[colorEndpointNdx].e1; 1426e5c31af7Sopenharmony_ci const TexelWeightPair& weight = texelWeights[texelNdx]; 1427e5c31af7Sopenharmony_ci 1428e5c31af7Sopenharmony_ci if (isLDRMode && isHDREndpoint[colorEndpointNdx]) 1429e5c31af7Sopenharmony_ci { 1430e5c31af7Sopenharmony_ci if (isSRGB) 1431e5c31af7Sopenharmony_ci { 1432e5c31af7Sopenharmony_ci ((deUint8*)dst)[texelNdx*4 + 0] = 0xff; 1433e5c31af7Sopenharmony_ci ((deUint8*)dst)[texelNdx*4 + 1] = 0; 1434e5c31af7Sopenharmony_ci ((deUint8*)dst)[texelNdx*4 + 2] = 0xff; 1435e5c31af7Sopenharmony_ci ((deUint8*)dst)[texelNdx*4 + 3] = 0xff; 1436e5c31af7Sopenharmony_ci } 1437e5c31af7Sopenharmony_ci else 1438e5c31af7Sopenharmony_ci { 1439e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + 0] = 1.0f; 1440e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + 1] = 0; 1441e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + 2] = 1.0f; 1442e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + 3] = 1.0f; 1443e5c31af7Sopenharmony_ci } 1444e5c31af7Sopenharmony_ci 1445e5c31af7Sopenharmony_ci result = DECOMPRESS_RESULT_ERROR; 1446e5c31af7Sopenharmony_ci } 1447e5c31af7Sopenharmony_ci else 1448e5c31af7Sopenharmony_ci { 1449e5c31af7Sopenharmony_ci for (int channelNdx = 0; channelNdx < 4; channelNdx++) 1450e5c31af7Sopenharmony_ci { 1451e5c31af7Sopenharmony_ci if (!isHDREndpoint[colorEndpointNdx] || (channelNdx == 3 && colorEndpointModes[colorEndpointNdx] == 14)) // \note Alpha for mode 14 is treated the same as LDR. 1452e5c31af7Sopenharmony_ci { 1453e5c31af7Sopenharmony_ci const deUint32 c0 = (e0[channelNdx] << 8) | (isSRGB ? 0x80 : e0[channelNdx]); 1454e5c31af7Sopenharmony_ci const deUint32 c1 = (e1[channelNdx] << 8) | (isSRGB ? 0x80 : e1[channelNdx]); 1455e5c31af7Sopenharmony_ci const deUint32 w = weight.w[ccs == channelNdx ? 1 : 0]; 1456e5c31af7Sopenharmony_ci const deUint32 c = (c0*(64-w) + c1*w + 32) / 64; 1457e5c31af7Sopenharmony_ci 1458e5c31af7Sopenharmony_ci if (isSRGB) 1459e5c31af7Sopenharmony_ci ((deUint8*)dst)[texelNdx*4 + channelNdx] = (deUint8)((c & 0xff00) >> 8); 1460e5c31af7Sopenharmony_ci else 1461e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + channelNdx] = c == 65535 ? 1.0f : (float)c / 65536.0f; 1462e5c31af7Sopenharmony_ci } 1463e5c31af7Sopenharmony_ci else 1464e5c31af7Sopenharmony_ci { 1465e5c31af7Sopenharmony_ci DE_STATIC_ASSERT((de::meta::TypesSame<deFloat16, deUint16>::Value)); 1466e5c31af7Sopenharmony_ci const deUint32 c0 = e0[channelNdx] << 4; 1467e5c31af7Sopenharmony_ci const deUint32 c1 = e1[channelNdx] << 4; 1468e5c31af7Sopenharmony_ci const deUint32 w = weight.w[ccs == channelNdx ? 1 : 0]; 1469e5c31af7Sopenharmony_ci const deUint32 c = (c0*(64-w) + c1*w + 32) / 64; 1470e5c31af7Sopenharmony_ci const deUint32 e = getBits(c, 11, 15); 1471e5c31af7Sopenharmony_ci const deUint32 m = getBits(c, 0, 10); 1472e5c31af7Sopenharmony_ci const deUint32 mt = m < 512 ? 3*m 1473e5c31af7Sopenharmony_ci : m >= 1536 ? 5*m - 2048 1474e5c31af7Sopenharmony_ci : 4*m - 512; 1475e5c31af7Sopenharmony_ci const deFloat16 cf = (deFloat16)((e << 10) + (mt >> 3)); 1476e5c31af7Sopenharmony_ci 1477e5c31af7Sopenharmony_ci ((float*)dst)[texelNdx*4 + channelNdx] = deFloat16To32(isFloat16InfOrNan(cf) ? 0x7bff : cf); 1478e5c31af7Sopenharmony_ci } 1479e5c31af7Sopenharmony_ci } 1480e5c31af7Sopenharmony_ci } 1481e5c31af7Sopenharmony_ci } 1482e5c31af7Sopenharmony_ci 1483e5c31af7Sopenharmony_ci return result; 1484e5c31af7Sopenharmony_ci} 1485e5c31af7Sopenharmony_ci 1486e5c31af7Sopenharmony_ciDecompressResult decompressBlock (void* dst, const Block128& blockData, int blockWidth, int blockHeight, bool isSRGB, bool isLDR) 1487e5c31af7Sopenharmony_ci{ 1488e5c31af7Sopenharmony_ci DE_ASSERT(isLDR || !isSRGB); 1489e5c31af7Sopenharmony_ci 1490e5c31af7Sopenharmony_ci // Decode block mode. 1491e5c31af7Sopenharmony_ci 1492e5c31af7Sopenharmony_ci const ASTCBlockMode blockMode = getASTCBlockMode(blockData.getBits(0, 10)); 1493e5c31af7Sopenharmony_ci 1494e5c31af7Sopenharmony_ci // Check for block mode errors. 1495e5c31af7Sopenharmony_ci 1496e5c31af7Sopenharmony_ci if (blockMode.isError) 1497e5c31af7Sopenharmony_ci { 1498e5c31af7Sopenharmony_ci setASTCErrorColorBlock(dst, blockWidth, blockHeight, isSRGB); 1499e5c31af7Sopenharmony_ci return DECOMPRESS_RESULT_ERROR; 1500e5c31af7Sopenharmony_ci } 1501e5c31af7Sopenharmony_ci 1502e5c31af7Sopenharmony_ci // Separate path for void-extent. 1503e5c31af7Sopenharmony_ci 1504e5c31af7Sopenharmony_ci if (blockMode.isVoidExtent) 1505e5c31af7Sopenharmony_ci return decodeVoidExtentBlock(dst, blockData, blockWidth, blockHeight, isSRGB, isLDR); 1506e5c31af7Sopenharmony_ci 1507e5c31af7Sopenharmony_ci // Compute weight grid values. 1508e5c31af7Sopenharmony_ci 1509e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockMode); 1510e5c31af7Sopenharmony_ci const int numWeightDataBits = computeNumRequiredBits(blockMode.weightISEParams, numWeights); 1511e5c31af7Sopenharmony_ci const int numPartitions = (int)blockData.getBits(11, 12) + 1; 1512e5c31af7Sopenharmony_ci 1513e5c31af7Sopenharmony_ci // Check for errors in weight grid, partition and dual-plane parameters. 1514e5c31af7Sopenharmony_ci 1515e5c31af7Sopenharmony_ci if (numWeights > 64 || 1516e5c31af7Sopenharmony_ci numWeightDataBits > 96 || 1517e5c31af7Sopenharmony_ci numWeightDataBits < 24 || 1518e5c31af7Sopenharmony_ci blockMode.weightGridWidth > blockWidth || 1519e5c31af7Sopenharmony_ci blockMode.weightGridHeight > blockHeight || 1520e5c31af7Sopenharmony_ci (numPartitions == 4 && blockMode.isDualPlane)) 1521e5c31af7Sopenharmony_ci { 1522e5c31af7Sopenharmony_ci setASTCErrorColorBlock(dst, blockWidth, blockHeight, isSRGB); 1523e5c31af7Sopenharmony_ci return DECOMPRESS_RESULT_ERROR; 1524e5c31af7Sopenharmony_ci } 1525e5c31af7Sopenharmony_ci 1526e5c31af7Sopenharmony_ci // Compute number of bits available for color endpoint data. 1527e5c31af7Sopenharmony_ci 1528e5c31af7Sopenharmony_ci const bool isSingleUniqueCem = numPartitions == 1 || blockData.getBits(23, 24) == 0; 1529e5c31af7Sopenharmony_ci const int numConfigDataBits = (numPartitions == 1 ? 17 : isSingleUniqueCem ? 29 : 25 + 3*numPartitions) + 1530e5c31af7Sopenharmony_ci (blockMode.isDualPlane ? 2 : 0); 1531e5c31af7Sopenharmony_ci const int numBitsForColorEndpoints = 128 - numWeightDataBits - numConfigDataBits; 1532e5c31af7Sopenharmony_ci const int extraCemBitsStart = 127 - numWeightDataBits - (isSingleUniqueCem ? -1 1533e5c31af7Sopenharmony_ci : numPartitions == 4 ? 7 1534e5c31af7Sopenharmony_ci : numPartitions == 3 ? 4 1535e5c31af7Sopenharmony_ci : numPartitions == 2 ? 1 1536e5c31af7Sopenharmony_ci : 0); 1537e5c31af7Sopenharmony_ci // Decode color endpoint modes. 1538e5c31af7Sopenharmony_ci 1539e5c31af7Sopenharmony_ci deUint32 colorEndpointModes[4]; 1540e5c31af7Sopenharmony_ci decodeColorEndpointModes(&colorEndpointModes[0], blockData, numPartitions, extraCemBitsStart); 1541e5c31af7Sopenharmony_ci 1542e5c31af7Sopenharmony_ci const int numColorEndpointValues = computeNumColorEndpointValues(colorEndpointModes, numPartitions); 1543e5c31af7Sopenharmony_ci 1544e5c31af7Sopenharmony_ci // Check for errors in color endpoint value count. 1545e5c31af7Sopenharmony_ci 1546e5c31af7Sopenharmony_ci if (numColorEndpointValues > 18 || numBitsForColorEndpoints < deDivRoundUp32(13*numColorEndpointValues, 5)) 1547e5c31af7Sopenharmony_ci { 1548e5c31af7Sopenharmony_ci setASTCErrorColorBlock(dst, blockWidth, blockHeight, isSRGB); 1549e5c31af7Sopenharmony_ci return DECOMPRESS_RESULT_ERROR; 1550e5c31af7Sopenharmony_ci } 1551e5c31af7Sopenharmony_ci 1552e5c31af7Sopenharmony_ci // Compute color endpoints. 1553e5c31af7Sopenharmony_ci 1554e5c31af7Sopenharmony_ci ColorEndpointPair colorEndpoints[4]; 1555e5c31af7Sopenharmony_ci computeColorEndpoints(&colorEndpoints[0], blockData, &colorEndpointModes[0], numPartitions, numColorEndpointValues, 1556e5c31af7Sopenharmony_ci computeMaximumRangeISEParams(numBitsForColorEndpoints, numColorEndpointValues), numBitsForColorEndpoints); 1557e5c31af7Sopenharmony_ci 1558e5c31af7Sopenharmony_ci // Compute texel weights. 1559e5c31af7Sopenharmony_ci 1560e5c31af7Sopenharmony_ci TexelWeightPair texelWeights[MAX_BLOCK_WIDTH*MAX_BLOCK_HEIGHT]; 1561e5c31af7Sopenharmony_ci computeTexelWeights(&texelWeights[0], blockData, blockWidth, blockHeight, blockMode); 1562e5c31af7Sopenharmony_ci 1563e5c31af7Sopenharmony_ci // Set texel colors. 1564e5c31af7Sopenharmony_ci 1565e5c31af7Sopenharmony_ci const int ccs = blockMode.isDualPlane ? (int)blockData.getBits(extraCemBitsStart-2, extraCemBitsStart-1) : -1; 1566e5c31af7Sopenharmony_ci const deUint32 partitionIndexSeed = numPartitions > 1 ? blockData.getBits(13, 22) : (deUint32)-1; 1567e5c31af7Sopenharmony_ci 1568e5c31af7Sopenharmony_ci return setTexelColors(dst, &colorEndpoints[0], &texelWeights[0], ccs, partitionIndexSeed, numPartitions, blockWidth, blockHeight, isSRGB, isLDR, &colorEndpointModes[0]); 1569e5c31af7Sopenharmony_ci} 1570e5c31af7Sopenharmony_ci 1571e5c31af7Sopenharmony_civoid decompress (const PixelBufferAccess& dst, const deUint8* data, bool isSRGB, bool isLDR) 1572e5c31af7Sopenharmony_ci{ 1573e5c31af7Sopenharmony_ci DE_ASSERT(isLDR || !isSRGB); 1574e5c31af7Sopenharmony_ci 1575e5c31af7Sopenharmony_ci const int blockWidth = dst.getWidth(); 1576e5c31af7Sopenharmony_ci const int blockHeight = dst.getHeight(); 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_ci union 1579e5c31af7Sopenharmony_ci { 1580e5c31af7Sopenharmony_ci deUint8 sRGB[MAX_BLOCK_WIDTH*MAX_BLOCK_HEIGHT*4]; 1581e5c31af7Sopenharmony_ci float linear[MAX_BLOCK_WIDTH*MAX_BLOCK_HEIGHT*4]; 1582e5c31af7Sopenharmony_ci } decompressedBuffer; 1583e5c31af7Sopenharmony_ci 1584e5c31af7Sopenharmony_ci const Block128 blockData(data); 1585e5c31af7Sopenharmony_ci decompressBlock(isSRGB ? (void*)&decompressedBuffer.sRGB[0] : (void*)&decompressedBuffer.linear[0], 1586e5c31af7Sopenharmony_ci blockData, dst.getWidth(), dst.getHeight(), isSRGB, isLDR); 1587e5c31af7Sopenharmony_ci 1588e5c31af7Sopenharmony_ci if (isSRGB) 1589e5c31af7Sopenharmony_ci { 1590e5c31af7Sopenharmony_ci for (int i = 0; i < blockHeight; i++) 1591e5c31af7Sopenharmony_ci for (int j = 0; j < blockWidth; j++) 1592e5c31af7Sopenharmony_ci { 1593e5c31af7Sopenharmony_ci dst.setPixel(IVec4(decompressedBuffer.sRGB[(i*blockWidth + j) * 4 + 0], 1594e5c31af7Sopenharmony_ci decompressedBuffer.sRGB[(i*blockWidth + j) * 4 + 1], 1595e5c31af7Sopenharmony_ci decompressedBuffer.sRGB[(i*blockWidth + j) * 4 + 2], 1596e5c31af7Sopenharmony_ci decompressedBuffer.sRGB[(i*blockWidth + j) * 4 + 3]), j, i); 1597e5c31af7Sopenharmony_ci } 1598e5c31af7Sopenharmony_ci } 1599e5c31af7Sopenharmony_ci else 1600e5c31af7Sopenharmony_ci { 1601e5c31af7Sopenharmony_ci for (int i = 0; i < blockHeight; i++) 1602e5c31af7Sopenharmony_ci for (int j = 0; j < blockWidth; j++) 1603e5c31af7Sopenharmony_ci { 1604e5c31af7Sopenharmony_ci dst.setPixel(Vec4(decompressedBuffer.linear[(i*blockWidth + j) * 4 + 0], 1605e5c31af7Sopenharmony_ci decompressedBuffer.linear[(i*blockWidth + j) * 4 + 1], 1606e5c31af7Sopenharmony_ci decompressedBuffer.linear[(i*blockWidth + j) * 4 + 2], 1607e5c31af7Sopenharmony_ci decompressedBuffer.linear[(i*blockWidth + j) * 4 + 3]), j, i); 1608e5c31af7Sopenharmony_ci } 1609e5c31af7Sopenharmony_ci } 1610e5c31af7Sopenharmony_ci} 1611e5c31af7Sopenharmony_ci 1612e5c31af7Sopenharmony_ci// Helper class for setting bits in a 128-bit block. 1613e5c31af7Sopenharmony_ciclass AssignBlock128 1614e5c31af7Sopenharmony_ci{ 1615e5c31af7Sopenharmony_ciprivate: 1616e5c31af7Sopenharmony_ci typedef deUint64 Word; 1617e5c31af7Sopenharmony_ci 1618e5c31af7Sopenharmony_ci enum 1619e5c31af7Sopenharmony_ci { 1620e5c31af7Sopenharmony_ci WORD_BYTES = sizeof(Word), 1621e5c31af7Sopenharmony_ci WORD_BITS = 8*WORD_BYTES, 1622e5c31af7Sopenharmony_ci NUM_WORDS = 128 / WORD_BITS 1623e5c31af7Sopenharmony_ci }; 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(128 % WORD_BITS == 0); 1626e5c31af7Sopenharmony_ci 1627e5c31af7Sopenharmony_cipublic: 1628e5c31af7Sopenharmony_ci AssignBlock128 (void) 1629e5c31af7Sopenharmony_ci { 1630e5c31af7Sopenharmony_ci for (int wordNdx = 0; wordNdx < NUM_WORDS; wordNdx++) 1631e5c31af7Sopenharmony_ci m_words[wordNdx] = 0; 1632e5c31af7Sopenharmony_ci } 1633e5c31af7Sopenharmony_ci 1634e5c31af7Sopenharmony_ci void setBit (int ndx, deUint32 val) 1635e5c31af7Sopenharmony_ci { 1636e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(ndx, 0, 128)); 1637e5c31af7Sopenharmony_ci DE_ASSERT((val & 1) == val); 1638e5c31af7Sopenharmony_ci const int wordNdx = ndx / WORD_BITS; 1639e5c31af7Sopenharmony_ci const int bitNdx = ndx % WORD_BITS; 1640e5c31af7Sopenharmony_ci m_words[wordNdx] = (m_words[wordNdx] & ~((Word)1 << bitNdx)) | ((Word)val << bitNdx); 1641e5c31af7Sopenharmony_ci } 1642e5c31af7Sopenharmony_ci 1643e5c31af7Sopenharmony_ci void setBits (int low, int high, deUint32 bits) 1644e5c31af7Sopenharmony_ci { 1645e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(low, 0, 128)); 1646e5c31af7Sopenharmony_ci DE_ASSERT(de::inBounds(high, 0, 128)); 1647e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(high-low+1, 0, 32)); 1648e5c31af7Sopenharmony_ci DE_ASSERT((bits & (((Word)1 << (high-low+1)) - 1)) == bits); 1649e5c31af7Sopenharmony_ci 1650e5c31af7Sopenharmony_ci if (high-low+1 == 0) 1651e5c31af7Sopenharmony_ci return; 1652e5c31af7Sopenharmony_ci 1653e5c31af7Sopenharmony_ci const int word0Ndx = low / WORD_BITS; 1654e5c31af7Sopenharmony_ci const int word1Ndx = high / WORD_BITS; 1655e5c31af7Sopenharmony_ci const int lowNdxInW0 = low % WORD_BITS; 1656e5c31af7Sopenharmony_ci 1657e5c31af7Sopenharmony_ci if (word0Ndx == word1Ndx) 1658e5c31af7Sopenharmony_ci m_words[word0Ndx] = (m_words[word0Ndx] & ~((((Word)1 << (high-low+1)) - 1) << lowNdxInW0)) | ((Word)bits << lowNdxInW0); 1659e5c31af7Sopenharmony_ci else 1660e5c31af7Sopenharmony_ci { 1661e5c31af7Sopenharmony_ci DE_ASSERT(word1Ndx == word0Ndx + 1); 1662e5c31af7Sopenharmony_ci 1663e5c31af7Sopenharmony_ci const int highNdxInW1 = high % WORD_BITS; 1664e5c31af7Sopenharmony_ci const int numBitsToSetInW0 = WORD_BITS - lowNdxInW0; 1665e5c31af7Sopenharmony_ci const Word bitsLowMask = ((Word)1 << numBitsToSetInW0) - 1; 1666e5c31af7Sopenharmony_ci 1667e5c31af7Sopenharmony_ci m_words[word0Ndx] = (m_words[word0Ndx] & (((Word)1 << lowNdxInW0) - 1)) | (((Word)bits & bitsLowMask) << lowNdxInW0); 1668e5c31af7Sopenharmony_ci m_words[word1Ndx] = (m_words[word1Ndx] & ~(((Word)1 << (highNdxInW1+1)) - 1)) | (((Word)bits & ~bitsLowMask) >> numBitsToSetInW0); 1669e5c31af7Sopenharmony_ci } 1670e5c31af7Sopenharmony_ci } 1671e5c31af7Sopenharmony_ci 1672e5c31af7Sopenharmony_ci void assignToMemory (deUint8* dst) const 1673e5c31af7Sopenharmony_ci { 1674e5c31af7Sopenharmony_ci for (int wordNdx = 0; wordNdx < NUM_WORDS; wordNdx++) 1675e5c31af7Sopenharmony_ci { 1676e5c31af7Sopenharmony_ci for (int byteNdx = 0; byteNdx < WORD_BYTES; byteNdx++) 1677e5c31af7Sopenharmony_ci dst[wordNdx*WORD_BYTES + byteNdx] = (deUint8)((m_words[wordNdx] >> (8*byteNdx)) & 0xff); 1678e5c31af7Sopenharmony_ci } 1679e5c31af7Sopenharmony_ci } 1680e5c31af7Sopenharmony_ci 1681e5c31af7Sopenharmony_ci void pushBytesToVector (vector<deUint8>& dst) const 1682e5c31af7Sopenharmony_ci { 1683e5c31af7Sopenharmony_ci const int assignStartIndex = (int)dst.size(); 1684e5c31af7Sopenharmony_ci dst.resize(dst.size() + BLOCK_SIZE_BYTES); 1685e5c31af7Sopenharmony_ci assignToMemory(&dst[assignStartIndex]); 1686e5c31af7Sopenharmony_ci } 1687e5c31af7Sopenharmony_ci 1688e5c31af7Sopenharmony_ciprivate: 1689e5c31af7Sopenharmony_ci Word m_words[NUM_WORDS]; 1690e5c31af7Sopenharmony_ci}; 1691e5c31af7Sopenharmony_ci 1692e5c31af7Sopenharmony_ci// A helper for sequential access into a AssignBlock128. 1693e5c31af7Sopenharmony_ciclass BitAssignAccessStream 1694e5c31af7Sopenharmony_ci{ 1695e5c31af7Sopenharmony_cipublic: 1696e5c31af7Sopenharmony_ci BitAssignAccessStream (AssignBlock128& dst, int startNdxInSrc, int length, bool forward) 1697e5c31af7Sopenharmony_ci : m_dst (dst) 1698e5c31af7Sopenharmony_ci , m_startNdxInSrc (startNdxInSrc) 1699e5c31af7Sopenharmony_ci , m_length (length) 1700e5c31af7Sopenharmony_ci , m_forward (forward) 1701e5c31af7Sopenharmony_ci , m_ndx (0) 1702e5c31af7Sopenharmony_ci { 1703e5c31af7Sopenharmony_ci } 1704e5c31af7Sopenharmony_ci 1705e5c31af7Sopenharmony_ci // Set the next num bits. Bits at positions greater than or equal to m_length are not touched. 1706e5c31af7Sopenharmony_ci void setNext (int num, deUint32 bits) 1707e5c31af7Sopenharmony_ci { 1708e5c31af7Sopenharmony_ci DE_ASSERT((bits & (((deUint64)1 << num) - 1)) == bits); 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci if (num == 0 || m_ndx >= m_length) 1711e5c31af7Sopenharmony_ci return; 1712e5c31af7Sopenharmony_ci 1713e5c31af7Sopenharmony_ci const int end = m_ndx + num; 1714e5c31af7Sopenharmony_ci const int numBitsToDst = de::max(0, de::min(m_length, end) - m_ndx); 1715e5c31af7Sopenharmony_ci const int low = m_ndx; 1716e5c31af7Sopenharmony_ci const int high = m_ndx + numBitsToDst - 1; 1717e5c31af7Sopenharmony_ci const deUint32 actualBits = getBits(bits, 0, numBitsToDst-1); 1718e5c31af7Sopenharmony_ci 1719e5c31af7Sopenharmony_ci m_ndx += num; 1720e5c31af7Sopenharmony_ci 1721e5c31af7Sopenharmony_ci return m_forward ? m_dst.setBits(m_startNdxInSrc + low, m_startNdxInSrc + high, actualBits) 1722e5c31af7Sopenharmony_ci : m_dst.setBits(m_startNdxInSrc - high, m_startNdxInSrc - low, reverseBits(actualBits, numBitsToDst)); 1723e5c31af7Sopenharmony_ci } 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ciprivate: 1726e5c31af7Sopenharmony_ci AssignBlock128& m_dst; 1727e5c31af7Sopenharmony_ci const int m_startNdxInSrc; 1728e5c31af7Sopenharmony_ci const int m_length; 1729e5c31af7Sopenharmony_ci const bool m_forward; 1730e5c31af7Sopenharmony_ci 1731e5c31af7Sopenharmony_ci int m_ndx; 1732e5c31af7Sopenharmony_ci}; 1733e5c31af7Sopenharmony_ci 1734e5c31af7Sopenharmony_cistruct VoidExtentParams 1735e5c31af7Sopenharmony_ci{ 1736e5c31af7Sopenharmony_ci DE_STATIC_ASSERT((de::meta::TypesSame<deFloat16, deUint16>::Value)); 1737e5c31af7Sopenharmony_ci bool isHDR; 1738e5c31af7Sopenharmony_ci deUint16 r; 1739e5c31af7Sopenharmony_ci deUint16 g; 1740e5c31af7Sopenharmony_ci deUint16 b; 1741e5c31af7Sopenharmony_ci deUint16 a; 1742e5c31af7Sopenharmony_ci // \note Currently extent coordinates are all set to all-ones. 1743e5c31af7Sopenharmony_ci 1744e5c31af7Sopenharmony_ci VoidExtentParams (bool isHDR_, deUint16 r_, deUint16 g_, deUint16 b_, deUint16 a_) : isHDR(isHDR_), r(r_), g(g_), b(b_), a(a_) {} 1745e5c31af7Sopenharmony_ci}; 1746e5c31af7Sopenharmony_ci 1747e5c31af7Sopenharmony_cistatic AssignBlock128 generateVoidExtentBlock (const VoidExtentParams& params) 1748e5c31af7Sopenharmony_ci{ 1749e5c31af7Sopenharmony_ci AssignBlock128 block; 1750e5c31af7Sopenharmony_ci 1751e5c31af7Sopenharmony_ci block.setBits(0, 8, 0x1fc); // \note Marks void-extent block. 1752e5c31af7Sopenharmony_ci block.setBit(9, params.isHDR); 1753e5c31af7Sopenharmony_ci block.setBits(10, 11, 3); // \note Spec shows that these bits are both set, although they serve no purpose. 1754e5c31af7Sopenharmony_ci 1755e5c31af7Sopenharmony_ci // Extent coordinates - currently all-ones. 1756e5c31af7Sopenharmony_ci block.setBits(12, 24, 0x1fff); 1757e5c31af7Sopenharmony_ci block.setBits(25, 37, 0x1fff); 1758e5c31af7Sopenharmony_ci block.setBits(38, 50, 0x1fff); 1759e5c31af7Sopenharmony_ci block.setBits(51, 63, 0x1fff); 1760e5c31af7Sopenharmony_ci 1761e5c31af7Sopenharmony_ci DE_ASSERT(!params.isHDR || (!isFloat16InfOrNan(params.r) && 1762e5c31af7Sopenharmony_ci !isFloat16InfOrNan(params.g) && 1763e5c31af7Sopenharmony_ci !isFloat16InfOrNan(params.b) && 1764e5c31af7Sopenharmony_ci !isFloat16InfOrNan(params.a))); 1765e5c31af7Sopenharmony_ci 1766e5c31af7Sopenharmony_ci block.setBits(64, 79, params.r); 1767e5c31af7Sopenharmony_ci block.setBits(80, 95, params.g); 1768e5c31af7Sopenharmony_ci block.setBits(96, 111, params.b); 1769e5c31af7Sopenharmony_ci block.setBits(112, 127, params.a); 1770e5c31af7Sopenharmony_ci 1771e5c31af7Sopenharmony_ci return block; 1772e5c31af7Sopenharmony_ci} 1773e5c31af7Sopenharmony_ci 1774e5c31af7Sopenharmony_ci// An input array of ISE inputs for an entire ASTC block. Can be given as either single values in the 1775e5c31af7Sopenharmony_ci// range [0, maximumValueOfISERange] or as explicit block value specifications. The latter is needed 1776e5c31af7Sopenharmony_ci// so we can test all possible values of T and Q in a block, since multiple T or Q values may map 1777e5c31af7Sopenharmony_ci// to the same set of decoded values. 1778e5c31af7Sopenharmony_cistruct ISEInput 1779e5c31af7Sopenharmony_ci{ 1780e5c31af7Sopenharmony_ci struct Block 1781e5c31af7Sopenharmony_ci { 1782e5c31af7Sopenharmony_ci deUint32 tOrQValue; //!< The 8-bit T or 7-bit Q in a trit or quint ISE block. 1783e5c31af7Sopenharmony_ci deUint32 bitValues[5]; 1784e5c31af7Sopenharmony_ci }; 1785e5c31af7Sopenharmony_ci 1786e5c31af7Sopenharmony_ci bool isGivenInBlockForm; 1787e5c31af7Sopenharmony_ci union 1788e5c31af7Sopenharmony_ci { 1789e5c31af7Sopenharmony_ci //!< \note 64 comes from the maximum number of weight values in an ASTC block. 1790e5c31af7Sopenharmony_ci deUint32 plain[64]; 1791e5c31af7Sopenharmony_ci Block block[64]; 1792e5c31af7Sopenharmony_ci } value; 1793e5c31af7Sopenharmony_ci 1794e5c31af7Sopenharmony_ci ISEInput (void) 1795e5c31af7Sopenharmony_ci : isGivenInBlockForm (false) 1796e5c31af7Sopenharmony_ci { 1797e5c31af7Sopenharmony_ci } 1798e5c31af7Sopenharmony_ci}; 1799e5c31af7Sopenharmony_ci 1800e5c31af7Sopenharmony_cistatic inline deUint32 computeISERangeMax (const ISEParams& iseParams) 1801e5c31af7Sopenharmony_ci{ 1802e5c31af7Sopenharmony_ci switch (iseParams.mode) 1803e5c31af7Sopenharmony_ci { 1804e5c31af7Sopenharmony_ci case ISEMODE_TRIT: return (1u << iseParams.numBits) * 3 - 1; 1805e5c31af7Sopenharmony_ci case ISEMODE_QUINT: return (1u << iseParams.numBits) * 5 - 1; 1806e5c31af7Sopenharmony_ci case ISEMODE_PLAIN_BIT: return (1u << iseParams.numBits) - 1; 1807e5c31af7Sopenharmony_ci default: 1808e5c31af7Sopenharmony_ci DE_ASSERT(false); 1809e5c31af7Sopenharmony_ci return -1; 1810e5c31af7Sopenharmony_ci } 1811e5c31af7Sopenharmony_ci} 1812e5c31af7Sopenharmony_ci 1813e5c31af7Sopenharmony_cistruct NormalBlockParams 1814e5c31af7Sopenharmony_ci{ 1815e5c31af7Sopenharmony_ci int weightGridWidth; 1816e5c31af7Sopenharmony_ci int weightGridHeight; 1817e5c31af7Sopenharmony_ci ISEParams weightISEParams; 1818e5c31af7Sopenharmony_ci bool isDualPlane; 1819e5c31af7Sopenharmony_ci deUint32 ccs; //! \note Irrelevant if !isDualPlane. 1820e5c31af7Sopenharmony_ci int numPartitions; 1821e5c31af7Sopenharmony_ci deUint32 colorEndpointModes[4]; 1822e5c31af7Sopenharmony_ci // \note Below members are irrelevant if numPartitions == 1. 1823e5c31af7Sopenharmony_ci bool isMultiPartSingleCemMode; //! \note If true, the single CEM is at colorEndpointModes[0]. 1824e5c31af7Sopenharmony_ci deUint32 partitionSeed; 1825e5c31af7Sopenharmony_ci 1826e5c31af7Sopenharmony_ci NormalBlockParams (void) 1827e5c31af7Sopenharmony_ci : weightGridWidth (-1) 1828e5c31af7Sopenharmony_ci , weightGridHeight (-1) 1829e5c31af7Sopenharmony_ci , weightISEParams (ISEMODE_LAST, -1) 1830e5c31af7Sopenharmony_ci , isDualPlane (true) 1831e5c31af7Sopenharmony_ci , ccs ((deUint32)-1) 1832e5c31af7Sopenharmony_ci , numPartitions (-1) 1833e5c31af7Sopenharmony_ci , isMultiPartSingleCemMode (false) 1834e5c31af7Sopenharmony_ci , partitionSeed ((deUint32)-1) 1835e5c31af7Sopenharmony_ci { 1836e5c31af7Sopenharmony_ci colorEndpointModes[0] = 0; 1837e5c31af7Sopenharmony_ci colorEndpointModes[1] = 0; 1838e5c31af7Sopenharmony_ci colorEndpointModes[2] = 0; 1839e5c31af7Sopenharmony_ci colorEndpointModes[3] = 0; 1840e5c31af7Sopenharmony_ci } 1841e5c31af7Sopenharmony_ci}; 1842e5c31af7Sopenharmony_ci 1843e5c31af7Sopenharmony_cistruct NormalBlockISEInputs 1844e5c31af7Sopenharmony_ci{ 1845e5c31af7Sopenharmony_ci ISEInput weight; 1846e5c31af7Sopenharmony_ci ISEInput endpoint; 1847e5c31af7Sopenharmony_ci 1848e5c31af7Sopenharmony_ci NormalBlockISEInputs (void) 1849e5c31af7Sopenharmony_ci : weight () 1850e5c31af7Sopenharmony_ci , endpoint () 1851e5c31af7Sopenharmony_ci { 1852e5c31af7Sopenharmony_ci } 1853e5c31af7Sopenharmony_ci}; 1854e5c31af7Sopenharmony_ci 1855e5c31af7Sopenharmony_cistatic inline int computeNumWeights (const NormalBlockParams& params) 1856e5c31af7Sopenharmony_ci{ 1857e5c31af7Sopenharmony_ci return params.weightGridWidth * params.weightGridHeight * (params.isDualPlane ? 2 : 1); 1858e5c31af7Sopenharmony_ci} 1859e5c31af7Sopenharmony_ci 1860e5c31af7Sopenharmony_cistatic inline int computeNumBitsForColorEndpoints (const NormalBlockParams& params) 1861e5c31af7Sopenharmony_ci{ 1862e5c31af7Sopenharmony_ci const int numWeightBits = computeNumRequiredBits(params.weightISEParams, computeNumWeights(params)); 1863e5c31af7Sopenharmony_ci const int numConfigDataBits = (params.numPartitions == 1 ? 17 : params.isMultiPartSingleCemMode ? 29 : 25 + 3*params.numPartitions) + 1864e5c31af7Sopenharmony_ci (params.isDualPlane ? 2 : 0); 1865e5c31af7Sopenharmony_ci 1866e5c31af7Sopenharmony_ci return 128 - numWeightBits - numConfigDataBits; 1867e5c31af7Sopenharmony_ci} 1868e5c31af7Sopenharmony_ci 1869e5c31af7Sopenharmony_cistatic inline int computeNumColorEndpointValues (const deUint32* endpointModes, int numPartitions, bool isMultiPartSingleCemMode) 1870e5c31af7Sopenharmony_ci{ 1871e5c31af7Sopenharmony_ci if (isMultiPartSingleCemMode) 1872e5c31af7Sopenharmony_ci return numPartitions * computeNumColorEndpointValues(endpointModes[0]); 1873e5c31af7Sopenharmony_ci else 1874e5c31af7Sopenharmony_ci { 1875e5c31af7Sopenharmony_ci int result = 0; 1876e5c31af7Sopenharmony_ci for (int i = 0; i < numPartitions; i++) 1877e5c31af7Sopenharmony_ci result += computeNumColorEndpointValues(endpointModes[i]); 1878e5c31af7Sopenharmony_ci return result; 1879e5c31af7Sopenharmony_ci } 1880e5c31af7Sopenharmony_ci} 1881e5c31af7Sopenharmony_ci 1882e5c31af7Sopenharmony_cistatic inline bool isValidBlockParams (const NormalBlockParams& params, int blockWidth, int blockHeight) 1883e5c31af7Sopenharmony_ci{ 1884e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(params); 1885e5c31af7Sopenharmony_ci const int numWeightBits = computeNumRequiredBits(params.weightISEParams, numWeights); 1886e5c31af7Sopenharmony_ci const int numColorEndpointValues = computeNumColorEndpointValues(¶ms.colorEndpointModes[0], params.numPartitions, params.isMultiPartSingleCemMode); 1887e5c31af7Sopenharmony_ci const int numBitsForColorEndpoints = computeNumBitsForColorEndpoints(params); 1888e5c31af7Sopenharmony_ci 1889e5c31af7Sopenharmony_ci return numWeights <= 64 && 1890e5c31af7Sopenharmony_ci de::inRange(numWeightBits, 24, 96) && 1891e5c31af7Sopenharmony_ci params.weightGridWidth <= blockWidth && 1892e5c31af7Sopenharmony_ci params.weightGridHeight <= blockHeight && 1893e5c31af7Sopenharmony_ci !(params.numPartitions == 4 && params.isDualPlane) && 1894e5c31af7Sopenharmony_ci numColorEndpointValues <= 18 && 1895e5c31af7Sopenharmony_ci numBitsForColorEndpoints >= deDivRoundUp32(13*numColorEndpointValues, 5); 1896e5c31af7Sopenharmony_ci} 1897e5c31af7Sopenharmony_ci 1898e5c31af7Sopenharmony_ci// Write bits 0 to 10 of an ASTC block. 1899e5c31af7Sopenharmony_cistatic void writeBlockMode (AssignBlock128& dst, const NormalBlockParams& blockParams) 1900e5c31af7Sopenharmony_ci{ 1901e5c31af7Sopenharmony_ci const deUint32 d = blockParams.isDualPlane != 0; 1902e5c31af7Sopenharmony_ci // r and h initialized in switch below. 1903e5c31af7Sopenharmony_ci deUint32 r; 1904e5c31af7Sopenharmony_ci deUint32 h; 1905e5c31af7Sopenharmony_ci // a, b and blockModeLayoutNdx initialized in block mode layout index detecting loop below. 1906e5c31af7Sopenharmony_ci deUint32 a = (deUint32)-1; 1907e5c31af7Sopenharmony_ci deUint32 b = (deUint32)-1; 1908e5c31af7Sopenharmony_ci int blockModeLayoutNdx; 1909e5c31af7Sopenharmony_ci 1910e5c31af7Sopenharmony_ci // Find the values of r and h (ISE range). 1911e5c31af7Sopenharmony_ci switch (computeISERangeMax(blockParams.weightISEParams)) 1912e5c31af7Sopenharmony_ci { 1913e5c31af7Sopenharmony_ci case 1: r = 2; h = 0; break; 1914e5c31af7Sopenharmony_ci case 2: r = 3; h = 0; break; 1915e5c31af7Sopenharmony_ci case 3: r = 4; h = 0; break; 1916e5c31af7Sopenharmony_ci case 4: r = 5; h = 0; break; 1917e5c31af7Sopenharmony_ci case 5: r = 6; h = 0; break; 1918e5c31af7Sopenharmony_ci case 7: r = 7; h = 0; break; 1919e5c31af7Sopenharmony_ci 1920e5c31af7Sopenharmony_ci case 9: r = 2; h = 1; break; 1921e5c31af7Sopenharmony_ci case 11: r = 3; h = 1; break; 1922e5c31af7Sopenharmony_ci case 15: r = 4; h = 1; break; 1923e5c31af7Sopenharmony_ci case 19: r = 5; h = 1; break; 1924e5c31af7Sopenharmony_ci case 23: r = 6; h = 1; break; 1925e5c31af7Sopenharmony_ci case 31: r = 7; h = 1; break; 1926e5c31af7Sopenharmony_ci 1927e5c31af7Sopenharmony_ci default: 1928e5c31af7Sopenharmony_ci DE_ASSERT(false); 1929e5c31af7Sopenharmony_ci r = (deUint32)-1; 1930e5c31af7Sopenharmony_ci h = (deUint32)-1; 1931e5c31af7Sopenharmony_ci } 1932e5c31af7Sopenharmony_ci 1933e5c31af7Sopenharmony_ci // Find block mode layout index, i.e. appropriate row in the "2d block mode layout" table in ASTC spec. 1934e5c31af7Sopenharmony_ci 1935e5c31af7Sopenharmony_ci { 1936e5c31af7Sopenharmony_ci enum BlockModeLayoutABVariable { Z=0, A=1, B=2 }; 1937e5c31af7Sopenharmony_ci 1938e5c31af7Sopenharmony_ci static const struct BlockModeLayout 1939e5c31af7Sopenharmony_ci { 1940e5c31af7Sopenharmony_ci int aNumBits; 1941e5c31af7Sopenharmony_ci int bNumBits; 1942e5c31af7Sopenharmony_ci BlockModeLayoutABVariable gridWidthVariableTerm; 1943e5c31af7Sopenharmony_ci int gridWidthConstantTerm; 1944e5c31af7Sopenharmony_ci BlockModeLayoutABVariable gridHeightVariableTerm; 1945e5c31af7Sopenharmony_ci int gridHeightConstantTerm; 1946e5c31af7Sopenharmony_ci } blockModeLayouts[] = 1947e5c31af7Sopenharmony_ci { 1948e5c31af7Sopenharmony_ci { 2, 2, B, 4, A, 2}, 1949e5c31af7Sopenharmony_ci { 2, 2, B, 8, A, 2}, 1950e5c31af7Sopenharmony_ci { 2, 2, A, 2, B, 8}, 1951e5c31af7Sopenharmony_ci { 2, 1, A, 2, B, 6}, 1952e5c31af7Sopenharmony_ci { 2, 1, B, 2, A, 2}, 1953e5c31af7Sopenharmony_ci { 2, 0, Z, 12, A, 2}, 1954e5c31af7Sopenharmony_ci { 2, 0, A, 2, Z, 12}, 1955e5c31af7Sopenharmony_ci { 0, 0, Z, 6, Z, 10}, 1956e5c31af7Sopenharmony_ci { 0, 0, Z, 10, Z, 6}, 1957e5c31af7Sopenharmony_ci { 2, 2, A, 6, B, 6} 1958e5c31af7Sopenharmony_ci }; 1959e5c31af7Sopenharmony_ci 1960e5c31af7Sopenharmony_ci for (blockModeLayoutNdx = 0; blockModeLayoutNdx < DE_LENGTH_OF_ARRAY(blockModeLayouts); blockModeLayoutNdx++) 1961e5c31af7Sopenharmony_ci { 1962e5c31af7Sopenharmony_ci const BlockModeLayout& layout = blockModeLayouts[blockModeLayoutNdx]; 1963e5c31af7Sopenharmony_ci const int aMax = (1 << layout.aNumBits) - 1; 1964e5c31af7Sopenharmony_ci const int bMax = (1 << layout.bNumBits) - 1; 1965e5c31af7Sopenharmony_ci const int variableOffsetsMax[3] = { 0, aMax, bMax }; 1966e5c31af7Sopenharmony_ci const int widthMin = layout.gridWidthConstantTerm; 1967e5c31af7Sopenharmony_ci const int heightMin = layout.gridHeightConstantTerm; 1968e5c31af7Sopenharmony_ci const int widthMax = widthMin + variableOffsetsMax[layout.gridWidthVariableTerm]; 1969e5c31af7Sopenharmony_ci const int heightMax = heightMin + variableOffsetsMax[layout.gridHeightVariableTerm]; 1970e5c31af7Sopenharmony_ci 1971e5c31af7Sopenharmony_ci DE_ASSERT(layout.gridWidthVariableTerm != layout.gridHeightVariableTerm || layout.gridWidthVariableTerm == Z); 1972e5c31af7Sopenharmony_ci 1973e5c31af7Sopenharmony_ci if (de::inRange(blockParams.weightGridWidth, widthMin, widthMax) && 1974e5c31af7Sopenharmony_ci de::inRange(blockParams.weightGridHeight, heightMin, heightMax)) 1975e5c31af7Sopenharmony_ci { 1976e5c31af7Sopenharmony_ci deUint32 defaultvalue = 0; 1977e5c31af7Sopenharmony_ci deUint32& widthVariable = layout.gridWidthVariableTerm == A ? a : layout.gridWidthVariableTerm == B ? b : defaultvalue; 1978e5c31af7Sopenharmony_ci deUint32& heightVariable = layout.gridHeightVariableTerm == A ? a : layout.gridHeightVariableTerm == B ? b : defaultvalue; 1979e5c31af7Sopenharmony_ci 1980e5c31af7Sopenharmony_ci widthVariable = blockParams.weightGridWidth - layout.gridWidthConstantTerm; 1981e5c31af7Sopenharmony_ci heightVariable = blockParams.weightGridHeight - layout.gridHeightConstantTerm; 1982e5c31af7Sopenharmony_ci 1983e5c31af7Sopenharmony_ci break; 1984e5c31af7Sopenharmony_ci } 1985e5c31af7Sopenharmony_ci } 1986e5c31af7Sopenharmony_ci } 1987e5c31af7Sopenharmony_ci 1988e5c31af7Sopenharmony_ci // Set block mode bits. 1989e5c31af7Sopenharmony_ci 1990e5c31af7Sopenharmony_ci const deUint32 a0 = getBit(a, 0); 1991e5c31af7Sopenharmony_ci const deUint32 a1 = getBit(a, 1); 1992e5c31af7Sopenharmony_ci const deUint32 b0 = getBit(b, 0); 1993e5c31af7Sopenharmony_ci const deUint32 b1 = getBit(b, 1); 1994e5c31af7Sopenharmony_ci const deUint32 r0 = getBit(r, 0); 1995e5c31af7Sopenharmony_ci const deUint32 r1 = getBit(r, 1); 1996e5c31af7Sopenharmony_ci const deUint32 r2 = getBit(r, 2); 1997e5c31af7Sopenharmony_ci 1998e5c31af7Sopenharmony_ci#define SB(NDX, VAL) dst.setBit((NDX), (VAL)) 1999e5c31af7Sopenharmony_ci#define ASSIGN_BITS(B10, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0) do { SB(10,(B10)); SB(9,(B9)); SB(8,(B8)); SB(7,(B7)); SB(6,(B6)); SB(5,(B5)); SB(4,(B4)); SB(3,(B3)); SB(2,(B2)); SB(1,(B1)); SB(0,(B0)); } while (false) 2000e5c31af7Sopenharmony_ci 2001e5c31af7Sopenharmony_ci switch (blockModeLayoutNdx) 2002e5c31af7Sopenharmony_ci { 2003e5c31af7Sopenharmony_ci case 0: ASSIGN_BITS(d, h, b1, b0, a1, a0, r0, 0, 0, r2, r1); break; 2004e5c31af7Sopenharmony_ci case 1: ASSIGN_BITS(d, h, b1, b0, a1, a0, r0, 0, 1, r2, r1); break; 2005e5c31af7Sopenharmony_ci case 2: ASSIGN_BITS(d, h, b1, b0, a1, a0, r0, 1, 0, r2, r1); break; 2006e5c31af7Sopenharmony_ci case 3: ASSIGN_BITS(d, h, 0, b, a1, a0, r0, 1, 1, r2, r1); break; 2007e5c31af7Sopenharmony_ci case 4: ASSIGN_BITS(d, h, 1, b, a1, a0, r0, 1, 1, r2, r1); break; 2008e5c31af7Sopenharmony_ci case 5: ASSIGN_BITS(d, h, 0, 0, a1, a0, r0, r2, r1, 0, 0); break; 2009e5c31af7Sopenharmony_ci case 6: ASSIGN_BITS(d, h, 0, 1, a1, a0, r0, r2, r1, 0, 0); break; 2010e5c31af7Sopenharmony_ci case 7: ASSIGN_BITS(d, h, 1, 1, 0, 0, r0, r2, r1, 0, 0); break; 2011e5c31af7Sopenharmony_ci case 8: ASSIGN_BITS(d, h, 1, 1, 0, 1, r0, r2, r1, 0, 0); break; 2012e5c31af7Sopenharmony_ci case 9: ASSIGN_BITS(b1, b0, 1, 0, a1, a0, r0, r2, r1, 0, 0); DE_ASSERT(d == 0 && h == 0); break; 2013e5c31af7Sopenharmony_ci default: 2014e5c31af7Sopenharmony_ci DE_ASSERT(false); 2015e5c31af7Sopenharmony_ci } 2016e5c31af7Sopenharmony_ci 2017e5c31af7Sopenharmony_ci#undef ASSIGN_BITS 2018e5c31af7Sopenharmony_ci#undef SB 2019e5c31af7Sopenharmony_ci} 2020e5c31af7Sopenharmony_ci 2021e5c31af7Sopenharmony_ci// Write color endpoint mode data of an ASTC block. 2022e5c31af7Sopenharmony_cistatic void writeColorEndpointModes (AssignBlock128& dst, const deUint32* colorEndpointModes, bool isMultiPartSingleCemMode, int numPartitions, int extraCemBitsStart) 2023e5c31af7Sopenharmony_ci{ 2024e5c31af7Sopenharmony_ci if (numPartitions == 1) 2025e5c31af7Sopenharmony_ci dst.setBits(13, 16, colorEndpointModes[0]); 2026e5c31af7Sopenharmony_ci else 2027e5c31af7Sopenharmony_ci { 2028e5c31af7Sopenharmony_ci if (isMultiPartSingleCemMode) 2029e5c31af7Sopenharmony_ci { 2030e5c31af7Sopenharmony_ci dst.setBits(23, 24, 0); 2031e5c31af7Sopenharmony_ci dst.setBits(25, 28, colorEndpointModes[0]); 2032e5c31af7Sopenharmony_ci } 2033e5c31af7Sopenharmony_ci else 2034e5c31af7Sopenharmony_ci { 2035e5c31af7Sopenharmony_ci DE_ASSERT(numPartitions > 0); 2036e5c31af7Sopenharmony_ci const deUint32 minCem = *std::min_element(&colorEndpointModes[0], &colorEndpointModes[numPartitions]); 2037e5c31af7Sopenharmony_ci const deUint32 maxCem = *std::max_element(&colorEndpointModes[0], &colorEndpointModes[numPartitions]); 2038e5c31af7Sopenharmony_ci const deUint32 minCemClass = minCem/4; 2039e5c31af7Sopenharmony_ci const deUint32 maxCemClass = maxCem/4; 2040e5c31af7Sopenharmony_ci DE_ASSERT(maxCemClass - minCemClass <= 1); 2041e5c31af7Sopenharmony_ci DE_UNREF(minCemClass); // \note For non-debug builds. 2042e5c31af7Sopenharmony_ci const deUint32 highLevelSelector = de::max(1u, maxCemClass); 2043e5c31af7Sopenharmony_ci 2044e5c31af7Sopenharmony_ci dst.setBits(23, 24, highLevelSelector); 2045e5c31af7Sopenharmony_ci 2046e5c31af7Sopenharmony_ci for (int partNdx = 0; partNdx < numPartitions; partNdx++) 2047e5c31af7Sopenharmony_ci { 2048e5c31af7Sopenharmony_ci const deUint32 c = colorEndpointModes[partNdx] / 4 == highLevelSelector ? 1 : 0; 2049e5c31af7Sopenharmony_ci const deUint32 m = colorEndpointModes[partNdx] % 4; 2050e5c31af7Sopenharmony_ci const deUint32 lowMBit0Ndx = numPartitions + 2*partNdx; 2051e5c31af7Sopenharmony_ci const deUint32 lowMBit1Ndx = numPartitions + 2*partNdx + 1; 2052e5c31af7Sopenharmony_ci dst.setBit(25 + partNdx, c); 2053e5c31af7Sopenharmony_ci dst.setBit(lowMBit0Ndx < 4 ? 25+lowMBit0Ndx : extraCemBitsStart+lowMBit0Ndx-4, getBit(m, 0)); 2054e5c31af7Sopenharmony_ci dst.setBit(lowMBit1Ndx < 4 ? 25+lowMBit1Ndx : extraCemBitsStart+lowMBit1Ndx-4, getBit(m, 1)); 2055e5c31af7Sopenharmony_ci } 2056e5c31af7Sopenharmony_ci } 2057e5c31af7Sopenharmony_ci } 2058e5c31af7Sopenharmony_ci} 2059e5c31af7Sopenharmony_ci 2060e5c31af7Sopenharmony_cistatic void encodeISETritBlock (BitAssignAccessStream& dst, int numBits, bool fromExplicitInputBlock, const ISEInput::Block& blockInput, const deUint32* nonBlockInput, int numValues) 2061e5c31af7Sopenharmony_ci{ 2062e5c31af7Sopenharmony_ci // tritBlockTValue[t0][t1][t2][t3][t4] is a value of T (not necessarily the only one) that will yield the given trits when decoded. 2063e5c31af7Sopenharmony_ci static const deUint32 tritBlockTValue[3][3][3][3][3] = 2064e5c31af7Sopenharmony_ci { 2065e5c31af7Sopenharmony_ci { 2066e5c31af7Sopenharmony_ci {{{0, 128, 96}, {32, 160, 224}, {64, 192, 28}}, {{16, 144, 112}, {48, 176, 240}, {80, 208, 156}}, {{3, 131, 99}, {35, 163, 227}, {67, 195, 31}}}, 2067e5c31af7Sopenharmony_ci {{{4, 132, 100}, {36, 164, 228}, {68, 196, 60}}, {{20, 148, 116}, {52, 180, 244}, {84, 212, 188}}, {{19, 147, 115}, {51, 179, 243}, {83, 211, 159}}}, 2068e5c31af7Sopenharmony_ci {{{8, 136, 104}, {40, 168, 232}, {72, 200, 92}}, {{24, 152, 120}, {56, 184, 248}, {88, 216, 220}}, {{12, 140, 108}, {44, 172, 236}, {76, 204, 124}}} 2069e5c31af7Sopenharmony_ci }, 2070e5c31af7Sopenharmony_ci { 2071e5c31af7Sopenharmony_ci {{{1, 129, 97}, {33, 161, 225}, {65, 193, 29}}, {{17, 145, 113}, {49, 177, 241}, {81, 209, 157}}, {{7, 135, 103}, {39, 167, 231}, {71, 199, 63}}}, 2072e5c31af7Sopenharmony_ci {{{5, 133, 101}, {37, 165, 229}, {69, 197, 61}}, {{21, 149, 117}, {53, 181, 245}, {85, 213, 189}}, {{23, 151, 119}, {55, 183, 247}, {87, 215, 191}}}, 2073e5c31af7Sopenharmony_ci {{{9, 137, 105}, {41, 169, 233}, {73, 201, 93}}, {{25, 153, 121}, {57, 185, 249}, {89, 217, 221}}, {{13, 141, 109}, {45, 173, 237}, {77, 205, 125}}} 2074e5c31af7Sopenharmony_ci }, 2075e5c31af7Sopenharmony_ci { 2076e5c31af7Sopenharmony_ci {{{2, 130, 98}, {34, 162, 226}, {66, 194, 30}}, {{18, 146, 114}, {50, 178, 242}, {82, 210, 158}}, {{11, 139, 107}, {43, 171, 235}, {75, 203, 95}}}, 2077e5c31af7Sopenharmony_ci {{{6, 134, 102}, {38, 166, 230}, {70, 198, 62}}, {{22, 150, 118}, {54, 182, 246}, {86, 214, 190}}, {{27, 155, 123}, {59, 187, 251}, {91, 219, 223}}}, 2078e5c31af7Sopenharmony_ci {{{10, 138, 106}, {42, 170, 234}, {74, 202, 94}}, {{26, 154, 122}, {58, 186, 250}, {90, 218, 222}}, {{14, 142, 110}, {46, 174, 238}, {78, 206, 126}}} 2079e5c31af7Sopenharmony_ci } 2080e5c31af7Sopenharmony_ci }; 2081e5c31af7Sopenharmony_ci 2082e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numValues, 1, 5)); 2083e5c31af7Sopenharmony_ci 2084e5c31af7Sopenharmony_ci deUint32 tritParts[5]; 2085e5c31af7Sopenharmony_ci deUint32 bitParts[5]; 2086e5c31af7Sopenharmony_ci 2087e5c31af7Sopenharmony_ci for (int i = 0; i < 5; i++) 2088e5c31af7Sopenharmony_ci { 2089e5c31af7Sopenharmony_ci if (i < numValues) 2090e5c31af7Sopenharmony_ci { 2091e5c31af7Sopenharmony_ci if (fromExplicitInputBlock) 2092e5c31af7Sopenharmony_ci { 2093e5c31af7Sopenharmony_ci bitParts[i] = blockInput.bitValues[i]; 2094e5c31af7Sopenharmony_ci tritParts[i] = -1; // \note Won't be used, but silences warning. 2095e5c31af7Sopenharmony_ci } 2096e5c31af7Sopenharmony_ci else 2097e5c31af7Sopenharmony_ci { 2098e5c31af7Sopenharmony_ci // \todo [2016-01-20 pyry] numBits = 0 doesn't make sense 2099e5c31af7Sopenharmony_ci bitParts[i] = numBits > 0 ? getBits(nonBlockInput[i], 0, numBits-1) : 0; 2100e5c31af7Sopenharmony_ci tritParts[i] = nonBlockInput[i] >> numBits; 2101e5c31af7Sopenharmony_ci } 2102e5c31af7Sopenharmony_ci } 2103e5c31af7Sopenharmony_ci else 2104e5c31af7Sopenharmony_ci { 2105e5c31af7Sopenharmony_ci bitParts[i] = 0; 2106e5c31af7Sopenharmony_ci tritParts[i] = 0; 2107e5c31af7Sopenharmony_ci } 2108e5c31af7Sopenharmony_ci } 2109e5c31af7Sopenharmony_ci 2110e5c31af7Sopenharmony_ci const deUint32 T = fromExplicitInputBlock ? blockInput.tOrQValue : tritBlockTValue[tritParts[0]] 2111e5c31af7Sopenharmony_ci [tritParts[1]] 2112e5c31af7Sopenharmony_ci [tritParts[2]] 2113e5c31af7Sopenharmony_ci [tritParts[3]] 2114e5c31af7Sopenharmony_ci [tritParts[4]]; 2115e5c31af7Sopenharmony_ci 2116e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[0]); 2117e5c31af7Sopenharmony_ci dst.setNext(2, getBits(T, 0, 1)); 2118e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[1]); 2119e5c31af7Sopenharmony_ci dst.setNext(2, getBits(T, 2, 3)); 2120e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[2]); 2121e5c31af7Sopenharmony_ci dst.setNext(1, getBit(T, 4)); 2122e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[3]); 2123e5c31af7Sopenharmony_ci dst.setNext(2, getBits(T, 5, 6)); 2124e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[4]); 2125e5c31af7Sopenharmony_ci dst.setNext(1, getBit(T, 7)); 2126e5c31af7Sopenharmony_ci} 2127e5c31af7Sopenharmony_ci 2128e5c31af7Sopenharmony_cistatic void encodeISEQuintBlock (BitAssignAccessStream& dst, int numBits, bool fromExplicitInputBlock, const ISEInput::Block& blockInput, const deUint32* nonBlockInput, int numValues) 2129e5c31af7Sopenharmony_ci{ 2130e5c31af7Sopenharmony_ci // quintBlockQValue[q0][q1][q2] is a value of Q (not necessarily the only one) that will yield the given quints when decoded. 2131e5c31af7Sopenharmony_ci static const deUint32 quintBlockQValue[5][5][5] = 2132e5c31af7Sopenharmony_ci { 2133e5c31af7Sopenharmony_ci {{0, 32, 64, 96, 102}, {8, 40, 72, 104, 110}, {16, 48, 80, 112, 118}, {24, 56, 88, 120, 126}, {5, 37, 69, 101, 39}}, 2134e5c31af7Sopenharmony_ci {{1, 33, 65, 97, 103}, {9, 41, 73, 105, 111}, {17, 49, 81, 113, 119}, {25, 57, 89, 121, 127}, {13, 45, 77, 109, 47}}, 2135e5c31af7Sopenharmony_ci {{2, 34, 66, 98, 70}, {10, 42, 74, 106, 78}, {18, 50, 82, 114, 86}, {26, 58, 90, 122, 94}, {21, 53, 85, 117, 55}}, 2136e5c31af7Sopenharmony_ci {{3, 35, 67, 99, 71}, {11, 43, 75, 107, 79}, {19, 51, 83, 115, 87}, {27, 59, 91, 123, 95}, {29, 61, 93, 125, 63}}, 2137e5c31af7Sopenharmony_ci {{4, 36, 68, 100, 38}, {12, 44, 76, 108, 46}, {20, 52, 84, 116, 54}, {28, 60, 92, 124, 62}, {6, 14, 22, 30, 7}} 2138e5c31af7Sopenharmony_ci }; 2139e5c31af7Sopenharmony_ci 2140e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(numValues, 1, 3)); 2141e5c31af7Sopenharmony_ci 2142e5c31af7Sopenharmony_ci deUint32 quintParts[3]; 2143e5c31af7Sopenharmony_ci deUint32 bitParts[3]; 2144e5c31af7Sopenharmony_ci 2145e5c31af7Sopenharmony_ci for (int i = 0; i < 3; i++) 2146e5c31af7Sopenharmony_ci { 2147e5c31af7Sopenharmony_ci if (i < numValues) 2148e5c31af7Sopenharmony_ci { 2149e5c31af7Sopenharmony_ci if (fromExplicitInputBlock) 2150e5c31af7Sopenharmony_ci { 2151e5c31af7Sopenharmony_ci bitParts[i] = blockInput.bitValues[i]; 2152e5c31af7Sopenharmony_ci quintParts[i] = -1; // \note Won't be used, but silences warning. 2153e5c31af7Sopenharmony_ci } 2154e5c31af7Sopenharmony_ci else 2155e5c31af7Sopenharmony_ci { 2156e5c31af7Sopenharmony_ci // \todo [2016-01-20 pyry] numBits = 0 doesn't make sense 2157e5c31af7Sopenharmony_ci bitParts[i] = numBits > 0 ? getBits(nonBlockInput[i], 0, numBits-1) : 0; 2158e5c31af7Sopenharmony_ci quintParts[i] = nonBlockInput[i] >> numBits; 2159e5c31af7Sopenharmony_ci } 2160e5c31af7Sopenharmony_ci } 2161e5c31af7Sopenharmony_ci else 2162e5c31af7Sopenharmony_ci { 2163e5c31af7Sopenharmony_ci bitParts[i] = 0; 2164e5c31af7Sopenharmony_ci quintParts[i] = 0; 2165e5c31af7Sopenharmony_ci } 2166e5c31af7Sopenharmony_ci } 2167e5c31af7Sopenharmony_ci 2168e5c31af7Sopenharmony_ci const deUint32 Q = fromExplicitInputBlock ? blockInput.tOrQValue : quintBlockQValue[quintParts[0]] 2169e5c31af7Sopenharmony_ci [quintParts[1]] 2170e5c31af7Sopenharmony_ci [quintParts[2]]; 2171e5c31af7Sopenharmony_ci 2172e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[0]); 2173e5c31af7Sopenharmony_ci dst.setNext(3, getBits(Q, 0, 2)); 2174e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[1]); 2175e5c31af7Sopenharmony_ci dst.setNext(2, getBits(Q, 3, 4)); 2176e5c31af7Sopenharmony_ci dst.setNext(numBits, bitParts[2]); 2177e5c31af7Sopenharmony_ci dst.setNext(2, getBits(Q, 5, 6)); 2178e5c31af7Sopenharmony_ci} 2179e5c31af7Sopenharmony_ci 2180e5c31af7Sopenharmony_cistatic void encodeISEBitBlock (BitAssignAccessStream& dst, int numBits, deUint32 value) 2181e5c31af7Sopenharmony_ci{ 2182e5c31af7Sopenharmony_ci DE_ASSERT(de::inRange(value, 0u, (1u<<numBits)-1)); 2183e5c31af7Sopenharmony_ci dst.setNext(numBits, value); 2184e5c31af7Sopenharmony_ci} 2185e5c31af7Sopenharmony_ci 2186e5c31af7Sopenharmony_cistatic void encodeISE (BitAssignAccessStream& dst, const ISEParams& params, const ISEInput& input, int numValues) 2187e5c31af7Sopenharmony_ci{ 2188e5c31af7Sopenharmony_ci if (params.mode == ISEMODE_TRIT) 2189e5c31af7Sopenharmony_ci { 2190e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numValues, 5); 2191e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2192e5c31af7Sopenharmony_ci { 2193e5c31af7Sopenharmony_ci const int numValuesInBlock = blockNdx == numBlocks-1 ? numValues - 5*(numBlocks-1) : 5; 2194e5c31af7Sopenharmony_ci encodeISETritBlock(dst, params.numBits, input.isGivenInBlockForm, 2195e5c31af7Sopenharmony_ci input.isGivenInBlockForm ? input.value.block[blockNdx] : ISEInput::Block(), 2196e5c31af7Sopenharmony_ci input.isGivenInBlockForm ? DE_NULL : &input.value.plain[5*blockNdx], 2197e5c31af7Sopenharmony_ci numValuesInBlock); 2198e5c31af7Sopenharmony_ci } 2199e5c31af7Sopenharmony_ci } 2200e5c31af7Sopenharmony_ci else if (params.mode == ISEMODE_QUINT) 2201e5c31af7Sopenharmony_ci { 2202e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numValues, 3); 2203e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2204e5c31af7Sopenharmony_ci { 2205e5c31af7Sopenharmony_ci const int numValuesInBlock = blockNdx == numBlocks-1 ? numValues - 3*(numBlocks-1) : 3; 2206e5c31af7Sopenharmony_ci encodeISEQuintBlock(dst, params.numBits, input.isGivenInBlockForm, 2207e5c31af7Sopenharmony_ci input.isGivenInBlockForm ? input.value.block[blockNdx] : ISEInput::Block(), 2208e5c31af7Sopenharmony_ci input.isGivenInBlockForm ? DE_NULL : &input.value.plain[3*blockNdx], 2209e5c31af7Sopenharmony_ci numValuesInBlock); 2210e5c31af7Sopenharmony_ci } 2211e5c31af7Sopenharmony_ci } 2212e5c31af7Sopenharmony_ci else 2213e5c31af7Sopenharmony_ci { 2214e5c31af7Sopenharmony_ci DE_ASSERT(params.mode == ISEMODE_PLAIN_BIT); 2215e5c31af7Sopenharmony_ci for (int i = 0; i < numValues; i++) 2216e5c31af7Sopenharmony_ci encodeISEBitBlock(dst, params.numBits, input.isGivenInBlockForm ? input.value.block[i].bitValues[0] : input.value.plain[i]); 2217e5c31af7Sopenharmony_ci } 2218e5c31af7Sopenharmony_ci} 2219e5c31af7Sopenharmony_ci 2220e5c31af7Sopenharmony_cistatic void writeWeightData (AssignBlock128& dst, const ISEParams& iseParams, const ISEInput& input, int numWeights) 2221e5c31af7Sopenharmony_ci{ 2222e5c31af7Sopenharmony_ci const int numWeightBits = computeNumRequiredBits(iseParams, numWeights); 2223e5c31af7Sopenharmony_ci BitAssignAccessStream access (dst, 127, numWeightBits, false); 2224e5c31af7Sopenharmony_ci encodeISE(access, iseParams, input, numWeights); 2225e5c31af7Sopenharmony_ci} 2226e5c31af7Sopenharmony_ci 2227e5c31af7Sopenharmony_cistatic void writeColorEndpointData (AssignBlock128& dst, const ISEParams& iseParams, const ISEInput& input, int numEndpoints, int numBitsForColorEndpoints, int colorEndpointDataStartNdx) 2228e5c31af7Sopenharmony_ci{ 2229e5c31af7Sopenharmony_ci BitAssignAccessStream access(dst, colorEndpointDataStartNdx, numBitsForColorEndpoints, true); 2230e5c31af7Sopenharmony_ci encodeISE(access, iseParams, input, numEndpoints); 2231e5c31af7Sopenharmony_ci} 2232e5c31af7Sopenharmony_ci 2233e5c31af7Sopenharmony_cistatic AssignBlock128 generateNormalBlock (const NormalBlockParams& blockParams, int blockWidth, int blockHeight, const NormalBlockISEInputs& iseInputs) 2234e5c31af7Sopenharmony_ci{ 2235e5c31af7Sopenharmony_ci DE_ASSERT(isValidBlockParams(blockParams, blockWidth, blockHeight)); 2236e5c31af7Sopenharmony_ci DE_UNREF(blockWidth); // \note For non-debug builds. 2237e5c31af7Sopenharmony_ci DE_UNREF(blockHeight); // \note For non-debug builds. 2238e5c31af7Sopenharmony_ci 2239e5c31af7Sopenharmony_ci AssignBlock128 block; 2240e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockParams); 2241e5c31af7Sopenharmony_ci const int numWeightBits = computeNumRequiredBits(blockParams.weightISEParams, numWeights); 2242e5c31af7Sopenharmony_ci 2243e5c31af7Sopenharmony_ci writeBlockMode(block, blockParams); 2244e5c31af7Sopenharmony_ci 2245e5c31af7Sopenharmony_ci block.setBits(11, 12, blockParams.numPartitions - 1); 2246e5c31af7Sopenharmony_ci if (blockParams.numPartitions > 1) 2247e5c31af7Sopenharmony_ci block.setBits(13, 22, blockParams.partitionSeed); 2248e5c31af7Sopenharmony_ci 2249e5c31af7Sopenharmony_ci { 2250e5c31af7Sopenharmony_ci const int extraCemBitsStart = 127 - numWeightBits - (blockParams.numPartitions == 1 || blockParams.isMultiPartSingleCemMode ? -1 2251e5c31af7Sopenharmony_ci : blockParams.numPartitions == 4 ? 7 2252e5c31af7Sopenharmony_ci : blockParams.numPartitions == 3 ? 4 2253e5c31af7Sopenharmony_ci : blockParams.numPartitions == 2 ? 1 2254e5c31af7Sopenharmony_ci : 0); 2255e5c31af7Sopenharmony_ci 2256e5c31af7Sopenharmony_ci writeColorEndpointModes(block, &blockParams.colorEndpointModes[0], blockParams.isMultiPartSingleCemMode, blockParams.numPartitions, extraCemBitsStart); 2257e5c31af7Sopenharmony_ci 2258e5c31af7Sopenharmony_ci if (blockParams.isDualPlane) 2259e5c31af7Sopenharmony_ci block.setBits(extraCemBitsStart-2, extraCemBitsStart-1, blockParams.ccs); 2260e5c31af7Sopenharmony_ci } 2261e5c31af7Sopenharmony_ci 2262e5c31af7Sopenharmony_ci writeWeightData(block, blockParams.weightISEParams, iseInputs.weight, numWeights); 2263e5c31af7Sopenharmony_ci 2264e5c31af7Sopenharmony_ci { 2265e5c31af7Sopenharmony_ci const int numColorEndpointValues = computeNumColorEndpointValues(&blockParams.colorEndpointModes[0], blockParams.numPartitions, blockParams.isMultiPartSingleCemMode); 2266e5c31af7Sopenharmony_ci const int numBitsForColorEndpoints = computeNumBitsForColorEndpoints(blockParams); 2267e5c31af7Sopenharmony_ci const int colorEndpointDataStartNdx = blockParams.numPartitions == 1 ? 17 : 29; 2268e5c31af7Sopenharmony_ci const ISEParams& colorEndpointISEParams = computeMaximumRangeISEParams(numBitsForColorEndpoints, numColorEndpointValues); 2269e5c31af7Sopenharmony_ci 2270e5c31af7Sopenharmony_ci writeColorEndpointData(block, colorEndpointISEParams, iseInputs.endpoint, numColorEndpointValues, numBitsForColorEndpoints, colorEndpointDataStartNdx); 2271e5c31af7Sopenharmony_ci } 2272e5c31af7Sopenharmony_ci 2273e5c31af7Sopenharmony_ci return block; 2274e5c31af7Sopenharmony_ci} 2275e5c31af7Sopenharmony_ci 2276e5c31af7Sopenharmony_ci// Generate default ISE inputs for weight and endpoint data - gradient-ish values. 2277e5c31af7Sopenharmony_cistatic NormalBlockISEInputs generateDefaultISEInputs (const NormalBlockParams& blockParams) 2278e5c31af7Sopenharmony_ci{ 2279e5c31af7Sopenharmony_ci NormalBlockISEInputs result; 2280e5c31af7Sopenharmony_ci 2281e5c31af7Sopenharmony_ci { 2282e5c31af7Sopenharmony_ci result.weight.isGivenInBlockForm = false; 2283e5c31af7Sopenharmony_ci 2284e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockParams); 2285e5c31af7Sopenharmony_ci const int weightRangeMax = computeISERangeMax(blockParams.weightISEParams); 2286e5c31af7Sopenharmony_ci 2287e5c31af7Sopenharmony_ci if (blockParams.isDualPlane) 2288e5c31af7Sopenharmony_ci { 2289e5c31af7Sopenharmony_ci for (int i = 0; i < numWeights; i += 2) 2290e5c31af7Sopenharmony_ci result.weight.value.plain[i] = (i*weightRangeMax + (numWeights-1)/2) / (numWeights-1); 2291e5c31af7Sopenharmony_ci 2292e5c31af7Sopenharmony_ci for (int i = 1; i < numWeights; i += 2) 2293e5c31af7Sopenharmony_ci result.weight.value.plain[i] = weightRangeMax - (i*weightRangeMax + (numWeights-1)/2) / (numWeights-1); 2294e5c31af7Sopenharmony_ci } 2295e5c31af7Sopenharmony_ci else 2296e5c31af7Sopenharmony_ci { 2297e5c31af7Sopenharmony_ci for (int i = 0; i < numWeights; i++) 2298e5c31af7Sopenharmony_ci result.weight.value.plain[i] = (i*weightRangeMax + (numWeights-1)/2) / (numWeights-1); 2299e5c31af7Sopenharmony_ci } 2300e5c31af7Sopenharmony_ci } 2301e5c31af7Sopenharmony_ci 2302e5c31af7Sopenharmony_ci { 2303e5c31af7Sopenharmony_ci result.endpoint.isGivenInBlockForm = false; 2304e5c31af7Sopenharmony_ci 2305e5c31af7Sopenharmony_ci const int numColorEndpointValues = computeNumColorEndpointValues(&blockParams.colorEndpointModes[0], blockParams.numPartitions, blockParams.isMultiPartSingleCemMode); 2306e5c31af7Sopenharmony_ci const int numBitsForColorEndpoints = computeNumBitsForColorEndpoints(blockParams); 2307e5c31af7Sopenharmony_ci const ISEParams& colorEndpointISEParams = computeMaximumRangeISEParams(numBitsForColorEndpoints, numColorEndpointValues); 2308e5c31af7Sopenharmony_ci const int colorEndpointRangeMax = computeISERangeMax(colorEndpointISEParams); 2309e5c31af7Sopenharmony_ci 2310e5c31af7Sopenharmony_ci for (int i = 0; i < numColorEndpointValues; i++) 2311e5c31af7Sopenharmony_ci result.endpoint.value.plain[i] = (i*colorEndpointRangeMax + (numColorEndpointValues-1)/2) / (numColorEndpointValues-1); 2312e5c31af7Sopenharmony_ci } 2313e5c31af7Sopenharmony_ci 2314e5c31af7Sopenharmony_ci return result; 2315e5c31af7Sopenharmony_ci} 2316e5c31af7Sopenharmony_ci 2317e5c31af7Sopenharmony_cistatic const ISEParams s_weightISEParamsCandidates[] = 2318e5c31af7Sopenharmony_ci{ 2319e5c31af7Sopenharmony_ci ISEParams(ISEMODE_PLAIN_BIT, 1), 2320e5c31af7Sopenharmony_ci ISEParams(ISEMODE_TRIT, 0), 2321e5c31af7Sopenharmony_ci ISEParams(ISEMODE_PLAIN_BIT, 2), 2322e5c31af7Sopenharmony_ci ISEParams(ISEMODE_QUINT, 0), 2323e5c31af7Sopenharmony_ci ISEParams(ISEMODE_TRIT, 1), 2324e5c31af7Sopenharmony_ci ISEParams(ISEMODE_PLAIN_BIT, 3), 2325e5c31af7Sopenharmony_ci ISEParams(ISEMODE_QUINT, 1), 2326e5c31af7Sopenharmony_ci ISEParams(ISEMODE_TRIT, 2), 2327e5c31af7Sopenharmony_ci ISEParams(ISEMODE_PLAIN_BIT, 4), 2328e5c31af7Sopenharmony_ci ISEParams(ISEMODE_QUINT, 2), 2329e5c31af7Sopenharmony_ci ISEParams(ISEMODE_TRIT, 3), 2330e5c31af7Sopenharmony_ci ISEParams(ISEMODE_PLAIN_BIT, 5) 2331e5c31af7Sopenharmony_ci}; 2332e5c31af7Sopenharmony_ci 2333e5c31af7Sopenharmony_civoid generateRandomBlock (deUint8* dst, const IVec3& blockSize, de::Random& rnd) 2334e5c31af7Sopenharmony_ci{ 2335e5c31af7Sopenharmony_ci DE_ASSERT(blockSize.z() == 1); 2336e5c31af7Sopenharmony_ci 2337e5c31af7Sopenharmony_ci if (rnd.getFloat() < 0.1f) 2338e5c31af7Sopenharmony_ci { 2339e5c31af7Sopenharmony_ci // Void extent block. 2340e5c31af7Sopenharmony_ci const bool isVoidExtentHDR = rnd.getBool(); 2341e5c31af7Sopenharmony_ci const deUint16 r = isVoidExtentHDR ? deFloat32To16(rnd.getFloat(0.0f, 1.0f)) : (deUint16)rnd.getInt(0, 0xffff); 2342e5c31af7Sopenharmony_ci const deUint16 g = isVoidExtentHDR ? deFloat32To16(rnd.getFloat(0.0f, 1.0f)) : (deUint16)rnd.getInt(0, 0xffff); 2343e5c31af7Sopenharmony_ci const deUint16 b = isVoidExtentHDR ? deFloat32To16(rnd.getFloat(0.0f, 1.0f)) : (deUint16)rnd.getInt(0, 0xffff); 2344e5c31af7Sopenharmony_ci const deUint16 a = isVoidExtentHDR ? deFloat32To16(rnd.getFloat(0.0f, 1.0f)) : (deUint16)rnd.getInt(0, 0xffff); 2345e5c31af7Sopenharmony_ci generateVoidExtentBlock(VoidExtentParams(isVoidExtentHDR, r, g, b, a)).assignToMemory(dst); 2346e5c31af7Sopenharmony_ci } 2347e5c31af7Sopenharmony_ci else 2348e5c31af7Sopenharmony_ci { 2349e5c31af7Sopenharmony_ci // Not void extent block. 2350e5c31af7Sopenharmony_ci 2351e5c31af7Sopenharmony_ci // Generate block params. 2352e5c31af7Sopenharmony_ci 2353e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2354e5c31af7Sopenharmony_ci 2355e5c31af7Sopenharmony_ci do 2356e5c31af7Sopenharmony_ci { 2357e5c31af7Sopenharmony_ci blockParams.weightGridWidth = rnd.getInt(2, blockSize.x()); 2358e5c31af7Sopenharmony_ci blockParams.weightGridHeight = rnd.getInt(2, blockSize.y()); 2359e5c31af7Sopenharmony_ci blockParams.weightISEParams = s_weightISEParamsCandidates[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates)-1)]; 2360e5c31af7Sopenharmony_ci blockParams.numPartitions = rnd.getInt(1, 4); 2361e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = rnd.getFloat() < 0.25f; 2362e5c31af7Sopenharmony_ci blockParams.isDualPlane = blockParams.numPartitions != 4 && rnd.getBool(); 2363e5c31af7Sopenharmony_ci blockParams.ccs = rnd.getInt(0, 3); 2364e5c31af7Sopenharmony_ci blockParams.partitionSeed = rnd.getInt(0, 1023); 2365e5c31af7Sopenharmony_ci 2366e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = rnd.getInt(0, 15); 2367e5c31af7Sopenharmony_ci 2368e5c31af7Sopenharmony_ci { 2369e5c31af7Sopenharmony_ci const int cemDiff = blockParams.isMultiPartSingleCemMode ? 0 2370e5c31af7Sopenharmony_ci : blockParams.colorEndpointModes[0] == 0 ? 1 2371e5c31af7Sopenharmony_ci : blockParams.colorEndpointModes[0] == 15 ? -1 2372e5c31af7Sopenharmony_ci : rnd.getBool() ? 1 : -1; 2373e5c31af7Sopenharmony_ci 2374e5c31af7Sopenharmony_ci for (int i = 1; i < blockParams.numPartitions; i++) 2375e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[i] = blockParams.colorEndpointModes[0] + (cemDiff == -1 ? rnd.getInt(-1, 0) : cemDiff == 1 ? rnd.getInt(0, 1) : 0); 2376e5c31af7Sopenharmony_ci } 2377e5c31af7Sopenharmony_ci } while (!isValidBlockParams(blockParams, blockSize.x(), blockSize.y())); 2378e5c31af7Sopenharmony_ci 2379e5c31af7Sopenharmony_ci // Generate ISE inputs for both weight and endpoint data. 2380e5c31af7Sopenharmony_ci 2381e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs; 2382e5c31af7Sopenharmony_ci 2383e5c31af7Sopenharmony_ci for (int weightOrEndpoints = 0; weightOrEndpoints <= 1; weightOrEndpoints++) 2384e5c31af7Sopenharmony_ci { 2385e5c31af7Sopenharmony_ci const bool setWeights = weightOrEndpoints == 0; 2386e5c31af7Sopenharmony_ci const int numValues = setWeights ? computeNumWeights(blockParams) : 2387e5c31af7Sopenharmony_ci computeNumColorEndpointValues(&blockParams.colorEndpointModes[0], blockParams.numPartitions, blockParams.isMultiPartSingleCemMode); 2388e5c31af7Sopenharmony_ci const ISEParams iseParams = setWeights ? blockParams.weightISEParams : computeMaximumRangeISEParams(computeNumBitsForColorEndpoints(blockParams), numValues); 2389e5c31af7Sopenharmony_ci ISEInput& iseInput = setWeights ? iseInputs.weight : iseInputs.endpoint; 2390e5c31af7Sopenharmony_ci 2391e5c31af7Sopenharmony_ci iseInput.isGivenInBlockForm = rnd.getBool(); 2392e5c31af7Sopenharmony_ci 2393e5c31af7Sopenharmony_ci if (iseInput.isGivenInBlockForm) 2394e5c31af7Sopenharmony_ci { 2395e5c31af7Sopenharmony_ci const int numValuesPerISEBlock = iseParams.mode == ISEMODE_TRIT ? 5 2396e5c31af7Sopenharmony_ci : iseParams.mode == ISEMODE_QUINT ? 3 2397e5c31af7Sopenharmony_ci : 1; 2398e5c31af7Sopenharmony_ci const int iseBitMax = (1 << iseParams.numBits) - 1; 2399e5c31af7Sopenharmony_ci const int numISEBlocks = deDivRoundUp32(numValues, numValuesPerISEBlock); 2400e5c31af7Sopenharmony_ci 2401e5c31af7Sopenharmony_ci for (int iseBlockNdx = 0; iseBlockNdx < numISEBlocks; iseBlockNdx++) 2402e5c31af7Sopenharmony_ci { 2403e5c31af7Sopenharmony_ci iseInput.value.block[iseBlockNdx].tOrQValue = rnd.getInt(0, 255); 2404e5c31af7Sopenharmony_ci for (int i = 0; i < numValuesPerISEBlock; i++) 2405e5c31af7Sopenharmony_ci iseInput.value.block[iseBlockNdx].bitValues[i] = rnd.getInt(0, iseBitMax); 2406e5c31af7Sopenharmony_ci } 2407e5c31af7Sopenharmony_ci } 2408e5c31af7Sopenharmony_ci else 2409e5c31af7Sopenharmony_ci { 2410e5c31af7Sopenharmony_ci const int rangeMax = computeISERangeMax(iseParams); 2411e5c31af7Sopenharmony_ci 2412e5c31af7Sopenharmony_ci for (int valueNdx = 0; valueNdx < numValues; valueNdx++) 2413e5c31af7Sopenharmony_ci iseInput.value.plain[valueNdx] = rnd.getInt(0, rangeMax); 2414e5c31af7Sopenharmony_ci } 2415e5c31af7Sopenharmony_ci } 2416e5c31af7Sopenharmony_ci 2417e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).assignToMemory(dst); 2418e5c31af7Sopenharmony_ci } 2419e5c31af7Sopenharmony_ci} 2420e5c31af7Sopenharmony_ci 2421e5c31af7Sopenharmony_ci} // anonymous 2422e5c31af7Sopenharmony_ci 2423e5c31af7Sopenharmony_ci// Generate block data for a given BlockTestType and format. 2424e5c31af7Sopenharmony_civoid generateBlockCaseTestData (vector<deUint8>& dst, CompressedTexFormat format, BlockTestType testType) 2425e5c31af7Sopenharmony_ci{ 2426e5c31af7Sopenharmony_ci DE_ASSERT(isAstcFormat(format)); 2427e5c31af7Sopenharmony_ci DE_ASSERT(!(isAstcSRGBFormat(format) && isBlockTestTypeHDROnly(testType))); 2428e5c31af7Sopenharmony_ci 2429e5c31af7Sopenharmony_ci const IVec3 blockSize = getBlockPixelSize(format); 2430e5c31af7Sopenharmony_ci DE_ASSERT(blockSize.z() == 1); 2431e5c31af7Sopenharmony_ci 2432e5c31af7Sopenharmony_ci switch (testType) 2433e5c31af7Sopenharmony_ci { 2434e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_LDR: 2435e5c31af7Sopenharmony_ci // Generate a gradient-like set of LDR void-extent blocks. 2436e5c31af7Sopenharmony_ci { 2437e5c31af7Sopenharmony_ci const int numBlocks = 1<<13; 2438e5c31af7Sopenharmony_ci const deUint32 numValues = 1<<16; 2439e5c31af7Sopenharmony_ci dst.reserve(numBlocks*BLOCK_SIZE_BYTES); 2440e5c31af7Sopenharmony_ci 2441e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2442e5c31af7Sopenharmony_ci { 2443e5c31af7Sopenharmony_ci const deUint32 baseValue = blockNdx*(numValues-1) / (numBlocks-1); 2444e5c31af7Sopenharmony_ci const deUint16 r = (deUint16)((baseValue + numValues*0/4) % numValues); 2445e5c31af7Sopenharmony_ci const deUint16 g = (deUint16)((baseValue + numValues*1/4) % numValues); 2446e5c31af7Sopenharmony_ci const deUint16 b = (deUint16)((baseValue + numValues*2/4) % numValues); 2447e5c31af7Sopenharmony_ci const deUint16 a = (deUint16)((baseValue + numValues*3/4) % numValues); 2448e5c31af7Sopenharmony_ci AssignBlock128 block; 2449e5c31af7Sopenharmony_ci 2450e5c31af7Sopenharmony_ci generateVoidExtentBlock(VoidExtentParams(false, r, g, b, a)).pushBytesToVector(dst); 2451e5c31af7Sopenharmony_ci } 2452e5c31af7Sopenharmony_ci 2453e5c31af7Sopenharmony_ci break; 2454e5c31af7Sopenharmony_ci } 2455e5c31af7Sopenharmony_ci 2456e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_HDR: 2457e5c31af7Sopenharmony_ci // Generate a gradient-like set of HDR void-extent blocks, with values ranging from the largest finite negative to largest finite positive of fp16. 2458e5c31af7Sopenharmony_ci { 2459e5c31af7Sopenharmony_ci const float minValue = -65504.0f; 2460e5c31af7Sopenharmony_ci const float maxValue = +65504.0f; 2461e5c31af7Sopenharmony_ci const int numBlocks = 1<<13; 2462e5c31af7Sopenharmony_ci dst.reserve(numBlocks*BLOCK_SIZE_BYTES); 2463e5c31af7Sopenharmony_ci 2464e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2465e5c31af7Sopenharmony_ci { 2466e5c31af7Sopenharmony_ci const int rNdx = (blockNdx + numBlocks*0/4) % numBlocks; 2467e5c31af7Sopenharmony_ci const int gNdx = (blockNdx + numBlocks*1/4) % numBlocks; 2468e5c31af7Sopenharmony_ci const int bNdx = (blockNdx + numBlocks*2/4) % numBlocks; 2469e5c31af7Sopenharmony_ci const int aNdx = (blockNdx + numBlocks*3/4) % numBlocks; 2470e5c31af7Sopenharmony_ci const deFloat16 r = deFloat32To16(minValue + (float)rNdx * (maxValue - minValue) / (float)(numBlocks-1)); 2471e5c31af7Sopenharmony_ci const deFloat16 g = deFloat32To16(minValue + (float)gNdx * (maxValue - minValue) / (float)(numBlocks-1)); 2472e5c31af7Sopenharmony_ci const deFloat16 b = deFloat32To16(minValue + (float)bNdx * (maxValue - minValue) / (float)(numBlocks-1)); 2473e5c31af7Sopenharmony_ci const deFloat16 a = deFloat32To16(minValue + (float)aNdx * (maxValue - minValue) / (float)(numBlocks-1)); 2474e5c31af7Sopenharmony_ci 2475e5c31af7Sopenharmony_ci generateVoidExtentBlock(VoidExtentParams(true, r, g, b, a)).pushBytesToVector(dst); 2476e5c31af7Sopenharmony_ci } 2477e5c31af7Sopenharmony_ci 2478e5c31af7Sopenharmony_ci break; 2479e5c31af7Sopenharmony_ci } 2480e5c31af7Sopenharmony_ci 2481e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_GRID: 2482e5c31af7Sopenharmony_ci // Generate different combinations of plane count, weight ISE params, and grid size. 2483e5c31af7Sopenharmony_ci { 2484e5c31af7Sopenharmony_ci for (int isDualPlane = 0; isDualPlane <= 1; isDualPlane++) 2485e5c31af7Sopenharmony_ci for (int iseParamsNdx = 0; iseParamsNdx < DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates); iseParamsNdx++) 2486e5c31af7Sopenharmony_ci for (int weightGridWidth = 2; weightGridWidth <= 12; weightGridWidth++) 2487e5c31af7Sopenharmony_ci for (int weightGridHeight = 2; weightGridHeight <= 12; weightGridHeight++) 2488e5c31af7Sopenharmony_ci { 2489e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2490e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs; 2491e5c31af7Sopenharmony_ci 2492e5c31af7Sopenharmony_ci blockParams.weightGridWidth = weightGridWidth; 2493e5c31af7Sopenharmony_ci blockParams.weightGridHeight = weightGridHeight; 2494e5c31af7Sopenharmony_ci blockParams.isDualPlane = isDualPlane != 0; 2495e5c31af7Sopenharmony_ci blockParams.weightISEParams = s_weightISEParamsCandidates[iseParamsNdx]; 2496e5c31af7Sopenharmony_ci blockParams.ccs = 0; 2497e5c31af7Sopenharmony_ci blockParams.numPartitions = 1; 2498e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 0; 2499e5c31af7Sopenharmony_ci 2500e5c31af7Sopenharmony_ci if (isValidBlockParams(blockParams, blockSize.x(), blockSize.y())) 2501e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), generateDefaultISEInputs(blockParams)).pushBytesToVector(dst); 2502e5c31af7Sopenharmony_ci } 2503e5c31af7Sopenharmony_ci 2504e5c31af7Sopenharmony_ci break; 2505e5c31af7Sopenharmony_ci } 2506e5c31af7Sopenharmony_ci 2507e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_ISE: 2508e5c31af7Sopenharmony_ci // For each weight ISE param set, generate blocks that cover: 2509e5c31af7Sopenharmony_ci // - each single value of the ISE's range, at each position inside an ISE block 2510e5c31af7Sopenharmony_ci // - for trit and quint ISEs, each single T or Q value of an ISE block 2511e5c31af7Sopenharmony_ci { 2512e5c31af7Sopenharmony_ci for (int iseParamsNdx = 0; iseParamsNdx < DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates); iseParamsNdx++) 2513e5c31af7Sopenharmony_ci { 2514e5c31af7Sopenharmony_ci const ISEParams& iseParams = s_weightISEParamsCandidates[iseParamsNdx]; 2515e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2516e5c31af7Sopenharmony_ci 2517e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 4; 2518e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 4; 2519e5c31af7Sopenharmony_ci blockParams.weightISEParams = iseParams; 2520e5c31af7Sopenharmony_ci blockParams.numPartitions = 1; 2521e5c31af7Sopenharmony_ci blockParams.isDualPlane = blockParams.weightGridWidth * blockParams.weightGridHeight < 24 ? true : false; 2522e5c31af7Sopenharmony_ci blockParams.ccs = 0; 2523e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 0; 2524e5c31af7Sopenharmony_ci 2525e5c31af7Sopenharmony_ci while (!isValidBlockParams(blockParams, blockSize.x(), blockSize.y())) 2526e5c31af7Sopenharmony_ci { 2527e5c31af7Sopenharmony_ci blockParams.weightGridWidth--; 2528e5c31af7Sopenharmony_ci blockParams.weightGridHeight--; 2529e5c31af7Sopenharmony_ci } 2530e5c31af7Sopenharmony_ci 2531e5c31af7Sopenharmony_ci const int numValuesInISEBlock = iseParams.mode == ISEMODE_TRIT ? 5 : iseParams.mode == ISEMODE_QUINT ? 3 : 1; 2532e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockParams); 2533e5c31af7Sopenharmony_ci 2534e5c31af7Sopenharmony_ci { 2535e5c31af7Sopenharmony_ci const int numWeightValues = (int)computeISERangeMax(iseParams) + 1; 2536e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numWeightValues, numWeights); 2537e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2538e5c31af7Sopenharmony_ci iseInputs.weight.isGivenInBlockForm = false; 2539e5c31af7Sopenharmony_ci 2540e5c31af7Sopenharmony_ci for (int offset = 0; offset < numValuesInISEBlock; offset++) 2541e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2542e5c31af7Sopenharmony_ci { 2543e5c31af7Sopenharmony_ci for (int weightNdx = 0; weightNdx < numWeights; weightNdx++) 2544e5c31af7Sopenharmony_ci iseInputs.weight.value.plain[weightNdx] = (blockNdx*numWeights + weightNdx + offset) % numWeightValues; 2545e5c31af7Sopenharmony_ci 2546e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).pushBytesToVector(dst); 2547e5c31af7Sopenharmony_ci } 2548e5c31af7Sopenharmony_ci } 2549e5c31af7Sopenharmony_ci 2550e5c31af7Sopenharmony_ci if (iseParams.mode == ISEMODE_TRIT || iseParams.mode == ISEMODE_QUINT) 2551e5c31af7Sopenharmony_ci { 2552e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2553e5c31af7Sopenharmony_ci iseInputs.weight.isGivenInBlockForm = true; 2554e5c31af7Sopenharmony_ci 2555e5c31af7Sopenharmony_ci const int numTQValues = 1 << (iseParams.mode == ISEMODE_TRIT ? 8 : 7); 2556e5c31af7Sopenharmony_ci const int numISEBlocksPerBlock = deDivRoundUp32(numWeights, numValuesInISEBlock); 2557e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numTQValues, numISEBlocksPerBlock); 2558e5c31af7Sopenharmony_ci 2559e5c31af7Sopenharmony_ci for (int offset = 0; offset < numValuesInISEBlock; offset++) 2560e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2561e5c31af7Sopenharmony_ci { 2562e5c31af7Sopenharmony_ci for (int iseBlockNdx = 0; iseBlockNdx < numISEBlocksPerBlock; iseBlockNdx++) 2563e5c31af7Sopenharmony_ci { 2564e5c31af7Sopenharmony_ci for (int i = 0; i < numValuesInISEBlock; i++) 2565e5c31af7Sopenharmony_ci iseInputs.weight.value.block[iseBlockNdx].bitValues[i] = 0; 2566e5c31af7Sopenharmony_ci iseInputs.weight.value.block[iseBlockNdx].tOrQValue = (blockNdx*numISEBlocksPerBlock + iseBlockNdx + offset) % numTQValues; 2567e5c31af7Sopenharmony_ci } 2568e5c31af7Sopenharmony_ci 2569e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).pushBytesToVector(dst); 2570e5c31af7Sopenharmony_ci } 2571e5c31af7Sopenharmony_ci } 2572e5c31af7Sopenharmony_ci } 2573e5c31af7Sopenharmony_ci 2574e5c31af7Sopenharmony_ci break; 2575e5c31af7Sopenharmony_ci } 2576e5c31af7Sopenharmony_ci 2577e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CEMS: 2578e5c31af7Sopenharmony_ci // For each plane count & partition count combination, generate all color endpoint mode combinations. 2579e5c31af7Sopenharmony_ci { 2580e5c31af7Sopenharmony_ci for (int isDualPlane = 0; isDualPlane <= 1; isDualPlane++) 2581e5c31af7Sopenharmony_ci for (int numPartitions = 1; numPartitions <= (isDualPlane != 0 ? 3 : 4); numPartitions++) 2582e5c31af7Sopenharmony_ci { 2583e5c31af7Sopenharmony_ci // Multi-partition, single-CEM mode. 2584e5c31af7Sopenharmony_ci if (numPartitions > 1) 2585e5c31af7Sopenharmony_ci { 2586e5c31af7Sopenharmony_ci for (deUint32 singleCem = 0; singleCem < 16; singleCem++) 2587e5c31af7Sopenharmony_ci { 2588e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2589e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 4; 2590e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 4; 2591e5c31af7Sopenharmony_ci blockParams.isDualPlane = isDualPlane != 0; 2592e5c31af7Sopenharmony_ci blockParams.ccs = 0; 2593e5c31af7Sopenharmony_ci blockParams.numPartitions = numPartitions; 2594e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = true; 2595e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = singleCem; 2596e5c31af7Sopenharmony_ci blockParams.partitionSeed = 634; 2597e5c31af7Sopenharmony_ci 2598e5c31af7Sopenharmony_ci for (int iseParamsNdx = 0; iseParamsNdx < DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates); iseParamsNdx++) 2599e5c31af7Sopenharmony_ci { 2600e5c31af7Sopenharmony_ci blockParams.weightISEParams = s_weightISEParamsCandidates[iseParamsNdx]; 2601e5c31af7Sopenharmony_ci if (isValidBlockParams(blockParams, blockSize.x(), blockSize.y())) 2602e5c31af7Sopenharmony_ci { 2603e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), generateDefaultISEInputs(blockParams)).pushBytesToVector(dst); 2604e5c31af7Sopenharmony_ci break; 2605e5c31af7Sopenharmony_ci } 2606e5c31af7Sopenharmony_ci } 2607e5c31af7Sopenharmony_ci } 2608e5c31af7Sopenharmony_ci } 2609e5c31af7Sopenharmony_ci 2610e5c31af7Sopenharmony_ci // Separate-CEM mode. 2611e5c31af7Sopenharmony_ci for (deUint32 cem0 = 0; cem0 < 16; cem0++) 2612e5c31af7Sopenharmony_ci for (deUint32 cem1 = 0; cem1 < (numPartitions >= 2 ? 16u : 1u); cem1++) 2613e5c31af7Sopenharmony_ci for (deUint32 cem2 = 0; cem2 < (numPartitions >= 3 ? 16u : 1u); cem2++) 2614e5c31af7Sopenharmony_ci for (deUint32 cem3 = 0; cem3 < (numPartitions >= 4 ? 16u : 1u); cem3++) 2615e5c31af7Sopenharmony_ci { 2616e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2617e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 4; 2618e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 4; 2619e5c31af7Sopenharmony_ci blockParams.isDualPlane = isDualPlane != 0; 2620e5c31af7Sopenharmony_ci blockParams.ccs = 0; 2621e5c31af7Sopenharmony_ci blockParams.numPartitions = numPartitions; 2622e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = false; 2623e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = cem0; 2624e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[1] = cem1; 2625e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[2] = cem2; 2626e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[3] = cem3; 2627e5c31af7Sopenharmony_ci blockParams.partitionSeed = 634; 2628e5c31af7Sopenharmony_ci 2629e5c31af7Sopenharmony_ci { 2630e5c31af7Sopenharmony_ci const deUint32 minCem = *std::min_element(&blockParams.colorEndpointModes[0], &blockParams.colorEndpointModes[numPartitions]); 2631e5c31af7Sopenharmony_ci const deUint32 maxCem = *std::max_element(&blockParams.colorEndpointModes[0], &blockParams.colorEndpointModes[numPartitions]); 2632e5c31af7Sopenharmony_ci const deUint32 minCemClass = minCem/4; 2633e5c31af7Sopenharmony_ci const deUint32 maxCemClass = maxCem/4; 2634e5c31af7Sopenharmony_ci 2635e5c31af7Sopenharmony_ci if (maxCemClass - minCemClass > 1) 2636e5c31af7Sopenharmony_ci continue; 2637e5c31af7Sopenharmony_ci } 2638e5c31af7Sopenharmony_ci 2639e5c31af7Sopenharmony_ci for (int iseParamsNdx = 0; iseParamsNdx < DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates); iseParamsNdx++) 2640e5c31af7Sopenharmony_ci { 2641e5c31af7Sopenharmony_ci blockParams.weightISEParams = s_weightISEParamsCandidates[iseParamsNdx]; 2642e5c31af7Sopenharmony_ci if (isValidBlockParams(blockParams, blockSize.x(), blockSize.y())) 2643e5c31af7Sopenharmony_ci { 2644e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), generateDefaultISEInputs(blockParams)).pushBytesToVector(dst); 2645e5c31af7Sopenharmony_ci break; 2646e5c31af7Sopenharmony_ci } 2647e5c31af7Sopenharmony_ci } 2648e5c31af7Sopenharmony_ci } 2649e5c31af7Sopenharmony_ci } 2650e5c31af7Sopenharmony_ci 2651e5c31af7Sopenharmony_ci break; 2652e5c31af7Sopenharmony_ci } 2653e5c31af7Sopenharmony_ci 2654e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_PARTITION_SEED: 2655e5c31af7Sopenharmony_ci // Test all partition seeds ("partition pattern indices"). 2656e5c31af7Sopenharmony_ci { 2657e5c31af7Sopenharmony_ci for (int numPartitions = 2; numPartitions <= 4; numPartitions++) 2658e5c31af7Sopenharmony_ci for (deUint32 partitionSeed = 0; partitionSeed < 1<<10; partitionSeed++) 2659e5c31af7Sopenharmony_ci { 2660e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2661e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 4; 2662e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 4; 2663e5c31af7Sopenharmony_ci blockParams.weightISEParams = ISEParams(ISEMODE_PLAIN_BIT, 2); 2664e5c31af7Sopenharmony_ci blockParams.isDualPlane = false; 2665e5c31af7Sopenharmony_ci blockParams.numPartitions = numPartitions; 2666e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = true; 2667e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 0; 2668e5c31af7Sopenharmony_ci blockParams.partitionSeed = partitionSeed; 2669e5c31af7Sopenharmony_ci 2670e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), generateDefaultISEInputs(blockParams)).pushBytesToVector(dst); 2671e5c31af7Sopenharmony_ci } 2672e5c31af7Sopenharmony_ci 2673e5c31af7Sopenharmony_ci break; 2674e5c31af7Sopenharmony_ci } 2675e5c31af7Sopenharmony_ci 2676e5c31af7Sopenharmony_ci // \note Fall-through. 2677e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_LDR: 2678e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15: 2679e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15: 2680e5c31af7Sopenharmony_ci // For each endpoint mode, for each pair of components in the endpoint value, test 10x10 combinations of values for that pair. 2681e5c31af7Sopenharmony_ci // \note Separate modes for HDR and mode 15 due to different color scales and biases. 2682e5c31af7Sopenharmony_ci { 2683e5c31af7Sopenharmony_ci for (deUint32 cem = 0; cem < 16; cem++) 2684e5c31af7Sopenharmony_ci { 2685e5c31af7Sopenharmony_ci const bool isHDRCem = cem == 2 || 2686e5c31af7Sopenharmony_ci cem == 3 || 2687e5c31af7Sopenharmony_ci cem == 7 || 2688e5c31af7Sopenharmony_ci cem == 11 || 2689e5c31af7Sopenharmony_ci cem == 14 || 2690e5c31af7Sopenharmony_ci cem == 15; 2691e5c31af7Sopenharmony_ci 2692e5c31af7Sopenharmony_ci if ((testType == BLOCK_TEST_TYPE_ENDPOINT_VALUE_LDR && isHDRCem) || 2693e5c31af7Sopenharmony_ci (testType == BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15 && (!isHDRCem || cem == 15)) || 2694e5c31af7Sopenharmony_ci (testType == BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15 && cem != 15)) 2695e5c31af7Sopenharmony_ci continue; 2696e5c31af7Sopenharmony_ci 2697e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2698e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 3; 2699e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 4; 2700e5c31af7Sopenharmony_ci blockParams.weightISEParams = ISEParams(ISEMODE_PLAIN_BIT, 2); 2701e5c31af7Sopenharmony_ci blockParams.isDualPlane = false; 2702e5c31af7Sopenharmony_ci blockParams.numPartitions = 1; 2703e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = cem; 2704e5c31af7Sopenharmony_ci 2705e5c31af7Sopenharmony_ci { 2706e5c31af7Sopenharmony_ci const int numBitsForEndpoints = computeNumBitsForColorEndpoints(blockParams); 2707e5c31af7Sopenharmony_ci const int numEndpointParts = computeNumColorEndpointValues(cem); 2708e5c31af7Sopenharmony_ci const ISEParams endpointISE = computeMaximumRangeISEParams(numBitsForEndpoints, numEndpointParts); 2709e5c31af7Sopenharmony_ci const int endpointISERangeMax = computeISERangeMax(endpointISE); 2710e5c31af7Sopenharmony_ci 2711e5c31af7Sopenharmony_ci for (int endpointPartNdx0 = 0; endpointPartNdx0 < numEndpointParts; endpointPartNdx0++) 2712e5c31af7Sopenharmony_ci for (int endpointPartNdx1 = endpointPartNdx0+1; endpointPartNdx1 < numEndpointParts; endpointPartNdx1++) 2713e5c31af7Sopenharmony_ci { 2714e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2715e5c31af7Sopenharmony_ci const int numEndpointValues = de::min(10, endpointISERangeMax+1); 2716e5c31af7Sopenharmony_ci 2717e5c31af7Sopenharmony_ci for (int endpointValueNdx0 = 0; endpointValueNdx0 < numEndpointValues; endpointValueNdx0++) 2718e5c31af7Sopenharmony_ci for (int endpointValueNdx1 = 0; endpointValueNdx1 < numEndpointValues; endpointValueNdx1++) 2719e5c31af7Sopenharmony_ci { 2720e5c31af7Sopenharmony_ci const int endpointValue0 = endpointValueNdx0 * endpointISERangeMax / (numEndpointValues-1); 2721e5c31af7Sopenharmony_ci const int endpointValue1 = endpointValueNdx1 * endpointISERangeMax / (numEndpointValues-1); 2722e5c31af7Sopenharmony_ci 2723e5c31af7Sopenharmony_ci iseInputs.endpoint.value.plain[endpointPartNdx0] = endpointValue0; 2724e5c31af7Sopenharmony_ci iseInputs.endpoint.value.plain[endpointPartNdx1] = endpointValue1; 2725e5c31af7Sopenharmony_ci 2726e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).pushBytesToVector(dst); 2727e5c31af7Sopenharmony_ci } 2728e5c31af7Sopenharmony_ci } 2729e5c31af7Sopenharmony_ci } 2730e5c31af7Sopenharmony_ci } 2731e5c31af7Sopenharmony_ci 2732e5c31af7Sopenharmony_ci break; 2733e5c31af7Sopenharmony_ci } 2734e5c31af7Sopenharmony_ci 2735e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_ISE: 2736e5c31af7Sopenharmony_ci // Similar to BLOCK_TEST_TYPE_WEIGHT_ISE, see above. 2737e5c31af7Sopenharmony_ci { 2738e5c31af7Sopenharmony_ci static const deUint32 endpointRangeMaximums[] = { 5, 9, 11, 19, 23, 39, 47, 79, 95, 159, 191 }; 2739e5c31af7Sopenharmony_ci 2740e5c31af7Sopenharmony_ci for (int endpointRangeNdx = 0; endpointRangeNdx < DE_LENGTH_OF_ARRAY(endpointRangeMaximums); endpointRangeNdx++) 2741e5c31af7Sopenharmony_ci { 2742e5c31af7Sopenharmony_ci bool validCaseGenerated = false; 2743e5c31af7Sopenharmony_ci 2744e5c31af7Sopenharmony_ci for (int numPartitions = 1; !validCaseGenerated && numPartitions <= 4; numPartitions++) 2745e5c31af7Sopenharmony_ci for (int isDual = 0; !validCaseGenerated && isDual <= 1; isDual++) 2746e5c31af7Sopenharmony_ci for (int weightISEParamsNdx = 0; !validCaseGenerated && weightISEParamsNdx < DE_LENGTH_OF_ARRAY(s_weightISEParamsCandidates); weightISEParamsNdx++) 2747e5c31af7Sopenharmony_ci for (int weightGridWidth = 2; !validCaseGenerated && weightGridWidth <= 12; weightGridWidth++) 2748e5c31af7Sopenharmony_ci for (int weightGridHeight = 2; !validCaseGenerated && weightGridHeight <= 12; weightGridHeight++) 2749e5c31af7Sopenharmony_ci { 2750e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2751e5c31af7Sopenharmony_ci blockParams.weightGridWidth = weightGridWidth; 2752e5c31af7Sopenharmony_ci blockParams.weightGridHeight = weightGridHeight; 2753e5c31af7Sopenharmony_ci blockParams.weightISEParams = s_weightISEParamsCandidates[weightISEParamsNdx]; 2754e5c31af7Sopenharmony_ci blockParams.isDualPlane = isDual != 0; 2755e5c31af7Sopenharmony_ci blockParams.ccs = 0; 2756e5c31af7Sopenharmony_ci blockParams.numPartitions = numPartitions; 2757e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = true; 2758e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 12; 2759e5c31af7Sopenharmony_ci blockParams.partitionSeed = 634; 2760e5c31af7Sopenharmony_ci 2761e5c31af7Sopenharmony_ci if (isValidBlockParams(blockParams, blockSize.x(), blockSize.y())) 2762e5c31af7Sopenharmony_ci { 2763e5c31af7Sopenharmony_ci const ISEParams endpointISEParams = computeMaximumRangeISEParams(computeNumBitsForColorEndpoints(blockParams), 2764e5c31af7Sopenharmony_ci computeNumColorEndpointValues(&blockParams.colorEndpointModes[0], numPartitions, true)); 2765e5c31af7Sopenharmony_ci 2766e5c31af7Sopenharmony_ci if (computeISERangeMax(endpointISEParams) == endpointRangeMaximums[endpointRangeNdx]) 2767e5c31af7Sopenharmony_ci { 2768e5c31af7Sopenharmony_ci validCaseGenerated = true; 2769e5c31af7Sopenharmony_ci 2770e5c31af7Sopenharmony_ci const int numColorEndpoints = computeNumColorEndpointValues(&blockParams.colorEndpointModes[0], numPartitions, blockParams.isMultiPartSingleCemMode); 2771e5c31af7Sopenharmony_ci const int numValuesInISEBlock = endpointISEParams.mode == ISEMODE_TRIT ? 5 : endpointISEParams.mode == ISEMODE_QUINT ? 3 : 1; 2772e5c31af7Sopenharmony_ci 2773e5c31af7Sopenharmony_ci { 2774e5c31af7Sopenharmony_ci const int numColorEndpointValues = (int)computeISERangeMax(endpointISEParams) + 1; 2775e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numColorEndpointValues, numColorEndpoints); 2776e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2777e5c31af7Sopenharmony_ci iseInputs.endpoint.isGivenInBlockForm = false; 2778e5c31af7Sopenharmony_ci 2779e5c31af7Sopenharmony_ci for (int offset = 0; offset < numValuesInISEBlock; offset++) 2780e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2781e5c31af7Sopenharmony_ci { 2782e5c31af7Sopenharmony_ci for (int endpointNdx = 0; endpointNdx < numColorEndpoints; endpointNdx++) 2783e5c31af7Sopenharmony_ci iseInputs.endpoint.value.plain[endpointNdx] = (blockNdx*numColorEndpoints + endpointNdx + offset) % numColorEndpointValues; 2784e5c31af7Sopenharmony_ci 2785e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).pushBytesToVector(dst); 2786e5c31af7Sopenharmony_ci } 2787e5c31af7Sopenharmony_ci } 2788e5c31af7Sopenharmony_ci 2789e5c31af7Sopenharmony_ci if (endpointISEParams.mode == ISEMODE_TRIT || endpointISEParams.mode == ISEMODE_QUINT) 2790e5c31af7Sopenharmony_ci { 2791e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2792e5c31af7Sopenharmony_ci iseInputs.endpoint.isGivenInBlockForm = true; 2793e5c31af7Sopenharmony_ci 2794e5c31af7Sopenharmony_ci const int numTQValues = 1 << (endpointISEParams.mode == ISEMODE_TRIT ? 8 : 7); 2795e5c31af7Sopenharmony_ci const int numISEBlocksPerBlock = deDivRoundUp32(numColorEndpoints, numValuesInISEBlock); 2796e5c31af7Sopenharmony_ci const int numBlocks = deDivRoundUp32(numTQValues, numISEBlocksPerBlock); 2797e5c31af7Sopenharmony_ci 2798e5c31af7Sopenharmony_ci for (int offset = 0; offset < numValuesInISEBlock; offset++) 2799e5c31af7Sopenharmony_ci for (int blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2800e5c31af7Sopenharmony_ci { 2801e5c31af7Sopenharmony_ci for (int iseBlockNdx = 0; iseBlockNdx < numISEBlocksPerBlock; iseBlockNdx++) 2802e5c31af7Sopenharmony_ci { 2803e5c31af7Sopenharmony_ci for (int i = 0; i < numValuesInISEBlock; i++) 2804e5c31af7Sopenharmony_ci iseInputs.endpoint.value.block[iseBlockNdx].bitValues[i] = 0; 2805e5c31af7Sopenharmony_ci iseInputs.endpoint.value.block[iseBlockNdx].tOrQValue = (blockNdx*numISEBlocksPerBlock + iseBlockNdx + offset) % numTQValues; 2806e5c31af7Sopenharmony_ci } 2807e5c31af7Sopenharmony_ci 2808e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), iseInputs).pushBytesToVector(dst); 2809e5c31af7Sopenharmony_ci } 2810e5c31af7Sopenharmony_ci } 2811e5c31af7Sopenharmony_ci } 2812e5c31af7Sopenharmony_ci } 2813e5c31af7Sopenharmony_ci } 2814e5c31af7Sopenharmony_ci 2815e5c31af7Sopenharmony_ci DE_ASSERT(validCaseGenerated); 2816e5c31af7Sopenharmony_ci } 2817e5c31af7Sopenharmony_ci 2818e5c31af7Sopenharmony_ci break; 2819e5c31af7Sopenharmony_ci } 2820e5c31af7Sopenharmony_ci 2821e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CCS: 2822e5c31af7Sopenharmony_ci // For all partition counts, test all values of the CCS (color component selector). 2823e5c31af7Sopenharmony_ci { 2824e5c31af7Sopenharmony_ci for (int numPartitions = 1; numPartitions <= 3; numPartitions++) 2825e5c31af7Sopenharmony_ci for (deUint32 ccs = 0; ccs < 4; ccs++) 2826e5c31af7Sopenharmony_ci { 2827e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2828e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 3; 2829e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 3; 2830e5c31af7Sopenharmony_ci blockParams.weightISEParams = ISEParams(ISEMODE_PLAIN_BIT, 2); 2831e5c31af7Sopenharmony_ci blockParams.isDualPlane = true; 2832e5c31af7Sopenharmony_ci blockParams.ccs = ccs; 2833e5c31af7Sopenharmony_ci blockParams.numPartitions = numPartitions; 2834e5c31af7Sopenharmony_ci blockParams.isMultiPartSingleCemMode = true; 2835e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 8; 2836e5c31af7Sopenharmony_ci blockParams.partitionSeed = 634; 2837e5c31af7Sopenharmony_ci 2838e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockSize.x(), blockSize.y(), generateDefaultISEInputs(blockParams)).pushBytesToVector(dst); 2839e5c31af7Sopenharmony_ci } 2840e5c31af7Sopenharmony_ci 2841e5c31af7Sopenharmony_ci break; 2842e5c31af7Sopenharmony_ci } 2843e5c31af7Sopenharmony_ci 2844e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_RANDOM: 2845e5c31af7Sopenharmony_ci // Generate a number of random (including invalid) blocks. 2846e5c31af7Sopenharmony_ci { 2847e5c31af7Sopenharmony_ci const int numBlocks = 16384; 2848e5c31af7Sopenharmony_ci const deUint32 seed = 1; 2849e5c31af7Sopenharmony_ci 2850e5c31af7Sopenharmony_ci dst.resize(numBlocks*BLOCK_SIZE_BYTES); 2851e5c31af7Sopenharmony_ci 2852e5c31af7Sopenharmony_ci generateRandomBlocks(&dst[0], numBlocks, format, seed); 2853e5c31af7Sopenharmony_ci 2854e5c31af7Sopenharmony_ci break; 2855e5c31af7Sopenharmony_ci } 2856e5c31af7Sopenharmony_ci 2857e5c31af7Sopenharmony_ci default: 2858e5c31af7Sopenharmony_ci DE_ASSERT(false); 2859e5c31af7Sopenharmony_ci } 2860e5c31af7Sopenharmony_ci} 2861e5c31af7Sopenharmony_ci 2862e5c31af7Sopenharmony_civoid generateRandomBlocks (deUint8* dst, size_t numBlocks, CompressedTexFormat format, deUint32 seed) 2863e5c31af7Sopenharmony_ci{ 2864e5c31af7Sopenharmony_ci const IVec3 blockSize = getBlockPixelSize(format); 2865e5c31af7Sopenharmony_ci de::Random rnd (seed); 2866e5c31af7Sopenharmony_ci size_t numBlocksGenerated = 0; 2867e5c31af7Sopenharmony_ci 2868e5c31af7Sopenharmony_ci DE_ASSERT(isAstcFormat(format)); 2869e5c31af7Sopenharmony_ci DE_ASSERT(blockSize.z() == 1); 2870e5c31af7Sopenharmony_ci 2871e5c31af7Sopenharmony_ci for (numBlocksGenerated = 0; numBlocksGenerated < numBlocks; numBlocksGenerated++) 2872e5c31af7Sopenharmony_ci { 2873e5c31af7Sopenharmony_ci deUint8* const curBlockPtr = dst + numBlocksGenerated*BLOCK_SIZE_BYTES; 2874e5c31af7Sopenharmony_ci 2875e5c31af7Sopenharmony_ci generateRandomBlock(curBlockPtr, blockSize, rnd); 2876e5c31af7Sopenharmony_ci } 2877e5c31af7Sopenharmony_ci} 2878e5c31af7Sopenharmony_ci 2879e5c31af7Sopenharmony_civoid generateRandomValidBlocks (deUint8* dst, size_t numBlocks, CompressedTexFormat format, TexDecompressionParams::AstcMode mode, deUint32 seed) 2880e5c31af7Sopenharmony_ci{ 2881e5c31af7Sopenharmony_ci const IVec3 blockSize = getBlockPixelSize(format); 2882e5c31af7Sopenharmony_ci de::Random rnd (seed); 2883e5c31af7Sopenharmony_ci size_t numBlocksGenerated = 0; 2884e5c31af7Sopenharmony_ci 2885e5c31af7Sopenharmony_ci DE_ASSERT(isAstcFormat(format)); 2886e5c31af7Sopenharmony_ci DE_ASSERT(blockSize.z() == 1); 2887e5c31af7Sopenharmony_ci 2888e5c31af7Sopenharmony_ci for (numBlocksGenerated = 0; numBlocksGenerated < numBlocks; numBlocksGenerated++) 2889e5c31af7Sopenharmony_ci { 2890e5c31af7Sopenharmony_ci deUint8* const curBlockPtr = dst + numBlocksGenerated*BLOCK_SIZE_BYTES; 2891e5c31af7Sopenharmony_ci 2892e5c31af7Sopenharmony_ci do 2893e5c31af7Sopenharmony_ci { 2894e5c31af7Sopenharmony_ci generateRandomBlock(curBlockPtr, blockSize, rnd); 2895e5c31af7Sopenharmony_ci } while (!isValidBlock(curBlockPtr, format, mode)); 2896e5c31af7Sopenharmony_ci } 2897e5c31af7Sopenharmony_ci} 2898e5c31af7Sopenharmony_ci 2899e5c31af7Sopenharmony_ci// Generate a number of trivial blocks to fill unneeded space in a texture. 2900e5c31af7Sopenharmony_civoid generateDefaultVoidExtentBlocks (deUint8* dst, size_t numBlocks) 2901e5c31af7Sopenharmony_ci{ 2902e5c31af7Sopenharmony_ci AssignBlock128 block = generateVoidExtentBlock(VoidExtentParams(false, 0, 0, 0, 0)); 2903e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < numBlocks; ndx++) 2904e5c31af7Sopenharmony_ci block.assignToMemory(&dst[ndx * BLOCK_SIZE_BYTES]); 2905e5c31af7Sopenharmony_ci} 2906e5c31af7Sopenharmony_ci 2907e5c31af7Sopenharmony_civoid generateDefaultNormalBlocks (deUint8* dst, size_t numBlocks, int blockWidth, int blockHeight) 2908e5c31af7Sopenharmony_ci{ 2909e5c31af7Sopenharmony_ci NormalBlockParams blockParams; 2910e5c31af7Sopenharmony_ci 2911e5c31af7Sopenharmony_ci blockParams.weightGridWidth = 3; 2912e5c31af7Sopenharmony_ci blockParams.weightGridHeight = 3; 2913e5c31af7Sopenharmony_ci blockParams.weightISEParams = ISEParams(ISEMODE_PLAIN_BIT, 5); 2914e5c31af7Sopenharmony_ci blockParams.isDualPlane = false; 2915e5c31af7Sopenharmony_ci blockParams.numPartitions = 1; 2916e5c31af7Sopenharmony_ci blockParams.colorEndpointModes[0] = 8; 2917e5c31af7Sopenharmony_ci 2918e5c31af7Sopenharmony_ci NormalBlockISEInputs iseInputs = generateDefaultISEInputs(blockParams); 2919e5c31af7Sopenharmony_ci iseInputs.weight.isGivenInBlockForm = false; 2920e5c31af7Sopenharmony_ci 2921e5c31af7Sopenharmony_ci const int numWeights = computeNumWeights(blockParams); 2922e5c31af7Sopenharmony_ci const int weightRangeMax = computeISERangeMax(blockParams.weightISEParams); 2923e5c31af7Sopenharmony_ci 2924e5c31af7Sopenharmony_ci for (size_t blockNdx = 0; blockNdx < numBlocks; blockNdx++) 2925e5c31af7Sopenharmony_ci { 2926e5c31af7Sopenharmony_ci for (int weightNdx = 0; weightNdx < numWeights; weightNdx++) 2927e5c31af7Sopenharmony_ci iseInputs.weight.value.plain[weightNdx] = (deUint32)((blockNdx*numWeights + weightNdx) * weightRangeMax / (numBlocks*numWeights-1)); 2928e5c31af7Sopenharmony_ci 2929e5c31af7Sopenharmony_ci generateNormalBlock(blockParams, blockWidth, blockHeight, iseInputs).assignToMemory(dst + blockNdx*BLOCK_SIZE_BYTES); 2930e5c31af7Sopenharmony_ci } 2931e5c31af7Sopenharmony_ci} 2932e5c31af7Sopenharmony_ci 2933e5c31af7Sopenharmony_cibool isValidBlock (const deUint8* data, CompressedTexFormat format, TexDecompressionParams::AstcMode mode) 2934e5c31af7Sopenharmony_ci{ 2935e5c31af7Sopenharmony_ci const tcu::IVec3 blockPixelSize = getBlockPixelSize(format); 2936e5c31af7Sopenharmony_ci const bool isSRGB = isAstcSRGBFormat(format); 2937e5c31af7Sopenharmony_ci const bool isLDR = isSRGB || mode == TexDecompressionParams::ASTCMODE_LDR; 2938e5c31af7Sopenharmony_ci 2939e5c31af7Sopenharmony_ci // sRGB is not supported in HDR mode 2940e5c31af7Sopenharmony_ci DE_ASSERT(!(mode == TexDecompressionParams::ASTCMODE_HDR && isSRGB)); 2941e5c31af7Sopenharmony_ci 2942e5c31af7Sopenharmony_ci union 2943e5c31af7Sopenharmony_ci { 2944e5c31af7Sopenharmony_ci deUint8 sRGB[MAX_BLOCK_WIDTH*MAX_BLOCK_HEIGHT*4]; 2945e5c31af7Sopenharmony_ci float linear[MAX_BLOCK_WIDTH*MAX_BLOCK_HEIGHT*4]; 2946e5c31af7Sopenharmony_ci } tmpBuffer; 2947e5c31af7Sopenharmony_ci const Block128 blockData (data); 2948e5c31af7Sopenharmony_ci const DecompressResult result = decompressBlock((isSRGB ? (void*)&tmpBuffer.sRGB[0] : (void*)&tmpBuffer.linear[0]), 2949e5c31af7Sopenharmony_ci blockData, blockPixelSize.x(), blockPixelSize.y(), isSRGB, isLDR); 2950e5c31af7Sopenharmony_ci 2951e5c31af7Sopenharmony_ci return result == DECOMPRESS_RESULT_VALID_BLOCK; 2952e5c31af7Sopenharmony_ci} 2953e5c31af7Sopenharmony_ci 2954e5c31af7Sopenharmony_civoid decompress (const PixelBufferAccess& dst, const deUint8* data, CompressedTexFormat format, TexDecompressionParams::AstcMode mode) 2955e5c31af7Sopenharmony_ci{ 2956e5c31af7Sopenharmony_ci const bool isSRGBFormat = isAstcSRGBFormat(format); 2957e5c31af7Sopenharmony_ci 2958e5c31af7Sopenharmony_ci#if defined(DE_DEBUG) 2959e5c31af7Sopenharmony_ci const tcu::IVec3 blockPixelSize = getBlockPixelSize(format); 2960e5c31af7Sopenharmony_ci 2961e5c31af7Sopenharmony_ci DE_ASSERT(dst.getWidth() == blockPixelSize.x() && 2962e5c31af7Sopenharmony_ci dst.getHeight() == blockPixelSize.y() && 2963e5c31af7Sopenharmony_ci dst.getDepth() == blockPixelSize.z()); 2964e5c31af7Sopenharmony_ci DE_ASSERT(mode == TexDecompressionParams::ASTCMODE_LDR || mode == TexDecompressionParams::ASTCMODE_HDR); 2965e5c31af7Sopenharmony_ci#endif 2966e5c31af7Sopenharmony_ci 2967e5c31af7Sopenharmony_ci // sRGB is not supported in HDR mode 2968e5c31af7Sopenharmony_ci DE_ASSERT(!(mode == TexDecompressionParams::ASTCMODE_HDR && isSRGBFormat)); 2969e5c31af7Sopenharmony_ci 2970e5c31af7Sopenharmony_ci decompress(dst, data, isSRGBFormat, isSRGBFormat || mode == TexDecompressionParams::ASTCMODE_LDR); 2971e5c31af7Sopenharmony_ci} 2972e5c31af7Sopenharmony_ci 2973e5c31af7Sopenharmony_ciconst char* getBlockTestTypeName (BlockTestType testType) 2974e5c31af7Sopenharmony_ci{ 2975e5c31af7Sopenharmony_ci switch (testType) 2976e5c31af7Sopenharmony_ci { 2977e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_LDR: return "void_extent_ldr"; 2978e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_HDR: return "void_extent_hdr"; 2979e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_GRID: return "weight_grid"; 2980e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_ISE: return "weight_ise"; 2981e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CEMS: return "color_endpoint_modes"; 2982e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_PARTITION_SEED: return "partition_pattern_index"; 2983e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_LDR: return "endpoint_value_ldr"; 2984e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15: return "endpoint_value_hdr_cem_not_15"; 2985e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15: return "endpoint_value_hdr_cem_15"; 2986e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_ISE: return "endpoint_ise"; 2987e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CCS: return "color_component_selector"; 2988e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_RANDOM: return "random"; 2989e5c31af7Sopenharmony_ci default: 2990e5c31af7Sopenharmony_ci DE_ASSERT(false); 2991e5c31af7Sopenharmony_ci return DE_NULL; 2992e5c31af7Sopenharmony_ci } 2993e5c31af7Sopenharmony_ci} 2994e5c31af7Sopenharmony_ci 2995e5c31af7Sopenharmony_ciconst char* getBlockTestTypeDescription (BlockTestType testType) 2996e5c31af7Sopenharmony_ci{ 2997e5c31af7Sopenharmony_ci switch (testType) 2998e5c31af7Sopenharmony_ci { 2999e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_LDR: return "Test void extent block, LDR mode"; 3000e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_VOID_EXTENT_HDR: return "Test void extent block, HDR mode"; 3001e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_GRID: return "Test combinations of plane count, weight integer sequence encoding parameters, and weight grid size"; 3002e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_WEIGHT_ISE: return "Test different integer sequence encoding block values for weight grid"; 3003e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CEMS: return "Test different color endpoint mode combinations, combined with different plane and partition counts"; 3004e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_PARTITION_SEED: return "Test different partition pattern indices"; 3005e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_LDR: return "Test various combinations of each pair of color endpoint values, for each LDR color endpoint mode"; 3006e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15: return "Test various combinations of each pair of color endpoint values, for each HDR color endpoint mode other than mode 15"; 3007e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15: return "Test various combinations of each pair of color endpoint values, HDR color endpoint mode 15"; 3008e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_ENDPOINT_ISE: return "Test different integer sequence encoding block values for color endpoints"; 3009e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_CCS: return "Test color component selector, for different partition counts"; 3010e5c31af7Sopenharmony_ci case BLOCK_TEST_TYPE_RANDOM: return "Random block test"; 3011e5c31af7Sopenharmony_ci default: 3012e5c31af7Sopenharmony_ci DE_ASSERT(false); 3013e5c31af7Sopenharmony_ci return DE_NULL; 3014e5c31af7Sopenharmony_ci } 3015e5c31af7Sopenharmony_ci} 3016e5c31af7Sopenharmony_ci 3017e5c31af7Sopenharmony_cibool isBlockTestTypeHDROnly (BlockTestType testType) 3018e5c31af7Sopenharmony_ci{ 3019e5c31af7Sopenharmony_ci return testType == BLOCK_TEST_TYPE_VOID_EXTENT_HDR || 3020e5c31af7Sopenharmony_ci testType == BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15 || 3021e5c31af7Sopenharmony_ci testType == BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15; 3022e5c31af7Sopenharmony_ci} 3023e5c31af7Sopenharmony_ci 3024e5c31af7Sopenharmony_ciVec4 getBlockTestTypeColorScale (BlockTestType testType) 3025e5c31af7Sopenharmony_ci{ 3026e5c31af7Sopenharmony_ci switch (testType) 3027e5c31af7Sopenharmony_ci { 3028e5c31af7Sopenharmony_ci case tcu::astc::BLOCK_TEST_TYPE_VOID_EXTENT_HDR: return Vec4(0.5f/65504.0f); 3029e5c31af7Sopenharmony_ci case tcu::astc::BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_NO_15: return Vec4(1.0f/65504.0f, 1.0f/65504.0f, 1.0f/65504.0f, 1.0f); 3030e5c31af7Sopenharmony_ci case tcu::astc::BLOCK_TEST_TYPE_ENDPOINT_VALUE_HDR_15: return Vec4(1.0f/65504.0f); 3031e5c31af7Sopenharmony_ci default: return Vec4(1.0f); 3032e5c31af7Sopenharmony_ci } 3033e5c31af7Sopenharmony_ci} 3034e5c31af7Sopenharmony_ci 3035e5c31af7Sopenharmony_ciVec4 getBlockTestTypeColorBias (BlockTestType testType) 3036e5c31af7Sopenharmony_ci{ 3037e5c31af7Sopenharmony_ci switch (testType) 3038e5c31af7Sopenharmony_ci { 3039e5c31af7Sopenharmony_ci case tcu::astc::BLOCK_TEST_TYPE_VOID_EXTENT_HDR: return Vec4(0.5f); 3040e5c31af7Sopenharmony_ci default: return Vec4(0.0f); 3041e5c31af7Sopenharmony_ci } 3042e5c31af7Sopenharmony_ci} 3043e5c31af7Sopenharmony_ci 3044e5c31af7Sopenharmony_ci} // astc 3045e5c31af7Sopenharmony_ci} // tcu 3046