bc2_encode_kernel.cpp 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. //=====================================================================
  2. // Copyright (c) 2020 Advanced Micro Devices, Inc. All rights reserved.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files(the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions :
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. //=====================================================================
  23. #include "bc2_encode_kernel.h"
  24. //============================================== BC2 INTERFACES =======================================================
  25. void CompressBlockBC2_Internal(const CMP_Vec4uc srcBlockTemp[16],
  26. CMP_GLOBAL CGU_UINT32 compressedBlock[4],
  27. CMP_GLOBAL const CMP_BC15Options *BC15options) {
  28. CGU_Vec2ui cmpBlock;
  29. CGU_Vec3f rgbBlock[16];
  30. CGU_FLOAT BlockA[16];
  31. for (CGU_INT32 i = 0; i < 16; i++) {
  32. rgbBlock[i].x = (CGU_FLOAT)(srcBlockTemp[i].x & 0xFF)/255.0f; // R
  33. rgbBlock[i].y = (CGU_FLOAT)(srcBlockTemp[i].y & 0xFF)/255.0f; // G
  34. rgbBlock[i].z = (CGU_FLOAT)(srcBlockTemp[i].z & 0xFF)/255.0f; // B
  35. BlockA[i] = (CGU_FLOAT)(srcBlockTemp[i].w & 0xFF)/255.0f; // A
  36. }
  37. cmpBlock = cmp_compressExplicitAlphaBlock(BlockA);
  38. compressedBlock[DXTC_OFFSET_ALPHA ] = cmpBlock.x;
  39. compressedBlock[DXTC_OFFSET_ALPHA+1] = cmpBlock.y;
  40. // Need a copy, as CalculateColourWeightings sets variables in the BC15options
  41. CMP_BC15Options internalOptions = *BC15options;
  42. internalOptions = CalculateColourWeightings3f(rgbBlock, internalOptions);
  43. internalOptions.m_bUseAlpha = false;
  44. CGU_Vec3f channelWeights = {internalOptions.m_fChannelWeights[0],internalOptions.m_fChannelWeights[1],internalOptions.m_fChannelWeights[2]};
  45. CGU_Vec3f MinColor = {0,0,0}, MaxColor= {0,0,0};
  46. cmpBlock = CompressBlockBC1_RGBA_Internal(
  47. rgbBlock,
  48. BlockA,
  49. channelWeights,
  50. internalOptions.m_nAlphaThreshold,
  51. internalOptions.m_nRefinementSteps,
  52. internalOptions.m_fquality,
  53. FALSE);
  54. compressedBlock[DXTC_OFFSET_RGB] = cmpBlock.x;
  55. compressedBlock[DXTC_OFFSET_RGB+1] = cmpBlock.y;
  56. }
  57. //============================================== USER INTERFACES ========================================================
  58. #ifndef ASPM_GPU
  59. int CMP_CDECL CreateOptionsBC2(void **options) {
  60. CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
  61. if (BC15optionsDefault) {
  62. SetDefaultBC15Options(BC15optionsDefault);
  63. (*options) = BC15optionsDefault;
  64. } else {
  65. (*options) = NULL;
  66. return CGU_CORE_ERR_NEWMEM;
  67. }
  68. return CGU_CORE_OK;
  69. }
  70. int CMP_CDECL DestroyOptionsBC2(void *options) {
  71. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  72. CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
  73. delete BCOptions;
  74. return CGU_CORE_OK;
  75. }
  76. int CMP_CDECL SetQualityBC2(void *options,
  77. CGU_FLOAT fquality) {
  78. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  79. CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
  80. if (fquality < 0.0f) fquality = 0.0f;
  81. else if (fquality > 1.0f) fquality = 1.0f;
  82. BC15optionsDefault->m_fquality = fquality;
  83. return CGU_CORE_OK;
  84. }
  85. int CMP_CDECL SetChannelWeightsBC2(void *options,
  86. CGU_FLOAT WeightRed,
  87. CGU_FLOAT WeightGreen,
  88. CGU_FLOAT WeightBlue) {
  89. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  90. CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
  91. if ((WeightRed < 0.0f) || (WeightRed > 1.0f)) return CGU_CORE_ERR_RANGERED;
  92. if ((WeightGreen < 0.0f) || (WeightGreen > 1.0f)) return CGU_CORE_ERR_RANGEGREEN;
  93. if ((WeightBlue < 0.0f) || (WeightBlue > 1.0f)) return CGU_CORE_ERR_RANGEBLUE;
  94. BC15optionsDefault->m_bUseChannelWeighting = true;
  95. BC15optionsDefault->m_fChannelWeights[0] = WeightRed;
  96. BC15optionsDefault->m_fChannelWeights[1] = WeightGreen;
  97. BC15optionsDefault->m_fChannelWeights[2] = WeightBlue;
  98. return CGU_CORE_OK;
  99. }
  100. int CMP_CDECL SetSrgbBC2(void* options,
  101. CGU_BOOL sRGB) {
  102. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  103. CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
  104. BC15optionsDefault->m_bIsSRGB = sRGB;
  105. return CGU_CORE_OK;
  106. }
  107. #define EXPLICIT_ALPHA_PIXEL_MASK 0xf
  108. #define EXPLICIT_ALPHA_PIXEL_BPP 4
  109. // Decompresses an explicit alpha block (DXT3)
  110. void DecompressExplicitAlphaBlock(CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4],
  111. const CGU_UINT32 compressedBlock[2]) {
  112. for (int i = 0; i < 16; i++) {
  113. int nBlock = i < 8 ? 0 : 1;
  114. CGU_UINT8 cAlpha = (CGU_UINT8)((compressedBlock[nBlock] >> ((i % 8) * EXPLICIT_ALPHA_PIXEL_BPP)) & EXPLICIT_ALPHA_PIXEL_MASK);
  115. alphaBlock[i] = (CGU_UINT8)((cAlpha << EXPLICIT_ALPHA_PIXEL_BPP) | cAlpha);
  116. }
  117. }
  118. void DecompressBC2_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[BLOCK_SIZE_4X4X4],
  119. const CGU_UINT32 compressedBlock[4],
  120. const CMP_BC15Options *BC15options) {
  121. CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
  122. DecompressExplicitAlphaBlock(alphaBlock, &compressedBlock[DXTC_OFFSET_ALPHA]);
  123. CGU_Vec2ui compBlock;
  124. compBlock.x = compressedBlock[DXTC_OFFSET_RGB];
  125. compBlock.y = compressedBlock[DXTC_OFFSET_RGB+1];
  126. cmp_decompressDXTRGBA_Internal(rgbaBlock, compBlock,BC15options->m_mapDecodeRGBA);
  127. for (CGU_UINT32 i = 0; i < 16; i++)
  128. ((CMP_GLOBAL CGU_UINT32*)rgbaBlock)[i] = (alphaBlock[i] << RGBA8888_OFFSET_A) | (((CMP_GLOBAL CGU_UINT32*)rgbaBlock)[i] & ~(BYTE_MASK << RGBA8888_OFFSET_A));
  129. }
  130. int CMP_CDECL CompressBlockBC2(const unsigned char *srcBlock,
  131. unsigned int srcStrideInBytes,
  132. CMP_GLOBAL unsigned char cmpBlock[16],
  133. CMP_GLOBAL const void *options = NULL) {
  134. CMP_Vec4uc inBlock[16];
  135. //----------------------------------
  136. // Fill the inBlock with source data
  137. //----------------------------------
  138. CGU_INT srcpos = 0;
  139. CGU_INT dstptr = 0;
  140. for (CGU_UINT8 row = 0; row < 4; row++) {
  141. srcpos = row * srcStrideInBytes;
  142. for (CGU_UINT8 col = 0; col < 4; col++) {
  143. inBlock[dstptr].x = CGU_UINT8(srcBlock[srcpos++]);
  144. inBlock[dstptr].y = CGU_UINT8(srcBlock[srcpos++]);
  145. inBlock[dstptr].z = CGU_UINT8(srcBlock[srcpos++]);
  146. inBlock[dstptr].w = CGU_UINT8(srcBlock[srcpos++]);
  147. dstptr++;
  148. }
  149. }
  150. CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
  151. CMP_BC15Options BC15optionsDefault;
  152. if (BC15options == NULL) {
  153. BC15options = &BC15optionsDefault;
  154. SetDefaultBC15Options(BC15options);
  155. }
  156. CompressBlockBC2_Internal(inBlock, (CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
  157. return CGU_CORE_OK;
  158. }
  159. int CMP_CDECL DecompressBlockBC2(const unsigned char cmpBlock[16],
  160. CMP_GLOBAL unsigned char srcBlock[64],
  161. const void *options = NULL) {
  162. CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
  163. CMP_BC15Options BC15optionsDefault;
  164. if (BC15options == NULL) {
  165. BC15options = &BC15optionsDefault;
  166. SetDefaultBC15Options(BC15options);
  167. }
  168. DecompressBC2_Internal(srcBlock, (CGU_UINT32 *)cmpBlock,BC15options);
  169. return CGU_CORE_OK;
  170. }
  171. #endif
  172. //============================================== OpenCL USER INTERFACE ========================================================
  173. #ifdef ASPM_OPENCL
  174. CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
  175. CMP_GLOBAL const CMP_Vec4uc* ImageSource,
  176. CMP_GLOBAL CGU_UINT8* ImageDestination,
  177. CMP_GLOBAL Source_Info* SourceInfo,
  178. CMP_GLOBAL CMP_BC15Options* BC15options
  179. ) {
  180. CGU_UINT32 xID;
  181. CGU_UINT32 yID;
  182. #ifdef ASPM_GPU
  183. xID = get_global_id(0);
  184. yID = get_global_id(1);
  185. #else
  186. xID = 0;
  187. yID = 0;
  188. #endif
  189. if (xID >= (SourceInfo->m_src_width / BlockX)) return;
  190. if (yID >= (SourceInfo->m_src_height / BlockX)) return;
  191. int srcWidth = SourceInfo->m_src_width;
  192. CGU_UINT32 destI = (xID*BC2CompBlockSize) + (yID*(srcWidth / BlockX)*BC2CompBlockSize);
  193. int srcindex = 4 * (yID * srcWidth + xID);
  194. int blkindex = 0;
  195. CMP_Vec4uc srcData[16];
  196. srcWidth = srcWidth - 4;
  197. for ( CGU_INT32 j = 0; j < 4; j++) {
  198. for ( CGU_INT32 i = 0; i < 4; i++) {
  199. srcData[blkindex++] = ImageSource[srcindex++];
  200. }
  201. srcindex += srcWidth;
  202. }
  203. CompressBlockBC2_Internal(srcData,(CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
  204. }
  205. #endif