bc3_encode_kernel.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 "bc3_encode_kernel.h"
  24. //============================================== BC3 INTERFACES =======================================================
  25. #ifndef ASPM_HLSL
  26. void CompressBlockBC3_Internal(const CMP_Vec4uc srcBlockTemp[16],
  27. CMP_GLOBAL CGU_UINT32 compressedBlock[4],
  28. CMP_GLOBAL CMP_BC15Options *BC15options) {
  29. CGU_Vec3f rgbBlock[16];
  30. CGU_FLOAT alphaBlock[BLOCK_SIZE_4X4];
  31. for (CGU_INT32 i = 0; i < 16; i++) {
  32. rgbBlock[i].x = (CGU_FLOAT)(srcBlockTemp[i].x & 0xFF)/255; // R
  33. rgbBlock[i].y = (CGU_FLOAT)(srcBlockTemp[i].y & 0xFF)/255; // G
  34. rgbBlock[i].z = (CGU_FLOAT)(srcBlockTemp[i].z & 0xFF)/255; // B
  35. alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i].w) / 255.0f;
  36. }
  37. CMP_BC15Options internalOptions = *BC15options;
  38. CGU_Vec2ui cmpBlock;
  39. cmpBlock = cmp_compressAlphaBlock(alphaBlock,internalOptions.m_fquality,FALSE);
  40. compressedBlock[0] = cmpBlock.x;
  41. compressedBlock[1] = cmpBlock.y;
  42. for (CGU_INT32 i = 0; i < 16; i++) {
  43. alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i].w);
  44. }
  45. internalOptions = CalculateColourWeightings3f(rgbBlock, internalOptions);
  46. CGU_Vec3f channelWeights = {internalOptions.m_fChannelWeights[0],internalOptions.m_fChannelWeights[1],internalOptions.m_fChannelWeights[2]};
  47. cmpBlock = CompressBlockBC1_RGBA_Internal(
  48. rgbBlock,
  49. alphaBlock,
  50. channelWeights,
  51. internalOptions.m_nAlphaThreshold,
  52. internalOptions.m_nRefinementSteps,
  53. internalOptions.m_fquality,
  54. FALSE);
  55. compressedBlock[2] = cmpBlock.x;
  56. compressedBlock[3] = cmpBlock.y;
  57. }
  58. #endif
  59. //============================================== USER INTERFACES ========================================================
  60. #ifndef ASPM_GPU
  61. int CMP_CDECL CreateOptionsBC3(void **options) {
  62. CMP_BC15Options *BC15optionsDefault = new CMP_BC15Options;
  63. if (BC15optionsDefault) {
  64. SetDefaultBC15Options(BC15optionsDefault);
  65. (*options) = BC15optionsDefault;
  66. } else {
  67. (*options) = NULL;
  68. return CGU_CORE_ERR_NEWMEM;
  69. }
  70. return CGU_CORE_OK;
  71. }
  72. int CMP_CDECL DestroyOptionsBC3(void *options) {
  73. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  74. CMP_BC15Options *BCOptions = reinterpret_cast <CMP_BC15Options *>(options);
  75. delete BCOptions;
  76. return CGU_CORE_OK;
  77. }
  78. int CMP_CDECL SetQualityBC3(void *options,
  79. CGU_FLOAT fquality) {
  80. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  81. CMP_BC15Options *BC15optionsDefault = reinterpret_cast <CMP_BC15Options *>(options);
  82. if (fquality < 0.0f) fquality = 0.0f;
  83. else if (fquality > 1.0f) fquality = 1.0f;
  84. BC15optionsDefault->m_fquality = fquality;
  85. return CGU_CORE_OK;
  86. }
  87. int CMP_CDECL SetChannelWeightsBC3(void *options,
  88. CGU_FLOAT WeightRed,
  89. CGU_FLOAT WeightGreen,
  90. CGU_FLOAT WeightBlue) {
  91. if (!options) return 1;
  92. CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
  93. if ((WeightRed < 0.0f) || (WeightRed > 1.0f)) return CGU_CORE_ERR_RANGERED;
  94. if ((WeightGreen < 0.0f) || (WeightGreen > 1.0f)) return CGU_CORE_ERR_RANGEGREEN;
  95. if ((WeightBlue < 0.0f) || (WeightBlue > 1.0f)) return CGU_CORE_ERR_RANGEBLUE;
  96. BC15optionsDefault->m_bUseChannelWeighting = true;
  97. BC15optionsDefault->m_fChannelWeights[0] = WeightRed;
  98. BC15optionsDefault->m_fChannelWeights[1] = WeightGreen;
  99. BC15optionsDefault->m_fChannelWeights[2] = WeightBlue;
  100. return CGU_CORE_OK;
  101. }
  102. int CMP_CDECL SetSrgbBC3(void* options,CGU_BOOL sRGB) {
  103. if (!options) return CGU_CORE_ERR_INVALIDPTR;
  104. CMP_BC15Options *BC15optionsDefault = (CMP_BC15Options *)options;
  105. BC15optionsDefault->m_bIsSRGB = sRGB;
  106. return CGU_CORE_OK;
  107. }
  108. void DecompressBC3_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[64],
  109. const CGU_UINT32 compressedBlock[4],
  110. const CMP_BC15Options *BC15options) {
  111. CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
  112. cmp_decompressAlphaBlock(alphaBlock, &compressedBlock[DXTC_OFFSET_ALPHA]);
  113. CGU_Vec2ui compBlock;
  114. compBlock.x = compressedBlock[DXTC_OFFSET_RGB];
  115. compBlock.y = compressedBlock[DXTC_OFFSET_RGB+1];
  116. cmp_decompressDXTRGBA_Internal(rgbaBlock, compBlock,BC15options->m_mapDecodeRGBA);
  117. for (CGU_UINT32 i = 0; i < 16; i++)
  118. ((CMP_GLOBAL CGU_UINT32 *)rgbaBlock)[i] =
  119. (alphaBlock[i] << RGBA8888_OFFSET_A) |
  120. (((CMP_GLOBAL CGU_UINT32 *)rgbaBlock)[i] &
  121. ~(BYTE_MASK << RGBA8888_OFFSET_A));
  122. }
  123. int CMP_CDECL CompressBlockBC3( const unsigned char *srcBlock,
  124. unsigned int srcStrideInBytes,
  125. CMP_GLOBAL unsigned char cmpBlock[16],
  126. const void *options = NULL) {
  127. CMP_Vec4uc inBlock[16];
  128. //----------------------------------
  129. // Fill the inBlock with source data
  130. //----------------------------------
  131. CGU_INT srcpos = 0;
  132. CGU_INT dstptr = 0;
  133. for (CGU_UINT8 row = 0; row < 4; row++) {
  134. srcpos = row * srcStrideInBytes;
  135. for (CGU_UINT8 col = 0; col < 4; col++) {
  136. inBlock[dstptr].x = CGU_UINT8(srcBlock[srcpos++]);
  137. inBlock[dstptr].y = CGU_UINT8(srcBlock[srcpos++]);
  138. inBlock[dstptr].z = CGU_UINT8(srcBlock[srcpos++]);
  139. inBlock[dstptr].w = CGU_UINT8(srcBlock[srcpos++]);
  140. dstptr++;
  141. }
  142. }
  143. CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
  144. CMP_BC15Options BC15optionsDefault;
  145. if (BC15options == NULL) {
  146. BC15options = &BC15optionsDefault;
  147. SetDefaultBC15Options(BC15options);
  148. }
  149. CompressBlockBC3_Internal(inBlock,(CMP_GLOBAL CGU_UINT32 *)cmpBlock, BC15options);
  150. return CGU_CORE_OK;
  151. }
  152. int CMP_CDECL DecompressBlockBC3(const unsigned char cmpBlock[16],
  153. CMP_GLOBAL unsigned char srcBlock[64],
  154. const void *options = NULL) {
  155. CMP_BC15Options *BC15options = (CMP_BC15Options *)options;
  156. CMP_BC15Options BC15optionsDefault;
  157. if (BC15options == NULL) {
  158. BC15options = &BC15optionsDefault;
  159. SetDefaultBC15Options(BC15options);
  160. }
  161. DecompressBC3_Internal(srcBlock, (CGU_UINT32 *)cmpBlock,BC15options);
  162. return CGU_CORE_OK;
  163. }
  164. #endif
  165. //============================================== OpenCL USER INTERFACE ====================================================
  166. #ifdef ASPM_OPENCL
  167. CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(
  168. CMP_GLOBAL const CMP_Vec4uc *ImageSource,
  169. CMP_GLOBAL CGU_UINT8 *ImageDestination, CMP_GLOBAL Source_Info *SourceInfo,
  170. CMP_GLOBAL CMP_BC15Options *BC15options) {
  171. CGU_UINT32 xID;
  172. CGU_UINT32 yID;
  173. #ifdef ASPM_GPU
  174. xID = get_global_id(0);
  175. yID = get_global_id(1);
  176. #else
  177. xID = 0;
  178. yID = 0;
  179. #endif
  180. if (xID >= (SourceInfo->m_src_width / BlockX)) return;
  181. if (yID >= (SourceInfo->m_src_height / BlockX)) return;
  182. int srcWidth = SourceInfo->m_src_width;
  183. CGU_UINT32 destI =
  184. (xID * BC3CompBlockSize) + (yID * (srcWidth / BlockX) * BC3CompBlockSize);
  185. int srcindex = 4 * (yID * srcWidth + xID);
  186. int blkindex = 0;
  187. CMP_Vec4uc srcData[16];
  188. srcWidth = srcWidth - 4;
  189. for (CGU_INT32 j = 0; j < 4; j++) {
  190. for (CGU_INT32 i = 0; i < 4; i++) {
  191. srcData[blkindex++] = ImageSource[srcindex++];
  192. }
  193. srcindex += srcWidth;
  194. }
  195. CompressBlockBC3_Internal(
  196. srcData, (CMP_GLOBAL CGU_UINT32 *)&ImageDestination[destI], BC15options);
  197. }
  198. #endif