bc4_encode_kernel.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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 "bc4_encode_kernel.h"
  24. //============================================== BC4 INTERFACES =======================================================
  25. // Processing UINT to either SNORM or UNORM
  26. void CompressBlockBC4_Internal(const CMP_Vec4uc srcBlockTemp[16], CMP_GLOBAL CGU_UINT32 compressedBlock[2], CMP_GLOBAL const CMP_BC15Options* BC15options)
  27. {
  28. if (BC15options->m_fquality)
  29. {
  30. // Reserved!
  31. }
  32. CGU_Vec2ui cmpBlock;
  33. CGU_FLOAT alphaBlock[16];
  34. if (BC15options->m_bIsSNORM)
  35. {
  36. if (BC15options->m_sintsrc)
  37. {
  38. // Convert UINT (carrier of signed ) -> SINT -> SNORM
  39. for (int i = 0; i < BLOCK_SIZE_4X4; i++)
  40. {
  41. char x = (char)(srcBlockTemp[i].x);
  42. alphaBlock[i] = (CGU_FLOAT)(x) / 127.0f;
  43. }
  44. }
  45. else
  46. {
  47. // Convert UINT -> SNORM
  48. for (int i = 0; i < BLOCK_SIZE_4X4; i++)
  49. {
  50. alphaBlock[i] = (((CGU_FLOAT)(srcBlockTemp[i].x) / 255.0f) * 2.0f - 1.0f);
  51. }
  52. }
  53. }
  54. else
  55. {
  56. // Convert SINT -> UNORM
  57. if (BC15options->m_sintsrc)
  58. {
  59. for (int i = 0; i < BLOCK_SIZE_4X4; i++)
  60. {
  61. char x = (char)(srcBlockTemp[i].x);
  62. alphaBlock[i] = ((((CGU_FLOAT)(x) / 127.0f) * 0.5f) + 0.5f);
  63. }
  64. }
  65. else
  66. {
  67. // Convert UINT -> UNORM
  68. for (int i = 0; i < BLOCK_SIZE_4X4; i++)
  69. {
  70. alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i].x) / 255.0f;
  71. }
  72. }
  73. }
  74. cmpBlock = cmp_compressAlphaBlock(alphaBlock, BC15options->m_fquality, BC15options->m_bIsSNORM);
  75. compressedBlock[0] = cmpBlock.x;
  76. compressedBlock[1] = cmpBlock.y;
  77. }
  78. void DecompressBC4_Internal(CMP_GLOBAL CGU_UINT8 rgbaBlock[64], const CGU_UINT32 compressedBlock[2], const CMP_BC15Options* BC15options)
  79. {
  80. if (BC15options)
  81. {
  82. }
  83. CGU_UINT8 alphaBlock[BLOCK_SIZE_4X4];
  84. cmp_decompressAlphaBlock(alphaBlock, compressedBlock);
  85. CGU_UINT8 blkindex = 0;
  86. CGU_UINT8 srcindex = 0;
  87. for (CGU_INT32 j = 0; j < 4; j++)
  88. {
  89. for (CGU_INT32 i = 0; i < 4; i++)
  90. {
  91. rgbaBlock[blkindex++] = (CGU_UINT8)(alphaBlock[srcindex]); // R
  92. rgbaBlock[blkindex++] = (CGU_UINT8)(alphaBlock[srcindex]); // G
  93. rgbaBlock[blkindex++] = (CGU_UINT8)(alphaBlock[srcindex]); // B
  94. rgbaBlock[blkindex++] = (CGU_UINT8)(alphaBlock[srcindex]); // A
  95. srcindex++;
  96. }
  97. }
  98. }
  99. void CompressBlockBC4_SingleChannel(const CGU_UINT8 srcBlockTemp[BLOCK_SIZE_4X4],
  100. CMP_GLOBAL CGU_UINT32 compressedBlock[2],
  101. CMP_GLOBAL const CMP_BC15Options* BC15options)
  102. {
  103. if (BC15options)
  104. {
  105. }
  106. CGU_FLOAT alphaBlock[BLOCK_SIZE_4X4];
  107. for (CGU_INT32 i = 0; i < BLOCK_SIZE_4X4; i++)
  108. alphaBlock[i] = (CGU_FLOAT)(srcBlockTemp[i]) / 255.0f;
  109. CGU_Vec2ui cmpBlock;
  110. cmpBlock = cmp_compressAlphaBlock(alphaBlock, BC15options->m_fquality, FALSE);
  111. compressedBlock[0] = cmpBlock.x;
  112. compressedBlock[1] = cmpBlock.y;
  113. }
  114. void DecompressBlockBC4_SingleChannel(CGU_UINT8 srcBlockTemp[16], const CGU_UINT32 compressedBlock[2], const CMP_BC15Options* BC15options)
  115. {
  116. if (BC15options)
  117. {
  118. }
  119. cmp_decompressAlphaBlock(srcBlockTemp, compressedBlock);
  120. }
  121. void CompressBlockBC4S_SingleChannel(const CGU_INT8 srcBlockTemp[BLOCK_SIZE_4X4],
  122. CMP_GLOBAL CGU_UINT32 compressedBlock[2],
  123. CMP_GLOBAL const CMP_BC15Options* BC15options)
  124. {
  125. if (BC15options) { }
  126. CGU_FLOAT alphaBlock[BLOCK_SIZE_4X4];
  127. for (CGU_INT32 i = 0; i < BLOCK_SIZE_4X4; i++)
  128. alphaBlock[i] = (srcBlockTemp[i] / 127.0f);
  129. CGU_Vec2ui cmpBlock;
  130. cmpBlock = cmp_compressAlphaBlock(alphaBlock, BC15options->m_fquality, TRUE);
  131. compressedBlock[0] = cmpBlock.x;
  132. compressedBlock[1] = cmpBlock.y;
  133. }
  134. void DecompressBlockBC4S_SingleChannel(CGU_INT8 srcBlockTemp[16], const CGU_UINT32 compressedBlock[2], const CMP_BC15Options* BC15options)
  135. {
  136. if (BC15options) { }
  137. cmp_decompressAlphaBlockS(srcBlockTemp, compressedBlock);
  138. }
  139. //============================================== USER INTERFACES ========================================================
  140. #ifndef ASPM_GPU
  141. int CMP_CDECL CreateOptionsBC4(void** options)
  142. {
  143. CMP_BC15Options* BC15optionsDefault = new CMP_BC15Options;
  144. if (BC15optionsDefault)
  145. {
  146. SetDefaultBC15Options(BC15optionsDefault);
  147. (*options) = BC15optionsDefault;
  148. }
  149. else
  150. {
  151. (*options) = NULL;
  152. return CGU_CORE_ERR_NEWMEM;
  153. }
  154. return CGU_CORE_OK;
  155. }
  156. int CMP_CDECL DestroyOptionsBC4(void* options)
  157. {
  158. if (!options)
  159. return CGU_CORE_ERR_INVALIDPTR;
  160. CMP_BC15Options* BCOptions = reinterpret_cast<CMP_BC15Options*>(options);
  161. delete BCOptions;
  162. return CGU_CORE_OK;
  163. }
  164. int CMP_CDECL SetQualityBC4(void* options, CGU_FLOAT fquality)
  165. {
  166. if (!options)
  167. return CGU_CORE_ERR_INVALIDPTR;
  168. CMP_BC15Options* BC15optionsDefault = reinterpret_cast<CMP_BC15Options*>(options);
  169. if (fquality < 0.0f)
  170. fquality = 0.0f;
  171. else if (fquality > 1.0f)
  172. fquality = 1.0f;
  173. BC15optionsDefault->m_fquality = fquality;
  174. return CGU_CORE_OK;
  175. }
  176. // prototype code
  177. int CMP_CDECL CompressBlockBC4S(const char* srcBlock, unsigned int srcStrideInBytes, CMP_GLOBAL unsigned char cmpBlock[8], const void* options = NULL)
  178. {
  179. char inBlock[16];
  180. //----------------------------------
  181. // Fill the inBlock with source data
  182. //----------------------------------
  183. CGU_INT srcpos = 0;
  184. CGU_INT dstptr = 0;
  185. for (CGU_UINT8 row = 0; row < 4; row++)
  186. {
  187. srcpos = row * srcStrideInBytes;
  188. for (CGU_UINT8 col = 0; col < 4; col++)
  189. {
  190. inBlock[dstptr++] = CGU_INT8(srcBlock[srcpos++]);
  191. }
  192. }
  193. CMP_BC15Options* BC15options = (CMP_BC15Options*)options;
  194. if (BC15options == NULL)
  195. {
  196. CMP_BC15Options BC15optionsDefault;
  197. BC15options = &BC15optionsDefault;
  198. SetDefaultBC15Options(BC15options);
  199. }
  200. CompressBlockBC4S_SingleChannel(inBlock, (CMP_GLOBAL CGU_UINT32*)cmpBlock, BC15options);
  201. return CGU_CORE_OK;
  202. }
  203. // prototype code
  204. int CMP_CDECL DecompressBlockBC4S(const unsigned char cmpBlock[8], CMP_GLOBAL char srcBlock[16], const void* options = NULL)
  205. {
  206. CMP_BC15Options* BC15options = (CMP_BC15Options*)options;
  207. CMP_BC15Options BC15optionsDefault;
  208. if (BC15options == NULL)
  209. {
  210. BC15options = &BC15optionsDefault;
  211. SetDefaultBC15Options(BC15options);
  212. }
  213. DecompressBlockBC4S_SingleChannel((CGU_INT8*)srcBlock, (CGU_UINT32*)cmpBlock, BC15options);
  214. return CGU_CORE_OK;
  215. }
  216. int CMP_CDECL CompressBlockBC4(const unsigned char* srcBlock, unsigned int srcStrideInBytes, CMP_GLOBAL unsigned char cmpBlock[8], const void* options = NULL)
  217. {
  218. CMP_BC15Options* BC15options = (CMP_BC15Options*)options;
  219. if (BC15options == NULL)
  220. {
  221. CMP_BC15Options BC15optionsDefault;
  222. BC15options = &BC15optionsDefault;
  223. SetDefaultBC15Options(BC15options);
  224. }
  225. unsigned char inBlock[16];
  226. //----------------------------------
  227. // Fill the inBlock with source data
  228. //----------------------------------
  229. CGU_INT srcpos = 0;
  230. CGU_INT dstptr = 0;
  231. for (CGU_UINT8 row = 0; row < 4; row++)
  232. {
  233. srcpos = row * srcStrideInBytes;
  234. for (CGU_UINT8 col = 0; col < 4; col++)
  235. {
  236. inBlock[dstptr++] = CGU_UINT8(srcBlock[srcpos++]);
  237. }
  238. }
  239. CompressBlockBC4_SingleChannel(inBlock, (CMP_GLOBAL CGU_UINT32*)cmpBlock, BC15options);
  240. return CGU_CORE_OK;
  241. }
  242. int CMP_CDECL DecompressBlockBC4(const unsigned char cmpBlock[8], CMP_GLOBAL unsigned char srcBlock[16], const void* options = NULL)
  243. {
  244. CMP_BC15Options* BC15options = (CMP_BC15Options*)options;
  245. CMP_BC15Options BC15optionsDefault;
  246. if (BC15options == NULL)
  247. {
  248. BC15options = &BC15optionsDefault;
  249. SetDefaultBC15Options(BC15options);
  250. }
  251. DecompressBlockBC4_SingleChannel(srcBlock, (CGU_UINT32*)cmpBlock, BC15options);
  252. return CGU_CORE_OK;
  253. }
  254. #endif
  255. //============================================== OpenCL USER INTERFACE ====================================================
  256. #ifdef ASPM_OPENCL
  257. CMP_STATIC CMP_KERNEL void CMP_GPUEncoder(CMP_GLOBAL const CMP_Vec4uc* ImageSource,
  258. CMP_GLOBAL CGU_UINT8* ImageDestination,
  259. CMP_GLOBAL Source_Info* SourceInfo,
  260. CMP_GLOBAL CMP_BC15Options* BC15options)
  261. {
  262. CGU_UINT32 xID;
  263. CGU_UINT32 yID;
  264. #ifdef ASPM_GPU
  265. xID = get_global_id(0);
  266. yID = get_global_id(1);
  267. #else
  268. xID = 0;
  269. yID = 0;
  270. #endif
  271. if (xID >= (SourceInfo->m_src_width / BlockX))
  272. return;
  273. if (yID >= (SourceInfo->m_src_height / BlockX))
  274. return;
  275. int srcWidth = SourceInfo->m_src_width;
  276. CGU_UINT32 destI = (xID * BC4CompBlockSize) + (yID * (srcWidth / BlockX) * BC4CompBlockSize);
  277. int srcindex = 4 * (yID * srcWidth + xID);
  278. int blkindex = 0;
  279. CMP_Vec4uc srcData[16];
  280. srcWidth = srcWidth - 4;
  281. for (CGU_INT32 j = 0; j < 4; j++)
  282. {
  283. for (CGU_INT32 i = 0; i < 4; i++)
  284. {
  285. srcData[blkindex++] = ImageSource[srcindex++];
  286. }
  287. srcindex += srcWidth;
  288. }
  289. CompressBlockBC4_Internal(srcData, (CMP_GLOBAL CGU_UINT32*)&ImageDestination[destI], BC15options);
  290. }
  291. #endif