| 1 | #pragma once |
| 2 | #ifndef __CVTT_CONVECTIONKERNELS_ETC_H__ |
| 3 | #define __CVTT_CONVECTIONKERNELS_ETC_H__ |
| 4 | |
| 5 | #include "ConvectionKernels.h" |
| 6 | #include "ConvectionKernels_ParallelMath.h" |
| 7 | |
| 8 | namespace cvtt |
| 9 | { |
| 10 | struct Options; |
| 11 | |
| 12 | namespace Internal |
| 13 | { |
| 14 | class ETCComputer |
| 15 | { |
| 16 | public: |
| 17 | static void CompressETC1Block(uint8_t *outputBuffer, const PixelBlockU8 *inputBlocks, ETC1CompressionData *compressionData, const Options &options); |
| 18 | static void CompressETC2Block(uint8_t *outputBuffer, const PixelBlockU8 *inputBlocks, ETC2CompressionData *compressionData, const Options &options, bool punchthroughAlpha); |
| 19 | static void CompressETC2AlphaBlock(uint8_t *outputBuffer, const PixelBlockU8 *inputBlocks, const Options &options); |
| 20 | static void CompressEACBlock(uint8_t *outputBuffer, const PixelBlockScalarS16 *inputBlocks, bool isSigned, const Options &options); |
| 21 | |
| 22 | static ETC2CompressionData *AllocETC2Data(cvtt::Kernels::allocFunc_t allocFunc, void *context, const cvtt::Options &options); |
| 23 | static void ReleaseETC2Data(ETC2CompressionData *compressionData, cvtt::Kernels::freeFunc_t freeFunc); |
| 24 | |
| 25 | static ETC1CompressionData *AllocETC1Data(cvtt::Kernels::allocFunc_t allocFunc, void *context); |
| 26 | static void ReleaseETC1Data(ETC1CompressionData *compressionData, cvtt::Kernels::freeFunc_t freeFunc); |
| 27 | |
| 28 | private: |
| 29 | typedef ParallelMath::Float MFloat; |
| 30 | typedef ParallelMath::SInt16 MSInt16; |
| 31 | typedef ParallelMath::UInt15 MUInt15; |
| 32 | typedef ParallelMath::UInt16 MUInt16; |
| 33 | typedef ParallelMath::SInt32 MSInt32; |
| 34 | typedef ParallelMath::UInt31 MUInt31; |
| 35 | |
| 36 | struct DifferentialResolveStorage |
| 37 | { |
| 38 | static const unsigned int MaxAttemptsPerSector = 57 + 81 + 81 + 81 + 81 + 81 + 81 + 81; |
| 39 | |
| 40 | MUInt15 diffNumAttempts[2]; |
| 41 | MFloat diffErrors[2][MaxAttemptsPerSector]; |
| 42 | MUInt16 diffSelectors[2][MaxAttemptsPerSector]; |
| 43 | MUInt15 diffColors[2][MaxAttemptsPerSector]; |
| 44 | MUInt15 diffTables[2][MaxAttemptsPerSector]; |
| 45 | |
| 46 | uint16_t attemptSortIndexes[2][MaxAttemptsPerSector]; |
| 47 | }; |
| 48 | |
| 49 | struct HModeEval |
| 50 | { |
| 51 | MFloat errors[62][16]; |
| 52 | MUInt16 signBits[62]; |
| 53 | MUInt15 uniqueQuantizedColors[62]; |
| 54 | MUInt15 numUniqueColors[2]; |
| 55 | }; |
| 56 | |
| 57 | struct ETC1CompressionDataInternal : public cvtt::ETC1CompressionData |
| 58 | { |
| 59 | explicit ETC1CompressionDataInternal(void *context) |
| 60 | : m_context(context) |
| 61 | { |
| 62 | } |
| 63 | |
| 64 | DifferentialResolveStorage m_drs; |
| 65 | void *m_context; |
| 66 | }; |
| 67 | |
| 68 | struct ETC2CompressionDataInternal : public cvtt::ETC2CompressionData |
| 69 | { |
| 70 | explicit ETC2CompressionDataInternal(void *context, const cvtt::Options &options); |
| 71 | |
| 72 | HModeEval m_h; |
| 73 | DifferentialResolveStorage m_drs; |
| 74 | |
| 75 | void *m_context; |
| 76 | float m_chromaSideAxis0[3]; |
| 77 | float m_chromaSideAxis1[3]; |
| 78 | }; |
| 79 | |
| 80 | static MFloat ComputeErrorUniform(const MUInt15 pixelA[3], const MUInt15 pixelB[3]); |
| 81 | static MFloat ComputeErrorWeighted(const MUInt15 reconstructed[3], const MFloat pixelB[3], const Options options); |
| 82 | static MFloat ComputeErrorFakeBT709(const MUInt15 reconstructed[3], const MFloat pixelB[3]); |
| 83 | |
| 84 | static void TestHalfBlock(MFloat &outError, MUInt16 &outSelectors, MUInt15 quantizedPackedColor, const MUInt15 pixels[8][3], const MFloat preWeightedPixels[8][3], const MSInt16 modifiers[4], bool isDifferential, const Options &options); |
| 85 | static void TestHalfBlockPunchthrough(MFloat &outError, MUInt16 &outSelectors, MUInt15 quantizedPackedColor, const MUInt15 pixels[8][3], const MFloat preWeightedPixels[8][3], const ParallelMath::Int16CompFlag isTransparent[8], const MUInt15 modifier, const Options &options); |
| 86 | static void FindBestDifferentialCombination(int flip, int d, const ParallelMath::Int16CompFlag canIgnoreSector[2], ParallelMath::Int16CompFlag& bestIsThisMode, MFloat& bestTotalError, MUInt15& bestFlip, MUInt15& bestD, MUInt15 bestColors[2], MUInt16 bestSelectors[2], MUInt15 bestTables[2], DifferentialResolveStorage &drs); |
| 87 | |
| 88 | static ParallelMath::Int16CompFlag ETCDifferentialIsLegalForChannel(const MUInt15 &a, const MUInt15 &b); |
| 89 | static ParallelMath::Int16CompFlag ETCDifferentialIsLegal(const MUInt15 &a, const MUInt15 &b); |
| 90 | static bool ETCDifferentialIsLegalForChannelScalar(const uint16_t &a, const uint16_t &b); |
| 91 | static bool ETCDifferentialIsLegalScalar(const uint16_t &a, const uint16_t &b); |
| 92 | |
| 93 | static void EncodeTMode(uint8_t *outputBuffer, MFloat &bestError, const ParallelMath::Int16CompFlag isIsolated[16], const MUInt15 pixels[16][3], const MFloat preWeightedPixels[16][3], const Options &options); |
| 94 | static void EncodeHMode(uint8_t *outputBuffer, MFloat &bestError, const ParallelMath::Int16CompFlag groupings[16], const MUInt15 pixels[16][3], HModeEval &he, const MFloat preWeightedPixels[16][3], const Options &options); |
| 95 | |
| 96 | static void EncodeVirtualTModePunchthrough(uint8_t *outputBuffer, MFloat &bestError, const ParallelMath::Int16CompFlag isIsolated[16], const MUInt15 pixels[16][3], const MFloat preWeightedPixels[16][3], const ParallelMath::Int16CompFlag isTransparent[16], const ParallelMath::Int16CompFlag& anyTransparent, const ParallelMath::Int16CompFlag& allTransparent, const Options &options); |
| 97 | |
| 98 | static MUInt15 DecodePlanarCoeff(const MUInt15 &coeff, int ch); |
| 99 | static void EncodePlanar(uint8_t *outputBuffer, MFloat &bestError, const MUInt15 pixels[16][3], const MFloat preWeightedPixels[16][3], const Options &options); |
| 100 | |
| 101 | static void CompressETC1BlockInternal(MFloat &bestTotalError, uint8_t *outputBuffer, const MUInt15 pixels[16][3], const MFloat preWeightedPixels[16][3], DifferentialResolveStorage& compressionData, const Options &options, bool punchthrough); |
| 102 | static void CompressETC1PunchthroughBlockInternal(MFloat &bestTotalError, uint8_t *outputBuffer, const MUInt15 pixels[16][3], const MFloat preWeightedPixels[16][3], const ParallelMath::Int16CompFlag isTransparent[16], DifferentialResolveStorage& compressionData, const Options &options); |
| 103 | static void CompressETC2AlphaBlockInternal(uint8_t *outputBuffer, const MUInt15 pixels[16], bool is11Bit, bool isSigned, const Options &options); |
| 104 | |
| 105 | static void (MUInt15 pixels[16][3], MFloat preWeightedPixels[16][3], const PixelBlockU8 *inputBlocks, const Options &options); |
| 106 | |
| 107 | static void ResolveHalfBlockFakeBT709RoundingAccurate(MUInt15 quantized[3], const MUInt15 sectorCumulative[3], bool isDifferential); |
| 108 | static void ResolveHalfBlockFakeBT709RoundingFast(MUInt15 quantized[3], const MUInt15 sectorCumulative[3], bool isDifferential); |
| 109 | static void ResolveTHFakeBT709Rounding(MUInt15 quantized[3], const MUInt15 target[3], const MUInt15 &granularity); |
| 110 | static void ConvertToFakeBT709(MFloat yuv[3], const MUInt15 color[3]); |
| 111 | static void ConvertToFakeBT709(MFloat yuv[3], const MFloat color[3]); |
| 112 | static void ConvertToFakeBT709(MFloat yuv[3], const MFloat &r, const MFloat &g, const MFloat &b); |
| 113 | static void ConvertFromFakeBT709(MFloat rgb[3], const MFloat yuv[3]); |
| 114 | |
| 115 | static void QuantizeETC2Alpha(int tableIndex, const MUInt15& value, const MUInt15& baseValue, const MUInt15& multiplier, bool is11Bit, bool isSigned, MUInt15& outIndexes, MUInt15& outQuantizedValues); |
| 116 | |
| 117 | static void EmitTModeBlock(uint8_t *outputBuffer, const ParallelMath::ScalarUInt16 lineColor[3], const ParallelMath::ScalarUInt16 isolatedColor[3], int32_t packedSelectors, ParallelMath::ScalarUInt16 table, bool opaque); |
| 118 | static void EmitHModeBlock(uint8_t *outputBuffer, const ParallelMath::ScalarUInt16 blockColors[2], ParallelMath::ScalarUInt16 sectorBits, ParallelMath::ScalarUInt16 signBits, ParallelMath::ScalarUInt16 table, bool opaque); |
| 119 | static void EmitETC1Block(uint8_t *outputBuffer, int blockBestFlip, int blockBestD, const int blockBestColors[2][3], const int blockBestTables[2], const ParallelMath::ScalarUInt16 blockBestSelectors[2], bool transparent); |
| 120 | |
| 121 | static const int g_flipTables[2][2][8]; |
| 122 | }; |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | #endif |
| 127 | |