/* -*- tab-width: 4; -*- */ /* vi: set sw=2 ts=4 expandtab: */ /* * Copyright 2019-2020 The Khronos Group Inc. * SPDX-License-Identifier: Apache-2.0 */ /** * @internal * @file basis_transcode.cpp * @~English * * @brief Functions for transcoding Basis Universal BasisLZ/ETC1S and UASTC textures. * * Two worlds collide here too. More uglyness! * * @author Mark Callow, www.edgewise-consulting.com */ #include <inttypes.h> #include <stdio.h> #include <KHR/khr_df.h> #include "dfdutils/dfd.h" #include "ktx.h" #include "ktxint.h" #include "texture2.h" #include "vkformat_enum.h" #include "vk_format.h" #include "basis_sgd.h" #include "transcoder/basisu_file_headers.h" #include "transcoder/basisu_transcoder.h" #include "transcoder/basisu_transcoder_internal.h" #undef DECLARE_PRIVATE #undef DECLARE_PROTECTED #define DECLARE_PRIVATE(n,t2) … #define DECLARE_PROTECTED(n,t2) … usingnamespacebasisu; usingnamespacebasist; inline bool isPow2(uint32_t x) { … } inline bool isPow2(uint64_t x) { … } KTX_error_code ktxTexture2_transcodeLzEtc1s(ktxTexture2* This, alpha_content_e alphaContent, ktxTexture2* prototype, ktx_transcode_fmt_e outputFormat, ktx_transcode_flags transcodeFlags); KTX_error_code ktxTexture2_transcodeUastc(ktxTexture2* This, alpha_content_e alphaContent, ktxTexture2* prototype, ktx_transcode_fmt_e outputFormat, ktx_transcode_flags transcodeFlags); /** * @memberof ktxTexture2 * @ingroup reader * @~English * @brief Transcode a KTX2 texture with BasisLZ/ETC1S or UASTC images. * * If the texture contains BasisLZ supercompressed images, Inflates them from * back to ETC1S then transcodes them to the specified block-compressed * format. If the texture contains UASTC images, inflates them, if they have been * supercompressed with zstd, then transcodes then to the specified format, The * transcoded images replace the original images and the texture's fields including * the DFD are modified to reflect the new format. * * These types of textures must be transcoded to a desired target * block-compressed format before they can be uploaded to a GPU via a * graphics API. * * The following block compressed transcode targets are available: @c KTX_TTF_ETC1_RGB, * @c KTX_TTF_ETC2_RGBA, @c KTX_TTF_BC1_RGB, @c KTX_TTF_BC3_RGBA, * @c KTX_TTF_BC4_R, @c KTX_TTF_BC5_RG, @c KTX_TTF_BC7_RGBA, * @c @c KTX_TTF_PVRTC1_4_RGB, @c KTX_TTF_PVRTC1_4_RGBA, * @c KTX_TTF_PVRTC2_4_RGB, @c KTX_TTF_PVRTC2_4_RGBA, @c KTX_TTF_ASTC_4x4_RGBA, * @c KTX_TTF_ETC2_EAC_R11, @c KTX_TTF_ETC2_EAC_RG11, @c KTX_TTF_ETC and * @c KTX_TTF_BC1_OR_3. * * @c KTX_TTF_ETC automatically selects between @c KTX_TTF_ETC1_RGB and * @c KTX_TTF_ETC2_RGBA according to whether an alpha channel is available. @c KTX_TTF_BC1_OR_3 * does likewise between @c KTX_TTF_BC1_RGB and @c KTX_TTF_BC3_RGBA. Note that if * @c KTX_TTF_PVRTC1_4_RGBA or @c KTX_TTF_PVRTC2_4_RGBA is specified and there is no alpha * channel @c KTX_TTF_PVRTC1_4_RGB or @c KTX_TTF_PVRTC2_4_RGB respectively will be selected. * * Transcoding to ATC & FXT1 formats is not supported by libktx as there * are no equivalent Vulkan formats. * * The following uncompressed transcode targets are also available: @c KTX_TTF_RGBA32, * @c KTX_TTF_RGB565, KTX_TTF_BGR565 and KTX_TTF_RGBA4444. * * The following @p transcodeFlags are available. * * @sa ktxtexture2_CompressBasis(). * * @param[in] This pointer to the ktxTexture2 object of interest. * @param[in] outputFormat a value from the ktx_texture_transcode_fmt_e enum * specifying the target format. * @param[in] transcodeFlags bitfield of flags modifying the transcode * operation. @sa ktx_texture_decode_flags_e. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_FILE_DATA_ERROR * Supercompression global data is corrupted. * @exception KTX_INVALID_OPERATION * The texture's format is not transcodable (not * ETC1S/BasisLZ or UASTC). * @exception KTX_INVALID_OPERATION * Supercompression global data is missing, i.e., * the texture object is invalid. * @exception KTX_INVALID_OPERATION * Image data is missing, i.e., the texture object * is invalid. * @exception KTX_INVALID_OPERATION * @p outputFormat is PVRTC1 but the texture does * does not have power-of-two dimensions. * @exception KTX_INVALID_VALUE @p outputFormat is invalid. * @exception KTX_TRANSCODE_FAILED * Something went wrong during transcoding. * @exception KTX_UNSUPPORTED_FEATURE * KTX_TF_PVRTC_DECODE_TO_NEXT_POW2 was requested * or the specified transcode target has not been * included in the library being used. * @exception KTX_OUT_OF_MEMORY Not enough memory to carry out transcoding. */ KTX_error_code ktxTexture2_TranscodeBasis(ktxTexture2* This, ktx_transcode_fmt_e outputFormat, ktx_transcode_flags transcodeFlags) { … } /** * @memberof ktxTexture2 @private * @ingroup reader * @~English * @brief Transcode a KTX2 texture with BasisLZ supercompressed ETC1S images. * * Inflates the images from BasisLZ supercompression back to ETC1S * then transcodes them to the specified block-compressed format. The * transcoded images replace the original images and the texture's fields * including the DFD are modified to reflect the new format. * * BasisLZ supercompressed textures must be transcoded to a desired target * block-compressed format before they can be uploaded to a GPU via a graphics * API. * * The following block compressed transcode targets are available: @c KTX_TTF_ETC1_RGB, * @c KTX_TTF_ETC2_RGBA, @c KTX_TTF_BC1_RGB, @c KTX_TTF_BC3_RGBA, * @c KTX_TTF_BC4_R, @c KTX_TTF_BC5_RG, @c KTX_TTF_BC7_RGBA, * @c @c KTX_TTF_PVRTC1_4_RGB, @c KTX_TTF_PVRTC1_4_RGBA, * @c KTX_TTF_PVRTC2_4_RGB, @c KTX_TTF_PVRTC2_4_RGBA, @c KTX_TTF_ASTC_4x4_RGBA, * @c KTX_TTF_ETC2_EAC_R11, @c KTX_TTF_ETC2_EAC_RG11, @c KTX_TTF_ETC and * @c KTX_TTF_BC1_OR_3. * * @c KTX_TTF_ETC automatically selects between @c KTX_TTF_ETC1_RGB and * @c KTX_TTF_ETC2_RGBA according to whether an alpha channel is available. @c KTX_TTF_BC1_OR_3 * does likewise between @c KTX_TTF_BC1_RGB and @c KTX_TTF_BC3_RGBA. Note that if * @c KTX_TTF_PVRTC1_4_RGBA or @c KTX_TTF_PVRTC2_4_RGBA is specified and there is no alpha * channel @c KTX_TTF_PVRTC1_4_RGB or @c KTX_TTF_PVRTC2_4_RGB respectively will be selected. * * ATC & FXT1 formats are not supported by KTX2 & libktx as there are no equivalent Vulkan formats. * * The following uncompressed transcode targets are also available: @c KTX_TTF_RGBA32, * @c KTX_TTF_RGB565, KTX_TTF_BGR565 and KTX_TTF_RGBA4444. * * The following @p transcodeFlags are available. * * @sa ktxtexture2_CompressBasis(). * * @param[in] This pointer to the ktxTexture2 object of interest. * @param[in] outputFormat a value from the ktx_texture_transcode_fmt_e enum * specifying the target format. * @param[in] transcodeFlags bitfield of flags modifying the transcode * operation. @sa ktx_texture_decode_flags_e. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * * @exception KTX_FILE_DATA_ERROR * Supercompression global data is corrupted. * @exception KTX_INVALID_OPERATION * The texture's format is not transcodable (not * ETC1S/BasisLZ or UASTC). * @exception KTX_INVALID_OPERATION * Supercompression global data is missing, i.e., * the texture object is invalid. * @exception KTX_INVALID_OPERATION * Image data is missing, i.e., the texture object * is invalid. * @exception KTX_INVALID_OPERATION * @p outputFormat is PVRTC1 but the texture does * does not have power-of-two dimensions. * @exception KTX_INVALID_VALUE @p outputFormat is invalid. * @exception KTX_TRANSCODE_FAILED * Something went wrong during transcoding. The * texture object will be corrupted. * @exception KTX_UNSUPPORTED_FEATURE * KTX_TF_PVRTC_DECODE_TO_NEXT_POW2 was requested * or the specified transcode target has not been * included in the library being used. * @exception KTX_OUT_OF_MEMORY Not enough memory to carry out transcoding. */ KTX_error_code ktxTexture2_transcodeLzEtc1s(ktxTexture2* This, alpha_content_e alphaContent, ktxTexture2* prototype, ktx_transcode_fmt_e outputFormat, ktx_transcode_flags transcodeFlags) { … } KTX_error_code ktxTexture2_transcodeUastc(ktxTexture2* This, alpha_content_e alphaContent, ktxTexture2* prototype, ktx_transcode_fmt_e outputFormat, ktx_transcode_flags transcodeFlags) { … }