From b71d0a367124e381f1c1cae31e8d0a509575fb17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Thu, 5 Jun 2025 18:13:31 +0200 Subject: [PATCH] libktx: Update to 4.4.0 --- modules/ktx/SCsub | 14 +- thirdparty/README.md | 13 +- .../{lib => external}/dfdutils/KHR/khr_df.h | 87 +++- .../{lib => external}/dfdutils/colourspaces.c | 0 .../{lib => external}/dfdutils/createdfd.c | 17 +- .../libktx/{lib => external}/dfdutils/dfd.h | 22 +- .../{lib => external}/dfdutils/dfd2vk.inl | 9 +- .../{lib => external}/dfdutils/interpretdfd.c | 0 .../{lib => external}/dfdutils/printdfd.c | 35 +- .../{lib => external}/dfdutils/queries.c | 54 ++- .../{lib => external}/dfdutils/vk2dfd.c | 0 .../{lib => external}/dfdutils/vk2dfd.inl | 2 +- thirdparty/libktx/include/KHR/khr_df.h | 234 ++++----- thirdparty/libktx/include/ktx.h | 217 ++++++--- thirdparty/libktx/lib/basis_transcode.cpp | 7 +- thirdparty/libktx/lib/checkheader.c | 2 +- thirdparty/libktx/lib/hashlist.c | 6 +- thirdparty/libktx/lib/memstream.c | 6 +- thirdparty/libktx/lib/miniz_wrapper.cpp | 2 +- thirdparty/libktx/lib/texture.c | 7 +- thirdparty/libktx/lib/texture.h | 5 +- thirdparty/libktx/lib/texture1.c | 42 +- thirdparty/libktx/lib/texture1.h | 2 +- thirdparty/libktx/lib/texture2.c | 444 ++++++++++++++---- thirdparty/libktx/lib/texture2.h | 5 +- thirdparty/libktx/lib/texture_funcs.inl | 17 +- thirdparty/libktx/lib/vkformat_check.c | 61 ++- .../libktx/lib/vkformat_check_variant.c | 171 +++++++ thirdparty/libktx/lib/vkformat_enum.h | 8 +- thirdparty/libktx/lib/vkformat_typesize.c | 8 +- .../patches/0002-disable-astc-block-ext.patch | 10 +- .../libktx/patches/0003-basisu-1.60.patch | 4 +- 32 files changed, 1130 insertions(+), 381 deletions(-) rename thirdparty/libktx/{lib => external}/dfdutils/KHR/khr_df.h (88%) rename thirdparty/libktx/{lib => external}/dfdutils/colourspaces.c (100%) rename thirdparty/libktx/{lib => external}/dfdutils/createdfd.c (98%) rename thirdparty/libktx/{lib => external}/dfdutils/dfd.h (93%) rename thirdparty/libktx/{lib => external}/dfdutils/dfd2vk.inl (99%) rename thirdparty/libktx/{lib => external}/dfdutils/interpretdfd.c (100%) rename thirdparty/libktx/{lib => external}/dfdutils/printdfd.c (96%) rename thirdparty/libktx/{lib => external}/dfdutils/queries.c (78%) rename thirdparty/libktx/{lib => external}/dfdutils/vk2dfd.c (100%) rename thirdparty/libktx/{lib => external}/dfdutils/vk2dfd.inl (99%) create mode 100644 thirdparty/libktx/lib/vkformat_check_variant.c diff --git a/modules/ktx/SCsub b/modules/ktx/SCsub index df994bf38e8..4d8481ffcfe 100644 --- a/modules/ktx/SCsub +++ b/modules/ktx/SCsub @@ -23,13 +23,14 @@ thirdparty_sources = [ "lib/texture1.c", "lib/texture2.c", "lib/vkformat_check.c", + "lib/vkformat_check_variant.c", "lib/vkformat_typesize.c", - "lib/dfdutils/createdfd.c", - "lib/dfdutils/colourspaces.c", - "lib/dfdutils/interpretdfd.c", - "lib/dfdutils/printdfd.c", - "lib/dfdutils/queries.c", - "lib/dfdutils/vk2dfd.c", + "external/dfdutils/createdfd.c", + "external/dfdutils/colourspaces.c", + "external/dfdutils/interpretdfd.c", + "external/dfdutils/printdfd.c", + "external/dfdutils/queries.c", + "external/dfdutils/vk2dfd.c", ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] @@ -37,6 +38,7 @@ env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "include"]) env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "utils"]) env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "lib"]) env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "other_include"]) +env_ktx.Prepend(CPPEXTPATH=[thirdparty_dir + "external"]) env_ktx.Prepend(CPPEXTPATH=["#thirdparty/basis_universal"]) if env.editor_build: diff --git a/thirdparty/README.md b/thirdparty/README.md index f5730f30bde..8379c0cf177 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -520,19 +520,20 @@ Patches: - `0002-disable-16bitlossless.patch` (GH-104347) - `0003-remove-bmp-ppm-support.patch` (GH-104347) + ## libktx - Upstream: https://github.com/KhronosGroup/KTX-Software -- Version: 4.3.2 (91ace88675ac59a97e55d0378a6602a9ae6b98bd, 2024) -- License: Apache-2.0 +- Version: 4.4.0 (beef80159525d9fb7abb8645ea85f4c4f6842e8f, 2025) +- License: Apache 2.0 Files extracted from upstream source: - `LICENSE.md` -- `include/` -- `lib/dfdutils/LICENSE.adoc` as `LICENSE.dfdutils.adoc` (in root) -- `lib/dfdutils/LICENSES/Apache-2.0.txt` as `Apache-2.0.txt` (in root) -- `lib/dfdutils/{KHR/,dfd.h,colourspaces.c,createdfd.c,interpretdfd.c,printdfd.c,queries.c,dfd2vk.inl,vk2dfd.*}` +- `include/` minus `.clang-format` +- `external/dfdutils/LICENSE.adoc` as `LICENSE.dfdutils.adoc` (in root) +- `external/dfdutils/LICENSES/Apache-2.0.txt` as `Apache-2.0.txt` (in root) +- `external/dfdutils/{KHR/,dfd.h,colourspaces.c,createdfd.c,interpretdfd.c,printdfd.c,queries.c,dfd2vk.inl,vk2dfd.*}` - `lib/{basis_sgd.h,formatsize.h,gl_format.h,ktxint.h,uthash.h,vk_format.h,vkformat_enum.h,checkheader.c,swap.c,hashlist.c,vkformat_check.c,vkformat_typesize.c,basis_transcode.cpp,miniz_wrapper.cpp,filestream.*,memstream.*,texture*}` - `other_include/KHR/` - `utils/unused.h` diff --git a/thirdparty/libktx/lib/dfdutils/KHR/khr_df.h b/thirdparty/libktx/external/dfdutils/KHR/khr_df.h similarity index 88% rename from thirdparty/libktx/lib/dfdutils/KHR/khr_df.h rename to thirdparty/libktx/external/dfdutils/KHR/khr_df.h index bbd0d14bd90..af4970505f2 100644 --- a/thirdparty/libktx/lib/dfdutils/KHR/khr_df.h +++ b/thirdparty/libktx/external/dfdutils/KHR/khr_df.h @@ -1,6 +1,6 @@ -/* The Khronos Data Format Specification (version 1.3) */ +/* The Khronos Data Format Specification (version 1.4.0) */ /* -** Copyright 2015-2020 The Khronos Group Inc. +** Copyright 2015-2025 The Khronos Group Inc. ** SPDX-License-Identifier: Apache-2.0 */ @@ -101,7 +101,7 @@ typedef enum _khr_df_mask_e { ((BDB)[KHR_DF_WORD_ ## X] = \ ((BDB)[KHR_DF_WORD_ ## X] & \ ~((KHR_DF_MASK_ ## X) << (KHR_DF_SHIFT_ ## X))) | \ - (((val) & (KHR_DF_MASK_ ## X)) << (KHR_DF_SHIFT_ ## X))) + (((uint32_t)(val) & (KHR_DF_MASK_ ## X)) << (KHR_DF_SHIFT_ ## X))) /* Offsets relative to the start of a sample */ typedef enum _khr_df_sampleword_e { @@ -135,14 +135,14 @@ typedef enum _khr_df_sampleshift_e { typedef enum _khr_df_samplemask_e { KHR_DF_SAMPLEMASK_BITOFFSET = 0xFFFFU, - KHR_DF_SAMPLEMASK_BITLENGTH = 0xFF, - KHR_DF_SAMPLEMASK_CHANNELID = 0xF, + KHR_DF_SAMPLEMASK_BITLENGTH = 0xFFU, + KHR_DF_SAMPLEMASK_CHANNELID = 0xFU, /* N.B. Qualifiers are defined as an offset into a byte */ - KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFF, + KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0U, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFFU, /* ISO C restricts enum values to range of int hence the cast. We do it verbosely instead of using -1 to ensure it is a 32-bit value even if int is 64 bits. */ @@ -169,7 +169,7 @@ typedef enum _khr_df_samplemask_e { ((S) * KHR_DF_WORD_SAMPLEWORDS) + \ KHR_DF_SAMPLEWORD_ ## X] & \ ~((uint32_t)(KHR_DF_SAMPLEMASK_ ## X) << (KHR_DF_SAMPLESHIFT_ ## X))) | \ - (((val) & (uint32_t)(KHR_DF_SAMPLEMASK_ ## X)) << (KHR_DF_SAMPLESHIFT_ ## X))) + (((uint32_t)(val) & (uint32_t)(KHR_DF_SAMPLEMASK_ ## X)) << (KHR_DF_SAMPLESHIFT_ ## X))) /* Helper macro: Number of samples in basic descriptor block BDB */ @@ -213,7 +213,8 @@ typedef enum _khr_df_versionnumber_e { KHR_DF_VERSIONNUMBER_1_1 = 0U, /* Version 1.1 did not bump the version number */ KHR_DF_VERSIONNUMBER_1_2 = 1U, /* Version 1.2 increased the version number */ KHR_DF_VERSIONNUMBER_1_3 = 2U, /* Version 1.3 increased the version number */ - KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_3, + KHR_DF_VERSIONNUMBER_1_4 = 2U, /* Version 1.4.0 did not bump the block version number */ + KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_4, KHR_DF_VERSIONNUMBER_MAX = 0xFFFFU } khr_df_versionnumber_e; @@ -273,11 +274,15 @@ typedef enum _khr_df_model_e { KHR_DF_MODEL_DXT4 = 130U, KHR_DF_MODEL_DXT5 = 130U, KHR_DF_MODEL_BC3 = 130U, - /* BC4 - single channel interpolated 8-bit data */ + /* ATI1n/DXT5A/BC4 - single channel interpolated 8-bit data */ /* (The UNORM/SNORM variation is recorded in the channel data) */ + KHR_DF_MODEL_ATI1N = 131U, + KHR_DF_MODEL_DXT5A = 131U, KHR_DF_MODEL_BC4 = 131U, - /* BC5 - two channel interpolated 8-bit data */ + /* ATI2n_XY/DXN/BC5 - two channel interpolated 8-bit data */ /* (The UNORM/SNORM variation is recorded in the channel data) */ + KHR_DF_MODEL_ATI2N_XY = 132U, + KHR_DF_MODEL_DXN = 132U, KHR_DF_MODEL_BC5 = 132U, /* BC6H - DX11 format for 16-bit float channels */ KHR_DF_MODEL_BC6H = 133U, @@ -502,7 +507,6 @@ typedef enum _khr_df_model_channels_e { KHR_DF_CHANNEL_PVRTC2_DATA = 0U, KHR_DF_CHANNEL_PVRTC2_COLOR = 0U, /* MODEL UASTC */ - KHR_DF_CHANNEL_UASTC_DATA = 0U, KHR_DF_CHANNEL_UASTC_RGB = 0U, KHR_DF_CHANNEL_UASTC_RGBA = 3U, KHR_DF_CHANNEL_UASTC_RRR = 4U, @@ -538,6 +542,8 @@ typedef enum _khr_df_primaries_e { KHR_DF_PRIMARIES_BT601_SMPTE = 3U, /* Color primaries of ITU-R BT.2020 */ KHR_DF_PRIMARIES_BT2020 = 4U, + /* ITU-R BT.2100 uses the same primaries as BT.2020 */ + KHR_DF_PRIMARIES_BT2100 = 4U, /* CIE theoretical color coordinate space */ KHR_DF_PRIMARIES_CIEXYZ = 5U, /* Academy Color Encoding System primaries */ @@ -559,49 +565,78 @@ typedef enum _khr_df_primaries_e { ("gamma correction"). Most transfer functions are not a pure power function and also include a linear element. LAB and related absolute color representations should use - KHR_DF_TRANSFER_UNSPECIFIED. */ + KHR_DF_TRANSFER_UNSPECIFIED. + These encodings indicate that the representation has had + the corresponding transfer function applied relative to a + linear representation; hence to process the linear intensity + represented by the value, a corresponding inverse transform + must be applied. */ typedef enum _khr_df_transfer_e { /* No transfer function defined */ KHR_DF_TRANSFER_UNSPECIFIED = 0U, /* Linear transfer function (value proportional to intensity) */ KHR_DF_TRANSFER_LINEAR = 1U, - /* Perceptually-linear transfer function of sRGH (~2.4) */ + /* Perceptually-linear transfer function of sRGB (~2.2); also used for scRGB */ KHR_DF_TRANSFER_SRGB = 2U, + KHR_DF_TRANSFER_SRGB_EOTF = 2U, + KHR_DF_TRANSFER_SCRGB = 2U, + KHR_DF_TRANSFER_SCRGB_EOTF = 2U, /* Perceptually-linear transfer function of ITU BT.601, BT.709 and BT.2020 (~1/.45) */ KHR_DF_TRANSFER_ITU = 3U, - /* SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) */ - KHR_DF_TRANSFER_SMTPE170M = 3U, + KHR_DF_TRANSFER_ITU_OETF = 3U, + KHR_DF_TRANSFER_BT601 = 3U, + KHR_DF_TRANSFER_BT601_OETF = 3U, + KHR_DF_TRANSFER_BT709 = 3U, + KHR_DF_TRANSFER_BT709_OETF = 3U, + KHR_DF_TRANSFER_BT2020 = 3U, + KHR_DF_TRANSFER_BT2020_OETF = 3U, + /* SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) and a linear OOTF */ + KHR_DF_TRANSFER_SMTPE170M = 3U, + KHR_DF_TRANSFER_SMTPE170M_OETF = 3U, + KHR_DF_TRANSFER_SMTPE170M_EOTF = 3U, /* Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */ KHR_DF_TRANSFER_NTSC = 4U, + KHR_DF_TRANSFER_NTSC_EOTF = 4U, /* Sony S-log used by Sony video cameras */ KHR_DF_TRANSFER_SLOG = 5U, + KHR_DF_TRANSFER_SLOG_OETF = 5U, /* Sony S-log 2 used by Sony video cameras */ KHR_DF_TRANSFER_SLOG2 = 6U, + KHR_DF_TRANSFER_SLOG2_OETF = 6U, /* ITU BT.1886 EOTF */ KHR_DF_TRANSFER_BT1886 = 7U, - /* ITU BT.2100 HLG OETF */ + KHR_DF_TRANSFER_BT1886_EOTF = 7U, + /* ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..1 */ KHR_DF_TRANSFER_HLG_OETF = 8U, - /* ITU BT.2100 HLG EOTF */ + /* ITU BT.2100 HLG EOTF (nominal HDR display of HLG content), linear light normalized 0..1 */ KHR_DF_TRANSFER_HLG_EOTF = 9U, - /* ITU BT.2100 PQ EOTF */ + /* ITU BT.2100 PQ EOTF (typical HDR display-referred PQ content) */ KHR_DF_TRANSFER_PQ_EOTF = 10U, - /* ITU BT.2100 PQ OETF */ + /* ITU BT.2100 PQ OETF (nominal scene described by PQ HDR content) */ KHR_DF_TRANSFER_PQ_OETF = 11U, /* DCI P3 transfer function */ KHR_DF_TRANSFER_DCIP3 = 12U, + KHR_DF_TRANSFER_DCIP3_EOTF = 12U, /* Legacy PAL OETF */ KHR_DF_TRANSFER_PAL_OETF = 13U, /* Legacy PAL 625-line EOTF */ KHR_DF_TRANSFER_PAL625_EOTF = 14U, /* Legacy ST240 transfer function */ KHR_DF_TRANSFER_ST240 = 15U, + KHR_DF_TRANSFER_ST240_OETF = 15U, + KHR_DF_TRANSFER_ST240_EOTF = 15U, /* ACEScc transfer function */ KHR_DF_TRANSFER_ACESCC = 16U, + KHR_DF_TRANSFER_ACESCC_OETF = 16U, /* ACEScct transfer function */ - KHR_DF_TRANSFER_ACESCCT = 17U, + KHR_DF_TRANSFER_ACESCCT = 17U, + KHR_DF_TRANSFER_ACESCCT_OETF = 17U, /* Adobe RGB (1998) transfer function */ - KHR_DF_TRANSFER_ADOBERGB = 18U, - KHR_DF_TRANSFER_MAX = 0xFFU + KHR_DF_TRANSFER_ADOBERGB = 18U, + KHR_DF_TRANSFER_ADOBERGB_EOTF = 18U, + /* Legacy ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..12 */ + KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF = 19U, + KHR_DF_TRANSFER_MAX = 0xFFU } khr_df_transfer_e; typedef enum _khr_df_flags_e { diff --git a/thirdparty/libktx/lib/dfdutils/colourspaces.c b/thirdparty/libktx/external/dfdutils/colourspaces.c similarity index 100% rename from thirdparty/libktx/lib/dfdutils/colourspaces.c rename to thirdparty/libktx/external/dfdutils/colourspaces.c diff --git a/thirdparty/libktx/lib/dfdutils/createdfd.c b/thirdparty/libktx/external/dfdutils/createdfd.c similarity index 98% rename from thirdparty/libktx/lib/dfdutils/createdfd.c rename to thirdparty/libktx/external/dfdutils/createdfd.c index eb64204189a..d063f419736 100644 --- a/thirdparty/libktx/lib/dfdutils/createdfd.c +++ b/thirdparty/libktx/external/dfdutils/createdfd.c @@ -94,7 +94,7 @@ static uint32_t setChannelFlags(uint32_t channel, enum VkSuffix suffix) channel |= KHR_DF_SAMPLE_DATATYPE_LINEAR; } break; - case s_S10_5: + case s_SFIXED5: channel |= KHR_DF_SAMPLE_DATATYPE_SIGNED; break; @@ -162,7 +162,7 @@ static void writeSample(uint32_t *DFD, int sampleNo, int channel, upper.f = 1.0f; lower.f = 0.0f; break; - case s_S10_5: + case s_SFIXED5: assert(bits == 16 && "Format with this suffix must be 16 bits per channel."); upper.i = 32; lower.i = ~upper.i + 1; // -32 @@ -736,6 +736,19 @@ uint32_t *createDFDDepthStencil(int depthBits, uint32_t *DFD = 0; DFD = writeHeader((depthBits > 0) + (stencilBits > 0), sizeBytes, s_UNORM, i_NON_COLOR); + + /* Handle the special case of D24_UNORM_S8_UINT where the order of the + channels is flipped by putting stencil in the LSBs. */ + if (depthBits == 24 && stencilBits == 8) { + writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_STENCIL, + 8, 0, + 1, 1, s_UINT); + writeSample(DFD, 1, KHR_DF_CHANNEL_RGBSDA_DEPTH, + 24, 8, + 1, 1, s_UNORM); + return DFD; + } + if (depthBits == 32) { writeSample(DFD, 0, KHR_DF_CHANNEL_RGBSDA_DEPTH, 32, 0, diff --git a/thirdparty/libktx/lib/dfdutils/dfd.h b/thirdparty/libktx/external/dfdutils/dfd.h similarity index 93% rename from thirdparty/libktx/lib/dfdutils/dfd.h rename to thirdparty/libktx/external/dfdutils/dfd.h index 756490fc82d..95d81699dd4 100644 --- a/thirdparty/libktx/lib/dfdutils/dfd.h +++ b/thirdparty/libktx/external/dfdutils/dfd.h @@ -36,7 +36,7 @@ enum VkSuffix { s_SFLOAT, /*!< Signed float format. */ s_UFLOAT, /*!< Unsigned float format. */ s_SRGB, /*!< sRGB normalized format. */ - s_S10_5 /*!< 2's complement fixed-point; 5 fractional bits. */ + s_SFIXED5 /*!< 2's complement fixed-point; 5 fractional bits. */ }; /** Compression scheme, in Vulkan terms. */ @@ -65,7 +65,7 @@ typedef unsigned int uint32_t; #if !defined(LIBKTX) #include #else -#include "../vkformat_enum.h" +#include "../../lib/vkformat_enum.h" #endif uint32_t* vk2dfd(enum VkFormat format); @@ -194,21 +194,21 @@ void printDFDJSON(uint32_t *DFD, uint32_t dataSize, uint32_t base_indent, uint32 /* Get the number of components & component size from a DFD for an * unpacked format. */ -void -getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents, - uint32_t* componentByteLength); +void getDFDComponentInfoUnpacked(const uint32_t* DFD, uint32_t* numComponents, + uint32_t* componentByteLength); /* Return the number of components described by a DFD. */ uint32_t getDFDNumComponents(const uint32_t* DFD); -/* Reconstruct and return the value of bytesPlane0 as it should be for the data - * post-inflation from variable-rate compression. +/* Reconstruct and update the bytesPlane[0-4] fields of an unsized DFD to what + * they were before supercompression. */ -uint32_t -reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD); +void reconstructDFDBytesPlanesFromSamples(uint32_t* DFD); /* Deprecated. For backward compatibility. */ -void -recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, uint32_t* bytesPlane0); +uint32_t reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD); +/* Deprecated. For backward compatibility. */ +void recreateBytesPlane0FromSampleInfo(const uint32_t* DFD, + uint32_t* bytesPlane0); /** @brief Colourspace primaries information. * diff --git a/thirdparty/libktx/lib/dfdutils/dfd2vk.inl b/thirdparty/libktx/external/dfdutils/dfd2vk.inl similarity index 99% rename from thirdparty/libktx/lib/dfdutils/dfd2vk.inl rename to thirdparty/libktx/external/dfdutils/dfd2vk.inl index a616566c744..9592c61efbb 100644 --- a/thirdparty/libktx/lib/dfdutils/dfd2vk.inl +++ b/thirdparty/libktx/external/dfdutils/dfd2vk.inl @@ -40,7 +40,12 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA || KHR_DFDVAL(dfd + 1, MOD } } if (KHR_DFDSVAL((dfd + 1), 0, CHANNELID) == KHR_DF_CHANNEL_RGBSDA_STENCIL) { - return VK_FORMAT_S8_UINT; + if (KHR_DFDSAMPLECOUNT((dfd + 1)) == 1) { + return VK_FORMAT_S8_UINT; + } else { + // The KTX 2.0 specification defines D24_UNORM_S8_UINT with S8 in the LSBs + return VK_FORMAT_D24_UNORM_S8_UINT; + } } r = interpretDFD(dfd, &R, &G, &B, &A, &wordBytes); @@ -173,7 +178,7 @@ if (KHR_DFDVAL(dfd + 1, MODEL) == KHR_DF_MODEL_RGBSDA || KHR_DFDVAL(dfd + 1, MOD if (!(r & i_NORMALIZED_FORMAT_BIT) && (r & i_SIGNED_FORMAT_BIT)) return VK_FORMAT_R8_SINT; } } else if (wordBytes == 2) { - if ((r & i_FIXED_FORMAT_BIT) && R.size == 2 && G.size == 2) return VK_FORMAT_R16G16_S10_5_NV; + if ((r & i_FIXED_FORMAT_BIT) && R.size == 2 && G.size == 2) return VK_FORMAT_R16G16_SFIXED5_NV; if (A.size > 0) { /* 4 channels */ if (R.offset == 0) { /* RGBA */ if ((r & i_FLOAT_FORMAT_BIT)) return VK_FORMAT_R16G16B16A16_SFLOAT; diff --git a/thirdparty/libktx/lib/dfdutils/interpretdfd.c b/thirdparty/libktx/external/dfdutils/interpretdfd.c similarity index 100% rename from thirdparty/libktx/lib/dfdutils/interpretdfd.c rename to thirdparty/libktx/external/dfdutils/interpretdfd.c diff --git a/thirdparty/libktx/lib/dfdutils/printdfd.c b/thirdparty/libktx/external/dfdutils/printdfd.c similarity index 96% rename from thirdparty/libktx/lib/dfdutils/printdfd.c rename to thirdparty/libktx/external/dfdutils/printdfd.c index bfdd33ba04d..6c902511325 100644 --- a/thirdparty/libktx/lib/dfdutils/printdfd.c +++ b/thirdparty/libktx/external/dfdutils/printdfd.c @@ -93,17 +93,34 @@ const char* dfdToStringTransferFunction(khr_df_transfer_e value) { case KHR_DF_TRANSFER_LINEAR: return "KHR_DF_TRANSFER_LINEAR"; case KHR_DF_TRANSFER_SRGB: + // case KHR_DF_TRANSFER_SRGB_EOTF: + // case KHR_DF_TRANSFER_SCRGB: + // case KHR_DF_TRANSFER_SCRGB_EOTF: // Fallthrough, matching values return "KHR_DF_TRANSFER_SRGB"; case KHR_DF_TRANSFER_ITU: + // case KHR_DF_ITU_OETF: + // case KHR_DF_TRANSFER_BT601: + // case KHR_DF_TRANSFER_BT601_OETF: + // case KHR_DF_TRANSFER_BT709: + // case KHR_DF_TRANSFER_BT709_OETF: + // case KHR_DF_TRANSFER_BT2020: + // case KHR_DF_TRANSFER_BT2020_OETF: + // case KHR_DF_TRANSFER_SMTPE170M: + // case KHR_DF_TRANSFER_SMTPE170M_OETF: + // case KHR_DF_TRANSFER_SMTPE170M_EOTF: + // case KHR_DF_TRANSFER_SMTPE170M: // Fallthrough, matching values return "KHR_DF_TRANSFER_ITU"; case KHR_DF_TRANSFER_NTSC: - // case KHR_DF_TRANSFER_SMTPE170M: // Fallthrough, Matching values + // case KHR_DF_TRANSFER_NTSC_EOTF: // Fallthrough, matching values return "KHR_DF_TRANSFER_NTSC"; case KHR_DF_TRANSFER_SLOG: + //case KHR_DF_TRANSFER_SLOG_OETF: // Fallthrough, matching values return "KHR_DF_TRANSFER_SLOG"; case KHR_DF_TRANSFER_SLOG2: - return "KHR_DF_TRANSFER_SLOG2"; + // case KHR_DF_TRANSFER_SLOG2_OETF: + return "KHR_DF_TRANSFER_SLOG2"; case KHR_DF_TRANSFER_BT1886: + // case KHR_DF_TRANSFER_BT1886_EOTF: // Fallthrough, matching values return "KHR_DF_TRANSFER_BT1886"; case KHR_DF_TRANSFER_HLG_OETF: return "KHR_DF_TRANSFER_HLG_OETF"; @@ -114,19 +131,27 @@ const char* dfdToStringTransferFunction(khr_df_transfer_e value) { case KHR_DF_TRANSFER_PQ_OETF: return "KHR_DF_TRANSFER_PQ_OETF"; case KHR_DF_TRANSFER_DCIP3: + // case KHR_DF_TRANSFER_DCIP3_EOTF: // Fallthrough, matching values return "KHR_DF_TRANSFER_DCIP3"; case KHR_DF_TRANSFER_PAL_OETF: return "KHR_DF_TRANSFER_PAL_OETF"; case KHR_DF_TRANSFER_PAL625_EOTF: return "KHR_DF_TRANSFER_PAL625_EOTF"; case KHR_DF_TRANSFER_ST240: + // case KHR_DF_TRANSFER_ST240_EOTF: + // case KHR_DF_TRANSFER_ST240_OETF: // Fallthrough, matching values return "KHR_DF_TRANSFER_ST240"; case KHR_DF_TRANSFER_ACESCC: + // case KHR_DF_TRANSFER_ACESCC_OETF: // Fallthrough, matching values return "KHR_DF_TRANSFER_ACESCC"; case KHR_DF_TRANSFER_ACESCCT: + // case KHR_DF_TRANSFER_ACESCCT_OETF: // Fallthrough, matching values return "KHR_DF_TRANSFER_ACESCCT"; case KHR_DF_TRANSFER_ADOBERGB: + // case KHR_DF_TRANSFER_ADOBERGB_EOTF: // Fallthrough, matching values return "KHR_DF_TRANSFER_ADOBERGB"; + case KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF: + return "KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF"; case KHR_DF_TRANSFER_MAX: // These enum values are not meant for string representation. Ignore @@ -245,7 +270,7 @@ const char* dfdToStringColorModel(khr_df_model_e value) { return NULL; } -const char* dfdToStringSampleDatatypeQualifiers(uint32_t bit_index, bool bit_value) { +const char* dfdToStringSampleDatatypeQualifiersBit(uint32_t bit_index, bool bit_value) { if (!bit_value) return NULL; @@ -782,7 +807,7 @@ void printDFD(uint32_t *DFD, uint32_t dataSize) khr_df_sample_datatype_qualifiers_e qualifiers = KHR_DFDSVAL(block, sample, QUALIFIERS); printf(" Qualifiers: 0x%X (", qualifiers); - printFlagBits(qualifiers, dfdToStringSampleDatatypeQualifiers); + printFlagBits(qualifiers, dfdToStringSampleDatatypeQualifiersBit); printf(")\n"); printf(" Channel Type: 0x%X", channelType); { @@ -960,7 +985,7 @@ void printDFDJSON(uint32_t* DFD, uint32_t dataSize, uint32_t base_indent, uint32 } else { PRINT_INDENT(4, "\"qualifiers\":%s[%s", space, nl) - printFlagBitsJSON(LENGTH_OF_INDENT(5), nl, qualifiers, dfdToStringSampleDatatypeQualifiers); + printFlagBitsJSON(LENGTH_OF_INDENT(5), nl, qualifiers, dfdToStringSampleDatatypeQualifiersBit); PRINT_INDENT(4, "],%s", nl) } diff --git a/thirdparty/libktx/lib/dfdutils/queries.c b/thirdparty/libktx/external/dfdutils/queries.c similarity index 78% rename from thirdparty/libktx/lib/dfdutils/queries.c rename to thirdparty/libktx/external/dfdutils/queries.c index 66d77cf6ade..f0cae3b1b49 100644 --- a/thirdparty/libktx/lib/dfdutils/queries.c +++ b/thirdparty/libktx/external/dfdutils/queries.c @@ -97,19 +97,23 @@ uint32_t getDFDNumComponents(const uint32_t* DFD) return numComponents; } - /** * @~English * @brief Reconstruct the value of bytesPlane0 from sample info. * - * Reconstruct the value for data that has been variable-rate compressed so - * has bytesPlane0 = 0. For DFDs that are valid for KTX files. Little-endian - * data only and no multi-plane formats. + * @deprecated Use reconstructDFDBytesPlanesFromSamples. This does not handle + * the possible second plane of the ETC1S model. * - * @param DFD Pointer to a Data Format Descriptor for which, - * described as 32-bit words in native endianness. + * Reconstruct the value for data that has been variable-rate compressed + * and and whose bytesPlane0 value has been set to 0. For DFDs that + * are valid for KTX files. Little-endian data only and no multi-plane models + * except ETC1S. + * + * @param DFD Pointer to the Data Format Descriptor for which to provide + * the value described as 32-bit words in native endianness. * Note that this is the whole descriptor, not just * the basic descriptor block. + * @return The number of bytes a pixel occupies in bytesPlane0. */ uint32_t reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD) @@ -143,6 +147,10 @@ reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD) } } } + if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) { + // Size of the first plane. + return 8; + } for (sampleNumber = 0; sampleNumber < numSamples; ++sampleNumber) { int32_t sampleBitOffset = KHR_DFDSVAL(BDFDB, sampleNumber, BITOFFSET); if (sampleBitOffset > largestOffset) { @@ -157,16 +165,44 @@ reconstructDFDBytesPlane0FromSamples(const uint32_t* DFD) return bitsPlane0 >> 3U; } +/** + * @~English + * @brief Reconstruct the values of bytesPlane[01] from sample info. + * + * Reconstruct the values for data that has been variable-rate compressed + * and whose bytesPlane[01] values have been set to 0 and update the + * fields of the target DFD. For DFDs that are valid for KTX files. + * Little-endian data only and no multi-plane models except ETC1S hence + * only looking at bytesPlane0 abd bytesPlane1. + * + * @param DFD Pointer to a Data Format Descriptor for which, + * described as 32-bit words in native endianness. + * Note that this is the whole descriptor, not just + * the basic descriptor block. + */ + +void +reconstructDFDBytesPlanesFromSamples(uint32_t* DFD) +{ + uint32_t *BDFDB = DFD+1; + + KHR_DFDSETVAL(BDFDB, BYTESPLANE0, reconstructDFDBytesPlane0FromSamples(DFD)); + if (KHR_DFDVAL(BDFDB, MODEL) == KHR_DF_MODEL_ETC1S) { + if (KHR_DFDSAMPLECOUNT(BDFDB) == 2) + KHR_DFDSETVAL(BDFDB, BYTESPLANE1, 8); + } +} + /** * @~English * @brief Reconstruct the value of bytesPlane0 from sample info. * * @see reconstructDFDBytesPlane0FromSamples for details. * @deprecated For backward comparibility only. Use - * reconstructDFDBytesPlane0FromSamples. + * reconstructDFDBytesPlanesFromSamples. * - * @param DFD Pointer to a Data Format Descriptor for which, - * described as 32-bit words in native endianness. + * @param DFD Pointer to the Data Format Descriptor for which to provide + * the value described as 32-bit words in native endianness. * Note that this is the whole descriptor, not just * the basic descriptor block. * @param bytesPlane0 pointer to a 32-bit word in which the recreated diff --git a/thirdparty/libktx/lib/dfdutils/vk2dfd.c b/thirdparty/libktx/external/dfdutils/vk2dfd.c similarity index 100% rename from thirdparty/libktx/lib/dfdutils/vk2dfd.c rename to thirdparty/libktx/external/dfdutils/vk2dfd.c diff --git a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl b/thirdparty/libktx/external/dfdutils/vk2dfd.inl similarity index 99% rename from thirdparty/libktx/lib/dfdutils/vk2dfd.inl rename to thirdparty/libktx/external/dfdutils/vk2dfd.inl index 3398441e8c1..f1f97a75ca9 100644 --- a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl +++ b/thirdparty/libktx/external/dfdutils/vk2dfd.inl @@ -402,7 +402,7 @@ case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SRGB); case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SFLOAT); #endif -case VK_FORMAT_R16G16_S10_5_NV: return createDFDUnpacked(0, 2, 2, 0, s_S10_5); +case VK_FORMAT_R16G16_SFIXED5_NV: return createDFDUnpacked(0, 2, 2, 0, s_SFIXED5); case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: { int channels[] = {0,1,2,3}; int bits[] = {5,5,5,1}; return createDFDPacked(0, 4, bits, channels, s_UNORM); diff --git a/thirdparty/libktx/include/KHR/khr_df.h b/thirdparty/libktx/include/KHR/khr_df.h index c0d03aa763e..af4970505f2 100644 --- a/thirdparty/libktx/include/KHR/khr_df.h +++ b/thirdparty/libktx/include/KHR/khr_df.h @@ -1,6 +1,6 @@ -/* The Khronos Data Format Specification (version 1.3) */ +/* The Khronos Data Format Specification (version 1.4.0) */ /* -** Copyright 2015-2020 The Khronos Group Inc. +** Copyright 2015-2025 The Khronos Group Inc. ** SPDX-License-Identifier: Apache-2.0 */ @@ -17,11 +17,6 @@ #ifndef _KHR_DATA_FORMAT_H_ #define _KHR_DATA_FORMAT_H_ -/** @file khr_df.h - - @brief Data Format enums and macros. -*/ - /* Accessors */ typedef enum _khr_word_e { KHR_DF_WORD_VENDORID = 0U, @@ -106,7 +101,7 @@ typedef enum _khr_df_mask_e { ((BDB)[KHR_DF_WORD_ ## X] = \ ((BDB)[KHR_DF_WORD_ ## X] & \ ~((KHR_DF_MASK_ ## X) << (KHR_DF_SHIFT_ ## X))) | \ - (((val) & (KHR_DF_MASK_ ## X)) << (KHR_DF_SHIFT_ ## X))) + (((uint32_t)(val) & (KHR_DF_MASK_ ## X)) << (KHR_DF_SHIFT_ ## X))) /* Offsets relative to the start of a sample */ typedef enum _khr_df_sampleword_e { @@ -140,14 +135,14 @@ typedef enum _khr_df_sampleshift_e { typedef enum _khr_df_samplemask_e { KHR_DF_SAMPLEMASK_BITOFFSET = 0xFFFFU, - KHR_DF_SAMPLEMASK_BITLENGTH = 0xFF, - KHR_DF_SAMPLEMASK_CHANNELID = 0xF, + KHR_DF_SAMPLEMASK_BITLENGTH = 0xFFU, + KHR_DF_SAMPLEMASK_CHANNELID = 0xFU, /* N.B. Qualifiers are defined as an offset into a byte */ - KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFF, - KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFF, + KHR_DF_SAMPLEMASK_QUALIFIERS = 0xF0U, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION0 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION1 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION2 = 0xFFU, + KHR_DF_SAMPLEMASK_SAMPLEPOSITION3 = 0xFFU, /* ISO C restricts enum values to range of int hence the cast. We do it verbosely instead of using -1 to ensure it is a 32-bit value even if int is 64 bits. */ @@ -174,7 +169,7 @@ typedef enum _khr_df_samplemask_e { ((S) * KHR_DF_WORD_SAMPLEWORDS) + \ KHR_DF_SAMPLEWORD_ ## X] & \ ~((uint32_t)(KHR_DF_SAMPLEMASK_ ## X) << (KHR_DF_SAMPLESHIFT_ ## X))) | \ - (((val) & (uint32_t)(KHR_DF_SAMPLEMASK_ ## X)) << (KHR_DF_SAMPLESHIFT_ ## X))) + (((uint32_t)(val) & (uint32_t)(KHR_DF_SAMPLEMASK_ ## X)) << (KHR_DF_SAMPLESHIFT_ ## X))) /* Helper macro: Number of samples in basic descriptor block BDB */ @@ -218,46 +213,46 @@ typedef enum _khr_df_versionnumber_e { KHR_DF_VERSIONNUMBER_1_1 = 0U, /* Version 1.1 did not bump the version number */ KHR_DF_VERSIONNUMBER_1_2 = 1U, /* Version 1.2 increased the version number */ KHR_DF_VERSIONNUMBER_1_3 = 2U, /* Version 1.3 increased the version number */ - KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_3, + KHR_DF_VERSIONNUMBER_1_4 = 2U, /* Version 1.4.0 did not bump the block version number */ + KHR_DF_VERSIONNUMBER_LATEST = KHR_DF_VERSIONNUMBER_1_4, KHR_DF_VERSIONNUMBER_MAX = 0xFFFFU } khr_df_versionnumber_e; -/** @~English - @brief Model in which the color coordinate space is defined. +/* Model in which the color coordinate space is defined. There is no requirement that a color format use all the channel types that are defined in the color model. */ typedef enum _khr_df_model_e { - /** No interpretation of color channels defined */ + /* No interpretation of color channels defined */ KHR_DF_MODEL_UNSPECIFIED = 0U, - /** Color primaries (red, green, blue) + alpha, depth and stencil */ + /* Color primaries (red, green, blue) + alpha, depth and stencil */ KHR_DF_MODEL_RGBSDA = 1U, - /** Color differences (Y', Cb, Cr) + alpha, depth and stencil */ + /* Color differences (Y', Cb, Cr) + alpha, depth and stencil */ KHR_DF_MODEL_YUVSDA = 2U, - /** Color differences (Y', I, Q) + alpha, depth and stencil */ + /* Color differences (Y', I, Q) + alpha, depth and stencil */ KHR_DF_MODEL_YIQSDA = 3U, - /** Perceptual color (CIE L*a*b*) + alpha, depth and stencil */ + /* Perceptual color (CIE L*a*b*) + alpha, depth and stencil */ KHR_DF_MODEL_LABSDA = 4U, - /** Subtractive colors (cyan, magenta, yellow, black) + alpha */ + /* Subtractive colors (cyan, magenta, yellow, black) + alpha */ KHR_DF_MODEL_CMYKA = 5U, - /** Non-color coordinate data (X, Y, Z, W) */ + /* Non-color coordinate data (X, Y, Z, W) */ KHR_DF_MODEL_XYZW = 6U, - /** Hue, saturation, value, hue angle on color circle, plus alpha */ + /* Hue, saturation, value, hue angle on color circle, plus alpha */ KHR_DF_MODEL_HSVA_ANG = 7U, - /** Hue, saturation, lightness, hue angle on color circle, plus alpha */ + /* Hue, saturation, lightness, hue angle on color circle, plus alpha */ KHR_DF_MODEL_HSLA_ANG = 8U, - /** Hue, saturation, value, hue on color hexagon, plus alpha */ + /* Hue, saturation, value, hue on color hexagon, plus alpha */ KHR_DF_MODEL_HSVA_HEX = 9U, - /** Hue, saturation, lightness, hue on color hexagon, plus alpha */ + /* Hue, saturation, lightness, hue on color hexagon, plus alpha */ KHR_DF_MODEL_HSLA_HEX = 10U, - /** Lightweight approximate color difference (luma, orange, green) */ + /* Lightweight approximate color difference (luma, orange, green) */ KHR_DF_MODEL_YCGCOA = 11U, - /** ITU BT.2020 constant luminance YcCbcCrc */ + /* ITU BT.2020 constant luminance YcCbcCrc */ KHR_DF_MODEL_YCCBCCRC = 12U, - /** ITU BT.2100 constant intensity ICtCp */ + /* ITU BT.2100 constant intensity ICtCp */ KHR_DF_MODEL_ICTCP = 13U, - /** CIE 1931 XYZ color coordinates (X, Y, Z) */ + /* CIE 1931 XYZ color coordinates (X, Y, Z) */ KHR_DF_MODEL_CIEXYZ = 14U, - /** CIE 1931 xyY color coordinates (X, Y, Y) */ + /* CIE 1931 xyY color coordinates (X, Y, Y) */ KHR_DF_MODEL_CIEXYY = 15U, /* Compressed formats start at 128. */ @@ -266,54 +261,55 @@ typedef enum _khr_df_model_e { channels are used to distinguish formats, these should be cosited. */ /* Direct3D (and S3) compressed formats */ /* Note that premultiplied status is recorded separately */ - /** DXT1 "channels" are RGB (0), Alpha (1) - DXT1/BC1 with one channel is opaque - DXT1/BC1 with a cosited alpha sample is transparent */ + /* DXT1 "channels" are RGB (0), Alpha (1) */ + /* DXT1/BC1 with one channel is opaque */ + /* DXT1/BC1 with a cosited alpha sample is transparent */ KHR_DF_MODEL_DXT1A = 128U, KHR_DF_MODEL_BC1A = 128U, - /** DXT2/DXT3/BC2, with explicit 4-bit alpha */ + /* DXT2/DXT3/BC2, with explicit 4-bit alpha */ KHR_DF_MODEL_DXT2 = 129U, KHR_DF_MODEL_DXT3 = 129U, KHR_DF_MODEL_BC2 = 129U, - /** DXT4/DXT5/BC3, with interpolated alpha */ + /* DXT4/DXT5/BC3, with interpolated alpha */ KHR_DF_MODEL_DXT4 = 130U, KHR_DF_MODEL_DXT5 = 130U, KHR_DF_MODEL_BC3 = 130U, - /** BC4 - single channel interpolated 8-bit data - (The UNORM/SNORM variation is recorded in the channel data) */ + /* ATI1n/DXT5A/BC4 - single channel interpolated 8-bit data */ + /* (The UNORM/SNORM variation is recorded in the channel data) */ + KHR_DF_MODEL_ATI1N = 131U, + KHR_DF_MODEL_DXT5A = 131U, KHR_DF_MODEL_BC4 = 131U, - /** BC5 - two channel interpolated 8-bit data - (The UNORM/SNORM variation is recorded in the channel data) */ + /* ATI2n_XY/DXN/BC5 - two channel interpolated 8-bit data */ + /* (The UNORM/SNORM variation is recorded in the channel data) */ + KHR_DF_MODEL_ATI2N_XY = 132U, + KHR_DF_MODEL_DXN = 132U, KHR_DF_MODEL_BC5 = 132U, - /** BC6H - DX11 format for 16-bit float channels */ + /* BC6H - DX11 format for 16-bit float channels */ KHR_DF_MODEL_BC6H = 133U, - /** BC7 - DX11 format */ + /* BC7 - DX11 format */ KHR_DF_MODEL_BC7 = 134U, /* Gap left for future desktop expansion */ /* Mobile compressed formats follow */ - /** A format of ETC1 indicates that the format shall be decodable - by an ETC1-compliant decoder and not rely on ETC2 features */ + /* A format of ETC1 indicates that the format shall be decodable + by an ETC1-compliant decoder and not rely on ETC2 features */ KHR_DF_MODEL_ETC1 = 160U, - /** A format of ETC2 is permitted to use ETC2 encodings on top of - the baseline ETC1 specification. - The ETC2 format has channels "red", "green", "RGB" and "alpha", - which should be cosited samples. - Punch-through alpha can be distinguished from full alpha by - the plane size in bytes required for the texel block */ + /* A format of ETC2 is permitted to use ETC2 encodings on top of + the baseline ETC1 specification */ + /* The ETC2 format has channels "red", "green", "RGB" and "alpha", + which should be cosited samples */ + /* Punch-through alpha can be distinguished from full alpha by + the plane size in bytes required for the texel block */ KHR_DF_MODEL_ETC2 = 161U, - /** Adaptive Scalable Texture Compression */ - /** ASTC HDR vs LDR is determined by the float flag in the channel */ - /** ASTC block size can be distinguished by texel block size */ + /* Adaptive Scalable Texture Compression */ + /* ASTC HDR vs LDR is determined by the float flag in the channel */ + /* ASTC block size can be distinguished by texel block size */ KHR_DF_MODEL_ASTC = 162U, - /** ETC1S is a simplified subset of ETC1 */ + /* ETC1S is a simplified subset of ETC1 */ KHR_DF_MODEL_ETC1S = 163U, - /** PowerVR Texture Compression v1 */ + /* PowerVR Texture Compression */ KHR_DF_MODEL_PVRTC = 164U, - /** PowerVR Texture Compression v2 */ KHR_DF_MODEL_PVRTC2 = 165U, - /** UASTC is a transcodable subset of ASTC - with additions to support the transcoding. */ KHR_DF_MODEL_UASTC = 166U, /* Proprietary formats (ATITC, etc.) should follow */ KHR_DF_MODEL_MAX = 0xFFU @@ -511,7 +507,6 @@ typedef enum _khr_df_model_channels_e { KHR_DF_CHANNEL_PVRTC2_DATA = 0U, KHR_DF_CHANNEL_PVRTC2_COLOR = 0U, /* MODEL UASTC */ - KHR_DF_CHANNEL_UASTC_DATA = 0U, KHR_DF_CHANNEL_UASTC_RGB = 0U, KHR_DF_CHANNEL_UASTC_RGBA = 3U, KHR_DF_CHANNEL_UASTC_RRR = 4U, @@ -529,90 +524,119 @@ typedef enum _khr_df_model_channels_e { KHR_DF_CHANNEL_COMMON_A = 15U } khr_df_model_channels_e; -/** @~English - @brief Definition of the primary colors in color coordinates. +/* Definition of the primary colors in color coordinates. This is implicitly responsible for defining the conversion between RGB an YUV color spaces. LAB and related absolute color models should use KHR_DF_PRIMARIES_CIEXYZ. */ typedef enum _khr_df_primaries_e { - /** No color primaries defined */ + /* No color primaries defined */ KHR_DF_PRIMARIES_UNSPECIFIED = 0U, - /** Color primaries of ITU-R BT.709 and sRGB */ + /* Color primaries of ITU-R BT.709 and sRGB */ KHR_DF_PRIMARIES_BT709 = 1U, - /** Synonym for KHR_DF_PRIMARIES_BT709 */ + /* Synonym for KHR_DF_PRIMARIES_BT709 */ KHR_DF_PRIMARIES_SRGB = 1U, - /** Color primaries of ITU-R BT.601 (625-line EBU variant) */ + /* Color primaries of ITU-R BT.601 (625-line EBU variant) */ KHR_DF_PRIMARIES_BT601_EBU = 2U, - /** Color primaries of ITU-R BT.601 (525-line SMPTE C variant) */ + /* Color primaries of ITU-R BT.601 (525-line SMPTE C variant) */ KHR_DF_PRIMARIES_BT601_SMPTE = 3U, - /** Color primaries of ITU-R BT.2020 */ + /* Color primaries of ITU-R BT.2020 */ KHR_DF_PRIMARIES_BT2020 = 4U, - /** CIE theoretical color coordinate space */ + /* ITU-R BT.2100 uses the same primaries as BT.2020 */ + KHR_DF_PRIMARIES_BT2100 = 4U, + /* CIE theoretical color coordinate space */ KHR_DF_PRIMARIES_CIEXYZ = 5U, - /** Academy Color Encoding System primaries */ + /* Academy Color Encoding System primaries */ KHR_DF_PRIMARIES_ACES = 6U, - /** Color primaries of ACEScc */ + /* Color primaries of ACEScc */ KHR_DF_PRIMARIES_ACESCC = 7U, - /** Legacy NTSC 1953 primaries */ + /* Legacy NTSC 1953 primaries */ KHR_DF_PRIMARIES_NTSC1953 = 8U, - /** Legacy PAL 525-line primaries */ + /* Legacy PAL 525-line primaries */ KHR_DF_PRIMARIES_PAL525 = 9U, - /** Color primaries of Display P3 */ + /* Color primaries of Display P3 */ KHR_DF_PRIMARIES_DISPLAYP3 = 10U, - /** Color primaries of Adobe RGB (1998) */ + /* Color primaries of Adobe RGB (1998) */ KHR_DF_PRIMARIES_ADOBERGB = 11U, KHR_DF_PRIMARIES_MAX = 0xFFU } khr_df_primaries_e; -/** @~English - @brief Definition of the optical to digital transfer function +/* Definition of the optical to digital transfer function ("gamma correction"). Most transfer functions are not a pure power function and also include a linear element. LAB and related absolute color representations should use - KHR_DF_TRANSFER_UNSPECIFIED. */ + KHR_DF_TRANSFER_UNSPECIFIED. + These encodings indicate that the representation has had + the corresponding transfer function applied relative to a + linear representation; hence to process the linear intensity + represented by the value, a corresponding inverse transform + must be applied. */ typedef enum _khr_df_transfer_e { - /** No transfer function defined */ + /* No transfer function defined */ KHR_DF_TRANSFER_UNSPECIFIED = 0U, - /** Linear transfer function (value proportional to intensity) */ + /* Linear transfer function (value proportional to intensity) */ KHR_DF_TRANSFER_LINEAR = 1U, - /** Perceptually-linear transfer function of sRGH (~2.4) */ + /* Perceptually-linear transfer function of sRGB (~2.2); also used for scRGB */ KHR_DF_TRANSFER_SRGB = 2U, - /** Perceptually-linear transfer function of ITU BT.601, BT.709 and BT.2020 (~1/.45) */ + KHR_DF_TRANSFER_SRGB_EOTF = 2U, + KHR_DF_TRANSFER_SCRGB = 2U, + KHR_DF_TRANSFER_SCRGB_EOTF = 2U, + /* Perceptually-linear transfer function of ITU BT.601, BT.709 and BT.2020 (~1/.45) */ KHR_DF_TRANSFER_ITU = 3U, - /** SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) */ - KHR_DF_TRANSFER_SMTPE170M = 3U, - /** Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */ + KHR_DF_TRANSFER_ITU_OETF = 3U, + KHR_DF_TRANSFER_BT601 = 3U, + KHR_DF_TRANSFER_BT601_OETF = 3U, + KHR_DF_TRANSFER_BT709 = 3U, + KHR_DF_TRANSFER_BT709_OETF = 3U, + KHR_DF_TRANSFER_BT2020 = 3U, + KHR_DF_TRANSFER_BT2020_OETF = 3U, + /* SMTPE170M (digital NTSC) defines an alias for the ITU transfer function (~1/.45) and a linear OOTF */ + KHR_DF_TRANSFER_SMTPE170M = 3U, + KHR_DF_TRANSFER_SMTPE170M_OETF = 3U, + KHR_DF_TRANSFER_SMTPE170M_EOTF = 3U, + /* Perceptually-linear gamma function of original NTSC (simple 2.2 gamma) */ KHR_DF_TRANSFER_NTSC = 4U, - /** Sony S-log used by Sony video cameras */ + KHR_DF_TRANSFER_NTSC_EOTF = 4U, + /* Sony S-log used by Sony video cameras */ KHR_DF_TRANSFER_SLOG = 5U, - /** Sony S-log 2 used by Sony video cameras */ + KHR_DF_TRANSFER_SLOG_OETF = 5U, + /* Sony S-log 2 used by Sony video cameras */ KHR_DF_TRANSFER_SLOG2 = 6U, - /** ITU BT.1886 EOTF */ + KHR_DF_TRANSFER_SLOG2_OETF = 6U, + /* ITU BT.1886 EOTF */ KHR_DF_TRANSFER_BT1886 = 7U, - /** ITU BT.2100 HLG OETF */ + KHR_DF_TRANSFER_BT1886_EOTF = 7U, + /* ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..1 */ KHR_DF_TRANSFER_HLG_OETF = 8U, - /** ITU BT.2100 HLG EOTF */ + /* ITU BT.2100 HLG EOTF (nominal HDR display of HLG content), linear light normalized 0..1 */ KHR_DF_TRANSFER_HLG_EOTF = 9U, - /** ITU BT.2100 PQ EOTF */ + /* ITU BT.2100 PQ EOTF (typical HDR display-referred PQ content) */ KHR_DF_TRANSFER_PQ_EOTF = 10U, - /** ITU BT.2100 PQ OETF */ + /* ITU BT.2100 PQ OETF (nominal scene described by PQ HDR content) */ KHR_DF_TRANSFER_PQ_OETF = 11U, - /** DCI P3 transfer function */ + /* DCI P3 transfer function */ KHR_DF_TRANSFER_DCIP3 = 12U, - /** Legacy PAL OETF */ + KHR_DF_TRANSFER_DCIP3_EOTF = 12U, + /* Legacy PAL OETF */ KHR_DF_TRANSFER_PAL_OETF = 13U, - /** Legacy PAL 625-line EOTF */ + /* Legacy PAL 625-line EOTF */ KHR_DF_TRANSFER_PAL625_EOTF = 14U, - /** Legacy ST240 transfer function */ + /* Legacy ST240 transfer function */ KHR_DF_TRANSFER_ST240 = 15U, - /** ACEScc transfer function */ + KHR_DF_TRANSFER_ST240_OETF = 15U, + KHR_DF_TRANSFER_ST240_EOTF = 15U, + /* ACEScc transfer function */ KHR_DF_TRANSFER_ACESCC = 16U, - /** ACEScct transfer function */ - KHR_DF_TRANSFER_ACESCCT = 17U, - /** Adobe RGB (1998) transfer function */ - KHR_DF_TRANSFER_ADOBERGB = 18U, - KHR_DF_TRANSFER_MAX = 0xFFU + KHR_DF_TRANSFER_ACESCC_OETF = 16U, + /* ACEScct transfer function */ + KHR_DF_TRANSFER_ACESCCT = 17U, + KHR_DF_TRANSFER_ACESCCT_OETF = 17U, + /* Adobe RGB (1998) transfer function */ + KHR_DF_TRANSFER_ADOBERGB = 18U, + KHR_DF_TRANSFER_ADOBERGB_EOTF = 18U, + /* Legacy ITU BT.2100 HLG OETF (typical scene-referred content), linear light normalized 0..12 */ + KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF = 19U, + KHR_DF_TRANSFER_MAX = 0xFFU } khr_df_transfer_e; typedef enum _khr_df_flags_e { diff --git a/thirdparty/libktx/include/ktx.h b/thirdparty/libktx/include/ktx.h index dcf5dae42a5..8360117c313 100644 --- a/thirdparty/libktx/include/ktx.h +++ b/thirdparty/libktx/include/ktx.h @@ -191,8 +191,8 @@ typedef enum ktx_error_code_e { KTX_ERROR_MAX_ENUM = KTX_DECOMPRESS_CHECKSUM_ERROR /*!< For safety checks. */ } ktx_error_code_e; /** - * @deprecated * @~English + * @deprecated Use #ktx_error_code_e. * @brief For backward compatibility */ #define KTX_error_code ktx_error_code_e @@ -326,7 +326,7 @@ typedef struct ktxTexture { * KTX_TRUE if the texture is a cubemap or cubemap array. */ /** - * @typedef ktxTexture::isCubemap + * @typedef ktxTexture::isCompressed * @~English * * KTX_TRUE if the texture's format is a block compressed format. @@ -338,7 +338,7 @@ typedef struct ktxTexture { * KTX_TRUE if mipmaps should be generated for the texture by * ktxTexture_GLUpload() or ktxTexture_VkUpload(). */ -/**n +/** * @typedef ktxTexture::baseWidth * @~English * @brief Width of the texture's base level. @@ -455,6 +455,8 @@ typedef ktx_size_t (KTX_APIENTRY* PFNKTEXGETDATASIZEUNCOMPRESSED)(ktxTexture* This); typedef ktx_size_t (KTX_APIENTRY* PFNKTEXGETIMAGESIZE)(ktxTexture* This, ktx_uint32_t level); +typedef ktx_size_t + (KTX_APIENTRY* PFNKTEXGETLEVELSIZE)(ktxTexture* This, ktx_uint32_t level); typedef KTX_error_code (KTX_APIENTRY* PFNKTEXITERATELEVELS)(ktxTexture* This, PFNKTXITERCB iterCb, void* userdata); @@ -506,6 +508,7 @@ typedef KTX_error_code PFNKTEXGETIMAGEOFFSET GetImageOffset; PFNKTEXGETDATASIZEUNCOMPRESSED GetDataSizeUncompressed; PFNKTEXGETIMAGESIZE GetImageSize; + PFNKTEXGETLEVELSIZE GetLevelSize; PFNKTEXITERATELEVELS IterateLevels; PFNKTEXITERATELOADLEVELFACES IterateLoadLevelFaces; PFNKTEXNEEDSTRANSCODING NeedsTranscoding; @@ -557,6 +560,14 @@ typedef KTX_error_code #define ktxTexture_GetImageSize(This, level) \ (This)->vtbl->GetImageSize(This, level) +/** + * @~English + * @brief Helper for calling the GetImageSize virtual method of a ktxTexture. + * @copydoc ktxTexture2.ktxTexture2_GetImageSize + */ +#define ktxTexture_GetLevelSize(This, level) \ + (This)->vtbl->GetLevelSize(This, level) + /** * @~English * @brief Helper for calling the IterateLevels virtual method of a ktxTexture. @@ -681,11 +692,7 @@ typedef enum ktxSupercmpScheme { KTX_SS_END_RANGE = KTX_SS_ZLIB, KTX_SS_BEGIN_VENDOR_RANGE = 0x10000, KTX_SS_END_VENDOR_RANGE = 0x1ffff, - KTX_SS_BEGIN_RESERVED = 0x20000, - KTX_SUPERCOMPRESSION_BASIS = KTX_SS_BASIS_LZ, - /*!< @deprecated Will be removed before v4 release. Use KTX_SS_BASIS_LZ instead. */ - KTX_SUPERCOMPRESSION_ZSTD = KTX_SS_ZSTD - /*!< @deprecated Will be removed before v4 release. Use KTX_SS_ZSTD instead. */ + KTX_SS_BEGIN_RESERVED = 0x20000 } ktxSupercmpScheme; /** @@ -708,12 +715,24 @@ typedef struct ktxTexture2 { struct ktxTexture2_private* _private; /*!< Private data. */ } ktxTexture2; -/** - * @brief Helper for casting ktxTexture1 and ktxTexture2 to ktxTexture. +/* + * If Doxygen sees this macro it gets confused and fails to spot + * references to ktxTexture_*() functions in the running text. It + * also complains it can't find the reference when @ref is used + * with a fully qualified method name to make an intra-class + * reference in the @c ktxTexture class. + * See https://github.com/doxygen/doxygen/issues/10311. * - * Use with caution. + * Not documenting the macro is the lesser of two evils. */ -#define ktxTexture(t) ((ktxTexture*)t) +#if !defined(KTX_DOXYGEN_SKIP) + /** + * @brief Helper for casting ktxTexture1 and ktxTexture2 to ktxTexture. + * + * Use with caution. + */ + #define ktxTexture(t) ((ktxTexture*)t) +#endif /** * @memberof ktxTexture @@ -905,6 +924,22 @@ struct ktxStream * functions. */ +/** + * @~English + * @brief typedef of function pointer returned by GLGetProcAddress functions. + */ +typedef void (KTX_APIENTRY* PFNVOIDFUNCTION)(void); +/** + * @~English + * @brief typedef of pointer to function for retrieving OpenGL function pointers. + */ +typedef PFNVOIDFUNCTION (KTX_APIENTRY* PFNGLGETPROCADDRESS) (const char *proc); +/* + * Load pointers for the OpenGL functions needed by ktxTexture_GLUpload. + */ +KTX_API KTX_error_code KTX_APIENTRY +ktxLoadOpenGL(PFNGLGETPROCADDRESS pfnGLGetProcAddress); + /* * These four create a ktxTexture1 or ktxTexture2 according to the data * header, and return a pointer to the base ktxTexture class. @@ -969,7 +1004,7 @@ ktxTexture_IterateLevelFaces(ktxTexture* This, PFNKTXITERCB iterCb, * Create a new ktxTexture1. */ KTX_API KTX_error_code KTX_APIENTRY -ktxTexture1_Create(ktxTextureCreateInfo* createInfo, +ktxTexture1_Create(const ktxTextureCreateInfo* const createInfo, ktxTextureCreateStorageEnum storageAllocation, ktxTexture1** newTex); @@ -995,32 +1030,44 @@ KTX_API KTX_error_code KTX_APIENTRY ktxTexture1_CreateFromStream(ktxStream* stream, ktxTextureCreateFlags createFlags, ktxTexture1** newTex); +KTX_API void KTX_APIENTRY +ktxTexture1_Destroy(ktxTexture1* This); KTX_API ktx_bool_t KTX_APIENTRY ktxTexture1_NeedsTranscoding(ktxTexture1* This); +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture1_LoadImageData(ktxTexture1* This, ktx_uint8_t* pBuffer, ktx_size_t bufSize); + /* - * Write a ktxTexture object to a stdio stream in KTX format. + * These four write a ktxTexture1 object to a KTX v1 file. + */ +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture1_WriteToStdioStream(ktxTexture1* This, FILE* dstsstr); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture1_WriteToNamedFile(ktxTexture1* This, const char* const dstname); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture1_WriteToMemory(ktxTexture1* This, + ktx_uint8_t** bytes, ktx_size_t* size); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture1_WriteToStream(ktxTexture1* This, ktxStream *dststr); + +/* + * These four write a ktxTexture1 object to a KTX v2 file. */ KTX_API KTX_error_code KTX_APIENTRY ktxTexture1_WriteKTX2ToStdioStream(ktxTexture1* This, FILE* dstsstr); -/* - * Write a ktxTexture object to a named file in KTX format. - */ KTX_API KTX_error_code KTX_APIENTRY ktxTexture1_WriteKTX2ToNamedFile(ktxTexture1* This, const char* const dstname); -/* - * Write a ktxTexture object to a block of memory in KTX format. - */ KTX_API KTX_error_code KTX_APIENTRY ktxTexture1_WriteKTX2ToMemory(ktxTexture1* This, ktx_uint8_t** bytes, ktx_size_t* size); -/* - * Write a ktxTexture object to a ktxStream in KTX format. - */ KTX_API KTX_error_code KTX_APIENTRY ktxTexture1_WriteKTX2ToStream(ktxTexture1* This, ktxStream *dststr); @@ -1028,7 +1075,7 @@ ktxTexture1_WriteKTX2ToStream(ktxTexture1* This, ktxStream *dststr); * Create a new ktxTexture2. */ KTX_API KTX_error_code KTX_APIENTRY -ktxTexture2_Create(ktxTextureCreateInfo* createInfo, +ktxTexture2_Create(const ktxTextureCreateInfo* const createInfo, ktxTextureCreateStorageEnum storageAllocation, ktxTexture2** newTex); @@ -1061,6 +1108,9 @@ ktxTexture2_CreateFromStream(ktxStream* stream, ktxTextureCreateFlags createFlags, ktxTexture2** newTex); +KTX_API void KTX_APIENTRY +ktxTexture2_Destroy(ktxTexture2* This); + KTX_API KTX_error_code KTX_APIENTRY ktxTexture2_CompressBasis(ktxTexture2* This, ktx_uint32_t quality); @@ -1074,13 +1124,19 @@ KTX_API void KTX_APIENTRY ktxTexture2_GetComponentInfo(ktxTexture2* This, ktx_uint32_t* numComponents, ktx_uint32_t* componentByteLength); +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_GetImageOffset(ktxTexture2* This, ktx_uint32_t level, + ktx_uint32_t layer, ktx_uint32_t faceSlice, + ktx_size_t* pOffset); + KTX_API ktx_uint32_t KTX_APIENTRY ktxTexture2_GetNumComponents(ktxTexture2* This); +KTX_API khr_df_transfer_e KTX_APIENTRY +ktxTexture2_GetTransferFunction_e(ktxTexture2* This); +/* For backward compatibility. */ KTX_API khr_df_transfer_e KTX_APIENTRY ktxTexture2_GetOETF_e(ktxTexture2* This); - -// For backward compatibility KTX_API ktx_uint32_t KTX_APIENTRY ktxTexture2_GetOETF(ktxTexture2* This); @@ -1090,9 +1146,46 @@ ktxTexture2_GetColorModel_e(ktxTexture2* This); KTX_API ktx_bool_t KTX_APIENTRY ktxTexture2_GetPremultipliedAlpha(ktxTexture2* This); +KTX_API khr_df_primaries_e KTX_APIENTRY +ktxTexture2_GetPrimaries_e(ktxTexture2* This); + KTX_API ktx_bool_t KTX_APIENTRY ktxTexture2_NeedsTranscoding(ktxTexture2* This); +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture2_SetTransferFunction(ktxTexture2* This, khr_df_transfer_e tf); +/* For backward compatibility. */ +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture2_SetOETF(ktxTexture2* This, khr_df_transfer_e oetf); + +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture2_SetPrimaries(ktxTexture2* This, khr_df_primaries_e primaries); + +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture2_LoadImageData(ktxTexture2* This, ktx_uint8_t* pBuffer, ktx_size_t bufSize); +/* + * For rare testing scenarios. Use ktxTexture2_LoadImageData. + */ +KTX_API ktx_error_code_e KTX_APIENTRY +ktxTexture2_LoadDeflatedImageData(ktxTexture2* This, + ktx_uint8_t* pBuffer, ktx_size_t bufSize); + +/* + * These four write a ktxTexture2 object to a KTX v2 file. + */ +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_WriteToStdioStream(ktxTexture2* This, FILE* dstsstr); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_WriteToNamedFile(ktxTexture2* This, const char* const dstname); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_WriteToMemory(ktxTexture2* This, + ktx_uint8_t** bytes, ktx_size_t* size); + +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_WriteToStream(ktxTexture2* This, ktxStream *dststr); + /** * @~English * @brief Flags specifiying UASTC encoding options. @@ -1258,23 +1351,27 @@ ktxTexture2_CompressAstcEx(ktxTexture2* This, ktxAstcParams* params); KTX_API KTX_error_code KTX_APIENTRY ktxTexture2_CompressAstc(ktxTexture2* This, ktx_uint32_t quality); +KTX_API KTX_error_code KTX_APIENTRY +ktxTexture2_DecodeAstc(ktxTexture2* This); + /** * @memberof ktxTexture2 * @~English * @brief Structure for passing extended parameters to * ktxTexture2_CompressBasisEx(). * - * If you only want default values, use ktxTexture2_CompressBasis(). Here, at a minimum you - * must initialize the structure as follows: + * If you only want default values, use ktxTexture2_CompressBasis(). Here, at + * a minimum you must initialize the structure as follows: * @code * ktxBasisParams params = {0}; * params.structSize = sizeof(params); * params.compressionLevel = KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL; * @endcode * - * @e compressionLevel has to be explicitly set because 0 is a valid @e compressionLevel - * but is not the default used by the BasisU encoder when no value is set. Only the other - * settings that are to be non-default must be non-zero. + * @e compressionLevel has to be explicitly set because 0 is a valid + * @e compressionLevel but is not the default used by the BasisU encoder + * when no value is set. Only the other settings that are to be non-default + * must be non-zero. */ typedef struct ktxBasisParams { ktx_uint32_t structSize; @@ -1296,10 +1393,11 @@ typedef struct ktxBasisParams { /* ETC1S params */ ktx_uint32_t compressionLevel; - /*!< Encoding speed vs. quality tradeoff. Range is [0,5]. Higher values - are slower, but give higher quality. There is no default. Callers - must explicitly set this value. Callers can use - KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL as a default value. + /*!< Encoding speed vs. quality tradeoff. Range is [0,6]. Higher values + are much slower, but give slightly higher quality. Higher levels + are intended for video. There is no default. Callers must + explicitly set this value. Callers can use + KTX\_ETC1S\_DEFAULT\_COMPRESSION\_LEVEL as a default value. Currently this is 2. */ ktx_uint32_t qualityLevel; @@ -1342,7 +1440,7 @@ typedef struct ktxBasisParams { /*!< A swizzle to apply before encoding. It must match the regular expression /^[rgba01]{4}$/. If both this and preSwizzle are specified ktxTexture_CompressBasisEx will raise - KTX_INVALID_OPERATION. + KTX_INVALID_OPERATION. Usable with both ETC1S and UASTC. */ ktx_bool_t normalMap; /*!< Tunes codec parameters for better quality on normal maps (no @@ -1350,13 +1448,15 @@ typedef struct ktxBasisParams { Only valid for linear textures. */ ktx_bool_t separateRGToRGB_A; - /*!< @deprecated. This was and is a no-op. 2-component inputs have always been - automatically separated using an "rrrg" inputSwizzle. @sa inputSwizzle and normalMode. + /*!< @deprecated This was and is a no-op. 2-component inputs have + always been automatically separated using an "rrrg" inputSwizzle. + @sa inputSwizzle and normalMode. */ ktx_bool_t preSwizzle; /*!< If the texture has @c KTXswizzle metadata, apply it before compressing. Swizzling, like @c rabb may yield drastically - different error metrics if done after supercompression. + different error metrics if done after supercompression. Usable + for both ETC1S and UASTC. */ ktx_bool_t noEndpointRDO; /*!< Disable endpoint rate distortion optimizations. Slightly faster, @@ -1543,25 +1643,25 @@ typedef enum ktx_transcode_fmt_e { // Old enums for compatibility with code compiled against previous // versions of libktx. KTX_TF_ETC1 = KTX_TTF_ETC1_RGB, - //!< @deprecated. Use #KTX_TTF_ETC1_RGB. + //!< @deprecated Use #KTX_TTF_ETC1_RGB. KTX_TF_ETC2 = KTX_TTF_ETC, - //!< @deprecated. Use #KTX_TTF_ETC. + //!< @deprecated Use #KTX_TTF_ETC. KTX_TF_BC1 = KTX_TTF_BC1_RGB, - //!< @deprecated. Use #KTX_TTF_BC1_RGB. + //!< @deprecated Use #KTX_TTF_BC1_RGB. KTX_TF_BC3 = KTX_TTF_BC3_RGBA, - //!< @deprecated. Use #KTX_TTF_BC3_RGBA. + //!< @deprecated Use #KTX_TTF_BC3_RGBA. KTX_TF_BC4 = KTX_TTF_BC4_R, - //!< @deprecated. Use #KTX_TTF_BC4_R. + //!< @deprecated Use #KTX_TTF_BC4_R. KTX_TF_BC5 = KTX_TTF_BC5_RG, - //!< @deprecated. Use #KTX_TTF_BC5_RG. + //!< @deprecated Use #KTX_TTF_BC5_RG. KTX_TTF_BC7_M6_RGB = KTX_TTF_BC7_RGBA, - //!< @deprecated. Use #KTX_TTF_BC7_RGBA. + //!< @deprecated Use #KTX_TTF_BC7_RGBA. KTX_TTF_BC7_M5_RGBA = KTX_TTF_BC7_RGBA, - //!< @deprecated. Use #KTX_TTF_BC7_RGBA. + //!< @deprecated Use #KTX_TTF_BC7_RGBA. KTX_TF_BC7_M6_OPAQUE_ONLY = KTX_TTF_BC7_RGBA, - //!< @deprecated. Use #KTX_TTF_BC7_RGBA + //!< @deprecated Use #KTX_TTF_BC7_RGBA KTX_TF_PVRTC1_4_OPAQUE_ONLY = KTX_TTF_PVRTC1_4_RGB - //!< @deprecated. Use #KTX_TTF_PVRTC1_4_RGB. + //!< @deprecated Use #KTX_TTF_PVRTC1_4_RGB. } ktx_transcode_fmt_e; /** @@ -1716,25 +1816,6 @@ KTX_API KTX_error_code KTX_APIENTRY ktxPrintKTX2InfoJSONForStream(ktxStream* str } #endif -/*========================================================================* - * For backward compatibilty with the V3 & early versions of the V4 APIs. * - *========================================================================*/ - -/** - * @deprecated Will be dropped before V4 release. - */ -#define ktx_texture_transcode_fmt_e ktx_transcode_fmt_e - -/** - * @deprecated Will be dropped before V4 release. - */ -#define ktx_texture_decode_flags ktx_transcode_flag_bits - -/** - * @deprecated Will be dropped before V4 release. - */ -#define ktxTexture_GetSize ktxTexture_GetDatasize - /** @~English @page libktx_history Revision History diff --git a/thirdparty/libktx/lib/basis_transcode.cpp b/thirdparty/libktx/lib/basis_transcode.cpp index 43ad0591500..9268b8f31b5 100644 --- a/thirdparty/libktx/lib/basis_transcode.cpp +++ b/thirdparty/libktx/lib/basis_transcode.cpp @@ -8,7 +8,7 @@ /** * @internal - * @file basis_transcode.cpp + * @file * @~English * * @brief Functions for transcoding Basis Universal BasisLZ/ETC1S and UASTC textures. @@ -494,6 +494,11 @@ ktxTexture2_transcodeLzEtc1s(ktxTexture2* This, uint32_t& imageCount = firstImages[This->numLevels]; if (BGD_TABLES_ADDR(0, bgdh, imageCount) + bgdh.tablesByteLength > priv._sgdByteLength) { + // Compiler will not allow `goto cleanup;` because "jump bypasses variable initialization." + // The static initializations below this and before the loop are presumably the issue + // as the compiler is,presumably, inserting code to destruct those at the end of the + // function. + delete[] firstImages; return KTX_FILE_DATA_ERROR; } // FIXME: Do more validation. diff --git a/thirdparty/libktx/lib/checkheader.c b/thirdparty/libktx/lib/checkheader.c index cee47ce3417..50bd0b8dbae 100644 --- a/thirdparty/libktx/lib/checkheader.c +++ b/thirdparty/libktx/lib/checkheader.c @@ -10,7 +10,7 @@ /** * @internal - * @file checkheader.c + * @file * @~English * * @brief Function to verify a KTX file header diff --git a/thirdparty/libktx/lib/hashlist.c b/thirdparty/libktx/lib/hashlist.c index acfe41e5fce..e34206ceec5 100644 --- a/thirdparty/libktx/lib/hashlist.c +++ b/thirdparty/libktx/lib/hashlist.c @@ -8,7 +8,7 @@ /** * @internal - * @file hashlist.c + * @file * @~English * * @brief Functions for creating and using a hash list of key-value @@ -546,8 +546,8 @@ ktxHashList_Deserialize(ktxHashList* pHead, unsigned int kvdLen, void* pKvd) while (keyLen < keyAndValueByteSize && key[keyLen] != '\0') keyLen++; - if (key[keyLen] != '\0') { - // Missing NULL terminator + if (keyLen == keyAndValueByteSize || key[keyLen] != '\0') { + // Missing NULL terminator or no value return KTX_FILE_DATA_ERROR; } diff --git a/thirdparty/libktx/lib/memstream.c b/thirdparty/libktx/lib/memstream.c index b963fa70cad..6298c7c5bb8 100644 --- a/thirdparty/libktx/lib/memstream.c +++ b/thirdparty/libktx/lib/memstream.c @@ -248,7 +248,7 @@ KTX_error_code ktxMemStream_read(ktxStream* str, void* dst, const ktx_size_t cou newpos = mem->pos + count; /* The first clause checks for overflow. */ - if (newpos < mem->pos || (ktx_uint32_t)newpos > mem->used_size) + if (newpos < mem->pos || (ktx_size_t)newpos > mem->used_size) return KTX_FILE_UNEXPECTED_EOF; bytes = mem->robytes ? mem->robytes : mem->bytes; @@ -282,7 +282,7 @@ KTX_error_code ktxMemStream_skip(ktxStream* str, const ktx_size_t count) newpos = mem->pos + count; /* The first clause checks for overflow. */ - if (newpos < mem->pos || (ktx_uint32_t)newpos > mem->used_size) + if (newpos < mem->pos || (ktx_size_t)newpos > mem->used_size) return KTX_FILE_UNEXPECTED_EOF; mem->pos = newpos; @@ -388,7 +388,7 @@ KTX_error_code ktxMemStream_setpos(ktxStream* str, ktx_off_t pos) assert(str->type == eStreamTypeMemory); - if (pos > (ktx_off_t)str->data.mem->alloc_size) + if (pos < 0 || (ktx_size_t)pos > str->data.mem->alloc_size) return KTX_INVALID_OPERATION; str->data.mem->pos = pos; diff --git a/thirdparty/libktx/lib/miniz_wrapper.cpp b/thirdparty/libktx/lib/miniz_wrapper.cpp index cbd7da540af..bbbd9a802be 100644 --- a/thirdparty/libktx/lib/miniz_wrapper.cpp +++ b/thirdparty/libktx/lib/miniz_wrapper.cpp @@ -9,7 +9,7 @@ /** * @internal - * @file miniz_wrapper.c + * @file * @~English * * @brief Wrapper functions for ZLIB compression/decompression using miniz. diff --git a/thirdparty/libktx/lib/texture.c b/thirdparty/libktx/lib/texture.c index 76821e195b3..ede6cd151a9 100644 --- a/thirdparty/libktx/lib/texture.c +++ b/thirdparty/libktx/lib/texture.c @@ -8,7 +8,7 @@ /** * @internal - * @file texture.c + * @file * @~English * * @brief ktxTexture implementation. @@ -81,7 +81,8 @@ static ktx_uint32_t padRow(ktx_uint32_t* rowBytes); * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture. */ KTX_error_code -ktxTexture_construct(ktxTexture* This, ktxTextureCreateInfo* createInfo, +ktxTexture_construct(ktxTexture* This, + const ktxTextureCreateInfo* const createInfo, ktxFormatSize* formatSize) { DECLARE_PROTECTED(ktxTexture); @@ -828,7 +829,7 @@ ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level, /** * @memberof ktxTexture * @~English - * @brief Return pitch betweeb rows of a texture image level in bytes. + * @brief Return pitch between rows of a texture image level in bytes. * * For uncompressed textures the pitch is the number of bytes between * rows of texels. For compressed textures it is the number of bytes diff --git a/thirdparty/libktx/lib/texture.h b/thirdparty/libktx/lib/texture.h index e415a09d6a4..d9f598657eb 100644 --- a/thirdparty/libktx/lib/texture.h +++ b/thirdparty/libktx/lib/texture.h @@ -8,7 +8,7 @@ /** * @internal - * @file texture.h + * @file * @~English * * @brief Declare internal ktxTexture functions for sharing between @@ -90,7 +90,8 @@ void ktxTexture_rowInfo(ktxTexture* This, ktx_uint32_t level, ktx_uint32_t* numRows, ktx_uint32_t* rowBytes, ktx_uint32_t* rowPadding); KTX_error_code -ktxTexture_construct(ktxTexture* This, ktxTextureCreateInfo* createInfo, +ktxTexture_construct(ktxTexture* This, + const ktxTextureCreateInfo* const createInfo, ktxFormatSize* formatSize); KTX_error_code diff --git a/thirdparty/libktx/lib/texture1.c b/thirdparty/libktx/lib/texture1.c index 1591f3b6dcd..4bd23590eeb 100644 --- a/thirdparty/libktx/lib/texture1.c +++ b/thirdparty/libktx/lib/texture1.c @@ -8,7 +8,7 @@ /** * @internal - * @file texture2.c + * @file * @~English * * @brief ktxTexture1 implementation. Support for KTX format. @@ -61,7 +61,8 @@ ktxTexture1_constructCommon(ktxTexture1* This) * @copydoc ktxTexture2_construct */ static KTX_error_code -ktxTexture1_construct(ktxTexture1* This, ktxTextureCreateInfo* createInfo, +ktxTexture1_construct(ktxTexture1* This, + const ktxTextureCreateInfo* const createInfo, ktxTextureCreateStorageEnum storageAllocation) { ktxTexture_protected* prtctd; @@ -590,9 +591,9 @@ ktxTexture1_destruct(ktxTexture1* This) * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture's images. */ KTX_error_code -ktxTexture1_Create(ktxTextureCreateInfo* createInfo, - ktxTextureCreateStorageEnum storageAllocation, - ktxTexture1** newTex) +ktxTexture1_Create(const ktxTextureCreateInfo* const createInfo, + ktxTextureCreateStorageEnum storageAllocation, + ktxTexture1** newTex) { KTX_error_code result; @@ -1012,7 +1013,7 @@ ktxTexture1_GetDataSizeUncompressed(ktxTexture1* This) * @brief Calculate & return the size in bytes of an image at the specified * mip level. * - * For arrays, this is the size of layer, for cubemaps, the size of a face + * For arrays, this is the size of a layer, for cubemaps, the size of a face * and for 3D textures, the size of a depth slice. * * The size reflects the padding of each row to KTX_GL_UNPACK_ALIGNMENT. @@ -1027,6 +1028,27 @@ ktxTexture1_GetImageSize(ktxTexture1* This, ktx_uint32_t level) KTX_FORMAT_VERSION_ONE); } +/** + * @memberof ktxTexture1 + * @~English + * @brief Calculate & return the size in bytes of all the images in the specified + * mip level. + * + * For arrays, this is the size of all layers in the level, for cubemaps, the size of all + * faces in the level and for 3D textures, the size of all depth slices in the level. + * + * The size reflects the padding of each row to KTX_GL_UNPACK_ALIGNMENT. + * + * @param[in] This pointer to the ktxTexture1 object of interest. + * @param[in] level level of interest. + */ +ktx_size_t +ktxTexture1_GetLevelSize(ktxTexture1* This, ktx_uint32_t level) +{ + return ktxTexture_calcLevelSize(ktxTexture(This), level, + KTX_FORMAT_VERSION_ONE); +} + /** * @memberof ktxTexture1 @private * @~English @@ -1282,6 +1304,7 @@ ktxTexture1_LoadImageData(ktxTexture1* This, DECLARE_PRIVATE(ktxTexture1); ktx_uint32_t miplevel; ktx_uint8_t* pDest; + ktx_uint8_t* pDestEnd; KTX_error_code result = KTX_SUCCESS; if (This == NULL) @@ -1296,10 +1319,12 @@ ktxTexture1_LoadImageData(ktxTexture1* This, if (This->pData == NULL) return KTX_OUT_OF_MEMORY; pDest = This->pData; + pDestEnd = pDest + This->dataSize; } else if (bufSize < This->dataSize) { return KTX_INVALID_VALUE; } else { pDest = pBuffer; + pDestEnd = pBuffer + bufSize; } // Need to loop through for correct byte swapping @@ -1330,6 +1355,10 @@ ktxTexture1_LoadImageData(ktxTexture1* This, innerIterations = 1; for (face = 0; face < innerIterations; ++face) { + if (pDest + faceLodSizePadded > pDestEnd) { + result = KTX_INVALID_VALUE; + goto cleanup; + } result = prtctd->_stream.read(&prtctd->_stream, pDest, faceLodSizePadded); if (result != KTX_SUCCESS) { @@ -1448,6 +1477,7 @@ struct ktxTexture_vtbl ktxTexture1_vtbl = { (PFNKTEXGETIMAGEOFFSET)ktxTexture1_GetImageOffset, (PFNKTEXGETDATASIZEUNCOMPRESSED)ktxTexture1_GetDataSizeUncompressed, (PFNKTEXGETIMAGESIZE)ktxTexture1_GetImageSize, + (PFNKTEXGETLEVELSIZE)ktxTexture1_GetLevelSize, (PFNKTEXITERATELEVELS)ktxTexture1_IterateLevels, (PFNKTEXITERATELOADLEVELFACES)ktxTexture1_IterateLoadLevelFaces, (PFNKTEXNEEDSTRANSCODING)ktxTexture1_NeedsTranscoding, diff --git a/thirdparty/libktx/lib/texture1.h b/thirdparty/libktx/lib/texture1.h index 95734cc5f74..e7902adc3c6 100644 --- a/thirdparty/libktx/lib/texture1.h +++ b/thirdparty/libktx/lib/texture1.h @@ -8,7 +8,7 @@ /** * @internal - * @file texture1.h + * @file * @~English * * @brief Declare internal ktxTexture1 functions for sharing between diff --git a/thirdparty/libktx/lib/texture2.c b/thirdparty/libktx/lib/texture2.c index 014612fb572..6a061187496 100644 --- a/thirdparty/libktx/lib/texture2.c +++ b/thirdparty/libktx/lib/texture2.c @@ -8,7 +8,7 @@ /** * @internal - * @file texture2.c + * @file * @~English * * @brief ktxTexture2 implementation. Support for KTX2 format. @@ -41,6 +41,7 @@ #define IS_BIG_ENDIAN 0 extern uint32_t vkFormatTypeSize(VkFormat format); +extern bool isProhibitedFormat(VkFormat format); struct ktxTexture_vtbl ktxTexture2_vtbl; struct ktxTexture_vtblInt ktxTexture2_vtblInt; @@ -218,6 +219,11 @@ ktx_uint32_t e5b9g9r9_ufloat_comparator[e5b9g9r9_bdbwordcount] = { }; #endif +/* Helper constant: + Minimal size of basic descriptor block to safely read its size */ +#define KHR_DFD_SIZEFOR_DESCRIPTORBLOCKSIZE \ + ((KHR_DF_WORD_DESCRIPTORBLOCKSIZE + 1) * sizeof(uint32_t)) + /** * @private * @~English @@ -235,12 +241,32 @@ bool ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd) { uint32_t* pBdb = pDfd + 1; - - // Check the DFD is of the expected type and version. - if (*pBdb != 0) { + // pDfd[0] contains totalSize in bytes, check if it has at least + // KHR_DFD_SIZEFOR_DESCRIPTORBLOCKSIZE bytes + if (pDfd[0] < KHR_DFD_SIZEFOR_DESCRIPTORBLOCKSIZE || *pBdb != 0) { // Either decriptorType or vendorId is not 0 return false; } + // Iterate through all block descriptors and check if sum of their sizes + // is equal to the totalSize in pDfd[0] + uint32_t descriptorSize = pDfd[0] - sizeof(uint32_t); + while(descriptorSize > KHR_DFD_SIZEFOR_DESCRIPTORBLOCKSIZE) { + uint32_t descriptorBlockSize = KHR_DFDVAL(pBdb, DESCRIPTORBLOCKSIZE); + if (descriptorBlockSize <= descriptorSize) { + descriptorSize -= descriptorBlockSize; + pBdb += descriptorBlockSize / sizeof(uint32_t); + } else { + break; + } + } + if (descriptorSize != 0) { + return false; + } + + // reset pBdb pointer to the first block descriptor + pBdb = pDfd + 1; + + // Check the DFD is of the expected version. if (KHR_DFDVAL(pBdb, VERSIONNUMBER) != KHR_DF_VERSIONNUMBER_1_3) { return false; } @@ -249,13 +275,24 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd) This->blockWidth = KHR_DFDVAL(pBdb, TEXELBLOCKDIMENSION0) + 1; This->blockHeight = KHR_DFDVAL(pBdb, TEXELBLOCKDIMENSION1) + 1; This->blockDepth = KHR_DFDVAL(pBdb, TEXELBLOCKDIMENSION2) + 1; + if (KHR_DFDVAL(pBdb, BYTESPLANE0) == 0) { + // The DFD uses the deprecated way of indicating a supercompressed + // texture. Reconstruct the original values. + reconstructDFDBytesPlanesFromSamples(pDfd); + } This->blockSizeInBits = KHR_DFDVAL(pBdb, BYTESPLANE0) * 8; + // Account for ETC1S with possible second slice. + This->blockSizeInBits += KHR_DFDVAL(pBdb, BYTESPLANE1) * 8; This->paletteSizeInBits = 0; // No paletted formats in ktx v2. This->flags = 0; This->minBlocksX = This->minBlocksY = 1; if (KHR_DFDVAL(pBdb, MODEL) >= KHR_DF_MODEL_DXT1A) { // A block compressed format. Entire block is a single sample. This->flags |= KTX_FORMAT_SIZE_COMPRESSED_BIT; + if (KHR_DFDVAL(pBdb, MODEL) == KHR_DF_MODEL_ETC1S) { + // Special case the only multi-plane format we handle. + This->blockSizeInBits += KHR_DFDVAL(pBdb, BYTESPLANE1) * 8; + } if (KHR_DFDVAL(pBdb, MODEL) == KHR_DF_MODEL_PVRTC) { This->minBlocksX = This->minBlocksY = 2; } @@ -302,19 +339,6 @@ ktxFormatSize_initFromDfd(ktxFormatSize* This, ktx_uint32_t* pDfd) This->flags |= KTX_FORMAT_SIZE_YUVSDA_BIT; } } - if (This->blockSizeInBits == 0) { - // The DFD shows a supercompressed texture. Complete the ktxFormatSize - // struct by figuring out the post inflation value for bytesPlane0. - // Setting it here simplifies stuff later in this file. Setting the - // post inflation block size here will not cause any problems for - // the following reasons. (1) in v2 files levelIndex is always used to - // calculate data size and, of course, for the level offsets. (2) Finer - // grain access to supercompressed data than levels is not possible. - // - // The value set here is applied to the DFD after the data has been - // inflated during loading. - This->blockSizeInBits = reconstructDFDBytesPlane0FromSamples(pDfd) * 8; - } return true; } @@ -368,6 +392,11 @@ ktxTexture2_constructCommon(ktxTexture2* This, ktx_uint32_t numLevels) return KTX_SUCCESS; } +/* + * In hindsight this function should have been `#if KTX_FEATURE_WRITE`. + * In the interest of not breaking an app that may be using this via + * `ktxTexture2_Create` in `libktx_read` we won't change it. + */ /** * @memberof ktxTexture2 @private * @~English @@ -384,10 +413,12 @@ ktxTexture2_constructCommon(ktxTexture2* This, ktx_uint32_t numLevels) * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture or image data. * @exception KTX_UNSUPPORTED_TEXTURE_TYPE * The request VkFormat is one of the - * prohibited formats. + * prohibited formats or is otherwise + * unsupported. */ static KTX_error_code -ktxTexture2_construct(ktxTexture2* This, ktxTextureCreateInfo* createInfo, +ktxTexture2_construct(ktxTexture2* This, + const ktxTextureCreateInfo* const createInfo, ktxTextureCreateStorageEnum storageAllocation) { ktxFormatSize formatSize; @@ -396,6 +427,8 @@ ktxTexture2_construct(ktxTexture2* This, ktxTextureCreateInfo* createInfo, memset(This, 0, sizeof(*This)); if (createInfo->vkFormat != VK_FORMAT_UNDEFINED) { + if (isProhibitedFormat(createInfo->vkFormat)) + return KTX_UNSUPPORTED_TEXTURE_TYPE; This->pDfd = ktxVk2dfd(createInfo->vkFormat); if (!This->pDfd) return KTX_INVALID_VALUE; // Format is unknown or unsupported. @@ -574,6 +607,9 @@ cleanup: return result; } +bool isSrgbFormat(VkFormat format); +bool isNotSrgbFormatButHasSrgbVariant(VkFormat format); + /** * @memberof ktxTexture2 @private * @~English @@ -742,10 +778,25 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream, result = KTX_FILE_DATA_ERROR; goto cleanup; } - if (pBDFD->transfer != KHR_DF_TRANSFER_LINEAR && pBDFD->transfer != KHR_DF_TRANSFER_SRGB) { - // Unsupported transfer function - result = KTX_FILE_DATA_ERROR; - goto cleanup; + if (pBDFD->transfer > KHR_DF_TRANSFER_HLG_UNNORMALIZED_OETF) { + // Invalid transfer function + result = KTX_FILE_DATA_ERROR; + goto cleanup; + } + // No test for VK_FORMAT_UNDEFINED is needed here because: + // - any transfer function is allowed when vkFormat is UNDEFINED as with, + // e.g., some Basis Universal formats; + // - the following tests return false for VK_FORMAT_UNDEFINED. + if (isSrgbFormat(This->vkFormat) && pBDFD->transfer != KHR_DF_TRANSFER_SRGB) { + // Invalid transfer function + result = KTX_FILE_DATA_ERROR; + goto cleanup; + } + if (isNotSrgbFormatButHasSrgbVariant(This->vkFormat) + && pBDFD->transfer == KHR_DF_TRANSFER_SRGB) { + // Invalid transfer function + result = KTX_FILE_DATA_ERROR; + goto cleanup; } if (!ktxFormatSize_initFromDfd(&This->_protected->_formatSize, This->pDfd)) { @@ -945,8 +996,10 @@ ktxTexture2_constructFromStreamAndHeader(ktxTexture2* This, ktxStream* pStream, goto cleanup; // There could be padding here so seek to the next item. - (void)stream->setpos(stream, + result = stream->setpos(stream, pHeader->supercompressionGlobalData.byteOffset); + if (result != KTX_SUCCESS) + goto cleanup; // Read supercompressionGlobalData private->_supercompressionGlobalData = @@ -1178,6 +1231,11 @@ ktxTexture2_destruct(ktxTexture2* This) ktxTexture_destruct(ktxTexture(This)); } +/* + * In hindsight this function should have been `#if KTX_FEATURE_WRITE`. + * In the interest of not breaking an app that may be using this in + * `libktx_read` we won't change it. + */ /** * @memberof ktxTexture2 * @ingroup writer @@ -1222,7 +1280,7 @@ ktxTexture2_destruct(ktxTexture2* This) * @exception KTX_OUT_OF_MEMORY Not enough memory for the texture's images. */ KTX_error_code -ktxTexture2_Create(ktxTextureCreateInfo* createInfo, +ktxTexture2_Create(const ktxTextureCreateInfo* const createInfo, ktxTextureCreateStorageEnum storageAllocation, ktxTexture2** newTex) { @@ -1383,7 +1441,7 @@ ktxTexture2_CreateFromStdioStream(FILE* stdioStream, * @exception KTX_FILE_OPEN_FAILED The file could not be opened. * @exception KTX_INVALID_VALUE @p filename is @c NULL. * - * For other exceptions, see ktxTexture_CreateFromStdioStream(). + * For other exceptions, see ktxTexture2_CreateFromStdioStream(). */ KTX_error_code ktxTexture2_CreateFromNamedFile(const char* const filename, @@ -1436,7 +1494,7 @@ ktxTexture2_CreateFromNamedFile(const char* const filename, * * @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0. * - * For other exceptions, see ktxTexture_CreateFromStdioStream(). + * For other exceptions, see ktxTexture2_CreateFromStdioStream(). */ KTX_error_code ktxTexture2_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size, @@ -1488,7 +1546,7 @@ ktxTexture2_CreateFromMemory(const ktx_uint8_t* bytes, ktx_size_t size, * * @exception KTX_INVALID_VALUE Either @p bytes is NULL or @p size is 0. * - * For other exceptions, see ktxTexture_CreateFromStdioStream(). + * For other exceptions, see ktxTexture2_CreateFromStdioStream(). */ KTX_error_code ktxTexture2_CreateFromStream(ktxStream* stream, @@ -1859,11 +1917,30 @@ ktxTexture2_GetImageOffset(ktxTexture2* This, ktx_uint32_t level, /** * @memberof ktxTexture2 * @~English - * @brief Retrieve the opto-electrical transfer function of the images. + * @brief Retrieve the transfer function of the images. * * @param[in] This pointer to the ktxTexture2 object of interest. * - * @return A @c khr_df_transfer enum value specifying the OETF. + * @return A @c khr_df_transfer enum value specifying the transfer function. + */ +khr_df_transfer_e +ktxTexture2_GetTransferFunction_e(ktxTexture2* This) +{ + return KHR_DFDVAL(This->pDfd+1, TRANSFER); +} + +/** + * @memberof ktxTexture2 + * @~English + * @brief Retrieve the transfer function of the images. + * @deprecated Use ktxTexture2\_GetTransferFunction\_e. Now that the KTX + * specification allows setting of non-linear transfer functions other than + * sRGB, it is possible for the transfer function to be an EOTF so this + * name is no longer appropriate. + * + * @param[in] This pointer to the ktxTexture2 object of interest. + * + * @return A @c khr_df_transfer enum value specifying the transfer function. */ khr_df_transfer_e ktxTexture2_GetOETF_e(ktxTexture2* This) @@ -1874,13 +1951,13 @@ ktxTexture2_GetOETF_e(ktxTexture2* This) /** * @memberof ktxTexture2 * @~English - * @brief Retrieve the opto-electrical transfer function of the images. - * @deprecated Retained for backward compatibility. Use ktxTexture2\_GetOETF\_e() + * @brief Retrieve the transfer function of the images. + * @deprecated Use ktxTexture2\_GetTransferFunction\_e. * * @param[in] This pointer to the ktxTexture2 object of interest. * - * @return A @c khr_df_transfer enum value specifying the OETF, returned as - * @c ktx_uint32_t. + * @return A @c khr_df_transfer enum value specifying the transfer function, + * returned as @c ktx_uint32_t. */ ktx_uint32_t ktxTexture2_GetOETF(ktxTexture2* This) @@ -1918,6 +1995,21 @@ ktxTexture2_GetPremultipliedAlpha(ktxTexture2* This) return KHR_DFDVAL(This->pDfd+1, FLAGS) & KHR_DF_FLAG_ALPHA_PREMULTIPLIED; } +/** + * @memberof ktxTexture2 + * @~English + * @brief Retrieve the color primaries of the images. + * + * @param[in] This pointer to the ktxTexture2 object of interest. + * + * @return A @c khr_df_primaries enum value specifying the primaries. + */ +khr_df_primaries_e +ktxTexture2_GetPrimaries_e(ktxTexture2* This) +{ + return KHR_DFDVAL(This->pDfd+1, PRIMARIES); +} + /** * @memberof ktxTexture2 * @~English @@ -1936,6 +2028,69 @@ ktxTexture2_NeedsTranscoding(ktxTexture2* This) return false; } +#if KTX_FEATURE_WRITE +/* + * @memberof ktxTexture2 + * @ingroup writer + * @~English + * @brief Set the transfer function for the images in a texture. + * + * @param[in] This pointer to the ktxTexture2 + * @param[in] tf enumerator of the transfer function to set + * + * @return KTX_SUCCESS on success, other KTX_* enum values on error. + * + * @exception KTX_INVALID_OPERATION The transfer function is not valid for the + * vkFormat of the texture. + * @exception KTX_INVALID_VALUE The transfer function is not allowed by the + * KTX spec. + */ +ktx_error_code_e +ktxTexture2_SetTransferFunction(ktxTexture2* This, khr_df_transfer_e tf) +{ + if (isSrgbFormat(This->vkFormat) && tf != KHR_DF_TRANSFER_SRGB) + return KTX_INVALID_OPERATION; + + if (isNotSrgbFormatButHasSrgbVariant(This->vkFormat) && tf == KHR_DF_TRANSFER_SRGB) + return KTX_INVALID_OPERATION; + + KHR_DFDSETVAL(This->pDfd + 1, TRANSFER, tf); + return KTX_SUCCESS; +} + +/** + * @memberof ktxTexture2 + * @ingroup writer + * @~English + * @brief Set the transfer function for the images in a texture. + * @deprecated Use ktxTexture2\_SetTransferFunction. + * + * @param[in] This pointer to the ktxTexture2 + * @param[in] tf enumerator of the transfer function to set + */ +ktx_error_code_e +ktxTexture2_SetOETF(ktxTexture2* This, khr_df_transfer_e tf) +{ + return ktxTexture2_SetTransferFunction(This, tf); +} + +/** + * @memberof ktxTexture2 + * @ingroup writer + * @~English + * @brief Set the primaries for the images in a texture. + * + * @param[in] This pointer to the ktxTexture2 + * @param[in] primaries enumerator of the primaries to set + */ +ktx_error_code_e +ktxTexture2_SetPrimaries(ktxTexture2* This, khr_df_primaries_e primaries) +{ + KHR_DFDSETVAL(This->pDfd + 1, PRIMARIES, primaries); + return KTX_SUCCESS; +} +#endif + /** * @memberof ktxTexture2 * @~English @@ -2009,6 +2164,25 @@ ktxTexture2_GetImageSize(ktxTexture2* This, ktx_uint32_t level) KTX_FORMAT_VERSION_TWO); } +/** + * @memberof ktxTexture2 + * @~English + * @brief Calculate & return the size in bytes of all the images in the specified + * mip level. + * + * For arrays, this is the size of all layers in the level, for cubemaps, the size of all + * faces in the level and for 3D textures, the size of all depth slices in the level. + * + * @param[in] This pointer to the ktxTexture2 object of interest. + * @param[in] level level of interest. * + */ +ktx_size_t +ktxTexture2_GetLevelSize(ktxTexture2* This, ktx_uint32_t level) +{ + return ktxTexture_calcLevelSize(ktxTexture(This), level, + KTX_FORMAT_VERSION_TWO); +} + /** * @memberof ktxTexture2 * @~English @@ -2219,13 +2393,17 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb, ZSTD_ErrorCode error = ZSTD_getErrorCode(levelSize); switch(error) { case ZSTD_error_dstSize_tooSmall: - return KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small. + result = KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small. + goto cleanup; case ZSTD_error_checksum_wrong: - return KTX_DECOMPRESS_CHECKSUM_ERROR; + result = KTX_DECOMPRESS_CHECKSUM_ERROR; + goto cleanup; case ZSTD_error_memory_allocation: - return KTX_OUT_OF_MEMORY; + result = KTX_OUT_OF_MEMORY; + goto cleanup; default: - return KTX_FILE_DATA_ERROR; + result = KTX_FILE_DATA_ERROR; + goto cleanup; } } @@ -2244,8 +2422,11 @@ ktxTexture2_IterateLoadLevelFaces(ktxTexture2* This, PFNKTXITERCB iterCb, return result; } - if (levelIndex[level].uncompressedByteLength != levelSize) - return KTX_DECOMPRESS_LENGTH_ERROR; + if (levelIndex[level].uncompressedByteLength != levelSize) { + result = KTX_DECOMPRESS_LENGTH_ERROR; + goto cleanup; + } + #if IS_BIG_ENDIAN switch (prtctd->_typeSize) { @@ -2319,13 +2500,19 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, ktx_uint8_t* pInflatedData, ktx_size_t inflatedDataCapacity); +typedef enum { + LOADDATA_DONT_INFLATE_ON_LOAD, + LOADDATA_INFLATE_ON_LOAD +} ktxTexture2InflateFlagEnum; + /** * @memberof ktxTexture2 + * @internal * @~English * @brief Load all the image data from the ktxTexture2's source. * - * The data will be inflated if supercompressionScheme == @c KTX_SS_ZSTD or - * @c KTX_SS_ZLIB. + * The data will be inflated if requested and supercompressionScheme == @c KTX_SS_ZSTD + * or @c KTX_SS_ZLIB. * The data is loaded into the provided buffer or to an internally allocated * buffer, if @p pBuffer is @c NULL. Callers providing their own buffer must * ensure the buffer large enough to hold the inflated data for files deflated @@ -2337,6 +2524,8 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, * @param[in] This pointer to the ktxTexture object of interest. * @param[in] pBuffer pointer to the buffer in which to load the image data. * @param[in] bufSize size of the buffer pointed at by @p pBuffer. + * @param[in] inflateHandling enum indicating whether or not to inflate + * supercompressed data. * * @return KTX_SUCCESS on success, other KTX_* enum values on error. * @@ -2347,17 +2536,19 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, * ktxTexture was not created from a KTX source. * @exception KTX_OUT_OF_MEMORY Insufficient memory for the image data. */ -KTX_error_code -ktxTexture2_LoadImageData(ktxTexture2* This, - ktx_uint8_t* pBuffer, ktx_size_t bufSize) +ktx_error_code_e +ktxTexture2_loadImageDataInt(ktxTexture2* This, + ktx_uint8_t* pBuffer, ktx_size_t bufSize, + ktxTexture2InflateFlagEnum inflateHandling) { DECLARE_PROTECTED(ktxTexture); DECLARE_PRIVATE(ktxTexture2); ktx_uint8_t* pDest; - ktx_uint8_t* pDeflatedData = 0; + ktx_uint8_t* pDeflatedData = NULL; ktx_uint8_t* pReadBuf; KTX_error_code result = KTX_SUCCESS; - ktx_size_t inflatedDataCapacity = ktxTexture2_GetDataSizeUncompressed(This); + ktx_size_t outputDataCapacity; + ktx_bool_t doInflate = false; if (This == NULL) return KTX_INVALID_VALUE; @@ -2369,18 +2560,26 @@ ktxTexture2_LoadImageData(ktxTexture2* This, // This Texture not created from a stream or images already loaded; return KTX_INVALID_OPERATION; + if (inflateHandling == LOADDATA_INFLATE_ON_LOAD) { + outputDataCapacity = ktxTexture2_GetDataSizeUncompressed(This); + if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) + doInflate = true; + } else { + outputDataCapacity = This->dataSize; + } + if (pBuffer == NULL) { - This->pData = malloc(inflatedDataCapacity); + This->pData = malloc(outputDataCapacity); if (This->pData == NULL) return KTX_OUT_OF_MEMORY; pDest = This->pData; - } else if (bufSize < inflatedDataCapacity) { + } else if (bufSize < outputDataCapacity) { return KTX_INVALID_VALUE; } else { pDest = pBuffer; } - if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) { + if (doInflate) { // Create buffer to hold deflated data. pDeflatedData = malloc(This->dataSize); if (pDeflatedData == NULL) @@ -2396,29 +2595,28 @@ ktxTexture2_LoadImageData(ktxTexture2* This, result = prtctd->_stream.setpos(&prtctd->_stream, private->_firstLevelFileOffset); if (result != KTX_SUCCESS) - return result; + goto cleanup; result = prtctd->_stream.read(&prtctd->_stream, pReadBuf, This->dataSize); if (result != KTX_SUCCESS) - return result; + goto cleanup; - if (This->supercompressionScheme == KTX_SS_ZSTD || This->supercompressionScheme == KTX_SS_ZLIB) { + if (doInflate) { assert(pDeflatedData != NULL); if (This->supercompressionScheme == KTX_SS_ZSTD) { result = ktxTexture2_inflateZstdInt(This, pDeflatedData, pDest, - inflatedDataCapacity); + outputDataCapacity); } else if (This->supercompressionScheme == KTX_SS_ZLIB) { result = ktxTexture2_inflateZLIBInt(This, pDeflatedData, pDest, - inflatedDataCapacity); + outputDataCapacity); } - free(pDeflatedData); if (result != KTX_SUCCESS) { if (pBuffer == NULL) { free(This->pData); This->pData = 0; } - return result; + goto cleanup; } } @@ -2450,9 +2648,82 @@ ktxTexture2_LoadImageData(ktxTexture2* This, // No further need for stream or file offset. prtctd->_stream.destruct(&prtctd->_stream); private->_firstLevelFileOffset = 0; + +cleanup: + free(pDeflatedData); + return result; } +/** + * @memberof ktxTexture2 + * @~English + * @brief Load all the image data from the ktxTexture2's source. + * + * The data will be inflated if supercompressionScheme == @c KTX_SS_ZSTD or + * @c KTX_SS_ZLIB. + * The data is loaded into the provided buffer or to an internally allocated + * buffer, if @p pBuffer is @c NULL. Callers providing their own buffer must + * ensure the buffer large enough to hold the inflated data for files deflated + * with Zstd or ZLIB. See ktxTexture2\_GetDataSizeUncompressed(). + * + * The texture's levelIndex, dataSize, DFD and supercompressionScheme will + * all be updated after successful inflation to reflect the inflated data. + * + * @param[in] This pointer to the ktxTexture object of interest. + * @param[in] pBuffer pointer to the buffer in which to load the image data. + * @param[in] bufSize size of the buffer pointed at by @p pBuffer. + * + * @return KTX_SUCCESS on success, other KTX_* enum values on error. + * + * @exception KTX_INVALID_VALUE @p This is NULL. + * @exception KTX_INVALID_VALUE @p bufSize is less than the the image data size. + * @exception KTX_INVALID_OPERATION + * The data has already been loaded or the + * ktxTexture was not created from a KTX source. + * @exception KTX_OUT_OF_MEMORY Insufficient memory for the image data. + */ +ktx_error_code_e +ktxTexture2_LoadImageData(ktxTexture2* This, + ktx_uint8_t* pBuffer, ktx_size_t bufSize) +{ + return ktxTexture2_loadImageDataInt(This, pBuffer, bufSize, LOADDATA_INFLATE_ON_LOAD); +} + +/** + * @memberof ktxTexture2 + * @~English + * @brief Load all the image data from the ktxTexture2's source without inflatiion.. + * + * The data will be not be inflated if supercompressionScheme == @c KTX_SS_ZSTD or + * @c KTX_SS_ZLIB. This function is provided to support some rare testing scenarios. + * Generally use of ktxTexture2\_LoadImageData is highly recommended. For supercompressionScheme + * values other than those mentioned, the result of this function is the same as + * ktxTexture2\_LoadImageData. + * + * The data is loaded into the provided buffer or to an internally allocated + * buffer, if @p pBuffer is @c NULL. + * + * @param[in] This pointer to the ktxTexture object of interest. + * @param[in] pBuffer pointer to the buffer in which to load the image data. + * @param[in] bufSize size of the buffer pointed at by @p pBuffer. + * + * @return KTX_SUCCESS on success, other KTX_* enum values on error. + * + * @exception KTX_INVALID_VALUE @p This is NULL. + * @exception KTX_INVALID_VALUE @p bufSize is less than the the image data size. + * @exception KTX_INVALID_OPERATION + * The data has already been loaded or the + * ktxTexture was not created from a KTX source. + * @exception KTX_OUT_OF_MEMORY Insufficient memory for the image data. + */ +ktx_error_code_e +ktxTexture2_LoadDeflatedImageData(ktxTexture2* This, + ktx_uint8_t* pBuffer, ktx_size_t bufSize) +{ + return ktxTexture2_loadImageDataInt(This, pBuffer, bufSize, LOADDATA_DONT_INFLATE_ON_LOAD); +} + /** * @memberof ktxTexture2 @private * @~English @@ -2471,7 +2742,7 @@ ktx_uint64_t ktxTexture2_levelDataOffset(ktxTexture2* This, ktx_uint32_t level) * @~English * @brief Inflate the data in a ktxTexture2 object using Zstandard. * - * The texture's levelIndex, dataSize, DFD and supercompressionScheme will + * The texture's levelIndex, dataSize, DFD, data pointer, and supercompressionScheme will * all be updated after successful inflation to reflect the inflated data. * * @param[in] This pointer to the ktxTexture2 object of interest. @@ -2487,15 +2758,15 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, ktx_uint8_t* pInflatedData, ktx_size_t inflatedDataCapacity) { - DECLARE_PROTECTED(ktxTexture); ktx_uint32_t levelIndexByteLength = This->numLevels * sizeof(ktxLevelIndexEntry); uint64_t levelOffset = 0; ktxLevelIndexEntry* cindex = This->_private->_levelIndex; - ktxLevelIndexEntry* nindex; + ktxLevelIndexEntry* nindex = NULL; ktx_uint32_t uncompressedLevelAlignment; + ktx_error_code_e result = KTX_SUCCESS; - ZSTD_DCtx* dctx; + ZSTD_DCtx* dctx = NULL; if (pDeflatedData == NULL) return KTX_INVALID_VALUE; @@ -2515,6 +2786,10 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, ktx_size_t inflatedByteLength = 0; dctx = ZSTD_createDCtx(); + if (dctx == NULL) { + result = KTX_OUT_OF_MEMORY; + goto cleanup; + } for (int32_t level = This->numLevels - 1; level >= 0; level--) { size_t levelByteLength = ZSTD_decompressDCtx(dctx, pInflatedData + levelOffset, @@ -2525,18 +2800,24 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, ZSTD_ErrorCode error = ZSTD_getErrorCode(levelByteLength); switch(error) { case ZSTD_error_dstSize_tooSmall: - return KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small. + result = KTX_DECOMPRESS_LENGTH_ERROR; // inflatedDataCapacity too small. + goto cleanup; case ZSTD_error_checksum_wrong: - return KTX_DECOMPRESS_CHECKSUM_ERROR; + result = KTX_DECOMPRESS_CHECKSUM_ERROR; + goto cleanup; case ZSTD_error_memory_allocation: - return KTX_OUT_OF_MEMORY; - default: - return KTX_FILE_DATA_ERROR; + result = KTX_OUT_OF_MEMORY; + goto cleanup; + default: + result = KTX_FILE_DATA_ERROR; + goto cleanup; } } - if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength) - return KTX_DECOMPRESS_LENGTH_ERROR; + if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength) { + result = KTX_DECOMPRESS_LENGTH_ERROR; + goto cleanup; + } nindex[level].byteOffset = levelOffset; nindex[level].uncompressedByteLength = nindex[level].byteLength = @@ -2547,21 +2828,18 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, levelOffset += paddedLevelByteLength; inflatedDataCapacity -= paddedLevelByteLength; } - ZSTD_freeDCtx(dctx); // Now modify the texture. This->dataSize = inflatedByteLength; This->supercompressionScheme = KTX_SS_NONE; memcpy(cindex, nindex, levelIndexByteLength); // Update level index - free(nindex); This->_private->_requiredLevelAlignment = uncompressedLevelAlignment; - // Set bytesPlane as we're now sized. - uint32_t* bdb = This->pDfd + 1; - // blockSizeInBits was set to the inflated size on file load. - bdb[KHR_DF_WORD_BYTESPLANE0] = prtctd->_formatSize.blockSizeInBits / 8; - return KTX_SUCCESS; +cleanup: + ZSTD_freeDCtx(dctx); + free(nindex); + return result; } /** @@ -2569,7 +2847,7 @@ ktxTexture2_inflateZstdInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, * @~English * @brief Inflate the data in a ktxTexture2 object using miniz (ZLIB). * - * The texture's levelIndex, dataSize, DFD and supercompressionScheme will + * The texture's levelIndex, dataSize, DFD, data pointer, and supercompressionScheme will * all be updated after successful inflation to reflect the inflated data. * * @param[in] This pointer to the ktxTexture2 object of interest. @@ -2585,7 +2863,6 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, ktx_uint8_t* pInflatedData, ktx_size_t inflatedDataCapacity) { - DECLARE_PROTECTED(ktxTexture); ktx_uint32_t levelIndexByteLength = This->numLevels * sizeof(ktxLevelIndexEntry); uint64_t levelOffset = 0; @@ -2616,11 +2893,15 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, &levelByteLength, &pDeflatedData[cindex[level].byteOffset], cindex[level].byteLength); - if (result != KTX_SUCCESS) + if (result != KTX_SUCCESS) { + free(nindex); return result; + } - if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength) + if (This->_private->_levelIndex[level].uncompressedByteLength != levelByteLength) { + free(nindex); return KTX_DECOMPRESS_LENGTH_ERROR; + } nindex[level].byteOffset = levelOffset; nindex[level].uncompressedByteLength = nindex[level].byteLength = @@ -2639,10 +2920,6 @@ ktxTexture2_inflateZLIBInt(ktxTexture2* This, ktx_uint8_t* pDeflatedData, memcpy(cindex, nindex, levelIndexByteLength); // Update level index free(nindex); This->_private->_requiredLevelAlignment = uncompressedLevelAlignment; - // Set bytesPlane as we're now sized. - uint32_t* bdb = This->pDfd + 1; - // blockSizeInBits was set to the inflated size on file load. - bdb[KHR_DF_WORD_BYTESPLANE0] = prtctd->_formatSize.blockSizeInBits / 8; return KTX_SUCCESS; } @@ -2734,6 +3011,7 @@ struct ktxTexture_vtbl ktxTexture2_vtbl = { (PFNKTEXGETIMAGEOFFSET)ktxTexture2_GetImageOffset, (PFNKTEXGETDATASIZEUNCOMPRESSED)ktxTexture2_GetDataSizeUncompressed, (PFNKTEXGETIMAGESIZE)ktxTexture2_GetImageSize, + (PFNKTEXGETLEVELSIZE)ktxTexture2_GetLevelSize, (PFNKTEXITERATELEVELS)ktxTexture2_IterateLevels, (PFNKTEXITERATELOADLEVELFACES)ktxTexture2_IterateLoadLevelFaces, (PFNKTEXNEEDSTRANSCODING)ktxTexture2_NeedsTranscoding, diff --git a/thirdparty/libktx/lib/texture2.h b/thirdparty/libktx/lib/texture2.h index 08507804d92..d3355c5f1a4 100644 --- a/thirdparty/libktx/lib/texture2.h +++ b/thirdparty/libktx/lib/texture2.h @@ -8,7 +8,7 @@ /** * @internal - * @file texture2.h + * @file * @~English * * @brief Declare internal ktxTexture2 functions for sharing between @@ -46,9 +46,6 @@ typedef struct ktxTexture2_private { index offset. */ } ktxTexture2_private; -KTX_error_code -ktxTexture2_LoadImageData(ktxTexture2* This, - ktx_uint8_t* pBuffer, ktx_size_t bufSize); KTX_error_code ktxTexture2_constructCopy(ktxTexture2* This, ktxTexture2* orig); diff --git a/thirdparty/libktx/lib/texture_funcs.inl b/thirdparty/libktx/lib/texture_funcs.inl index 5de16a396b9..e3aef819800 100644 --- a/thirdparty/libktx/lib/texture_funcs.inl +++ b/thirdparty/libktx/lib/texture_funcs.inl @@ -8,7 +8,7 @@ /** * @internal - * @file texture_funcs.h + * @file * @~English * * @brief Templates for functions common to base & derived ktxTexture classes. @@ -28,11 +28,6 @@ */ -void CLASS_FUNC(Destroy)(CLASS* This); -KTX_error_code CLASS_FUNC(GetImageOffset)(CLASS* This, ktx_uint32_t level, - ktx_uint32_t layer, - ktx_uint32_t faceSlice, - ktx_size_t* pOffset); ktx_size_t CLASS_FUNC(GetImageSize)(CLASS* This, ktx_uint32_t level); KTX_error_code CLASS_FUNC(GLUpload)(CLASS* This, GLuint* pTexture, GLenum* pTarget, GLenum* pGlerror); @@ -45,9 +40,6 @@ KTX_error_code CLASS_FUNC(IterateLevelFaces)(CLASS* This, KTX_error_code CLASS_FUNC(IterateLoadLevelFaces)(CLASS* This, PFNKTXITERCB iterCb, void* userdata); -KTX_error_code CLASS_FUNC(LoadImageData)(CLASS* This, - ktx_uint8_t* pBuffer, - ktx_size_t bufSize); KTX_error_code CLASS_FUNC(SetImageFromStdioStream)(CLASS* This, ktx_uint32_t level,ktx_uint32_t layer, ktx_uint32_t faceSlice, @@ -57,13 +49,6 @@ KTX_error_code CLASS_FUNC(SetImageFromMemory)(CLASS* This, ktx_uint32_t faceSlice, const ktx_uint8_t* src, ktx_size_t srcSize); -KTX_error_code CLASS_FUNC(WriteToStdioStream)(CLASS* This, FILE* dstsstr); -KTX_error_code CLASS_FUNC(WriteToNamedFile)(CLASS* This, - const char* const dstname); -KTX_error_code CLASS_FUNC(WriteToMemory)(CLASS* This, - ktx_uint8_t** ppDstBytes, ktx_size_t* pSize); -KTX_error_code CLASS_FUNC(WriteToStream)(CLASS* This, - ktxStream* dststr); /* ====================================== diff --git a/thirdparty/libktx/lib/vkformat_check.c b/thirdparty/libktx/lib/vkformat_check.c index 5b86e3c8fea..a1ec463eef8 100644 --- a/thirdparty/libktx/lib/vkformat_check.c +++ b/thirdparty/libktx/lib/vkformat_check.c @@ -1,14 +1,15 @@ /***************************** Do not edit. ***************************** - Automatically generated from vulkan_core.h version 267 by mkvkformatfiles. + Automatically generated from vulkan_core.h version 287 by mkvkformatfiles. *************************************************************************/ /* -** Copyright 2015-2023 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ +// clang-format off: CI is complicated if formatting checks on generated files are enforced. #include #include @@ -74,6 +75,59 @@ isProhibitedFormat(VkFormat format) } } +bool +isSrgbFormat(VkFormat format) +{ + switch(format) { + case VK_FORMAT_R8_SRGB: + case VK_FORMAT_R8G8_SRGB: + case VK_FORMAT_R8G8B8_SRGB: + case VK_FORMAT_B8G8R8_SRGB: + case VK_FORMAT_R8G8B8A8_SRGB: + case VK_FORMAT_B8G8R8A8_SRGB: + case VK_FORMAT_A8B8G8R8_SRGB_PACK32: + case VK_FORMAT_BC1_RGB_SRGB_BLOCK: + case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: + case VK_FORMAT_BC2_SRGB_BLOCK: + case VK_FORMAT_BC3_SRGB_BLOCK: + case VK_FORMAT_BC7_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: + case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: + case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: + case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: + case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: + case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: + case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: + case VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT: + case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: + return true; + default: + return false; + } +} + bool isValidFormat(VkFormat format) { @@ -149,7 +203,7 @@ isValidFormat(VkFormat format) case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: - case VK_FORMAT_R16G16_S10_5_NV: + case VK_FORMAT_R16G16_SFIXED5_NV: case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: case VK_FORMAT_A8_UNORM_KHR: return true; @@ -158,3 +212,4 @@ isValidFormat(VkFormat format) } } +// clang-format on diff --git a/thirdparty/libktx/lib/vkformat_check_variant.c b/thirdparty/libktx/lib/vkformat_check_variant.c new file mode 100644 index 00000000000..280e0f073e0 --- /dev/null +++ b/thirdparty/libktx/lib/vkformat_check_variant.c @@ -0,0 +1,171 @@ +/* +** Copyright 2025 The Khronos Group Inc. +** +** SPDX-License-Identifier: Apache-2.0 +*/ + +#include +#include + +#include "vkformat_enum.h" + +bool +isNotSrgbFormatButHasSrgbVariant(VkFormat format) +{ + switch (format) { + // VK_FORMAT_R8_SRGB + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R8_SNORM: + case VK_FORMAT_R8_UINT: + case VK_FORMAT_R8_SINT: + + // VK_FORMAT_R8G8_SRGB + case VK_FORMAT_R8G8_UNORM: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R8G8_UINT: + case VK_FORMAT_R8G8_SINT: + + // VK_FORMAT_R8G8B8_SRGB + case VK_FORMAT_R8G8B8_UNORM: + case VK_FORMAT_R8G8B8_SNORM: + case VK_FORMAT_R8G8B8_UINT: + case VK_FORMAT_R8G8B8_SINT: + + // VK_FORMAT_B8G8R8_SRGB + case VK_FORMAT_B8G8R8_UNORM: + case VK_FORMAT_B8G8R8_SNORM: + case VK_FORMAT_B8G8R8_UINT: + case VK_FORMAT_B8G8R8_SINT: + + // VK_FORMAT_R8G8B8A8_SRGB + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_R8G8B8A8_UINT: + case VK_FORMAT_R8G8B8A8_SINT: + + // VK_FORMAT_B8G8R8A8_SRGB + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SNORM: + case VK_FORMAT_B8G8R8A8_UINT: + case VK_FORMAT_B8G8R8A8_SINT: + + // VK_FORMAT_A8B8G8R8_SRGB_PACK32 + case VK_FORMAT_A8B8G8R8_UNORM_PACK32: + case VK_FORMAT_A8B8G8R8_SNORM_PACK32: + case VK_FORMAT_A8B8G8R8_UINT_PACK32: + case VK_FORMAT_A8B8G8R8_SINT_PACK32: + + // VK_FORMAT_BC1_RGB_SRGB_BLOCK + case VK_FORMAT_BC1_RGB_UNORM_BLOCK: + + // VK_FORMAT_BC1_RGBA_SRGB_BLOCK + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + + // VK_FORMAT_BC2_SRGB_BLOCK + case VK_FORMAT_BC2_UNORM_BLOCK: + + // VK_FORMAT_BC3_SRGB_BLOCK + case VK_FORMAT_BC3_UNORM_BLOCK: + + // VK_FORMAT_BC7_SRGB_BLOCK + case VK_FORMAT_BC7_UNORM_BLOCK: + + // VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK + case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: + + // VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK + case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: + + // VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK + case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: + + // VK_FORMAT_ASTC_4x4_SRGB_BLOCK + case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: + + // VK_FORMAT_ASTC_5x4_SRGB_BLOCK + case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: + + // VK_FORMAT_ASTC_5x5_SRGB_BLOCK + case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: + + // VK_FORMAT_ASTC_6x5_SRGB_BLOCK + case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: + + // VK_FORMAT_ASTC_6x6_SRGB_BLOCK + case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: + + // VK_FORMAT_ASTC_8x5_SRGB_BLOCK + case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: + + // VK_FORMAT_ASTC_8x6_SRGB_BLOCK + case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: + + // VK_FORMAT_ASTC_8x8_SRGB_BLOCK + case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: + + // VK_FORMAT_ASTC_10x5_SRGB_BLOCK + case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: + + // VK_FORMAT_ASTC_10x6_SRGB_BLOCK + case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: + + // VK_FORMAT_ASTC_10x8_SRGB_BLOCK + case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: + + // VK_FORMAT_ASTC_10x10_SRGB_BLOCK + case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: + + // VK_FORMAT_ASTC_12x10_SRGB_BLOCK + case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: + + // VK_FORMAT_ASTC_12x12_SRGB_BLOCK + case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: + + // VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG + case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: + + // VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG + case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: + + // VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG + case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: + + // VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG + case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: + + // VK_FORMAT_ASTC_3x3x3_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_3x3x3_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_4x3x3_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_4x3x3_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_4x4x3_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_4x4x3_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_4x4x4_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_4x4x4_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_5x4x4_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_5x4x4_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_5x5x4_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_5x5x4_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_5x5x5_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_5x5x5_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_6x5x5_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_6x5x5_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_6x6x5_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_6x6x5_UNORM_BLOCK_EXT: + + // VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT + case VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT: + return true; + default: + return false; + } +} + + diff --git a/thirdparty/libktx/lib/vkformat_enum.h b/thirdparty/libktx/lib/vkformat_enum.h index 62279bb0098..693a72f3a5a 100644 --- a/thirdparty/libktx/lib/vkformat_enum.h +++ b/thirdparty/libktx/lib/vkformat_enum.h @@ -1,12 +1,13 @@ +// clang-format off: CI is complicated if formatting checks on generated files are enforced. #if !defined(_VKFORMAT_ENUM_H_) && !defined(VULKAN_CORE_H_) #define _VKFORMAT_ENUM_H_ /***************************** Do not edit. ***************************** - Automatically generated from vulkan_core.h version 267 by mkvkformatfiles. + Automatically generated from vulkan_core.h version 287 by mkvkformatfiles. *************************************************************************/ /* -** Copyright 2015-2023 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ @@ -296,7 +297,7 @@ typedef enum VkFormat { VK_FORMAT_ASTC_6x6x6_UNORM_BLOCK_EXT = 1000288027, VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT = 1000288028, VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT = 1000288029, - VK_FORMAT_R16G16_S10_5_NV = 1000464000, + VK_FORMAT_R16G16_SFIXED5_NV = 1000464000, VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR = 1000470000, VK_FORMAT_A8_UNORM_KHR = 1000470001, VK_FORMAT_MAX_ENUM = 0x7FFFFFFF @@ -312,3 +313,4 @@ typedef uint64_t VkFlags64; #define VK_FORMAT_MAX_STANDARD_ENUM 184 #endif /* _VKFORMAT_ENUM_H_ */ +// clang-format on diff --git a/thirdparty/libktx/lib/vkformat_typesize.c b/thirdparty/libktx/lib/vkformat_typesize.c index 92fb4680455..a07f9bde1f2 100644 --- a/thirdparty/libktx/lib/vkformat_typesize.c +++ b/thirdparty/libktx/lib/vkformat_typesize.c @@ -1,14 +1,15 @@ /***************************** Do not edit. ***************************** - Automatically generated from vulkan_core.h version 267 by mkvkformatfiles. + Automatically generated from vulkan_core.h version 287 by mkvkformatfiles. *************************************************************************/ /* -** Copyright 2015-2023 The Khronos Group Inc. +** Copyright 2015-2024 The Khronos Group Inc. ** ** SPDX-License-Identifier: Apache-2.0 */ +// clang-format off: CI is complicated if formatting checks on generated files are enforced. #include @@ -572,7 +573,7 @@ vkFormatTypeSize(VkFormat format) return 1; case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: return 1; - case VK_FORMAT_R16G16_S10_5_NV: + case VK_FORMAT_R16G16_SFIXED5_NV: return 2; case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: return 2; @@ -582,3 +583,4 @@ vkFormatTypeSize(VkFormat format) return 0; } } +// clang-format on diff --git a/thirdparty/libktx/patches/0002-disable-astc-block-ext.patch b/thirdparty/libktx/patches/0002-disable-astc-block-ext.patch index 73299f485b3..43b69855268 100644 --- a/thirdparty/libktx/patches/0002-disable-astc-block-ext.patch +++ b/thirdparty/libktx/patches/0002-disable-astc-block-ext.patch @@ -1,7 +1,7 @@ -diff --git a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl b/thirdparty/libktx/lib/dfdutils/vk2dfd.inl -index 5104c8fcb4..3398441e8c 100644 ---- a/thirdparty/libktx/lib/dfdutils/vk2dfd.inl -+++ b/thirdparty/libktx/lib/dfdutils/vk2dfd.inl +diff --git a/thirdparty/libktx/external/dfdutils/vk2dfd.inl b/thirdparty/libktx/external/dfdutils/vk2dfd.inl +index 0ed0fbb820..f1f97a75ca 100644 +--- a/thirdparty/libktx/external/dfdutils/vk2dfd.inl ++++ b/thirdparty/libktx/external/dfdutils/vk2dfd.inl @@ -370,6 +370,7 @@ case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 8 case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC, 4, 4, 1, s_SRGB); case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return createDFDCompressed(c_PVRTC2, 8, 4, 1, s_SRGB); @@ -15,6 +15,6 @@ index 5104c8fcb4..3398441e8c 100644 case VK_FORMAT_ASTC_6x6x6_SRGB_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SRGB); case VK_FORMAT_ASTC_6x6x6_SFLOAT_BLOCK_EXT: return createDFDCompressed(c_ASTC, 6, 6, 6, s_SFLOAT); +#endif - case VK_FORMAT_R16G16_S10_5_NV: return createDFDUnpacked(0, 2, 2, 0, s_S10_5); + case VK_FORMAT_R16G16_SFIXED5_NV: return createDFDUnpacked(0, 2, 2, 0, s_SFIXED5); case VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR: { int channels[] = {0,1,2,3}; int bits[] = {5,5,5,1}; diff --git a/thirdparty/libktx/patches/0003-basisu-1.60.patch b/thirdparty/libktx/patches/0003-basisu-1.60.patch index e772a0d74b1..d510ba9f346 100644 --- a/thirdparty/libktx/patches/0003-basisu-1.60.patch +++ b/thirdparty/libktx/patches/0003-basisu-1.60.patch @@ -1,8 +1,8 @@ diff --git a/thirdparty/libktx/lib/basis_transcode.cpp b/thirdparty/libktx/lib/basis_transcode.cpp -index d7ecb7a0fd..43ad059150 100644 +index 293400f4a5..9268b8f31b 100644 --- a/thirdparty/libktx/lib/basis_transcode.cpp +++ b/thirdparty/libktx/lib/basis_transcode.cpp -@@ -658,7 +658,7 @@ ktxTexture2_transcodeUastc(ktxTexture2* This, +@@ -663,7 +663,7 @@ ktxTexture2_transcodeUastc(ktxTexture2* This, ktxLevelIndexEntry* protoLevelIndex = protoPriv._levelIndex; ktx_size_t levelOffsetWrite = 0;