yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1#ifndef SLANG_CORE_BYTE_ENCODE_UTIL_H 2#define SLANG_CORE_BYTE_ENCODE_UTIL_H 3 4#include "slang-list.h" 5 6namespace Slang 7{ 8 9struct ByteEncodeUtil 10{ 11enum 12 { 13kMaxLiteEncodeUInt16 = 3 ,/// One byte for prefix, the remaining 2 bytes hold the value 14kMaxLiteEncodeUInt32 = 5 ,/// One byte for prefix, the remaining 4 bytes hold the value 15// Cut values for 'Lite' encoding style 16kLiteCut1 = 185 , 17kLiteCut2 = 249 , 18 }; 19 20/** Find the most significant bit for 8 bits 21@param v The value to find most significant bit on 22@return The most significant bit, or -1 if no bits are set 23*/ 24SLANG_FORCE_INLINE static int calcMsb8 (uint32_t v ); 25 26/** Find the most significant bit for 32 bits 27@param v The value to find most significant bit on 28@return The most significant bit, or -1 if no bits are set 29*/ 30SLANG_FORCE_INLINE static int calcMsb32 (uint32_t v ); 31 32/** Calculates the 'most significant' byte ie the highest bytes that is non zero. 33Note return value is *undefined* if in is 0. 34@param in Value - cannot be 0. 35@return The byte index of the highest byte that is non zero. 36*/ 37SLANG_FORCE_INLINE static int calcNonZeroMsByte32 (uint32_t in ); 38 39/** Calculates the 'most significant' byte ie the highest bytes that is non zero. 40@param in Value - cannot be 0. 41@return The byte index of the highest byte that is non zero. 42*/ 43SLANG_FORCE_INLINE static int calcMsByte32 (uint32_t in ); 44 45/// Calculate the size of encoding bytes 46static size_t calcEncodeLiteSizeUInt32 (const uint32_t * in ,size_t num ); 47 48/// Calculate the size of a single value 49static size_t calcEncodeLiteSizeUInt32 (uint32_t in ); 50 51/** Encodes a uint32_t as an integer 52@return the number of bytes needed to encode */ 53static int encodeLiteUInt32 (uint32_t in ,uint8_t out [kMaxLiteEncodeUInt32 ]); 54 55/** Decode a lite encoding. 56@param in The lite encoded bytes 57@param out Value constructed 58@return number of bytes on in consumed */ 59static int decodeLiteUInt32 (const uint8_t * in ,uint32_t * out ); 60 61/** Encode an array of uint32_t 62@param in The values to encode 63@param num The amount of values to encode 64@param encodeOut The buffer to hold the encoded value. MUST be large enough to hold the encoding 65@return The size of the encoding in bytes 66*/ 67static size_t encodeLiteUInt32 (const uint32_t * in ,size_t num ,uint8_t * encodeOut ); 68 69/** Encode an array of uint32_t 70@param in The values to encode 71@param num The amount of values to encode 72@param encodeOut The buffer to hold the encoded value. 73*/ 74static void encodeLiteUInt32 (const uint32_t * in ,size_t num ,List < uint8_t >& encodeOut ); 75 76/** Encode an array of uint32_t 77@param encodeIn The encoded values 78@param numValues The amount of values to be decoded (NOTE! This is the number of valuesOut, not 79encodeIn) 80@param valuesOut The buffer to hold the encoded value. MUST be large enough to hold the encoding 81@return The amount of bytes decoded 82*/ 83static size_t decodeLiteUInt32 (const uint8_t * encodeIn ,size_t numValues ,uint32_t * valuesOut ); 84 85/// Table that maps 8 bits to it's most significant bit. If 0 returns -1. 86static const int8_t s_msb8 [256 ]; 87}; 88 89#if SLANG_VC 90// Works on ARM and x86/64 on visual studio compiler 91 92// --------------------------------------------------------------------------- 93SLANG_FORCE_INLINE int ByteEncodeUtil ::calcNonZeroMsByte32 (uint32_t in ) 94{ 95SLANG_ASSERT (in != 0 ); 96// Can use intrinsic 97// https://msdn.microsoft.com/en-us/library/fbxyd7zd.aspx 98unsigned long index ; 99_BitScanReverse (& index ,in ); 100return index >>3 ; 101} 102 103// --------------------------------------------------------------------------- 104SLANG_FORCE_INLINE int ByteEncodeUtil ::calcMsByte32 (uint32_t in ) 105{ 106if (in == 0 ) 107 { 108return -1 ; 109 } 110// Can use intrinsic 111// https://msdn.microsoft.com/en-us/library/fbxyd7zd.aspx 112unsigned long index ; 113_BitScanReverse (& index ,in ); 114return index >>3 ; 115} 116 117// --------------------------------------------------------------------------- 118SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcMsb8 (uint32_t v ) 119{ 120SLANG_ASSERT ((v & 0xffffff00 )== 0 ); 121if (v == 0 ) 122 { 123return -1 ; 124 } 125unsigned long index ; 126_BitScanReverse (& index ,v ); 127return index ; 128} 129 130// --------------------------------------------------------------------------- 131SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcMsb32 (uint32_t v ) 132{ 133if (v == 0 ) 134 { 135return -1 ; 136 } 137unsigned long index ; 138_BitScanReverse (& index ,v ); 139return index ; 140} 141 142#else 143 144// --------------------------------------------------------------------------- 145SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcNonZeroMsByte32 (uint32_t in ) 146{ 147return (in & 0xffff0000 ) ? ((in & 0xff000000 ) ?3 :2 ) : ((in & 0x0000ff00 ) ?1 :0 ); 148} 149 150// --------------------------------------------------------------------------- 151SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcMsByte32 (uint32_t in ) 152{ 153return (in & 0xffff0000 ) ? ((in & 0xff000000 ) ?3 :2 ) 154 : ((in & 0x0000ff00 ) ?1 : ((in == 0 ) ?-1 :0 )); 155} 156 157// --------------------------------------------------------------------------- 158SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcMsb8 (uint32_t v ) 159{ 160SLANG_ASSERT ((v & 0xffffff00 )== 0 ); 161return s_msb8 [v ]; 162} 163 164// --------------------------------------------------------------------------- 165SLANG_FORCE_INLINE /* static */ int ByteEncodeUtil ::calcMsb32 (uint32_t v ) 166{ 167return (v & 0xffff0000 ) ? ((v & 0xff000000 ) ?s_msb8 [v >>24 ]+ 24 :s_msb8 [v >>16 ]+ 16 ) 168 : ((v & 0x0000ff00 ) ?s_msb8 [v >>8 ]+ 8 :s_msb8 [v ]); 169} 170 171#endif 172 173// --------------------------------------------------------------------------- 174inline /* static */ size_t ByteEncodeUtil ::calcEncodeLiteSizeUInt32 (uint32_t v ) 175{ 176if (v < kLiteCut1 ) 177 { 178return 1 ; 179 } 180else if (v <=kLiteCut1 + 255 * (kLiteCut2 - 1 - kLiteCut1 )) 181 { 182return 2 ; 183 } 184else 185 { 186return calcNonZeroMsByte32 (v )+ 2 ; 187 } 188} 189 190}// namespace Slang 191 192#endif // SLANG_BYTE_ENCODE_UTIL_H