loadimage_astc.cpp (2796B)
1 // 2 // Copyright 2022 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // loadimage_astc.cpp: Decodes ASTC encoded textures. 8 9 #ifdef ANGLE_HAS_ASTCENC 10 # include <astcenc.h> 11 #endif 12 13 #include "image_util/loadimage.h" 14 15 namespace angle 16 { 17 18 void LoadASTCToRGBA8Inner(size_t width, 19 size_t height, 20 size_t depth, 21 uint32_t blockWidth, 22 uint32_t blockHeight, 23 const uint8_t *input, 24 size_t inputRowPitch, 25 size_t inputDepthPitch, 26 uint8_t *output, 27 size_t outputRowPitch, 28 size_t outputDepthPitch) 29 { 30 #ifdef ANGLE_HAS_ASTCENC 31 astcenc_config config; 32 33 constexpr unsigned int kBlockZ = 1; 34 35 const float kQuality = ASTCENC_PRE_MEDIUM; 36 constexpr astcenc_profile kProfile = ASTCENC_PRF_LDR; 37 38 astcenc_error status; 39 status = astcenc_config_init(kProfile, blockWidth, blockHeight, kBlockZ, kQuality, 40 ASTCENC_FLG_DECOMPRESS_ONLY, &config); 41 if (status != ASTCENC_SUCCESS) 42 { 43 WARN() << "astcenc config init failed: " << astcenc_get_error_string(status); 44 return; 45 } 46 47 constexpr unsigned int kThreadCount = 1; 48 49 astcenc_context *context; 50 status = astcenc_context_alloc(&config, kThreadCount, &context); 51 if (status != ASTCENC_SUCCESS) 52 { 53 WARN() << "Could not allocate astcenc context: " << astcenc_get_error_string(status); 54 return; 55 } 56 57 // Compute the number of ASTC blocks in each dimension 58 uint32_t blockCountX = (static_cast<uint32_t>(width) + config.block_x - 1) / config.block_x; 59 uint32_t blockCountY = (static_cast<uint32_t>(height) + config.block_y - 1) / config.block_y; 60 61 // Space needed for 16 bytes of output per compressed block 62 size_t blockSize = blockCountX * blockCountY * 16; 63 64 astcenc_image image; 65 image.dim_x = static_cast<uint32_t>(width); 66 image.dim_y = static_cast<uint32_t>(height); 67 image.dim_z = 1; 68 image.data_type = ASTCENC_TYPE_U8; 69 image.data = reinterpret_cast<void **>(&output); 70 71 constexpr astcenc_swizzle swizzle{ASTCENC_SWZ_R, ASTCENC_SWZ_G, ASTCENC_SWZ_B, ASTCENC_SWZ_A}; 72 73 status = astcenc_decompress_image(context, input, blockSize, &image, &swizzle, 0); 74 if (status != ASTCENC_SUCCESS) 75 { 76 WARN() << "astcenc decompress failed: " << astcenc_get_error_string(status); 77 } 78 79 astcenc_context_free(context); 80 #else 81 ERR() << "Trying to decode ASTC without having ASTC support built."; 82 #endif 83 } 84 } // namespace angle